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