diff options
Diffstat (limited to 'net/ipv6')
38 files changed, 679 insertions, 728 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 7b6a584b62dd..eea9542728ca 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3982,7 +3982,6 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp, | |||
3982 | } | 3982 | } |
3983 | 3983 | ||
3984 | static int addrconf_sysctl_forward_strategy(ctl_table *table, | 3984 | static int addrconf_sysctl_forward_strategy(ctl_table *table, |
3985 | int __user *name, int nlen, | ||
3986 | void __user *oldval, | 3985 | void __user *oldval, |
3987 | size_t __user *oldlenp, | 3986 | size_t __user *oldlenp, |
3988 | void __user *newval, size_t newlen) | 3987 | void __user *newval, size_t newlen) |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 95055f8c3f35..01edac888510 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <net/ipip.h> | 50 | #include <net/ipip.h> |
51 | #include <net/protocol.h> | 51 | #include <net/protocol.h> |
52 | #include <net/inet_common.h> | 52 | #include <net/inet_common.h> |
53 | #include <net/route.h> | ||
53 | #include <net/transp_v6.h> | 54 | #include <net/transp_v6.h> |
54 | #include <net/ip6_route.h> | 55 | #include <net/ip6_route.h> |
55 | #include <net/addrconf.h> | 56 | #include <net/addrconf.h> |
@@ -794,61 +795,55 @@ static void ipv6_packet_cleanup(void) | |||
794 | dev_remove_pack(&ipv6_packet_type); | 795 | dev_remove_pack(&ipv6_packet_type); |
795 | } | 796 | } |
796 | 797 | ||
797 | static int __init init_ipv6_mibs(void) | 798 | static int __net_init ipv6_init_mibs(struct net *net) |
798 | { | 799 | { |
799 | if (snmp_mib_init((void **)ipv6_statistics, | 800 | if (snmp_mib_init((void **)net->mib.udp_stats_in6, |
801 | sizeof (struct udp_mib)) < 0) | ||
802 | return -ENOMEM; | ||
803 | if (snmp_mib_init((void **)net->mib.udplite_stats_in6, | ||
804 | sizeof (struct udp_mib)) < 0) | ||
805 | goto err_udplite_mib; | ||
806 | if (snmp_mib_init((void **)net->mib.ipv6_statistics, | ||
800 | sizeof(struct ipstats_mib)) < 0) | 807 | sizeof(struct ipstats_mib)) < 0) |
801 | goto err_ip_mib; | 808 | goto err_ip_mib; |
802 | if (snmp_mib_init((void **)icmpv6_statistics, | 809 | if (snmp_mib_init((void **)net->mib.icmpv6_statistics, |
803 | sizeof(struct icmpv6_mib)) < 0) | 810 | sizeof(struct icmpv6_mib)) < 0) |
804 | goto err_icmp_mib; | 811 | goto err_icmp_mib; |
805 | if (snmp_mib_init((void **)icmpv6msg_statistics, | 812 | if (snmp_mib_init((void **)net->mib.icmpv6msg_statistics, |
806 | sizeof(struct icmpv6msg_mib)) < 0) | 813 | sizeof(struct icmpv6msg_mib)) < 0) |
807 | goto err_icmpmsg_mib; | 814 | goto err_icmpmsg_mib; |
808 | if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib)) < 0) | ||
809 | goto err_udp_mib; | ||
810 | if (snmp_mib_init((void **)udplite_stats_in6, | ||
811 | sizeof (struct udp_mib)) < 0) | ||
812 | goto err_udplite_mib; | ||
813 | return 0; | 815 | return 0; |
814 | 816 | ||
815 | err_udplite_mib: | ||
816 | snmp_mib_free((void **)udp_stats_in6); | ||
817 | err_udp_mib: | ||
818 | snmp_mib_free((void **)icmpv6msg_statistics); | ||
819 | err_icmpmsg_mib: | 817 | err_icmpmsg_mib: |
820 | snmp_mib_free((void **)icmpv6_statistics); | 818 | snmp_mib_free((void **)net->mib.icmpv6_statistics); |
821 | err_icmp_mib: | 819 | err_icmp_mib: |
822 | snmp_mib_free((void **)ipv6_statistics); | 820 | snmp_mib_free((void **)net->mib.ipv6_statistics); |
823 | err_ip_mib: | 821 | err_ip_mib: |
822 | snmp_mib_free((void **)net->mib.udplite_stats_in6); | ||
823 | err_udplite_mib: | ||
824 | snmp_mib_free((void **)net->mib.udp_stats_in6); | ||
824 | return -ENOMEM; | 825 | return -ENOMEM; |
825 | |||
826 | } | 826 | } |
827 | 827 | ||
828 | static void cleanup_ipv6_mibs(void) | 828 | static void __net_exit ipv6_cleanup_mibs(struct net *net) |
829 | { | 829 | { |
830 | snmp_mib_free((void **)ipv6_statistics); | 830 | snmp_mib_free((void **)net->mib.udp_stats_in6); |
831 | snmp_mib_free((void **)icmpv6_statistics); | 831 | snmp_mib_free((void **)net->mib.udplite_stats_in6); |
832 | snmp_mib_free((void **)icmpv6msg_statistics); | 832 | snmp_mib_free((void **)net->mib.ipv6_statistics); |
833 | snmp_mib_free((void **)udp_stats_in6); | 833 | snmp_mib_free((void **)net->mib.icmpv6_statistics); |
834 | snmp_mib_free((void **)udplite_stats_in6); | 834 | snmp_mib_free((void **)net->mib.icmpv6msg_statistics); |
835 | } | 835 | } |
836 | 836 | ||
837 | static int inet6_net_init(struct net *net) | 837 | static int __net_init inet6_net_init(struct net *net) |
838 | { | 838 | { |
839 | int err = 0; | 839 | int err = 0; |
840 | 840 | ||
841 | net->ipv6.sysctl.bindv6only = 0; | 841 | net->ipv6.sysctl.bindv6only = 0; |
842 | net->ipv6.sysctl.flush_delay = 0; | ||
843 | net->ipv6.sysctl.ip6_rt_max_size = 4096; | ||
844 | net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2; | ||
845 | net->ipv6.sysctl.ip6_rt_gc_timeout = 60*HZ; | ||
846 | net->ipv6.sysctl.ip6_rt_gc_interval = 30*HZ; | ||
847 | net->ipv6.sysctl.ip6_rt_gc_elasticity = 9; | ||
848 | net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ; | ||
849 | net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; | ||
850 | net->ipv6.sysctl.icmpv6_time = 1*HZ; | 842 | net->ipv6.sysctl.icmpv6_time = 1*HZ; |
851 | 843 | ||
844 | err = ipv6_init_mibs(net); | ||
845 | if (err) | ||
846 | return err; | ||
852 | #ifdef CONFIG_PROC_FS | 847 | #ifdef CONFIG_PROC_FS |
853 | err = udp6_proc_init(net); | 848 | err = udp6_proc_init(net); |
854 | if (err) | 849 | if (err) |
@@ -859,7 +854,6 @@ static int inet6_net_init(struct net *net) | |||
859 | err = ac6_proc_init(net); | 854 | err = ac6_proc_init(net); |
860 | if (err) | 855 | if (err) |
861 | goto proc_ac6_fail; | 856 | goto proc_ac6_fail; |
862 | out: | ||
863 | #endif | 857 | #endif |
864 | return err; | 858 | return err; |
865 | 859 | ||
@@ -868,7 +862,9 @@ proc_ac6_fail: | |||
868 | tcp6_proc_exit(net); | 862 | tcp6_proc_exit(net); |
869 | proc_tcp6_fail: | 863 | proc_tcp6_fail: |
870 | udp6_proc_exit(net); | 864 | udp6_proc_exit(net); |
871 | goto out; | 865 | out: |
866 | ipv6_cleanup_mibs(net); | ||
867 | return err; | ||
872 | #endif | 868 | #endif |
873 | } | 869 | } |
874 | 870 | ||
@@ -879,6 +875,7 @@ static void inet6_net_exit(struct net *net) | |||
879 | tcp6_proc_exit(net); | 875 | tcp6_proc_exit(net); |
880 | ac6_proc_exit(net); | 876 | ac6_proc_exit(net); |
881 | #endif | 877 | #endif |
878 | ipv6_cleanup_mibs(net); | ||
882 | } | 879 | } |
883 | 880 | ||
884 | static struct pernet_operations inet6_net_ops = { | 881 | static struct pernet_operations inet6_net_ops = { |
@@ -929,11 +926,6 @@ static int __init inet6_init(void) | |||
929 | if (err) | 926 | if (err) |
930 | goto out_sock_register_fail; | 927 | goto out_sock_register_fail; |
931 | 928 | ||
932 | /* Initialise ipv6 mibs */ | ||
933 | err = init_ipv6_mibs(); | ||
934 | if (err) | ||
935 | goto out_unregister_sock; | ||
936 | |||
937 | #ifdef CONFIG_SYSCTL | 929 | #ifdef CONFIG_SYSCTL |
938 | err = ipv6_static_sysctl_register(); | 930 | err = ipv6_static_sysctl_register(); |
939 | if (err) | 931 | if (err) |
@@ -1067,8 +1059,6 @@ register_pernet_fail: | |||
1067 | ipv6_static_sysctl_unregister(); | 1059 | ipv6_static_sysctl_unregister(); |
1068 | static_sysctl_fail: | 1060 | static_sysctl_fail: |
1069 | #endif | 1061 | #endif |
1070 | cleanup_ipv6_mibs(); | ||
1071 | out_unregister_sock: | ||
1072 | sock_unregister(PF_INET6); | 1062 | sock_unregister(PF_INET6); |
1073 | rtnl_unregister_all(PF_INET6); | 1063 | rtnl_unregister_all(PF_INET6); |
1074 | out_sock_register_fail: | 1064 | out_sock_register_fail: |
@@ -1125,7 +1115,6 @@ static void __exit inet6_exit(void) | |||
1125 | #ifdef CONFIG_SYSCTL | 1115 | #ifdef CONFIG_SYSCTL |
1126 | ipv6_static_sysctl_unregister(); | 1116 | ipv6_static_sysctl_unregister(); |
1127 | #endif | 1117 | #endif |
1128 | cleanup_ipv6_mibs(); | ||
1129 | proto_unregister(&rawv6_prot); | 1118 | proto_unregister(&rawv6_prot); |
1130 | proto_unregister(&udplitev6_prot); | 1119 | proto_unregister(&udplitev6_prot); |
1131 | proto_unregister(&udpv6_prot); | 1120 | proto_unregister(&udpv6_prot); |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 837c830d6d8e..6bfffec2371c 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -277,7 +277,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) | |||
277 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || | 277 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || |
278 | !pskb_may_pull(skb, (skb_transport_offset(skb) + | 278 | !pskb_may_pull(skb, (skb_transport_offset(skb) + |
279 | ((skb_transport_header(skb)[1] + 1) << 3)))) { | 279 | ((skb_transport_header(skb)[1] + 1) << 3)))) { |
280 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 280 | IP6_INC_STATS_BH(dev_net(skb->dst->dev), ip6_dst_idev(skb->dst), |
281 | IPSTATS_MIB_INHDRERRORS); | 281 | IPSTATS_MIB_INHDRERRORS); |
282 | kfree_skb(skb); | 282 | kfree_skb(skb); |
283 | return -1; | 283 | return -1; |
@@ -301,7 +301,8 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) | |||
301 | return 1; | 301 | return 1; |
302 | } | 302 | } |
303 | 303 | ||
304 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); | 304 | IP6_INC_STATS_BH(dev_net(dst->dev), |
305 | ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); | ||
305 | dst_release(dst); | 306 | dst_release(dst); |
306 | return -1; | 307 | return -1; |
307 | } | 308 | } |
@@ -319,7 +320,8 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) | |||
319 | int n, i; | 320 | int n, i; |
320 | struct ipv6_rt_hdr *hdr; | 321 | struct ipv6_rt_hdr *hdr; |
321 | struct rt0_hdr *rthdr; | 322 | struct rt0_hdr *rthdr; |
322 | int accept_source_route = dev_net(skb->dev)->ipv6.devconf_all->accept_source_route; | 323 | struct net *net = dev_net(skb->dev); |
324 | int accept_source_route = net->ipv6.devconf_all->accept_source_route; | ||
323 | 325 | ||
324 | idev = in6_dev_get(skb->dev); | 326 | idev = in6_dev_get(skb->dev); |
325 | if (idev) { | 327 | if (idev) { |
@@ -331,7 +333,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) | |||
331 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || | 333 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || |
332 | !pskb_may_pull(skb, (skb_transport_offset(skb) + | 334 | !pskb_may_pull(skb, (skb_transport_offset(skb) + |
333 | ((skb_transport_header(skb)[1] + 1) << 3)))) { | 335 | ((skb_transport_header(skb)[1] + 1) << 3)))) { |
334 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 336 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
335 | IPSTATS_MIB_INHDRERRORS); | 337 | IPSTATS_MIB_INHDRERRORS); |
336 | kfree_skb(skb); | 338 | kfree_skb(skb); |
337 | return -1; | 339 | return -1; |
@@ -341,7 +343,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) | |||
341 | 343 | ||
342 | if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) || | 344 | if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) || |
343 | skb->pkt_type != PACKET_HOST) { | 345 | skb->pkt_type != PACKET_HOST) { |
344 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 346 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
345 | IPSTATS_MIB_INADDRERRORS); | 347 | IPSTATS_MIB_INADDRERRORS); |
346 | kfree_skb(skb); | 348 | kfree_skb(skb); |
347 | return -1; | 349 | return -1; |
@@ -356,7 +358,7 @@ looped_back: | |||
356 | * processed by own | 358 | * processed by own |
357 | */ | 359 | */ |
358 | if (!addr) { | 360 | if (!addr) { |
359 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 361 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
360 | IPSTATS_MIB_INADDRERRORS); | 362 | IPSTATS_MIB_INADDRERRORS); |
361 | kfree_skb(skb); | 363 | kfree_skb(skb); |
362 | return -1; | 364 | return -1; |
@@ -382,7 +384,7 @@ looped_back: | |||
382 | goto unknown_rh; | 384 | goto unknown_rh; |
383 | /* Silently discard invalid RTH type 2 */ | 385 | /* Silently discard invalid RTH type 2 */ |
384 | if (hdr->hdrlen != 2 || hdr->segments_left != 1) { | 386 | if (hdr->hdrlen != 2 || hdr->segments_left != 1) { |
385 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 387 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
386 | IPSTATS_MIB_INHDRERRORS); | 388 | IPSTATS_MIB_INHDRERRORS); |
387 | kfree_skb(skb); | 389 | kfree_skb(skb); |
388 | return -1; | 390 | return -1; |
@@ -401,7 +403,7 @@ looped_back: | |||
401 | n = hdr->hdrlen >> 1; | 403 | n = hdr->hdrlen >> 1; |
402 | 404 | ||
403 | if (hdr->segments_left > n) { | 405 | if (hdr->segments_left > n) { |
404 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 406 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
405 | IPSTATS_MIB_INHDRERRORS); | 407 | IPSTATS_MIB_INHDRERRORS); |
406 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, | 408 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, |
407 | ((&hdr->segments_left) - | 409 | ((&hdr->segments_left) - |
@@ -415,7 +417,7 @@ looped_back: | |||
415 | if (skb_cloned(skb)) { | 417 | if (skb_cloned(skb)) { |
416 | /* the copy is a forwarded packet */ | 418 | /* the copy is a forwarded packet */ |
417 | if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { | 419 | if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { |
418 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 420 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
419 | IPSTATS_MIB_OUTDISCARDS); | 421 | IPSTATS_MIB_OUTDISCARDS); |
420 | kfree_skb(skb); | 422 | kfree_skb(skb); |
421 | return -1; | 423 | return -1; |
@@ -438,13 +440,13 @@ looped_back: | |||
438 | if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, | 440 | if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, |
439 | (xfrm_address_t *)&ipv6_hdr(skb)->saddr, | 441 | (xfrm_address_t *)&ipv6_hdr(skb)->saddr, |
440 | IPPROTO_ROUTING) < 0) { | 442 | IPPROTO_ROUTING) < 0) { |
441 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 443 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
442 | IPSTATS_MIB_INADDRERRORS); | 444 | IPSTATS_MIB_INADDRERRORS); |
443 | kfree_skb(skb); | 445 | kfree_skb(skb); |
444 | return -1; | 446 | return -1; |
445 | } | 447 | } |
446 | if (!ipv6_chk_home_addr(dev_net(skb->dst->dev), addr)) { | 448 | if (!ipv6_chk_home_addr(dev_net(skb->dst->dev), addr)) { |
447 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 449 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
448 | IPSTATS_MIB_INADDRERRORS); | 450 | IPSTATS_MIB_INADDRERRORS); |
449 | kfree_skb(skb); | 451 | kfree_skb(skb); |
450 | return -1; | 452 | return -1; |
@@ -456,7 +458,7 @@ looped_back: | |||
456 | } | 458 | } |
457 | 459 | ||
458 | if (ipv6_addr_is_multicast(addr)) { | 460 | if (ipv6_addr_is_multicast(addr)) { |
459 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 461 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
460 | IPSTATS_MIB_INADDRERRORS); | 462 | IPSTATS_MIB_INADDRERRORS); |
461 | kfree_skb(skb); | 463 | kfree_skb(skb); |
462 | return -1; | 464 | return -1; |
@@ -476,7 +478,7 @@ looped_back: | |||
476 | 478 | ||
477 | if (skb->dst->dev->flags&IFF_LOOPBACK) { | 479 | if (skb->dst->dev->flags&IFF_LOOPBACK) { |
478 | if (ipv6_hdr(skb)->hop_limit <= 1) { | 480 | if (ipv6_hdr(skb)->hop_limit <= 1) { |
479 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 481 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
480 | IPSTATS_MIB_INHDRERRORS); | 482 | IPSTATS_MIB_INHDRERRORS); |
481 | icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, | 483 | icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, |
482 | 0, skb->dev); | 484 | 0, skb->dev); |
@@ -492,7 +494,7 @@ looped_back: | |||
492 | return -1; | 494 | return -1; |
493 | 495 | ||
494 | unknown_rh: | 496 | unknown_rh: |
495 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); | 497 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); |
496 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, | 498 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, |
497 | (&hdr->type) - skb_network_header(skb)); | 499 | (&hdr->type) - skb_network_header(skb)); |
498 | return -1; | 500 | return -1; |
@@ -579,29 +581,33 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff) | |||
579 | { | 581 | { |
580 | const unsigned char *nh = skb_network_header(skb); | 582 | const unsigned char *nh = skb_network_header(skb); |
581 | u32 pkt_len; | 583 | u32 pkt_len; |
584 | struct net *net = dev_net(skb->dst->dev); | ||
582 | 585 | ||
583 | if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { | 586 | if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { |
584 | LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", | 587 | LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", |
585 | nh[optoff+1]); | 588 | nh[optoff+1]); |
586 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), | 589 | IP6_INC_STATS_BH(net, ipv6_skb_idev(skb), |
587 | IPSTATS_MIB_INHDRERRORS); | 590 | IPSTATS_MIB_INHDRERRORS); |
588 | goto drop; | 591 | goto drop; |
589 | } | 592 | } |
590 | 593 | ||
591 | pkt_len = ntohl(*(__be32 *)(nh + optoff + 2)); | 594 | pkt_len = ntohl(*(__be32 *)(nh + optoff + 2)); |
592 | if (pkt_len <= IPV6_MAXPLEN) { | 595 | if (pkt_len <= IPV6_MAXPLEN) { |
593 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); | 596 | IP6_INC_STATS_BH(net, ipv6_skb_idev(skb), |
597 | IPSTATS_MIB_INHDRERRORS); | ||
594 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); | 598 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); |
595 | return 0; | 599 | return 0; |
596 | } | 600 | } |
597 | if (ipv6_hdr(skb)->payload_len) { | 601 | if (ipv6_hdr(skb)->payload_len) { |
598 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); | 602 | IP6_INC_STATS_BH(net, ipv6_skb_idev(skb), |
603 | IPSTATS_MIB_INHDRERRORS); | ||
599 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); | 604 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); |
600 | return 0; | 605 | return 0; |
601 | } | 606 | } |
602 | 607 | ||
603 | if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { | 608 | if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { |
604 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INTRUNCATEDPKTS); | 609 | IP6_INC_STATS_BH(net, ipv6_skb_idev(skb), |
610 | IPSTATS_MIB_INTRUNCATEDPKTS); | ||
605 | goto drop; | 611 | goto drop; |
606 | } | 612 | } |
607 | 613 | ||
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index b3157a0cc15d..9b7d19ae5ced 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -183,7 +183,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type, | |||
183 | */ | 183 | */ |
184 | dst = ip6_route_output(net, sk, fl); | 184 | dst = ip6_route_output(net, sk, fl); |
185 | if (dst->error) { | 185 | if (dst->error) { |
186 | IP6_INC_STATS(ip6_dst_idev(dst), | 186 | IP6_INC_STATS(net, ip6_dst_idev(dst), |
187 | IPSTATS_MIB_OUTNOROUTES); | 187 | IPSTATS_MIB_OUTNOROUTES); |
188 | } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) { | 188 | } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) { |
189 | res = 1; | 189 | res = 1; |
@@ -664,7 +664,7 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
664 | skb_set_network_header(skb, nh); | 664 | skb_set_network_header(skb, nh); |
665 | } | 665 | } |
666 | 666 | ||
667 | ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INMSGS); | 667 | ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INMSGS); |
668 | 668 | ||
669 | saddr = &ipv6_hdr(skb)->saddr; | 669 | saddr = &ipv6_hdr(skb)->saddr; |
670 | daddr = &ipv6_hdr(skb)->daddr; | 670 | daddr = &ipv6_hdr(skb)->daddr; |
@@ -693,7 +693,7 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
693 | 693 | ||
694 | type = hdr->icmp6_type; | 694 | type = hdr->icmp6_type; |
695 | 695 | ||
696 | ICMP6MSGIN_INC_STATS_BH(idev, type); | 696 | ICMP6MSGIN_INC_STATS_BH(dev_net(dev), idev, type); |
697 | 697 | ||
698 | switch (type) { | 698 | switch (type) { |
699 | case ICMPV6_ECHO_REQUEST: | 699 | case ICMPV6_ECHO_REQUEST: |
@@ -772,7 +772,7 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
772 | return 0; | 772 | return 0; |
773 | 773 | ||
774 | discard_it: | 774 | discard_it: |
775 | ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INERRORS); | 775 | ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INERRORS); |
776 | drop_no_count: | 776 | drop_no_count: |
777 | kfree_skb(skb); | 777 | kfree_skb(skb); |
778 | return 0; | 778 | return 0; |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 7e14cccd0561..936f48946e20 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
@@ -59,6 +59,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
59 | struct ipv6hdr *hdr; | 59 | struct ipv6hdr *hdr; |
60 | u32 pkt_len; | 60 | u32 pkt_len; |
61 | struct inet6_dev *idev; | 61 | struct inet6_dev *idev; |
62 | struct net *net = dev_net(skb->dev); | ||
62 | 63 | ||
63 | if (skb->pkt_type == PACKET_OTHERHOST) { | 64 | if (skb->pkt_type == PACKET_OTHERHOST) { |
64 | kfree_skb(skb); | 65 | kfree_skb(skb); |
@@ -69,11 +70,11 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
69 | 70 | ||
70 | idev = __in6_dev_get(skb->dev); | 71 | idev = __in6_dev_get(skb->dev); |
71 | 72 | ||
72 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INRECEIVES); | 73 | IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INRECEIVES); |
73 | 74 | ||
74 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL || | 75 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL || |
75 | !idev || unlikely(idev->cnf.disable_ipv6)) { | 76 | !idev || unlikely(idev->cnf.disable_ipv6)) { |
76 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS); | 77 | IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDISCARDS); |
77 | rcu_read_unlock(); | 78 | rcu_read_unlock(); |
78 | goto out; | 79 | goto out; |
79 | } | 80 | } |
@@ -118,11 +119,12 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
118 | /* pkt_len may be zero if Jumbo payload option is present */ | 119 | /* pkt_len may be zero if Jumbo payload option is present */ |
119 | if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) { | 120 | if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) { |
120 | if (pkt_len + sizeof(struct ipv6hdr) > skb->len) { | 121 | if (pkt_len + sizeof(struct ipv6hdr) > skb->len) { |
121 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INTRUNCATEDPKTS); | 122 | IP6_INC_STATS_BH(net, |
123 | idev, IPSTATS_MIB_INTRUNCATEDPKTS); | ||
122 | goto drop; | 124 | goto drop; |
123 | } | 125 | } |
124 | if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) { | 126 | if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) { |
125 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); | 127 | IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INHDRERRORS); |
126 | goto drop; | 128 | goto drop; |
127 | } | 129 | } |
128 | hdr = ipv6_hdr(skb); | 130 | hdr = ipv6_hdr(skb); |
@@ -130,7 +132,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
130 | 132 | ||
131 | if (hdr->nexthdr == NEXTHDR_HOP) { | 133 | if (hdr->nexthdr == NEXTHDR_HOP) { |
132 | if (ipv6_parse_hopopts(skb) < 0) { | 134 | if (ipv6_parse_hopopts(skb) < 0) { |
133 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); | 135 | IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INHDRERRORS); |
134 | rcu_read_unlock(); | 136 | rcu_read_unlock(); |
135 | return 0; | 137 | return 0; |
136 | } | 138 | } |
@@ -141,7 +143,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
141 | return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL, | 143 | return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL, |
142 | ip6_rcv_finish); | 144 | ip6_rcv_finish); |
143 | err: | 145 | err: |
144 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); | 146 | IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INHDRERRORS); |
145 | drop: | 147 | drop: |
146 | rcu_read_unlock(); | 148 | rcu_read_unlock(); |
147 | kfree_skb(skb); | 149 | kfree_skb(skb); |
@@ -161,6 +163,7 @@ static int ip6_input_finish(struct sk_buff *skb) | |||
161 | int nexthdr, raw; | 163 | int nexthdr, raw; |
162 | u8 hash; | 164 | u8 hash; |
163 | struct inet6_dev *idev; | 165 | struct inet6_dev *idev; |
166 | struct net *net = dev_net(skb->dst->dev); | ||
164 | 167 | ||
165 | /* | 168 | /* |
166 | * Parse extension headers | 169 | * Parse extension headers |
@@ -205,24 +208,25 @@ resubmit: | |||
205 | if (ret > 0) | 208 | if (ret > 0) |
206 | goto resubmit; | 209 | goto resubmit; |
207 | else if (ret == 0) | 210 | else if (ret == 0) |
208 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS); | 211 | IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS); |
209 | } else { | 212 | } else { |
210 | if (!raw) { | 213 | if (!raw) { |
211 | if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 214 | if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
212 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INUNKNOWNPROTOS); | 215 | IP6_INC_STATS_BH(net, idev, |
216 | IPSTATS_MIB_INUNKNOWNPROTOS); | ||
213 | icmpv6_send(skb, ICMPV6_PARAMPROB, | 217 | icmpv6_send(skb, ICMPV6_PARAMPROB, |
214 | ICMPV6_UNK_NEXTHDR, nhoff, | 218 | ICMPV6_UNK_NEXTHDR, nhoff, |
215 | skb->dev); | 219 | skb->dev); |
216 | } | 220 | } |
217 | } else | 221 | } else |
218 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS); | 222 | IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS); |
219 | kfree_skb(skb); | 223 | kfree_skb(skb); |
220 | } | 224 | } |
221 | rcu_read_unlock(); | 225 | rcu_read_unlock(); |
222 | return 0; | 226 | return 0; |
223 | 227 | ||
224 | discard: | 228 | discard: |
225 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS); | 229 | IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDISCARDS); |
226 | rcu_read_unlock(); | 230 | rcu_read_unlock(); |
227 | kfree_skb(skb); | 231 | kfree_skb(skb); |
228 | return 0; | 232 | return 0; |
@@ -240,7 +244,8 @@ int ip6_mc_input(struct sk_buff *skb) | |||
240 | struct ipv6hdr *hdr; | 244 | struct ipv6hdr *hdr; |
241 | int deliver; | 245 | int deliver; |
242 | 246 | ||
243 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); | 247 | IP6_INC_STATS_BH(dev_net(skb->dst->dev), |
248 | ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); | ||
244 | 249 | ||
245 | hdr = ipv6_hdr(skb); | 250 | hdr = ipv6_hdr(skb); |
246 | deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); | 251 | deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 0e844c2736a7..c77db0b95e26 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -103,7 +103,8 @@ static int ip6_output_finish(struct sk_buff *skb) | |||
103 | else if (dst->neighbour) | 103 | else if (dst->neighbour) |
104 | return dst->neighbour->output(skb); | 104 | return dst->neighbour->output(skb); |
105 | 105 | ||
106 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | 106 | IP6_INC_STATS_BH(dev_net(dst->dev), |
107 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | ||
107 | kfree_skb(skb); | 108 | kfree_skb(skb); |
108 | return -EINVAL; | 109 | return -EINVAL; |
109 | 110 | ||
@@ -150,13 +151,14 @@ static int ip6_output2(struct sk_buff *skb) | |||
150 | ip6_dev_loopback_xmit); | 151 | ip6_dev_loopback_xmit); |
151 | 152 | ||
152 | if (ipv6_hdr(skb)->hop_limit == 0) { | 153 | if (ipv6_hdr(skb)->hop_limit == 0) { |
153 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); | 154 | IP6_INC_STATS(dev_net(dev), idev, |
155 | IPSTATS_MIB_OUTDISCARDS); | ||
154 | kfree_skb(skb); | 156 | kfree_skb(skb); |
155 | return 0; | 157 | return 0; |
156 | } | 158 | } |
157 | } | 159 | } |
158 | 160 | ||
159 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS); | 161 | IP6_INC_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCASTPKTS); |
160 | } | 162 | } |
161 | 163 | ||
162 | return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev, | 164 | return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev, |
@@ -175,7 +177,8 @@ int ip6_output(struct sk_buff *skb) | |||
175 | { | 177 | { |
176 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); | 178 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); |
177 | if (unlikely(idev->cnf.disable_ipv6)) { | 179 | if (unlikely(idev->cnf.disable_ipv6)) { |
178 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); | 180 | IP6_INC_STATS(dev_net(skb->dst->dev), idev, |
181 | IPSTATS_MIB_OUTDISCARDS); | ||
179 | kfree_skb(skb); | 182 | kfree_skb(skb); |
180 | return 0; | 183 | return 0; |
181 | } | 184 | } |
@@ -194,6 +197,7 @@ int ip6_output(struct sk_buff *skb) | |||
194 | int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | 197 | int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, |
195 | struct ipv6_txoptions *opt, int ipfragok) | 198 | struct ipv6_txoptions *opt, int ipfragok) |
196 | { | 199 | { |
200 | struct net *net = sock_net(sk); | ||
197 | struct ipv6_pinfo *np = inet6_sk(sk); | 201 | struct ipv6_pinfo *np = inet6_sk(sk); |
198 | struct in6_addr *first_hop = &fl->fl6_dst; | 202 | struct in6_addr *first_hop = &fl->fl6_dst; |
199 | struct dst_entry *dst = skb->dst; | 203 | struct dst_entry *dst = skb->dst; |
@@ -216,7 +220,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
216 | if (skb_headroom(skb) < head_room) { | 220 | if (skb_headroom(skb) < head_room) { |
217 | struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); | 221 | struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); |
218 | if (skb2 == NULL) { | 222 | if (skb2 == NULL) { |
219 | IP6_INC_STATS(ip6_dst_idev(skb->dst), | 223 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), |
220 | IPSTATS_MIB_OUTDISCARDS); | 224 | IPSTATS_MIB_OUTDISCARDS); |
221 | kfree_skb(skb); | 225 | kfree_skb(skb); |
222 | return -ENOBUFS; | 226 | return -ENOBUFS; |
@@ -270,7 +274,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
270 | 274 | ||
271 | mtu = dst_mtu(dst); | 275 | mtu = dst_mtu(dst); |
272 | if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { | 276 | if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { |
273 | IP6_INC_STATS(ip6_dst_idev(skb->dst), | 277 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), |
274 | IPSTATS_MIB_OUTREQUESTS); | 278 | IPSTATS_MIB_OUTREQUESTS); |
275 | return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, | 279 | return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, |
276 | dst_output); | 280 | dst_output); |
@@ -280,7 +284,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
280 | printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); | 284 | printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); |
281 | skb->dev = dst->dev; | 285 | skb->dev = dst->dev; |
282 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); | 286 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); |
283 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); | 287 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); |
284 | kfree_skb(skb); | 288 | kfree_skb(skb); |
285 | return -EMSGSIZE; | 289 | return -EMSGSIZE; |
286 | } | 290 | } |
@@ -422,7 +426,7 @@ int ip6_forward(struct sk_buff *skb) | |||
422 | goto drop; | 426 | goto drop; |
423 | 427 | ||
424 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { | 428 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { |
425 | IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); | 429 | IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); |
426 | goto drop; | 430 | goto drop; |
427 | } | 431 | } |
428 | 432 | ||
@@ -455,7 +459,8 @@ int ip6_forward(struct sk_buff *skb) | |||
455 | skb->dev = dst->dev; | 459 | skb->dev = dst->dev; |
456 | icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, | 460 | icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, |
457 | 0, skb->dev); | 461 | 0, skb->dev); |
458 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); | 462 | IP6_INC_STATS_BH(net, |
463 | ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); | ||
459 | 464 | ||
460 | kfree_skb(skb); | 465 | kfree_skb(skb); |
461 | return -ETIMEDOUT; | 466 | return -ETIMEDOUT; |
@@ -468,13 +473,14 @@ int ip6_forward(struct sk_buff *skb) | |||
468 | if (proxied > 0) | 473 | if (proxied > 0) |
469 | return ip6_input(skb); | 474 | return ip6_input(skb); |
470 | else if (proxied < 0) { | 475 | else if (proxied < 0) { |
471 | IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); | 476 | IP6_INC_STATS(net, ip6_dst_idev(dst), |
477 | IPSTATS_MIB_INDISCARDS); | ||
472 | goto drop; | 478 | goto drop; |
473 | } | 479 | } |
474 | } | 480 | } |
475 | 481 | ||
476 | if (!xfrm6_route_forward(skb)) { | 482 | if (!xfrm6_route_forward(skb)) { |
477 | IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); | 483 | IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); |
478 | goto drop; | 484 | goto drop; |
479 | } | 485 | } |
480 | dst = skb->dst; | 486 | dst = skb->dst; |
@@ -523,14 +529,16 @@ int ip6_forward(struct sk_buff *skb) | |||
523 | /* Again, force OUTPUT device used as source address */ | 529 | /* Again, force OUTPUT device used as source address */ |
524 | skb->dev = dst->dev; | 530 | skb->dev = dst->dev; |
525 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); | 531 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); |
526 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); | 532 | IP6_INC_STATS_BH(net, |
527 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS); | 533 | ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); |
534 | IP6_INC_STATS_BH(net, | ||
535 | ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS); | ||
528 | kfree_skb(skb); | 536 | kfree_skb(skb); |
529 | return -EMSGSIZE; | 537 | return -EMSGSIZE; |
530 | } | 538 | } |
531 | 539 | ||
532 | if (skb_cow(skb, dst->dev->hard_header_len)) { | 540 | if (skb_cow(skb, dst->dev->hard_header_len)) { |
533 | IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS); | 541 | IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS); |
534 | goto drop; | 542 | goto drop; |
535 | } | 543 | } |
536 | 544 | ||
@@ -540,12 +548,12 @@ int ip6_forward(struct sk_buff *skb) | |||
540 | 548 | ||
541 | hdr->hop_limit--; | 549 | hdr->hop_limit--; |
542 | 550 | ||
543 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS); | 551 | IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS); |
544 | return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dst->dev, | 552 | return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dst->dev, |
545 | ip6_forward_finish); | 553 | ip6_forward_finish); |
546 | 554 | ||
547 | error: | 555 | error: |
548 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS); | 556 | IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS); |
549 | drop: | 557 | drop: |
550 | kfree_skb(skb); | 558 | kfree_skb(skb); |
551 | return -EINVAL; | 559 | return -EINVAL; |
@@ -613,7 +621,6 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) | |||
613 | 621 | ||
614 | static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | 622 | static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
615 | { | 623 | { |
616 | struct net_device *dev; | ||
617 | struct sk_buff *frag; | 624 | struct sk_buff *frag; |
618 | struct rt6_info *rt = (struct rt6_info*)skb->dst; | 625 | struct rt6_info *rt = (struct rt6_info*)skb->dst; |
619 | struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; | 626 | struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; |
@@ -623,8 +630,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
623 | __be32 frag_id = 0; | 630 | __be32 frag_id = 0; |
624 | int ptr, offset = 0, err=0; | 631 | int ptr, offset = 0, err=0; |
625 | u8 *prevhdr, nexthdr = 0; | 632 | u8 *prevhdr, nexthdr = 0; |
633 | struct net *net = dev_net(skb->dst->dev); | ||
626 | 634 | ||
627 | dev = rt->u.dst.dev; | ||
628 | hlen = ip6_find_1stfragopt(skb, &prevhdr); | 635 | hlen = ip6_find_1stfragopt(skb, &prevhdr); |
629 | nexthdr = *prevhdr; | 636 | nexthdr = *prevhdr; |
630 | 637 | ||
@@ -637,7 +644,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
637 | if (!skb->local_df) { | 644 | if (!skb->local_df) { |
638 | skb->dev = skb->dst->dev; | 645 | skb->dev = skb->dst->dev; |
639 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); | 646 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); |
640 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); | 647 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), |
648 | IPSTATS_MIB_FRAGFAILS); | ||
641 | kfree_skb(skb); | 649 | kfree_skb(skb); |
642 | return -EMSGSIZE; | 650 | return -EMSGSIZE; |
643 | } | 651 | } |
@@ -686,7 +694,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
686 | *prevhdr = NEXTHDR_FRAGMENT; | 694 | *prevhdr = NEXTHDR_FRAGMENT; |
687 | tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); | 695 | tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); |
688 | if (!tmp_hdr) { | 696 | if (!tmp_hdr) { |
689 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); | 697 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), |
698 | IPSTATS_MIB_FRAGFAILS); | ||
690 | return -ENOMEM; | 699 | return -ENOMEM; |
691 | } | 700 | } |
692 | 701 | ||
@@ -737,7 +746,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
737 | 746 | ||
738 | err = output(skb); | 747 | err = output(skb); |
739 | if(!err) | 748 | if(!err) |
740 | IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGCREATES); | 749 | IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst), |
750 | IPSTATS_MIB_FRAGCREATES); | ||
741 | 751 | ||
742 | if (err || !frag) | 752 | if (err || !frag) |
743 | break; | 753 | break; |
@@ -750,7 +760,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
750 | kfree(tmp_hdr); | 760 | kfree(tmp_hdr); |
751 | 761 | ||
752 | if (err == 0) { | 762 | if (err == 0) { |
753 | IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGOKS); | 763 | IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst), |
764 | IPSTATS_MIB_FRAGOKS); | ||
754 | dst_release(&rt->u.dst); | 765 | dst_release(&rt->u.dst); |
755 | return 0; | 766 | return 0; |
756 | } | 767 | } |
@@ -761,7 +772,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
761 | frag = skb; | 772 | frag = skb; |
762 | } | 773 | } |
763 | 774 | ||
764 | IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGFAILS); | 775 | IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst), |
776 | IPSTATS_MIB_FRAGFAILS); | ||
765 | dst_release(&rt->u.dst); | 777 | dst_release(&rt->u.dst); |
766 | return err; | 778 | return err; |
767 | } | 779 | } |
@@ -795,7 +807,7 @@ slow_path: | |||
795 | 807 | ||
796 | if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { | 808 | if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { |
797 | NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); | 809 | NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); |
798 | IP6_INC_STATS(ip6_dst_idev(skb->dst), | 810 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), |
799 | IPSTATS_MIB_FRAGFAILS); | 811 | IPSTATS_MIB_FRAGFAILS); |
800 | err = -ENOMEM; | 812 | err = -ENOMEM; |
801 | goto fail; | 813 | goto fail; |
@@ -859,15 +871,16 @@ slow_path: | |||
859 | if (err) | 871 | if (err) |
860 | goto fail; | 872 | goto fail; |
861 | 873 | ||
862 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGCREATES); | 874 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), |
875 | IPSTATS_MIB_FRAGCREATES); | ||
863 | } | 876 | } |
864 | IP6_INC_STATS(ip6_dst_idev(skb->dst), | 877 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), |
865 | IPSTATS_MIB_FRAGOKS); | 878 | IPSTATS_MIB_FRAGOKS); |
866 | kfree_skb(skb); | 879 | kfree_skb(skb); |
867 | return err; | 880 | return err; |
868 | 881 | ||
869 | fail: | 882 | fail: |
870 | IP6_INC_STATS(ip6_dst_idev(skb->dst), | 883 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), |
871 | IPSTATS_MIB_FRAGFAILS); | 884 | IPSTATS_MIB_FRAGFAILS); |
872 | kfree_skb(skb); | 885 | kfree_skb(skb); |
873 | return err; | 886 | return err; |
@@ -943,46 +956,46 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
943 | } | 956 | } |
944 | 957 | ||
945 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | 958 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD |
946 | /* | 959 | /* |
947 | * Here if the dst entry we've looked up | 960 | * Here if the dst entry we've looked up |
948 | * has a neighbour entry that is in the INCOMPLETE | 961 | * has a neighbour entry that is in the INCOMPLETE |
949 | * state and the src address from the flow is | 962 | * state and the src address from the flow is |
950 | * marked as OPTIMISTIC, we release the found | 963 | * marked as OPTIMISTIC, we release the found |
951 | * dst entry and replace it instead with the | 964 | * dst entry and replace it instead with the |
952 | * dst entry of the nexthop router | 965 | * dst entry of the nexthop router |
953 | */ | 966 | */ |
954 | if (!((*dst)->neighbour->nud_state & NUD_VALID)) { | 967 | if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) { |
955 | struct inet6_ifaddr *ifp; | 968 | struct inet6_ifaddr *ifp; |
956 | struct flowi fl_gw; | 969 | struct flowi fl_gw; |
957 | int redirect; | 970 | int redirect; |
958 | 971 | ||
959 | ifp = ipv6_get_ifaddr(net, &fl->fl6_src, | 972 | ifp = ipv6_get_ifaddr(net, &fl->fl6_src, |
960 | (*dst)->dev, 1); | 973 | (*dst)->dev, 1); |
961 | 974 | ||
962 | redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); | 975 | redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); |
963 | if (ifp) | 976 | if (ifp) |
964 | in6_ifa_put(ifp); | 977 | in6_ifa_put(ifp); |
965 | 978 | ||
966 | if (redirect) { | 979 | if (redirect) { |
967 | /* | 980 | /* |
968 | * We need to get the dst entry for the | 981 | * We need to get the dst entry for the |
969 | * default router instead | 982 | * default router instead |
970 | */ | 983 | */ |
971 | dst_release(*dst); | 984 | dst_release(*dst); |
972 | memcpy(&fl_gw, fl, sizeof(struct flowi)); | 985 | memcpy(&fl_gw, fl, sizeof(struct flowi)); |
973 | memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); | 986 | memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); |
974 | *dst = ip6_route_output(net, sk, &fl_gw); | 987 | *dst = ip6_route_output(net, sk, &fl_gw); |
975 | if ((err = (*dst)->error)) | 988 | if ((err = (*dst)->error)) |
976 | goto out_err_release; | 989 | goto out_err_release; |
977 | } | ||
978 | } | 990 | } |
991 | } | ||
979 | #endif | 992 | #endif |
980 | 993 | ||
981 | return 0; | 994 | return 0; |
982 | 995 | ||
983 | out_err_release: | 996 | out_err_release: |
984 | if (err == -ENETUNREACH) | 997 | if (err == -ENETUNREACH) |
985 | IP6_INC_STATS_BH(NULL, IPSTATS_MIB_OUTNOROUTES); | 998 | IP6_INC_STATS_BH(net, NULL, IPSTATS_MIB_OUTNOROUTES); |
986 | dst_release(*dst); | 999 | dst_release(*dst); |
987 | *dst = NULL; | 1000 | *dst = NULL; |
988 | return err; | 1001 | return err; |
@@ -1387,7 +1400,7 @@ alloc_new_skb: | |||
1387 | return 0; | 1400 | return 0; |
1388 | error: | 1401 | error: |
1389 | inet->cork.length -= length; | 1402 | inet->cork.length -= length; |
1390 | IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); | 1403 | IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); |
1391 | return err; | 1404 | return err; |
1392 | } | 1405 | } |
1393 | 1406 | ||
@@ -1411,6 +1424,7 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1411 | struct in6_addr final_dst_buf, *final_dst = &final_dst_buf; | 1424 | struct in6_addr final_dst_buf, *final_dst = &final_dst_buf; |
1412 | struct inet_sock *inet = inet_sk(sk); | 1425 | struct inet_sock *inet = inet_sk(sk); |
1413 | struct ipv6_pinfo *np = inet6_sk(sk); | 1426 | struct ipv6_pinfo *np = inet6_sk(sk); |
1427 | struct net *net = sock_net(sk); | ||
1414 | struct ipv6hdr *hdr; | 1428 | struct ipv6hdr *hdr; |
1415 | struct ipv6_txoptions *opt = np->cork.opt; | 1429 | struct ipv6_txoptions *opt = np->cork.opt; |
1416 | struct rt6_info *rt = (struct rt6_info *)inet->cork.dst; | 1430 | struct rt6_info *rt = (struct rt6_info *)inet->cork.dst; |
@@ -1464,12 +1478,12 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1464 | skb->mark = sk->sk_mark; | 1478 | skb->mark = sk->sk_mark; |
1465 | 1479 | ||
1466 | skb->dst = dst_clone(&rt->u.dst); | 1480 | skb->dst = dst_clone(&rt->u.dst); |
1467 | IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); | 1481 | IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); |
1468 | if (proto == IPPROTO_ICMPV6) { | 1482 | if (proto == IPPROTO_ICMPV6) { |
1469 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); | 1483 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); |
1470 | 1484 | ||
1471 | ICMP6MSGOUT_INC_STATS_BH(idev, icmp6_hdr(skb)->icmp6_type); | 1485 | ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type); |
1472 | ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); | 1486 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); |
1473 | } | 1487 | } |
1474 | 1488 | ||
1475 | err = ip6_local_out(skb); | 1489 | err = ip6_local_out(skb); |
@@ -1493,7 +1507,7 @@ void ip6_flush_pending_frames(struct sock *sk) | |||
1493 | 1507 | ||
1494 | while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { | 1508 | while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { |
1495 | if (skb->dst) | 1509 | if (skb->dst) |
1496 | IP6_INC_STATS(ip6_dst_idev(skb->dst), | 1510 | IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb->dst), |
1497 | IPSTATS_MIB_OUTDISCARDS); | 1511 | IPSTATS_MIB_OUTDISCARDS); |
1498 | kfree_skb(skb); | 1512 | kfree_skb(skb); |
1499 | } | 1513 | } |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 17c7b098cdb0..64ce3d33d9c6 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -1050,10 +1050,10 @@ ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | switch (skb->protocol) { | 1052 | switch (skb->protocol) { |
1053 | case __constant_htons(ETH_P_IP): | 1053 | case htons(ETH_P_IP): |
1054 | ret = ip4ip6_tnl_xmit(skb, dev); | 1054 | ret = ip4ip6_tnl_xmit(skb, dev); |
1055 | break; | 1055 | break; |
1056 | case __constant_htons(ETH_P_IPV6): | 1056 | case htons(ETH_P_IPV6): |
1057 | ret = ip6ip6_tnl_xmit(skb, dev); | 1057 | ret = ip6ip6_tnl_xmit(skb, dev); |
1058 | break; | 1058 | break; |
1059 | default: | 1059 | default: |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 095bc453ff4c..182f8a177e7f 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -1383,7 +1383,8 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
1383 | 1383 | ||
1384 | static inline int ip6mr_forward2_finish(struct sk_buff *skb) | 1384 | static inline int ip6mr_forward2_finish(struct sk_buff *skb) |
1385 | { | 1385 | { |
1386 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTFORWDATAGRAMS); | 1386 | IP6_INC_STATS_BH(dev_net(skb->dst->dev), ip6_dst_idev(skb->dst), |
1387 | IPSTATS_MIB_OUTFORWDATAGRAMS); | ||
1387 | return dst_output(skb); | 1388 | return dst_output(skb); |
1388 | } | 1389 | } |
1389 | 1390 | ||
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index e7c03bcc2788..d7b3c6d398ae 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -1446,7 +1446,7 @@ static void mld_sendpack(struct sk_buff *skb) | |||
1446 | int err; | 1446 | int err; |
1447 | struct flowi fl; | 1447 | struct flowi fl; |
1448 | 1448 | ||
1449 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS); | 1449 | IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); |
1450 | payload_len = (skb->tail - skb->network_header) - sizeof(*pip6); | 1450 | payload_len = (skb->tail - skb->network_header) - sizeof(*pip6); |
1451 | mldlen = skb->tail - skb->transport_header; | 1451 | mldlen = skb->tail - skb->transport_header; |
1452 | pip6->payload_len = htons(payload_len); | 1452 | pip6->payload_len = htons(payload_len); |
@@ -1474,11 +1474,11 @@ static void mld_sendpack(struct sk_buff *skb) | |||
1474 | dst_output); | 1474 | dst_output); |
1475 | out: | 1475 | out: |
1476 | if (!err) { | 1476 | if (!err) { |
1477 | ICMP6MSGOUT_INC_STATS_BH(idev, ICMPV6_MLD2_REPORT); | 1477 | ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT); |
1478 | ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); | 1478 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); |
1479 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTMCASTPKTS); | 1479 | IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTMCASTPKTS); |
1480 | } else | 1480 | } else |
1481 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTDISCARDS); | 1481 | IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS); |
1482 | 1482 | ||
1483 | if (likely(idev != NULL)) | 1483 | if (likely(idev != NULL)) |
1484 | in6_dev_put(idev); | 1484 | in6_dev_put(idev); |
@@ -1771,7 +1771,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1771 | struct flowi fl; | 1771 | struct flowi fl; |
1772 | 1772 | ||
1773 | rcu_read_lock(); | 1773 | rcu_read_lock(); |
1774 | IP6_INC_STATS(__in6_dev_get(dev), | 1774 | IP6_INC_STATS(net, __in6_dev_get(dev), |
1775 | IPSTATS_MIB_OUTREQUESTS); | 1775 | IPSTATS_MIB_OUTREQUESTS); |
1776 | rcu_read_unlock(); | 1776 | rcu_read_unlock(); |
1777 | if (type == ICMPV6_MGM_REDUCTION) | 1777 | if (type == ICMPV6_MGM_REDUCTION) |
@@ -1787,7 +1787,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1787 | 1787 | ||
1788 | if (skb == NULL) { | 1788 | if (skb == NULL) { |
1789 | rcu_read_lock(); | 1789 | rcu_read_lock(); |
1790 | IP6_INC_STATS(__in6_dev_get(dev), | 1790 | IP6_INC_STATS(net, __in6_dev_get(dev), |
1791 | IPSTATS_MIB_OUTDISCARDS); | 1791 | IPSTATS_MIB_OUTDISCARDS); |
1792 | rcu_read_unlock(); | 1792 | rcu_read_unlock(); |
1793 | return; | 1793 | return; |
@@ -1839,11 +1839,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1839 | dst_output); | 1839 | dst_output); |
1840 | out: | 1840 | out: |
1841 | if (!err) { | 1841 | if (!err) { |
1842 | ICMP6MSGOUT_INC_STATS(idev, type); | 1842 | ICMP6MSGOUT_INC_STATS(net, idev, type); |
1843 | ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); | 1843 | ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); |
1844 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS); | 1844 | IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTMCASTPKTS); |
1845 | } else | 1845 | } else |
1846 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); | 1846 | IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); |
1847 | 1847 | ||
1848 | if (likely(idev != NULL)) | 1848 | if (likely(idev != NULL)) |
1849 | in6_dev_put(idev); | 1849 | in6_dev_put(idev); |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index f1c62ba0f56b..172438320eec 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -516,13 +516,13 @@ static void __ndisc_send(struct net_device *dev, | |||
516 | skb->dst = dst; | 516 | skb->dst = dst; |
517 | 517 | ||
518 | idev = in6_dev_get(dst->dev); | 518 | idev = in6_dev_get(dst->dev); |
519 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS); | 519 | IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); |
520 | 520 | ||
521 | err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, | 521 | err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, |
522 | dst_output); | 522 | dst_output); |
523 | if (!err) { | 523 | if (!err) { |
524 | ICMP6MSGOUT_INC_STATS(idev, type); | 524 | ICMP6MSGOUT_INC_STATS(net, idev, type); |
525 | ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); | 525 | ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); |
526 | } | 526 | } |
527 | 527 | ||
528 | if (likely(idev != NULL)) | 528 | if (likely(idev != NULL)) |
@@ -1199,7 +1199,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1199 | } | 1199 | } |
1200 | neigh->flags |= NTF_ROUTER; | 1200 | neigh->flags |= NTF_ROUTER; |
1201 | } else if (rt) { | 1201 | } else if (rt) { |
1202 | rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); | 1202 | rt->rt6i_flags = (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); |
1203 | } | 1203 | } |
1204 | 1204 | ||
1205 | if (rt) | 1205 | if (rt) |
@@ -1581,12 +1581,12 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1581 | 1581 | ||
1582 | buff->dst = dst; | 1582 | buff->dst = dst; |
1583 | idev = in6_dev_get(dst->dev); | 1583 | idev = in6_dev_get(dst->dev); |
1584 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS); | 1584 | IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); |
1585 | err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, | 1585 | err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, |
1586 | dst_output); | 1586 | dst_output); |
1587 | if (!err) { | 1587 | if (!err) { |
1588 | ICMP6MSGOUT_INC_STATS(idev, NDISC_REDIRECT); | 1588 | ICMP6MSGOUT_INC_STATS(net, idev, NDISC_REDIRECT); |
1589 | ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); | 1589 | ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); |
1590 | } | 1590 | } |
1591 | 1591 | ||
1592 | if (likely(idev != NULL)) | 1592 | if (likely(idev != NULL)) |
@@ -1730,9 +1730,8 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * f | |||
1730 | return ret; | 1730 | return ret; |
1731 | } | 1731 | } |
1732 | 1732 | ||
1733 | int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name, | 1733 | int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, |
1734 | int nlen, void __user *oldval, | 1734 | void __user *oldval, size_t __user *oldlenp, |
1735 | size_t __user *oldlenp, | ||
1736 | void __user *newval, size_t newlen) | 1735 | void __user *newval, size_t newlen) |
1737 | { | 1736 | { |
1738 | struct net_device *dev = ctl->extra1; | 1737 | struct net_device *dev = ctl->extra1; |
@@ -1745,13 +1744,11 @@ int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name, | |||
1745 | 1744 | ||
1746 | switch (ctl->ctl_name) { | 1745 | switch (ctl->ctl_name) { |
1747 | case NET_NEIGH_REACHABLE_TIME: | 1746 | case NET_NEIGH_REACHABLE_TIME: |
1748 | ret = sysctl_jiffies(ctl, name, nlen, | 1747 | ret = sysctl_jiffies(ctl, oldval, oldlenp, newval, newlen); |
1749 | oldval, oldlenp, newval, newlen); | ||
1750 | break; | 1748 | break; |
1751 | case NET_NEIGH_RETRANS_TIME_MS: | 1749 | case NET_NEIGH_RETRANS_TIME_MS: |
1752 | case NET_NEIGH_REACHABLE_TIME_MS: | 1750 | case NET_NEIGH_REACHABLE_TIME_MS: |
1753 | ret = sysctl_ms_jiffies(ctl, name, nlen, | 1751 | ret = sysctl_ms_jiffies(ctl, oldval, oldlenp, newval, newlen); |
1754 | oldval, oldlenp, newval, newlen); | ||
1755 | break; | 1752 | break; |
1756 | default: | 1753 | default: |
1757 | ret = 0; | 1754 | ret = 0; |
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 8c6c5e71f210..fd5b3a4e3329 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | int ip6_route_me_harder(struct sk_buff *skb) | 13 | int ip6_route_me_harder(struct sk_buff *skb) |
14 | { | 14 | { |
15 | struct net *net = dev_net(skb->dst->dev); | ||
15 | struct ipv6hdr *iph = ipv6_hdr(skb); | 16 | struct ipv6hdr *iph = ipv6_hdr(skb); |
16 | struct dst_entry *dst; | 17 | struct dst_entry *dst; |
17 | struct flowi fl = { | 18 | struct flowi fl = { |
@@ -23,7 +24,7 @@ int ip6_route_me_harder(struct sk_buff *skb) | |||
23 | .saddr = iph->saddr, } }, | 24 | .saddr = iph->saddr, } }, |
24 | }; | 25 | }; |
25 | 26 | ||
26 | dst = ip6_route_output(&init_net, skb->sk, &fl); | 27 | dst = ip6_route_output(net, skb->sk, &fl); |
27 | 28 | ||
28 | #ifdef CONFIG_XFRM | 29 | #ifdef CONFIG_XFRM |
29 | if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && | 30 | if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && |
@@ -33,7 +34,7 @@ int ip6_route_me_harder(struct sk_buff *skb) | |||
33 | #endif | 34 | #endif |
34 | 35 | ||
35 | if (dst->error) { | 36 | if (dst->error) { |
36 | IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | 37 | IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); |
37 | LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); | 38 | LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); |
38 | dst_release(dst); | 39 | dst_release(dst); |
39 | return -EINVAL; | 40 | return -EINVAL; |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 0cfcce7b18d8..53ea512c4608 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -55,30 +55,29 @@ config IP6_NF_IPTABLES | |||
55 | 55 | ||
56 | To compile it as a module, choose M here. If unsure, say N. | 56 | To compile it as a module, choose M here. If unsure, say N. |
57 | 57 | ||
58 | if IP6_NF_IPTABLES | ||
59 | |||
58 | # The simple matches. | 60 | # The simple matches. |
59 | config IP6_NF_MATCH_RT | 61 | config IP6_NF_MATCH_AH |
60 | tristate '"rt" Routing header match support' | 62 | tristate '"ah" match support' |
61 | depends on IP6_NF_IPTABLES | ||
62 | depends on NETFILTER_ADVANCED | 63 | depends on NETFILTER_ADVANCED |
63 | help | 64 | help |
64 | rt matching allows you to match packets based on the routing | 65 | This module allows one to match AH packets. |
65 | header of the packet. | ||
66 | 66 | ||
67 | To compile it as a module, choose M here. If unsure, say N. | 67 | To compile it as a module, choose M here. If unsure, say N. |
68 | 68 | ||
69 | config IP6_NF_MATCH_OPTS | 69 | config IP6_NF_MATCH_EUI64 |
70 | tristate '"hopbyhop" and "dst" opts header match support' | 70 | tristate '"eui64" address check' |
71 | depends on IP6_NF_IPTABLES | ||
72 | depends on NETFILTER_ADVANCED | 71 | depends on NETFILTER_ADVANCED |
73 | help | 72 | help |
74 | This allows one to match packets based on the hop-by-hop | 73 | This module performs checking on the IPv6 source address |
75 | and destination options headers of a packet. | 74 | Compares the last 64 bits with the EUI64 (delivered |
75 | from the MAC address) address | ||
76 | 76 | ||
77 | To compile it as a module, choose M here. If unsure, say N. | 77 | To compile it as a module, choose M here. If unsure, say N. |
78 | 78 | ||
79 | config IP6_NF_MATCH_FRAG | 79 | config IP6_NF_MATCH_FRAG |
80 | tristate '"frag" Fragmentation header match support' | 80 | tristate '"frag" Fragmentation header match support' |
81 | depends on IP6_NF_IPTABLES | ||
82 | depends on NETFILTER_ADVANCED | 81 | depends on NETFILTER_ADVANCED |
83 | help | 82 | help |
84 | frag matching allows you to match packets based on the fragmentation | 83 | frag matching allows you to match packets based on the fragmentation |
@@ -86,9 +85,17 @@ config IP6_NF_MATCH_FRAG | |||
86 | 85 | ||
87 | To compile it as a module, choose M here. If unsure, say N. | 86 | To compile it as a module, choose M here. If unsure, say N. |
88 | 87 | ||
88 | config IP6_NF_MATCH_OPTS | ||
89 | tristate '"hbh" hop-by-hop and "dst" opts header match support' | ||
90 | depends on NETFILTER_ADVANCED | ||
91 | help | ||
92 | This allows one to match packets based on the hop-by-hop | ||
93 | and destination options headers of a packet. | ||
94 | |||
95 | To compile it as a module, choose M here. If unsure, say N. | ||
96 | |||
89 | config IP6_NF_MATCH_HL | 97 | config IP6_NF_MATCH_HL |
90 | tristate '"hl" match support' | 98 | tristate '"hl" match support' |
91 | depends on IP6_NF_IPTABLES | ||
92 | depends on NETFILTER_ADVANCED | 99 | depends on NETFILTER_ADVANCED |
93 | help | 100 | help |
94 | HL matching allows you to match packets based on the hop | 101 | HL matching allows you to match packets based on the hop |
@@ -98,7 +105,6 @@ config IP6_NF_MATCH_HL | |||
98 | 105 | ||
99 | config IP6_NF_MATCH_IPV6HEADER | 106 | config IP6_NF_MATCH_IPV6HEADER |
100 | tristate '"ipv6header" IPv6 Extension Headers Match' | 107 | tristate '"ipv6header" IPv6 Extension Headers Match' |
101 | depends on IP6_NF_IPTABLES | ||
102 | default m if NETFILTER_ADVANCED=n | 108 | default m if NETFILTER_ADVANCED=n |
103 | help | 109 | help |
104 | This module allows one to match packets based upon | 110 | This module allows one to match packets based upon |
@@ -106,54 +112,40 @@ config IP6_NF_MATCH_IPV6HEADER | |||
106 | 112 | ||
107 | To compile it as a module, choose M here. If unsure, say N. | 113 | To compile it as a module, choose M here. If unsure, say N. |
108 | 114 | ||
109 | config IP6_NF_MATCH_AH | ||
110 | tristate '"ah" match support' | ||
111 | depends on IP6_NF_IPTABLES | ||
112 | depends on NETFILTER_ADVANCED | ||
113 | help | ||
114 | This module allows one to match AH packets. | ||
115 | |||
116 | To compile it as a module, choose M here. If unsure, say N. | ||
117 | |||
118 | config IP6_NF_MATCH_MH | 115 | config IP6_NF_MATCH_MH |
119 | tristate '"mh" match support' | 116 | tristate '"mh" match support' |
120 | depends on IP6_NF_IPTABLES | ||
121 | depends on NETFILTER_ADVANCED | 117 | depends on NETFILTER_ADVANCED |
122 | help | 118 | help |
123 | This module allows one to match MH packets. | 119 | This module allows one to match MH packets. |
124 | 120 | ||
125 | To compile it as a module, choose M here. If unsure, say N. | 121 | To compile it as a module, choose M here. If unsure, say N. |
126 | 122 | ||
127 | config IP6_NF_MATCH_EUI64 | 123 | config IP6_NF_MATCH_RT |
128 | tristate '"eui64" address check' | 124 | tristate '"rt" Routing header match support' |
129 | depends on IP6_NF_IPTABLES | ||
130 | depends on NETFILTER_ADVANCED | 125 | depends on NETFILTER_ADVANCED |
131 | help | 126 | help |
132 | This module performs checking on the IPv6 source address | 127 | rt matching allows you to match packets based on the routing |
133 | Compares the last 64 bits with the EUI64 (delivered | 128 | header of the packet. |
134 | from the MAC address) address | ||
135 | 129 | ||
136 | To compile it as a module, choose M here. If unsure, say N. | 130 | To compile it as a module, choose M here. If unsure, say N. |
137 | 131 | ||
138 | # The targets | 132 | # The targets |
139 | config IP6_NF_FILTER | 133 | config IP6_NF_TARGET_LOG |
140 | tristate "Packet filtering" | 134 | tristate "LOG target support" |
141 | depends on IP6_NF_IPTABLES | ||
142 | default m if NETFILTER_ADVANCED=n | 135 | default m if NETFILTER_ADVANCED=n |
143 | help | 136 | help |
144 | Packet filtering defines a table `filter', which has a series of | 137 | This option adds a `LOG' target, which allows you to create rules in |
145 | rules for simple packet filtering at local input, forwarding and | 138 | any iptables table which records the packet header to the syslog. |
146 | local output. See the man page for iptables(8). | ||
147 | 139 | ||
148 | To compile it as a module, choose M here. If unsure, say N. | 140 | To compile it as a module, choose M here. If unsure, say N. |
149 | 141 | ||
150 | config IP6_NF_TARGET_LOG | 142 | config IP6_NF_FILTER |
151 | tristate "LOG target support" | 143 | tristate "Packet filtering" |
152 | depends on IP6_NF_FILTER | ||
153 | default m if NETFILTER_ADVANCED=n | 144 | default m if NETFILTER_ADVANCED=n |
154 | help | 145 | help |
155 | This option adds a `LOG' target, which allows you to create rules in | 146 | Packet filtering defines a table `filter', which has a series of |
156 | any iptables table which records the packet header to the syslog. | 147 | rules for simple packet filtering at local input, forwarding and |
148 | local output. See the man page for iptables(8). | ||
157 | 149 | ||
158 | To compile it as a module, choose M here. If unsure, say N. | 150 | To compile it as a module, choose M here. If unsure, say N. |
159 | 151 | ||
@@ -170,7 +162,6 @@ config IP6_NF_TARGET_REJECT | |||
170 | 162 | ||
171 | config IP6_NF_MANGLE | 163 | config IP6_NF_MANGLE |
172 | tristate "Packet mangling" | 164 | tristate "Packet mangling" |
173 | depends on IP6_NF_IPTABLES | ||
174 | default m if NETFILTER_ADVANCED=n | 165 | default m if NETFILTER_ADVANCED=n |
175 | help | 166 | help |
176 | This option adds a `mangle' table to iptables: see the man page for | 167 | This option adds a `mangle' table to iptables: see the man page for |
@@ -198,7 +189,6 @@ config IP6_NF_TARGET_HL | |||
198 | 189 | ||
199 | config IP6_NF_RAW | 190 | config IP6_NF_RAW |
200 | tristate 'raw table support (required for TRACE)' | 191 | tristate 'raw table support (required for TRACE)' |
201 | depends on IP6_NF_IPTABLES | ||
202 | depends on NETFILTER_ADVANCED | 192 | depends on NETFILTER_ADVANCED |
203 | help | 193 | help |
204 | This option adds a `raw' table to ip6tables. This table is the very | 194 | This option adds a `raw' table to ip6tables. This table is the very |
@@ -211,7 +201,6 @@ config IP6_NF_RAW | |||
211 | # security table for MAC policy | 201 | # security table for MAC policy |
212 | config IP6_NF_SECURITY | 202 | config IP6_NF_SECURITY |
213 | tristate "Security table" | 203 | tristate "Security table" |
214 | depends on IP6_NF_IPTABLES | ||
215 | depends on SECURITY | 204 | depends on SECURITY |
216 | depends on NETFILTER_ADVANCED | 205 | depends on NETFILTER_ADVANCED |
217 | help | 206 | help |
@@ -220,5 +209,7 @@ config IP6_NF_SECURITY | |||
220 | 209 | ||
221 | If unsure, say N. | 210 | If unsure, say N. |
222 | 211 | ||
212 | endif # IP6_NF_IPTABLES | ||
213 | |||
223 | endmenu | 214 | endmenu |
224 | 215 | ||
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 0b4557e03431..a33485dc81cb 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -200,32 +200,25 @@ ip6_checkentry(const struct ip6t_ip6 *ipv6) | |||
200 | } | 200 | } |
201 | 201 | ||
202 | static unsigned int | 202 | static unsigned int |
203 | ip6t_error(struct sk_buff *skb, | 203 | ip6t_error(struct sk_buff *skb, const struct xt_target_param *par) |
204 | const struct net_device *in, | ||
205 | const struct net_device *out, | ||
206 | unsigned int hooknum, | ||
207 | const struct xt_target *target, | ||
208 | const void *targinfo) | ||
209 | { | 204 | { |
210 | if (net_ratelimit()) | 205 | if (net_ratelimit()) |
211 | printk("ip6_tables: error: `%s'\n", (char *)targinfo); | 206 | printk("ip6_tables: error: `%s'\n", |
207 | (const char *)par->targinfo); | ||
212 | 208 | ||
213 | return NF_DROP; | 209 | return NF_DROP; |
214 | } | 210 | } |
215 | 211 | ||
216 | /* Performance critical - called for every packet */ | 212 | /* Performance critical - called for every packet */ |
217 | static inline bool | 213 | static inline bool |
218 | do_match(struct ip6t_entry_match *m, | 214 | do_match(struct ip6t_entry_match *m, const struct sk_buff *skb, |
219 | const struct sk_buff *skb, | 215 | struct xt_match_param *par) |
220 | const struct net_device *in, | ||
221 | const struct net_device *out, | ||
222 | int offset, | ||
223 | unsigned int protoff, | ||
224 | bool *hotdrop) | ||
225 | { | 216 | { |
217 | par->match = m->u.kernel.match; | ||
218 | par->matchinfo = m->data; | ||
219 | |||
226 | /* Stop iteration if it doesn't match */ | 220 | /* Stop iteration if it doesn't match */ |
227 | if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, | 221 | if (!m->u.kernel.match->match(skb, par)) |
228 | offset, protoff, hotdrop)) | ||
229 | return true; | 222 | return true; |
230 | else | 223 | else |
231 | return false; | 224 | return false; |
@@ -355,8 +348,6 @@ ip6t_do_table(struct sk_buff *skb, | |||
355 | struct xt_table *table) | 348 | struct xt_table *table) |
356 | { | 349 | { |
357 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); | 350 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
358 | int offset = 0; | ||
359 | unsigned int protoff = 0; | ||
360 | bool hotdrop = false; | 351 | bool hotdrop = false; |
361 | /* Initializing verdict to NF_DROP keeps gcc happy. */ | 352 | /* Initializing verdict to NF_DROP keeps gcc happy. */ |
362 | unsigned int verdict = NF_DROP; | 353 | unsigned int verdict = NF_DROP; |
@@ -364,6 +355,8 @@ ip6t_do_table(struct sk_buff *skb, | |||
364 | void *table_base; | 355 | void *table_base; |
365 | struct ip6t_entry *e, *back; | 356 | struct ip6t_entry *e, *back; |
366 | struct xt_table_info *private; | 357 | struct xt_table_info *private; |
358 | struct xt_match_param mtpar; | ||
359 | struct xt_target_param tgpar; | ||
367 | 360 | ||
368 | /* Initialization */ | 361 | /* Initialization */ |
369 | indev = in ? in->name : nulldevname; | 362 | indev = in ? in->name : nulldevname; |
@@ -374,6 +367,11 @@ ip6t_do_table(struct sk_buff *skb, | |||
374 | * things we don't know, ie. tcp syn flag or ports). If the | 367 | * things we don't know, ie. tcp syn flag or ports). If the |
375 | * rule is also a fragment-specific rule, non-fragments won't | 368 | * rule is also a fragment-specific rule, non-fragments won't |
376 | * match it. */ | 369 | * match it. */ |
370 | mtpar.hotdrop = &hotdrop; | ||
371 | mtpar.in = tgpar.in = in; | ||
372 | mtpar.out = tgpar.out = out; | ||
373 | mtpar.family = tgpar.family = NFPROTO_IPV6; | ||
374 | tgpar.hooknum = hook; | ||
377 | 375 | ||
378 | read_lock_bh(&table->lock); | 376 | read_lock_bh(&table->lock); |
379 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 377 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
@@ -388,12 +386,10 @@ ip6t_do_table(struct sk_buff *skb, | |||
388 | IP_NF_ASSERT(e); | 386 | IP_NF_ASSERT(e); |
389 | IP_NF_ASSERT(back); | 387 | IP_NF_ASSERT(back); |
390 | if (ip6_packet_match(skb, indev, outdev, &e->ipv6, | 388 | if (ip6_packet_match(skb, indev, outdev, &e->ipv6, |
391 | &protoff, &offset, &hotdrop)) { | 389 | &mtpar.thoff, &mtpar.fragoff, &hotdrop)) { |
392 | struct ip6t_entry_target *t; | 390 | struct ip6t_entry_target *t; |
393 | 391 | ||
394 | if (IP6T_MATCH_ITERATE(e, do_match, | 392 | if (IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) |
395 | skb, in, out, | ||
396 | offset, protoff, &hotdrop) != 0) | ||
397 | goto no_match; | 393 | goto no_match; |
398 | 394 | ||
399 | ADD_COUNTER(e->counters, | 395 | ADD_COUNTER(e->counters, |
@@ -441,15 +437,15 @@ ip6t_do_table(struct sk_buff *skb, | |||
441 | } else { | 437 | } else { |
442 | /* Targets which reenter must return | 438 | /* Targets which reenter must return |
443 | abs. verdicts */ | 439 | abs. verdicts */ |
440 | tgpar.target = t->u.kernel.target; | ||
441 | tgpar.targinfo = t->data; | ||
442 | |||
444 | #ifdef CONFIG_NETFILTER_DEBUG | 443 | #ifdef CONFIG_NETFILTER_DEBUG |
445 | ((struct ip6t_entry *)table_base)->comefrom | 444 | ((struct ip6t_entry *)table_base)->comefrom |
446 | = 0xeeeeeeec; | 445 | = 0xeeeeeeec; |
447 | #endif | 446 | #endif |
448 | verdict = t->u.kernel.target->target(skb, | 447 | verdict = t->u.kernel.target->target(skb, |
449 | in, out, | 448 | &tgpar); |
450 | hook, | ||
451 | t->u.kernel.target, | ||
452 | t->data); | ||
453 | 449 | ||
454 | #ifdef CONFIG_NETFILTER_DEBUG | 450 | #ifdef CONFIG_NETFILTER_DEBUG |
455 | if (((struct ip6t_entry *)table_base)->comefrom | 451 | if (((struct ip6t_entry *)table_base)->comefrom |
@@ -602,12 +598,17 @@ mark_source_chains(struct xt_table_info *newinfo, | |||
602 | static int | 598 | static int |
603 | cleanup_match(struct ip6t_entry_match *m, unsigned int *i) | 599 | cleanup_match(struct ip6t_entry_match *m, unsigned int *i) |
604 | { | 600 | { |
601 | struct xt_mtdtor_param par; | ||
602 | |||
605 | if (i && (*i)-- == 0) | 603 | if (i && (*i)-- == 0) |
606 | return 1; | 604 | return 1; |
607 | 605 | ||
608 | if (m->u.kernel.match->destroy) | 606 | par.match = m->u.kernel.match; |
609 | m->u.kernel.match->destroy(m->u.kernel.match, m->data); | 607 | par.matchinfo = m->data; |
610 | module_put(m->u.kernel.match->me); | 608 | par.family = NFPROTO_IPV6; |
609 | if (par.match->destroy != NULL) | ||
610 | par.match->destroy(&par); | ||
611 | module_put(par.match->me); | ||
611 | return 0; | 612 | return 0; |
612 | } | 613 | } |
613 | 614 | ||
@@ -632,34 +633,28 @@ check_entry(struct ip6t_entry *e, const char *name) | |||
632 | return 0; | 633 | return 0; |
633 | } | 634 | } |
634 | 635 | ||
635 | static int check_match(struct ip6t_entry_match *m, const char *name, | 636 | static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par, |
636 | const struct ip6t_ip6 *ipv6, | 637 | unsigned int *i) |
637 | unsigned int hookmask, unsigned int *i) | ||
638 | { | 638 | { |
639 | struct xt_match *match; | 639 | const struct ip6t_ip6 *ipv6 = par->entryinfo; |
640 | int ret; | 640 | int ret; |
641 | 641 | ||
642 | match = m->u.kernel.match; | 642 | par->match = m->u.kernel.match; |
643 | ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m), | 643 | par->matchinfo = m->data; |
644 | name, hookmask, ipv6->proto, | 644 | |
645 | ipv6->invflags & IP6T_INV_PROTO); | 645 | ret = xt_check_match(par, m->u.match_size - sizeof(*m), |
646 | if (!ret && m->u.kernel.match->checkentry | 646 | ipv6->proto, ipv6->invflags & IP6T_INV_PROTO); |
647 | && !m->u.kernel.match->checkentry(name, ipv6, match, m->data, | 647 | if (ret < 0) { |
648 | hookmask)) { | ||
649 | duprintf("ip_tables: check failed for `%s'.\n", | 648 | duprintf("ip_tables: check failed for `%s'.\n", |
650 | m->u.kernel.match->name); | 649 | par.match->name); |
651 | ret = -EINVAL; | 650 | return ret; |
652 | } | 651 | } |
653 | if (!ret) | 652 | ++*i; |
654 | (*i)++; | 653 | return 0; |
655 | return ret; | ||
656 | } | 654 | } |
657 | 655 | ||
658 | static int | 656 | static int |
659 | find_check_match(struct ip6t_entry_match *m, | 657 | find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par, |
660 | const char *name, | ||
661 | const struct ip6t_ip6 *ipv6, | ||
662 | unsigned int hookmask, | ||
663 | unsigned int *i) | 658 | unsigned int *i) |
664 | { | 659 | { |
665 | struct xt_match *match; | 660 | struct xt_match *match; |
@@ -674,7 +669,7 @@ find_check_match(struct ip6t_entry_match *m, | |||
674 | } | 669 | } |
675 | m->u.kernel.match = match; | 670 | m->u.kernel.match = match; |
676 | 671 | ||
677 | ret = check_match(m, name, ipv6, hookmask, i); | 672 | ret = check_match(m, par, i); |
678 | if (ret) | 673 | if (ret) |
679 | goto err; | 674 | goto err; |
680 | 675 | ||
@@ -686,23 +681,26 @@ err: | |||
686 | 681 | ||
687 | static int check_target(struct ip6t_entry *e, const char *name) | 682 | static int check_target(struct ip6t_entry *e, const char *name) |
688 | { | 683 | { |
689 | struct ip6t_entry_target *t; | 684 | struct ip6t_entry_target *t = ip6t_get_target(e); |
690 | struct xt_target *target; | 685 | struct xt_tgchk_param par = { |
686 | .table = name, | ||
687 | .entryinfo = e, | ||
688 | .target = t->u.kernel.target, | ||
689 | .targinfo = t->data, | ||
690 | .hook_mask = e->comefrom, | ||
691 | .family = NFPROTO_IPV6, | ||
692 | }; | ||
691 | int ret; | 693 | int ret; |
692 | 694 | ||
693 | t = ip6t_get_target(e); | 695 | t = ip6t_get_target(e); |
694 | target = t->u.kernel.target; | 696 | ret = xt_check_target(&par, t->u.target_size - sizeof(*t), |
695 | ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t), | 697 | e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO); |
696 | name, e->comefrom, e->ipv6.proto, | 698 | if (ret < 0) { |
697 | e->ipv6.invflags & IP6T_INV_PROTO); | ||
698 | if (!ret && t->u.kernel.target->checkentry | ||
699 | && !t->u.kernel.target->checkentry(name, e, target, t->data, | ||
700 | e->comefrom)) { | ||
701 | duprintf("ip_tables: check failed for `%s'.\n", | 699 | duprintf("ip_tables: check failed for `%s'.\n", |
702 | t->u.kernel.target->name); | 700 | t->u.kernel.target->name); |
703 | ret = -EINVAL; | 701 | return ret; |
704 | } | 702 | } |
705 | return ret; | 703 | return 0; |
706 | } | 704 | } |
707 | 705 | ||
708 | static int | 706 | static int |
@@ -713,14 +711,18 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size, | |||
713 | struct xt_target *target; | 711 | struct xt_target *target; |
714 | int ret; | 712 | int ret; |
715 | unsigned int j; | 713 | unsigned int j; |
714 | struct xt_mtchk_param mtpar; | ||
716 | 715 | ||
717 | ret = check_entry(e, name); | 716 | ret = check_entry(e, name); |
718 | if (ret) | 717 | if (ret) |
719 | return ret; | 718 | return ret; |
720 | 719 | ||
721 | j = 0; | 720 | j = 0; |
722 | ret = IP6T_MATCH_ITERATE(e, find_check_match, name, &e->ipv6, | 721 | mtpar.table = name; |
723 | e->comefrom, &j); | 722 | mtpar.entryinfo = &e->ipv6; |
723 | mtpar.hook_mask = e->comefrom; | ||
724 | mtpar.family = NFPROTO_IPV6; | ||
725 | ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j); | ||
724 | if (ret != 0) | 726 | if (ret != 0) |
725 | goto cleanup_matches; | 727 | goto cleanup_matches; |
726 | 728 | ||
@@ -795,6 +797,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e, | |||
795 | static int | 797 | static int |
796 | cleanup_entry(struct ip6t_entry *e, unsigned int *i) | 798 | cleanup_entry(struct ip6t_entry *e, unsigned int *i) |
797 | { | 799 | { |
800 | struct xt_tgdtor_param par; | ||
798 | struct ip6t_entry_target *t; | 801 | struct ip6t_entry_target *t; |
799 | 802 | ||
800 | if (i && (*i)-- == 0) | 803 | if (i && (*i)-- == 0) |
@@ -803,9 +806,13 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i) | |||
803 | /* Cleanup all matches */ | 806 | /* Cleanup all matches */ |
804 | IP6T_MATCH_ITERATE(e, cleanup_match, NULL); | 807 | IP6T_MATCH_ITERATE(e, cleanup_match, NULL); |
805 | t = ip6t_get_target(e); | 808 | t = ip6t_get_target(e); |
806 | if (t->u.kernel.target->destroy) | 809 | |
807 | t->u.kernel.target->destroy(t->u.kernel.target, t->data); | 810 | par.target = t->u.kernel.target; |
808 | module_put(t->u.kernel.target->me); | 811 | par.targinfo = t->data; |
812 | par.family = NFPROTO_IPV6; | ||
813 | if (par.target->destroy != NULL) | ||
814 | par.target->destroy(&par); | ||
815 | module_put(par.target->me); | ||
809 | return 0; | 816 | return 0; |
810 | } | 817 | } |
811 | 818 | ||
@@ -1677,10 +1684,14 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name, | |||
1677 | { | 1684 | { |
1678 | unsigned int j; | 1685 | unsigned int j; |
1679 | int ret; | 1686 | int ret; |
1687 | struct xt_mtchk_param mtpar; | ||
1680 | 1688 | ||
1681 | j = 0; | 1689 | j = 0; |
1682 | ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, | 1690 | mtpar.table = name; |
1683 | e->comefrom, &j); | 1691 | mtpar.entryinfo = &e->ipv6; |
1692 | mtpar.hook_mask = e->comefrom; | ||
1693 | mtpar.family = NFPROTO_IPV6; | ||
1694 | ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j); | ||
1684 | if (ret) | 1695 | if (ret) |
1685 | goto cleanup_matches; | 1696 | goto cleanup_matches; |
1686 | 1697 | ||
@@ -2146,30 +2157,23 @@ icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code, | |||
2146 | } | 2157 | } |
2147 | 2158 | ||
2148 | static bool | 2159 | static bool |
2149 | icmp6_match(const struct sk_buff *skb, | 2160 | icmp6_match(const struct sk_buff *skb, const struct xt_match_param *par) |
2150 | const struct net_device *in, | ||
2151 | const struct net_device *out, | ||
2152 | const struct xt_match *match, | ||
2153 | const void *matchinfo, | ||
2154 | int offset, | ||
2155 | unsigned int protoff, | ||
2156 | bool *hotdrop) | ||
2157 | { | 2161 | { |
2158 | const struct icmp6hdr *ic; | 2162 | const struct icmp6hdr *ic; |
2159 | struct icmp6hdr _icmph; | 2163 | struct icmp6hdr _icmph; |
2160 | const struct ip6t_icmp *icmpinfo = matchinfo; | 2164 | const struct ip6t_icmp *icmpinfo = par->matchinfo; |
2161 | 2165 | ||
2162 | /* Must not be a fragment. */ | 2166 | /* Must not be a fragment. */ |
2163 | if (offset) | 2167 | if (par->fragoff != 0) |
2164 | return false; | 2168 | return false; |
2165 | 2169 | ||
2166 | ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); | 2170 | ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph); |
2167 | if (ic == NULL) { | 2171 | if (ic == NULL) { |
2168 | /* We've been asked to examine this packet, and we | 2172 | /* We've been asked to examine this packet, and we |
2169 | * can't. Hence, no choice but to drop. | 2173 | * can't. Hence, no choice but to drop. |
2170 | */ | 2174 | */ |
2171 | duprintf("Dropping evil ICMP tinygram.\n"); | 2175 | duprintf("Dropping evil ICMP tinygram.\n"); |
2172 | *hotdrop = true; | 2176 | *par->hotdrop = true; |
2173 | return false; | 2177 | return false; |
2174 | } | 2178 | } |
2175 | 2179 | ||
@@ -2181,14 +2185,9 @@ icmp6_match(const struct sk_buff *skb, | |||
2181 | } | 2185 | } |
2182 | 2186 | ||
2183 | /* Called when user tries to insert an entry of this type. */ | 2187 | /* Called when user tries to insert an entry of this type. */ |
2184 | static bool | 2188 | static bool icmp6_checkentry(const struct xt_mtchk_param *par) |
2185 | icmp6_checkentry(const char *tablename, | ||
2186 | const void *entry, | ||
2187 | const struct xt_match *match, | ||
2188 | void *matchinfo, | ||
2189 | unsigned int hook_mask) | ||
2190 | { | 2189 | { |
2191 | const struct ip6t_icmp *icmpinfo = matchinfo; | 2190 | const struct ip6t_icmp *icmpinfo = par->matchinfo; |
2192 | 2191 | ||
2193 | /* Must specify no unknown invflags */ | 2192 | /* Must specify no unknown invflags */ |
2194 | return !(icmpinfo->invflags & ~IP6T_ICMP_INV); | 2193 | return !(icmpinfo->invflags & ~IP6T_ICMP_INV); |
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c index d5f8fd5f29d3..27b5adf670a2 100644 --- a/net/ipv6/netfilter/ip6t_HL.c +++ b/net/ipv6/netfilter/ip6t_HL.c | |||
@@ -19,12 +19,10 @@ MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field modification target"); | |||
19 | MODULE_LICENSE("GPL"); | 19 | MODULE_LICENSE("GPL"); |
20 | 20 | ||
21 | static unsigned int | 21 | static unsigned int |
22 | hl_tg6(struct sk_buff *skb, const struct net_device *in, | 22 | hl_tg6(struct sk_buff *skb, const struct xt_target_param *par) |
23 | const struct net_device *out, unsigned int hooknum, | ||
24 | const struct xt_target *target, const void *targinfo) | ||
25 | { | 23 | { |
26 | struct ipv6hdr *ip6h; | 24 | struct ipv6hdr *ip6h; |
27 | const struct ip6t_HL_info *info = targinfo; | 25 | const struct ip6t_HL_info *info = par->targinfo; |
28 | int new_hl; | 26 | int new_hl; |
29 | 27 | ||
30 | if (!skb_make_writable(skb, skb->len)) | 28 | if (!skb_make_writable(skb, skb->len)) |
@@ -56,12 +54,9 @@ hl_tg6(struct sk_buff *skb, const struct net_device *in, | |||
56 | return XT_CONTINUE; | 54 | return XT_CONTINUE; |
57 | } | 55 | } |
58 | 56 | ||
59 | static bool | 57 | static bool hl_tg6_check(const struct xt_tgchk_param *par) |
60 | hl_tg6_check(const char *tablename, const void *entry, | ||
61 | const struct xt_target *target, void *targinfo, | ||
62 | unsigned int hook_mask) | ||
63 | { | 58 | { |
64 | const struct ip6t_HL_info *info = targinfo; | 59 | const struct ip6t_HL_info *info = par->targinfo; |
65 | 60 | ||
66 | if (info->mode > IP6T_HL_MAXMODE) { | 61 | if (info->mode > IP6T_HL_MAXMODE) { |
67 | printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n", | 62 | printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n", |
@@ -78,7 +73,7 @@ hl_tg6_check(const char *tablename, const void *entry, | |||
78 | 73 | ||
79 | static struct xt_target hl_tg6_reg __read_mostly = { | 74 | static struct xt_target hl_tg6_reg __read_mostly = { |
80 | .name = "HL", | 75 | .name = "HL", |
81 | .family = AF_INET6, | 76 | .family = NFPROTO_IPV6, |
82 | .target = hl_tg6, | 77 | .target = hl_tg6, |
83 | .targetsize = sizeof(struct ip6t_HL_info), | 78 | .targetsize = sizeof(struct ip6t_HL_info), |
84 | .table = "mangle", | 79 | .table = "mangle", |
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index 3a2316974f83..caa441d09567 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c | |||
@@ -385,7 +385,7 @@ static struct nf_loginfo default_loginfo = { | |||
385 | }; | 385 | }; |
386 | 386 | ||
387 | static void | 387 | static void |
388 | ip6t_log_packet(unsigned int pf, | 388 | ip6t_log_packet(u_int8_t pf, |
389 | unsigned int hooknum, | 389 | unsigned int hooknum, |
390 | const struct sk_buff *skb, | 390 | const struct sk_buff *skb, |
391 | const struct net_device *in, | 391 | const struct net_device *in, |
@@ -438,28 +438,24 @@ ip6t_log_packet(unsigned int pf, | |||
438 | } | 438 | } |
439 | 439 | ||
440 | static unsigned int | 440 | static unsigned int |
441 | log_tg6(struct sk_buff *skb, const struct net_device *in, | 441 | log_tg6(struct sk_buff *skb, const struct xt_target_param *par) |
442 | const struct net_device *out, unsigned int hooknum, | ||
443 | const struct xt_target *target, const void *targinfo) | ||
444 | { | 442 | { |
445 | const struct ip6t_log_info *loginfo = targinfo; | 443 | const struct ip6t_log_info *loginfo = par->targinfo; |
446 | struct nf_loginfo li; | 444 | struct nf_loginfo li; |
447 | 445 | ||
448 | li.type = NF_LOG_TYPE_LOG; | 446 | li.type = NF_LOG_TYPE_LOG; |
449 | li.u.log.level = loginfo->level; | 447 | li.u.log.level = loginfo->level; |
450 | li.u.log.logflags = loginfo->logflags; | 448 | li.u.log.logflags = loginfo->logflags; |
451 | 449 | ||
452 | ip6t_log_packet(PF_INET6, hooknum, skb, in, out, &li, loginfo->prefix); | 450 | ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, par->out, |
451 | &li, loginfo->prefix); | ||
453 | return XT_CONTINUE; | 452 | return XT_CONTINUE; |
454 | } | 453 | } |
455 | 454 | ||
456 | 455 | ||
457 | static bool | 456 | static bool log_tg6_check(const struct xt_tgchk_param *par) |
458 | log_tg6_check(const char *tablename, const void *entry, | ||
459 | const struct xt_target *target, void *targinfo, | ||
460 | unsigned int hook_mask) | ||
461 | { | 457 | { |
462 | const struct ip6t_log_info *loginfo = targinfo; | 458 | const struct ip6t_log_info *loginfo = par->targinfo; |
463 | 459 | ||
464 | if (loginfo->level >= 8) { | 460 | if (loginfo->level >= 8) { |
465 | pr_debug("LOG: level %u >= 8\n", loginfo->level); | 461 | pr_debug("LOG: level %u >= 8\n", loginfo->level); |
@@ -475,7 +471,7 @@ log_tg6_check(const char *tablename, const void *entry, | |||
475 | 471 | ||
476 | static struct xt_target log_tg6_reg __read_mostly = { | 472 | static struct xt_target log_tg6_reg __read_mostly = { |
477 | .name = "LOG", | 473 | .name = "LOG", |
478 | .family = AF_INET6, | 474 | .family = NFPROTO_IPV6, |
479 | .target = log_tg6, | 475 | .target = log_tg6, |
480 | .targetsize = sizeof(struct ip6t_log_info), | 476 | .targetsize = sizeof(struct ip6t_log_info), |
481 | .checkentry = log_tg6_check, | 477 | .checkentry = log_tg6_check, |
@@ -495,7 +491,7 @@ static int __init log_tg6_init(void) | |||
495 | ret = xt_register_target(&log_tg6_reg); | 491 | ret = xt_register_target(&log_tg6_reg); |
496 | if (ret < 0) | 492 | if (ret < 0) |
497 | return ret; | 493 | return ret; |
498 | nf_log_register(PF_INET6, &ip6t_logger); | 494 | nf_log_register(NFPROTO_IPV6, &ip6t_logger); |
499 | return 0; | 495 | return 0; |
500 | } | 496 | } |
501 | 497 | ||
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 44c8d65a2431..0981b4ccb8b1 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -35,7 +35,7 @@ MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv6"); | |||
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | 36 | ||
37 | /* Send RST reply */ | 37 | /* Send RST reply */ |
38 | static void send_reset(struct sk_buff *oldskb) | 38 | static void send_reset(struct net *net, struct sk_buff *oldskb) |
39 | { | 39 | { |
40 | struct sk_buff *nskb; | 40 | struct sk_buff *nskb; |
41 | struct tcphdr otcph, *tcph; | 41 | struct tcphdr otcph, *tcph; |
@@ -94,7 +94,7 @@ static void send_reset(struct sk_buff *oldskb) | |||
94 | fl.fl_ip_sport = otcph.dest; | 94 | fl.fl_ip_sport = otcph.dest; |
95 | fl.fl_ip_dport = otcph.source; | 95 | fl.fl_ip_dport = otcph.source; |
96 | security_skb_classify_flow(oldskb, &fl); | 96 | security_skb_classify_flow(oldskb, &fl); |
97 | dst = ip6_route_output(&init_net, NULL, &fl); | 97 | dst = ip6_route_output(net, NULL, &fl); |
98 | if (dst == NULL) | 98 | if (dst == NULL) |
99 | return; | 99 | return; |
100 | if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0)) | 100 | if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0)) |
@@ -163,20 +163,20 @@ static void send_reset(struct sk_buff *oldskb) | |||
163 | } | 163 | } |
164 | 164 | ||
165 | static inline void | 165 | static inline void |
166 | send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum) | 166 | send_unreach(struct net *net, struct sk_buff *skb_in, unsigned char code, |
167 | unsigned int hooknum) | ||
167 | { | 168 | { |
168 | if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL) | 169 | if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL) |
169 | skb_in->dev = init_net.loopback_dev; | 170 | skb_in->dev = net->loopback_dev; |
170 | 171 | ||
171 | icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL); | 172 | icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL); |
172 | } | 173 | } |
173 | 174 | ||
174 | static unsigned int | 175 | static unsigned int |
175 | reject_tg6(struct sk_buff *skb, const struct net_device *in, | 176 | reject_tg6(struct sk_buff *skb, const struct xt_target_param *par) |
176 | const struct net_device *out, unsigned int hooknum, | ||
177 | const struct xt_target *target, const void *targinfo) | ||
178 | { | 177 | { |
179 | const struct ip6t_reject_info *reject = targinfo; | 178 | const struct ip6t_reject_info *reject = par->targinfo; |
179 | struct net *net = dev_net((par->in != NULL) ? par->in : par->out); | ||
180 | 180 | ||
181 | pr_debug("%s: medium point\n", __func__); | 181 | pr_debug("%s: medium point\n", __func__); |
182 | /* WARNING: This code causes reentry within ip6tables. | 182 | /* WARNING: This code causes reentry within ip6tables. |
@@ -184,25 +184,25 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in, | |||
184 | must return an absolute verdict. --RR */ | 184 | must return an absolute verdict. --RR */ |
185 | switch (reject->with) { | 185 | switch (reject->with) { |
186 | case IP6T_ICMP6_NO_ROUTE: | 186 | case IP6T_ICMP6_NO_ROUTE: |
187 | send_unreach(skb, ICMPV6_NOROUTE, hooknum); | 187 | send_unreach(net, skb, ICMPV6_NOROUTE, par->hooknum); |
188 | break; | 188 | break; |
189 | case IP6T_ICMP6_ADM_PROHIBITED: | 189 | case IP6T_ICMP6_ADM_PROHIBITED: |
190 | send_unreach(skb, ICMPV6_ADM_PROHIBITED, hooknum); | 190 | send_unreach(net, skb, ICMPV6_ADM_PROHIBITED, par->hooknum); |
191 | break; | 191 | break; |
192 | case IP6T_ICMP6_NOT_NEIGHBOUR: | 192 | case IP6T_ICMP6_NOT_NEIGHBOUR: |
193 | send_unreach(skb, ICMPV6_NOT_NEIGHBOUR, hooknum); | 193 | send_unreach(net, skb, ICMPV6_NOT_NEIGHBOUR, par->hooknum); |
194 | break; | 194 | break; |
195 | case IP6T_ICMP6_ADDR_UNREACH: | 195 | case IP6T_ICMP6_ADDR_UNREACH: |
196 | send_unreach(skb, ICMPV6_ADDR_UNREACH, hooknum); | 196 | send_unreach(net, skb, ICMPV6_ADDR_UNREACH, par->hooknum); |
197 | break; | 197 | break; |
198 | case IP6T_ICMP6_PORT_UNREACH: | 198 | case IP6T_ICMP6_PORT_UNREACH: |
199 | send_unreach(skb, ICMPV6_PORT_UNREACH, hooknum); | 199 | send_unreach(net, skb, ICMPV6_PORT_UNREACH, par->hooknum); |
200 | break; | 200 | break; |
201 | case IP6T_ICMP6_ECHOREPLY: | 201 | case IP6T_ICMP6_ECHOREPLY: |
202 | /* Do nothing */ | 202 | /* Do nothing */ |
203 | break; | 203 | break; |
204 | case IP6T_TCP_RESET: | 204 | case IP6T_TCP_RESET: |
205 | send_reset(skb); | 205 | send_reset(net, skb); |
206 | break; | 206 | break; |
207 | default: | 207 | default: |
208 | if (net_ratelimit()) | 208 | if (net_ratelimit()) |
@@ -213,13 +213,10 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in, | |||
213 | return NF_DROP; | 213 | return NF_DROP; |
214 | } | 214 | } |
215 | 215 | ||
216 | static bool | 216 | static bool reject_tg6_check(const struct xt_tgchk_param *par) |
217 | reject_tg6_check(const char *tablename, const void *entry, | ||
218 | const struct xt_target *target, void *targinfo, | ||
219 | unsigned int hook_mask) | ||
220 | { | 217 | { |
221 | const struct ip6t_reject_info *rejinfo = targinfo; | 218 | const struct ip6t_reject_info *rejinfo = par->targinfo; |
222 | const struct ip6t_entry *e = entry; | 219 | const struct ip6t_entry *e = par->entryinfo; |
223 | 220 | ||
224 | if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) { | 221 | if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) { |
225 | printk("ip6t_REJECT: ECHOREPLY is not supported.\n"); | 222 | printk("ip6t_REJECT: ECHOREPLY is not supported.\n"); |
@@ -237,7 +234,7 @@ reject_tg6_check(const char *tablename, const void *entry, | |||
237 | 234 | ||
238 | static struct xt_target reject_tg6_reg __read_mostly = { | 235 | static struct xt_target reject_tg6_reg __read_mostly = { |
239 | .name = "REJECT", | 236 | .name = "REJECT", |
240 | .family = AF_INET6, | 237 | .family = NFPROTO_IPV6, |
241 | .target = reject_tg6, | 238 | .target = reject_tg6, |
242 | .targetsize = sizeof(struct ip6t_reject_info), | 239 | .targetsize = sizeof(struct ip6t_reject_info), |
243 | .table = "filter", | 240 | .table = "filter", |
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c index 429629fd63b6..3a82f24746b9 100644 --- a/net/ipv6/netfilter/ip6t_ah.c +++ b/net/ipv6/netfilter/ip6t_ah.c | |||
@@ -36,14 +36,11 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert) | |||
36 | return r; | 36 | return r; |
37 | } | 37 | } |
38 | 38 | ||
39 | static bool | 39 | static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
40 | ah_mt6(const struct sk_buff *skb, const struct net_device *in, | ||
41 | const struct net_device *out, const struct xt_match *match, | ||
42 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
43 | { | 40 | { |
44 | struct ip_auth_hdr _ah; | 41 | struct ip_auth_hdr _ah; |
45 | const struct ip_auth_hdr *ah; | 42 | const struct ip_auth_hdr *ah; |
46 | const struct ip6t_ah *ahinfo = matchinfo; | 43 | const struct ip6t_ah *ahinfo = par->matchinfo; |
47 | unsigned int ptr; | 44 | unsigned int ptr; |
48 | unsigned int hdrlen = 0; | 45 | unsigned int hdrlen = 0; |
49 | int err; | 46 | int err; |
@@ -51,13 +48,13 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
51 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); | 48 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); |
52 | if (err < 0) { | 49 | if (err < 0) { |
53 | if (err != -ENOENT) | 50 | if (err != -ENOENT) |
54 | *hotdrop = true; | 51 | *par->hotdrop = true; |
55 | return false; | 52 | return false; |
56 | } | 53 | } |
57 | 54 | ||
58 | ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); | 55 | ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); |
59 | if (ah == NULL) { | 56 | if (ah == NULL) { |
60 | *hotdrop = true; | 57 | *par->hotdrop = true; |
61 | return false; | 58 | return false; |
62 | } | 59 | } |
63 | 60 | ||
@@ -93,13 +90,9 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
93 | !(ahinfo->hdrres && ah->reserved); | 90 | !(ahinfo->hdrres && ah->reserved); |
94 | } | 91 | } |
95 | 92 | ||
96 | /* Called when user tries to insert an entry of this type. */ | 93 | static bool ah_mt6_check(const struct xt_mtchk_param *par) |
97 | static bool | ||
98 | ah_mt6_check(const char *tablename, const void *entry, | ||
99 | const struct xt_match *match, void *matchinfo, | ||
100 | unsigned int hook_mask) | ||
101 | { | 94 | { |
102 | const struct ip6t_ah *ahinfo = matchinfo; | 95 | const struct ip6t_ah *ahinfo = par->matchinfo; |
103 | 96 | ||
104 | if (ahinfo->invflags & ~IP6T_AH_INV_MASK) { | 97 | if (ahinfo->invflags & ~IP6T_AH_INV_MASK) { |
105 | pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags); | 98 | pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags); |
@@ -110,7 +103,7 @@ ah_mt6_check(const char *tablename, const void *entry, | |||
110 | 103 | ||
111 | static struct xt_match ah_mt6_reg __read_mostly = { | 104 | static struct xt_match ah_mt6_reg __read_mostly = { |
112 | .name = "ah", | 105 | .name = "ah", |
113 | .family = AF_INET6, | 106 | .family = NFPROTO_IPV6, |
114 | .match = ah_mt6, | 107 | .match = ah_mt6, |
115 | .matchsize = sizeof(struct ip6t_ah), | 108 | .matchsize = sizeof(struct ip6t_ah), |
116 | .checkentry = ah_mt6_check, | 109 | .checkentry = ah_mt6_check, |
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c index 8f331f12b2ec..db610bacbcce 100644 --- a/net/ipv6/netfilter/ip6t_eui64.c +++ b/net/ipv6/netfilter/ip6t_eui64.c | |||
@@ -20,18 +20,15 @@ MODULE_LICENSE("GPL"); | |||
20 | MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); | 20 | MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); |
21 | 21 | ||
22 | static bool | 22 | static bool |
23 | eui64_mt6(const struct sk_buff *skb, const struct net_device *in, | 23 | eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
24 | const struct net_device *out, const struct xt_match *match, | ||
25 | const void *matchinfo, int offset, unsigned int protoff, | ||
26 | bool *hotdrop) | ||
27 | { | 24 | { |
28 | unsigned char eui64[8]; | 25 | unsigned char eui64[8]; |
29 | int i = 0; | 26 | int i = 0; |
30 | 27 | ||
31 | if (!(skb_mac_header(skb) >= skb->head && | 28 | if (!(skb_mac_header(skb) >= skb->head && |
32 | skb_mac_header(skb) + ETH_HLEN <= skb->data) && | 29 | skb_mac_header(skb) + ETH_HLEN <= skb->data) && |
33 | offset != 0) { | 30 | par->fragoff != 0) { |
34 | *hotdrop = true; | 31 | *par->hotdrop = true; |
35 | return false; | 32 | return false; |
36 | } | 33 | } |
37 | 34 | ||
@@ -60,7 +57,7 @@ eui64_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
60 | 57 | ||
61 | static struct xt_match eui64_mt6_reg __read_mostly = { | 58 | static struct xt_match eui64_mt6_reg __read_mostly = { |
62 | .name = "eui64", | 59 | .name = "eui64", |
63 | .family = AF_INET6, | 60 | .family = NFPROTO_IPV6, |
64 | .match = eui64_mt6, | 61 | .match = eui64_mt6, |
65 | .matchsize = sizeof(int), | 62 | .matchsize = sizeof(int), |
66 | .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) | | 63 | .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) | |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index e2bbc63dba5b..673aa0a5084e 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c | |||
@@ -35,27 +35,24 @@ id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert) | |||
35 | } | 35 | } |
36 | 36 | ||
37 | static bool | 37 | static bool |
38 | frag_mt6(const struct sk_buff *skb, const struct net_device *in, | 38 | frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
39 | const struct net_device *out, const struct xt_match *match, | ||
40 | const void *matchinfo, int offset, unsigned int protoff, | ||
41 | bool *hotdrop) | ||
42 | { | 39 | { |
43 | struct frag_hdr _frag; | 40 | struct frag_hdr _frag; |
44 | const struct frag_hdr *fh; | 41 | const struct frag_hdr *fh; |
45 | const struct ip6t_frag *fraginfo = matchinfo; | 42 | const struct ip6t_frag *fraginfo = par->matchinfo; |
46 | unsigned int ptr; | 43 | unsigned int ptr; |
47 | int err; | 44 | int err; |
48 | 45 | ||
49 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); | 46 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); |
50 | if (err < 0) { | 47 | if (err < 0) { |
51 | if (err != -ENOENT) | 48 | if (err != -ENOENT) |
52 | *hotdrop = true; | 49 | *par->hotdrop = true; |
53 | return false; | 50 | return false; |
54 | } | 51 | } |
55 | 52 | ||
56 | fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); | 53 | fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); |
57 | if (fh == NULL) { | 54 | if (fh == NULL) { |
58 | *hotdrop = true; | 55 | *par->hotdrop = true; |
59 | return false; | 56 | return false; |
60 | } | 57 | } |
61 | 58 | ||
@@ -110,13 +107,9 @@ frag_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
110 | && (ntohs(fh->frag_off) & IP6_MF)); | 107 | && (ntohs(fh->frag_off) & IP6_MF)); |
111 | } | 108 | } |
112 | 109 | ||
113 | /* Called when user tries to insert an entry of this type. */ | 110 | static bool frag_mt6_check(const struct xt_mtchk_param *par) |
114 | static bool | ||
115 | frag_mt6_check(const char *tablename, const void *ip, | ||
116 | const struct xt_match *match, void *matchinfo, | ||
117 | unsigned int hook_mask) | ||
118 | { | 111 | { |
119 | const struct ip6t_frag *fraginfo = matchinfo; | 112 | const struct ip6t_frag *fraginfo = par->matchinfo; |
120 | 113 | ||
121 | if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { | 114 | if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { |
122 | pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags); | 115 | pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags); |
@@ -127,7 +120,7 @@ frag_mt6_check(const char *tablename, const void *ip, | |||
127 | 120 | ||
128 | static struct xt_match frag_mt6_reg __read_mostly = { | 121 | static struct xt_match frag_mt6_reg __read_mostly = { |
129 | .name = "frag", | 122 | .name = "frag", |
130 | .family = AF_INET6, | 123 | .family = NFPROTO_IPV6, |
131 | .match = frag_mt6, | 124 | .match = frag_mt6, |
132 | .matchsize = sizeof(struct ip6t_frag), | 125 | .matchsize = sizeof(struct ip6t_frag), |
133 | .checkentry = frag_mt6_check, | 126 | .checkentry = frag_mt6_check, |
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index 62e39ace0588..cbe8dec9744b 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c | |||
@@ -42,14 +42,11 @@ MODULE_ALIAS("ip6t_dst"); | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | static bool | 44 | static bool |
45 | hbh_mt6(const struct sk_buff *skb, const struct net_device *in, | 45 | hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
46 | const struct net_device *out, const struct xt_match *match, | ||
47 | const void *matchinfo, int offset, unsigned int protoff, | ||
48 | bool *hotdrop) | ||
49 | { | 46 | { |
50 | struct ipv6_opt_hdr _optsh; | 47 | struct ipv6_opt_hdr _optsh; |
51 | const struct ipv6_opt_hdr *oh; | 48 | const struct ipv6_opt_hdr *oh; |
52 | const struct ip6t_opts *optinfo = matchinfo; | 49 | const struct ip6t_opts *optinfo = par->matchinfo; |
53 | unsigned int temp; | 50 | unsigned int temp; |
54 | unsigned int ptr; | 51 | unsigned int ptr; |
55 | unsigned int hdrlen = 0; | 52 | unsigned int hdrlen = 0; |
@@ -61,16 +58,16 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
61 | unsigned int optlen; | 58 | unsigned int optlen; |
62 | int err; | 59 | int err; |
63 | 60 | ||
64 | err = ipv6_find_hdr(skb, &ptr, match->data, NULL); | 61 | err = ipv6_find_hdr(skb, &ptr, par->match->data, NULL); |
65 | if (err < 0) { | 62 | if (err < 0) { |
66 | if (err != -ENOENT) | 63 | if (err != -ENOENT) |
67 | *hotdrop = true; | 64 | *par->hotdrop = true; |
68 | return false; | 65 | return false; |
69 | } | 66 | } |
70 | 67 | ||
71 | oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); | 68 | oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); |
72 | if (oh == NULL) { | 69 | if (oh == NULL) { |
73 | *hotdrop = true; | 70 | *par->hotdrop = true; |
74 | return false; | 71 | return false; |
75 | } | 72 | } |
76 | 73 | ||
@@ -97,8 +94,6 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
97 | hdrlen -= 2; | 94 | hdrlen -= 2; |
98 | if (!(optinfo->flags & IP6T_OPTS_OPTS)) { | 95 | if (!(optinfo->flags & IP6T_OPTS_OPTS)) { |
99 | return ret; | 96 | return ret; |
100 | } else if (optinfo->flags & IP6T_OPTS_NSTRICT) { | ||
101 | pr_debug("Not strict - not implemented"); | ||
102 | } else { | 97 | } else { |
103 | pr_debug("Strict "); | 98 | pr_debug("Strict "); |
104 | pr_debug("#%d ", optinfo->optsnr); | 99 | pr_debug("#%d ", optinfo->optsnr); |
@@ -165,25 +160,27 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
165 | return false; | 160 | return false; |
166 | } | 161 | } |
167 | 162 | ||
168 | /* Called when user tries to insert an entry of this type. */ | 163 | static bool hbh_mt6_check(const struct xt_mtchk_param *par) |
169 | static bool | ||
170 | hbh_mt6_check(const char *tablename, const void *entry, | ||
171 | const struct xt_match *match, void *matchinfo, | ||
172 | unsigned int hook_mask) | ||
173 | { | 164 | { |
174 | const struct ip6t_opts *optsinfo = matchinfo; | 165 | const struct ip6t_opts *optsinfo = par->matchinfo; |
175 | 166 | ||
176 | if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) { | 167 | if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) { |
177 | pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); | 168 | pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); |
178 | return false; | 169 | return false; |
179 | } | 170 | } |
171 | |||
172 | if (optsinfo->flags & IP6T_OPTS_NSTRICT) { | ||
173 | pr_debug("ip6t_opts: Not strict - not implemented"); | ||
174 | return false; | ||
175 | } | ||
176 | |||
180 | return true; | 177 | return true; |
181 | } | 178 | } |
182 | 179 | ||
183 | static struct xt_match hbh_mt6_reg[] __read_mostly = { | 180 | static struct xt_match hbh_mt6_reg[] __read_mostly = { |
184 | { | 181 | { |
185 | .name = "hbh", | 182 | .name = "hbh", |
186 | .family = AF_INET6, | 183 | .family = NFPROTO_IPV6, |
187 | .match = hbh_mt6, | 184 | .match = hbh_mt6, |
188 | .matchsize = sizeof(struct ip6t_opts), | 185 | .matchsize = sizeof(struct ip6t_opts), |
189 | .checkentry = hbh_mt6_check, | 186 | .checkentry = hbh_mt6_check, |
@@ -192,7 +189,7 @@ static struct xt_match hbh_mt6_reg[] __read_mostly = { | |||
192 | }, | 189 | }, |
193 | { | 190 | { |
194 | .name = "dst", | 191 | .name = "dst", |
195 | .family = AF_INET6, | 192 | .family = NFPROTO_IPV6, |
196 | .match = hbh_mt6, | 193 | .match = hbh_mt6, |
197 | .matchsize = sizeof(struct ip6t_opts), | 194 | .matchsize = sizeof(struct ip6t_opts), |
198 | .checkentry = hbh_mt6_check, | 195 | .checkentry = hbh_mt6_check, |
diff --git a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c index 345671673845..c964dca1132d 100644 --- a/net/ipv6/netfilter/ip6t_hl.c +++ b/net/ipv6/netfilter/ip6t_hl.c | |||
@@ -19,12 +19,9 @@ MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>"); | |||
19 | MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match"); | 19 | MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match"); |
20 | MODULE_LICENSE("GPL"); | 20 | MODULE_LICENSE("GPL"); |
21 | 21 | ||
22 | static bool | 22 | static bool hl_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
23 | hl_mt6(const struct sk_buff *skb, const struct net_device *in, | ||
24 | const struct net_device *out, const struct xt_match *match, | ||
25 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
26 | { | 23 | { |
27 | const struct ip6t_hl_info *info = matchinfo; | 24 | const struct ip6t_hl_info *info = par->matchinfo; |
28 | const struct ipv6hdr *ip6h = ipv6_hdr(skb); | 25 | const struct ipv6hdr *ip6h = ipv6_hdr(skb); |
29 | 26 | ||
30 | switch (info->mode) { | 27 | switch (info->mode) { |
@@ -51,7 +48,7 @@ hl_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
51 | 48 | ||
52 | static struct xt_match hl_mt6_reg __read_mostly = { | 49 | static struct xt_match hl_mt6_reg __read_mostly = { |
53 | .name = "hl", | 50 | .name = "hl", |
54 | .family = AF_INET6, | 51 | .family = NFPROTO_IPV6, |
55 | .match = hl_mt6, | 52 | .match = hl_mt6, |
56 | .matchsize = sizeof(struct ip6t_hl_info), | 53 | .matchsize = sizeof(struct ip6t_hl_info), |
57 | .me = THIS_MODULE, | 54 | .me = THIS_MODULE, |
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c index 317a8960a757..14e6724d5672 100644 --- a/net/ipv6/netfilter/ip6t_ipv6header.c +++ b/net/ipv6/netfilter/ip6t_ipv6header.c | |||
@@ -27,12 +27,9 @@ MODULE_DESCRIPTION("Xtables: IPv6 header types match"); | |||
27 | MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); | 27 | MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); |
28 | 28 | ||
29 | static bool | 29 | static bool |
30 | ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in, | 30 | ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
31 | const struct net_device *out, const struct xt_match *match, | ||
32 | const void *matchinfo, int offset, unsigned int protoff, | ||
33 | bool *hotdrop) | ||
34 | { | 31 | { |
35 | const struct ip6t_ipv6header_info *info = matchinfo; | 32 | const struct ip6t_ipv6header_info *info = par->matchinfo; |
36 | unsigned int temp; | 33 | unsigned int temp; |
37 | int len; | 34 | int len; |
38 | u8 nexthdr; | 35 | u8 nexthdr; |
@@ -121,12 +118,9 @@ ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
121 | } | 118 | } |
122 | } | 119 | } |
123 | 120 | ||
124 | static bool | 121 | static bool ipv6header_mt6_check(const struct xt_mtchk_param *par) |
125 | ipv6header_mt6_check(const char *tablename, const void *ip, | ||
126 | const struct xt_match *match, void *matchinfo, | ||
127 | unsigned int hook_mask) | ||
128 | { | 122 | { |
129 | const struct ip6t_ipv6header_info *info = matchinfo; | 123 | const struct ip6t_ipv6header_info *info = par->matchinfo; |
130 | 124 | ||
131 | /* invflags is 0 or 0xff in hard mode */ | 125 | /* invflags is 0 or 0xff in hard mode */ |
132 | if ((!info->modeflag) && info->invflags != 0x00 && | 126 | if ((!info->modeflag) && info->invflags != 0x00 && |
@@ -138,7 +132,7 @@ ipv6header_mt6_check(const char *tablename, const void *ip, | |||
138 | 132 | ||
139 | static struct xt_match ipv6header_mt6_reg __read_mostly = { | 133 | static struct xt_match ipv6header_mt6_reg __read_mostly = { |
140 | .name = "ipv6header", | 134 | .name = "ipv6header", |
141 | .family = AF_INET6, | 135 | .family = NFPROTO_IPV6, |
142 | .match = ipv6header_mt6, | 136 | .match = ipv6header_mt6, |
143 | .matchsize = sizeof(struct ip6t_ipv6header_info), | 137 | .matchsize = sizeof(struct ip6t_ipv6header_info), |
144 | .checkentry = ipv6header_mt6_check, | 138 | .checkentry = ipv6header_mt6_check, |
diff --git a/net/ipv6/netfilter/ip6t_mh.c b/net/ipv6/netfilter/ip6t_mh.c index e06678d07ec8..aafe4e66577b 100644 --- a/net/ipv6/netfilter/ip6t_mh.c +++ b/net/ipv6/netfilter/ip6t_mh.c | |||
@@ -37,32 +37,29 @@ type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert) | |||
37 | return (type >= min && type <= max) ^ invert; | 37 | return (type >= min && type <= max) ^ invert; |
38 | } | 38 | } |
39 | 39 | ||
40 | static bool | 40 | static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
41 | mh_mt6(const struct sk_buff *skb, const struct net_device *in, | ||
42 | const struct net_device *out, const struct xt_match *match, | ||
43 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
44 | { | 41 | { |
45 | struct ip6_mh _mh; | 42 | struct ip6_mh _mh; |
46 | const struct ip6_mh *mh; | 43 | const struct ip6_mh *mh; |
47 | const struct ip6t_mh *mhinfo = matchinfo; | 44 | const struct ip6t_mh *mhinfo = par->matchinfo; |
48 | 45 | ||
49 | /* Must not be a fragment. */ | 46 | /* Must not be a fragment. */ |
50 | if (offset) | 47 | if (par->fragoff != 0) |
51 | return false; | 48 | return false; |
52 | 49 | ||
53 | mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh); | 50 | mh = skb_header_pointer(skb, par->thoff, sizeof(_mh), &_mh); |
54 | if (mh == NULL) { | 51 | if (mh == NULL) { |
55 | /* We've been asked to examine this packet, and we | 52 | /* We've been asked to examine this packet, and we |
56 | can't. Hence, no choice but to drop. */ | 53 | can't. Hence, no choice but to drop. */ |
57 | duprintf("Dropping evil MH tinygram.\n"); | 54 | duprintf("Dropping evil MH tinygram.\n"); |
58 | *hotdrop = true; | 55 | *par->hotdrop = true; |
59 | return false; | 56 | return false; |
60 | } | 57 | } |
61 | 58 | ||
62 | if (mh->ip6mh_proto != IPPROTO_NONE) { | 59 | if (mh->ip6mh_proto != IPPROTO_NONE) { |
63 | duprintf("Dropping invalid MH Payload Proto: %u\n", | 60 | duprintf("Dropping invalid MH Payload Proto: %u\n", |
64 | mh->ip6mh_proto); | 61 | mh->ip6mh_proto); |
65 | *hotdrop = true; | 62 | *par->hotdrop = true; |
66 | return false; | 63 | return false; |
67 | } | 64 | } |
68 | 65 | ||
@@ -70,13 +67,9 @@ mh_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
70 | !!(mhinfo->invflags & IP6T_MH_INV_TYPE)); | 67 | !!(mhinfo->invflags & IP6T_MH_INV_TYPE)); |
71 | } | 68 | } |
72 | 69 | ||
73 | /* Called when user tries to insert an entry of this type. */ | 70 | static bool mh_mt6_check(const struct xt_mtchk_param *par) |
74 | static bool | ||
75 | mh_mt6_check(const char *tablename, const void *entry, | ||
76 | const struct xt_match *match, void *matchinfo, | ||
77 | unsigned int hook_mask) | ||
78 | { | 71 | { |
79 | const struct ip6t_mh *mhinfo = matchinfo; | 72 | const struct ip6t_mh *mhinfo = par->matchinfo; |
80 | 73 | ||
81 | /* Must specify no unknown invflags */ | 74 | /* Must specify no unknown invflags */ |
82 | return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); | 75 | return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); |
@@ -84,7 +77,7 @@ mh_mt6_check(const char *tablename, const void *entry, | |||
84 | 77 | ||
85 | static struct xt_match mh_mt6_reg __read_mostly = { | 78 | static struct xt_match mh_mt6_reg __read_mostly = { |
86 | .name = "mh", | 79 | .name = "mh", |
87 | .family = AF_INET6, | 80 | .family = NFPROTO_IPV6, |
88 | .checkentry = mh_mt6_check, | 81 | .checkentry = mh_mt6_check, |
89 | .match = mh_mt6, | 82 | .match = mh_mt6, |
90 | .matchsize = sizeof(struct ip6t_mh), | 83 | .matchsize = sizeof(struct ip6t_mh), |
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index 81aaf7aaaabf..356b8d6f6baa 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c | |||
@@ -36,14 +36,11 @@ segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert) | |||
36 | return r; | 36 | return r; |
37 | } | 37 | } |
38 | 38 | ||
39 | static bool | 39 | static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
40 | rt_mt6(const struct sk_buff *skb, const struct net_device *in, | ||
41 | const struct net_device *out, const struct xt_match *match, | ||
42 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
43 | { | 40 | { |
44 | struct ipv6_rt_hdr _route; | 41 | struct ipv6_rt_hdr _route; |
45 | const struct ipv6_rt_hdr *rh; | 42 | const struct ipv6_rt_hdr *rh; |
46 | const struct ip6t_rt *rtinfo = matchinfo; | 43 | const struct ip6t_rt *rtinfo = par->matchinfo; |
47 | unsigned int temp; | 44 | unsigned int temp; |
48 | unsigned int ptr; | 45 | unsigned int ptr; |
49 | unsigned int hdrlen = 0; | 46 | unsigned int hdrlen = 0; |
@@ -55,13 +52,13 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
55 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); | 52 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); |
56 | if (err < 0) { | 53 | if (err < 0) { |
57 | if (err != -ENOENT) | 54 | if (err != -ENOENT) |
58 | *hotdrop = true; | 55 | *par->hotdrop = true; |
59 | return false; | 56 | return false; |
60 | } | 57 | } |
61 | 58 | ||
62 | rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); | 59 | rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); |
63 | if (rh == NULL) { | 60 | if (rh == NULL) { |
64 | *hotdrop = true; | 61 | *par->hotdrop = true; |
65 | return false; | 62 | return false; |
66 | } | 63 | } |
67 | 64 | ||
@@ -189,13 +186,9 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
189 | return false; | 186 | return false; |
190 | } | 187 | } |
191 | 188 | ||
192 | /* Called when user tries to insert an entry of this type. */ | 189 | static bool rt_mt6_check(const struct xt_mtchk_param *par) |
193 | static bool | ||
194 | rt_mt6_check(const char *tablename, const void *entry, | ||
195 | const struct xt_match *match, void *matchinfo, | ||
196 | unsigned int hook_mask) | ||
197 | { | 190 | { |
198 | const struct ip6t_rt *rtinfo = matchinfo; | 191 | const struct ip6t_rt *rtinfo = par->matchinfo; |
199 | 192 | ||
200 | if (rtinfo->invflags & ~IP6T_RT_INV_MASK) { | 193 | if (rtinfo->invflags & ~IP6T_RT_INV_MASK) { |
201 | pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags); | 194 | pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags); |
@@ -214,7 +207,7 @@ rt_mt6_check(const char *tablename, const void *entry, | |||
214 | 207 | ||
215 | static struct xt_match rt_mt6_reg __read_mostly = { | 208 | static struct xt_match rt_mt6_reg __read_mostly = { |
216 | .name = "rt", | 209 | .name = "rt", |
217 | .family = AF_INET6, | 210 | .family = NFPROTO_IPV6, |
218 | .match = rt_mt6, | 211 | .match = rt_mt6, |
219 | .matchsize = sizeof(struct ip6t_rt), | 212 | .matchsize = sizeof(struct ip6t_rt), |
220 | .checkentry = rt_mt6_check, | 213 | .checkentry = rt_mt6_check, |
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index 55a2c290bad4..b110a8a85a14 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c | |||
@@ -68,7 +68,7 @@ ip6t_local_in_hook(unsigned int hook, | |||
68 | int (*okfn)(struct sk_buff *)) | 68 | int (*okfn)(struct sk_buff *)) |
69 | { | 69 | { |
70 | return ip6t_do_table(skb, hook, in, out, | 70 | return ip6t_do_table(skb, hook, in, out, |
71 | nf_local_in_net(in, out)->ipv6.ip6table_filter); | 71 | dev_net(in)->ipv6.ip6table_filter); |
72 | } | 72 | } |
73 | 73 | ||
74 | static unsigned int | 74 | static unsigned int |
@@ -79,7 +79,7 @@ ip6t_forward_hook(unsigned int hook, | |||
79 | int (*okfn)(struct sk_buff *)) | 79 | int (*okfn)(struct sk_buff *)) |
80 | { | 80 | { |
81 | return ip6t_do_table(skb, hook, in, out, | 81 | return ip6t_do_table(skb, hook, in, out, |
82 | nf_forward_net(in, out)->ipv6.ip6table_filter); | 82 | dev_net(in)->ipv6.ip6table_filter); |
83 | } | 83 | } |
84 | 84 | ||
85 | static unsigned int | 85 | static unsigned int |
@@ -100,7 +100,7 @@ ip6t_local_out_hook(unsigned int hook, | |||
100 | #endif | 100 | #endif |
101 | 101 | ||
102 | return ip6t_do_table(skb, hook, in, out, | 102 | return ip6t_do_table(skb, hook, in, out, |
103 | nf_local_out_net(in, out)->ipv6.ip6table_filter); | 103 | dev_net(out)->ipv6.ip6table_filter); |
104 | } | 104 | } |
105 | 105 | ||
106 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { | 106 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { |
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index f405cea21a8b..d0b31b259d4d 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
@@ -67,17 +67,29 @@ static struct xt_table packet_mangler = { | |||
67 | 67 | ||
68 | /* The work comes in here from netfilter.c. */ | 68 | /* The work comes in here from netfilter.c. */ |
69 | static unsigned int | 69 | static unsigned int |
70 | ip6t_route_hook(unsigned int hook, | 70 | ip6t_in_hook(unsigned int hook, |
71 | struct sk_buff *skb, | 71 | struct sk_buff *skb, |
72 | const struct net_device *in, | 72 | const struct net_device *in, |
73 | const struct net_device *out, | 73 | const struct net_device *out, |
74 | int (*okfn)(struct sk_buff *)) | 74 | int (*okfn)(struct sk_buff *)) |
75 | { | 75 | { |
76 | return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle); | 76 | return ip6t_do_table(skb, hook, in, out, |
77 | dev_net(in)->ipv6.ip6table_mangle); | ||
77 | } | 78 | } |
78 | 79 | ||
79 | static unsigned int | 80 | static unsigned int |
80 | ip6t_local_hook(unsigned int hook, | 81 | ip6t_post_routing_hook(unsigned int hook, |
82 | struct sk_buff *skb, | ||
83 | const struct net_device *in, | ||
84 | const struct net_device *out, | ||
85 | int (*okfn)(struct sk_buff *)) | ||
86 | { | ||
87 | return ip6t_do_table(skb, hook, in, out, | ||
88 | dev_net(out)->ipv6.ip6table_mangle); | ||
89 | } | ||
90 | |||
91 | static unsigned int | ||
92 | ip6t_local_out_hook(unsigned int hook, | ||
81 | struct sk_buff *skb, | 93 | struct sk_buff *skb, |
82 | const struct net_device *in, | 94 | const struct net_device *in, |
83 | const struct net_device *out, | 95 | const struct net_device *out, |
@@ -108,7 +120,8 @@ ip6t_local_hook(unsigned int hook, | |||
108 | /* flowlabel and prio (includes version, which shouldn't change either */ | 120 | /* flowlabel and prio (includes version, which shouldn't change either */ |
109 | flowlabel = *((u_int32_t *)ipv6_hdr(skb)); | 121 | flowlabel = *((u_int32_t *)ipv6_hdr(skb)); |
110 | 122 | ||
111 | ret = ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle); | 123 | ret = ip6t_do_table(skb, hook, in, out, |
124 | dev_net(out)->ipv6.ip6table_mangle); | ||
112 | 125 | ||
113 | if (ret != NF_DROP && ret != NF_STOLEN | 126 | if (ret != NF_DROP && ret != NF_STOLEN |
114 | && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) | 127 | && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) |
@@ -122,35 +135,35 @@ ip6t_local_hook(unsigned int hook, | |||
122 | 135 | ||
123 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { | 136 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { |
124 | { | 137 | { |
125 | .hook = ip6t_route_hook, | 138 | .hook = ip6t_in_hook, |
126 | .owner = THIS_MODULE, | 139 | .owner = THIS_MODULE, |
127 | .pf = PF_INET6, | 140 | .pf = PF_INET6, |
128 | .hooknum = NF_INET_PRE_ROUTING, | 141 | .hooknum = NF_INET_PRE_ROUTING, |
129 | .priority = NF_IP6_PRI_MANGLE, | 142 | .priority = NF_IP6_PRI_MANGLE, |
130 | }, | 143 | }, |
131 | { | 144 | { |
132 | .hook = ip6t_route_hook, | 145 | .hook = ip6t_in_hook, |
133 | .owner = THIS_MODULE, | 146 | .owner = THIS_MODULE, |
134 | .pf = PF_INET6, | 147 | .pf = PF_INET6, |
135 | .hooknum = NF_INET_LOCAL_IN, | 148 | .hooknum = NF_INET_LOCAL_IN, |
136 | .priority = NF_IP6_PRI_MANGLE, | 149 | .priority = NF_IP6_PRI_MANGLE, |
137 | }, | 150 | }, |
138 | { | 151 | { |
139 | .hook = ip6t_route_hook, | 152 | .hook = ip6t_in_hook, |
140 | .owner = THIS_MODULE, | 153 | .owner = THIS_MODULE, |
141 | .pf = PF_INET6, | 154 | .pf = PF_INET6, |
142 | .hooknum = NF_INET_FORWARD, | 155 | .hooknum = NF_INET_FORWARD, |
143 | .priority = NF_IP6_PRI_MANGLE, | 156 | .priority = NF_IP6_PRI_MANGLE, |
144 | }, | 157 | }, |
145 | { | 158 | { |
146 | .hook = ip6t_local_hook, | 159 | .hook = ip6t_local_out_hook, |
147 | .owner = THIS_MODULE, | 160 | .owner = THIS_MODULE, |
148 | .pf = PF_INET6, | 161 | .pf = PF_INET6, |
149 | .hooknum = NF_INET_LOCAL_OUT, | 162 | .hooknum = NF_INET_LOCAL_OUT, |
150 | .priority = NF_IP6_PRI_MANGLE, | 163 | .priority = NF_IP6_PRI_MANGLE, |
151 | }, | 164 | }, |
152 | { | 165 | { |
153 | .hook = ip6t_route_hook, | 166 | .hook = ip6t_post_routing_hook, |
154 | .owner = THIS_MODULE, | 167 | .owner = THIS_MODULE, |
155 | .pf = PF_INET6, | 168 | .pf = PF_INET6, |
156 | .hooknum = NF_INET_POST_ROUTING, | 169 | .hooknum = NF_INET_POST_ROUTING, |
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index 92b91077ac29..109fab6f831a 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c | |||
@@ -45,25 +45,37 @@ static struct xt_table packet_raw = { | |||
45 | 45 | ||
46 | /* The work comes in here from netfilter.c. */ | 46 | /* The work comes in here from netfilter.c. */ |
47 | static unsigned int | 47 | static unsigned int |
48 | ip6t_hook(unsigned int hook, | 48 | ip6t_pre_routing_hook(unsigned int hook, |
49 | struct sk_buff *skb, | 49 | struct sk_buff *skb, |
50 | const struct net_device *in, | 50 | const struct net_device *in, |
51 | const struct net_device *out, | 51 | const struct net_device *out, |
52 | int (*okfn)(struct sk_buff *)) | 52 | int (*okfn)(struct sk_buff *)) |
53 | { | 53 | { |
54 | return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_raw); | 54 | return ip6t_do_table(skb, hook, in, out, |
55 | dev_net(in)->ipv6.ip6table_raw); | ||
56 | } | ||
57 | |||
58 | static unsigned int | ||
59 | ip6t_local_out_hook(unsigned int hook, | ||
60 | struct sk_buff *skb, | ||
61 | const struct net_device *in, | ||
62 | const struct net_device *out, | ||
63 | int (*okfn)(struct sk_buff *)) | ||
64 | { | ||
65 | return ip6t_do_table(skb, hook, in, out, | ||
66 | dev_net(out)->ipv6.ip6table_raw); | ||
55 | } | 67 | } |
56 | 68 | ||
57 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { | 69 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { |
58 | { | 70 | { |
59 | .hook = ip6t_hook, | 71 | .hook = ip6t_pre_routing_hook, |
60 | .pf = PF_INET6, | 72 | .pf = PF_INET6, |
61 | .hooknum = NF_INET_PRE_ROUTING, | 73 | .hooknum = NF_INET_PRE_ROUTING, |
62 | .priority = NF_IP6_PRI_FIRST, | 74 | .priority = NF_IP6_PRI_FIRST, |
63 | .owner = THIS_MODULE, | 75 | .owner = THIS_MODULE, |
64 | }, | 76 | }, |
65 | { | 77 | { |
66 | .hook = ip6t_hook, | 78 | .hook = ip6t_local_out_hook, |
67 | .pf = PF_INET6, | 79 | .pf = PF_INET6, |
68 | .hooknum = NF_INET_LOCAL_OUT, | 80 | .hooknum = NF_INET_LOCAL_OUT, |
69 | .priority = NF_IP6_PRI_FIRST, | 81 | .priority = NF_IP6_PRI_FIRST, |
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c index 6e7131036bc6..20bc52f13e43 100644 --- a/net/ipv6/netfilter/ip6table_security.c +++ b/net/ipv6/netfilter/ip6table_security.c | |||
@@ -72,7 +72,7 @@ ip6t_local_in_hook(unsigned int hook, | |||
72 | int (*okfn)(struct sk_buff *)) | 72 | int (*okfn)(struct sk_buff *)) |
73 | { | 73 | { |
74 | return ip6t_do_table(skb, hook, in, out, | 74 | return ip6t_do_table(skb, hook, in, out, |
75 | nf_local_in_net(in, out)->ipv6.ip6table_security); | 75 | dev_net(in)->ipv6.ip6table_security); |
76 | } | 76 | } |
77 | 77 | ||
78 | static unsigned int | 78 | static unsigned int |
@@ -83,7 +83,7 @@ ip6t_forward_hook(unsigned int hook, | |||
83 | int (*okfn)(struct sk_buff *)) | 83 | int (*okfn)(struct sk_buff *)) |
84 | { | 84 | { |
85 | return ip6t_do_table(skb, hook, in, out, | 85 | return ip6t_do_table(skb, hook, in, out, |
86 | nf_forward_net(in, out)->ipv6.ip6table_security); | 86 | dev_net(in)->ipv6.ip6table_security); |
87 | } | 87 | } |
88 | 88 | ||
89 | static unsigned int | 89 | static unsigned int |
@@ -95,7 +95,7 @@ ip6t_local_out_hook(unsigned int hook, | |||
95 | { | 95 | { |
96 | /* TBD: handle short packets via raw socket */ | 96 | /* TBD: handle short packets via raw socket */ |
97 | return ip6t_do_table(skb, hook, in, out, | 97 | return ip6t_do_table(skb, hook, in, out, |
98 | nf_local_out_net(in, out)->ipv6.ip6table_security); | 98 | dev_net(out)->ipv6.ip6table_security); |
99 | } | 99 | } |
100 | 100 | ||
101 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { | 101 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 85050c072abd..e91db16611d9 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -211,11 +211,10 @@ static unsigned int ipv6_defrag(unsigned int hooknum, | |||
211 | return NF_STOLEN; | 211 | return NF_STOLEN; |
212 | } | 212 | } |
213 | 213 | ||
214 | static unsigned int ipv6_conntrack_in(unsigned int hooknum, | 214 | static unsigned int __ipv6_conntrack_in(struct net *net, |
215 | struct sk_buff *skb, | 215 | unsigned int hooknum, |
216 | const struct net_device *in, | 216 | struct sk_buff *skb, |
217 | const struct net_device *out, | 217 | int (*okfn)(struct sk_buff *)) |
218 | int (*okfn)(struct sk_buff *)) | ||
219 | { | 218 | { |
220 | struct sk_buff *reasm = skb->nfct_reasm; | 219 | struct sk_buff *reasm = skb->nfct_reasm; |
221 | 220 | ||
@@ -225,7 +224,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum, | |||
225 | if (!reasm->nfct) { | 224 | if (!reasm->nfct) { |
226 | unsigned int ret; | 225 | unsigned int ret; |
227 | 226 | ||
228 | ret = nf_conntrack_in(PF_INET6, hooknum, reasm); | 227 | ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm); |
229 | if (ret != NF_ACCEPT) | 228 | if (ret != NF_ACCEPT) |
230 | return ret; | 229 | return ret; |
231 | } | 230 | } |
@@ -235,7 +234,16 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum, | |||
235 | return NF_ACCEPT; | 234 | return NF_ACCEPT; |
236 | } | 235 | } |
237 | 236 | ||
238 | return nf_conntrack_in(PF_INET6, hooknum, skb); | 237 | return nf_conntrack_in(net, PF_INET6, hooknum, skb); |
238 | } | ||
239 | |||
240 | static unsigned int ipv6_conntrack_in(unsigned int hooknum, | ||
241 | struct sk_buff *skb, | ||
242 | const struct net_device *in, | ||
243 | const struct net_device *out, | ||
244 | int (*okfn)(struct sk_buff *)) | ||
245 | { | ||
246 | return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn); | ||
239 | } | 247 | } |
240 | 248 | ||
241 | static unsigned int ipv6_conntrack_local(unsigned int hooknum, | 249 | static unsigned int ipv6_conntrack_local(unsigned int hooknum, |
@@ -250,7 +258,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum, | |||
250 | printk("ipv6_conntrack_local: packet too short\n"); | 258 | printk("ipv6_conntrack_local: packet too short\n"); |
251 | return NF_ACCEPT; | 259 | return NF_ACCEPT; |
252 | } | 260 | } |
253 | return ipv6_conntrack_in(hooknum, skb, in, out, okfn); | 261 | return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn); |
254 | } | 262 | } |
255 | 263 | ||
256 | static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { | 264 | static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 14d47d833545..05726177903f 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -81,7 +81,7 @@ static int icmpv6_packet(struct nf_conn *ct, | |||
81 | const struct sk_buff *skb, | 81 | const struct sk_buff *skb, |
82 | unsigned int dataoff, | 82 | unsigned int dataoff, |
83 | enum ip_conntrack_info ctinfo, | 83 | enum ip_conntrack_info ctinfo, |
84 | int pf, | 84 | u_int8_t pf, |
85 | unsigned int hooknum) | 85 | unsigned int hooknum) |
86 | { | 86 | { |
87 | /* Try to delete connection immediately after all replies: | 87 | /* Try to delete connection immediately after all replies: |
@@ -93,7 +93,7 @@ static int icmpv6_packet(struct nf_conn *ct, | |||
93 | nf_ct_kill_acct(ct, ctinfo, skb); | 93 | nf_ct_kill_acct(ct, ctinfo, skb); |
94 | } else { | 94 | } else { |
95 | atomic_inc(&ct->proto.icmp.count); | 95 | atomic_inc(&ct->proto.icmp.count); |
96 | nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); | 96 | nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct); |
97 | nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout); | 97 | nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout); |
98 | } | 98 | } |
99 | 99 | ||
@@ -122,7 +122,8 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, | |||
122 | } | 122 | } |
123 | 123 | ||
124 | static int | 124 | static int |
125 | icmpv6_error_message(struct sk_buff *skb, | 125 | icmpv6_error_message(struct net *net, |
126 | struct sk_buff *skb, | ||
126 | unsigned int icmp6off, | 127 | unsigned int icmp6off, |
127 | enum ip_conntrack_info *ctinfo, | 128 | enum ip_conntrack_info *ctinfo, |
128 | unsigned int hooknum) | 129 | unsigned int hooknum) |
@@ -156,7 +157,7 @@ icmpv6_error_message(struct sk_buff *skb, | |||
156 | 157 | ||
157 | *ctinfo = IP_CT_RELATED; | 158 | *ctinfo = IP_CT_RELATED; |
158 | 159 | ||
159 | h = nf_conntrack_find_get(&intuple); | 160 | h = nf_conntrack_find_get(net, &intuple); |
160 | if (!h) { | 161 | if (!h) { |
161 | pr_debug("icmpv6_error: no match\n"); | 162 | pr_debug("icmpv6_error: no match\n"); |
162 | return -NF_ACCEPT; | 163 | return -NF_ACCEPT; |
@@ -172,21 +173,21 @@ icmpv6_error_message(struct sk_buff *skb, | |||
172 | } | 173 | } |
173 | 174 | ||
174 | static int | 175 | static int |
175 | icmpv6_error(struct sk_buff *skb, unsigned int dataoff, | 176 | icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff, |
176 | enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum) | 177 | enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum) |
177 | { | 178 | { |
178 | const struct icmp6hdr *icmp6h; | 179 | const struct icmp6hdr *icmp6h; |
179 | struct icmp6hdr _ih; | 180 | struct icmp6hdr _ih; |
180 | 181 | ||
181 | icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); | 182 | icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); |
182 | if (icmp6h == NULL) { | 183 | if (icmp6h == NULL) { |
183 | if (LOG_INVALID(IPPROTO_ICMPV6)) | 184 | if (LOG_INVALID(net, IPPROTO_ICMPV6)) |
184 | nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, | 185 | nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, |
185 | "nf_ct_icmpv6: short packet "); | 186 | "nf_ct_icmpv6: short packet "); |
186 | return -NF_ACCEPT; | 187 | return -NF_ACCEPT; |
187 | } | 188 | } |
188 | 189 | ||
189 | if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && | 190 | if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && |
190 | nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { | 191 | nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { |
191 | nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, | 192 | nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, |
192 | "nf_ct_icmpv6: ICMPv6 checksum failed\n"); | 193 | "nf_ct_icmpv6: ICMPv6 checksum failed\n"); |
@@ -197,7 +198,7 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff, | |||
197 | if (icmp6h->icmp6_type >= 128) | 198 | if (icmp6h->icmp6_type >= 128) |
198 | return NF_ACCEPT; | 199 | return NF_ACCEPT; |
199 | 200 | ||
200 | return icmpv6_error_message(skb, dataoff, ctinfo, hooknum); | 201 | return icmpv6_error_message(net, skb, dataoff, ctinfo, hooknum); |
201 | } | 202 | } |
202 | 203 | ||
203 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 204 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 52d06dd4b817..9967ac7a01a8 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/ipv6.h> | 27 | #include <linux/ipv6.h> |
28 | #include <linux/icmpv6.h> | 28 | #include <linux/icmpv6.h> |
29 | #include <linux/random.h> | 29 | #include <linux/random.h> |
30 | #include <linux/jhash.h> | ||
31 | 30 | ||
32 | #include <net/sock.h> | 31 | #include <net/sock.h> |
33 | #include <net/snmp.h> | 32 | #include <net/snmp.h> |
@@ -103,39 +102,12 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = { | |||
103 | }; | 102 | }; |
104 | #endif | 103 | #endif |
105 | 104 | ||
106 | static unsigned int ip6qhashfn(__be32 id, const struct in6_addr *saddr, | ||
107 | const struct in6_addr *daddr) | ||
108 | { | ||
109 | u32 a, b, c; | ||
110 | |||
111 | a = (__force u32)saddr->s6_addr32[0]; | ||
112 | b = (__force u32)saddr->s6_addr32[1]; | ||
113 | c = (__force u32)saddr->s6_addr32[2]; | ||
114 | |||
115 | a += JHASH_GOLDEN_RATIO; | ||
116 | b += JHASH_GOLDEN_RATIO; | ||
117 | c += nf_frags.rnd; | ||
118 | __jhash_mix(a, b, c); | ||
119 | |||
120 | a += (__force u32)saddr->s6_addr32[3]; | ||
121 | b += (__force u32)daddr->s6_addr32[0]; | ||
122 | c += (__force u32)daddr->s6_addr32[1]; | ||
123 | __jhash_mix(a, b, c); | ||
124 | |||
125 | a += (__force u32)daddr->s6_addr32[2]; | ||
126 | b += (__force u32)daddr->s6_addr32[3]; | ||
127 | c += (__force u32)id; | ||
128 | __jhash_mix(a, b, c); | ||
129 | |||
130 | return c & (INETFRAGS_HASHSZ - 1); | ||
131 | } | ||
132 | |||
133 | static unsigned int nf_hashfn(struct inet_frag_queue *q) | 105 | static unsigned int nf_hashfn(struct inet_frag_queue *q) |
134 | { | 106 | { |
135 | const struct nf_ct_frag6_queue *nq; | 107 | const struct nf_ct_frag6_queue *nq; |
136 | 108 | ||
137 | nq = container_of(q, struct nf_ct_frag6_queue, q); | 109 | nq = container_of(q, struct nf_ct_frag6_queue, q); |
138 | return ip6qhashfn(nq->id, &nq->saddr, &nq->daddr); | 110 | return inet6_hash_frag(nq->id, &nq->saddr, &nq->daddr, nf_frags.rnd); |
139 | } | 111 | } |
140 | 112 | ||
141 | static void nf_skb_free(struct sk_buff *skb) | 113 | static void nf_skb_free(struct sk_buff *skb) |
@@ -209,7 +181,7 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) | |||
209 | arg.dst = dst; | 181 | arg.dst = dst; |
210 | 182 | ||
211 | read_lock_bh(&nf_frags.lock); | 183 | read_lock_bh(&nf_frags.lock); |
212 | hash = ip6qhashfn(id, src, dst); | 184 | hash = inet6_hash_frag(id, src, dst, nf_frags.rnd); |
213 | 185 | ||
214 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); | 186 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); |
215 | local_bh_enable(); | 187 | local_bh_enable(); |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 0179b66864f1..07f0b76e7427 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -29,8 +29,6 @@ | |||
29 | #include <net/transp_v6.h> | 29 | #include <net/transp_v6.h> |
30 | #include <net/ipv6.h> | 30 | #include <net/ipv6.h> |
31 | 31 | ||
32 | static struct proc_dir_entry *proc_net_devsnmp6; | ||
33 | |||
34 | static int sockstat6_seq_show(struct seq_file *seq, void *v) | 32 | static int sockstat6_seq_show(struct seq_file *seq, void *v) |
35 | { | 33 | { |
36 | struct net *net = seq->private; | 34 | struct net *net = seq->private; |
@@ -48,6 +46,19 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v) | |||
48 | return 0; | 46 | return 0; |
49 | } | 47 | } |
50 | 48 | ||
49 | static int sockstat6_seq_open(struct inode *inode, struct file *file) | ||
50 | { | ||
51 | return single_open_net(inode, file, sockstat6_seq_show); | ||
52 | } | ||
53 | |||
54 | static const struct file_operations sockstat6_seq_fops = { | ||
55 | .owner = THIS_MODULE, | ||
56 | .open = sockstat6_seq_open, | ||
57 | .read = seq_read, | ||
58 | .llseek = seq_lseek, | ||
59 | .release = single_release_net, | ||
60 | }; | ||
61 | |||
51 | static struct snmp_mib snmp6_ipstats_list[] = { | 62 | static struct snmp_mib snmp6_ipstats_list[] = { |
52 | /* ipv6 mib according to RFC 2465 */ | 63 | /* ipv6 mib according to RFC 2465 */ |
53 | SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES), | 64 | SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES), |
@@ -164,44 +175,52 @@ snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist) | |||
164 | 175 | ||
165 | static int snmp6_seq_show(struct seq_file *seq, void *v) | 176 | static int snmp6_seq_show(struct seq_file *seq, void *v) |
166 | { | 177 | { |
167 | struct inet6_dev *idev = (struct inet6_dev *)seq->private; | 178 | struct net *net = (struct net *)seq->private; |
168 | 179 | ||
169 | if (idev) { | 180 | snmp6_seq_show_item(seq, (void **)net->mib.ipv6_statistics, |
170 | seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex); | 181 | snmp6_ipstats_list); |
171 | snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list); | 182 | snmp6_seq_show_item(seq, (void **)net->mib.icmpv6_statistics, |
172 | snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); | 183 | snmp6_icmp6_list); |
173 | snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg); | 184 | snmp6_seq_show_icmpv6msg(seq, (void **)net->mib.icmpv6msg_statistics); |
174 | } else { | 185 | snmp6_seq_show_item(seq, (void **)net->mib.udp_stats_in6, |
175 | snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list); | 186 | snmp6_udp6_list); |
176 | snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list); | 187 | snmp6_seq_show_item(seq, (void **)net->mib.udplite_stats_in6, |
177 | snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics); | 188 | snmp6_udplite6_list); |
178 | snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list); | ||
179 | snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list); | ||
180 | } | ||
181 | return 0; | 189 | return 0; |
182 | } | 190 | } |
183 | 191 | ||
184 | static int sockstat6_seq_open(struct inode *inode, struct file *file) | 192 | static int snmp6_seq_open(struct inode *inode, struct file *file) |
185 | { | 193 | { |
186 | return single_open_net(inode, file, sockstat6_seq_show); | 194 | return single_open_net(inode, file, snmp6_seq_show); |
187 | } | 195 | } |
188 | 196 | ||
189 | static const struct file_operations sockstat6_seq_fops = { | 197 | static const struct file_operations snmp6_seq_fops = { |
190 | .owner = THIS_MODULE, | 198 | .owner = THIS_MODULE, |
191 | .open = sockstat6_seq_open, | 199 | .open = snmp6_seq_open, |
192 | .read = seq_read, | 200 | .read = seq_read, |
193 | .llseek = seq_lseek, | 201 | .llseek = seq_lseek, |
194 | .release = single_release_net, | 202 | .release = single_release_net, |
195 | }; | 203 | }; |
196 | 204 | ||
197 | static int snmp6_seq_open(struct inode *inode, struct file *file) | 205 | static int snmp6_dev_seq_show(struct seq_file *seq, void *v) |
198 | { | 206 | { |
199 | return single_open(file, snmp6_seq_show, PDE(inode)->data); | 207 | struct inet6_dev *idev = (struct inet6_dev *)seq->private; |
208 | |||
209 | seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex); | ||
210 | snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list); | ||
211 | snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); | ||
212 | snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg); | ||
213 | return 0; | ||
200 | } | 214 | } |
201 | 215 | ||
202 | static const struct file_operations snmp6_seq_fops = { | 216 | static int snmp6_dev_seq_open(struct inode *inode, struct file *file) |
217 | { | ||
218 | return single_open(file, snmp6_dev_seq_show, PDE(inode)->data); | ||
219 | } | ||
220 | |||
221 | static const struct file_operations snmp6_dev_seq_fops = { | ||
203 | .owner = THIS_MODULE, | 222 | .owner = THIS_MODULE, |
204 | .open = snmp6_seq_open, | 223 | .open = snmp6_dev_seq_open, |
205 | .read = seq_read, | 224 | .read = seq_read, |
206 | .llseek = seq_lseek, | 225 | .llseek = seq_lseek, |
207 | .release = single_release, | 226 | .release = single_release, |
@@ -210,18 +229,18 @@ static const struct file_operations snmp6_seq_fops = { | |||
210 | int snmp6_register_dev(struct inet6_dev *idev) | 229 | int snmp6_register_dev(struct inet6_dev *idev) |
211 | { | 230 | { |
212 | struct proc_dir_entry *p; | 231 | struct proc_dir_entry *p; |
232 | struct net *net; | ||
213 | 233 | ||
214 | if (!idev || !idev->dev) | 234 | if (!idev || !idev->dev) |
215 | return -EINVAL; | 235 | return -EINVAL; |
216 | 236 | ||
217 | if (!net_eq(dev_net(idev->dev), &init_net)) | 237 | net = dev_net(idev->dev); |
218 | return 0; | 238 | if (!net->mib.proc_net_devsnmp6) |
219 | |||
220 | if (!proc_net_devsnmp6) | ||
221 | return -ENOENT; | 239 | return -ENOENT; |
222 | 240 | ||
223 | p = proc_create_data(idev->dev->name, S_IRUGO, | 241 | p = proc_create_data(idev->dev->name, S_IRUGO, |
224 | proc_net_devsnmp6, &snmp6_seq_fops, idev); | 242 | net->mib.proc_net_devsnmp6, |
243 | &snmp6_dev_seq_fops, idev); | ||
225 | if (!p) | 244 | if (!p) |
226 | return -ENOMEM; | 245 | return -ENOMEM; |
227 | 246 | ||
@@ -231,12 +250,13 @@ int snmp6_register_dev(struct inet6_dev *idev) | |||
231 | 250 | ||
232 | int snmp6_unregister_dev(struct inet6_dev *idev) | 251 | int snmp6_unregister_dev(struct inet6_dev *idev) |
233 | { | 252 | { |
234 | if (!proc_net_devsnmp6) | 253 | struct net *net = dev_net(idev->dev); |
254 | if (!net->mib.proc_net_devsnmp6) | ||
235 | return -ENOENT; | 255 | return -ENOENT; |
236 | if (!idev || !idev->stats.proc_dir_entry) | 256 | if (!idev || !idev->stats.proc_dir_entry) |
237 | return -EINVAL; | 257 | return -EINVAL; |
238 | remove_proc_entry(idev->stats.proc_dir_entry->name, | 258 | remove_proc_entry(idev->stats.proc_dir_entry->name, |
239 | proc_net_devsnmp6); | 259 | net->mib.proc_net_devsnmp6); |
240 | idev->stats.proc_dir_entry = NULL; | 260 | idev->stats.proc_dir_entry = NULL; |
241 | return 0; | 261 | return 0; |
242 | } | 262 | } |
@@ -246,12 +266,27 @@ static int ipv6_proc_init_net(struct net *net) | |||
246 | if (!proc_net_fops_create(net, "sockstat6", S_IRUGO, | 266 | if (!proc_net_fops_create(net, "sockstat6", S_IRUGO, |
247 | &sockstat6_seq_fops)) | 267 | &sockstat6_seq_fops)) |
248 | return -ENOMEM; | 268 | return -ENOMEM; |
269 | |||
270 | if (!proc_net_fops_create(net, "snmp6", S_IRUGO, &snmp6_seq_fops)) | ||
271 | goto proc_snmp6_fail; | ||
272 | |||
273 | net->mib.proc_net_devsnmp6 = proc_mkdir("dev_snmp6", net->proc_net); | ||
274 | if (!net->mib.proc_net_devsnmp6) | ||
275 | goto proc_dev_snmp6_fail; | ||
249 | return 0; | 276 | return 0; |
277 | |||
278 | proc_snmp6_fail: | ||
279 | proc_net_remove(net, "sockstat6"); | ||
280 | proc_dev_snmp6_fail: | ||
281 | proc_net_remove(net, "dev_snmp6"); | ||
282 | return -ENOMEM; | ||
250 | } | 283 | } |
251 | 284 | ||
252 | static void ipv6_proc_exit_net(struct net *net) | 285 | static void ipv6_proc_exit_net(struct net *net) |
253 | { | 286 | { |
254 | proc_net_remove(net, "sockstat6"); | 287 | proc_net_remove(net, "sockstat6"); |
288 | proc_net_remove(net, "dev_snmp6"); | ||
289 | proc_net_remove(net, "snmp6"); | ||
255 | } | 290 | } |
256 | 291 | ||
257 | static struct pernet_operations ipv6_proc_ops = { | 292 | static struct pernet_operations ipv6_proc_ops = { |
@@ -261,33 +296,11 @@ static struct pernet_operations ipv6_proc_ops = { | |||
261 | 296 | ||
262 | int __init ipv6_misc_proc_init(void) | 297 | int __init ipv6_misc_proc_init(void) |
263 | { | 298 | { |
264 | int rc = 0; | 299 | return register_pernet_subsys(&ipv6_proc_ops); |
265 | |||
266 | if (register_pernet_subsys(&ipv6_proc_ops)) | ||
267 | goto proc_net_fail; | ||
268 | |||
269 | if (!proc_net_fops_create(&init_net, "snmp6", S_IRUGO, &snmp6_seq_fops)) | ||
270 | goto proc_snmp6_fail; | ||
271 | |||
272 | proc_net_devsnmp6 = proc_mkdir("dev_snmp6", init_net.proc_net); | ||
273 | if (!proc_net_devsnmp6) | ||
274 | goto proc_dev_snmp6_fail; | ||
275 | out: | ||
276 | return rc; | ||
277 | |||
278 | proc_dev_snmp6_fail: | ||
279 | proc_net_remove(&init_net, "snmp6"); | ||
280 | proc_snmp6_fail: | ||
281 | unregister_pernet_subsys(&ipv6_proc_ops); | ||
282 | proc_net_fail: | ||
283 | rc = -ENOMEM; | ||
284 | goto out; | ||
285 | } | 300 | } |
286 | 301 | ||
287 | void ipv6_misc_proc_exit(void) | 302 | void ipv6_misc_proc_exit(void) |
288 | { | 303 | { |
289 | proc_net_remove(&init_net, "dev_snmp6"); | ||
290 | proc_net_remove(&init_net, "snmp6"); | ||
291 | unregister_pernet_subsys(&ipv6_proc_ops); | 304 | unregister_pernet_subsys(&ipv6_proc_ops); |
292 | } | 305 | } |
293 | 306 | ||
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index e53e493606c5..2ba04d41dc25 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -638,7 +638,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, | |||
638 | if (err) | 638 | if (err) |
639 | goto error_fault; | 639 | goto error_fault; |
640 | 640 | ||
641 | IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); | 641 | IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); |
642 | err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, | 642 | err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, |
643 | dst_output); | 643 | dst_output); |
644 | if (err > 0) | 644 | if (err > 0) |
@@ -652,7 +652,7 @@ error_fault: | |||
652 | err = -EFAULT; | 652 | err = -EFAULT; |
653 | kfree_skb(skb); | 653 | kfree_skb(skb); |
654 | error: | 654 | error: |
655 | IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); | 655 | IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); |
656 | return err; | 656 | return err; |
657 | } | 657 | } |
658 | 658 | ||
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 89184b576e23..af12de071f4c 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -99,8 +99,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, | |||
99 | * callers should be careful not to use the hash value outside the ipfrag_lock | 99 | * callers should be careful not to use the hash value outside the ipfrag_lock |
100 | * as doing so could race with ipfrag_hash_rnd being recalculated. | 100 | * as doing so could race with ipfrag_hash_rnd being recalculated. |
101 | */ | 101 | */ |
102 | static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr, | 102 | unsigned int inet6_hash_frag(__be32 id, const struct in6_addr *saddr, |
103 | struct in6_addr *daddr) | 103 | const struct in6_addr *daddr, u32 rnd) |
104 | { | 104 | { |
105 | u32 a, b, c; | 105 | u32 a, b, c; |
106 | 106 | ||
@@ -110,7 +110,7 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr, | |||
110 | 110 | ||
111 | a += JHASH_GOLDEN_RATIO; | 111 | a += JHASH_GOLDEN_RATIO; |
112 | b += JHASH_GOLDEN_RATIO; | 112 | b += JHASH_GOLDEN_RATIO; |
113 | c += ip6_frags.rnd; | 113 | c += rnd; |
114 | __jhash_mix(a, b, c); | 114 | __jhash_mix(a, b, c); |
115 | 115 | ||
116 | a += (__force u32)saddr->s6_addr32[3]; | 116 | a += (__force u32)saddr->s6_addr32[3]; |
@@ -125,13 +125,14 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr, | |||
125 | 125 | ||
126 | return c & (INETFRAGS_HASHSZ - 1); | 126 | return c & (INETFRAGS_HASHSZ - 1); |
127 | } | 127 | } |
128 | EXPORT_SYMBOL_GPL(inet6_hash_frag); | ||
128 | 129 | ||
129 | static unsigned int ip6_hashfn(struct inet_frag_queue *q) | 130 | static unsigned int ip6_hashfn(struct inet_frag_queue *q) |
130 | { | 131 | { |
131 | struct frag_queue *fq; | 132 | struct frag_queue *fq; |
132 | 133 | ||
133 | fq = container_of(q, struct frag_queue, q); | 134 | fq = container_of(q, struct frag_queue, q); |
134 | return ip6qhashfn(fq->id, &fq->saddr, &fq->daddr); | 135 | return inet6_hash_frag(fq->id, &fq->saddr, &fq->daddr, ip6_frags.rnd); |
135 | } | 136 | } |
136 | 137 | ||
137 | int ip6_frag_match(struct inet_frag_queue *q, void *a) | 138 | int ip6_frag_match(struct inet_frag_queue *q, void *a) |
@@ -188,7 +189,7 @@ static void ip6_evictor(struct net *net, struct inet6_dev *idev) | |||
188 | 189 | ||
189 | evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags); | 190 | evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags); |
190 | if (evicted) | 191 | if (evicted) |
191 | IP6_ADD_STATS_BH(idev, IPSTATS_MIB_REASMFAILS, evicted); | 192 | IP6_ADD_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS, evicted); |
192 | } | 193 | } |
193 | 194 | ||
194 | static void ip6_frag_expire(unsigned long data) | 195 | static void ip6_frag_expire(unsigned long data) |
@@ -212,8 +213,8 @@ static void ip6_frag_expire(unsigned long data) | |||
212 | goto out; | 213 | goto out; |
213 | 214 | ||
214 | rcu_read_lock(); | 215 | rcu_read_lock(); |
215 | IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); | 216 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); |
216 | IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); | 217 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); |
217 | rcu_read_unlock(); | 218 | rcu_read_unlock(); |
218 | 219 | ||
219 | /* Don't send error if the first segment did not arrive. */ | 220 | /* Don't send error if the first segment did not arrive. */ |
@@ -247,7 +248,7 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst, | |||
247 | arg.dst = dst; | 248 | arg.dst = dst; |
248 | 249 | ||
249 | read_lock(&ip6_frags.lock); | 250 | read_lock(&ip6_frags.lock); |
250 | hash = ip6qhashfn(id, src, dst); | 251 | hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd); |
251 | 252 | ||
252 | q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); | 253 | q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); |
253 | if (q == NULL) | 254 | if (q == NULL) |
@@ -256,7 +257,7 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst, | |||
256 | return container_of(q, struct frag_queue, q); | 257 | return container_of(q, struct frag_queue, q); |
257 | 258 | ||
258 | oom: | 259 | oom: |
259 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS); | 260 | IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS); |
260 | return NULL; | 261 | return NULL; |
261 | } | 262 | } |
262 | 263 | ||
@@ -266,6 +267,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, | |||
266 | struct sk_buff *prev, *next; | 267 | struct sk_buff *prev, *next; |
267 | struct net_device *dev; | 268 | struct net_device *dev; |
268 | int offset, end; | 269 | int offset, end; |
270 | struct net *net = dev_net(skb->dst->dev); | ||
269 | 271 | ||
270 | if (fq->q.last_in & INET_FRAG_COMPLETE) | 272 | if (fq->q.last_in & INET_FRAG_COMPLETE) |
271 | goto err; | 273 | goto err; |
@@ -275,7 +277,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, | |||
275 | ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1))); | 277 | ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1))); |
276 | 278 | ||
277 | if ((unsigned int)end > IPV6_MAXPLEN) { | 279 | if ((unsigned int)end > IPV6_MAXPLEN) { |
278 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 280 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
279 | IPSTATS_MIB_INHDRERRORS); | 281 | IPSTATS_MIB_INHDRERRORS); |
280 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, | 282 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, |
281 | ((u8 *)&fhdr->frag_off - | 283 | ((u8 *)&fhdr->frag_off - |
@@ -308,7 +310,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, | |||
308 | /* RFC2460 says always send parameter problem in | 310 | /* RFC2460 says always send parameter problem in |
309 | * this case. -DaveM | 311 | * this case. -DaveM |
310 | */ | 312 | */ |
311 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 313 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), |
312 | IPSTATS_MIB_INHDRERRORS); | 314 | IPSTATS_MIB_INHDRERRORS); |
313 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, | 315 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, |
314 | offsetof(struct ipv6hdr, payload_len)); | 316 | offsetof(struct ipv6hdr, payload_len)); |
@@ -432,7 +434,8 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, | |||
432 | return -1; | 434 | return -1; |
433 | 435 | ||
434 | err: | 436 | err: |
435 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS); | 437 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), |
438 | IPSTATS_MIB_REASMFAILS); | ||
436 | kfree_skb(skb); | 439 | kfree_skb(skb); |
437 | return -1; | 440 | return -1; |
438 | } | 441 | } |
@@ -548,7 +551,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, | |||
548 | head->csum); | 551 | head->csum); |
549 | 552 | ||
550 | rcu_read_lock(); | 553 | rcu_read_lock(); |
551 | IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMOKS); | 554 | IP6_INC_STATS_BH(dev_net(dev), |
555 | __in6_dev_get(dev), IPSTATS_MIB_REASMOKS); | ||
552 | rcu_read_unlock(); | 556 | rcu_read_unlock(); |
553 | fq->q.fragments = NULL; | 557 | fq->q.fragments = NULL; |
554 | return 1; | 558 | return 1; |
@@ -562,7 +566,8 @@ out_oom: | |||
562 | printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n"); | 566 | printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n"); |
563 | out_fail: | 567 | out_fail: |
564 | rcu_read_lock(); | 568 | rcu_read_lock(); |
565 | IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); | 569 | IP6_INC_STATS_BH(dev_net(dev), |
570 | __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); | ||
566 | rcu_read_unlock(); | 571 | rcu_read_unlock(); |
567 | return -1; | 572 | return -1; |
568 | } | 573 | } |
@@ -572,24 +577,17 @@ static int ipv6_frag_rcv(struct sk_buff *skb) | |||
572 | struct frag_hdr *fhdr; | 577 | struct frag_hdr *fhdr; |
573 | struct frag_queue *fq; | 578 | struct frag_queue *fq; |
574 | struct ipv6hdr *hdr = ipv6_hdr(skb); | 579 | struct ipv6hdr *hdr = ipv6_hdr(skb); |
575 | struct net *net; | 580 | struct net *net = dev_net(skb->dst->dev); |
576 | 581 | ||
577 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMREQDS); | 582 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMREQDS); |
578 | 583 | ||
579 | /* Jumbo payload inhibits frag. header */ | 584 | /* Jumbo payload inhibits frag. header */ |
580 | if (hdr->payload_len==0) { | 585 | if (hdr->payload_len==0) |
581 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); | 586 | goto fail_hdr; |
582 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, | 587 | |
583 | skb_network_header_len(skb)); | ||
584 | return -1; | ||
585 | } | ||
586 | if (!pskb_may_pull(skb, (skb_transport_offset(skb) + | 588 | if (!pskb_may_pull(skb, (skb_transport_offset(skb) + |
587 | sizeof(struct frag_hdr)))) { | 589 | sizeof(struct frag_hdr)))) |
588 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); | 590 | goto fail_hdr; |
589 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, | ||
590 | skb_network_header_len(skb)); | ||
591 | return -1; | ||
592 | } | ||
593 | 591 | ||
594 | hdr = ipv6_hdr(skb); | 592 | hdr = ipv6_hdr(skb); |
595 | fhdr = (struct frag_hdr *)skb_transport_header(skb); | 593 | fhdr = (struct frag_hdr *)skb_transport_header(skb); |
@@ -597,13 +595,13 @@ static int ipv6_frag_rcv(struct sk_buff *skb) | |||
597 | if (!(fhdr->frag_off & htons(0xFFF9))) { | 595 | if (!(fhdr->frag_off & htons(0xFFF9))) { |
598 | /* It is not a fragmented frame */ | 596 | /* It is not a fragmented frame */ |
599 | skb->transport_header += sizeof(struct frag_hdr); | 597 | skb->transport_header += sizeof(struct frag_hdr); |
600 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS); | 598 | IP6_INC_STATS_BH(net, |
599 | ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS); | ||
601 | 600 | ||
602 | IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb); | 601 | IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb); |
603 | return 1; | 602 | return 1; |
604 | } | 603 | } |
605 | 604 | ||
606 | net = dev_net(skb->dev); | ||
607 | if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh) | 605 | if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh) |
608 | ip6_evictor(net, ip6_dst_idev(skb->dst)); | 606 | ip6_evictor(net, ip6_dst_idev(skb->dst)); |
609 | 607 | ||
@@ -620,9 +618,14 @@ static int ipv6_frag_rcv(struct sk_buff *skb) | |||
620 | return ret; | 618 | return ret; |
621 | } | 619 | } |
622 | 620 | ||
623 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS); | 621 | IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS); |
624 | kfree_skb(skb); | 622 | kfree_skb(skb); |
625 | return -1; | 623 | return -1; |
624 | |||
625 | fail_hdr: | ||
626 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); | ||
627 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb_network_header_len(skb)); | ||
628 | return -1; | ||
626 | } | 629 | } |
627 | 630 | ||
628 | static struct inet6_protocol frag_protocol = | 631 | static struct inet6_protocol frag_protocol = |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 9af6115f0f50..89dc69924340 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1003,6 +1003,25 @@ int icmp6_dst_gc(void) | |||
1003 | return more; | 1003 | return more; |
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | static void icmp6_clean_all(int (*func)(struct rt6_info *rt, void *arg), | ||
1007 | void *arg) | ||
1008 | { | ||
1009 | struct dst_entry *dst, **pprev; | ||
1010 | |||
1011 | spin_lock_bh(&icmp6_dst_lock); | ||
1012 | pprev = &icmp6_dst_gc_list; | ||
1013 | while ((dst = *pprev) != NULL) { | ||
1014 | struct rt6_info *rt = (struct rt6_info *) dst; | ||
1015 | if (func(rt, arg)) { | ||
1016 | *pprev = dst->next; | ||
1017 | dst_free(dst); | ||
1018 | } else { | ||
1019 | pprev = &dst->next; | ||
1020 | } | ||
1021 | } | ||
1022 | spin_unlock_bh(&icmp6_dst_lock); | ||
1023 | } | ||
1024 | |||
1006 | static int ip6_dst_gc(struct dst_ops *ops) | 1025 | static int ip6_dst_gc(struct dst_ops *ops) |
1007 | { | 1026 | { |
1008 | unsigned long now = jiffies; | 1027 | unsigned long now = jiffies; |
@@ -1814,16 +1833,19 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg) | |||
1814 | static int ip6_pkt_drop(struct sk_buff *skb, int code, int ipstats_mib_noroutes) | 1833 | static int ip6_pkt_drop(struct sk_buff *skb, int code, int ipstats_mib_noroutes) |
1815 | { | 1834 | { |
1816 | int type; | 1835 | int type; |
1836 | struct dst_entry *dst = skb->dst; | ||
1817 | switch (ipstats_mib_noroutes) { | 1837 | switch (ipstats_mib_noroutes) { |
1818 | case IPSTATS_MIB_INNOROUTES: | 1838 | case IPSTATS_MIB_INNOROUTES: |
1819 | type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); | 1839 | type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); |
1820 | if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) { | 1840 | if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) { |
1821 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); | 1841 | IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), |
1842 | IPSTATS_MIB_INADDRERRORS); | ||
1822 | break; | 1843 | break; |
1823 | } | 1844 | } |
1824 | /* FALLTHROUGH */ | 1845 | /* FALLTHROUGH */ |
1825 | case IPSTATS_MIB_OUTNOROUTES: | 1846 | case IPSTATS_MIB_OUTNOROUTES: |
1826 | IP6_INC_STATS(ip6_dst_idev(skb->dst), ipstats_mib_noroutes); | 1847 | IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), |
1848 | ipstats_mib_noroutes); | ||
1827 | break; | 1849 | break; |
1828 | } | 1850 | } |
1829 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); | 1851 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); |
@@ -1930,6 +1952,7 @@ void rt6_ifdown(struct net *net, struct net_device *dev) | |||
1930 | }; | 1952 | }; |
1931 | 1953 | ||
1932 | fib6_clean_all(net, fib6_ifdown, 0, &adn); | 1954 | fib6_clean_all(net, fib6_ifdown, 0, &adn); |
1955 | icmp6_clean_all(fib6_ifdown, &adn); | ||
1933 | } | 1956 | } |
1934 | 1957 | ||
1935 | struct rt6_mtu_change_arg | 1958 | struct rt6_mtu_change_arg |
@@ -2611,10 +2634,8 @@ static int ip6_route_net_init(struct net *net) | |||
2611 | net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, | 2634 | net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, |
2612 | sizeof(*net->ipv6.ip6_prohibit_entry), | 2635 | sizeof(*net->ipv6.ip6_prohibit_entry), |
2613 | GFP_KERNEL); | 2636 | GFP_KERNEL); |
2614 | if (!net->ipv6.ip6_prohibit_entry) { | 2637 | if (!net->ipv6.ip6_prohibit_entry) |
2615 | kfree(net->ipv6.ip6_null_entry); | 2638 | goto out_ip6_null_entry; |
2616 | goto out; | ||
2617 | } | ||
2618 | net->ipv6.ip6_prohibit_entry->u.dst.path = | 2639 | net->ipv6.ip6_prohibit_entry->u.dst.path = |
2619 | (struct dst_entry *)net->ipv6.ip6_prohibit_entry; | 2640 | (struct dst_entry *)net->ipv6.ip6_prohibit_entry; |
2620 | net->ipv6.ip6_prohibit_entry->u.dst.ops = net->ipv6.ip6_dst_ops; | 2641 | net->ipv6.ip6_prohibit_entry->u.dst.ops = net->ipv6.ip6_dst_ops; |
@@ -2622,16 +2643,22 @@ static int ip6_route_net_init(struct net *net) | |||
2622 | net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, | 2643 | net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, |
2623 | sizeof(*net->ipv6.ip6_blk_hole_entry), | 2644 | sizeof(*net->ipv6.ip6_blk_hole_entry), |
2624 | GFP_KERNEL); | 2645 | GFP_KERNEL); |
2625 | if (!net->ipv6.ip6_blk_hole_entry) { | 2646 | if (!net->ipv6.ip6_blk_hole_entry) |
2626 | kfree(net->ipv6.ip6_null_entry); | 2647 | goto out_ip6_prohibit_entry; |
2627 | kfree(net->ipv6.ip6_prohibit_entry); | ||
2628 | goto out; | ||
2629 | } | ||
2630 | net->ipv6.ip6_blk_hole_entry->u.dst.path = | 2648 | net->ipv6.ip6_blk_hole_entry->u.dst.path = |
2631 | (struct dst_entry *)net->ipv6.ip6_blk_hole_entry; | 2649 | (struct dst_entry *)net->ipv6.ip6_blk_hole_entry; |
2632 | net->ipv6.ip6_blk_hole_entry->u.dst.ops = net->ipv6.ip6_dst_ops; | 2650 | net->ipv6.ip6_blk_hole_entry->u.dst.ops = net->ipv6.ip6_dst_ops; |
2633 | #endif | 2651 | #endif |
2634 | 2652 | ||
2653 | net->ipv6.sysctl.flush_delay = 0; | ||
2654 | net->ipv6.sysctl.ip6_rt_max_size = 4096; | ||
2655 | net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2; | ||
2656 | net->ipv6.sysctl.ip6_rt_gc_timeout = 60*HZ; | ||
2657 | net->ipv6.sysctl.ip6_rt_gc_interval = 30*HZ; | ||
2658 | net->ipv6.sysctl.ip6_rt_gc_elasticity = 9; | ||
2659 | net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ; | ||
2660 | net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; | ||
2661 | |||
2635 | #ifdef CONFIG_PROC_FS | 2662 | #ifdef CONFIG_PROC_FS |
2636 | proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); | 2663 | proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); |
2637 | proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); | 2664 | proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); |
@@ -2642,6 +2669,12 @@ static int ip6_route_net_init(struct net *net) | |||
2642 | out: | 2669 | out: |
2643 | return ret; | 2670 | return ret; |
2644 | 2671 | ||
2672 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
2673 | out_ip6_prohibit_entry: | ||
2674 | kfree(net->ipv6.ip6_prohibit_entry); | ||
2675 | out_ip6_null_entry: | ||
2676 | kfree(net->ipv6.ip6_null_entry); | ||
2677 | #endif | ||
2645 | out_ip6_dst_ops: | 2678 | out_ip6_dst_ops: |
2646 | release_net(net->ipv6.ip6_dst_ops->dst_net); | 2679 | release_net(net->ipv6.ip6_dst_ops->dst_net); |
2647 | kfree(net->ipv6.ip6_dst_ops); | 2680 | kfree(net->ipv6.ip6_dst_ops); |
@@ -2688,6 +2721,8 @@ int __init ip6_route_init(void) | |||
2688 | if (ret) | 2721 | if (ret) |
2689 | goto out_kmem_cache; | 2722 | goto out_kmem_cache; |
2690 | 2723 | ||
2724 | ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; | ||
2725 | |||
2691 | /* Registering of the loopback is done before this portion of code, | 2726 | /* Registering of the loopback is done before this portion of code, |
2692 | * the loopback reference in rt6_info will not be taken, do it | 2727 | * the loopback reference in rt6_info will not be taken, do it |
2693 | * manually for init_net */ | 2728 | * manually for init_net */ |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5b90b369ccb2..e5310c9b84dc 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -330,7 +330,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
330 | th->dest, &hdr->saddr, th->source, skb->dev->ifindex); | 330 | th->dest, &hdr->saddr, th->source, skb->dev->ifindex); |
331 | 331 | ||
332 | if (sk == NULL) { | 332 | if (sk == NULL) { |
333 | ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); | 333 | ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev), |
334 | ICMP6_MIB_INERRORS); | ||
334 | return; | 335 | return; |
335 | } | 336 | } |
336 | 337 | ||
@@ -941,117 +942,14 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb) | |||
941 | return 0; | 942 | return 0; |
942 | } | 943 | } |
943 | 944 | ||
944 | static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) | 945 | static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, |
946 | u32 ts, struct tcp_md5sig_key *key, int rst) | ||
945 | { | 947 | { |
946 | struct tcphdr *th = tcp_hdr(skb), *t1; | 948 | struct tcphdr *th = tcp_hdr(skb), *t1; |
947 | struct sk_buff *buff; | 949 | struct sk_buff *buff; |
948 | struct flowi fl; | 950 | struct flowi fl; |
949 | struct net *net = dev_net(skb->dst->dev); | 951 | struct net *net = dev_net(skb->dst->dev); |
950 | struct sock *ctl_sk = net->ipv6.tcp_sk; | 952 | struct sock *ctl_sk = net->ipv6.tcp_sk; |
951 | unsigned int tot_len = sizeof(*th); | ||
952 | #ifdef CONFIG_TCP_MD5SIG | ||
953 | struct tcp_md5sig_key *key; | ||
954 | #endif | ||
955 | |||
956 | if (th->rst) | ||
957 | return; | ||
958 | |||
959 | if (!ipv6_unicast_destination(skb)) | ||
960 | return; | ||
961 | |||
962 | #ifdef CONFIG_TCP_MD5SIG | ||
963 | if (sk) | ||
964 | key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr); | ||
965 | else | ||
966 | key = NULL; | ||
967 | |||
968 | if (key) | ||
969 | tot_len += TCPOLEN_MD5SIG_ALIGNED; | ||
970 | #endif | ||
971 | |||
972 | /* | ||
973 | * We need to grab some memory, and put together an RST, | ||
974 | * and then put it into the queue to be sent. | ||
975 | */ | ||
976 | |||
977 | buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, | ||
978 | GFP_ATOMIC); | ||
979 | if (buff == NULL) | ||
980 | return; | ||
981 | |||
982 | skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); | ||
983 | |||
984 | t1 = (struct tcphdr *) skb_push(buff, tot_len); | ||
985 | |||
986 | /* Swap the send and the receive. */ | ||
987 | memset(t1, 0, sizeof(*t1)); | ||
988 | t1->dest = th->source; | ||
989 | t1->source = th->dest; | ||
990 | t1->doff = tot_len / 4; | ||
991 | t1->rst = 1; | ||
992 | |||
993 | if(th->ack) { | ||
994 | t1->seq = th->ack_seq; | ||
995 | } else { | ||
996 | t1->ack = 1; | ||
997 | t1->ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin | ||
998 | + skb->len - (th->doff<<2)); | ||
999 | } | ||
1000 | |||
1001 | #ifdef CONFIG_TCP_MD5SIG | ||
1002 | if (key) { | ||
1003 | __be32 *opt = (__be32*)(t1 + 1); | ||
1004 | opt[0] = htonl((TCPOPT_NOP << 24) | | ||
1005 | (TCPOPT_NOP << 16) | | ||
1006 | (TCPOPT_MD5SIG << 8) | | ||
1007 | TCPOLEN_MD5SIG); | ||
1008 | tcp_v6_md5_hash_hdr((__u8 *)&opt[1], key, | ||
1009 | &ipv6_hdr(skb)->daddr, | ||
1010 | &ipv6_hdr(skb)->saddr, t1); | ||
1011 | } | ||
1012 | #endif | ||
1013 | |||
1014 | buff->csum = csum_partial((char *)t1, sizeof(*t1), 0); | ||
1015 | |||
1016 | memset(&fl, 0, sizeof(fl)); | ||
1017 | ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); | ||
1018 | ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr); | ||
1019 | |||
1020 | t1->check = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst, | ||
1021 | sizeof(*t1), IPPROTO_TCP, | ||
1022 | buff->csum); | ||
1023 | |||
1024 | fl.proto = IPPROTO_TCP; | ||
1025 | fl.oif = inet6_iif(skb); | ||
1026 | fl.fl_ip_dport = t1->dest; | ||
1027 | fl.fl_ip_sport = t1->source; | ||
1028 | security_skb_classify_flow(skb, &fl); | ||
1029 | |||
1030 | /* Pass a socket to ip6_dst_lookup either it is for RST | ||
1031 | * Underlying function will use this to retrieve the network | ||
1032 | * namespace | ||
1033 | */ | ||
1034 | if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) { | ||
1035 | |||
1036 | if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { | ||
1037 | ip6_xmit(ctl_sk, buff, &fl, NULL, 0); | ||
1038 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); | ||
1039 | TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); | ||
1040 | return; | ||
1041 | } | ||
1042 | } | ||
1043 | |||
1044 | kfree_skb(buff); | ||
1045 | } | ||
1046 | |||
1047 | static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts, | ||
1048 | struct tcp_md5sig_key *key) | ||
1049 | { | ||
1050 | struct tcphdr *th = tcp_hdr(skb), *t1; | ||
1051 | struct sk_buff *buff; | ||
1052 | struct flowi fl; | ||
1053 | struct net *net = dev_net(skb->dev); | ||
1054 | struct sock *ctl_sk = net->ipv6.tcp_sk; | ||
1055 | unsigned int tot_len = sizeof(struct tcphdr); | 953 | unsigned int tot_len = sizeof(struct tcphdr); |
1056 | __be32 *topt; | 954 | __be32 *topt; |
1057 | 955 | ||
@@ -1069,16 +967,17 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
1069 | 967 | ||
1070 | skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); | 968 | skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); |
1071 | 969 | ||
1072 | t1 = (struct tcphdr *) skb_push(buff,tot_len); | 970 | t1 = (struct tcphdr *) skb_push(buff, tot_len); |
1073 | 971 | ||
1074 | /* Swap the send and the receive. */ | 972 | /* Swap the send and the receive. */ |
1075 | memset(t1, 0, sizeof(*t1)); | 973 | memset(t1, 0, sizeof(*t1)); |
1076 | t1->dest = th->source; | 974 | t1->dest = th->source; |
1077 | t1->source = th->dest; | 975 | t1->source = th->dest; |
1078 | t1->doff = tot_len/4; | 976 | t1->doff = tot_len / 4; |
1079 | t1->seq = htonl(seq); | 977 | t1->seq = htonl(seq); |
1080 | t1->ack_seq = htonl(ack); | 978 | t1->ack_seq = htonl(ack); |
1081 | t1->ack = 1; | 979 | t1->ack = !rst || !th->ack; |
980 | t1->rst = rst; | ||
1082 | t1->window = htons(win); | 981 | t1->window = htons(win); |
1083 | 982 | ||
1084 | topt = (__be32 *)(t1 + 1); | 983 | topt = (__be32 *)(t1 + 1); |
@@ -1087,7 +986,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
1087 | *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | 986 | *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | |
1088 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | 987 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); |
1089 | *topt++ = htonl(tcp_time_stamp); | 988 | *topt++ = htonl(tcp_time_stamp); |
1090 | *topt = htonl(ts); | 989 | *topt++ = htonl(ts); |
1091 | } | 990 | } |
1092 | 991 | ||
1093 | #ifdef CONFIG_TCP_MD5SIG | 992 | #ifdef CONFIG_TCP_MD5SIG |
@@ -1116,10 +1015,16 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
1116 | fl.fl_ip_sport = t1->source; | 1015 | fl.fl_ip_sport = t1->source; |
1117 | security_skb_classify_flow(skb, &fl); | 1016 | security_skb_classify_flow(skb, &fl); |
1118 | 1017 | ||
1018 | /* Pass a socket to ip6_dst_lookup either it is for RST | ||
1019 | * Underlying function will use this to retrieve the network | ||
1020 | * namespace | ||
1021 | */ | ||
1119 | if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) { | 1022 | if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) { |
1120 | if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { | 1023 | if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { |
1121 | ip6_xmit(ctl_sk, buff, &fl, NULL, 0); | 1024 | ip6_xmit(ctl_sk, buff, &fl, NULL, 0); |
1122 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); | 1025 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); |
1026 | if (rst) | ||
1027 | TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); | ||
1123 | return; | 1028 | return; |
1124 | } | 1029 | } |
1125 | } | 1030 | } |
@@ -1127,6 +1032,38 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
1127 | kfree_skb(buff); | 1032 | kfree_skb(buff); |
1128 | } | 1033 | } |
1129 | 1034 | ||
1035 | static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) | ||
1036 | { | ||
1037 | struct tcphdr *th = tcp_hdr(skb); | ||
1038 | u32 seq = 0, ack_seq = 0; | ||
1039 | struct tcp_md5sig_key *key = NULL; | ||
1040 | |||
1041 | if (th->rst) | ||
1042 | return; | ||
1043 | |||
1044 | if (!ipv6_unicast_destination(skb)) | ||
1045 | return; | ||
1046 | |||
1047 | #ifdef CONFIG_TCP_MD5SIG | ||
1048 | if (sk) | ||
1049 | key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr); | ||
1050 | #endif | ||
1051 | |||
1052 | if (th->ack) | ||
1053 | seq = ntohl(th->ack_seq); | ||
1054 | else | ||
1055 | ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len - | ||
1056 | (th->doff << 2); | ||
1057 | |||
1058 | tcp_v6_send_response(skb, seq, ack_seq, 0, 0, key, 1); | ||
1059 | } | ||
1060 | |||
1061 | static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts, | ||
1062 | struct tcp_md5sig_key *key) | ||
1063 | { | ||
1064 | tcp_v6_send_response(skb, seq, ack, win, ts, key, 0); | ||
1065 | } | ||
1066 | |||
1130 | static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) | 1067 | static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) |
1131 | { | 1068 | { |
1132 | struct inet_timewait_sock *tw = inet_twsk(sk); | 1069 | struct inet_timewait_sock *tw = inet_twsk(sk); |
@@ -1286,7 +1223,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1286 | struct request_sock *req, | 1223 | struct request_sock *req, |
1287 | struct dst_entry *dst) | 1224 | struct dst_entry *dst) |
1288 | { | 1225 | { |
1289 | struct inet6_request_sock *treq = inet6_rsk(req); | 1226 | struct inet6_request_sock *treq; |
1290 | struct ipv6_pinfo *newnp, *np = inet6_sk(sk); | 1227 | struct ipv6_pinfo *newnp, *np = inet6_sk(sk); |
1291 | struct tcp6_sock *newtcp6sk; | 1228 | struct tcp6_sock *newtcp6sk; |
1292 | struct inet_sock *newinet; | 1229 | struct inet_sock *newinet; |
@@ -1350,6 +1287,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1350 | return newsk; | 1287 | return newsk; |
1351 | } | 1288 | } |
1352 | 1289 | ||
1290 | treq = inet6_rsk(req); | ||
1353 | opt = np->opt; | 1291 | opt = np->opt; |
1354 | 1292 | ||
1355 | if (sk_acceptq_is_full(sk)) | 1293 | if (sk_acceptq_is_full(sk)) |
@@ -1680,11 +1618,7 @@ static int tcp_v6_rcv(struct sk_buff *skb) | |||
1680 | TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb)); | 1618 | TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb)); |
1681 | TCP_SKB_CB(skb)->sacked = 0; | 1619 | TCP_SKB_CB(skb)->sacked = 0; |
1682 | 1620 | ||
1683 | sk = __inet6_lookup(net, &tcp_hashinfo, | 1621 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); |
1684 | &ipv6_hdr(skb)->saddr, th->source, | ||
1685 | &ipv6_hdr(skb)->daddr, ntohs(th->dest), | ||
1686 | inet6_iif(skb)); | ||
1687 | |||
1688 | if (!sk) | 1622 | if (!sk) |
1689 | goto no_tcp_socket; | 1623 | goto no_tcp_socket; |
1690 | 1624 | ||
@@ -2148,6 +2082,7 @@ static int tcpv6_net_init(struct net *net) | |||
2148 | static void tcpv6_net_exit(struct net *net) | 2082 | static void tcpv6_net_exit(struct net *net) |
2149 | { | 2083 | { |
2150 | inet_ctl_sock_destroy(net->ipv6.tcp_sk); | 2084 | inet_ctl_sock_destroy(net->ipv6.tcp_sk); |
2085 | inet_twsk_purge(net, &tcp_hashinfo, &tcp_death_row, AF_INET6); | ||
2151 | } | 2086 | } |
2152 | 2087 | ||
2153 | static struct pernet_operations tcpv6_net_ops = { | 2088 | static struct pernet_operations tcpv6_net_ops = { |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index a6aecf76a71b..e51da8c092fa 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -107,6 +107,21 @@ static struct sock *__udp6_lib_lookup(struct net *net, | |||
107 | return result; | 107 | return result; |
108 | } | 108 | } |
109 | 109 | ||
110 | static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, | ||
111 | __be16 sport, __be16 dport, | ||
112 | struct hlist_head udptable[]) | ||
113 | { | ||
114 | struct sock *sk; | ||
115 | struct ipv6hdr *iph = ipv6_hdr(skb); | ||
116 | |||
117 | if (unlikely(sk = skb_steal_sock(skb))) | ||
118 | return sk; | ||
119 | else | ||
120 | return __udp6_lib_lookup(dev_net(skb->dst->dev), &iph->saddr, sport, | ||
121 | &iph->daddr, dport, inet6_iif(skb), | ||
122 | udptable); | ||
123 | } | ||
124 | |||
110 | /* | 125 | /* |
111 | * This should be easy, if there is something there we | 126 | * This should be easy, if there is something there we |
112 | * return it, otherwise we block. | 127 | * return it, otherwise we block. |
@@ -488,8 +503,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
488 | * check socket cache ... must talk to Alan about his plans | 503 | * check socket cache ... must talk to Alan about his plans |
489 | * for sock caches... i'll skip this for now. | 504 | * for sock caches... i'll skip this for now. |
490 | */ | 505 | */ |
491 | sk = __udp6_lib_lookup(net, saddr, uh->source, | 506 | sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable); |
492 | daddr, uh->dest, inet6_iif(skb), udptable); | ||
493 | 507 | ||
494 | if (sk == NULL) { | 508 | if (sk == NULL) { |
495 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) | 509 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) |
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index f6cdcb348e05..3cd1a1ac3d6c 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c | |||
@@ -13,8 +13,6 @@ | |||
13 | */ | 13 | */ |
14 | #include "udp_impl.h" | 14 | #include "udp_impl.h" |
15 | 15 | ||
16 | DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6) __read_mostly; | ||
17 | |||
18 | static int udplitev6_rcv(struct sk_buff *skb) | 16 | static int udplitev6_rcv(struct sk_buff *skb) |
19 | { | 17 | { |
20 | return __udp6_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE); | 18 | return __udp6_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE); |