1 /*
2 * IPv6 output functions
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * $Id: ip6_output.c,v 1.27 2000/06/21 17:18:40 davem Exp $
9 *
10 * Based on linux/net/ipv4/ip_output.c
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 * Changes:
18 * A.N.Kuznetsov : airthmetics in fragmentation.
19 * extension headers are implemented.
20 * route changes now work.
21 * ip6_forward does not confuse sniffers.
22 * etc.
23 *
24 * H. von Brand : Added missing #include <linux/string.h>
25 */
26
27 #include <linux/config.h>
28 #include <linux/errno.h>
29 #include <linux/types.h>
30 #include <linux/string.h>
31 #include <linux/socket.h>
32 #include <linux/net.h>
33 #include <linux/netdevice.h>
34 #include <linux/if_arp.h>
35 #include <linux/in6.h>
36 #include <linux/route.h>
37
38 #include <linux/netfilter.h>
39 #include <linux/netfilter_ipv6.h>
40
41 #include <net/sock.h>
42 #include <net/snmp.h>
43
44 #include <net/ipv6.h>
45 #include <net/ndisc.h>
46 #include <net/protocol.h>
47 #include <net/ip6_route.h>
48 #include <net/addrconf.h>
49 #include <net/rawv6.h>
50 #include <net/icmp.h>
51
52 static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *fhdr)
53 {
54 static u32 ipv6_fragmentation_id = 1;
55 static spinlock_t ip6_id_lock = SPIN_LOCK_UNLOCKED;
56
57 spin_lock_bh(&ip6_id_lock);
58 fhdr->identification = ipv6_fragmentation_id;
59 if (++ipv6_fragmentation_id == 0)
60 ipv6_fragmentation_id = 1;
61 spin_unlock_bh(&ip6_id_lock);
62 }
63
64 static inline int ip6_output_finish(struct sk_buff *skb)
65 {
66
67 struct dst_entry *dst = skb->dst;
68 struct hh_cache *hh = dst->hh;
69
70 if (hh) {
71 read_lock_bh(&hh->hh_lock);
72 memcpy(skb->data - 16, hh->hh_data, 16);
73 read_unlock_bh(&hh->hh_lock);
74 skb_push(skb, hh->hh_len);
75 return hh->hh_output(skb);
76 } else if (dst->neighbour)
77 return dst->neighbour->output(skb);
78
79 kfree_skb(skb);
80 return -EINVAL;
81
82 }
83
84 /* dev_loopback_xmit for use with netfilter. */
85 static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
86 {
87 newskb->mac.raw = newskb->data;
88 skb_pull(newskb, newskb->nh.raw - newskb->data);
89 newskb->pkt_type = PACKET_LOOPBACK;
90 newskb->ip_summed = CHECKSUM_UNNECESSARY;
91 BUG_TRAP(newskb->dst);
92
93 netif_rx(newskb);
94 return 0;
95 }
96
97
98 int ip6_output(struct sk_buff *skb)
99 {
100 struct dst_entry *dst = skb->dst;
101 struct net_device *dev = dst->dev;
102
103 skb->protocol = __constant_htons(ETH_P_IPV6);
104 skb->dev = dev;
105
106 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) {
107 if (!(dev->flags&IFF_LOOPBACK) &&
108 (skb->sk == NULL || skb->sk->net_pinfo.af_inet6.mc_loop) &&
109 ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr)) {
110 struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
111
112 /* Do not check for IFF_ALLMULTI; multicast routing
113 is not supported in any case.
114 */
115 if (newskb)
116 NF_HOOK(PF_INET, NF_IP6_POST_ROUTING, newskb, NULL,
117 newskb->dev,
118 ip6_dev_loopback_xmit);
119
120 if (skb->nh.ipv6h->hop_limit == 0) {
121 kfree_skb(skb);
122 return 0;
123 }
124 }
125
126 IP6_INC_STATS(Ip6OutMcastPkts);
127 }
128
129 return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
130 }
131
132
133 #ifdef CONFIG_NETFILTER
134 static int route6_me_harder(struct sk_buff *skb)
135 {
136 struct ipv6hdr *iph = skb->nh.ipv6h;
137 struct dst_entry *dst;
138 struct flowi fl;
139
140 fl.proto = iph->nexthdr;
141 fl.fl6_dst = &iph->daddr;
142 fl.fl6_src = &iph->saddr;
143 fl.oif = skb->sk ? skb->sk->bound_dev_if : 0;
144 fl.fl6_flowlabel = 0;
145 fl.uli_u.ports.dport = 0;
146 fl.uli_u.ports.sport = 0;
147
148 dst = ip6_route_output(skb->sk, &fl);
149
150 if (dst->error) {
151 printk(KERN_DEBUG "route6_me_harder: No more route.\n");
152 return -EINVAL;
153 }
154
155 /* Drop old route. */
156 dst_release(skb->dst);
157
158 skb->dst = dst;
159 return 0;
160 }
161 #endif
162
163 static inline int ip6_maybe_reroute(struct sk_buff *skb)
164 {
165 #ifdef CONFIG_NETFILTER
166 if (skb->nfcache & NFC_ALTERED){
167 if (route6_me_harder(skb) != 0){
168 kfree_skb(skb);
169 return -EINVAL;
170 }
171 }
172 #endif /* CONFIG_NETFILTER */
173 return skb->dst->output(skb);
174 }
175
176 /*
177 * xmit an sk_buff (used by TCP)
178 */
179
180 int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
181 struct ipv6_txoptions *opt)
182 {
183 struct ipv6_pinfo * np = sk ? &sk->net_pinfo.af_inet6 : NULL;
184 struct in6_addr *first_hop = fl->nl_u.ip6_u.daddr;
185 struct dst_entry *dst = skb->dst;
186 struct ipv6hdr *hdr;
187 u8 proto = fl->proto;
188 int seg_len = skb->len;
189 int hlimit;
190
191 if (opt) {
192 int head_room;
193
194 /* First: exthdrs may take lots of space (~8K for now)
195 MAX_HEADER is not enough.
196 */
197 head_room = opt->opt_nflen + opt->opt_flen;
198 seg_len += head_room;
199 head_room += sizeof(struct ipv6hdr) + ((dst->dev->hard_header_len + 15)&~15);
200
201 if (skb_headroom(skb) < head_room) {
202 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
203 kfree_skb(skb);
204 skb = skb2;
205 if (skb == NULL)
206 return -ENOBUFS;
207 if (sk)
208 skb_set_owner_w(skb, sk);
209 }
210 if (opt->opt_flen)
211 ipv6_push_frag_opts(skb, opt, &proto);
212 if (opt->opt_nflen)
213 ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop);
214 }
215
216 hdr = skb->nh.ipv6h = (struct ipv6hdr*)skb_push(skb, sizeof(struct ipv6hdr));
217
218 /*
219 * Fill in the IPv6 header
220 */
221
222 *(u32*)hdr = __constant_htonl(0x60000000) | fl->fl6_flowlabel;
223 hlimit = -1;
224 if (np)
225 hlimit = np->hop_limit;
226 if (hlimit < 0)
227 hlimit = ((struct rt6_info*)dst)->rt6i_hoplimit;
228
229 hdr->payload_len = htons(seg_len);
230 hdr->nexthdr = proto;
231 hdr->hop_limit = hlimit;
232
233 ipv6_addr_copy(&hdr->saddr, fl->nl_u.ip6_u.saddr);
234 ipv6_addr_copy(&hdr->daddr, first_hop);
235
236 if (skb->len <= dst->pmtu) {
237 IP6_INC_STATS(Ip6OutRequests);
238 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
239 }
240
241 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
242 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst->pmtu, skb->dev);
243 kfree_skb(skb);
244 return -EMSGSIZE;
245 }
246
247 /*
248 * To avoid extra problems ND packets are send through this
249 * routine. It's code duplication but I really want to avoid
250 * extra checks since ipv6_build_header is used by TCP (which
251 * is for us performace critical)
252 */
253
254 int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
255 struct in6_addr *saddr, struct in6_addr *daddr,
256 int proto, int len)
257 {
258 struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
259 struct ipv6hdr *hdr;
260 int totlen;
261
262 skb->protocol = __constant_htons(ETH_P_IPV6);
263 skb->dev = dev;
264
265 totlen = len + sizeof(struct ipv6hdr);
266
267 hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr));
268 skb->nh.ipv6h = hdr;
269
270 *(u32*)hdr = htonl(0x60000000);
271
272 hdr->payload_len = htons(len);
273 hdr->nexthdr = proto;
274 hdr->hop_limit = np->hop_limit;
275
276 ipv6_addr_copy(&hdr->saddr, saddr);
277 ipv6_addr_copy(&hdr->daddr, daddr);
278
279 return 0;
280 }
281
282 static struct ipv6hdr * ip6_bld_1(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
283 int hlimit, unsigned pktlength)
284 {
285 struct ipv6hdr *hdr;
286
287 skb->nh.raw = skb_put(skb, sizeof(struct ipv6hdr));
288 hdr = skb->nh.ipv6h;
289
290 *(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000);
291
292 hdr->payload_len = htons(pktlength - sizeof(struct ipv6hdr));
293 hdr->hop_limit = hlimit;
294 hdr->nexthdr = fl->proto;
295
296 ipv6_addr_copy(&hdr->saddr, fl->nl_u.ip6_u.saddr);
297 ipv6_addr_copy(&hdr->daddr, fl->nl_u.ip6_u.daddr);
298 return hdr;
299 }
300
301 static __inline__ u8 * ipv6_build_fraghdr(struct sk_buff *skb, u8* prev_hdr, unsigned offset)
302 {
303 struct frag_hdr *fhdr;
304
305 fhdr = (struct frag_hdr *) skb_put(skb, sizeof(struct frag_hdr));
306
307 fhdr->nexthdr = *prev_hdr;
308 *prev_hdr = NEXTHDR_FRAGMENT;
309 prev_hdr = &fhdr->nexthdr;
310
311 fhdr->reserved = 0;
312 fhdr->frag_off = htons(offset);
313 ipv6_select_ident(skb, fhdr);
314 return &fhdr->nexthdr;
315 }
316
317 static int ip6_frag_xmit(struct sock *sk, inet_getfrag_t getfrag,
318 const void *data, struct dst_entry *dst,
319 struct flowi *fl, struct ipv6_txoptions *opt,
320 struct in6_addr *final_dst,
321 int hlimit, int flags, unsigned length, int mtu)
322 {
323 struct ipv6hdr *hdr;
324 struct sk_buff *last_skb;
325 u8 *prev_hdr;
326 int unfrag_len;
327 int frag_len;
328 int last_len;
329 int nfrags;
330 int fhdr_dist;
331 int frag_off;
332 int data_off;
333 int err;
334
335 /*
336 * Fragmentation
337 *
338 * Extension header order:
339 * Hop-by-hop -> Dest0 -> Routing -> Fragment -> Auth -> Dest1 -> rest (...)
340 *
341 * We must build the non-fragmented part that
342 * will be in every packet... this also means
343 * that other extension headers (Dest, Auth, etc)
344 * must be considered in the data to be fragmented
345 */
346
347 unfrag_len = sizeof(struct ipv6hdr) + sizeof(struct frag_hdr);
348 last_len = length;
349
350 if (opt) {
351 unfrag_len += opt->opt_nflen;
352 last_len += opt->opt_flen;
353 }
354
355 /*
356 * Length of fragmented part on every packet but
357 * the last must be an:
358 * "integer multiple of 8 octects".
359 */
360
361 frag_len = (mtu - unfrag_len) & ~0x7;
362
363 /* Unfragmentable part exceeds mtu. */
364 if (frag_len <= 0) {
365 ipv6_local_error(sk, EMSGSIZE, fl, mtu);
366 return -EMSGSIZE;
367 }
368
369 nfrags = last_len / frag_len;
370
371 /*
372 * We must send from end to start because of
373 * UDP/ICMP checksums. We do a funny trick:
374 * fill the last skb first with the fixed
375 * header (and its data) and then use it
376 * to create the following segments and send it
377 * in the end. If the peer is checking the M_flag
378 * to trigger the reassembly code then this
379 * might be a good idea.
380 */
381
382 frag_off = nfrags * frag_len;
383 last_len -= frag_off;
384
385 if (last_len == 0) {
386 last_len = frag_len;
387 frag_off -= frag_len;
388 nfrags--;
389 }
390 data_off = frag_off;
391
392 /* And it is implementation problem: for now we assume, that
393 all the exthdrs will fit to the first fragment.
394 */
395 if (opt) {
396 if (frag_len < opt->opt_flen) {
397 ipv6_local_error(sk, EMSGSIZE, fl, mtu);
398 return -EMSGSIZE;
399 }
400 data_off = frag_off - opt->opt_flen;
401 }
402
403 if (flags&MSG_PROBE)
404 return 0;
405
406 last_skb = sock_alloc_send_skb(sk, unfrag_len + frag_len +
407 dst->dev->hard_header_len + 15,
408 0, flags & MSG_DONTWAIT, &err);
409
410 if (last_skb == NULL)
411 return err;
412
413 last_skb->dst = dst_clone(dst);
414
415 skb_reserve(last_skb, (dst->dev->hard_header_len + 15) & ~15);
416
417 hdr = ip6_bld_1(sk, last_skb, fl, hlimit, frag_len+unfrag_len);
418 prev_hdr = &hdr->nexthdr;
419
420 if (opt && opt->opt_nflen)
421 prev_hdr = ipv6_build_nfrag_opts(last_skb, prev_hdr, opt, final_dst, 0);
422
423 prev_hdr = ipv6_build_fraghdr(last_skb, prev_hdr, frag_off);
424 fhdr_dist = prev_hdr - last_skb->data;
425
426 err = getfrag(data, &hdr->saddr, last_skb->tail, data_off, last_len);
427
428 if (!err) {
429 while (nfrags--) {
430 struct sk_buff *skb;
431
432 struct frag_hdr *fhdr2;
433
434 skb = skb_copy(last_skb, sk->allocation);
435
436 if (skb == NULL) {
437 IP6_INC_STATS(Ip6FragFails);
438 kfree_skb(last_skb);
439 return -ENOMEM;
440 }
441
442 frag_off -= frag_len;
443 data_off -= frag_len;
444
445 fhdr2 = (struct frag_hdr *) (skb->data + fhdr_dist);
446
447 /* more flag on */
448 fhdr2->frag_off = htons(frag_off | 1);
449
450 /* Write fragmentable exthdrs to the first chunk */
451 if (nfrags == 0 && opt && opt->opt_flen) {
452 ipv6_build_frag_opts(skb, &fhdr2->nexthdr, opt);
453 frag_len -= opt->opt_flen;
454 data_off = 0;
455 }
456
457 err = getfrag(data, &hdr->saddr,skb_put(skb, frag_len),
458 data_off, frag_len);
459
460 if (err) {
461 kfree_skb(skb);
462 break;
463 }
464
465 IP6_INC_STATS(Ip6FragCreates);
466 IP6_INC_STATS(Ip6OutRequests);
467 err = NF_HOOK(PF_INET6,NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
468 if (err) {
469 kfree_skb(last_skb);
470 return err;
471 }
472 }
473 }
474
475 if (err) {
476 IP6_INC_STATS(Ip6FragFails);
477 kfree_skb(last_skb);
478 return -EFAULT;
479 }
480
481 hdr->payload_len = htons(unfrag_len + last_len - sizeof(struct ipv6hdr));
482
483 /*
484 * update last_skb to reflect the getfrag we did
485 * on start.
486 */
487
488 skb_put(last_skb, last_len);
489
490 IP6_INC_STATS(Ip6FragCreates);
491 IP6_INC_STATS(Ip6FragOKs);
492 IP6_INC_STATS(Ip6OutRequests);
493 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, last_skb, NULL,dst->dev, ip6_maybe_reroute);
494 }
495
496 int ip6_build_xmit(struct sock *sk, inet_getfrag_t getfrag, const void *data,
497 struct flowi *fl, unsigned length,
498 struct ipv6_txoptions *opt, int hlimit, int flags)
499 {
500 struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
501 struct in6_addr *final_dst = NULL;
502 struct dst_entry *dst;
503 int err = 0;
504 unsigned int pktlength, jumbolen, mtu;
505 struct in6_addr saddr;
506
507 if (opt && opt->srcrt) {
508 struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
509 final_dst = fl->fl6_dst;
510 fl->fl6_dst = rt0->addr;
511 }
512
513 if (!fl->oif && ipv6_addr_is_multicast(fl->nl_u.ip6_u.daddr))
514 fl->oif = np->mcast_oif;
515
516 dst = __sk_dst_check(sk, np->dst_cookie);
517 if (dst) {
518 struct rt6_info *rt = (struct rt6_info*)dst;
519
520 /* Yes, checking route validity in not connected
521 case is not very simple. Take into account,
522 that we do not support routing by source, TOS,
523 and MSG_DONTROUTE --ANK (980726)
524
525 1. If route was host route, check that
526 cached destination is current.
527 If it is network route, we still may
528 check its validity using saved pointer
529 to the last used address: daddr_cache.
530 We do not want to save whole address now,
531 (because main consumer of this service
532 is tcp, which has not this problem),
533 so that the last trick works only on connected
534 sockets.
535 2. oif also should be the same.
536 */
537
538 if (((rt->rt6i_dst.plen != 128 ||
539 ipv6_addr_cmp(fl->fl6_dst, &rt->rt6i_dst.addr))
540 && (np->daddr_cache == NULL ||
541 ipv6_addr_cmp(fl->fl6_dst, np->daddr_cache)))
542 || (fl->oif && fl->oif != dst->dev->ifindex)) {
543 dst = NULL;
544 } else
545 dst_clone(dst);
546 }
547
548 if (dst == NULL)
549 dst = ip6_route_output(sk, fl);
550
551 if (dst->error) {
552 IP6_INC_STATS(Ip6OutNoRoutes);
553 dst_release(dst);
554 return -ENETUNREACH;
555 }
556
557 if (fl->fl6_src == NULL) {
558 err = ipv6_get_saddr(dst, fl->fl6_dst, &saddr);
559
560 if (err) {
561 #if IP6_DEBUG >= 2
562 printk(KERN_DEBUG "ip6_build_xmit: "
563 "no availiable source address\n");
564 #endif
565 goto out;
566 }
567 fl->fl6_src = &saddr;
568 }
569 pktlength = length;
570
571 if (hlimit < 0) {
572 if (ipv6_addr_is_multicast(fl->fl6_dst))
573 hlimit = np->mcast_hops;
574 else
575 hlimit = np->hop_limit;
576 if (hlimit < 0)
577 hlimit = ((struct rt6_info*)dst)->rt6i_hoplimit;
578 }
579
580 jumbolen = 0;
581
582 if (!sk->protinfo.af_inet.hdrincl) {
583 pktlength += sizeof(struct ipv6hdr);
584 if (opt)
585 pktlength += opt->opt_flen + opt->opt_nflen;
586
587 if (pktlength > 0xFFFF + sizeof(struct ipv6hdr)) {
588 /* Jumbo datagram.
589 It is assumed, that in the case of hdrincl
590 jumbo option is supplied by user.
591 */
592 pktlength += 8;
593 jumbolen = pktlength - sizeof(struct ipv6hdr);
594 }
595 }
596
597 mtu = dst->pmtu;
598 if (np->frag_size < mtu) {
599 if (np->frag_size)
600 mtu = np->frag_size;
601 else if (np->pmtudisc == IPV6_PMTUDISC_DONT)
602 mtu = IPV6_MIN_MTU;
603 }
604
605 /* Critical arithmetic overflow check.
606 FIXME: may gcc optimize it out? --ANK (980726)
607 */
608 if (pktlength < length) {
609 ipv6_local_error(sk, EMSGSIZE, fl, mtu);
610 err = -EMSGSIZE;
611 goto out;
612 }
613
614 if (flags&MSG_CONFIRM)
615 dst_confirm(dst);
616
617 if (pktlength <= mtu) {
618 struct sk_buff *skb;
619 struct ipv6hdr *hdr;
620 struct net_device *dev = dst->dev;
621
622 err = 0;
623 if (flags&MSG_PROBE)
624 goto out;
625
626 skb = sock_alloc_send_skb(sk, pktlength + 15 +
627 dev->hard_header_len, 0,
628 flags & MSG_DONTWAIT, &err);
629
630 if (skb == NULL) {
631 IP6_INC_STATS(Ip6OutDiscards);
632 goto out;
633 }
634
635 skb->dst = dst_clone(dst);
636
637 skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
638
639 hdr = (struct ipv6hdr *) skb->tail;
640 skb->nh.ipv6h = hdr;
641
642 if (!sk->protinfo.af_inet.hdrincl) {
643 ip6_bld_1(sk, skb, fl, hlimit,
644 jumbolen ? sizeof(struct ipv6hdr) : pktlength);
645
646 if (opt || jumbolen) {
647 u8 *prev_hdr = &hdr->nexthdr;
648 prev_hdr = ipv6_build_nfrag_opts(skb, prev_hdr, opt, final_dst, jumbolen);
649 if (opt && opt->opt_flen)
650 ipv6_build_frag_opts(skb, prev_hdr, opt);
651 }
652 }
653
654 skb_put(skb, length);
655 err = getfrag(data, &hdr->saddr,
656 ((char *) hdr) + (pktlength - length),
657 0, length);
658
659 if (!err) {
660 IP6_INC_STATS(Ip6OutRequests);
661 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
662 } else {
663 err = -EFAULT;
664 kfree_skb(skb);
665 }
666 } else {
667 if (sk->protinfo.af_inet.hdrincl || jumbolen ||
668 np->pmtudisc == IPV6_PMTUDISC_DO) {
669 ipv6_local_error(sk, EMSGSIZE, fl, mtu);
670 err = -EMSGSIZE;
671 goto out;
672 }
673
674 err = ip6_frag_xmit(sk, getfrag, data, dst, fl, opt, final_dst, hlimit,
675 flags, length, mtu);
676 }
677
678 /*
679 * cleanup
680 */
681 out:
682 ip6_dst_store(sk, dst, fl->nl_u.ip6_u.daddr == &np->daddr ? &np->daddr : NULL);
683 if (err > 0)
684 err = np->recverr ? net_xmit_errno(err) : 0;
685 return err;
686 }
687
688 int ip6_call_ra_chain(struct sk_buff *skb, int sel)
689 {
690 struct ip6_ra_chain *ra;
691 struct sock *last = NULL;
692
693 read_lock(&ip6_ra_lock);
694 for (ra = ip6_ra_chain; ra; ra = ra->next) {
695 struct sock *sk = ra->sk;
696 if (sk && ra->sel == sel) {
697 if (last) {
698 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
699 if (skb2)
700 rawv6_rcv(last, skb2, skb2->len);
701 }
702 last = sk;
703 }
704 }
705
706 if (last) {
707 rawv6_rcv(last, skb, skb->len);
708 read_unlock(&ip6_ra_lock);
709 return 1;
710 }
711 read_unlock(&ip6_ra_lock);
712 return 0;
713 }
714
715 static inline int ip6_forward_finish(struct sk_buff *skb)
716 {
717 return skb->dst->output(skb);
718 }
719
720 int ip6_forward(struct sk_buff *skb)
721 {
722 struct dst_entry *dst = skb->dst;
723 struct ipv6hdr *hdr = skb->nh.ipv6h;
724 struct inet6_skb_parm *opt =(struct inet6_skb_parm*)skb->cb;
725
726 if (ipv6_devconf.forwarding == 0 && opt->srcrt == 0)
727 goto drop;
728
729 /*
730 * We DO NOT make any processing on
731 * RA packets, pushing them to user level AS IS
732 * without ane WARRANTY that application will be able
733 * to interpret them. The reason is that we
734 * cannot make anything clever here.
735 *
736 * We are not end-node, so that if packet contains
737 * AH/ESP, we cannot make anything.
738 * Defragmentation also would be mistake, RA packets
739 * cannot be fragmented, because there is no warranty
740 * that different fragments will go along one path. --ANK
741 */
742 if (opt->ra) {
743 u8 *ptr = skb->nh.raw + opt->ra;
744 if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3]))
745 return 0;
746 }
747
748 /*
749 * check and decrement ttl
750 */
751 if (hdr->hop_limit <= 1) {
752 /* Force OUTPUT device used as source address */
753 skb->dev = dst->dev;
754 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
755 0, skb->dev);
756
757 kfree_skb(skb);
758 return -ETIMEDOUT;
759 }
760
761 /* IPv6 specs say nothing about it, but it is clear that we cannot
762 send redirects to source routed frames.
763 */
764 if (skb->dev == dst->dev && dst->neighbour && opt->srcrt == 0) {
765 struct in6_addr *target = NULL;
766 struct rt6_info *rt;
767 struct neighbour *n = dst->neighbour;
768
769 /*
770 * incoming and outgoing devices are the same
771 * send a redirect.
772 */
773
774 rt = (struct rt6_info *) dst;
775 if ((rt->rt6i_flags & RTF_GATEWAY))
776 target = (struct in6_addr*)&n->primary_key;
777 else
778 target = &hdr->daddr;
779
780 /* Limit redirects both by destination (here)
781 and by source (inside ndisc_send_redirect)
782 */
783 if (xrlim_allow(dst, 1*HZ))
784 ndisc_send_redirect(skb, n, target);
785 } else if (ipv6_addr_type(&hdr->saddr)&(IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK
786 |IPV6_ADDR_LINKLOCAL)) {
787 /* This check is security critical. */
788 goto drop;
789 }
790
791 if (skb->len > dst->pmtu) {
792 /* Again, force OUTPUT device used as source address */
793 skb->dev = dst->dev;
794 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst->pmtu, skb->dev);
795 IP6_INC_STATS_BH(Ip6InTooBigErrors);
796 kfree_skb(skb);
797 return -EMSGSIZE;
798 }
799
800 if ((skb = skb_cow(skb, dst->dev->hard_header_len)) == NULL)
801 return 0;
802
803 hdr = skb->nh.ipv6h;
804
805 /* Mangling hops number delayed to point after skb COW */
806
807 hdr->hop_limit--;
808
809 IP6_INC_STATS_BH(Ip6OutForwDatagrams);
810 return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish);
811
812 drop:
813 IP6_INC_STATS_BH(Ip6InAddrErrors);
814 kfree_skb(skb);
815 return -EINVAL;
816 }
817
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.