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