1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <linux/config.h>
29#include <linux/errno.h>
30#include <linux/types.h>
31#include <linux/string.h>
32#include <linux/socket.h>
33#include <linux/net.h>
34#include <linux/netdevice.h>
35#include <linux/if_arp.h>
36#include <linux/in6.h>
37#include <linux/route.h>
38
39#include <linux/netfilter.h>
40#include <linux/netfilter_ipv6.h>
41
42#include <net/sock.h>
43#include <net/snmp.h>
44
45#include <net/ipv6.h>
46#include <net/ndisc.h>
47#include <net/protocol.h>
48#include <net/ip6_route.h>
49#include <net/addrconf.h>
50#include <net/rawv6.h>
51#include <net/icmp.h>
52
53static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *fhdr)
54{
55 static u32 ipv6_fragmentation_id = 1;
56 static spinlock_t ip6_id_lock = SPIN_LOCK_UNLOCKED;
57
58 spin_lock_bh(&ip6_id_lock);
59 fhdr->identification = htonl(ipv6_fragmentation_id);
60 if (++ipv6_fragmentation_id == 0)
61 ipv6_fragmentation_id = 1;
62 spin_unlock_bh(&ip6_id_lock);
63}
64
65static inline int ip6_output_finish(struct sk_buff *skb)
66{
67
68 struct dst_entry *dst = skb->dst;
69 struct hh_cache *hh = dst->hh;
70
71 if (hh) {
72 int hh_alen;
73
74 read_lock_bh(&hh->hh_lock);
75 hh_alen = HH_DATA_ALIGN(hh->hh_len);
76 memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
77 read_unlock_bh(&hh->hh_lock);
78 skb_push(skb, hh->hh_len);
79 return hh->hh_output(skb);
80 } else if (dst->neighbour)
81 return dst->neighbour->output(skb);
82
83 kfree_skb(skb);
84 return -EINVAL;
85
86}
87
88
89static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
90{
91 newskb->mac.raw = newskb->data;
92 __skb_pull(newskb, newskb->nh.raw - newskb->data);
93 newskb->pkt_type = PACKET_LOOPBACK;
94 newskb->ip_summed = CHECKSUM_UNNECESSARY;
95 BUG_TRAP(newskb->dst);
96
97 netif_rx(newskb);
98 return 0;
99}
100
101
102int ip6_output(struct sk_buff *skb)
103{
104 struct dst_entry *dst = skb->dst;
105 struct net_device *dev = dst->dev;
106
107 skb->protocol = htons(ETH_P_IPV6);
108 skb->dev = dev;
109
110 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) {
111 if (!(dev->flags&IFF_LOOPBACK) &&
112 (skb->sk == NULL || skb->sk->net_pinfo.af_inet6.mc_loop) &&
113 ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr,
114 &skb->nh.ipv6h->saddr)) {
115 struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
116
117
118
119
120 if (newskb)
121 NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, newskb, NULL,
122 newskb->dev,
123 ip6_dev_loopback_xmit);
124
125 if (skb->nh.ipv6h->hop_limit == 0) {
126 kfree_skb(skb);
127 return 0;
128 }
129 }
130
131 IP6_INC_STATS(Ip6OutMcastPkts);
132 }
133
134 return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
135}
136
137
138#ifdef CONFIG_NETFILTER
139int ip6_route_me_harder(struct sk_buff *skb)
140{
141 struct ipv6hdr *iph = skb->nh.ipv6h;
142 struct dst_entry *dst;
143 struct flowi fl;
144
145 fl.proto = iph->nexthdr;
146 fl.fl6_dst = &iph->daddr;
147 fl.fl6_src = &iph->saddr;
148 fl.oif = skb->sk ? skb->sk->bound_dev_if : 0;
149 fl.fl6_flowlabel = 0;
150 fl.uli_u.ports.dport = 0;
151 fl.uli_u.ports.sport = 0;
152
153 dst = ip6_route_output(skb->sk, &fl);
154
155 if (dst->error) {
156 if (net_ratelimit())
157 printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
158 dst_release(dst);
159 return -EINVAL;
160 }
161
162
163 dst_release(skb->dst);
164
165 skb->dst = dst;
166 return 0;
167}
168#endif
169
170static inline int ip6_maybe_reroute(struct sk_buff *skb)
171{
172#ifdef CONFIG_NETFILTER
173 if (skb->nfcache & NFC_ALTERED){
174 if (ip6_route_me_harder(skb) != 0){
175 kfree_skb(skb);
176 return -EINVAL;
177 }
178 }
179#endif
180 return skb->dst->output(skb);
181}
182
183
184
185
186
187int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
188 struct ipv6_txoptions *opt)
189{
190 struct ipv6_pinfo * np = sk ? &sk->net_pinfo.af_inet6 : NULL;
191 struct in6_addr *first_hop = fl->nl_u.ip6_u.daddr;
192 struct dst_entry *dst = skb->dst;
193 struct ipv6hdr *hdr;
194 u8 proto = fl->proto;
195 int seg_len = skb->len;
196 int hlimit;
197
198 if (opt) {
199 int head_room;
200
201
202
203
204 head_room = opt->opt_nflen + opt->opt_flen;
205 seg_len += head_room;
206 head_room += sizeof(struct ipv6hdr) + ((dst->dev->hard_header_len + 15)&~15);
207
208 if (skb_headroom(skb) < head_room) {
209 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
210 kfree_skb(skb);
211 skb = skb2;
212 if (skb == NULL)
213 return -ENOBUFS;
214 if (sk)
215 skb_set_owner_w(skb, sk);
216 }
217 if (opt->opt_flen)
218 ipv6_push_frag_opts(skb, opt, &proto);
219 if (opt->opt_nflen)
220 ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop);
221 }
222
223 hdr = skb->nh.ipv6h = (struct ipv6hdr*)skb_push(skb, sizeof(struct ipv6hdr));
224
225
226
227
228
229 *(u32*)hdr = htonl(0x60000000) | fl->fl6_flowlabel;
230 hlimit = -1;
231 if (np)
232 hlimit = np->hop_limit;
233 if (hlimit < 0)
234 hlimit = ((struct rt6_info*)dst)->rt6i_hoplimit;
235
236 hdr->payload_len = htons(seg_len);
237 hdr->nexthdr = proto;
238 hdr->hop_limit = hlimit;
239
240 ipv6_addr_copy(&hdr->saddr, fl->nl_u.ip6_u.saddr);
241 ipv6_addr_copy(&hdr->daddr, first_hop);
242
243 if (skb->len <= dst->pmtu) {
244 IP6_INC_STATS(Ip6OutRequests);
245 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
246 }
247
248 if (net_ratelimit())
249 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
250 skb->dev = dst->dev;
251 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst->pmtu, skb->dev);
252 kfree_skb(skb);
253 return -EMSGSIZE;
254}
255
256
257
258
259
260
261
262
263int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
264 struct in6_addr *saddr, struct in6_addr *daddr,
265 int proto, int len)
266{
267 struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
268 struct ipv6hdr *hdr;
269 int totlen;
270
271 skb->protocol = htons(ETH_P_IPV6);
272 skb->dev = dev;
273
274 totlen = len + sizeof(struct ipv6hdr);
275
276 hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr));
277 skb->nh.ipv6h = hdr;
278
279 *(u32*)hdr = htonl(0x60000000);
280
281 hdr->payload_len = htons(len);
282 hdr->nexthdr = proto;
283 hdr->hop_limit = np->hop_limit;
284
285 ipv6_addr_copy(&hdr->saddr, saddr);
286 ipv6_addr_copy(&hdr->daddr, daddr);
287
288 return 0;
289}
290
291static struct ipv6hdr * ip6_bld_1(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
292 int hlimit, unsigned pktlength)
293{
294 struct ipv6hdr *hdr;
295
296 skb->nh.raw = skb_put(skb, sizeof(struct ipv6hdr));
297 hdr = skb->nh.ipv6h;
298
299 *(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000);
300
301 hdr->payload_len = htons(pktlength - sizeof(struct ipv6hdr));
302 hdr->hop_limit = hlimit;
303 hdr->nexthdr = fl->proto;
304
305 ipv6_addr_copy(&hdr->saddr, fl->nl_u.ip6_u.saddr);
306 ipv6_addr_copy(&hdr->daddr, fl->nl_u.ip6_u.daddr);
307 return hdr;
308}
309
310static __inline__ u8 * ipv6_build_fraghdr(struct sk_buff *skb, u8* prev_hdr, unsigned offset)
311{
312 struct frag_hdr *fhdr;
313
314 fhdr = (struct frag_hdr *) skb_put(skb, sizeof(struct frag_hdr));
315
316 fhdr->nexthdr = *prev_hdr;
317 *prev_hdr = NEXTHDR_FRAGMENT;
318 prev_hdr = &fhdr->nexthdr;
319
320 fhdr->reserved = 0;
321 fhdr->frag_off = htons(offset);
322 ipv6_select_ident(skb, fhdr);
323 return &fhdr->nexthdr;
324}
325
326static int ip6_frag_xmit(struct sock *sk, inet_getfrag_t getfrag,
327 const void *data, struct dst_entry *dst,
328 struct flowi *fl, struct ipv6_txoptions *opt,
329 struct in6_addr *final_dst,
330 int hlimit, int flags, unsigned length, int mtu)
331{
332 struct ipv6hdr *hdr;
333 struct sk_buff *last_skb;
334 u8 *prev_hdr;
335 int unfrag_len;
336 int frag_len;
337 int last_len;
338 int nfrags;
339 int fhdr_dist;
340 int frag_off;
341 int data_off;
342 int err;
343
344
345
346
347
348
349
350
351
352
353
354
355
356 unfrag_len = sizeof(struct ipv6hdr) + sizeof(struct frag_hdr);
357 last_len = length;
358
359 if (opt) {
360 unfrag_len += opt->opt_nflen;
361 last_len += opt->opt_flen;
362 }
363
364
365
366
367
368
369
370 frag_len = (mtu - unfrag_len) & ~0x7;
371
372
373 if (frag_len <= 0) {
374 ipv6_local_error(sk, EMSGSIZE, fl, mtu);
375 return -EMSGSIZE;
376 }
377
378 nfrags = last_len / frag_len;
379
380
381
382
383
384
385
386
387
388
389
390
391 frag_off = nfrags * frag_len;
392 last_len -= frag_off;
393
394 if (last_len == 0) {
395 last_len = frag_len;
396 frag_off -= frag_len;
397 nfrags--;
398 }
399 data_off = frag_off;
400
401
402
403
404 if (opt) {
405 if (frag_len < opt->opt_flen) {
406 ipv6_local_error(sk, EMSGSIZE, fl, mtu);
407 return -EMSGSIZE;
408 }
409 data_off = frag_off - opt->opt_flen;
410 }
411
412 if (flags&MSG_PROBE)
413 return 0;
414
415 last_skb = sock_alloc_send_skb(sk, unfrag_len + frag_len +
416 dst->dev->hard_header_len + 15,
417 flags & MSG_DONTWAIT, &err);
418
419 if (last_skb == NULL)
420 return err;
421
422 last_skb->dst = dst_clone(dst);
423
424 skb_reserve(last_skb, (dst->dev->hard_header_len + 15) & ~15);
425
426 hdr = ip6_bld_1(sk, last_skb, fl, hlimit, frag_len+unfrag_len);
427 prev_hdr = &hdr->nexthdr;
428
429 if (opt && opt->opt_nflen)
430 prev_hdr = ipv6_build_nfrag_opts(last_skb, prev_hdr, opt, final_dst, 0);
431
432 prev_hdr = ipv6_build_fraghdr(last_skb, prev_hdr, frag_off);
433 fhdr_dist = prev_hdr - last_skb->data;
434
435 err = getfrag(data, &hdr->saddr, last_skb->tail, data_off, last_len);
436
437 if (!err) {
438 while (nfrags--) {
439 struct sk_buff *skb;
440
441 struct frag_hdr *fhdr2;
442
443 skb = skb_copy(last_skb, sk->allocation);
444
445 if (skb == NULL) {
446 IP6_INC_STATS(Ip6FragFails);
447 kfree_skb(last_skb);
448 return -ENOMEM;
449 }
450
451 frag_off -= frag_len;
452 data_off -= frag_len;
453
454 fhdr2 = (struct frag_hdr *) (skb->data + fhdr_dist);
455
456
457 fhdr2->frag_off = htons(frag_off | 1);
458
459
460 if (nfrags == 0 && opt && opt->opt_flen) {
461 ipv6_build_frag_opts(skb, &fhdr2->nexthdr, opt);
462 frag_len -= opt->opt_flen;
463 data_off = 0;
464 }
465
466 err = getfrag(data, &hdr->saddr,skb_put(skb, frag_len),
467 data_off, frag_len);
468
469 if (err) {
470 kfree_skb(skb);
471 break;
472 }
473
474 IP6_INC_STATS(Ip6FragCreates);
475 IP6_INC_STATS(Ip6OutRequests);
476 err = NF_HOOK(PF_INET6,NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
477 if (err) {
478 kfree_skb(last_skb);
479 return err;
480 }
481 }
482 }
483
484 if (err) {
485 IP6_INC_STATS(Ip6FragFails);
486 kfree_skb(last_skb);
487 return -EFAULT;
488 }
489
490 hdr->payload_len = htons(unfrag_len + last_len - sizeof(struct ipv6hdr));
491
492
493
494
495
496
497 skb_put(last_skb, last_len);
498
499 IP6_INC_STATS(Ip6FragCreates);
500 IP6_INC_STATS(Ip6FragOKs);
501 IP6_INC_STATS(Ip6OutRequests);
502 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, last_skb, NULL,dst->dev, ip6_maybe_reroute);
503}
504
505int ip6_build_xmit(struct sock *sk, inet_getfrag_t getfrag, const void *data,
506 struct flowi *fl, unsigned length,
507 struct ipv6_txoptions *opt, int hlimit, int flags)
508{
509 struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
510 struct in6_addr *final_dst = NULL;
511 struct dst_entry *dst;
512 int err = 0;
513 unsigned int pktlength, jumbolen, mtu;
514 struct in6_addr saddr;
515
516 if (opt && opt->srcrt) {
517 struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
518 final_dst = fl->fl6_dst;
519 fl->fl6_dst = rt0->addr;
520 }
521
522 if (!fl->oif && ipv6_addr_is_multicast(fl->nl_u.ip6_u.daddr))
523 fl->oif = np->mcast_oif;
524
525 dst = __sk_dst_check(sk, np->dst_cookie);
526 if (dst) {
527 struct rt6_info *rt = (struct rt6_info*)dst;
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547 if (((rt->rt6i_dst.plen != 128 ||
548 ipv6_addr_cmp(fl->fl6_dst, &rt->rt6i_dst.addr))
549 && (np->daddr_cache == NULL ||
550 ipv6_addr_cmp(fl->fl6_dst, np->daddr_cache)))
551 || (fl->oif && fl->oif != dst->dev->ifindex)) {
552 dst = NULL;
553 } else
554 dst_hold(dst);
555 }
556
557 if (dst == NULL)
558 dst = ip6_route_output(sk, fl);
559
560 if (dst->error) {
561 IP6_INC_STATS(Ip6OutNoRoutes);
562 dst_release(dst);
563 return -ENETUNREACH;
564 }
565
566 if (fl->fl6_src == NULL) {
567 err = ipv6_get_saddr(dst, fl->fl6_dst, &saddr);
568
569 if (err) {
570#if IP6_DEBUG >= 2
571 printk(KERN_DEBUG "ip6_build_xmit: "
572 "no available source address\n");
573#endif
574 goto out;
575 }
576 fl->fl6_src = &saddr;
577 }
578 pktlength = length;
579
580 if (hlimit < 0) {
581 if (ipv6_addr_is_multicast(fl->fl6_dst))
582 hlimit = np->mcast_hops;
583 else
584 hlimit = np->hop_limit;
585 if (hlimit < 0)
586 hlimit = ((struct rt6_info*)dst)->rt6i_hoplimit;
587 }
588
589 jumbolen = 0;
590
591 if (!sk->protinfo.af_inet.hdrincl) {
592 pktlength += sizeof(struct ipv6hdr);
593 if (opt)
594 pktlength += opt->opt_flen + opt->opt_nflen;
595
596 if (pktlength > 0xFFFF + sizeof(struct ipv6hdr)) {
597
598
599
600
601 pktlength += 8;
602 jumbolen = pktlength - sizeof(struct ipv6hdr);
603 }
604 }
605
606 mtu = dst->pmtu;
607 if (np->frag_size < mtu) {
608 if (np->frag_size)
609 mtu = np->frag_size;
610 else if (np->pmtudisc == IPV6_PMTUDISC_DONT)
611 mtu = IPV6_MIN_MTU;
612 }
613
614
615
616
617 if (pktlength < length) {
618 ipv6_local_error(sk, EMSGSIZE, fl, mtu);
619 err = -EMSGSIZE;
620 goto out;
621 }
622
623 if (flags&MSG_CONFIRM)
624 dst_confirm(dst);
625
626 if (pktlength <= mtu) {
627 struct sk_buff *skb;
628 struct ipv6hdr *hdr;
629 struct net_device *dev = dst->dev;
630
631 err = 0;
632 if (flags&MSG_PROBE)
633 goto out;
634
635 skb = sock_alloc_send_skb(sk, pktlength + 15 +
636 dev->hard_header_len,
637 flags & MSG_DONTWAIT, &err);
638
639 if (skb == NULL) {
640 IP6_INC_STATS(Ip6OutDiscards);
641 goto out;
642 }
643
644 skb->dst = dst_clone(dst);
645
646 skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
647
648 hdr = (struct ipv6hdr *) skb->tail;
649 skb->nh.ipv6h = hdr;
650
651 if (!sk->protinfo.af_inet.hdrincl) {
652 ip6_bld_1(sk, skb, fl, hlimit,
653 jumbolen ? sizeof(struct ipv6hdr) : pktlength);
654
655 if (opt || jumbolen) {
656 u8 *prev_hdr = &hdr->nexthdr;
657 prev_hdr = ipv6_build_nfrag_opts(skb, prev_hdr, opt, final_dst, jumbolen);
658 if (opt && opt->opt_flen)
659 ipv6_build_frag_opts(skb, prev_hdr, opt);
660 }
661 }
662
663 skb_put(skb, length);
664 err = getfrag(data, &hdr->saddr,
665 ((char *) hdr) + (pktlength - length),
666 0, length);
667
668 if (!err) {
669 IP6_INC_STATS(Ip6OutRequests);
670 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
671 } else {
672 err = -EFAULT;
673 kfree_skb(skb);
674 }
675 } else {
676 if (sk->protinfo.af_inet.hdrincl || jumbolen ||
677 np->pmtudisc == IPV6_PMTUDISC_DO) {
678 ipv6_local_error(sk, EMSGSIZE, fl, mtu);
679 err = -EMSGSIZE;
680 goto out;
681 }
682
683 err = ip6_frag_xmit(sk, getfrag, data, dst, fl, opt, final_dst, hlimit,
684 flags, length, mtu);
685 }
686
687
688
689
690out:
691 ip6_dst_store(sk, dst, fl->nl_u.ip6_u.daddr == &np->daddr ? &np->daddr : NULL);
692 if (err > 0)
693 err = np->recverr ? net_xmit_errno(err) : 0;
694 return err;
695}
696
697int ip6_call_ra_chain(struct sk_buff *skb, int sel)
698{
699 struct ip6_ra_chain *ra;
700 struct sock *last = NULL;
701
702 read_lock(&ip6_ra_lock);
703 for (ra = ip6_ra_chain; ra; ra = ra->next) {
704 struct sock *sk = ra->sk;
705 if (sk && ra->sel == sel) {
706 if (last) {
707 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
708 if (skb2)
709 rawv6_rcv(last, skb2);
710 }
711 last = sk;
712 }
713 }
714
715 if (last) {
716 rawv6_rcv(last, skb);
717 read_unlock(&ip6_ra_lock);
718 return 1;
719 }
720 read_unlock(&ip6_ra_lock);
721 return 0;
722}
723
724static inline int ip6_forward_finish(struct sk_buff *skb)
725{
726 return skb->dst->output(skb);
727}
728
729int ip6_forward(struct sk_buff *skb)
730{
731 struct dst_entry *dst = skb->dst;
732 struct ipv6hdr *hdr = skb->nh.ipv6h;
733 struct inet6_skb_parm *opt =(struct inet6_skb_parm*)skb->cb;
734
735 if (ipv6_devconf.forwarding == 0)
736 goto error;
737
738 skb->ip_summed = CHECKSUM_NONE;
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753 if (opt->ra) {
754 u8 *ptr = skb->nh.raw + opt->ra;
755 if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3]))
756 return 0;
757 }
758
759
760
761
762 if (hdr->hop_limit <= 1) {
763
764 skb->dev = dst->dev;
765 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
766 0, skb->dev);
767
768 kfree_skb(skb);
769 return -ETIMEDOUT;
770 }
771
772
773
774
775 if (skb->dev == dst->dev && dst->neighbour && opt->srcrt == 0) {
776 struct in6_addr *target = NULL;
777 struct rt6_info *rt;
778 struct neighbour *n = dst->neighbour;
779
780
781
782
783
784
785 rt = (struct rt6_info *) dst;
786 if ((rt->rt6i_flags & RTF_GATEWAY))
787 target = (struct in6_addr*)&n->primary_key;
788 else
789 target = &hdr->daddr;
790
791
792
793
794 if (xrlim_allow(dst, 1*HZ))
795 ndisc_send_redirect(skb, n, target);
796 } else if (ipv6_addr_type(&hdr->saddr)&(IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK
797 |IPV6_ADDR_LINKLOCAL)) {
798
799 goto error;
800 }
801
802 if (skb->len > dst->pmtu) {
803
804 skb->dev = dst->dev;
805 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst->pmtu, skb->dev);
806 IP6_INC_STATS_BH(Ip6InTooBigErrors);
807 kfree_skb(skb);
808 return -EMSGSIZE;
809 }
810
811 if (skb_cow(skb, dst->dev->hard_header_len))
812 goto drop;
813
814 hdr = skb->nh.ipv6h;
815
816
817
818 hdr->hop_limit--;
819
820 IP6_INC_STATS_BH(Ip6OutForwDatagrams);
821 return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish);
822
823error:
824 IP6_INC_STATS_BH(Ip6InAddrErrors);
825drop:
826 kfree_skb(skb);
827 return -EINVAL;
828}
829