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