]> err.no Git - linux-2.6/blob - net/ipv6/exthdrs.c
[IPV6] MIP6: Several obvious clean-ups.
[linux-2.6] / net / ipv6 / exthdrs.c
1 /*
2  *      Extension Header handling for IPv6
3  *      Linux INET6 implementation
4  *
5  *      Authors:
6  *      Pedro Roque             <roque@di.fc.ul.pt>
7  *      Andi Kleen              <ak@muc.de>
8  *      Alexey Kuznetsov        <kuznet@ms2.inr.ac.ru>
9  *
10  *      $Id: exthdrs.c,v 1.13 2001/06/19 15:58:56 davem Exp $
11  *
12  *      This program is free software; you can redistribute it and/or
13  *      modify it under the terms of the GNU General Public License
14  *      as published by the Free Software Foundation; either version
15  *      2 of the License, or (at your option) any later version.
16  */
17
18 /* Changes:
19  *      yoshfuji                : ensure not to overrun while parsing 
20  *                                tlv options.
21  *      Mitsuru KANDA @USAGI and: Remove ipv6_parse_exthdrs().
22  *      YOSHIFUJI Hideaki @USAGI  Register inbound extension header
23  *                                handlers as inet6_protocol{}.
24  */
25
26 #include <linux/errno.h>
27 #include <linux/types.h>
28 #include <linux/socket.h>
29 #include <linux/sockios.h>
30 #include <linux/sched.h>
31 #include <linux/net.h>
32 #include <linux/netdevice.h>
33 #include <linux/in6.h>
34 #include <linux/icmpv6.h>
35
36 #include <net/sock.h>
37 #include <net/snmp.h>
38
39 #include <net/ipv6.h>
40 #include <net/protocol.h>
41 #include <net/transp_v6.h>
42 #include <net/rawv6.h>
43 #include <net/ndisc.h>
44 #include <net/ip6_route.h>
45 #include <net/addrconf.h>
46 #ifdef CONFIG_IPV6_MIP6
47 #include <net/xfrm.h>
48 #endif
49
50 #include <asm/uaccess.h>
51
52 int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
53 {
54         int packet_len = skb->tail - skb->nh.raw;
55         struct ipv6_opt_hdr *hdr;
56         int len;
57
58         if (offset + 2 > packet_len)
59                 goto bad;
60         hdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
61         len = ((hdr->hdrlen + 1) << 3);
62
63         if (offset + len > packet_len)
64                 goto bad;
65
66         offset += 2;
67         len -= 2;
68
69         while (len > 0) {
70                 int opttype = skb->nh.raw[offset];
71                 int optlen;
72
73                 if (opttype == type)
74                         return offset;
75
76                 switch (opttype) {
77                 case IPV6_TLV_PAD0:
78                         optlen = 1;
79                         break;
80                 default:
81                         optlen = skb->nh.raw[offset + 1] + 2;
82                         if (optlen > len)
83                                 goto bad;
84                         break;
85                 }
86                 offset += optlen;
87                 len -= optlen;
88         }
89         /* not_found */
90  bad:
91         return -1;
92 }
93
94 /*
95  *      Parsing tlv encoded headers.
96  *
97  *      Parsing function "func" returns 1, if parsing succeed
98  *      and 0, if it failed.
99  *      It MUST NOT touch skb->h.
100  */
101
102 struct tlvtype_proc {
103         int     type;
104         int     (*func)(struct sk_buff **skbp, int offset);
105 };
106
107 /*********************
108   Generic functions
109  *********************/
110
111 /* An unknown option is detected, decide what to do */
112
113 static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff)
114 {
115         struct sk_buff *skb = *skbp;
116
117         switch ((skb->nh.raw[optoff] & 0xC0) >> 6) {
118         case 0: /* ignore */
119                 return 1;
120
121         case 1: /* drop packet */
122                 break;
123
124         case 3: /* Send ICMP if not a multicast address and drop packet */
125                 /* Actually, it is redundant check. icmp_send
126                    will recheck in any case.
127                  */
128                 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
129                         break;
130         case 2: /* send ICMP PARM PROB regardless and drop packet */
131                 icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
132                 return 0;
133         };
134
135         kfree_skb(skb);
136         return 0;
137 }
138
139 /* Parse tlv encoded option header (hop-by-hop or destination) */
140
141 static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
142 {
143         struct sk_buff *skb = *skbp;
144         struct tlvtype_proc *curr;
145         int off = skb->h.raw - skb->nh.raw;
146         int len = ((skb->h.raw[1]+1)<<3);
147
148         if ((skb->h.raw + len) - skb->data > skb_headlen(skb))
149                 goto bad;
150
151         off += 2;
152         len -= 2;
153
154         while (len > 0) {
155                 int optlen = skb->nh.raw[off+1]+2;
156
157                 switch (skb->nh.raw[off]) {
158                 case IPV6_TLV_PAD0:
159                         optlen = 1;
160                         break;
161
162                 case IPV6_TLV_PADN:
163                         break;
164
165                 default: /* Other TLV code so scan list */
166                         if (optlen > len)
167                                 goto bad;
168                         for (curr=procs; curr->type >= 0; curr++) {
169                                 if (curr->type == skb->nh.raw[off]) {
170                                         /* type specific length/alignment 
171                                            checks will be performed in the 
172                                            func(). */
173                                         if (curr->func(skbp, off) == 0)
174                                                 return 0;
175                                         break;
176                                 }
177                         }
178                         if (curr->type < 0) {
179                                 if (ip6_tlvopt_unknown(skbp, off) == 0)
180                                         return 0;
181                         }
182                         break;
183                 }
184                 off += optlen;
185                 len -= optlen;
186         }
187         if (len == 0)
188                 return 1;
189 bad:
190         kfree_skb(skb);
191         return 0;
192 }
193
194 /*****************************
195   Destination options header.
196  *****************************/
197
198 #ifdef CONFIG_IPV6_MIP6
199 static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
200 {
201         struct sk_buff *skb = *skbp;
202         struct ipv6_destopt_hao *hao;
203         struct inet6_skb_parm *opt = IP6CB(skb);
204         struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb->nh.raw;
205         struct in6_addr tmp_addr;
206         int ret;
207
208         if (opt->dsthao) {
209                 LIMIT_NETDEBUG(KERN_DEBUG "hao duplicated\n");
210                 goto discard;
211         }
212         opt->dsthao = opt->dst1;
213         opt->dst1 = 0;
214
215         hao = (struct ipv6_destopt_hao *)(skb->nh.raw + optoff);
216
217         if (hao->length != 16) {
218                 LIMIT_NETDEBUG(
219                         KERN_DEBUG "hao invalid option length = %d\n", hao->length);
220                 goto discard;
221         }
222
223         if (!(ipv6_addr_type(&hao->addr) & IPV6_ADDR_UNICAST)) {
224                 LIMIT_NETDEBUG(
225                         KERN_DEBUG "hao is not an unicast addr: " NIP6_FMT "\n", NIP6(hao->addr));
226                 goto discard;
227         }
228
229         ret = xfrm6_input_addr(skb, (xfrm_address_t *)&ipv6h->daddr,
230                                (xfrm_address_t *)&hao->addr, IPPROTO_DSTOPTS);
231         if (unlikely(ret < 0))
232                 goto discard;
233
234         if (skb_cloned(skb)) {
235                 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
236                 if (skb2 == NULL)
237                         goto discard;
238
239                 kfree_skb(skb);
240
241                 /* update all variable using below by copied skbuff */
242                 *skbp = skb = skb2;
243                 hao = (struct ipv6_destopt_hao *)(skb2->nh.raw + optoff);
244                 ipv6h = (struct ipv6hdr *)skb2->nh.raw;
245         }
246
247         if (skb->ip_summed == CHECKSUM_COMPLETE)
248                 skb->ip_summed = CHECKSUM_NONE;
249
250         ipv6_addr_copy(&tmp_addr, &ipv6h->saddr);
251         ipv6_addr_copy(&ipv6h->saddr, &hao->addr);
252         ipv6_addr_copy(&hao->addr, &tmp_addr);
253
254         if (skb->tstamp.off_sec == 0)
255                 __net_timestamp(skb);
256
257         return 1;
258
259  discard:
260         kfree_skb(skb);
261         return 0;
262 }
263 #endif
264
265 static struct tlvtype_proc tlvprocdestopt_lst[] = {
266 #ifdef CONFIG_IPV6_MIP6
267         {
268                 .type   = IPV6_TLV_HAO,
269                 .func   = ipv6_dest_hao,
270         },
271 #endif
272         {-1,                    NULL}
273 };
274
275 static int ipv6_destopt_rcv(struct sk_buff **skbp)
276 {
277         struct sk_buff *skb = *skbp;
278         struct inet6_skb_parm *opt = IP6CB(skb);
279 #ifdef CONFIG_IPV6_MIP6
280         __u16 dstbuf;
281 #endif
282
283         if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
284             !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
285                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
286                 kfree_skb(skb);
287                 return -1;
288         }
289
290         opt->lastopt = skb->h.raw - skb->nh.raw;
291         opt->dst1 = skb->h.raw - skb->nh.raw;
292 #ifdef CONFIG_IPV6_MIP6
293         dstbuf = opt->dst1;
294 #endif
295
296         if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) {
297                 skb = *skbp;
298                 skb->h.raw += ((skb->h.raw[1]+1)<<3);
299 #ifdef CONFIG_IPV6_MIP6
300                 opt->nhoff = dstbuf;
301 #else
302                 opt->nhoff = opt->dst1;
303 #endif
304                 return 1;
305         }
306
307         IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
308         return -1;
309 }
310
311 static struct inet6_protocol destopt_protocol = {
312         .handler        =       ipv6_destopt_rcv,
313         .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
314 };
315
316 void __init ipv6_destopt_init(void)
317 {
318         if (inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS) < 0)
319                 printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n");
320 }
321
322 /********************************
323   NONE header. No data in packet.
324  ********************************/
325
326 static int ipv6_nodata_rcv(struct sk_buff **skbp)
327 {
328         struct sk_buff *skb = *skbp;
329
330         kfree_skb(skb);
331         return 0;
332 }
333
334 static struct inet6_protocol nodata_protocol = {
335         .handler        =       ipv6_nodata_rcv,
336         .flags          =       INET6_PROTO_NOPOLICY,
337 };
338
339 void __init ipv6_nodata_init(void)
340 {
341         if (inet6_add_protocol(&nodata_protocol, IPPROTO_NONE) < 0)
342                 printk(KERN_ERR "ipv6_nodata_init: Could not register protocol\n");
343 }
344
345 /********************************
346   Routing header.
347  ********************************/
348
349 static int ipv6_rthdr_rcv(struct sk_buff **skbp)
350 {
351         struct sk_buff *skb = *skbp;
352         struct inet6_skb_parm *opt = IP6CB(skb);
353         struct in6_addr *addr = NULL;
354         struct in6_addr daddr;
355         int n, i;
356
357         struct ipv6_rt_hdr *hdr;
358         struct rt0_hdr *rthdr;
359
360         if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
361             !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
362                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
363                 kfree_skb(skb);
364                 return -1;
365         }
366
367         hdr = (struct ipv6_rt_hdr *) skb->h.raw;
368
369         if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
370             skb->pkt_type != PACKET_HOST) {
371                 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
372                 kfree_skb(skb);
373                 return -1;
374         }
375
376 looped_back:
377         if (hdr->segments_left == 0) {
378                 switch (hdr->type) {
379 #ifdef CONFIG_IPV6_MIP6
380                 case IPV6_SRCRT_TYPE_2:
381                         /* Silently discard type 2 header unless it was
382                          * processed by own
383                          */
384                         if (!addr) {
385                                 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
386                                 kfree_skb(skb);
387                                 return -1;
388                         }
389                         break;
390 #endif
391                 default:
392                         break;
393                 }
394
395                 opt->lastopt = skb->h.raw - skb->nh.raw;
396                 opt->srcrt = skb->h.raw - skb->nh.raw;
397                 skb->h.raw += (hdr->hdrlen + 1) << 3;
398                 opt->dst0 = opt->dst1;
399                 opt->dst1 = 0;
400                 opt->nhoff = (&hdr->nexthdr) - skb->nh.raw;
401                 return 1;
402         }
403
404         switch (hdr->type) {
405         case IPV6_SRCRT_TYPE_0:
406                 if (hdr->hdrlen & 0x01) {
407                         IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
408                         icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
409                         return -1;
410                 }
411                 break;
412 #ifdef CONFIG_IPV6_MIP6
413         case IPV6_SRCRT_TYPE_2:
414                 /* Silently discard invalid RTH type 2 */
415                 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
416                         IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
417                         kfree_skb(skb);
418                         return -1;
419                 }
420                 break;
421 #endif
422         default:
423                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
424                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
425                 return -1;
426         }
427
428         /*
429          *      This is the routing header forwarding algorithm from
430          *      RFC 2460, page 16.
431          */
432
433         n = hdr->hdrlen >> 1;
434
435         if (hdr->segments_left > n) {
436                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
437                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
438                 return -1;
439         }
440
441         /* We are about to mangle packet header. Be careful!
442            Do not damage packets queued somewhere.
443          */
444         if (skb_cloned(skb)) {
445                 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
446                 kfree_skb(skb);
447                 /* the copy is a forwarded packet */
448                 if (skb2 == NULL) {
449                         IP6_INC_STATS_BH(IPSTATS_MIB_OUTDISCARDS);      
450                         return -1;
451                 }
452                 *skbp = skb = skb2;
453                 opt = IP6CB(skb2);
454                 hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
455         }
456
457         if (skb->ip_summed == CHECKSUM_COMPLETE)
458                 skb->ip_summed = CHECKSUM_NONE;
459
460         i = n - --hdr->segments_left;
461
462         rthdr = (struct rt0_hdr *) hdr;
463         addr = rthdr->addr;
464         addr += i - 1;
465
466         switch (hdr->type) {
467 #ifdef CONFIG_IPV6_MIP6
468         case IPV6_SRCRT_TYPE_2:
469                 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
470                                      (xfrm_address_t *)&skb->nh.ipv6h->saddr,
471                                      IPPROTO_ROUTING) < 0) {
472                         IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
473                         kfree_skb(skb);
474                         return -1;
475                 }
476                 if (!ipv6_chk_home_addr(addr)) {
477                         IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
478                         kfree_skb(skb);
479                         return -1;
480                 }
481                 break;
482 #endif
483         default:
484                 break;
485         }
486
487         if (ipv6_addr_is_multicast(addr)) {
488                 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
489                 kfree_skb(skb);
490                 return -1;
491         }
492
493         ipv6_addr_copy(&daddr, addr);
494         ipv6_addr_copy(addr, &skb->nh.ipv6h->daddr);
495         ipv6_addr_copy(&skb->nh.ipv6h->daddr, &daddr);
496
497         dst_release(xchg(&skb->dst, NULL));
498         ip6_route_input(skb);
499         if (skb->dst->error) {
500                 skb_push(skb, skb->data - skb->nh.raw);
501                 dst_input(skb);
502                 return -1;
503         }
504
505         if (skb->dst->dev->flags&IFF_LOOPBACK) {
506                 if (skb->nh.ipv6h->hop_limit <= 1) {
507                         IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
508                         icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
509                                     0, skb->dev);
510                         kfree_skb(skb);
511                         return -1;
512                 }
513                 skb->nh.ipv6h->hop_limit--;
514                 goto looped_back;
515         }
516
517         skb_push(skb, skb->data - skb->nh.raw);
518         dst_input(skb);
519         return -1;
520 }
521
522 static struct inet6_protocol rthdr_protocol = {
523         .handler        =       ipv6_rthdr_rcv,
524         .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
525 };
526
527 void __init ipv6_rthdr_init(void)
528 {
529         if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0)
530                 printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
531 };
532
533 /*
534    This function inverts received rthdr.
535    NOTE: specs allow to make it automatically only if
536    packet authenticated.
537
538    I will not discuss it here (though, I am really pissed off at
539    this stupid requirement making rthdr idea useless)
540
541    Actually, it creates severe problems  for us.
542    Embryonic requests has no associated sockets,
543    so that user have no control over it and
544    cannot not only to set reply options, but
545    even to know, that someone wants to connect
546    without success. :-(
547
548    For now we need to test the engine, so that I created
549    temporary (or permanent) backdoor.
550    If listening socket set IPV6_RTHDR to 2, then we invert header.
551                                                    --ANK (980729)
552  */
553
554 struct ipv6_txoptions *
555 ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
556 {
557         /* Received rthdr:
558
559            [ H1 -> H2 -> ... H_prev ]  daddr=ME
560
561            Inverted result:
562            [ H_prev -> ... -> H1 ] daddr =sender
563
564            Note, that IP output engine will rewrite this rthdr
565            by rotating it left by one addr.
566          */
567
568         int n, i;
569         struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
570         struct rt0_hdr *irthdr;
571         struct ipv6_txoptions *opt;
572         int hdrlen = ipv6_optlen(hdr);
573
574         if (hdr->segments_left ||
575             hdr->type != IPV6_SRCRT_TYPE_0 ||
576             hdr->hdrlen & 0x01)
577                 return NULL;
578
579         n = hdr->hdrlen >> 1;
580         opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
581         if (opt == NULL)
582                 return NULL;
583         memset(opt, 0, sizeof(*opt));
584         opt->tot_len = sizeof(*opt) + hdrlen;
585         opt->srcrt = (void*)(opt+1);
586         opt->opt_nflen = hdrlen;
587
588         memcpy(opt->srcrt, hdr, sizeof(*hdr));
589         irthdr = (struct rt0_hdr*)opt->srcrt;
590         irthdr->reserved = 0;
591         opt->srcrt->segments_left = n;
592         for (i=0; i<n; i++)
593                 memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
594         return opt;
595 }
596
597 EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
598
599 /**********************************
600   Hop-by-hop options.
601  **********************************/
602
603 /* Router Alert as of RFC 2711 */
604
605 static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
606 {
607         struct sk_buff *skb = *skbp;
608
609         if (skb->nh.raw[optoff+1] == 2) {
610                 IP6CB(skb)->ra = optoff;
611                 return 1;
612         }
613         LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
614                        skb->nh.raw[optoff+1]);
615         kfree_skb(skb);
616         return 0;
617 }
618
619 /* Jumbo payload */
620
621 static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
622 {
623         struct sk_buff *skb = *skbp;
624         u32 pkt_len;
625
626         if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
627                 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
628                                skb->nh.raw[optoff+1]);
629                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
630                 goto drop;
631         }
632
633         pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2));
634         if (pkt_len <= IPV6_MAXPLEN) {
635                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
636                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
637                 return 0;
638         }
639         if (skb->nh.ipv6h->payload_len) {
640                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
641                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
642                 return 0;
643         }
644
645         if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
646                 IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS);
647                 goto drop;
648         }
649
650         if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
651                 goto drop;
652
653         return 1;
654
655 drop:
656         kfree_skb(skb);
657         return 0;
658 }
659
660 static struct tlvtype_proc tlvprochopopt_lst[] = {
661         {
662                 .type   = IPV6_TLV_ROUTERALERT,
663                 .func   = ipv6_hop_ra,
664         },
665         {
666                 .type   = IPV6_TLV_JUMBO,
667                 .func   = ipv6_hop_jumbo,
668         },
669         { -1, }
670 };
671
672 int ipv6_parse_hopopts(struct sk_buff **skbp)
673 {
674         struct sk_buff *skb = *skbp;
675         struct inet6_skb_parm *opt = IP6CB(skb);
676
677         /*
678          * skb->nh.raw is equal to skb->data, and
679          * skb->h.raw - skb->nh.raw is always equal to
680          * sizeof(struct ipv6hdr) by definition of
681          * hop-by-hop options.
682          */
683         if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
684             !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) {
685                 kfree_skb(skb);
686                 return -1;
687         }
688
689         opt->hop = sizeof(struct ipv6hdr);
690         if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) {
691                 skb = *skbp;
692                 skb->h.raw += (skb->h.raw[1]+1)<<3;
693                 opt->nhoff = sizeof(struct ipv6hdr);
694                 return 1;
695         }
696         return -1;
697 }
698
699 /*
700  *      Creating outbound headers.
701  *
702  *      "build" functions work when skb is filled from head to tail (datagram)
703  *      "push"  functions work when headers are added from tail to head (tcp)
704  *
705  *      In both cases we assume, that caller reserved enough room
706  *      for headers.
707  */
708
709 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
710                             struct ipv6_rt_hdr *opt,
711                             struct in6_addr **addr_p)
712 {
713         struct rt0_hdr *phdr, *ihdr;
714         int hops;
715
716         ihdr = (struct rt0_hdr *) opt;
717         
718         phdr = (struct rt0_hdr *) skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
719         memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
720
721         hops = ihdr->rt_hdr.hdrlen >> 1;
722
723         if (hops > 1)
724                 memcpy(phdr->addr, ihdr->addr + 1,
725                        (hops - 1) * sizeof(struct in6_addr));
726
727         ipv6_addr_copy(phdr->addr + (hops - 1), *addr_p);
728         *addr_p = ihdr->addr;
729
730         phdr->rt_hdr.nexthdr = *proto;
731         *proto = NEXTHDR_ROUTING;
732 }
733
734 static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
735 {
736         struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
737
738         memcpy(h, opt, ipv6_optlen(opt));
739         h->nexthdr = *proto;
740         *proto = type;
741 }
742
743 void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
744                           u8 *proto,
745                           struct in6_addr **daddr)
746 {
747         if (opt->srcrt) {
748                 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
749                 /*
750                  * IPV6_RTHDRDSTOPTS is ignored
751                  * unless IPV6_RTHDR is set (RFC3542).
752                  */
753                 if (opt->dst0opt)
754                         ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
755         }
756         if (opt->hopopt)
757                 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
758 }
759
760 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
761 {
762         if (opt->dst1opt)
763                 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
764 }
765
766 struct ipv6_txoptions *
767 ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
768 {
769         struct ipv6_txoptions *opt2;
770
771         opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
772         if (opt2) {
773                 long dif = (char*)opt2 - (char*)opt;
774                 memcpy(opt2, opt, opt->tot_len);
775                 if (opt2->hopopt)
776                         *((char**)&opt2->hopopt) += dif;
777                 if (opt2->dst0opt)
778                         *((char**)&opt2->dst0opt) += dif;
779                 if (opt2->dst1opt)
780                         *((char**)&opt2->dst1opt) += dif;
781                 if (opt2->srcrt)
782                         *((char**)&opt2->srcrt) += dif;
783         }
784         return opt2;
785 }
786
787 EXPORT_SYMBOL_GPL(ipv6_dup_options);
788
789 static int ipv6_renew_option(void *ohdr,
790                              struct ipv6_opt_hdr __user *newopt, int newoptlen,
791                              int inherit,
792                              struct ipv6_opt_hdr **hdr,
793                              char **p)
794 {
795         if (inherit) {
796                 if (ohdr) {
797                         memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
798                         *hdr = (struct ipv6_opt_hdr *)*p;
799                         *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr));
800                 }
801         } else {
802                 if (newopt) {
803                         if (copy_from_user(*p, newopt, newoptlen))
804                                 return -EFAULT;
805                         *hdr = (struct ipv6_opt_hdr *)*p;
806                         if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen)
807                                 return -EINVAL;
808                         *p += CMSG_ALIGN(newoptlen);
809                 }
810         }
811         return 0;
812 }
813
814 struct ipv6_txoptions *
815 ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
816                    int newtype,
817                    struct ipv6_opt_hdr __user *newopt, int newoptlen)
818 {
819         int tot_len = 0;
820         char *p;
821         struct ipv6_txoptions *opt2;
822         int err;
823
824         if (opt) {
825                 if (newtype != IPV6_HOPOPTS && opt->hopopt)
826                         tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
827                 if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
828                         tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
829                 if (newtype != IPV6_RTHDR && opt->srcrt)
830                         tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
831                 if (newtype != IPV6_DSTOPTS && opt->dst1opt)
832                         tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
833         }
834
835         if (newopt && newoptlen)
836                 tot_len += CMSG_ALIGN(newoptlen);
837
838         if (!tot_len)
839                 return NULL;
840
841         tot_len += sizeof(*opt2);
842         opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
843         if (!opt2)
844                 return ERR_PTR(-ENOBUFS);
845
846         memset(opt2, 0, tot_len);
847
848         opt2->tot_len = tot_len;
849         p = (char *)(opt2 + 1);
850
851         err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen,
852                                 newtype != IPV6_HOPOPTS,
853                                 &opt2->hopopt, &p);
854         if (err)
855                 goto out;
856
857         err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen,
858                                 newtype != IPV6_RTHDRDSTOPTS,
859                                 &opt2->dst0opt, &p);
860         if (err)
861                 goto out;
862
863         err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen,
864                                 newtype != IPV6_RTHDR,
865                                 (struct ipv6_opt_hdr **)&opt2->srcrt, &p);
866         if (err)
867                 goto out;
868
869         err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen,
870                                 newtype != IPV6_DSTOPTS,
871                                 &opt2->dst1opt, &p);
872         if (err)
873                 goto out;
874
875         opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
876                           (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
877                           (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
878         opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
879
880         return opt2;
881 out:
882         sock_kfree_s(sk, opt2, opt2->tot_len);
883         return ERR_PTR(err);
884 }
885
886 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
887                                           struct ipv6_txoptions *opt)
888 {
889         /*
890          * ignore the dest before srcrt unless srcrt is being included.
891          * --yoshfuji
892          */
893         if (opt && opt->dst0opt && !opt->srcrt) {
894                 if (opt_space != opt) {
895                         memcpy(opt_space, opt, sizeof(*opt_space));
896                         opt = opt_space;
897                 }
898                 opt->opt_nflen -= ipv6_optlen(opt->dst0opt);
899                 opt->dst0opt = NULL;
900         }
901
902         return opt;
903 }
904