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