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