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