aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c110
-rw-r--r--net/ipv6/addrconf_core.c2
-rw-r--r--net/ipv6/af_inet6.c32
-rw-r--r--net/ipv6/ah6.c2
-rw-r--r--net/ipv6/anycast.c2
-rw-r--r--net/ipv6/esp6.c2
-rw-r--r--net/ipv6/exthdrs.c2
-rw-r--r--net/ipv6/fib6_rules.c4
-rw-r--r--net/ipv6/icmp.c12
-rw-r--r--net/ipv6/ip6_fib.c52
-rw-r--r--net/ipv6/ip6_flowlabel.c9
-rw-r--r--net/ipv6/ip6_input.c3
-rw-r--r--net/ipv6/ip6_output.c21
-rw-r--r--net/ipv6/ip6_tunnel.c43
-rw-r--r--net/ipv6/ipcomp6.c21
-rw-r--r--net/ipv6/mcast.c32
-rw-r--r--net/ipv6/mip6.c2
-rw-r--r--net/ipv6/ndisc.c7
-rw-r--r--net/ipv6/netfilter/ip6_tables.c563
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c2
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c113
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c141
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c86
-rw-r--r--net/ipv6/netfilter/ip6table_security.c109
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c14
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c11
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c15
-rw-r--r--net/ipv6/proc.c39
-rw-r--r--net/ipv6/raw.c4
-rw-r--r--net/ipv6/reassembly.c27
-rw-r--r--net/ipv6/route.c12
-rw-r--r--net/ipv6/sit.c25
-rw-r--r--net/ipv6/syncookies.c3
-rw-r--r--net/ipv6/sysctl_net_ipv6.c4
-rw-r--r--net/ipv6/tcp_ipv6.c22
-rw-r--r--net/ipv6/tunnel6.c4
-rw-r--r--net/ipv6/udp.c22
-rw-r--r--net/ipv6/udplite.c4
-rw-r--r--net/ipv6/xfrm6_input.c2
-rw-r--r--net/ipv6/xfrm6_output.c2
-rw-r--r--net/ipv6/xfrm6_tunnel.c194
41 files changed, 797 insertions, 979 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index de7a194a64ab..88fd8c5877ee 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -278,31 +278,31 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
278 278
279static int snmp6_alloc_dev(struct inet6_dev *idev) 279static int snmp6_alloc_dev(struct inet6_dev *idev)
280{ 280{
281 if (snmp_mib_init((void **)idev->stats.ipv6, 281 if (snmp_mib_init((void __percpu **)idev->stats.ipv6,
282 sizeof(struct ipstats_mib)) < 0) 282 sizeof(struct ipstats_mib)) < 0)
283 goto err_ip; 283 goto err_ip;
284 if (snmp_mib_init((void **)idev->stats.icmpv6, 284 if (snmp_mib_init((void __percpu **)idev->stats.icmpv6,
285 sizeof(struct icmpv6_mib)) < 0) 285 sizeof(struct icmpv6_mib)) < 0)
286 goto err_icmp; 286 goto err_icmp;
287 if (snmp_mib_init((void **)idev->stats.icmpv6msg, 287 if (snmp_mib_init((void __percpu **)idev->stats.icmpv6msg,
288 sizeof(struct icmpv6msg_mib)) < 0) 288 sizeof(struct icmpv6msg_mib)) < 0)
289 goto err_icmpmsg; 289 goto err_icmpmsg;
290 290
291 return 0; 291 return 0;
292 292
293err_icmpmsg: 293err_icmpmsg:
294 snmp_mib_free((void **)idev->stats.icmpv6); 294 snmp_mib_free((void __percpu **)idev->stats.icmpv6);
295err_icmp: 295err_icmp:
296 snmp_mib_free((void **)idev->stats.ipv6); 296 snmp_mib_free((void __percpu **)idev->stats.ipv6);
297err_ip: 297err_ip:
298 return -ENOMEM; 298 return -ENOMEM;
299} 299}
300 300
301static void snmp6_free_dev(struct inet6_dev *idev) 301static void snmp6_free_dev(struct inet6_dev *idev)
302{ 302{
303 snmp_mib_free((void **)idev->stats.icmpv6msg); 303 snmp_mib_free((void __percpu **)idev->stats.icmpv6msg);
304 snmp_mib_free((void **)idev->stats.icmpv6); 304 snmp_mib_free((void __percpu **)idev->stats.icmpv6);
305 snmp_mib_free((void **)idev->stats.ipv6); 305 snmp_mib_free((void __percpu **)idev->stats.ipv6);
306} 306}
307 307
308/* Nobody refers to this device, we may destroy it. */ 308/* Nobody refers to this device, we may destroy it. */
@@ -502,8 +502,11 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
502 if (p == &net->ipv6.devconf_dflt->forwarding) 502 if (p == &net->ipv6.devconf_dflt->forwarding)
503 return 0; 503 return 0;
504 504
505 if (!rtnl_trylock()) 505 if (!rtnl_trylock()) {
506 /* Restore the original values before restarting */
507 *p = old;
506 return restart_syscall(); 508 return restart_syscall();
509 }
507 510
508 if (p == &net->ipv6.devconf_all->forwarding) { 511 if (p == &net->ipv6.devconf_all->forwarding) {
509 __s32 newf = net->ipv6.devconf_all->forwarding; 512 __s32 newf = net->ipv6.devconf_all->forwarding;
@@ -989,8 +992,7 @@ struct ipv6_saddr_dst {
989 992
990static inline int ipv6_saddr_preferred(int type) 993static inline int ipv6_saddr_preferred(int type)
991{ 994{
992 if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4| 995 if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|IPV6_ADDR_LOOPBACK))
993 IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
994 return 1; 996 return 1;
995 return 0; 997 return 0;
996} 998}
@@ -2646,7 +2648,8 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2646 2648
2647 write_lock_bh(&addrconf_hash_lock); 2649 write_lock_bh(&addrconf_hash_lock);
2648 while ((ifa = *bifa) != NULL) { 2650 while ((ifa = *bifa) != NULL) {
2649 if (ifa->idev == idev) { 2651 if (ifa->idev == idev &&
2652 (how || !(ifa->flags&IFA_F_PERMANENT))) {
2650 *bifa = ifa->lst_next; 2653 *bifa = ifa->lst_next;
2651 ifa->lst_next = NULL; 2654 ifa->lst_next = NULL;
2652 addrconf_del_timer(ifa); 2655 addrconf_del_timer(ifa);
@@ -2686,18 +2689,30 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2686 write_lock_bh(&idev->lock); 2689 write_lock_bh(&idev->lock);
2687 } 2690 }
2688#endif 2691#endif
2689 while ((ifa = idev->addr_list) != NULL) { 2692 bifa = &idev->addr_list;
2690 idev->addr_list = ifa->if_next; 2693 while ((ifa = *bifa) != NULL) {
2691 ifa->if_next = NULL; 2694 if (how == 0 && (ifa->flags&IFA_F_PERMANENT)) {
2692 ifa->dead = 1; 2695 /* Retain permanent address on admin down */
2693 addrconf_del_timer(ifa); 2696 bifa = &ifa->if_next;
2694 write_unlock_bh(&idev->lock); 2697
2698 /* Restart DAD if needed when link comes back up */
2699 if ( !((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
2700 idev->cnf.accept_dad <= 0 ||
2701 (ifa->flags & IFA_F_NODAD)))
2702 ifa->flags |= IFA_F_TENTATIVE;
2703 } else {
2704 *bifa = ifa->if_next;
2705 ifa->if_next = NULL;
2695 2706
2696 __ipv6_ifa_notify(RTM_DELADDR, ifa); 2707 ifa->dead = 1;
2697 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); 2708 write_unlock_bh(&idev->lock);
2698 in6_ifa_put(ifa);
2699 2709
2700 write_lock_bh(&idev->lock); 2710 __ipv6_ifa_notify(RTM_DELADDR, ifa);
2711 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
2712 in6_ifa_put(ifa);
2713
2714 write_lock_bh(&idev->lock);
2715 }
2701 } 2716 }
2702 write_unlock_bh(&idev->lock); 2717 write_unlock_bh(&idev->lock);
2703 2718
@@ -2789,14 +2804,14 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2789 read_lock_bh(&idev->lock); 2804 read_lock_bh(&idev->lock);
2790 if (ifp->dead) 2805 if (ifp->dead)
2791 goto out; 2806 goto out;
2792 spin_lock_bh(&ifp->lock);
2793 2807
2808 spin_lock(&ifp->lock);
2794 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || 2809 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
2795 idev->cnf.accept_dad < 1 || 2810 idev->cnf.accept_dad < 1 ||
2796 !(ifp->flags&IFA_F_TENTATIVE) || 2811 !(ifp->flags&IFA_F_TENTATIVE) ||
2797 ifp->flags & IFA_F_NODAD) { 2812 ifp->flags & IFA_F_NODAD) {
2798 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); 2813 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
2799 spin_unlock_bh(&ifp->lock); 2814 spin_unlock(&ifp->lock);
2800 read_unlock_bh(&idev->lock); 2815 read_unlock_bh(&idev->lock);
2801 2816
2802 addrconf_dad_completed(ifp); 2817 addrconf_dad_completed(ifp);
@@ -2804,7 +2819,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2804 } 2819 }
2805 2820
2806 if (!(idev->if_flags & IF_READY)) { 2821 if (!(idev->if_flags & IF_READY)) {
2807 spin_unlock_bh(&ifp->lock); 2822 spin_unlock(&ifp->lock);
2808 read_unlock_bh(&idev->lock); 2823 read_unlock_bh(&idev->lock);
2809 /* 2824 /*
2810 * If the device is not ready: 2825 * If the device is not ready:
@@ -2824,7 +2839,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2824 ip6_ins_rt(ifp->rt); 2839 ip6_ins_rt(ifp->rt);
2825 2840
2826 addrconf_dad_kick(ifp); 2841 addrconf_dad_kick(ifp);
2827 spin_unlock_bh(&ifp->lock); 2842 spin_unlock(&ifp->lock);
2828out: 2843out:
2829 read_unlock_bh(&idev->lock); 2844 read_unlock_bh(&idev->lock);
2830} 2845}
@@ -2840,14 +2855,15 @@ static void addrconf_dad_timer(unsigned long data)
2840 read_unlock_bh(&idev->lock); 2855 read_unlock_bh(&idev->lock);
2841 goto out; 2856 goto out;
2842 } 2857 }
2843 spin_lock_bh(&ifp->lock); 2858
2859 spin_lock(&ifp->lock);
2844 if (ifp->probes == 0) { 2860 if (ifp->probes == 0) {
2845 /* 2861 /*
2846 * DAD was successful 2862 * DAD was successful
2847 */ 2863 */
2848 2864
2849 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); 2865 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
2850 spin_unlock_bh(&ifp->lock); 2866 spin_unlock(&ifp->lock);
2851 read_unlock_bh(&idev->lock); 2867 read_unlock_bh(&idev->lock);
2852 2868
2853 addrconf_dad_completed(ifp); 2869 addrconf_dad_completed(ifp);
@@ -2857,7 +2873,7 @@ static void addrconf_dad_timer(unsigned long data)
2857 2873
2858 ifp->probes--; 2874 ifp->probes--;
2859 addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time); 2875 addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time);
2860 spin_unlock_bh(&ifp->lock); 2876 spin_unlock(&ifp->lock);
2861 read_unlock_bh(&idev->lock); 2877 read_unlock_bh(&idev->lock);
2862 2878
2863 /* send a neighbour solicitation for our addr */ 2879 /* send a neighbour solicitation for our addr */
@@ -2905,12 +2921,12 @@ static void addrconf_dad_run(struct inet6_dev *idev) {
2905 2921
2906 read_lock_bh(&idev->lock); 2922 read_lock_bh(&idev->lock);
2907 for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) { 2923 for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) {
2908 spin_lock_bh(&ifp->lock); 2924 spin_lock(&ifp->lock);
2909 if (!(ifp->flags & IFA_F_TENTATIVE)) { 2925 if (!(ifp->flags & IFA_F_TENTATIVE)) {
2910 spin_unlock_bh(&ifp->lock); 2926 spin_unlock(&ifp->lock);
2911 continue; 2927 continue;
2912 } 2928 }
2913 spin_unlock_bh(&ifp->lock); 2929 spin_unlock(&ifp->lock);
2914 addrconf_dad_kick(ifp); 2930 addrconf_dad_kick(ifp);
2915 } 2931 }
2916 read_unlock_bh(&idev->lock); 2932 read_unlock_bh(&idev->lock);
@@ -3027,14 +3043,14 @@ static const struct file_operations if6_fops = {
3027 .release = seq_release_net, 3043 .release = seq_release_net,
3028}; 3044};
3029 3045
3030static int if6_proc_net_init(struct net *net) 3046static int __net_init if6_proc_net_init(struct net *net)
3031{ 3047{
3032 if (!proc_net_fops_create(net, "if_inet6", S_IRUGO, &if6_fops)) 3048 if (!proc_net_fops_create(net, "if_inet6", S_IRUGO, &if6_fops))
3033 return -ENOMEM; 3049 return -ENOMEM;
3034 return 0; 3050 return 0;
3035} 3051}
3036 3052
3037static void if6_proc_net_exit(struct net *net) 3053static void __net_exit if6_proc_net_exit(struct net *net)
3038{ 3054{
3039 proc_net_remove(net, "if_inet6"); 3055 proc_net_remove(net, "if_inet6");
3040} 3056}
@@ -3752,8 +3768,8 @@ static inline size_t inet6_if_nlmsg_size(void)
3752 ); 3768 );
3753} 3769}
3754 3770
3755static inline void __snmp6_fill_stats(u64 *stats, void **mib, int items, 3771static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,
3756 int bytes) 3772 int items, int bytes)
3757{ 3773{
3758 int i; 3774 int i;
3759 int pad = bytes - sizeof(u64) * items; 3775 int pad = bytes - sizeof(u64) * items;
@@ -3772,10 +3788,10 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
3772{ 3788{
3773 switch(attrtype) { 3789 switch(attrtype) {
3774 case IFLA_INET6_STATS: 3790 case IFLA_INET6_STATS:
3775 __snmp6_fill_stats(stats, (void **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes); 3791 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
3776 break; 3792 break;
3777 case IFLA_INET6_ICMP6STATS: 3793 case IFLA_INET6_ICMP6STATS:
3778 __snmp6_fill_stats(stats, (void **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes); 3794 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
3779 break; 3795 break;
3780 } 3796 }
3781} 3797}
@@ -4028,12 +4044,15 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write,
4028{ 4044{
4029 int *valp = ctl->data; 4045 int *valp = ctl->data;
4030 int val = *valp; 4046 int val = *valp;
4047 loff_t pos = *ppos;
4031 int ret; 4048 int ret;
4032 4049
4033 ret = proc_dointvec(ctl, write, buffer, lenp, ppos); 4050 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
4034 4051
4035 if (write) 4052 if (write)
4036 ret = addrconf_fixup_forwarding(ctl, valp, val); 4053 ret = addrconf_fixup_forwarding(ctl, valp, val);
4054 if (ret)
4055 *ppos = pos;
4037 return ret; 4056 return ret;
4038} 4057}
4039 4058
@@ -4075,8 +4094,11 @@ static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
4075 if (p == &net->ipv6.devconf_dflt->disable_ipv6) 4094 if (p == &net->ipv6.devconf_dflt->disable_ipv6)
4076 return 0; 4095 return 0;
4077 4096
4078 if (!rtnl_trylock()) 4097 if (!rtnl_trylock()) {
4098 /* Restore the original values before restarting */
4099 *p = old;
4079 return restart_syscall(); 4100 return restart_syscall();
4101 }
4080 4102
4081 if (p == &net->ipv6.devconf_all->disable_ipv6) { 4103 if (p == &net->ipv6.devconf_all->disable_ipv6) {
4082 __s32 newf = net->ipv6.devconf_all->disable_ipv6; 4104 __s32 newf = net->ipv6.devconf_all->disable_ipv6;
@@ -4095,12 +4117,15 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write,
4095{ 4117{
4096 int *valp = ctl->data; 4118 int *valp = ctl->data;
4097 int val = *valp; 4119 int val = *valp;
4120 loff_t pos = *ppos;
4098 int ret; 4121 int ret;
4099 4122
4100 ret = proc_dointvec(ctl, write, buffer, lenp, ppos); 4123 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
4101 4124
4102 if (write) 4125 if (write)
4103 ret = addrconf_disable_ipv6(ctl, valp, val); 4126 ret = addrconf_disable_ipv6(ctl, valp, val);
4127 if (ret)
4128 *ppos = pos;
4104 return ret; 4129 return ret;
4105} 4130}
4106 4131
@@ -4402,8 +4427,7 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
4402 4427
4403static void addrconf_sysctl_register(struct inet6_dev *idev) 4428static void addrconf_sysctl_register(struct inet6_dev *idev)
4404{ 4429{
4405 neigh_sysctl_register(idev->dev, idev->nd_parms, NET_IPV6, 4430 neigh_sysctl_register(idev->dev, idev->nd_parms, "ipv6",
4406 NET_IPV6_NEIGH, "ipv6",
4407 &ndisc_ifinfo_sysctl_change); 4431 &ndisc_ifinfo_sysctl_change);
4408 __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name, 4432 __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name,
4409 idev, &idev->cnf); 4433 idev, &idev->cnf);
@@ -4418,7 +4442,7 @@ static void addrconf_sysctl_unregister(struct inet6_dev *idev)
4418 4442
4419#endif 4443#endif
4420 4444
4421static int addrconf_init_net(struct net *net) 4445static int __net_init addrconf_init_net(struct net *net)
4422{ 4446{
4423 int err; 4447 int err;
4424 struct ipv6_devconf *all, *dflt; 4448 struct ipv6_devconf *all, *dflt;
@@ -4467,7 +4491,7 @@ err_alloc_all:
4467 return err; 4491 return err;
4468} 4492}
4469 4493
4470static void addrconf_exit_net(struct net *net) 4494static void __net_exit addrconf_exit_net(struct net *net)
4471{ 4495{
4472#ifdef CONFIG_SYSCTL 4496#ifdef CONFIG_SYSCTL
4473 __addrconf_sysctl_unregister(net->ipv6.devconf_dflt); 4497 __addrconf_sysctl_unregister(net->ipv6.devconf_dflt);
diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c
index 3f82e9542eda..6b03826552e1 100644
--- a/net/ipv6/addrconf_core.c
+++ b/net/ipv6/addrconf_core.c
@@ -72,7 +72,7 @@ int __ipv6_addr_type(const struct in6_addr *addr)
72 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */ 72 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */
73 } 73 }
74 74
75 return (IPV6_ADDR_RESERVED | 75 return (IPV6_ADDR_UNICAST |
76 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.4 */ 76 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.4 */
77} 77}
78EXPORT_SYMBOL(__ipv6_addr_type); 78EXPORT_SYMBOL(__ipv6_addr_type);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 12e69d364dd5..37d14e735c27 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -971,41 +971,41 @@ static void ipv6_packet_cleanup(void)
971 971
972static int __net_init ipv6_init_mibs(struct net *net) 972static int __net_init ipv6_init_mibs(struct net *net)
973{ 973{
974 if (snmp_mib_init((void **)net->mib.udp_stats_in6, 974 if (snmp_mib_init((void __percpu **)net->mib.udp_stats_in6,
975 sizeof (struct udp_mib)) < 0) 975 sizeof (struct udp_mib)) < 0)
976 return -ENOMEM; 976 return -ENOMEM;
977 if (snmp_mib_init((void **)net->mib.udplite_stats_in6, 977 if (snmp_mib_init((void __percpu **)net->mib.udplite_stats_in6,
978 sizeof (struct udp_mib)) < 0) 978 sizeof (struct udp_mib)) < 0)
979 goto err_udplite_mib; 979 goto err_udplite_mib;
980 if (snmp_mib_init((void **)net->mib.ipv6_statistics, 980 if (snmp_mib_init((void __percpu **)net->mib.ipv6_statistics,
981 sizeof(struct ipstats_mib)) < 0) 981 sizeof(struct ipstats_mib)) < 0)
982 goto err_ip_mib; 982 goto err_ip_mib;
983 if (snmp_mib_init((void **)net->mib.icmpv6_statistics, 983 if (snmp_mib_init((void __percpu **)net->mib.icmpv6_statistics,
984 sizeof(struct icmpv6_mib)) < 0) 984 sizeof(struct icmpv6_mib)) < 0)
985 goto err_icmp_mib; 985 goto err_icmp_mib;
986 if (snmp_mib_init((void **)net->mib.icmpv6msg_statistics, 986 if (snmp_mib_init((void __percpu **)net->mib.icmpv6msg_statistics,
987 sizeof(struct icmpv6msg_mib)) < 0) 987 sizeof(struct icmpv6msg_mib)) < 0)
988 goto err_icmpmsg_mib; 988 goto err_icmpmsg_mib;
989 return 0; 989 return 0;
990 990
991err_icmpmsg_mib: 991err_icmpmsg_mib:
992 snmp_mib_free((void **)net->mib.icmpv6_statistics); 992 snmp_mib_free((void __percpu **)net->mib.icmpv6_statistics);
993err_icmp_mib: 993err_icmp_mib:
994 snmp_mib_free((void **)net->mib.ipv6_statistics); 994 snmp_mib_free((void __percpu **)net->mib.ipv6_statistics);
995err_ip_mib: 995err_ip_mib:
996 snmp_mib_free((void **)net->mib.udplite_stats_in6); 996 snmp_mib_free((void __percpu **)net->mib.udplite_stats_in6);
997err_udplite_mib: 997err_udplite_mib:
998 snmp_mib_free((void **)net->mib.udp_stats_in6); 998 snmp_mib_free((void __percpu **)net->mib.udp_stats_in6);
999 return -ENOMEM; 999 return -ENOMEM;
1000} 1000}
1001 1001
1002static void __net_exit ipv6_cleanup_mibs(struct net *net) 1002static void ipv6_cleanup_mibs(struct net *net)
1003{ 1003{
1004 snmp_mib_free((void **)net->mib.udp_stats_in6); 1004 snmp_mib_free((void __percpu **)net->mib.udp_stats_in6);
1005 snmp_mib_free((void **)net->mib.udplite_stats_in6); 1005 snmp_mib_free((void __percpu **)net->mib.udplite_stats_in6);
1006 snmp_mib_free((void **)net->mib.ipv6_statistics); 1006 snmp_mib_free((void __percpu **)net->mib.ipv6_statistics);
1007 snmp_mib_free((void **)net->mib.icmpv6_statistics); 1007 snmp_mib_free((void __percpu **)net->mib.icmpv6_statistics);
1008 snmp_mib_free((void **)net->mib.icmpv6msg_statistics); 1008 snmp_mib_free((void __percpu **)net->mib.icmpv6msg_statistics);
1009} 1009}
1010 1010
1011static int __net_init inet6_net_init(struct net *net) 1011static int __net_init inet6_net_init(struct net *net)
@@ -1042,7 +1042,7 @@ out:
1042#endif 1042#endif
1043} 1043}
1044 1044
1045static void inet6_net_exit(struct net *net) 1045static void __net_exit inet6_net_exit(struct net *net)
1046{ 1046{
1047#ifdef CONFIG_PROC_FS 1047#ifdef CONFIG_PROC_FS
1048 udp6_proc_exit(net); 1048 udp6_proc_exit(net);
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index c2f300c314be..5ac89025f9de 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -614,7 +614,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
614 type != ICMPV6_PKT_TOOBIG) 614 type != ICMPV6_PKT_TOOBIG)
615 return; 615 return;
616 616
617 x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6); 617 x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6);
618 if (!x) 618 if (!x)
619 return; 619 return;
620 620
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index f1c74c8ef9de..c4f6ca32fa74 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -538,7 +538,7 @@ static const struct file_operations ac6_seq_fops = {
538 .release = seq_release_net, 538 .release = seq_release_net,
539}; 539};
540 540
541int ac6_proc_init(struct net *net) 541int __net_init ac6_proc_init(struct net *net)
542{ 542{
543 if (!proc_net_fops_create(net, "anycast6", S_IRUGO, &ac6_seq_fops)) 543 if (!proc_net_fops_create(net, "anycast6", S_IRUGO, &ac6_seq_fops))
544 return -ENOMEM; 544 return -ENOMEM;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 668a46b655e6..ee9b93bdd6a2 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -365,7 +365,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
365 type != ICMPV6_PKT_TOOBIG) 365 type != ICMPV6_PKT_TOOBIG)
366 return; 366 return;
367 367
368 x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6); 368 x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
369 if (!x) 369 if (!x)
370 return; 370 return;
371 printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n", 371 printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n",
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 4bac362b1335..074f2c084f9f 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -481,7 +481,7 @@ looped_back:
481 IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), 481 IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
482 IPSTATS_MIB_INHDRERRORS); 482 IPSTATS_MIB_INHDRERRORS);
483 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 483 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
484 0, skb->dev); 484 0);
485 kfree_skb(skb); 485 kfree_skb(skb);
486 return -1; 486 return -1;
487 } 487 }
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index b7aa7c64cc4a..551882b9dfd6 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -262,7 +262,7 @@ static struct fib_rules_ops fib6_rules_ops_template = {
262 .fro_net = &init_net, 262 .fro_net = &init_net,
263}; 263};
264 264
265static int fib6_rules_net_init(struct net *net) 265static int __net_init fib6_rules_net_init(struct net *net)
266{ 266{
267 struct fib_rules_ops *ops; 267 struct fib_rules_ops *ops;
268 int err = -ENOMEM; 268 int err = -ENOMEM;
@@ -291,7 +291,7 @@ out_fib6_rules_ops:
291 goto out; 291 goto out;
292} 292}
293 293
294static void fib6_rules_net_exit(struct net *net) 294static void __net_exit fib6_rules_net_exit(struct net *net)
295{ 295{
296 fib_rules_unregister(net->ipv6.fib6_rules_ops); 296 fib_rules_unregister(net->ipv6.fib6_rules_ops);
297} 297}
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 4ae661bc3677..eb9abe24bdf0 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -67,11 +67,6 @@
67#include <asm/uaccess.h> 67#include <asm/uaccess.h>
68#include <asm/system.h> 68#include <asm/system.h>
69 69
70DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly;
71EXPORT_SYMBOL(icmpv6_statistics);
72DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics) __read_mostly;
73EXPORT_SYMBOL(icmpv6msg_statistics);
74
75/* 70/*
76 * The ICMP socket(s). This is the most convenient way to flow control 71 * The ICMP socket(s). This is the most convenient way to flow control
77 * our ICMP output as well as maintain a clean interface throughout 72 * our ICMP output as well as maintain a clean interface throughout
@@ -119,7 +114,7 @@ static __inline__ void icmpv6_xmit_unlock(struct sock *sk)
119 */ 114 */
120void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos) 115void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
121{ 116{
122 icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos, skb->dev); 117 icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos);
123 kfree_skb(skb); 118 kfree_skb(skb);
124} 119}
125 120
@@ -305,8 +300,7 @@ static inline void mip6_addr_swap(struct sk_buff *skb) {}
305/* 300/*
306 * Send an ICMP message in response to a packet in error 301 * Send an ICMP message in response to a packet in error
307 */ 302 */
308void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, 303void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
309 struct net_device *dev)
310{ 304{
311 struct net *net = dev_net(skb->dev); 305 struct net *net = dev_net(skb->dev);
312 struct inet6_dev *idev = NULL; 306 struct inet6_dev *idev = NULL;
@@ -951,7 +945,7 @@ ctl_table ipv6_icmp_table_template[] = {
951 { }, 945 { },
952}; 946};
953 947
954struct ctl_table *ipv6_icmp_sysctl_init(struct net *net) 948struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
955{ 949{
956 struct ctl_table *table; 950 struct ctl_table *table;
957 951
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 0e93ca56eb69..2f9847924fa5 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -93,29 +93,20 @@ static __u32 rt_sernum;
93 93
94static void fib6_gc_timer_cb(unsigned long arg); 94static void fib6_gc_timer_cb(unsigned long arg);
95 95
96static struct fib6_walker_t fib6_walker_list = { 96static LIST_HEAD(fib6_walkers);
97 .prev = &fib6_walker_list, 97#define FOR_WALKERS(w) list_for_each_entry(w, &fib6_walkers, lh)
98 .next = &fib6_walker_list,
99};
100
101#define FOR_WALKERS(w) for ((w)=fib6_walker_list.next; (w) != &fib6_walker_list; (w)=(w)->next)
102 98
103static inline void fib6_walker_link(struct fib6_walker_t *w) 99static inline void fib6_walker_link(struct fib6_walker_t *w)
104{ 100{
105 write_lock_bh(&fib6_walker_lock); 101 write_lock_bh(&fib6_walker_lock);
106 w->next = fib6_walker_list.next; 102 list_add(&w->lh, &fib6_walkers);
107 w->prev = &fib6_walker_list;
108 w->next->prev = w;
109 w->prev->next = w;
110 write_unlock_bh(&fib6_walker_lock); 103 write_unlock_bh(&fib6_walker_lock);
111} 104}
112 105
113static inline void fib6_walker_unlink(struct fib6_walker_t *w) 106static inline void fib6_walker_unlink(struct fib6_walker_t *w)
114{ 107{
115 write_lock_bh(&fib6_walker_lock); 108 write_lock_bh(&fib6_walker_lock);
116 w->next->prev = w->prev; 109 list_del(&w->lh);
117 w->prev->next = w->next;
118 w->prev = w->next = w;
119 write_unlock_bh(&fib6_walker_lock); 110 write_unlock_bh(&fib6_walker_lock);
120} 111}
121static __inline__ u32 fib6_new_sernum(void) 112static __inline__ u32 fib6_new_sernum(void)
@@ -239,7 +230,7 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id)
239 return NULL; 230 return NULL;
240} 231}
241 232
242static void fib6_tables_init(struct net *net) 233static void __net_init fib6_tables_init(struct net *net)
243{ 234{
244 fib6_link_table(net, net->ipv6.fib6_main_tbl); 235 fib6_link_table(net, net->ipv6.fib6_main_tbl);
245 fib6_link_table(net, net->ipv6.fib6_local_tbl); 236 fib6_link_table(net, net->ipv6.fib6_local_tbl);
@@ -262,7 +253,7 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl,
262 return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl, flags); 253 return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl, flags);
263} 254}
264 255
265static void fib6_tables_init(struct net *net) 256static void __net_init fib6_tables_init(struct net *net)
266{ 257{
267 fib6_link_table(net, net->ipv6.fib6_main_tbl); 258 fib6_link_table(net, net->ipv6.fib6_main_tbl);
268} 259}
@@ -319,12 +310,26 @@ static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb,
319 w->root = &table->tb6_root; 310 w->root = &table->tb6_root;
320 311
321 if (cb->args[4] == 0) { 312 if (cb->args[4] == 0) {
313 w->count = 0;
314 w->skip = 0;
315
322 read_lock_bh(&table->tb6_lock); 316 read_lock_bh(&table->tb6_lock);
323 res = fib6_walk(w); 317 res = fib6_walk(w);
324 read_unlock_bh(&table->tb6_lock); 318 read_unlock_bh(&table->tb6_lock);
325 if (res > 0) 319 if (res > 0) {
326 cb->args[4] = 1; 320 cb->args[4] = 1;
321 cb->args[5] = w->root->fn_sernum;
322 }
327 } else { 323 } else {
324 if (cb->args[5] != w->root->fn_sernum) {
325 /* Begin at the root if the tree changed */
326 cb->args[5] = w->root->fn_sernum;
327 w->state = FWS_INIT;
328 w->node = w->root;
329 w->skip = w->count;
330 } else
331 w->skip = 0;
332
328 read_lock_bh(&table->tb6_lock); 333 read_lock_bh(&table->tb6_lock);
329 res = fib6_walk_continue(w); 334 res = fib6_walk_continue(w);
330 read_unlock_bh(&table->tb6_lock); 335 read_unlock_bh(&table->tb6_lock);
@@ -1250,9 +1255,18 @@ static int fib6_walk_continue(struct fib6_walker_t *w)
1250 w->leaf = fn->leaf; 1255 w->leaf = fn->leaf;
1251 case FWS_C: 1256 case FWS_C:
1252 if (w->leaf && fn->fn_flags&RTN_RTINFO) { 1257 if (w->leaf && fn->fn_flags&RTN_RTINFO) {
1253 int err = w->func(w); 1258 int err;
1259
1260 if (w->count < w->skip) {
1261 w->count++;
1262 continue;
1263 }
1264
1265 err = w->func(w);
1254 if (err) 1266 if (err)
1255 return err; 1267 return err;
1268
1269 w->count++;
1256 continue; 1270 continue;
1257 } 1271 }
1258 w->state = FWS_U; 1272 w->state = FWS_U;
@@ -1346,6 +1360,8 @@ static void fib6_clean_tree(struct net *net, struct fib6_node *root,
1346 c.w.root = root; 1360 c.w.root = root;
1347 c.w.func = fib6_clean_node; 1361 c.w.func = fib6_clean_node;
1348 c.w.prune = prune; 1362 c.w.prune = prune;
1363 c.w.count = 0;
1364 c.w.skip = 0;
1349 c.func = func; 1365 c.func = func;
1350 c.arg = arg; 1366 c.arg = arg;
1351 c.net = net; 1367 c.net = net;
@@ -1469,7 +1485,7 @@ static void fib6_gc_timer_cb(unsigned long arg)
1469 fib6_run_gc(0, (struct net *)arg); 1485 fib6_run_gc(0, (struct net *)arg);
1470} 1486}
1471 1487
1472static int fib6_net_init(struct net *net) 1488static int __net_init fib6_net_init(struct net *net)
1473{ 1489{
1474 setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net); 1490 setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net);
1475 1491
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 6e7bffa2205e..e41eba8aacf1 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -154,7 +154,7 @@ static void ip6_fl_gc(unsigned long dummy)
154 write_unlock(&ip6_fl_lock); 154 write_unlock(&ip6_fl_lock);
155} 155}
156 156
157static void ip6_fl_purge(struct net *net) 157static void __net_exit ip6_fl_purge(struct net *net)
158{ 158{
159 int i; 159 int i;
160 160
@@ -735,7 +735,7 @@ static const struct file_operations ip6fl_seq_fops = {
735 .release = seq_release_net, 735 .release = seq_release_net,
736}; 736};
737 737
738static int ip6_flowlabel_proc_init(struct net *net) 738static int __net_init ip6_flowlabel_proc_init(struct net *net)
739{ 739{
740 if (!proc_net_fops_create(net, "ip6_flowlabel", 740 if (!proc_net_fops_create(net, "ip6_flowlabel",
741 S_IRUGO, &ip6fl_seq_fops)) 741 S_IRUGO, &ip6fl_seq_fops))
@@ -743,7 +743,7 @@ static int ip6_flowlabel_proc_init(struct net *net)
743 return 0; 743 return 0;
744} 744}
745 745
746static void ip6_flowlabel_proc_fini(struct net *net) 746static void __net_exit ip6_flowlabel_proc_fini(struct net *net)
747{ 747{
748 proc_net_remove(net, "ip6_flowlabel"); 748 proc_net_remove(net, "ip6_flowlabel");
749} 749}
@@ -754,11 +754,10 @@ static inline int ip6_flowlabel_proc_init(struct net *net)
754} 754}
755static inline void ip6_flowlabel_proc_fini(struct net *net) 755static inline void ip6_flowlabel_proc_fini(struct net *net)
756{ 756{
757 return ;
758} 757}
759#endif 758#endif
760 759
761static inline void ip6_flowlabel_net_exit(struct net *net) 760static void __net_exit ip6_flowlabel_net_exit(struct net *net)
762{ 761{
763 ip6_fl_purge(net); 762 ip6_fl_purge(net);
764 ip6_flowlabel_proc_fini(net); 763 ip6_flowlabel_proc_fini(net);
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 237e2dba6e94..e28f9203deca 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -216,8 +216,7 @@ resubmit:
216 IP6_INC_STATS_BH(net, idev, 216 IP6_INC_STATS_BH(net, idev,
217 IPSTATS_MIB_INUNKNOWNPROTOS); 217 IPSTATS_MIB_INUNKNOWNPROTOS);
218 icmpv6_send(skb, ICMPV6_PARAMPROB, 218 icmpv6_send(skb, ICMPV6_PARAMPROB,
219 ICMPV6_UNK_NEXTHDR, nhoff, 219 ICMPV6_UNK_NEXTHDR, nhoff);
220 skb->dev);
221 } 220 }
222 } else 221 } else
223 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS); 222 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index eb6d09728633..dabf108ad811 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -267,7 +267,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
267 if (net_ratelimit()) 267 if (net_ratelimit())
268 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); 268 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
269 skb->dev = dst->dev; 269 skb->dev = dst->dev;
270 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 270 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
271 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); 271 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS);
272 kfree_skb(skb); 272 kfree_skb(skb);
273 return -EMSGSIZE; 273 return -EMSGSIZE;
@@ -402,6 +402,7 @@ int ip6_forward(struct sk_buff *skb)
402 struct ipv6hdr *hdr = ipv6_hdr(skb); 402 struct ipv6hdr *hdr = ipv6_hdr(skb);
403 struct inet6_skb_parm *opt = IP6CB(skb); 403 struct inet6_skb_parm *opt = IP6CB(skb);
404 struct net *net = dev_net(dst->dev); 404 struct net *net = dev_net(dst->dev);
405 u32 mtu;
405 406
406 if (net->ipv6.devconf_all->forwarding == 0) 407 if (net->ipv6.devconf_all->forwarding == 0)
407 goto error; 408 goto error;
@@ -441,8 +442,7 @@ int ip6_forward(struct sk_buff *skb)
441 if (hdr->hop_limit <= 1) { 442 if (hdr->hop_limit <= 1) {
442 /* Force OUTPUT device used as source address */ 443 /* Force OUTPUT device used as source address */
443 skb->dev = dst->dev; 444 skb->dev = dst->dev;
444 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 445 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0);
445 0, skb->dev);
446 IP6_INC_STATS_BH(net, 446 IP6_INC_STATS_BH(net,
447 ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); 447 ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
448 448
@@ -504,15 +504,19 @@ int ip6_forward(struct sk_buff *skb)
504 goto error; 504 goto error;
505 if (addrtype & IPV6_ADDR_LINKLOCAL) { 505 if (addrtype & IPV6_ADDR_LINKLOCAL) {
506 icmpv6_send(skb, ICMPV6_DEST_UNREACH, 506 icmpv6_send(skb, ICMPV6_DEST_UNREACH,
507 ICMPV6_NOT_NEIGHBOUR, 0, skb->dev); 507 ICMPV6_NOT_NEIGHBOUR, 0);
508 goto error; 508 goto error;
509 } 509 }
510 } 510 }
511 511
512 if (skb->len > dst_mtu(dst)) { 512 mtu = dst_mtu(dst);
513 if (mtu < IPV6_MIN_MTU)
514 mtu = IPV6_MIN_MTU;
515
516 if (skb->len > mtu) {
513 /* Again, force OUTPUT device used as source address */ 517 /* Again, force OUTPUT device used as source address */
514 skb->dev = dst->dev; 518 skb->dev = dst->dev;
515 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); 519 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
516 IP6_INC_STATS_BH(net, 520 IP6_INC_STATS_BH(net,
517 ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); 521 ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS);
518 IP6_INC_STATS_BH(net, 522 IP6_INC_STATS_BH(net,
@@ -622,12 +626,11 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
622 mtu = ip6_skb_dst_mtu(skb); 626 mtu = ip6_skb_dst_mtu(skb);
623 627
624 /* We must not fragment if the socket is set to force MTU discovery 628 /* We must not fragment if the socket is set to force MTU discovery
625 * or if the skb it not generated by a local socket. (This last 629 * or if the skb it not generated by a local socket.
626 * check should be redundant, but it's free.)
627 */ 630 */
628 if (!skb->local_df) { 631 if (!skb->local_df) {
629 skb->dev = skb_dst(skb)->dev; 632 skb->dev = skb_dst(skb)->dev;
630 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 633 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
631 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 634 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
632 IPSTATS_MIB_FRAGFAILS); 635 IPSTATS_MIB_FRAGFAILS);
633 kfree_skb(skb); 636 kfree_skb(skb);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index d453d07b0dfe..138980eec214 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -74,7 +74,6 @@ MODULE_LICENSE("GPL");
74 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ 74 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \
75 (HASH_SIZE - 1)) 75 (HASH_SIZE - 1))
76 76
77static void ip6_fb_tnl_dev_init(struct net_device *dev);
78static void ip6_tnl_dev_init(struct net_device *dev); 77static void ip6_tnl_dev_init(struct net_device *dev);
79static void ip6_tnl_dev_setup(struct net_device *dev); 78static void ip6_tnl_dev_setup(struct net_device *dev);
80 79
@@ -623,7 +622,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
623 if (rt && rt->rt6i_dev) 622 if (rt && rt->rt6i_dev)
624 skb2->dev = rt->rt6i_dev; 623 skb2->dev = rt->rt6i_dev;
625 624
626 icmpv6_send(skb2, rel_type, rel_code, rel_info, skb2->dev); 625 icmpv6_send(skb2, rel_type, rel_code, rel_info);
627 626
628 if (rt) 627 if (rt)
629 dst_release(&rt->u.dst); 628 dst_release(&rt->u.dst);
@@ -1015,7 +1014,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1015 tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset]; 1014 tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset];
1016 if (tel->encap_limit == 0) { 1015 if (tel->encap_limit == 0) {
1017 icmpv6_send(skb, ICMPV6_PARAMPROB, 1016 icmpv6_send(skb, ICMPV6_PARAMPROB,
1018 ICMPV6_HDR_FIELD, offset + 2, skb->dev); 1017 ICMPV6_HDR_FIELD, offset + 2);
1019 return -1; 1018 return -1;
1020 } 1019 }
1021 encap_limit = tel->encap_limit - 1; 1020 encap_limit = tel->encap_limit - 1;
@@ -1034,7 +1033,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1034 err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu); 1033 err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu);
1035 if (err != 0) { 1034 if (err != 0) {
1036 if (err == -EMSGSIZE) 1035 if (err == -EMSGSIZE)
1037 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); 1036 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
1038 return -1; 1037 return -1;
1039 } 1038 }
1040 1039
@@ -1364,7 +1363,7 @@ static void ip6_tnl_dev_init(struct net_device *dev)
1364 * Return: 0 1363 * Return: 0
1365 **/ 1364 **/
1366 1365
1367static void ip6_fb_tnl_dev_init(struct net_device *dev) 1366static void __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
1368{ 1367{
1369 struct ip6_tnl *t = netdev_priv(dev); 1368 struct ip6_tnl *t = netdev_priv(dev);
1370 struct net *net = dev_net(dev); 1369 struct net *net = dev_net(dev);
@@ -1388,7 +1387,7 @@ static struct xfrm6_tunnel ip6ip6_handler = {
1388 .priority = 1, 1387 .priority = 1,
1389}; 1388};
1390 1389
1391static void ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n) 1390static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
1392{ 1391{
1393 int h; 1392 int h;
1394 struct ip6_tnl *t; 1393 struct ip6_tnl *t;
@@ -1407,7 +1406,7 @@ static void ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
1407 unregister_netdevice_many(&list); 1406 unregister_netdevice_many(&list);
1408} 1407}
1409 1408
1410static int ip6_tnl_init_net(struct net *net) 1409static int __net_init ip6_tnl_init_net(struct net *net)
1411{ 1410{
1412 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 1411 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1413 int err; 1412 int err;
@@ -1436,7 +1435,7 @@ err_alloc_dev:
1436 return err; 1435 return err;
1437} 1436}
1438 1437
1439static void ip6_tnl_exit_net(struct net *net) 1438static void __net_exit ip6_tnl_exit_net(struct net *net)
1440{ 1439{
1441 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 1440 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1442 1441
@@ -1462,27 +1461,29 @@ static int __init ip6_tunnel_init(void)
1462{ 1461{
1463 int err; 1462 int err;
1464 1463
1465 if (xfrm6_tunnel_register(&ip4ip6_handler, AF_INET)) { 1464 err = register_pernet_device(&ip6_tnl_net_ops);
1465 if (err < 0)
1466 goto out_pernet;
1467
1468 err = xfrm6_tunnel_register(&ip4ip6_handler, AF_INET);
1469 if (err < 0) {
1466 printk(KERN_ERR "ip6_tunnel init: can't register ip4ip6\n"); 1470 printk(KERN_ERR "ip6_tunnel init: can't register ip4ip6\n");
1467 err = -EAGAIN; 1471 goto out_ip4ip6;
1468 goto out;
1469 } 1472 }
1470 1473
1471 if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) { 1474 err = xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6);
1475 if (err < 0) {
1472 printk(KERN_ERR "ip6_tunnel init: can't register ip6ip6\n"); 1476 printk(KERN_ERR "ip6_tunnel init: can't register ip6ip6\n");
1473 err = -EAGAIN; 1477 goto out_ip6ip6;
1474 goto unreg_ip4ip6;
1475 } 1478 }
1476 1479
1477 err = register_pernet_device(&ip6_tnl_net_ops);
1478 if (err < 0)
1479 goto err_pernet;
1480 return 0; 1480 return 0;
1481err_pernet: 1481
1482 xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6); 1482out_ip6ip6:
1483unreg_ip4ip6:
1484 xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET); 1483 xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET);
1485out: 1484out_ip4ip6:
1485 unregister_pernet_device(&ip6_tnl_net_ops);
1486out_pernet:
1486 return err; 1487 return err;
1487} 1488}
1488 1489
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 2f2a5ca2c878..85cccd6ed0b7 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -53,6 +53,7 @@
53static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 53static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
54 u8 type, u8 code, int offset, __be32 info) 54 u8 type, u8 code, int offset, __be32 info)
55{ 55{
56 struct net *net = dev_net(skb->dev);
56 __be32 spi; 57 __be32 spi;
57 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 58 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
58 struct ip_comp_hdr *ipcomph = 59 struct ip_comp_hdr *ipcomph =
@@ -63,7 +64,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
63 return; 64 return;
64 65
65 spi = htonl(ntohs(ipcomph->cpi)); 66 spi = htonl(ntohs(ipcomph->cpi));
66 x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); 67 x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6);
67 if (!x) 68 if (!x)
68 return; 69 return;
69 70
@@ -74,14 +75,15 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
74 75
75static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) 76static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
76{ 77{
78 struct net *net = xs_net(x);
77 struct xfrm_state *t = NULL; 79 struct xfrm_state *t = NULL;
78 80
79 t = xfrm_state_alloc(&init_net); 81 t = xfrm_state_alloc(net);
80 if (!t) 82 if (!t)
81 goto out; 83 goto out;
82 84
83 t->id.proto = IPPROTO_IPV6; 85 t->id.proto = IPPROTO_IPV6;
84 t->id.spi = xfrm6_tunnel_alloc_spi((xfrm_address_t *)&x->props.saddr); 86 t->id.spi = xfrm6_tunnel_alloc_spi(net, (xfrm_address_t *)&x->props.saddr);
85 if (!t->id.spi) 87 if (!t->id.spi)
86 goto error; 88 goto error;
87 89
@@ -90,6 +92,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
90 t->props.family = AF_INET6; 92 t->props.family = AF_INET6;
91 t->props.mode = x->props.mode; 93 t->props.mode = x->props.mode;
92 memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr)); 94 memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
95 memcpy(&t->mark, &x->mark, sizeof(t->mark));
93 96
94 if (xfrm_init_state(t)) 97 if (xfrm_init_state(t))
95 goto error; 98 goto error;
@@ -108,13 +111,15 @@ error:
108 111
109static int ipcomp6_tunnel_attach(struct xfrm_state *x) 112static int ipcomp6_tunnel_attach(struct xfrm_state *x)
110{ 113{
114 struct net *net = xs_net(x);
111 int err = 0; 115 int err = 0;
112 struct xfrm_state *t = NULL; 116 struct xfrm_state *t = NULL;
113 __be32 spi; 117 __be32 spi;
118 u32 mark = x->mark.m & x->mark.v;
114 119
115 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr); 120 spi = xfrm6_tunnel_spi_lookup(net, (xfrm_address_t *)&x->props.saddr);
116 if (spi) 121 if (spi)
117 t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr, 122 t = xfrm_state_lookup(net, mark, (xfrm_address_t *)&x->id.daddr,
118 spi, IPPROTO_IPV6, AF_INET6); 123 spi, IPPROTO_IPV6, AF_INET6);
119 if (!t) { 124 if (!t) {
120 t = ipcomp6_tunnel_create(x); 125 t = ipcomp6_tunnel_create(x);
@@ -154,16 +159,12 @@ static int ipcomp6_init_state(struct xfrm_state *x)
154 if (x->props.mode == XFRM_MODE_TUNNEL) { 159 if (x->props.mode == XFRM_MODE_TUNNEL) {
155 err = ipcomp6_tunnel_attach(x); 160 err = ipcomp6_tunnel_attach(x);
156 if (err) 161 if (err)
157 goto error_tunnel; 162 goto out;
158 } 163 }
159 164
160 err = 0; 165 err = 0;
161out: 166out:
162 return err; 167 return err;
163error_tunnel:
164 ipcomp_destroy(x);
165
166 goto out;
167} 168}
168 169
169static const struct xfrm_type ipcomp6_type = 170static const struct xfrm_type ipcomp6_type =
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 1f9c44442e65..bcd971915969 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -793,10 +793,10 @@ static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
793 } 793 }
794 spin_unlock_bh(&im->mca_lock); 794 spin_unlock_bh(&im->mca_lock);
795 795
796 write_lock_bh(&idev->mc_lock); 796 spin_lock_bh(&idev->mc_lock);
797 pmc->next = idev->mc_tomb; 797 pmc->next = idev->mc_tomb;
798 idev->mc_tomb = pmc; 798 idev->mc_tomb = pmc;
799 write_unlock_bh(&idev->mc_lock); 799 spin_unlock_bh(&idev->mc_lock);
800} 800}
801 801
802static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca) 802static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca)
@@ -804,7 +804,7 @@ static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca)
804 struct ifmcaddr6 *pmc, *pmc_prev; 804 struct ifmcaddr6 *pmc, *pmc_prev;
805 struct ip6_sf_list *psf, *psf_next; 805 struct ip6_sf_list *psf, *psf_next;
806 806
807 write_lock_bh(&idev->mc_lock); 807 spin_lock_bh(&idev->mc_lock);
808 pmc_prev = NULL; 808 pmc_prev = NULL;
809 for (pmc=idev->mc_tomb; pmc; pmc=pmc->next) { 809 for (pmc=idev->mc_tomb; pmc; pmc=pmc->next) {
810 if (ipv6_addr_equal(&pmc->mca_addr, pmca)) 810 if (ipv6_addr_equal(&pmc->mca_addr, pmca))
@@ -817,7 +817,8 @@ static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca)
817 else 817 else
818 idev->mc_tomb = pmc->next; 818 idev->mc_tomb = pmc->next;
819 } 819 }
820 write_unlock_bh(&idev->mc_lock); 820 spin_unlock_bh(&idev->mc_lock);
821
821 if (pmc) { 822 if (pmc) {
822 for (psf=pmc->mca_tomb; psf; psf=psf_next) { 823 for (psf=pmc->mca_tomb; psf; psf=psf_next) {
823 psf_next = psf->sf_next; 824 psf_next = psf->sf_next;
@@ -832,10 +833,10 @@ static void mld_clear_delrec(struct inet6_dev *idev)
832{ 833{
833 struct ifmcaddr6 *pmc, *nextpmc; 834 struct ifmcaddr6 *pmc, *nextpmc;
834 835
835 write_lock_bh(&idev->mc_lock); 836 spin_lock_bh(&idev->mc_lock);
836 pmc = idev->mc_tomb; 837 pmc = idev->mc_tomb;
837 idev->mc_tomb = NULL; 838 idev->mc_tomb = NULL;
838 write_unlock_bh(&idev->mc_lock); 839 spin_unlock_bh(&idev->mc_lock);
839 840
840 for (; pmc; pmc = nextpmc) { 841 for (; pmc; pmc = nextpmc) {
841 nextpmc = pmc->next; 842 nextpmc = pmc->next;
@@ -1696,7 +1697,7 @@ static void mld_send_cr(struct inet6_dev *idev)
1696 int type, dtype; 1697 int type, dtype;
1697 1698
1698 read_lock_bh(&idev->lock); 1699 read_lock_bh(&idev->lock);
1699 write_lock_bh(&idev->mc_lock); 1700 spin_lock(&idev->mc_lock);
1700 1701
1701 /* deleted MCA's */ 1702 /* deleted MCA's */
1702 pmc_prev = NULL; 1703 pmc_prev = NULL;
@@ -1730,7 +1731,7 @@ static void mld_send_cr(struct inet6_dev *idev)
1730 } else 1731 } else
1731 pmc_prev = pmc; 1732 pmc_prev = pmc;
1732 } 1733 }
1733 write_unlock_bh(&idev->mc_lock); 1734 spin_unlock(&idev->mc_lock);
1734 1735
1735 /* change recs */ 1736 /* change recs */
1736 for (pmc=idev->mc_list; pmc; pmc=pmc->next) { 1737 for (pmc=idev->mc_list; pmc; pmc=pmc->next) {
@@ -2311,7 +2312,7 @@ void ipv6_mc_up(struct inet6_dev *idev)
2311void ipv6_mc_init_dev(struct inet6_dev *idev) 2312void ipv6_mc_init_dev(struct inet6_dev *idev)
2312{ 2313{
2313 write_lock_bh(&idev->lock); 2314 write_lock_bh(&idev->lock);
2314 rwlock_init(&idev->mc_lock); 2315 spin_lock_init(&idev->mc_lock);
2315 idev->mc_gq_running = 0; 2316 idev->mc_gq_running = 0;
2316 setup_timer(&idev->mc_gq_timer, mld_gq_timer_expire, 2317 setup_timer(&idev->mc_gq_timer, mld_gq_timer_expire,
2317 (unsigned long)idev); 2318 (unsigned long)idev);
@@ -2646,7 +2647,7 @@ static const struct file_operations igmp6_mcf_seq_fops = {
2646 .release = seq_release_net, 2647 .release = seq_release_net,
2647}; 2648};
2648 2649
2649static int igmp6_proc_init(struct net *net) 2650static int __net_init igmp6_proc_init(struct net *net)
2650{ 2651{
2651 int err; 2652 int err;
2652 2653
@@ -2666,23 +2667,22 @@ out_proc_net_igmp6:
2666 goto out; 2667 goto out;
2667} 2668}
2668 2669
2669static void igmp6_proc_exit(struct net *net) 2670static void __net_exit igmp6_proc_exit(struct net *net)
2670{ 2671{
2671 proc_net_remove(net, "mcfilter6"); 2672 proc_net_remove(net, "mcfilter6");
2672 proc_net_remove(net, "igmp6"); 2673 proc_net_remove(net, "igmp6");
2673} 2674}
2674#else 2675#else
2675static int igmp6_proc_init(struct net *net) 2676static inline int igmp6_proc_init(struct net *net)
2676{ 2677{
2677 return 0; 2678 return 0;
2678} 2679}
2679static void igmp6_proc_exit(struct net *net) 2680static inline void igmp6_proc_exit(struct net *net)
2680{ 2681{
2681 ;
2682} 2682}
2683#endif 2683#endif
2684 2684
2685static int igmp6_net_init(struct net *net) 2685static int __net_init igmp6_net_init(struct net *net)
2686{ 2686{
2687 int err; 2687 int err;
2688 2688
@@ -2708,7 +2708,7 @@ out_sock_create:
2708 goto out; 2708 goto out;
2709} 2709}
2710 2710
2711static void igmp6_net_exit(struct net *net) 2711static void __net_exit igmp6_net_exit(struct net *net)
2712{ 2712{
2713 inet_ctl_sock_destroy(net->ipv6.igmp_sk); 2713 inet_ctl_sock_destroy(net->ipv6.igmp_sk);
2714 igmp6_proc_exit(net); 2714 igmp6_proc_exit(net);
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index f797e8c6f3b3..2794b6002836 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -56,7 +56,7 @@ static inline void *mip6_padn(__u8 *data, __u8 padlen)
56 56
57static inline void mip6_param_prob(struct sk_buff *skb, u8 code, int pos) 57static inline void mip6_param_prob(struct sk_buff *skb, u8 code, int pos)
58{ 58{
59 icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos, skb->dev); 59 icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos);
60} 60}
61 61
62static int mip6_mh_len(int type) 62static int mip6_mh_len(int type)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index c45852798092..8bcc4b7db3bf 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1772,7 +1772,7 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, void __user *bu
1772 1772
1773#endif 1773#endif
1774 1774
1775static int ndisc_net_init(struct net *net) 1775static int __net_init ndisc_net_init(struct net *net)
1776{ 1776{
1777 struct ipv6_pinfo *np; 1777 struct ipv6_pinfo *np;
1778 struct sock *sk; 1778 struct sock *sk;
@@ -1797,7 +1797,7 @@ static int ndisc_net_init(struct net *net)
1797 return 0; 1797 return 0;
1798} 1798}
1799 1799
1800static void ndisc_net_exit(struct net *net) 1800static void __net_exit ndisc_net_exit(struct net *net)
1801{ 1801{
1802 inet_ctl_sock_destroy(net->ipv6.ndisc_sk); 1802 inet_ctl_sock_destroy(net->ipv6.ndisc_sk);
1803} 1803}
@@ -1820,8 +1820,7 @@ int __init ndisc_init(void)
1820 neigh_table_init(&nd_tbl); 1820 neigh_table_init(&nd_tbl);
1821 1821
1822#ifdef CONFIG_SYSCTL 1822#ifdef CONFIG_SYSCTL
1823 err = neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, 1823 err = neigh_sysctl_register(NULL, &nd_tbl.parms, "ipv6",
1824 NET_IPV6_NEIGH, "ipv6",
1825 &ndisc_ifinfo_sysctl_change); 1824 &ndisc_ifinfo_sysctl_change);
1826 if (err) 1825 if (err)
1827 goto out_unregister_pernet; 1826 goto out_unregister_pernet;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 480d7f8c9802..9210e312edf1 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -29,6 +29,7 @@
29#include <linux/netfilter_ipv6/ip6_tables.h> 29#include <linux/netfilter_ipv6/ip6_tables.h>
30#include <linux/netfilter/x_tables.h> 30#include <linux/netfilter/x_tables.h>
31#include <net/netfilter/nf_log.h> 31#include <net/netfilter/nf_log.h>
32#include "../../netfilter/xt_repldata.h"
32 33
33MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
34MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 35MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
@@ -67,6 +68,12 @@ do { \
67#define inline 68#define inline
68#endif 69#endif
69 70
71void *ip6t_alloc_initial_table(const struct xt_table *info)
72{
73 return xt_alloc_initial_table(ip6t, IP6T);
74}
75EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table);
76
70/* 77/*
71 We keep a set of rules for each CPU, so we can avoid write-locking 78 We keep a set of rules for each CPU, so we can avoid write-locking
72 them in the softirq when updating the counters and therefore 79 them in the softirq when updating the counters and therefore
@@ -201,7 +208,7 @@ ip6t_error(struct sk_buff *skb, const struct xt_target_param *par)
201 208
202/* Performance critical - called for every packet */ 209/* Performance critical - called for every packet */
203static inline bool 210static inline bool
204do_match(struct ip6t_entry_match *m, const struct sk_buff *skb, 211do_match(const struct ip6t_entry_match *m, const struct sk_buff *skb,
205 struct xt_match_param *par) 212 struct xt_match_param *par)
206{ 213{
207 par->match = m->u.kernel.match; 214 par->match = m->u.kernel.match;
@@ -215,7 +222,7 @@ do_match(struct ip6t_entry_match *m, const struct sk_buff *skb,
215} 222}
216 223
217static inline struct ip6t_entry * 224static inline struct ip6t_entry *
218get_entry(void *base, unsigned int offset) 225get_entry(const void *base, unsigned int offset)
219{ 226{
220 return (struct ip6t_entry *)(base + offset); 227 return (struct ip6t_entry *)(base + offset);
221} 228}
@@ -229,6 +236,12 @@ static inline bool unconditional(const struct ip6t_ip6 *ipv6)
229 return memcmp(ipv6, &uncond, sizeof(uncond)) == 0; 236 return memcmp(ipv6, &uncond, sizeof(uncond)) == 0;
230} 237}
231 238
239static inline const struct ip6t_entry_target *
240ip6t_get_target_c(const struct ip6t_entry *e)
241{
242 return ip6t_get_target((struct ip6t_entry *)e);
243}
244
232#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ 245#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
233 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) 246 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
234/* This cries for unification! */ 247/* This cries for unification! */
@@ -264,11 +277,11 @@ static struct nf_loginfo trace_loginfo = {
264 277
265/* Mildly perf critical (only if packet tracing is on) */ 278/* Mildly perf critical (only if packet tracing is on) */
266static inline int 279static inline int
267get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e, 280get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e,
268 const char *hookname, const char **chainname, 281 const char *hookname, const char **chainname,
269 const char **comment, unsigned int *rulenum) 282 const char **comment, unsigned int *rulenum)
270{ 283{
271 struct ip6t_standard_target *t = (void *)ip6t_get_target(s); 284 const struct ip6t_standard_target *t = (void *)ip6t_get_target_c(s);
272 285
273 if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) { 286 if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) {
274 /* Head of user chain: ERROR target with chainname */ 287 /* Head of user chain: ERROR target with chainname */
@@ -294,17 +307,18 @@ get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
294 return 0; 307 return 0;
295} 308}
296 309
297static void trace_packet(struct sk_buff *skb, 310static void trace_packet(const struct sk_buff *skb,
298 unsigned int hook, 311 unsigned int hook,
299 const struct net_device *in, 312 const struct net_device *in,
300 const struct net_device *out, 313 const struct net_device *out,
301 const char *tablename, 314 const char *tablename,
302 struct xt_table_info *private, 315 const struct xt_table_info *private,
303 struct ip6t_entry *e) 316 const struct ip6t_entry *e)
304{ 317{
305 void *table_base; 318 const void *table_base;
306 const struct ip6t_entry *root; 319 const struct ip6t_entry *root;
307 const char *hookname, *chainname, *comment; 320 const char *hookname, *chainname, *comment;
321 const struct ip6t_entry *iter;
308 unsigned int rulenum = 0; 322 unsigned int rulenum = 0;
309 323
310 table_base = private->entries[smp_processor_id()]; 324 table_base = private->entries[smp_processor_id()];
@@ -313,10 +327,10 @@ static void trace_packet(struct sk_buff *skb,
313 hookname = chainname = hooknames[hook]; 327 hookname = chainname = hooknames[hook];
314 comment = comments[NF_IP6_TRACE_COMMENT_RULE]; 328 comment = comments[NF_IP6_TRACE_COMMENT_RULE];
315 329
316 IP6T_ENTRY_ITERATE(root, 330 xt_entry_foreach(iter, root, private->size - private->hook_entry[hook])
317 private->size - private->hook_entry[hook], 331 if (get_chainname_rulenum(iter, e, hookname,
318 get_chainname_rulenum, 332 &chainname, &comment, &rulenum) != 0)
319 e, hookname, &chainname, &comment, &rulenum); 333 break;
320 334
321 nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo, 335 nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo,
322 "TRACE: %s:%s:%s:%u ", 336 "TRACE: %s:%s:%s:%u ",
@@ -345,9 +359,9 @@ ip6t_do_table(struct sk_buff *skb,
345 /* Initializing verdict to NF_DROP keeps gcc happy. */ 359 /* Initializing verdict to NF_DROP keeps gcc happy. */
346 unsigned int verdict = NF_DROP; 360 unsigned int verdict = NF_DROP;
347 const char *indev, *outdev; 361 const char *indev, *outdev;
348 void *table_base; 362 const void *table_base;
349 struct ip6t_entry *e, *back; 363 struct ip6t_entry *e, *back;
350 struct xt_table_info *private; 364 const struct xt_table_info *private;
351 struct xt_match_param mtpar; 365 struct xt_match_param mtpar;
352 struct xt_target_param tgpar; 366 struct xt_target_param tgpar;
353 367
@@ -378,22 +392,27 @@ ip6t_do_table(struct sk_buff *skb,
378 back = get_entry(table_base, private->underflow[hook]); 392 back = get_entry(table_base, private->underflow[hook]);
379 393
380 do { 394 do {
381 struct ip6t_entry_target *t; 395 const struct ip6t_entry_target *t;
396 const struct xt_entry_match *ematch;
382 397
383 IP_NF_ASSERT(e); 398 IP_NF_ASSERT(e);
384 IP_NF_ASSERT(back); 399 IP_NF_ASSERT(back);
385 if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, 400 if (!ip6_packet_match(skb, indev, outdev, &e->ipv6,
386 &mtpar.thoff, &mtpar.fragoff, &hotdrop) || 401 &mtpar.thoff, &mtpar.fragoff, &hotdrop)) {
387 IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) { 402 no_match:
388 e = ip6t_next_entry(e); 403 e = ip6t_next_entry(e);
389 continue; 404 continue;
390 } 405 }
391 406
407 xt_ematch_foreach(ematch, e)
408 if (do_match(ematch, skb, &mtpar) != 0)
409 goto no_match;
410
392 ADD_COUNTER(e->counters, 411 ADD_COUNTER(e->counters,
393 ntohs(ipv6_hdr(skb)->payload_len) + 412 ntohs(ipv6_hdr(skb)->payload_len) +
394 sizeof(struct ipv6hdr), 1); 413 sizeof(struct ipv6hdr), 1);
395 414
396 t = ip6t_get_target(e); 415 t = ip6t_get_target_c(e);
397 IP_NF_ASSERT(t->u.kernel.target); 416 IP_NF_ASSERT(t->u.kernel.target);
398 417
399#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ 418#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
@@ -475,7 +494,7 @@ ip6t_do_table(struct sk_buff *skb,
475/* Figures out from what hook each rule can be called: returns 0 if 494/* Figures out from what hook each rule can be called: returns 0 if
476 there are loops. Puts hook bitmask in comefrom. */ 495 there are loops. Puts hook bitmask in comefrom. */
477static int 496static int
478mark_source_chains(struct xt_table_info *newinfo, 497mark_source_chains(const struct xt_table_info *newinfo,
479 unsigned int valid_hooks, void *entry0) 498 unsigned int valid_hooks, void *entry0)
480{ 499{
481 unsigned int hook; 500 unsigned int hook;
@@ -493,8 +512,8 @@ mark_source_chains(struct xt_table_info *newinfo,
493 e->counters.pcnt = pos; 512 e->counters.pcnt = pos;
494 513
495 for (;;) { 514 for (;;) {
496 struct ip6t_standard_target *t 515 const struct ip6t_standard_target *t
497 = (void *)ip6t_get_target(e); 516 = (void *)ip6t_get_target_c(e);
498 int visited = e->comefrom & (1 << hook); 517 int visited = e->comefrom & (1 << hook);
499 518
500 if (e->comefrom & (1 << NF_INET_NUMHOOKS)) { 519 if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
@@ -584,27 +603,23 @@ mark_source_chains(struct xt_table_info *newinfo,
584 return 1; 603 return 1;
585} 604}
586 605
587static int 606static void cleanup_match(struct ip6t_entry_match *m, struct net *net)
588cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
589{ 607{
590 struct xt_mtdtor_param par; 608 struct xt_mtdtor_param par;
591 609
592 if (i && (*i)-- == 0) 610 par.net = net;
593 return 1;
594
595 par.match = m->u.kernel.match; 611 par.match = m->u.kernel.match;
596 par.matchinfo = m->data; 612 par.matchinfo = m->data;
597 par.family = NFPROTO_IPV6; 613 par.family = NFPROTO_IPV6;
598 if (par.match->destroy != NULL) 614 if (par.match->destroy != NULL)
599 par.match->destroy(&par); 615 par.match->destroy(&par);
600 module_put(par.match->me); 616 module_put(par.match->me);
601 return 0;
602} 617}
603 618
604static int 619static int
605check_entry(struct ip6t_entry *e, const char *name) 620check_entry(const struct ip6t_entry *e, const char *name)
606{ 621{
607 struct ip6t_entry_target *t; 622 const struct ip6t_entry_target *t;
608 623
609 if (!ip6_checkentry(&e->ipv6)) { 624 if (!ip6_checkentry(&e->ipv6)) {
610 duprintf("ip_tables: ip check failed %p %s.\n", e, name); 625 duprintf("ip_tables: ip check failed %p %s.\n", e, name);
@@ -615,15 +630,14 @@ check_entry(struct ip6t_entry *e, const char *name)
615 e->next_offset) 630 e->next_offset)
616 return -EINVAL; 631 return -EINVAL;
617 632
618 t = ip6t_get_target(e); 633 t = ip6t_get_target_c(e);
619 if (e->target_offset + t->u.target_size > e->next_offset) 634 if (e->target_offset + t->u.target_size > e->next_offset)
620 return -EINVAL; 635 return -EINVAL;
621 636
622 return 0; 637 return 0;
623} 638}
624 639
625static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par, 640static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par)
626 unsigned int *i)
627{ 641{
628 const struct ip6t_ip6 *ipv6 = par->entryinfo; 642 const struct ip6t_ip6 *ipv6 = par->entryinfo;
629 int ret; 643 int ret;
@@ -638,13 +652,11 @@ static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
638 par.match->name); 652 par.match->name);
639 return ret; 653 return ret;
640 } 654 }
641 ++*i;
642 return 0; 655 return 0;
643} 656}
644 657
645static int 658static int
646find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par, 659find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par)
647 unsigned int *i)
648{ 660{
649 struct xt_match *match; 661 struct xt_match *match;
650 int ret; 662 int ret;
@@ -658,7 +670,7 @@ find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
658 } 670 }
659 m->u.kernel.match = match; 671 m->u.kernel.match = match;
660 672
661 ret = check_match(m, par, i); 673 ret = check_match(m, par);
662 if (ret) 674 if (ret)
663 goto err; 675 goto err;
664 676
@@ -668,10 +680,11 @@ err:
668 return ret; 680 return ret;
669} 681}
670 682
671static int check_target(struct ip6t_entry *e, const char *name) 683static int check_target(struct ip6t_entry *e, struct net *net, const char *name)
672{ 684{
673 struct ip6t_entry_target *t = ip6t_get_target(e); 685 struct ip6t_entry_target *t = ip6t_get_target(e);
674 struct xt_tgchk_param par = { 686 struct xt_tgchk_param par = {
687 .net = net,
675 .table = name, 688 .table = name,
676 .entryinfo = e, 689 .entryinfo = e,
677 .target = t->u.kernel.target, 690 .target = t->u.kernel.target,
@@ -693,27 +706,32 @@ static int check_target(struct ip6t_entry *e, const char *name)
693} 706}
694 707
695static int 708static int
696find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size, 709find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
697 unsigned int *i) 710 unsigned int size)
698{ 711{
699 struct ip6t_entry_target *t; 712 struct ip6t_entry_target *t;
700 struct xt_target *target; 713 struct xt_target *target;
701 int ret; 714 int ret;
702 unsigned int j; 715 unsigned int j;
703 struct xt_mtchk_param mtpar; 716 struct xt_mtchk_param mtpar;
717 struct xt_entry_match *ematch;
704 718
705 ret = check_entry(e, name); 719 ret = check_entry(e, name);
706 if (ret) 720 if (ret)
707 return ret; 721 return ret;
708 722
709 j = 0; 723 j = 0;
724 mtpar.net = net;
710 mtpar.table = name; 725 mtpar.table = name;
711 mtpar.entryinfo = &e->ipv6; 726 mtpar.entryinfo = &e->ipv6;
712 mtpar.hook_mask = e->comefrom; 727 mtpar.hook_mask = e->comefrom;
713 mtpar.family = NFPROTO_IPV6; 728 mtpar.family = NFPROTO_IPV6;
714 ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j); 729 xt_ematch_foreach(ematch, e) {
715 if (ret != 0) 730 ret = find_check_match(ematch, &mtpar);
716 goto cleanup_matches; 731 if (ret != 0)
732 goto cleanup_matches;
733 ++j;
734 }
717 735
718 t = ip6t_get_target(e); 736 t = ip6t_get_target(e);
719 target = try_then_request_module(xt_find_target(AF_INET6, 737 target = try_then_request_module(xt_find_target(AF_INET6,
@@ -727,27 +745,29 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
727 } 745 }
728 t->u.kernel.target = target; 746 t->u.kernel.target = target;
729 747
730 ret = check_target(e, name); 748 ret = check_target(e, net, name);
731 if (ret) 749 if (ret)
732 goto err; 750 goto err;
733
734 (*i)++;
735 return 0; 751 return 0;
736 err: 752 err:
737 module_put(t->u.kernel.target->me); 753 module_put(t->u.kernel.target->me);
738 cleanup_matches: 754 cleanup_matches:
739 IP6T_MATCH_ITERATE(e, cleanup_match, &j); 755 xt_ematch_foreach(ematch, e) {
756 if (j-- == 0)
757 break;
758 cleanup_match(ematch, net);
759 }
740 return ret; 760 return ret;
741} 761}
742 762
743static bool check_underflow(struct ip6t_entry *e) 763static bool check_underflow(const struct ip6t_entry *e)
744{ 764{
745 const struct ip6t_entry_target *t; 765 const struct ip6t_entry_target *t;
746 unsigned int verdict; 766 unsigned int verdict;
747 767
748 if (!unconditional(&e->ipv6)) 768 if (!unconditional(&e->ipv6))
749 return false; 769 return false;
750 t = ip6t_get_target(e); 770 t = ip6t_get_target_c(e);
751 if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) 771 if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
752 return false; 772 return false;
753 verdict = ((struct ip6t_standard_target *)t)->verdict; 773 verdict = ((struct ip6t_standard_target *)t)->verdict;
@@ -758,12 +778,11 @@ static bool check_underflow(struct ip6t_entry *e)
758static int 778static int
759check_entry_size_and_hooks(struct ip6t_entry *e, 779check_entry_size_and_hooks(struct ip6t_entry *e,
760 struct xt_table_info *newinfo, 780 struct xt_table_info *newinfo,
761 unsigned char *base, 781 const unsigned char *base,
762 unsigned char *limit, 782 const unsigned char *limit,
763 const unsigned int *hook_entries, 783 const unsigned int *hook_entries,
764 const unsigned int *underflows, 784 const unsigned int *underflows,
765 unsigned int valid_hooks, 785 unsigned int valid_hooks)
766 unsigned int *i)
767{ 786{
768 unsigned int h; 787 unsigned int h;
769 788
@@ -800,50 +819,41 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
800 /* Clear counters and comefrom */ 819 /* Clear counters and comefrom */
801 e->counters = ((struct xt_counters) { 0, 0 }); 820 e->counters = ((struct xt_counters) { 0, 0 });
802 e->comefrom = 0; 821 e->comefrom = 0;
803
804 (*i)++;
805 return 0; 822 return 0;
806} 823}
807 824
808static int 825static void cleanup_entry(struct ip6t_entry *e, struct net *net)
809cleanup_entry(struct ip6t_entry *e, unsigned int *i)
810{ 826{
811 struct xt_tgdtor_param par; 827 struct xt_tgdtor_param par;
812 struct ip6t_entry_target *t; 828 struct ip6t_entry_target *t;
813 829 struct xt_entry_match *ematch;
814 if (i && (*i)-- == 0)
815 return 1;
816 830
817 /* Cleanup all matches */ 831 /* Cleanup all matches */
818 IP6T_MATCH_ITERATE(e, cleanup_match, NULL); 832 xt_ematch_foreach(ematch, e)
833 cleanup_match(ematch, net);
819 t = ip6t_get_target(e); 834 t = ip6t_get_target(e);
820 835
836 par.net = net;
821 par.target = t->u.kernel.target; 837 par.target = t->u.kernel.target;
822 par.targinfo = t->data; 838 par.targinfo = t->data;
823 par.family = NFPROTO_IPV6; 839 par.family = NFPROTO_IPV6;
824 if (par.target->destroy != NULL) 840 if (par.target->destroy != NULL)
825 par.target->destroy(&par); 841 par.target->destroy(&par);
826 module_put(par.target->me); 842 module_put(par.target->me);
827 return 0;
828} 843}
829 844
830/* Checks and translates the user-supplied table segment (held in 845/* Checks and translates the user-supplied table segment (held in
831 newinfo) */ 846 newinfo) */
832static int 847static int
833translate_table(const char *name, 848translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
834 unsigned int valid_hooks, 849 const struct ip6t_replace *repl)
835 struct xt_table_info *newinfo,
836 void *entry0,
837 unsigned int size,
838 unsigned int number,
839 const unsigned int *hook_entries,
840 const unsigned int *underflows)
841{ 850{
851 struct ip6t_entry *iter;
842 unsigned int i; 852 unsigned int i;
843 int ret; 853 int ret = 0;
844 854
845 newinfo->size = size; 855 newinfo->size = repl->size;
846 newinfo->number = number; 856 newinfo->number = repl->num_entries;
847 857
848 /* Init all hooks to impossible value. */ 858 /* Init all hooks to impossible value. */
849 for (i = 0; i < NF_INET_NUMHOOKS; i++) { 859 for (i = 0; i < NF_INET_NUMHOOKS; i++) {
@@ -854,49 +864,58 @@ translate_table(const char *name,
854 duprintf("translate_table: size %u\n", newinfo->size); 864 duprintf("translate_table: size %u\n", newinfo->size);
855 i = 0; 865 i = 0;
856 /* Walk through entries, checking offsets. */ 866 /* Walk through entries, checking offsets. */
857 ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, 867 xt_entry_foreach(iter, entry0, newinfo->size) {
858 check_entry_size_and_hooks, 868 ret = check_entry_size_and_hooks(iter, newinfo, entry0,
859 newinfo, 869 entry0 + repl->size,
860 entry0, 870 repl->hook_entry,
861 entry0 + size, 871 repl->underflow,
862 hook_entries, underflows, valid_hooks, &i); 872 repl->valid_hooks);
863 if (ret != 0) 873 if (ret != 0)
864 return ret; 874 return ret;
875 ++i;
876 }
865 877
866 if (i != number) { 878 if (i != repl->num_entries) {
867 duprintf("translate_table: %u not %u entries\n", 879 duprintf("translate_table: %u not %u entries\n",
868 i, number); 880 i, repl->num_entries);
869 return -EINVAL; 881 return -EINVAL;
870 } 882 }
871 883
872 /* Check hooks all assigned */ 884 /* Check hooks all assigned */
873 for (i = 0; i < NF_INET_NUMHOOKS; i++) { 885 for (i = 0; i < NF_INET_NUMHOOKS; i++) {
874 /* Only hooks which are valid */ 886 /* Only hooks which are valid */
875 if (!(valid_hooks & (1 << i))) 887 if (!(repl->valid_hooks & (1 << i)))
876 continue; 888 continue;
877 if (newinfo->hook_entry[i] == 0xFFFFFFFF) { 889 if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
878 duprintf("Invalid hook entry %u %u\n", 890 duprintf("Invalid hook entry %u %u\n",
879 i, hook_entries[i]); 891 i, repl->hook_entry[i]);
880 return -EINVAL; 892 return -EINVAL;
881 } 893 }
882 if (newinfo->underflow[i] == 0xFFFFFFFF) { 894 if (newinfo->underflow[i] == 0xFFFFFFFF) {
883 duprintf("Invalid underflow %u %u\n", 895 duprintf("Invalid underflow %u %u\n",
884 i, underflows[i]); 896 i, repl->underflow[i]);
885 return -EINVAL; 897 return -EINVAL;
886 } 898 }
887 } 899 }
888 900
889 if (!mark_source_chains(newinfo, valid_hooks, entry0)) 901 if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
890 return -ELOOP; 902 return -ELOOP;
891 903
892 /* Finally, each sanity check must pass */ 904 /* Finally, each sanity check must pass */
893 i = 0; 905 i = 0;
894 ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, 906 xt_entry_foreach(iter, entry0, newinfo->size) {
895 find_check_entry, name, size, &i); 907 ret = find_check_entry(iter, net, repl->name, repl->size);
908 if (ret != 0)
909 break;
910 ++i;
911 }
896 912
897 if (ret != 0) { 913 if (ret != 0) {
898 IP6T_ENTRY_ITERATE(entry0, newinfo->size, 914 xt_entry_foreach(iter, entry0, newinfo->size) {
899 cleanup_entry, &i); 915 if (i-- == 0)
916 break;
917 cleanup_entry(iter, net);
918 }
900 return ret; 919 return ret;
901 } 920 }
902 921
@@ -909,33 +928,11 @@ translate_table(const char *name,
909 return ret; 928 return ret;
910} 929}
911 930
912/* Gets counters. */
913static inline int
914add_entry_to_counter(const struct ip6t_entry *e,
915 struct xt_counters total[],
916 unsigned int *i)
917{
918 ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
919
920 (*i)++;
921 return 0;
922}
923
924static inline int
925set_entry_to_counter(const struct ip6t_entry *e,
926 struct ip6t_counters total[],
927 unsigned int *i)
928{
929 SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
930
931 (*i)++;
932 return 0;
933}
934
935static void 931static void
936get_counters(const struct xt_table_info *t, 932get_counters(const struct xt_table_info *t,
937 struct xt_counters counters[]) 933 struct xt_counters counters[])
938{ 934{
935 struct ip6t_entry *iter;
939 unsigned int cpu; 936 unsigned int cpu;
940 unsigned int i; 937 unsigned int i;
941 unsigned int curcpu; 938 unsigned int curcpu;
@@ -951,32 +948,32 @@ get_counters(const struct xt_table_info *t,
951 curcpu = smp_processor_id(); 948 curcpu = smp_processor_id();
952 949
953 i = 0; 950 i = 0;
954 IP6T_ENTRY_ITERATE(t->entries[curcpu], 951 xt_entry_foreach(iter, t->entries[curcpu], t->size) {
955 t->size, 952 SET_COUNTER(counters[i], iter->counters.bcnt,
956 set_entry_to_counter, 953 iter->counters.pcnt);
957 counters, 954 ++i;
958 &i); 955 }
959 956
960 for_each_possible_cpu(cpu) { 957 for_each_possible_cpu(cpu) {
961 if (cpu == curcpu) 958 if (cpu == curcpu)
962 continue; 959 continue;
963 i = 0; 960 i = 0;
964 xt_info_wrlock(cpu); 961 xt_info_wrlock(cpu);
965 IP6T_ENTRY_ITERATE(t->entries[cpu], 962 xt_entry_foreach(iter, t->entries[cpu], t->size) {
966 t->size, 963 ADD_COUNTER(counters[i], iter->counters.bcnt,
967 add_entry_to_counter, 964 iter->counters.pcnt);
968 counters, 965 ++i;
969 &i); 966 }
970 xt_info_wrunlock(cpu); 967 xt_info_wrunlock(cpu);
971 } 968 }
972 local_bh_enable(); 969 local_bh_enable();
973} 970}
974 971
975static struct xt_counters *alloc_counters(struct xt_table *table) 972static struct xt_counters *alloc_counters(const struct xt_table *table)
976{ 973{
977 unsigned int countersize; 974 unsigned int countersize;
978 struct xt_counters *counters; 975 struct xt_counters *counters;
979 struct xt_table_info *private = table->private; 976 const struct xt_table_info *private = table->private;
980 977
981 /* We need atomic snapshot of counters: rest doesn't change 978 /* We need atomic snapshot of counters: rest doesn't change
982 (other than comefrom, which userspace doesn't care 979 (other than comefrom, which userspace doesn't care
@@ -994,11 +991,11 @@ static struct xt_counters *alloc_counters(struct xt_table *table)
994 991
995static int 992static int
996copy_entries_to_user(unsigned int total_size, 993copy_entries_to_user(unsigned int total_size,
997 struct xt_table *table, 994 const struct xt_table *table,
998 void __user *userptr) 995 void __user *userptr)
999{ 996{
1000 unsigned int off, num; 997 unsigned int off, num;
1001 struct ip6t_entry *e; 998 const struct ip6t_entry *e;
1002 struct xt_counters *counters; 999 struct xt_counters *counters;
1003 const struct xt_table_info *private = table->private; 1000 const struct xt_table_info *private = table->private;
1004 int ret = 0; 1001 int ret = 0;
@@ -1050,7 +1047,7 @@ copy_entries_to_user(unsigned int total_size,
1050 } 1047 }
1051 } 1048 }
1052 1049
1053 t = ip6t_get_target(e); 1050 t = ip6t_get_target_c(e);
1054 if (copy_to_user(userptr + off + e->target_offset 1051 if (copy_to_user(userptr + off + e->target_offset
1055 + offsetof(struct ip6t_entry_target, 1052 + offsetof(struct ip6t_entry_target,
1056 u.user.name), 1053 u.user.name),
@@ -1067,7 +1064,7 @@ copy_entries_to_user(unsigned int total_size,
1067} 1064}
1068 1065
1069#ifdef CONFIG_COMPAT 1066#ifdef CONFIG_COMPAT
1070static void compat_standard_from_user(void *dst, void *src) 1067static void compat_standard_from_user(void *dst, const void *src)
1071{ 1068{
1072 int v = *(compat_int_t *)src; 1069 int v = *(compat_int_t *)src;
1073 1070
@@ -1076,7 +1073,7 @@ static void compat_standard_from_user(void *dst, void *src)
1076 memcpy(dst, &v, sizeof(v)); 1073 memcpy(dst, &v, sizeof(v));
1077} 1074}
1078 1075
1079static int compat_standard_to_user(void __user *dst, void *src) 1076static int compat_standard_to_user(void __user *dst, const void *src)
1080{ 1077{
1081 compat_int_t cv = *(int *)src; 1078 compat_int_t cv = *(int *)src;
1082 1079
@@ -1085,25 +1082,20 @@ static int compat_standard_to_user(void __user *dst, void *src)
1085 return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0; 1082 return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
1086} 1083}
1087 1084
1088static inline int 1085static int compat_calc_entry(const struct ip6t_entry *e,
1089compat_calc_match(struct ip6t_entry_match *m, int *size)
1090{
1091 *size += xt_compat_match_offset(m->u.kernel.match);
1092 return 0;
1093}
1094
1095static int compat_calc_entry(struct ip6t_entry *e,
1096 const struct xt_table_info *info, 1086 const struct xt_table_info *info,
1097 void *base, struct xt_table_info *newinfo) 1087 const void *base, struct xt_table_info *newinfo)
1098{ 1088{
1099 struct ip6t_entry_target *t; 1089 const struct xt_entry_match *ematch;
1090 const struct ip6t_entry_target *t;
1100 unsigned int entry_offset; 1091 unsigned int entry_offset;
1101 int off, i, ret; 1092 int off, i, ret;
1102 1093
1103 off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1094 off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
1104 entry_offset = (void *)e - base; 1095 entry_offset = (void *)e - base;
1105 IP6T_MATCH_ITERATE(e, compat_calc_match, &off); 1096 xt_ematch_foreach(ematch, e)
1106 t = ip6t_get_target(e); 1097 off += xt_compat_match_offset(ematch->u.kernel.match);
1098 t = ip6t_get_target_c(e);
1107 off += xt_compat_target_offset(t->u.kernel.target); 1099 off += xt_compat_target_offset(t->u.kernel.target);
1108 newinfo->size -= off; 1100 newinfo->size -= off;
1109 ret = xt_compat_add_offset(AF_INET6, entry_offset, off); 1101 ret = xt_compat_add_offset(AF_INET6, entry_offset, off);
@@ -1124,7 +1116,9 @@ static int compat_calc_entry(struct ip6t_entry *e,
1124static int compat_table_info(const struct xt_table_info *info, 1116static int compat_table_info(const struct xt_table_info *info,
1125 struct xt_table_info *newinfo) 1117 struct xt_table_info *newinfo)
1126{ 1118{
1119 struct ip6t_entry *iter;
1127 void *loc_cpu_entry; 1120 void *loc_cpu_entry;
1121 int ret;
1128 1122
1129 if (!newinfo || !info) 1123 if (!newinfo || !info)
1130 return -EINVAL; 1124 return -EINVAL;
@@ -1133,13 +1127,17 @@ static int compat_table_info(const struct xt_table_info *info,
1133 memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); 1127 memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
1134 newinfo->initial_entries = 0; 1128 newinfo->initial_entries = 0;
1135 loc_cpu_entry = info->entries[raw_smp_processor_id()]; 1129 loc_cpu_entry = info->entries[raw_smp_processor_id()];
1136 return IP6T_ENTRY_ITERATE(loc_cpu_entry, info->size, 1130 xt_entry_foreach(iter, loc_cpu_entry, info->size) {
1137 compat_calc_entry, info, loc_cpu_entry, 1131 ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo);
1138 newinfo); 1132 if (ret != 0)
1133 return ret;
1134 }
1135 return 0;
1139} 1136}
1140#endif 1137#endif
1141 1138
1142static int get_info(struct net *net, void __user *user, int *len, int compat) 1139static int get_info(struct net *net, void __user *user,
1140 const int *len, int compat)
1143{ 1141{
1144 char name[IP6T_TABLE_MAXNAMELEN]; 1142 char name[IP6T_TABLE_MAXNAMELEN];
1145 struct xt_table *t; 1143 struct xt_table *t;
@@ -1164,10 +1162,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
1164 if (t && !IS_ERR(t)) { 1162 if (t && !IS_ERR(t)) {
1165 struct ip6t_getinfo info; 1163 struct ip6t_getinfo info;
1166 const struct xt_table_info *private = t->private; 1164 const struct xt_table_info *private = t->private;
1167
1168#ifdef CONFIG_COMPAT 1165#ifdef CONFIG_COMPAT
1166 struct xt_table_info tmp;
1167
1169 if (compat) { 1168 if (compat) {
1170 struct xt_table_info tmp;
1171 ret = compat_table_info(private, &tmp); 1169 ret = compat_table_info(private, &tmp);
1172 xt_compat_flush_offsets(AF_INET6); 1170 xt_compat_flush_offsets(AF_INET6);
1173 private = &tmp; 1171 private = &tmp;
@@ -1199,7 +1197,8 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
1199} 1197}
1200 1198
1201static int 1199static int
1202get_entries(struct net *net, struct ip6t_get_entries __user *uptr, int *len) 1200get_entries(struct net *net, struct ip6t_get_entries __user *uptr,
1201 const int *len)
1203{ 1202{
1204 int ret; 1203 int ret;
1205 struct ip6t_get_entries get; 1204 struct ip6t_get_entries get;
@@ -1247,6 +1246,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
1247 struct xt_table_info *oldinfo; 1246 struct xt_table_info *oldinfo;
1248 struct xt_counters *counters; 1247 struct xt_counters *counters;
1249 const void *loc_cpu_old_entry; 1248 const void *loc_cpu_old_entry;
1249 struct ip6t_entry *iter;
1250 1250
1251 ret = 0; 1251 ret = 0;
1252 counters = vmalloc_node(num_counters * sizeof(struct xt_counters), 1252 counters = vmalloc_node(num_counters * sizeof(struct xt_counters),
@@ -1290,8 +1290,9 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
1290 1290
1291 /* Decrease module usage counts and free resource */ 1291 /* Decrease module usage counts and free resource */
1292 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1292 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
1293 IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry, 1293 xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size)
1294 NULL); 1294 cleanup_entry(iter, net);
1295
1295 xt_free_table_info(oldinfo); 1296 xt_free_table_info(oldinfo);
1296 if (copy_to_user(counters_ptr, counters, 1297 if (copy_to_user(counters_ptr, counters,
1297 sizeof(struct xt_counters) * num_counters) != 0) 1298 sizeof(struct xt_counters) * num_counters) != 0)
@@ -1310,12 +1311,13 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
1310} 1311}
1311 1312
1312static int 1313static int
1313do_replace(struct net *net, void __user *user, unsigned int len) 1314do_replace(struct net *net, const void __user *user, unsigned int len)
1314{ 1315{
1315 int ret; 1316 int ret;
1316 struct ip6t_replace tmp; 1317 struct ip6t_replace tmp;
1317 struct xt_table_info *newinfo; 1318 struct xt_table_info *newinfo;
1318 void *loc_cpu_entry; 1319 void *loc_cpu_entry;
1320 struct ip6t_entry *iter;
1319 1321
1320 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1322 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1321 return -EFAULT; 1323 return -EFAULT;
@@ -1336,9 +1338,7 @@ do_replace(struct net *net, void __user *user, unsigned int len)
1336 goto free_newinfo; 1338 goto free_newinfo;
1337 } 1339 }
1338 1340
1339 ret = translate_table(tmp.name, tmp.valid_hooks, 1341 ret = translate_table(net, newinfo, loc_cpu_entry, &tmp);
1340 newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
1341 tmp.hook_entry, tmp.underflow);
1342 if (ret != 0) 1342 if (ret != 0)
1343 goto free_newinfo; 1343 goto free_newinfo;
1344 1344
@@ -1351,27 +1351,15 @@ do_replace(struct net *net, void __user *user, unsigned int len)
1351 return 0; 1351 return 0;
1352 1352
1353 free_newinfo_untrans: 1353 free_newinfo_untrans:
1354 IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 1354 xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1355 cleanup_entry(iter, net);
1355 free_newinfo: 1356 free_newinfo:
1356 xt_free_table_info(newinfo); 1357 xt_free_table_info(newinfo);
1357 return ret; 1358 return ret;
1358} 1359}
1359 1360
1360/* We're lazy, and add to the first CPU; overflow works its fey magic
1361 * and everything is OK. */
1362static int 1361static int
1363add_counter_to_entry(struct ip6t_entry *e, 1362do_add_counters(struct net *net, const void __user *user, unsigned int len,
1364 const struct xt_counters addme[],
1365 unsigned int *i)
1366{
1367 ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt);
1368
1369 (*i)++;
1370 return 0;
1371}
1372
1373static int
1374do_add_counters(struct net *net, void __user *user, unsigned int len,
1375 int compat) 1363 int compat)
1376{ 1364{
1377 unsigned int i, curcpu; 1365 unsigned int i, curcpu;
@@ -1385,6 +1373,7 @@ do_add_counters(struct net *net, void __user *user, unsigned int len,
1385 const struct xt_table_info *private; 1373 const struct xt_table_info *private;
1386 int ret = 0; 1374 int ret = 0;
1387 const void *loc_cpu_entry; 1375 const void *loc_cpu_entry;
1376 struct ip6t_entry *iter;
1388#ifdef CONFIG_COMPAT 1377#ifdef CONFIG_COMPAT
1389 struct compat_xt_counters_info compat_tmp; 1378 struct compat_xt_counters_info compat_tmp;
1390 1379
@@ -1443,11 +1432,10 @@ do_add_counters(struct net *net, void __user *user, unsigned int len,
1443 curcpu = smp_processor_id(); 1432 curcpu = smp_processor_id();
1444 xt_info_wrlock(curcpu); 1433 xt_info_wrlock(curcpu);
1445 loc_cpu_entry = private->entries[curcpu]; 1434 loc_cpu_entry = private->entries[curcpu];
1446 IP6T_ENTRY_ITERATE(loc_cpu_entry, 1435 xt_entry_foreach(iter, loc_cpu_entry, private->size) {
1447 private->size, 1436 ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt);
1448 add_counter_to_entry, 1437 ++i;
1449 paddc, 1438 }
1450 &i);
1451 xt_info_wrunlock(curcpu); 1439 xt_info_wrunlock(curcpu);
1452 1440
1453 unlock_up_free: 1441 unlock_up_free:
@@ -1476,45 +1464,40 @@ struct compat_ip6t_replace {
1476static int 1464static int
1477compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr, 1465compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
1478 unsigned int *size, struct xt_counters *counters, 1466 unsigned int *size, struct xt_counters *counters,
1479 unsigned int *i) 1467 unsigned int i)
1480{ 1468{
1481 struct ip6t_entry_target *t; 1469 struct ip6t_entry_target *t;
1482 struct compat_ip6t_entry __user *ce; 1470 struct compat_ip6t_entry __user *ce;
1483 u_int16_t target_offset, next_offset; 1471 u_int16_t target_offset, next_offset;
1484 compat_uint_t origsize; 1472 compat_uint_t origsize;
1485 int ret; 1473 const struct xt_entry_match *ematch;
1474 int ret = 0;
1486 1475
1487 ret = -EFAULT;
1488 origsize = *size; 1476 origsize = *size;
1489 ce = (struct compat_ip6t_entry __user *)*dstptr; 1477 ce = (struct compat_ip6t_entry __user *)*dstptr;
1490 if (copy_to_user(ce, e, sizeof(struct ip6t_entry))) 1478 if (copy_to_user(ce, e, sizeof(struct ip6t_entry)) != 0 ||
1491 goto out; 1479 copy_to_user(&ce->counters, &counters[i],
1492 1480 sizeof(counters[i])) != 0)
1493 if (copy_to_user(&ce->counters, &counters[*i], sizeof(counters[*i]))) 1481 return -EFAULT;
1494 goto out;
1495 1482
1496 *dstptr += sizeof(struct compat_ip6t_entry); 1483 *dstptr += sizeof(struct compat_ip6t_entry);
1497 *size -= sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1484 *size -= sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
1498 1485
1499 ret = IP6T_MATCH_ITERATE(e, xt_compat_match_to_user, dstptr, size); 1486 xt_ematch_foreach(ematch, e) {
1487 ret = xt_compat_match_to_user(ematch, dstptr, size);
1488 if (ret != 0)
1489 return ret;
1490 }
1500 target_offset = e->target_offset - (origsize - *size); 1491 target_offset = e->target_offset - (origsize - *size);
1501 if (ret)
1502 goto out;
1503 t = ip6t_get_target(e); 1492 t = ip6t_get_target(e);
1504 ret = xt_compat_target_to_user(t, dstptr, size); 1493 ret = xt_compat_target_to_user(t, dstptr, size);
1505 if (ret) 1494 if (ret)
1506 goto out; 1495 return ret;
1507 ret = -EFAULT;
1508 next_offset = e->next_offset - (origsize - *size); 1496 next_offset = e->next_offset - (origsize - *size);
1509 if (put_user(target_offset, &ce->target_offset)) 1497 if (put_user(target_offset, &ce->target_offset) != 0 ||
1510 goto out; 1498 put_user(next_offset, &ce->next_offset) != 0)
1511 if (put_user(next_offset, &ce->next_offset)) 1499 return -EFAULT;
1512 goto out;
1513
1514 (*i)++;
1515 return 0; 1500 return 0;
1516out:
1517 return ret;
1518} 1501}
1519 1502
1520static int 1503static int
@@ -1522,7 +1505,7 @@ compat_find_calc_match(struct ip6t_entry_match *m,
1522 const char *name, 1505 const char *name,
1523 const struct ip6t_ip6 *ipv6, 1506 const struct ip6t_ip6 *ipv6,
1524 unsigned int hookmask, 1507 unsigned int hookmask,
1525 int *size, unsigned int *i) 1508 int *size)
1526{ 1509{
1527 struct xt_match *match; 1510 struct xt_match *match;
1528 1511
@@ -1536,47 +1519,32 @@ compat_find_calc_match(struct ip6t_entry_match *m,
1536 } 1519 }
1537 m->u.kernel.match = match; 1520 m->u.kernel.match = match;
1538 *size += xt_compat_match_offset(match); 1521 *size += xt_compat_match_offset(match);
1539
1540 (*i)++;
1541 return 0;
1542}
1543
1544static int
1545compat_release_match(struct ip6t_entry_match *m, unsigned int *i)
1546{
1547 if (i && (*i)-- == 0)
1548 return 1;
1549
1550 module_put(m->u.kernel.match->me);
1551 return 0; 1522 return 0;
1552} 1523}
1553 1524
1554static int 1525static void compat_release_entry(struct compat_ip6t_entry *e)
1555compat_release_entry(struct compat_ip6t_entry *e, unsigned int *i)
1556{ 1526{
1557 struct ip6t_entry_target *t; 1527 struct ip6t_entry_target *t;
1558 1528 struct xt_entry_match *ematch;
1559 if (i && (*i)-- == 0)
1560 return 1;
1561 1529
1562 /* Cleanup all matches */ 1530 /* Cleanup all matches */
1563 COMPAT_IP6T_MATCH_ITERATE(e, compat_release_match, NULL); 1531 xt_ematch_foreach(ematch, e)
1532 module_put(ematch->u.kernel.match->me);
1564 t = compat_ip6t_get_target(e); 1533 t = compat_ip6t_get_target(e);
1565 module_put(t->u.kernel.target->me); 1534 module_put(t->u.kernel.target->me);
1566 return 0;
1567} 1535}
1568 1536
1569static int 1537static int
1570check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, 1538check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
1571 struct xt_table_info *newinfo, 1539 struct xt_table_info *newinfo,
1572 unsigned int *size, 1540 unsigned int *size,
1573 unsigned char *base, 1541 const unsigned char *base,
1574 unsigned char *limit, 1542 const unsigned char *limit,
1575 unsigned int *hook_entries, 1543 const unsigned int *hook_entries,
1576 unsigned int *underflows, 1544 const unsigned int *underflows,
1577 unsigned int *i,
1578 const char *name) 1545 const char *name)
1579{ 1546{
1547 struct xt_entry_match *ematch;
1580 struct ip6t_entry_target *t; 1548 struct ip6t_entry_target *t;
1581 struct xt_target *target; 1549 struct xt_target *target;
1582 unsigned int entry_offset; 1550 unsigned int entry_offset;
@@ -1605,10 +1573,13 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
1605 off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1573 off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
1606 entry_offset = (void *)e - (void *)base; 1574 entry_offset = (void *)e - (void *)base;
1607 j = 0; 1575 j = 0;
1608 ret = COMPAT_IP6T_MATCH_ITERATE(e, compat_find_calc_match, name, 1576 xt_ematch_foreach(ematch, e) {
1609 &e->ipv6, e->comefrom, &off, &j); 1577 ret = compat_find_calc_match(ematch, name,
1610 if (ret != 0) 1578 &e->ipv6, e->comefrom, &off);
1611 goto release_matches; 1579 if (ret != 0)
1580 goto release_matches;
1581 ++j;
1582 }
1612 1583
1613 t = compat_ip6t_get_target(e); 1584 t = compat_ip6t_get_target(e);
1614 target = try_then_request_module(xt_find_target(AF_INET6, 1585 target = try_then_request_module(xt_find_target(AF_INET6,
@@ -1640,14 +1611,16 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
1640 /* Clear counters and comefrom */ 1611 /* Clear counters and comefrom */
1641 memset(&e->counters, 0, sizeof(e->counters)); 1612 memset(&e->counters, 0, sizeof(e->counters));
1642 e->comefrom = 0; 1613 e->comefrom = 0;
1643
1644 (*i)++;
1645 return 0; 1614 return 0;
1646 1615
1647out: 1616out:
1648 module_put(t->u.kernel.target->me); 1617 module_put(t->u.kernel.target->me);
1649release_matches: 1618release_matches:
1650 IP6T_MATCH_ITERATE(e, compat_release_match, &j); 1619 xt_ematch_foreach(ematch, e) {
1620 if (j-- == 0)
1621 break;
1622 module_put(ematch->u.kernel.match->me);
1623 }
1651 return ret; 1624 return ret;
1652} 1625}
1653 1626
@@ -1661,6 +1634,7 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
1661 struct ip6t_entry *de; 1634 struct ip6t_entry *de;
1662 unsigned int origsize; 1635 unsigned int origsize;
1663 int ret, h; 1636 int ret, h;
1637 struct xt_entry_match *ematch;
1664 1638
1665 ret = 0; 1639 ret = 0;
1666 origsize = *size; 1640 origsize = *size;
@@ -1671,10 +1645,11 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
1671 *dstptr += sizeof(struct ip6t_entry); 1645 *dstptr += sizeof(struct ip6t_entry);
1672 *size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1646 *size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
1673 1647
1674 ret = COMPAT_IP6T_MATCH_ITERATE(e, xt_compat_match_from_user, 1648 xt_ematch_foreach(ematch, e) {
1675 dstptr, size); 1649 ret = xt_compat_match_from_user(ematch, dstptr, size);
1676 if (ret) 1650 if (ret != 0)
1677 return ret; 1651 return ret;
1652 }
1678 de->target_offset = e->target_offset - (origsize - *size); 1653 de->target_offset = e->target_offset - (origsize - *size);
1679 t = compat_ip6t_get_target(e); 1654 t = compat_ip6t_get_target(e);
1680 target = t->u.kernel.target; 1655 target = t->u.kernel.target;
@@ -1690,36 +1665,44 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
1690 return ret; 1665 return ret;
1691} 1666}
1692 1667
1693static int compat_check_entry(struct ip6t_entry *e, const char *name, 1668static int compat_check_entry(struct ip6t_entry *e, struct net *net,
1694 unsigned int *i) 1669 const char *name)
1695{ 1670{
1696 unsigned int j; 1671 unsigned int j;
1697 int ret; 1672 int ret = 0;
1698 struct xt_mtchk_param mtpar; 1673 struct xt_mtchk_param mtpar;
1674 struct xt_entry_match *ematch;
1699 1675
1700 j = 0; 1676 j = 0;
1677 mtpar.net = net;
1701 mtpar.table = name; 1678 mtpar.table = name;
1702 mtpar.entryinfo = &e->ipv6; 1679 mtpar.entryinfo = &e->ipv6;
1703 mtpar.hook_mask = e->comefrom; 1680 mtpar.hook_mask = e->comefrom;
1704 mtpar.family = NFPROTO_IPV6; 1681 mtpar.family = NFPROTO_IPV6;
1705 ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j); 1682 xt_ematch_foreach(ematch, e) {
1706 if (ret) 1683 ret = check_match(ematch, &mtpar);
1707 goto cleanup_matches; 1684 if (ret != 0)
1685 goto cleanup_matches;
1686 ++j;
1687 }
1708 1688
1709 ret = check_target(e, name); 1689 ret = check_target(e, net, name);
1710 if (ret) 1690 if (ret)
1711 goto cleanup_matches; 1691 goto cleanup_matches;
1712
1713 (*i)++;
1714 return 0; 1692 return 0;
1715 1693
1716 cleanup_matches: 1694 cleanup_matches:
1717 IP6T_MATCH_ITERATE(e, cleanup_match, &j); 1695 xt_ematch_foreach(ematch, e) {
1696 if (j-- == 0)
1697 break;
1698 cleanup_match(ematch, net);
1699 }
1718 return ret; 1700 return ret;
1719} 1701}
1720 1702
1721static int 1703static int
1722translate_compat_table(const char *name, 1704translate_compat_table(struct net *net,
1705 const char *name,
1723 unsigned int valid_hooks, 1706 unsigned int valid_hooks,
1724 struct xt_table_info **pinfo, 1707 struct xt_table_info **pinfo,
1725 void **pentry0, 1708 void **pentry0,
@@ -1731,8 +1714,10 @@ translate_compat_table(const char *name,
1731 unsigned int i, j; 1714 unsigned int i, j;
1732 struct xt_table_info *newinfo, *info; 1715 struct xt_table_info *newinfo, *info;
1733 void *pos, *entry0, *entry1; 1716 void *pos, *entry0, *entry1;
1717 struct compat_ip6t_entry *iter0;
1718 struct ip6t_entry *iter1;
1734 unsigned int size; 1719 unsigned int size;
1735 int ret; 1720 int ret = 0;
1736 1721
1737 info = *pinfo; 1722 info = *pinfo;
1738 entry0 = *pentry0; 1723 entry0 = *pentry0;
@@ -1749,13 +1734,17 @@ translate_compat_table(const char *name,
1749 j = 0; 1734 j = 0;
1750 xt_compat_lock(AF_INET6); 1735 xt_compat_lock(AF_INET6);
1751 /* Walk through entries, checking offsets. */ 1736 /* Walk through entries, checking offsets. */
1752 ret = COMPAT_IP6T_ENTRY_ITERATE(entry0, total_size, 1737 xt_entry_foreach(iter0, entry0, total_size) {
1753 check_compat_entry_size_and_hooks, 1738 ret = check_compat_entry_size_and_hooks(iter0, info, &size,
1754 info, &size, entry0, 1739 entry0,
1755 entry0 + total_size, 1740 entry0 + total_size,
1756 hook_entries, underflows, &j, name); 1741 hook_entries,
1757 if (ret != 0) 1742 underflows,
1758 goto out_unlock; 1743 name);
1744 if (ret != 0)
1745 goto out_unlock;
1746 ++j;
1747 }
1759 1748
1760 ret = -EINVAL; 1749 ret = -EINVAL;
1761 if (j != number) { 1750 if (j != number) {
@@ -1794,9 +1783,12 @@ translate_compat_table(const char *name,
1794 entry1 = newinfo->entries[raw_smp_processor_id()]; 1783 entry1 = newinfo->entries[raw_smp_processor_id()];
1795 pos = entry1; 1784 pos = entry1;
1796 size = total_size; 1785 size = total_size;
1797 ret = COMPAT_IP6T_ENTRY_ITERATE(entry0, total_size, 1786 xt_entry_foreach(iter0, entry0, total_size) {
1798 compat_copy_entry_from_user, 1787 ret = compat_copy_entry_from_user(iter0, &pos, &size,
1799 &pos, &size, name, newinfo, entry1); 1788 name, newinfo, entry1);
1789 if (ret != 0)
1790 break;
1791 }
1800 xt_compat_flush_offsets(AF_INET6); 1792 xt_compat_flush_offsets(AF_INET6);
1801 xt_compat_unlock(AF_INET6); 1793 xt_compat_unlock(AF_INET6);
1802 if (ret) 1794 if (ret)
@@ -1807,13 +1799,32 @@ translate_compat_table(const char *name,
1807 goto free_newinfo; 1799 goto free_newinfo;
1808 1800
1809 i = 0; 1801 i = 0;
1810 ret = IP6T_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, 1802 xt_entry_foreach(iter1, entry1, newinfo->size) {
1811 name, &i); 1803 ret = compat_check_entry(iter1, net, name);
1804 if (ret != 0)
1805 break;
1806 ++i;
1807 }
1812 if (ret) { 1808 if (ret) {
1809 /*
1810 * The first i matches need cleanup_entry (calls ->destroy)
1811 * because they had called ->check already. The other j-i
1812 * entries need only release.
1813 */
1814 int skip = i;
1813 j -= i; 1815 j -= i;
1814 COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, 1816 xt_entry_foreach(iter0, entry0, newinfo->size) {
1815 compat_release_entry, &j); 1817 if (skip-- > 0)
1816 IP6T_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); 1818 continue;
1819 if (j-- == 0)
1820 break;
1821 compat_release_entry(iter0);
1822 }
1823 xt_entry_foreach(iter1, entry1, newinfo->size) {
1824 if (i-- == 0)
1825 break;
1826 cleanup_entry(iter1, net);
1827 }
1817 xt_free_table_info(newinfo); 1828 xt_free_table_info(newinfo);
1818 return ret; 1829 return ret;
1819 } 1830 }
@@ -1831,7 +1842,11 @@ translate_compat_table(const char *name,
1831free_newinfo: 1842free_newinfo:
1832 xt_free_table_info(newinfo); 1843 xt_free_table_info(newinfo);
1833out: 1844out:
1834 COMPAT_IP6T_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); 1845 xt_entry_foreach(iter0, entry0, total_size) {
1846 if (j-- == 0)
1847 break;
1848 compat_release_entry(iter0);
1849 }
1835 return ret; 1850 return ret;
1836out_unlock: 1851out_unlock:
1837 xt_compat_flush_offsets(AF_INET6); 1852 xt_compat_flush_offsets(AF_INET6);
@@ -1846,6 +1861,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
1846 struct compat_ip6t_replace tmp; 1861 struct compat_ip6t_replace tmp;
1847 struct xt_table_info *newinfo; 1862 struct xt_table_info *newinfo;
1848 void *loc_cpu_entry; 1863 void *loc_cpu_entry;
1864 struct ip6t_entry *iter;
1849 1865
1850 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1866 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1851 return -EFAULT; 1867 return -EFAULT;
@@ -1868,7 +1884,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
1868 goto free_newinfo; 1884 goto free_newinfo;
1869 } 1885 }
1870 1886
1871 ret = translate_compat_table(tmp.name, tmp.valid_hooks, 1887 ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
1872 &newinfo, &loc_cpu_entry, tmp.size, 1888 &newinfo, &loc_cpu_entry, tmp.size,
1873 tmp.num_entries, tmp.hook_entry, 1889 tmp.num_entries, tmp.hook_entry,
1874 tmp.underflow); 1890 tmp.underflow);
@@ -1884,7 +1900,8 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
1884 return 0; 1900 return 0;
1885 1901
1886 free_newinfo_untrans: 1902 free_newinfo_untrans:
1887 IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 1903 xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1904 cleanup_entry(iter, net);
1888 free_newinfo: 1905 free_newinfo:
1889 xt_free_table_info(newinfo); 1906 xt_free_table_info(newinfo);
1890 return ret; 1907 return ret;
@@ -1933,6 +1950,7 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
1933 int ret = 0; 1950 int ret = 0;
1934 const void *loc_cpu_entry; 1951 const void *loc_cpu_entry;
1935 unsigned int i = 0; 1952 unsigned int i = 0;
1953 struct ip6t_entry *iter;
1936 1954
1937 counters = alloc_counters(table); 1955 counters = alloc_counters(table);
1938 if (IS_ERR(counters)) 1956 if (IS_ERR(counters))
@@ -1945,9 +1963,12 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
1945 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1963 loc_cpu_entry = private->entries[raw_smp_processor_id()];
1946 pos = userptr; 1964 pos = userptr;
1947 size = total_size; 1965 size = total_size;
1948 ret = IP6T_ENTRY_ITERATE(loc_cpu_entry, total_size, 1966 xt_entry_foreach(iter, loc_cpu_entry, total_size) {
1949 compat_copy_entry_to_user, 1967 ret = compat_copy_entry_to_user(iter, &pos,
1950 &pos, &size, counters, &i); 1968 &size, counters, i++);
1969 if (ret != 0)
1970 break;
1971 }
1951 1972
1952 vfree(counters); 1973 vfree(counters);
1953 return ret; 1974 return ret;
@@ -2121,11 +2142,7 @@ struct xt_table *ip6t_register_table(struct net *net,
2121 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; 2142 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
2122 memcpy(loc_cpu_entry, repl->entries, repl->size); 2143 memcpy(loc_cpu_entry, repl->entries, repl->size);
2123 2144
2124 ret = translate_table(table->name, table->valid_hooks, 2145 ret = translate_table(net, newinfo, loc_cpu_entry, repl);
2125 newinfo, loc_cpu_entry, repl->size,
2126 repl->num_entries,
2127 repl->hook_entry,
2128 repl->underflow);
2129 if (ret != 0) 2146 if (ret != 0)
2130 goto out_free; 2147 goto out_free;
2131 2148
@@ -2142,17 +2159,19 @@ out:
2142 return ERR_PTR(ret); 2159 return ERR_PTR(ret);
2143} 2160}
2144 2161
2145void ip6t_unregister_table(struct xt_table *table) 2162void ip6t_unregister_table(struct net *net, struct xt_table *table)
2146{ 2163{
2147 struct xt_table_info *private; 2164 struct xt_table_info *private;
2148 void *loc_cpu_entry; 2165 void *loc_cpu_entry;
2149 struct module *table_owner = table->me; 2166 struct module *table_owner = table->me;
2167 struct ip6t_entry *iter;
2150 2168
2151 private = xt_unregister_table(table); 2169 private = xt_unregister_table(table);
2152 2170
2153 /* Decrease module usage counts and free resources */ 2171 /* Decrease module usage counts and free resources */
2154 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 2172 loc_cpu_entry = private->entries[raw_smp_processor_id()];
2155 IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); 2173 xt_entry_foreach(iter, loc_cpu_entry, private->size)
2174 cleanup_entry(iter, net);
2156 if (private->number > private->initial_entries) 2175 if (private->number > private->initial_entries)
2157 module_put(table_owner); 2176 module_put(table_owner);
2158 xt_free_table_info(private); 2177 xt_free_table_info(private);
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 8311ca31816a..dd8afbaf00a8 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -169,7 +169,7 @@ send_unreach(struct net *net, struct sk_buff *skb_in, unsigned char code,
169 if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL) 169 if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
170 skb_in->dev = net->loopback_dev; 170 skb_in->dev = net->loopback_dev;
171 171
172 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL); 172 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0);
173} 173}
174 174
175static unsigned int 175static unsigned int
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index ad378efd0eb8..36b72cafc227 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -21,99 +21,26 @@ MODULE_DESCRIPTION("ip6tables filter table");
21 (1 << NF_INET_FORWARD) | \ 21 (1 << NF_INET_FORWARD) | \
22 (1 << NF_INET_LOCAL_OUT)) 22 (1 << NF_INET_LOCAL_OUT))
23 23
24static struct
25{
26 struct ip6t_replace repl;
27 struct ip6t_standard entries[3];
28 struct ip6t_error term;
29} initial_table __net_initdata = {
30 .repl = {
31 .name = "filter",
32 .valid_hooks = FILTER_VALID_HOOKS,
33 .num_entries = 4,
34 .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
35 .hook_entry = {
36 [NF_INET_LOCAL_IN] = 0,
37 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
38 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
39 },
40 .underflow = {
41 [NF_INET_LOCAL_IN] = 0,
42 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
43 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
44 },
45 },
46 .entries = {
47 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
48 IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
49 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
50 },
51 .term = IP6T_ERROR_INIT, /* ERROR */
52};
53
54static const struct xt_table packet_filter = { 24static const struct xt_table packet_filter = {
55 .name = "filter", 25 .name = "filter",
56 .valid_hooks = FILTER_VALID_HOOKS, 26 .valid_hooks = FILTER_VALID_HOOKS,
57 .me = THIS_MODULE, 27 .me = THIS_MODULE,
58 .af = NFPROTO_IPV6, 28 .af = NFPROTO_IPV6,
29 .priority = NF_IP6_PRI_FILTER,
59}; 30};
60 31
61/* The work comes in here from netfilter.c. */ 32/* The work comes in here from netfilter.c. */
62static unsigned int 33static unsigned int
63ip6t_in_hook(unsigned int hook, 34ip6table_filter_hook(unsigned int hook, struct sk_buff *skb,
64 struct sk_buff *skb, 35 const struct net_device *in, const struct net_device *out,
65 const struct net_device *in, 36 int (*okfn)(struct sk_buff *))
66 const struct net_device *out,
67 int (*okfn)(struct sk_buff *))
68{
69 return ip6t_do_table(skb, hook, in, out,
70 dev_net(in)->ipv6.ip6table_filter);
71}
72
73static unsigned int
74ip6t_local_out_hook(unsigned int hook,
75 struct sk_buff *skb,
76 const struct net_device *in,
77 const struct net_device *out,
78 int (*okfn)(struct sk_buff *))
79{ 37{
80#if 0 38 const struct net *net = dev_net((in != NULL) ? in : out);
81 /* root is playing with raw sockets. */
82 if (skb->len < sizeof(struct iphdr) ||
83 ip_hdrlen(skb) < sizeof(struct iphdr)) {
84 if (net_ratelimit())
85 printk("ip6t_hook: happy cracking.\n");
86 return NF_ACCEPT;
87 }
88#endif
89 39
90 return ip6t_do_table(skb, hook, in, out, 40 return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_filter);
91 dev_net(out)->ipv6.ip6table_filter);
92} 41}
93 42
94static struct nf_hook_ops ip6t_ops[] __read_mostly = { 43static struct nf_hook_ops *filter_ops __read_mostly;
95 {
96 .hook = ip6t_in_hook,
97 .owner = THIS_MODULE,
98 .pf = NFPROTO_IPV6,
99 .hooknum = NF_INET_LOCAL_IN,
100 .priority = NF_IP6_PRI_FILTER,
101 },
102 {
103 .hook = ip6t_in_hook,
104 .owner = THIS_MODULE,
105 .pf = NFPROTO_IPV6,
106 .hooknum = NF_INET_FORWARD,
107 .priority = NF_IP6_PRI_FILTER,
108 },
109 {
110 .hook = ip6t_local_out_hook,
111 .owner = THIS_MODULE,
112 .pf = NFPROTO_IPV6,
113 .hooknum = NF_INET_LOCAL_OUT,
114 .priority = NF_IP6_PRI_FILTER,
115 },
116};
117 44
118/* Default to forward because I got too much mail already. */ 45/* Default to forward because I got too much mail already. */
119static int forward = NF_ACCEPT; 46static int forward = NF_ACCEPT;
@@ -121,9 +48,18 @@ module_param(forward, bool, 0000);
121 48
122static int __net_init ip6table_filter_net_init(struct net *net) 49static int __net_init ip6table_filter_net_init(struct net *net)
123{ 50{
124 /* Register table */ 51 struct ip6t_replace *repl;
52
53 repl = ip6t_alloc_initial_table(&packet_filter);
54 if (repl == NULL)
55 return -ENOMEM;
56 /* Entry 1 is the FORWARD hook */
57 ((struct ip6t_standard *)repl->entries)[1].target.verdict =
58 -forward - 1;
59
125 net->ipv6.ip6table_filter = 60 net->ipv6.ip6table_filter =
126 ip6t_register_table(net, &packet_filter, &initial_table.repl); 61 ip6t_register_table(net, &packet_filter, repl);
62 kfree(repl);
127 if (IS_ERR(net->ipv6.ip6table_filter)) 63 if (IS_ERR(net->ipv6.ip6table_filter))
128 return PTR_ERR(net->ipv6.ip6table_filter); 64 return PTR_ERR(net->ipv6.ip6table_filter);
129 return 0; 65 return 0;
@@ -131,7 +67,7 @@ static int __net_init ip6table_filter_net_init(struct net *net)
131 67
132static void __net_exit ip6table_filter_net_exit(struct net *net) 68static void __net_exit ip6table_filter_net_exit(struct net *net)
133{ 69{
134 ip6t_unregister_table(net->ipv6.ip6table_filter); 70 ip6t_unregister_table(net, net->ipv6.ip6table_filter);
135} 71}
136 72
137static struct pernet_operations ip6table_filter_net_ops = { 73static struct pernet_operations ip6table_filter_net_ops = {
@@ -148,17 +84,16 @@ static int __init ip6table_filter_init(void)
148 return -EINVAL; 84 return -EINVAL;
149 } 85 }
150 86
151 /* Entry 1 is the FORWARD hook */
152 initial_table.entries[1].target.verdict = -forward - 1;
153
154 ret = register_pernet_subsys(&ip6table_filter_net_ops); 87 ret = register_pernet_subsys(&ip6table_filter_net_ops);
155 if (ret < 0) 88 if (ret < 0)
156 return ret; 89 return ret;
157 90
158 /* Register hooks */ 91 /* Register hooks */
159 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 92 filter_ops = xt_hook_link(&packet_filter, ip6table_filter_hook);
160 if (ret < 0) 93 if (IS_ERR(filter_ops)) {
94 ret = PTR_ERR(filter_ops);
161 goto cleanup_table; 95 goto cleanup_table;
96 }
162 97
163 return ret; 98 return ret;
164 99
@@ -169,7 +104,7 @@ static int __init ip6table_filter_init(void)
169 104
170static void __exit ip6table_filter_fini(void) 105static void __exit ip6table_filter_fini(void)
171{ 106{
172 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 107 xt_hook_unlink(&packet_filter, filter_ops);
173 unregister_pernet_subsys(&ip6table_filter_net_ops); 108 unregister_pernet_subsys(&ip6table_filter_net_ops);
174} 109}
175 110
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index a929c19d30e3..7844e557c0ec 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -21,80 +21,17 @@ MODULE_DESCRIPTION("ip6tables mangle table");
21 (1 << NF_INET_LOCAL_OUT) | \ 21 (1 << NF_INET_LOCAL_OUT) | \
22 (1 << NF_INET_POST_ROUTING)) 22 (1 << NF_INET_POST_ROUTING))
23 23
24static const struct
25{
26 struct ip6t_replace repl;
27 struct ip6t_standard entries[5];
28 struct ip6t_error term;
29} initial_table __net_initdata = {
30 .repl = {
31 .name = "mangle",
32 .valid_hooks = MANGLE_VALID_HOOKS,
33 .num_entries = 6,
34 .size = sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error),
35 .hook_entry = {
36 [NF_INET_PRE_ROUTING] = 0,
37 [NF_INET_LOCAL_IN] = sizeof(struct ip6t_standard),
38 [NF_INET_FORWARD] = sizeof(struct ip6t_standard) * 2,
39 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3,
40 [NF_INET_POST_ROUTING] = sizeof(struct ip6t_standard) * 4,
41 },
42 .underflow = {
43 [NF_INET_PRE_ROUTING] = 0,
44 [NF_INET_LOCAL_IN] = sizeof(struct ip6t_standard),
45 [NF_INET_FORWARD] = sizeof(struct ip6t_standard) * 2,
46 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3,
47 [NF_INET_POST_ROUTING] = sizeof(struct ip6t_standard) * 4,
48 },
49 },
50 .entries = {
51 IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */
52 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
53 IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
54 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
55 IP6T_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
56 },
57 .term = IP6T_ERROR_INIT, /* ERROR */
58};
59
60static const struct xt_table packet_mangler = { 24static const struct xt_table packet_mangler = {
61 .name = "mangle", 25 .name = "mangle",
62 .valid_hooks = MANGLE_VALID_HOOKS, 26 .valid_hooks = MANGLE_VALID_HOOKS,
63 .me = THIS_MODULE, 27 .me = THIS_MODULE,
64 .af = NFPROTO_IPV6, 28 .af = NFPROTO_IPV6,
29 .priority = NF_IP6_PRI_MANGLE,
65}; 30};
66 31
67/* The work comes in here from netfilter.c. */
68static unsigned int
69ip6t_in_hook(unsigned int hook,
70 struct sk_buff *skb,
71 const struct net_device *in,
72 const struct net_device *out,
73 int (*okfn)(struct sk_buff *))
74{
75 return ip6t_do_table(skb, hook, in, out,
76 dev_net(in)->ipv6.ip6table_mangle);
77}
78
79static unsigned int
80ip6t_post_routing_hook(unsigned int hook,
81 struct sk_buff *skb,
82 const struct net_device *in,
83 const struct net_device *out,
84 int (*okfn)(struct sk_buff *))
85{
86 return ip6t_do_table(skb, hook, in, out,
87 dev_net(out)->ipv6.ip6table_mangle);
88}
89
90static unsigned int 32static unsigned int
91ip6t_local_out_hook(unsigned int hook, 33ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out)
92 struct sk_buff *skb,
93 const struct net_device *in,
94 const struct net_device *out,
95 int (*okfn)(struct sk_buff *))
96{ 34{
97
98 unsigned int ret; 35 unsigned int ret;
99 struct in6_addr saddr, daddr; 36 struct in6_addr saddr, daddr;
100 u_int8_t hop_limit; 37 u_int8_t hop_limit;
@@ -119,7 +56,7 @@ ip6t_local_out_hook(unsigned int hook,
119 /* flowlabel and prio (includes version, which shouldn't change either */ 56 /* flowlabel and prio (includes version, which shouldn't change either */
120 flowlabel = *((u_int32_t *)ipv6_hdr(skb)); 57 flowlabel = *((u_int32_t *)ipv6_hdr(skb));
121 58
122 ret = ip6t_do_table(skb, hook, in, out, 59 ret = ip6t_do_table(skb, NF_INET_LOCAL_OUT, NULL, out,
123 dev_net(out)->ipv6.ip6table_mangle); 60 dev_net(out)->ipv6.ip6table_mangle);
124 61
125 if (ret != NF_DROP && ret != NF_STOLEN && 62 if (ret != NF_DROP && ret != NF_STOLEN &&
@@ -132,49 +69,33 @@ ip6t_local_out_hook(unsigned int hook,
132 return ret; 69 return ret;
133} 70}
134 71
135static struct nf_hook_ops ip6t_ops[] __read_mostly = { 72/* The work comes in here from netfilter.c. */
136 { 73static unsigned int
137 .hook = ip6t_in_hook, 74ip6table_mangle_hook(unsigned int hook, struct sk_buff *skb,
138 .owner = THIS_MODULE, 75 const struct net_device *in, const struct net_device *out,
139 .pf = NFPROTO_IPV6, 76 int (*okfn)(struct sk_buff *))
140 .hooknum = NF_INET_PRE_ROUTING, 77{
141 .priority = NF_IP6_PRI_MANGLE, 78 if (hook == NF_INET_LOCAL_OUT)
142 }, 79 return ip6t_mangle_out(skb, out);
143 { 80 if (hook == NF_INET_POST_ROUTING)
144 .hook = ip6t_in_hook, 81 return ip6t_do_table(skb, hook, in, out,
145 .owner = THIS_MODULE, 82 dev_net(out)->ipv6.ip6table_mangle);
146 .pf = NFPROTO_IPV6, 83 /* INPUT/FORWARD */
147 .hooknum = NF_INET_LOCAL_IN, 84 return ip6t_do_table(skb, hook, in, out,
148 .priority = NF_IP6_PRI_MANGLE, 85 dev_net(in)->ipv6.ip6table_mangle);
149 }, 86}
150 {
151 .hook = ip6t_in_hook,
152 .owner = THIS_MODULE,
153 .pf = NFPROTO_IPV6,
154 .hooknum = NF_INET_FORWARD,
155 .priority = NF_IP6_PRI_MANGLE,
156 },
157 {
158 .hook = ip6t_local_out_hook,
159 .owner = THIS_MODULE,
160 .pf = NFPROTO_IPV6,
161 .hooknum = NF_INET_LOCAL_OUT,
162 .priority = NF_IP6_PRI_MANGLE,
163 },
164 {
165 .hook = ip6t_post_routing_hook,
166 .owner = THIS_MODULE,
167 .pf = NFPROTO_IPV6,
168 .hooknum = NF_INET_POST_ROUTING,
169 .priority = NF_IP6_PRI_MANGLE,
170 },
171};
172 87
88static struct nf_hook_ops *mangle_ops __read_mostly;
173static int __net_init ip6table_mangle_net_init(struct net *net) 89static int __net_init ip6table_mangle_net_init(struct net *net)
174{ 90{
175 /* Register table */ 91 struct ip6t_replace *repl;
92
93 repl = ip6t_alloc_initial_table(&packet_mangler);
94 if (repl == NULL)
95 return -ENOMEM;
176 net->ipv6.ip6table_mangle = 96 net->ipv6.ip6table_mangle =
177 ip6t_register_table(net, &packet_mangler, &initial_table.repl); 97 ip6t_register_table(net, &packet_mangler, repl);
98 kfree(repl);
178 if (IS_ERR(net->ipv6.ip6table_mangle)) 99 if (IS_ERR(net->ipv6.ip6table_mangle))
179 return PTR_ERR(net->ipv6.ip6table_mangle); 100 return PTR_ERR(net->ipv6.ip6table_mangle);
180 return 0; 101 return 0;
@@ -182,7 +103,7 @@ static int __net_init ip6table_mangle_net_init(struct net *net)
182 103
183static void __net_exit ip6table_mangle_net_exit(struct net *net) 104static void __net_exit ip6table_mangle_net_exit(struct net *net)
184{ 105{
185 ip6t_unregister_table(net->ipv6.ip6table_mangle); 106 ip6t_unregister_table(net, net->ipv6.ip6table_mangle);
186} 107}
187 108
188static struct pernet_operations ip6table_mangle_net_ops = { 109static struct pernet_operations ip6table_mangle_net_ops = {
@@ -199,9 +120,11 @@ static int __init ip6table_mangle_init(void)
199 return ret; 120 return ret;
200 121
201 /* Register hooks */ 122 /* Register hooks */
202 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 123 mangle_ops = xt_hook_link(&packet_mangler, ip6table_mangle_hook);
203 if (ret < 0) 124 if (IS_ERR(mangle_ops)) {
125 ret = PTR_ERR(mangle_ops);
204 goto cleanup_table; 126 goto cleanup_table;
127 }
205 128
206 return ret; 129 return ret;
207 130
@@ -212,7 +135,7 @@ static int __init ip6table_mangle_init(void)
212 135
213static void __exit ip6table_mangle_fini(void) 136static void __exit ip6table_mangle_fini(void)
214{ 137{
215 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 138 xt_hook_unlink(&packet_mangler, mangle_ops);
216 unregister_pernet_subsys(&ip6table_mangle_net_ops); 139 unregister_pernet_subsys(&ip6table_mangle_net_ops);
217} 140}
218 141
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index ed1a1180f3b3..aef31a29de9e 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -8,85 +8,37 @@
8 8
9#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT)) 9#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
10 10
11static const struct
12{
13 struct ip6t_replace repl;
14 struct ip6t_standard entries[2];
15 struct ip6t_error term;
16} initial_table __net_initdata = {
17 .repl = {
18 .name = "raw",
19 .valid_hooks = RAW_VALID_HOOKS,
20 .num_entries = 3,
21 .size = sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
22 .hook_entry = {
23 [NF_INET_PRE_ROUTING] = 0,
24 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard)
25 },
26 .underflow = {
27 [NF_INET_PRE_ROUTING] = 0,
28 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard)
29 },
30 },
31 .entries = {
32 IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */
33 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
34 },
35 .term = IP6T_ERROR_INIT, /* ERROR */
36};
37
38static const struct xt_table packet_raw = { 11static const struct xt_table packet_raw = {
39 .name = "raw", 12 .name = "raw",
40 .valid_hooks = RAW_VALID_HOOKS, 13 .valid_hooks = RAW_VALID_HOOKS,
41 .me = THIS_MODULE, 14 .me = THIS_MODULE,
42 .af = NFPROTO_IPV6, 15 .af = NFPROTO_IPV6,
16 .priority = NF_IP6_PRI_FIRST,
43}; 17};
44 18
45/* The work comes in here from netfilter.c. */ 19/* The work comes in here from netfilter.c. */
46static unsigned int 20static unsigned int
47ip6t_pre_routing_hook(unsigned int hook, 21ip6table_raw_hook(unsigned int hook, struct sk_buff *skb,
48 struct sk_buff *skb, 22 const struct net_device *in, const struct net_device *out,
49 const struct net_device *in, 23 int (*okfn)(struct sk_buff *))
50 const struct net_device *out,
51 int (*okfn)(struct sk_buff *))
52{ 24{
53 return ip6t_do_table(skb, hook, in, out, 25 const struct net *net = dev_net((in != NULL) ? in : out);
54 dev_net(in)->ipv6.ip6table_raw);
55}
56 26
57static unsigned int 27 return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_raw);
58ip6t_local_out_hook(unsigned int hook,
59 struct sk_buff *skb,
60 const struct net_device *in,
61 const struct net_device *out,
62 int (*okfn)(struct sk_buff *))
63{
64 return ip6t_do_table(skb, hook, in, out,
65 dev_net(out)->ipv6.ip6table_raw);
66} 28}
67 29
68static struct nf_hook_ops ip6t_ops[] __read_mostly = { 30static struct nf_hook_ops *rawtable_ops __read_mostly;
69 {
70 .hook = ip6t_pre_routing_hook,
71 .pf = NFPROTO_IPV6,
72 .hooknum = NF_INET_PRE_ROUTING,
73 .priority = NF_IP6_PRI_FIRST,
74 .owner = THIS_MODULE,
75 },
76 {
77 .hook = ip6t_local_out_hook,
78 .pf = NFPROTO_IPV6,
79 .hooknum = NF_INET_LOCAL_OUT,
80 .priority = NF_IP6_PRI_FIRST,
81 .owner = THIS_MODULE,
82 },
83};
84 31
85static int __net_init ip6table_raw_net_init(struct net *net) 32static int __net_init ip6table_raw_net_init(struct net *net)
86{ 33{
87 /* Register table */ 34 struct ip6t_replace *repl;
35
36 repl = ip6t_alloc_initial_table(&packet_raw);
37 if (repl == NULL)
38 return -ENOMEM;
88 net->ipv6.ip6table_raw = 39 net->ipv6.ip6table_raw =
89 ip6t_register_table(net, &packet_raw, &initial_table.repl); 40 ip6t_register_table(net, &packet_raw, repl);
41 kfree(repl);
90 if (IS_ERR(net->ipv6.ip6table_raw)) 42 if (IS_ERR(net->ipv6.ip6table_raw))
91 return PTR_ERR(net->ipv6.ip6table_raw); 43 return PTR_ERR(net->ipv6.ip6table_raw);
92 return 0; 44 return 0;
@@ -94,7 +46,7 @@ static int __net_init ip6table_raw_net_init(struct net *net)
94 46
95static void __net_exit ip6table_raw_net_exit(struct net *net) 47static void __net_exit ip6table_raw_net_exit(struct net *net)
96{ 48{
97 ip6t_unregister_table(net->ipv6.ip6table_raw); 49 ip6t_unregister_table(net, net->ipv6.ip6table_raw);
98} 50}
99 51
100static struct pernet_operations ip6table_raw_net_ops = { 52static struct pernet_operations ip6table_raw_net_ops = {
@@ -111,9 +63,11 @@ static int __init ip6table_raw_init(void)
111 return ret; 63 return ret;
112 64
113 /* Register hooks */ 65 /* Register hooks */
114 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 66 rawtable_ops = xt_hook_link(&packet_raw, ip6table_raw_hook);
115 if (ret < 0) 67 if (IS_ERR(rawtable_ops)) {
68 ret = PTR_ERR(rawtable_ops);
116 goto cleanup_table; 69 goto cleanup_table;
70 }
117 71
118 return ret; 72 return ret;
119 73
@@ -124,7 +78,7 @@ static int __init ip6table_raw_init(void)
124 78
125static void __exit ip6table_raw_fini(void) 79static void __exit ip6table_raw_fini(void)
126{ 80{
127 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 81 xt_hook_unlink(&packet_raw, rawtable_ops);
128 unregister_pernet_subsys(&ip6table_raw_net_ops); 82 unregister_pernet_subsys(&ip6table_raw_net_ops);
129} 83}
130 84
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 41b444c60934..0824d865aa9b 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -26,106 +26,37 @@ MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
26 (1 << NF_INET_FORWARD) | \ 26 (1 << NF_INET_FORWARD) | \
27 (1 << NF_INET_LOCAL_OUT) 27 (1 << NF_INET_LOCAL_OUT)
28 28
29static const struct
30{
31 struct ip6t_replace repl;
32 struct ip6t_standard entries[3];
33 struct ip6t_error term;
34} initial_table __net_initdata = {
35 .repl = {
36 .name = "security",
37 .valid_hooks = SECURITY_VALID_HOOKS,
38 .num_entries = 4,
39 .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
40 .hook_entry = {
41 [NF_INET_LOCAL_IN] = 0,
42 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
43 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2,
44 },
45 .underflow = {
46 [NF_INET_LOCAL_IN] = 0,
47 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
48 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2,
49 },
50 },
51 .entries = {
52 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
53 IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
54 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
55 },
56 .term = IP6T_ERROR_INIT, /* ERROR */
57};
58
59static const struct xt_table security_table = { 29static const struct xt_table security_table = {
60 .name = "security", 30 .name = "security",
61 .valid_hooks = SECURITY_VALID_HOOKS, 31 .valid_hooks = SECURITY_VALID_HOOKS,
62 .me = THIS_MODULE, 32 .me = THIS_MODULE,
63 .af = NFPROTO_IPV6, 33 .af = NFPROTO_IPV6,
34 .priority = NF_IP6_PRI_SECURITY,
64}; 35};
65 36
66static unsigned int 37static unsigned int
67ip6t_local_in_hook(unsigned int hook, 38ip6table_security_hook(unsigned int hook, struct sk_buff *skb,
68 struct sk_buff *skb, 39 const struct net_device *in,
69 const struct net_device *in, 40 const struct net_device *out,
70 const struct net_device *out, 41 int (*okfn)(struct sk_buff *))
71 int (*okfn)(struct sk_buff *))
72{
73 return ip6t_do_table(skb, hook, in, out,
74 dev_net(in)->ipv6.ip6table_security);
75}
76
77static unsigned int
78ip6t_forward_hook(unsigned int hook,
79 struct sk_buff *skb,
80 const struct net_device *in,
81 const struct net_device *out,
82 int (*okfn)(struct sk_buff *))
83{ 42{
84 return ip6t_do_table(skb, hook, in, out, 43 const struct net *net = dev_net((in != NULL) ? in : out);
85 dev_net(in)->ipv6.ip6table_security);
86}
87 44
88static unsigned int 45 return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_security);
89ip6t_local_out_hook(unsigned int hook,
90 struct sk_buff *skb,
91 const struct net_device *in,
92 const struct net_device *out,
93 int (*okfn)(struct sk_buff *))
94{
95 /* TBD: handle short packets via raw socket */
96 return ip6t_do_table(skb, hook, in, out,
97 dev_net(out)->ipv6.ip6table_security);
98} 46}
99 47
100static struct nf_hook_ops ip6t_ops[] __read_mostly = { 48static struct nf_hook_ops *sectbl_ops __read_mostly;
101 {
102 .hook = ip6t_local_in_hook,
103 .owner = THIS_MODULE,
104 .pf = NFPROTO_IPV6,
105 .hooknum = NF_INET_LOCAL_IN,
106 .priority = NF_IP6_PRI_SECURITY,
107 },
108 {
109 .hook = ip6t_forward_hook,
110 .owner = THIS_MODULE,
111 .pf = NFPROTO_IPV6,
112 .hooknum = NF_INET_FORWARD,
113 .priority = NF_IP6_PRI_SECURITY,
114 },
115 {
116 .hook = ip6t_local_out_hook,
117 .owner = THIS_MODULE,
118 .pf = NFPROTO_IPV6,
119 .hooknum = NF_INET_LOCAL_OUT,
120 .priority = NF_IP6_PRI_SECURITY,
121 },
122};
123 49
124static int __net_init ip6table_security_net_init(struct net *net) 50static int __net_init ip6table_security_net_init(struct net *net)
125{ 51{
126 net->ipv6.ip6table_security = 52 struct ip6t_replace *repl;
127 ip6t_register_table(net, &security_table, &initial_table.repl);
128 53
54 repl = ip6t_alloc_initial_table(&security_table);
55 if (repl == NULL)
56 return -ENOMEM;
57 net->ipv6.ip6table_security =
58 ip6t_register_table(net, &security_table, repl);
59 kfree(repl);
129 if (IS_ERR(net->ipv6.ip6table_security)) 60 if (IS_ERR(net->ipv6.ip6table_security))
130 return PTR_ERR(net->ipv6.ip6table_security); 61 return PTR_ERR(net->ipv6.ip6table_security);
131 62
@@ -134,7 +65,7 @@ static int __net_init ip6table_security_net_init(struct net *net)
134 65
135static void __net_exit ip6table_security_net_exit(struct net *net) 66static void __net_exit ip6table_security_net_exit(struct net *net)
136{ 67{
137 ip6t_unregister_table(net->ipv6.ip6table_security); 68 ip6t_unregister_table(net, net->ipv6.ip6table_security);
138} 69}
139 70
140static struct pernet_operations ip6table_security_net_ops = { 71static struct pernet_operations ip6table_security_net_ops = {
@@ -150,9 +81,11 @@ static int __init ip6table_security_init(void)
150 if (ret < 0) 81 if (ret < 0)
151 return ret; 82 return ret;
152 83
153 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 84 sectbl_ops = xt_hook_link(&security_table, ip6table_security_hook);
154 if (ret < 0) 85 if (IS_ERR(sectbl_ops)) {
86 ret = PTR_ERR(sectbl_ops);
155 goto cleanup_table; 87 goto cleanup_table;
88 }
156 89
157 return ret; 90 return ret;
158 91
@@ -163,7 +96,7 @@ cleanup_table:
163 96
164static void __exit ip6table_security_fini(void) 97static void __exit ip6table_security_fini(void)
165{ 98{
166 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 99 xt_hook_unlink(&security_table, sectbl_ops);
167 unregister_pernet_subsys(&ip6table_security_net_ops); 100 unregister_pernet_subsys(&ip6table_security_net_ops);
168} 101}
169 102
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 0956ebabbff2..996c3f41fecd 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -27,6 +27,7 @@
27#include <net/netfilter/nf_conntrack_l4proto.h> 27#include <net/netfilter/nf_conntrack_l4proto.h>
28#include <net/netfilter/nf_conntrack_l3proto.h> 28#include <net/netfilter/nf_conntrack_l3proto.h>
29#include <net/netfilter/nf_conntrack_core.h> 29#include <net/netfilter/nf_conntrack_core.h>
30#include <net/netfilter/nf_conntrack_zones.h>
30#include <net/netfilter/ipv6/nf_conntrack_ipv6.h> 31#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
31#include <net/netfilter/nf_log.h> 32#include <net/netfilter/nf_log.h>
32 33
@@ -191,15 +192,20 @@ out:
191static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, 192static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
192 struct sk_buff *skb) 193 struct sk_buff *skb)
193{ 194{
195 u16 zone = NF_CT_DEFAULT_ZONE;
196
197 if (skb->nfct)
198 zone = nf_ct_zone((struct nf_conn *)skb->nfct);
199
194#ifdef CONFIG_BRIDGE_NETFILTER 200#ifdef CONFIG_BRIDGE_NETFILTER
195 if (skb->nf_bridge && 201 if (skb->nf_bridge &&
196 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) 202 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
197 return IP6_DEFRAG_CONNTRACK_BRIDGE_IN; 203 return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
198#endif 204#endif
199 if (hooknum == NF_INET_PRE_ROUTING) 205 if (hooknum == NF_INET_PRE_ROUTING)
200 return IP6_DEFRAG_CONNTRACK_IN; 206 return IP6_DEFRAG_CONNTRACK_IN + zone;
201 else 207 else
202 return IP6_DEFRAG_CONNTRACK_OUT; 208 return IP6_DEFRAG_CONNTRACK_OUT + zone;
203 209
204} 210}
205 211
@@ -212,7 +218,7 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
212 struct sk_buff *reasm; 218 struct sk_buff *reasm;
213 219
214 /* Previously seen (loopback)? */ 220 /* Previously seen (loopback)? */
215 if (skb->nfct) 221 if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
216 return NF_ACCEPT; 222 return NF_ACCEPT;
217 223
218 reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb)); 224 reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index c7b8bd1d7984..9be81776415e 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -23,6 +23,7 @@
23#include <net/netfilter/nf_conntrack_tuple.h> 23#include <net/netfilter/nf_conntrack_tuple.h>
24#include <net/netfilter/nf_conntrack_l4proto.h> 24#include <net/netfilter/nf_conntrack_l4proto.h>
25#include <net/netfilter/nf_conntrack_core.h> 25#include <net/netfilter/nf_conntrack_core.h>
26#include <net/netfilter/nf_conntrack_zones.h>
26#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> 27#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
27#include <net/netfilter/nf_log.h> 28#include <net/netfilter/nf_log.h>
28 29
@@ -128,7 +129,7 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
128} 129}
129 130
130static int 131static int
131icmpv6_error_message(struct net *net, 132icmpv6_error_message(struct net *net, struct nf_conn *tmpl,
132 struct sk_buff *skb, 133 struct sk_buff *skb,
133 unsigned int icmp6off, 134 unsigned int icmp6off,
134 enum ip_conntrack_info *ctinfo, 135 enum ip_conntrack_info *ctinfo,
@@ -137,6 +138,7 @@ icmpv6_error_message(struct net *net,
137 struct nf_conntrack_tuple intuple, origtuple; 138 struct nf_conntrack_tuple intuple, origtuple;
138 const struct nf_conntrack_tuple_hash *h; 139 const struct nf_conntrack_tuple_hash *h;
139 const struct nf_conntrack_l4proto *inproto; 140 const struct nf_conntrack_l4proto *inproto;
141 u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE;
140 142
141 NF_CT_ASSERT(skb->nfct == NULL); 143 NF_CT_ASSERT(skb->nfct == NULL);
142 144
@@ -163,7 +165,7 @@ icmpv6_error_message(struct net *net,
163 165
164 *ctinfo = IP_CT_RELATED; 166 *ctinfo = IP_CT_RELATED;
165 167
166 h = nf_conntrack_find_get(net, &intuple); 168 h = nf_conntrack_find_get(net, zone, &intuple);
167 if (!h) { 169 if (!h) {
168 pr_debug("icmpv6_error: no match\n"); 170 pr_debug("icmpv6_error: no match\n");
169 return -NF_ACCEPT; 171 return -NF_ACCEPT;
@@ -179,7 +181,8 @@ icmpv6_error_message(struct net *net,
179} 181}
180 182
181static int 183static int
182icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff, 184icmpv6_error(struct net *net, struct nf_conn *tmpl,
185 struct sk_buff *skb, unsigned int dataoff,
183 enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum) 186 enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
184{ 187{
185 const struct icmp6hdr *icmp6h; 188 const struct icmp6hdr *icmp6h;
@@ -215,7 +218,7 @@ icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
215 if (icmp6h->icmp6_type >= 128) 218 if (icmp6h->icmp6_type >= 128)
216 return NF_ACCEPT; 219 return NF_ACCEPT;
217 220
218 return icmpv6_error_message(net, skb, dataoff, ctinfo, hooknum); 221 return icmpv6_error_message(net, tmpl, skb, dataoff, ctinfo, hooknum);
219} 222}
220 223
221#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 224#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 624a54832a7c..f1171b744650 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -45,9 +45,6 @@
45#include <linux/kernel.h> 45#include <linux/kernel.h>
46#include <linux/module.h> 46#include <linux/module.h>
47 47
48#define NF_CT_FRAG6_HIGH_THRESH 262144 /* == 256*1024 */
49#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */
50#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
51 48
52struct nf_ct_frag6_skb_cb 49struct nf_ct_frag6_skb_cb
53{ 50{
@@ -472,7 +469,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
472 469
473 /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */ 470 /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */
474 fp = skb_shinfo(head)->frag_list; 471 fp = skb_shinfo(head)->frag_list;
475 if (NFCT_FRAG6_CB(fp)->orig == NULL) 472 if (fp && NFCT_FRAG6_CB(fp)->orig == NULL)
476 /* at above code, head skb is divided into two skbs. */ 473 /* at above code, head skb is divided into two skbs. */
477 fp = fp->next; 474 fp = fp->next;
478 475
@@ -598,12 +595,6 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
598 hdr = ipv6_hdr(clone); 595 hdr = ipv6_hdr(clone);
599 fhdr = (struct frag_hdr *)skb_transport_header(clone); 596 fhdr = (struct frag_hdr *)skb_transport_header(clone);
600 597
601 if (!(fhdr->frag_off & htons(0xFFF9))) {
602 pr_debug("Invalid fragment offset\n");
603 /* It is not a fragmented frame */
604 goto ret_orig;
605 }
606
607 if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh) 598 if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
608 nf_ct_frag6_evictor(); 599 nf_ct_frag6_evictor();
609 600
@@ -670,8 +661,8 @@ int nf_ct_frag6_init(void)
670 nf_frags.frag_expire = nf_ct_frag6_expire; 661 nf_frags.frag_expire = nf_ct_frag6_expire;
671 nf_frags.secret_interval = 10 * 60 * HZ; 662 nf_frags.secret_interval = 10 * 60 * HZ;
672 nf_init_frags.timeout = IPV6_FRAG_TIMEOUT; 663 nf_init_frags.timeout = IPV6_FRAG_TIMEOUT;
673 nf_init_frags.high_thresh = 256 * 1024; 664 nf_init_frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
674 nf_init_frags.low_thresh = 192 * 1024; 665 nf_init_frags.low_thresh = IPV6_FRAG_LOW_THRESH;
675 inet_frags_init_net(&nf_init_frags); 666 inet_frags_init_net(&nf_init_frags);
676 inet_frags_init(&nf_frags); 667 inet_frags_init(&nf_frags);
677 668
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index c9605c3ad91f..58344c0fbd13 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -59,7 +59,7 @@ static const struct file_operations sockstat6_seq_fops = {
59 .release = single_release_net, 59 .release = single_release_net,
60}; 60};
61 61
62static struct snmp_mib snmp6_ipstats_list[] = { 62static const struct snmp_mib snmp6_ipstats_list[] = {
63/* ipv6 mib according to RFC 2465 */ 63/* ipv6 mib according to RFC 2465 */
64 SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INPKTS), 64 SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INPKTS),
65 SNMP_MIB_ITEM("Ip6InHdrErrors", IPSTATS_MIB_INHDRERRORS), 65 SNMP_MIB_ITEM("Ip6InHdrErrors", IPSTATS_MIB_INHDRERRORS),
@@ -92,7 +92,7 @@ static struct snmp_mib snmp6_ipstats_list[] = {
92 SNMP_MIB_SENTINEL 92 SNMP_MIB_SENTINEL
93}; 93};
94 94
95static struct snmp_mib snmp6_icmp6_list[] = { 95static const struct snmp_mib snmp6_icmp6_list[] = {
96/* icmpv6 mib according to RFC 2466 */ 96/* icmpv6 mib according to RFC 2466 */
97 SNMP_MIB_ITEM("Icmp6InMsgs", ICMP6_MIB_INMSGS), 97 SNMP_MIB_ITEM("Icmp6InMsgs", ICMP6_MIB_INMSGS),
98 SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS), 98 SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS),
@@ -120,7 +120,7 @@ static const char *const icmp6type2name[256] = {
120}; 120};
121 121
122 122
123static struct snmp_mib snmp6_udp6_list[] = { 123static const struct snmp_mib snmp6_udp6_list[] = {
124 SNMP_MIB_ITEM("Udp6InDatagrams", UDP_MIB_INDATAGRAMS), 124 SNMP_MIB_ITEM("Udp6InDatagrams", UDP_MIB_INDATAGRAMS),
125 SNMP_MIB_ITEM("Udp6NoPorts", UDP_MIB_NOPORTS), 125 SNMP_MIB_ITEM("Udp6NoPorts", UDP_MIB_NOPORTS),
126 SNMP_MIB_ITEM("Udp6InErrors", UDP_MIB_INERRORS), 126 SNMP_MIB_ITEM("Udp6InErrors", UDP_MIB_INERRORS),
@@ -128,7 +128,7 @@ static struct snmp_mib snmp6_udp6_list[] = {
128 SNMP_MIB_SENTINEL 128 SNMP_MIB_SENTINEL
129}; 129};
130 130
131static struct snmp_mib snmp6_udplite6_list[] = { 131static const struct snmp_mib snmp6_udplite6_list[] = {
132 SNMP_MIB_ITEM("UdpLite6InDatagrams", UDP_MIB_INDATAGRAMS), 132 SNMP_MIB_ITEM("UdpLite6InDatagrams", UDP_MIB_INDATAGRAMS),
133 SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS), 133 SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS),
134 SNMP_MIB_ITEM("UdpLite6InErrors", UDP_MIB_INERRORS), 134 SNMP_MIB_ITEM("UdpLite6InErrors", UDP_MIB_INERRORS),
@@ -136,7 +136,7 @@ static struct snmp_mib snmp6_udplite6_list[] = {
136 SNMP_MIB_SENTINEL 136 SNMP_MIB_SENTINEL
137}; 137};
138 138
139static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib) 139static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void __percpu **mib)
140{ 140{
141 char name[32]; 141 char name[32];
142 int i; 142 int i;
@@ -170,8 +170,8 @@ static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib)
170 return; 170 return;
171} 171}
172 172
173static inline void 173static void snmp6_seq_show_item(struct seq_file *seq, void __percpu **mib,
174snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist) 174 const struct snmp_mib *itemlist)
175{ 175{
176 int i; 176 int i;
177 for (i=0; itemlist[i].name; i++) 177 for (i=0; itemlist[i].name; i++)
@@ -183,14 +183,15 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
183{ 183{
184 struct net *net = (struct net *)seq->private; 184 struct net *net = (struct net *)seq->private;
185 185
186 snmp6_seq_show_item(seq, (void **)net->mib.ipv6_statistics, 186 snmp6_seq_show_item(seq, (void __percpu **)net->mib.ipv6_statistics,
187 snmp6_ipstats_list); 187 snmp6_ipstats_list);
188 snmp6_seq_show_item(seq, (void **)net->mib.icmpv6_statistics, 188 snmp6_seq_show_item(seq, (void __percpu **)net->mib.icmpv6_statistics,
189 snmp6_icmp6_list); 189 snmp6_icmp6_list);
190 snmp6_seq_show_icmpv6msg(seq, (void **)net->mib.icmpv6msg_statistics); 190 snmp6_seq_show_icmpv6msg(seq,
191 snmp6_seq_show_item(seq, (void **)net->mib.udp_stats_in6, 191 (void __percpu **)net->mib.icmpv6msg_statistics);
192 snmp6_seq_show_item(seq, (void __percpu **)net->mib.udp_stats_in6,
192 snmp6_udp6_list); 193 snmp6_udp6_list);
193 snmp6_seq_show_item(seq, (void **)net->mib.udplite_stats_in6, 194 snmp6_seq_show_item(seq, (void __percpu **)net->mib.udplite_stats_in6,
194 snmp6_udplite6_list); 195 snmp6_udplite6_list);
195 return 0; 196 return 0;
196} 197}
@@ -213,9 +214,11 @@ static int snmp6_dev_seq_show(struct seq_file *seq, void *v)
213 struct inet6_dev *idev = (struct inet6_dev *)seq->private; 214 struct inet6_dev *idev = (struct inet6_dev *)seq->private;
214 215
215 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex); 216 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
216 snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list); 217 snmp6_seq_show_item(seq, (void __percpu **)idev->stats.ipv6,
217 snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); 218 snmp6_ipstats_list);
218 snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg); 219 snmp6_seq_show_item(seq, (void __percpu **)idev->stats.icmpv6,
220 snmp6_icmp6_list);
221 snmp6_seq_show_icmpv6msg(seq, (void __percpu **)idev->stats.icmpv6msg);
219 return 0; 222 return 0;
220} 223}
221 224
@@ -259,7 +262,7 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
259 struct net *net = dev_net(idev->dev); 262 struct net *net = dev_net(idev->dev);
260 if (!net->mib.proc_net_devsnmp6) 263 if (!net->mib.proc_net_devsnmp6)
261 return -ENOENT; 264 return -ENOENT;
262 if (!idev || !idev->stats.proc_dir_entry) 265 if (!idev->stats.proc_dir_entry)
263 return -EINVAL; 266 return -EINVAL;
264 remove_proc_entry(idev->stats.proc_dir_entry->name, 267 remove_proc_entry(idev->stats.proc_dir_entry->name,
265 net->mib.proc_net_devsnmp6); 268 net->mib.proc_net_devsnmp6);
@@ -267,7 +270,7 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
267 return 0; 270 return 0;
268} 271}
269 272
270static int ipv6_proc_init_net(struct net *net) 273static int __net_init ipv6_proc_init_net(struct net *net)
271{ 274{
272 if (!proc_net_fops_create(net, "sockstat6", S_IRUGO, 275 if (!proc_net_fops_create(net, "sockstat6", S_IRUGO,
273 &sockstat6_seq_fops)) 276 &sockstat6_seq_fops))
@@ -288,7 +291,7 @@ proc_dev_snmp6_fail:
288 return -ENOMEM; 291 return -ENOMEM;
289} 292}
290 293
291static void ipv6_proc_exit_net(struct net *net) 294static void __net_exit ipv6_proc_exit_net(struct net *net)
292{ 295{
293 proc_net_remove(net, "sockstat6"); 296 proc_net_remove(net, "sockstat6");
294 proc_net_remove(net, "dev_snmp6"); 297 proc_net_remove(net, "dev_snmp6");
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 926ce8eeffaf..ed31c37c6e39 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1275,7 +1275,7 @@ static const struct file_operations raw6_seq_fops = {
1275 .release = seq_release_net, 1275 .release = seq_release_net,
1276}; 1276};
1277 1277
1278static int raw6_init_net(struct net *net) 1278static int __net_init raw6_init_net(struct net *net)
1279{ 1279{
1280 if (!proc_net_fops_create(net, "raw6", S_IRUGO, &raw6_seq_fops)) 1280 if (!proc_net_fops_create(net, "raw6", S_IRUGO, &raw6_seq_fops))
1281 return -ENOMEM; 1281 return -ENOMEM;
@@ -1283,7 +1283,7 @@ static int raw6_init_net(struct net *net)
1283 return 0; 1283 return 0;
1284} 1284}
1285 1285
1286static void raw6_exit_net(struct net *net) 1286static void __net_exit raw6_exit_net(struct net *net)
1287{ 1287{
1288 proc_net_remove(net, "raw6"); 1288 proc_net_remove(net, "raw6");
1289} 1289}
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 2cddea3bd6be..a555156e9779 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -228,7 +228,7 @@ static void ip6_frag_expire(unsigned long data)
228 pointer directly, device might already disappeared. 228 pointer directly, device might already disappeared.
229 */ 229 */
230 fq->q.fragments->dev = dev; 230 fq->q.fragments->dev = dev;
231 icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev); 231 icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0);
232out_rcu_unlock: 232out_rcu_unlock:
233 rcu_read_unlock(); 233 rcu_read_unlock();
234out: 234out:
@@ -237,8 +237,7 @@ out:
237} 237}
238 238
239static __inline__ struct frag_queue * 239static __inline__ struct frag_queue *
240fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst, 240fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst)
241 struct inet6_dev *idev)
242{ 241{
243 struct inet_frag_queue *q; 242 struct inet_frag_queue *q;
244 struct ip6_create_arg arg; 243 struct ip6_create_arg arg;
@@ -254,13 +253,9 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
254 253
255 q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); 254 q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
256 if (q == NULL) 255 if (q == NULL)
257 goto oom; 256 return NULL;
258 257
259 return container_of(q, struct frag_queue, q); 258 return container_of(q, struct frag_queue, q);
260
261oom:
262 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS);
263 return NULL;
264} 259}
265 260
266static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, 261static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
@@ -606,8 +601,8 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
606 if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh) 601 if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
607 ip6_evictor(net, ip6_dst_idev(skb_dst(skb))); 602 ip6_evictor(net, ip6_dst_idev(skb_dst(skb)));
608 603
609 if ((fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr, 604 fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr);
610 ip6_dst_idev(skb_dst(skb)))) != NULL) { 605 if (fq != NULL) {
611 int ret; 606 int ret;
612 607
613 spin_lock(&fq->q.lock); 608 spin_lock(&fq->q.lock);
@@ -672,7 +667,7 @@ static struct ctl_table ip6_frags_ctl_table[] = {
672 { } 667 { }
673}; 668};
674 669
675static int ip6_frags_ns_sysctl_register(struct net *net) 670static int __net_init ip6_frags_ns_sysctl_register(struct net *net)
676{ 671{
677 struct ctl_table *table; 672 struct ctl_table *table;
678 struct ctl_table_header *hdr; 673 struct ctl_table_header *hdr;
@@ -702,7 +697,7 @@ err_alloc:
702 return -ENOMEM; 697 return -ENOMEM;
703} 698}
704 699
705static void ip6_frags_ns_sysctl_unregister(struct net *net) 700static void __net_exit ip6_frags_ns_sysctl_unregister(struct net *net)
706{ 701{
707 struct ctl_table *table; 702 struct ctl_table *table;
708 703
@@ -745,10 +740,10 @@ static inline void ip6_frags_sysctl_unregister(void)
745} 740}
746#endif 741#endif
747 742
748static int ipv6_frags_init_net(struct net *net) 743static int __net_init ipv6_frags_init_net(struct net *net)
749{ 744{
750 net->ipv6.frags.high_thresh = 256 * 1024; 745 net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
751 net->ipv6.frags.low_thresh = 192 * 1024; 746 net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
752 net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT; 747 net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
753 748
754 inet_frags_init_net(&net->ipv6.frags); 749 inet_frags_init_net(&net->ipv6.frags);
@@ -756,7 +751,7 @@ static int ipv6_frags_init_net(struct net *net)
756 return ip6_frags_ns_sysctl_register(net); 751 return ip6_frags_ns_sysctl_register(net);
757} 752}
758 753
759static void ipv6_frags_exit_net(struct net *net) 754static void __net_exit ipv6_frags_exit_net(struct net *net)
760{ 755{
761 ip6_frags_ns_sysctl_unregister(net); 756 ip6_frags_ns_sysctl_unregister(net);
762 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags); 757 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c2bd74c5f8d9..b08879e97f22 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -909,7 +909,7 @@ static void ip6_link_failure(struct sk_buff *skb)
909{ 909{
910 struct rt6_info *rt; 910 struct rt6_info *rt;
911 911
912 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, skb->dev); 912 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
913 913
914 rt = (struct rt6_info *) skb_dst(skb); 914 rt = (struct rt6_info *) skb_dst(skb);
915 if (rt) { 915 if (rt) {
@@ -1873,7 +1873,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes)
1873 switch (ipstats_mib_noroutes) { 1873 switch (ipstats_mib_noroutes) {
1874 case IPSTATS_MIB_INNOROUTES: 1874 case IPSTATS_MIB_INNOROUTES:
1875 type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); 1875 type = ipv6_addr_type(&ipv6_hdr(skb)->daddr);
1876 if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) { 1876 if (type == IPV6_ADDR_ANY) {
1877 IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), 1877 IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst),
1878 IPSTATS_MIB_INADDRERRORS); 1878 IPSTATS_MIB_INADDRERRORS);
1879 break; 1879 break;
@@ -1884,7 +1884,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes)
1884 ipstats_mib_noroutes); 1884 ipstats_mib_noroutes);
1885 break; 1885 break;
1886 } 1886 }
1887 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); 1887 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0);
1888 kfree_skb(skb); 1888 kfree_skb(skb);
1889 return 0; 1889 return 0;
1890} 1890}
@@ -2612,7 +2612,7 @@ ctl_table ipv6_route_table_template[] = {
2612 { } 2612 { }
2613}; 2613};
2614 2614
2615struct ctl_table *ipv6_route_sysctl_init(struct net *net) 2615struct ctl_table * __net_init ipv6_route_sysctl_init(struct net *net)
2616{ 2616{
2617 struct ctl_table *table; 2617 struct ctl_table *table;
2618 2618
@@ -2637,7 +2637,7 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net)
2637} 2637}
2638#endif 2638#endif
2639 2639
2640static int ip6_route_net_init(struct net *net) 2640static int __net_init ip6_route_net_init(struct net *net)
2641{ 2641{
2642 int ret = -ENOMEM; 2642 int ret = -ENOMEM;
2643 2643
@@ -2702,7 +2702,7 @@ out_ip6_dst_ops:
2702 goto out; 2702 goto out;
2703} 2703}
2704 2704
2705static void ip6_route_net_exit(struct net *net) 2705static void __net_exit ip6_route_net_exit(struct net *net)
2706{ 2706{
2707#ifdef CONFIG_PROC_FS 2707#ifdef CONFIG_PROC_FS
2708 proc_net_remove(net, "ipv6_route"); 2708 proc_net_remove(net, "ipv6_route");
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 976e68244b99..b1eea811be48 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -62,7 +62,6 @@
62#define HASH_SIZE 16 62#define HASH_SIZE 16
63#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) 63#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
64 64
65static void ipip6_fb_tunnel_init(struct net_device *dev);
66static void ipip6_tunnel_init(struct net_device *dev); 65static void ipip6_tunnel_init(struct net_device *dev);
67static void ipip6_tunnel_setup(struct net_device *dev); 66static void ipip6_tunnel_setup(struct net_device *dev);
68 67
@@ -364,7 +363,6 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
364 goto out; 363 goto out;
365 } 364 }
366 365
367 INIT_RCU_HEAD(&p->rcu_head);
368 p->next = t->prl; 366 p->next = t->prl;
369 p->addr = a->addr; 367 p->addr = a->addr;
370 p->flags = a->flags; 368 p->flags = a->flags;
@@ -745,7 +743,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
745 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); 743 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
746 744
747 if (skb->len > mtu) { 745 if (skb->len > mtu) {
748 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); 746 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
749 ip_rt_put(rt); 747 ip_rt_put(rt);
750 goto tx_error; 748 goto tx_error;
751 } 749 }
@@ -1120,7 +1118,7 @@ static void ipip6_tunnel_init(struct net_device *dev)
1120 ipip6_tunnel_bind_dev(dev); 1118 ipip6_tunnel_bind_dev(dev);
1121} 1119}
1122 1120
1123static void ipip6_fb_tunnel_init(struct net_device *dev) 1121static void __net_init ipip6_fb_tunnel_init(struct net_device *dev)
1124{ 1122{
1125 struct ip_tunnel *tunnel = netdev_priv(dev); 1123 struct ip_tunnel *tunnel = netdev_priv(dev);
1126 struct iphdr *iph = &tunnel->parms.iph; 1124 struct iphdr *iph = &tunnel->parms.iph;
@@ -1145,7 +1143,7 @@ static struct xfrm_tunnel sit_handler = {
1145 .priority = 1, 1143 .priority = 1,
1146}; 1144};
1147 1145
1148static void sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head) 1146static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head)
1149{ 1147{
1150 int prio; 1148 int prio;
1151 1149
@@ -1162,7 +1160,7 @@ static void sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head)
1162 } 1160 }
1163} 1161}
1164 1162
1165static int sit_init_net(struct net *net) 1163static int __net_init sit_init_net(struct net *net)
1166{ 1164{
1167 struct sit_net *sitn = net_generic(net, sit_net_id); 1165 struct sit_net *sitn = net_generic(net, sit_net_id);
1168 int err; 1166 int err;
@@ -1195,7 +1193,7 @@ err_alloc_dev:
1195 return err; 1193 return err;
1196} 1194}
1197 1195
1198static void sit_exit_net(struct net *net) 1196static void __net_exit sit_exit_net(struct net *net)
1199{ 1197{
1200 struct sit_net *sitn = net_generic(net, sit_net_id); 1198 struct sit_net *sitn = net_generic(net, sit_net_id);
1201 LIST_HEAD(list); 1199 LIST_HEAD(list);
@@ -1228,15 +1226,14 @@ static int __init sit_init(void)
1228 1226
1229 printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); 1227 printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n");
1230 1228
1231 if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) {
1232 printk(KERN_INFO "sit init: Can't add protocol\n");
1233 return -EAGAIN;
1234 }
1235
1236 err = register_pernet_device(&sit_net_ops); 1229 err = register_pernet_device(&sit_net_ops);
1237 if (err < 0) 1230 if (err < 0)
1238 xfrm4_tunnel_deregister(&sit_handler, AF_INET6); 1231 return err;
1239 1232 err = xfrm4_tunnel_register(&sit_handler, AF_INET6);
1233 if (err < 0) {
1234 unregister_pernet_device(&sit_net_ops);
1235 printk(KERN_INFO "sit init: Can't add protocol\n");
1236 }
1240 return err; 1237 return err;
1241} 1238}
1242 1239
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 7208a06576c6..34d1f0690d7e 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -269,7 +269,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
269 req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); 269 req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
270 tcp_select_initial_window(tcp_full_space(sk), req->mss, 270 tcp_select_initial_window(tcp_full_space(sk), req->mss,
271 &req->rcv_wnd, &req->window_clamp, 271 &req->rcv_wnd, &req->window_clamp,
272 ireq->wscale_ok, &rcv_wscale); 272 ireq->wscale_ok, &rcv_wscale,
273 dst_metric(dst, RTAX_INITRWND));
273 274
274 ireq->rcv_wscale = rcv_wscale; 275 ireq->rcv_wscale = rcv_wscale;
275 276
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index c690736885b4..f841d93bf987 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -55,7 +55,7 @@ struct ctl_path net_ipv6_ctl_path[] = {
55}; 55};
56EXPORT_SYMBOL_GPL(net_ipv6_ctl_path); 56EXPORT_SYMBOL_GPL(net_ipv6_ctl_path);
57 57
58static int ipv6_sysctl_net_init(struct net *net) 58static int __net_init ipv6_sysctl_net_init(struct net *net)
59{ 59{
60 struct ctl_table *ipv6_table; 60 struct ctl_table *ipv6_table;
61 struct ctl_table *ipv6_route_table; 61 struct ctl_table *ipv6_route_table;
@@ -98,7 +98,7 @@ out_ipv6_table:
98 goto out; 98 goto out;
99} 99}
100 100
101static void ipv6_sysctl_net_exit(struct net *net) 101static void __net_exit ipv6_sysctl_net_exit(struct net *net)
102{ 102{
103 struct ctl_table *ipv6_table; 103 struct ctl_table *ipv6_table;
104 struct ctl_table *ipv6_route_table; 104 struct ctl_table *ipv6_route_table;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index febfd595a40d..6963a6b6763e 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -520,6 +520,13 @@ done:
520 return err; 520 return err;
521} 521}
522 522
523static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req,
524 struct request_values *rvp)
525{
526 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
527 return tcp_v6_send_synack(sk, req, rvp);
528}
529
523static inline void syn_flood_warning(struct sk_buff *skb) 530static inline void syn_flood_warning(struct sk_buff *skb)
524{ 531{
525#ifdef CONFIG_SYN_COOKIES 532#ifdef CONFIG_SYN_COOKIES
@@ -876,7 +883,7 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
876 883
877 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 884 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
878 if (net_ratelimit()) { 885 if (net_ratelimit()) {
879 printk(KERN_INFO "MD5 Hash %s for (%pI6, %u)->(%pI6, %u)\n", 886 printk(KERN_INFO "MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u\n",
880 genhash ? "failed" : "mismatch", 887 genhash ? "failed" : "mismatch",
881 &ip6h->saddr, ntohs(th->source), 888 &ip6h->saddr, ntohs(th->source),
882 &ip6h->daddr, ntohs(th->dest)); 889 &ip6h->daddr, ntohs(th->dest));
@@ -890,10 +897,11 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
890struct request_sock_ops tcp6_request_sock_ops __read_mostly = { 897struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
891 .family = AF_INET6, 898 .family = AF_INET6,
892 .obj_size = sizeof(struct tcp6_request_sock), 899 .obj_size = sizeof(struct tcp6_request_sock),
893 .rtx_syn_ack = tcp_v6_send_synack, 900 .rtx_syn_ack = tcp_v6_rtx_synack,
894 .send_ack = tcp_v6_reqsk_send_ack, 901 .send_ack = tcp_v6_reqsk_send_ack,
895 .destructor = tcp_v6_reqsk_destructor, 902 .destructor = tcp_v6_reqsk_destructor,
896 .send_reset = tcp_v6_send_reset 903 .send_reset = tcp_v6_send_reset,
904 .syn_ack_timeout = tcp_syn_ack_timeout,
897}; 905};
898 906
899#ifdef CONFIG_TCP_MD5SIG 907#ifdef CONFIG_TCP_MD5SIG
@@ -2105,7 +2113,7 @@ static struct tcp_seq_afinfo tcp6_seq_afinfo = {
2105 }, 2113 },
2106}; 2114};
2107 2115
2108int tcp6_proc_init(struct net *net) 2116int __net_init tcp6_proc_init(struct net *net)
2109{ 2117{
2110 return tcp_proc_register(net, &tcp6_seq_afinfo); 2118 return tcp_proc_register(net, &tcp6_seq_afinfo);
2111} 2119}
@@ -2174,18 +2182,18 @@ static struct inet_protosw tcpv6_protosw = {
2174 INET_PROTOSW_ICSK, 2182 INET_PROTOSW_ICSK,
2175}; 2183};
2176 2184
2177static int tcpv6_net_init(struct net *net) 2185static int __net_init tcpv6_net_init(struct net *net)
2178{ 2186{
2179 return inet_ctl_sock_create(&net->ipv6.tcp_sk, PF_INET6, 2187 return inet_ctl_sock_create(&net->ipv6.tcp_sk, PF_INET6,
2180 SOCK_RAW, IPPROTO_TCP, net); 2188 SOCK_RAW, IPPROTO_TCP, net);
2181} 2189}
2182 2190
2183static void tcpv6_net_exit(struct net *net) 2191static void __net_exit tcpv6_net_exit(struct net *net)
2184{ 2192{
2185 inet_ctl_sock_destroy(net->ipv6.tcp_sk); 2193 inet_ctl_sock_destroy(net->ipv6.tcp_sk);
2186} 2194}
2187 2195
2188static void tcpv6_net_exit_batch(struct list_head *net_exit_list) 2196static void __net_exit tcpv6_net_exit_batch(struct list_head *net_exit_list)
2189{ 2197{
2190 inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET6); 2198 inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET6);
2191} 2199}
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index 51e2832d13a6..e17bc1dfc1a4 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -98,7 +98,7 @@ static int tunnel6_rcv(struct sk_buff *skb)
98 if (!handler->handler(skb)) 98 if (!handler->handler(skb))
99 return 0; 99 return 0;
100 100
101 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev); 101 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
102 102
103drop: 103drop:
104 kfree_skb(skb); 104 kfree_skb(skb);
@@ -116,7 +116,7 @@ static int tunnel46_rcv(struct sk_buff *skb)
116 if (!handler->handler(skb)) 116 if (!handler->handler(skb))
117 return 0; 117 return 0;
118 118
119 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev); 119 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
120 120
121drop: 121drop:
122 kfree_skb(skb); 122 kfree_skb(skb);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 69ebdbe78c47..52b8347ae3b2 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -322,7 +322,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
322 struct ipv6_pinfo *np = inet6_sk(sk); 322 struct ipv6_pinfo *np = inet6_sk(sk);
323 struct inet_sock *inet = inet_sk(sk); 323 struct inet_sock *inet = inet_sk(sk);
324 struct sk_buff *skb; 324 struct sk_buff *skb;
325 unsigned int ulen, copied; 325 unsigned int ulen;
326 int peeked; 326 int peeked;
327 int err; 327 int err;
328 int is_udplite = IS_UDPLITE(sk); 328 int is_udplite = IS_UDPLITE(sk);
@@ -341,10 +341,9 @@ try_again:
341 goto out; 341 goto out;
342 342
343 ulen = skb->len - sizeof(struct udphdr); 343 ulen = skb->len - sizeof(struct udphdr);
344 copied = len; 344 if (len > ulen)
345 if (copied > ulen) 345 len = ulen;
346 copied = ulen; 346 else if (len < ulen)
347 else if (copied < ulen)
348 msg->msg_flags |= MSG_TRUNC; 347 msg->msg_flags |= MSG_TRUNC;
349 348
350 is_udp4 = (skb->protocol == htons(ETH_P_IP)); 349 is_udp4 = (skb->protocol == htons(ETH_P_IP));
@@ -355,14 +354,14 @@ try_again:
355 * coverage checksum (UDP-Lite), do it before the copy. 354 * coverage checksum (UDP-Lite), do it before the copy.
356 */ 355 */
357 356
358 if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) { 357 if (len < ulen || UDP_SKB_CB(skb)->partial_cov) {
359 if (udp_lib_checksum_complete(skb)) 358 if (udp_lib_checksum_complete(skb))
360 goto csum_copy_err; 359 goto csum_copy_err;
361 } 360 }
362 361
363 if (skb_csum_unnecessary(skb)) 362 if (skb_csum_unnecessary(skb))
364 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), 363 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
365 msg->msg_iov, copied ); 364 msg->msg_iov,len);
366 else { 365 else {
367 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); 366 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
368 if (err == -EINVAL) 367 if (err == -EINVAL)
@@ -411,7 +410,7 @@ try_again:
411 datagram_recv_ctl(sk, msg, skb); 410 datagram_recv_ctl(sk, msg, skb);
412 } 411 }
413 412
414 err = copied; 413 err = len;
415 if (flags & MSG_TRUNC) 414 if (flags & MSG_TRUNC)
416 err = ulen; 415 err = ulen;
417 416
@@ -681,12 +680,11 @@ static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh,
681int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, 680int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
682 int proto) 681 int proto)
683{ 682{
683 struct net *net = dev_net(skb->dev);
684 struct sock *sk; 684 struct sock *sk;
685 struct udphdr *uh; 685 struct udphdr *uh;
686 struct net_device *dev = skb->dev;
687 struct in6_addr *saddr, *daddr; 686 struct in6_addr *saddr, *daddr;
688 u32 ulen = 0; 687 u32 ulen = 0;
689 struct net *net = dev_net(skb->dev);
690 688
691 if (!pskb_may_pull(skb, sizeof(struct udphdr))) 689 if (!pskb_may_pull(skb, sizeof(struct udphdr)))
692 goto short_packet; 690 goto short_packet;
@@ -745,7 +743,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
745 UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, 743 UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS,
746 proto == IPPROTO_UDPLITE); 744 proto == IPPROTO_UDPLITE);
747 745
748 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev); 746 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
749 747
750 kfree_skb(skb); 748 kfree_skb(skb);
751 return 0; 749 return 0;
@@ -1396,7 +1394,7 @@ static struct udp_seq_afinfo udp6_seq_afinfo = {
1396 }, 1394 },
1397}; 1395};
1398 1396
1399int udp6_proc_init(struct net *net) 1397int __net_init udp6_proc_init(struct net *net)
1400{ 1398{
1401 return udp_proc_register(net, &udp6_seq_afinfo); 1399 return udp_proc_register(net, &udp6_seq_afinfo);
1402} 1400}
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 6ea6938919e6..5f48fadc27f7 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -104,12 +104,12 @@ static struct udp_seq_afinfo udplite6_seq_afinfo = {
104 }, 104 },
105}; 105};
106 106
107static int udplite6_proc_init_net(struct net *net) 107static int __net_init udplite6_proc_init_net(struct net *net)
108{ 108{
109 return udp_proc_register(net, &udplite6_seq_afinfo); 109 return udp_proc_register(net, &udplite6_seq_afinfo);
110} 110}
111 111
112static void udplite6_proc_exit_net(struct net *net) 112static void __net_exit udplite6_proc_exit_net(struct net *net)
113{ 113{
114 udp_proc_unregister(net, &udplite6_seq_afinfo); 114 udp_proc_unregister(net, &udplite6_seq_afinfo);
115} 115}
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 9084582d236b..2bc98ede1235 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -101,7 +101,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
101 break; 101 break;
102 } 102 }
103 103
104 x = xfrm_state_lookup_byaddr(net, dst, src, proto, AF_INET6); 104 x = xfrm_state_lookup_byaddr(net, skb->mark, dst, src, proto, AF_INET6);
105 if (!x) 105 if (!x)
106 continue; 106 continue;
107 107
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index c4f4eef032a3..0c92112dcba3 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -38,7 +38,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
38 38
39 if (!skb->local_df && skb->len > mtu) { 39 if (!skb->local_df && skb->len > mtu) {
40 skb->dev = dst->dev; 40 skb->dev = dst->dev;
41 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 41 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
42 ret = -EMSGSIZE; 42 ret = -EMSGSIZE;
43 } 43 }
44 44
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 438831d33593..fa85a7d22dc4 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -30,6 +30,25 @@
30#include <linux/ipv6.h> 30#include <linux/ipv6.h>
31#include <linux/icmpv6.h> 31#include <linux/icmpv6.h>
32#include <linux/mutex.h> 32#include <linux/mutex.h>
33#include <net/netns/generic.h>
34
35#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
36#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256
37
38#define XFRM6_TUNNEL_SPI_MIN 1
39#define XFRM6_TUNNEL_SPI_MAX 0xffffffff
40
41struct xfrm6_tunnel_net {
42 struct hlist_head spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
43 struct hlist_head spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
44 u32 spi;
45};
46
47static int xfrm6_tunnel_net_id __read_mostly;
48static inline struct xfrm6_tunnel_net *xfrm6_tunnel_pernet(struct net *net)
49{
50 return net_generic(net, xfrm6_tunnel_net_id);
51}
33 52
34/* 53/*
35 * xfrm_tunnel_spi things are for allocating unique id ("spi") 54 * xfrm_tunnel_spi things are for allocating unique id ("spi")
@@ -46,19 +65,8 @@ struct xfrm6_tunnel_spi {
46 65
47static DEFINE_SPINLOCK(xfrm6_tunnel_spi_lock); 66static DEFINE_SPINLOCK(xfrm6_tunnel_spi_lock);
48 67
49static u32 xfrm6_tunnel_spi;
50
51#define XFRM6_TUNNEL_SPI_MIN 1
52#define XFRM6_TUNNEL_SPI_MAX 0xffffffff
53
54static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly; 68static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly;
55 69
56#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
57#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256
58
59static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
60static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
61
62static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr) 70static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
63{ 71{
64 unsigned h; 72 unsigned h;
@@ -76,50 +84,14 @@ static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi)
76 return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE; 84 return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
77} 85}
78 86
79 87static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr)
80static int xfrm6_tunnel_spi_init(void)
81{
82 int i;
83
84 xfrm6_tunnel_spi = 0;
85 xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
86 sizeof(struct xfrm6_tunnel_spi),
87 0, SLAB_HWCACHE_ALIGN,
88 NULL);
89 if (!xfrm6_tunnel_spi_kmem)
90 return -ENOMEM;
91
92 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
93 INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byaddr[i]);
94 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++)
95 INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byspi[i]);
96 return 0;
97}
98
99static void xfrm6_tunnel_spi_fini(void)
100{
101 int i;
102
103 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) {
104 if (!hlist_empty(&xfrm6_tunnel_spi_byaddr[i]))
105 return;
106 }
107 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++) {
108 if (!hlist_empty(&xfrm6_tunnel_spi_byspi[i]))
109 return;
110 }
111 rcu_barrier();
112 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
113 xfrm6_tunnel_spi_kmem = NULL;
114}
115
116static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
117{ 88{
89 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
118 struct xfrm6_tunnel_spi *x6spi; 90 struct xfrm6_tunnel_spi *x6spi;
119 struct hlist_node *pos; 91 struct hlist_node *pos;
120 92
121 hlist_for_each_entry_rcu(x6spi, pos, 93 hlist_for_each_entry_rcu(x6spi, pos,
122 &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)], 94 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
123 list_byaddr) { 95 list_byaddr) {
124 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) 96 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0)
125 return x6spi; 97 return x6spi;
@@ -128,13 +100,13 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
128 return NULL; 100 return NULL;
129} 101}
130 102
131__be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) 103__be32 xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr)
132{ 104{
133 struct xfrm6_tunnel_spi *x6spi; 105 struct xfrm6_tunnel_spi *x6spi;
134 u32 spi; 106 u32 spi;
135 107
136 rcu_read_lock_bh(); 108 rcu_read_lock_bh();
137 x6spi = __xfrm6_tunnel_spi_lookup(saddr); 109 x6spi = __xfrm6_tunnel_spi_lookup(net, saddr);
138 spi = x6spi ? x6spi->spi : 0; 110 spi = x6spi ? x6spi->spi : 0;
139 rcu_read_unlock_bh(); 111 rcu_read_unlock_bh();
140 return htonl(spi); 112 return htonl(spi);
@@ -142,14 +114,15 @@ __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
142 114
143EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); 115EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup);
144 116
145static int __xfrm6_tunnel_spi_check(u32 spi) 117static int __xfrm6_tunnel_spi_check(struct net *net, u32 spi)
146{ 118{
119 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
147 struct xfrm6_tunnel_spi *x6spi; 120 struct xfrm6_tunnel_spi *x6spi;
148 int index = xfrm6_tunnel_spi_hash_byspi(spi); 121 int index = xfrm6_tunnel_spi_hash_byspi(spi);
149 struct hlist_node *pos; 122 struct hlist_node *pos;
150 123
151 hlist_for_each_entry(x6spi, pos, 124 hlist_for_each_entry(x6spi, pos,
152 &xfrm6_tunnel_spi_byspi[index], 125 &xfrm6_tn->spi_byspi[index],
153 list_byspi) { 126 list_byspi) {
154 if (x6spi->spi == spi) 127 if (x6spi->spi == spi)
155 return -1; 128 return -1;
@@ -157,61 +130,61 @@ static int __xfrm6_tunnel_spi_check(u32 spi)
157 return index; 130 return index;
158} 131}
159 132
160static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) 133static u32 __xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr)
161{ 134{
135 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
162 u32 spi; 136 u32 spi;
163 struct xfrm6_tunnel_spi *x6spi; 137 struct xfrm6_tunnel_spi *x6spi;
164 int index; 138 int index;
165 139
166 if (xfrm6_tunnel_spi < XFRM6_TUNNEL_SPI_MIN || 140 if (xfrm6_tn->spi < XFRM6_TUNNEL_SPI_MIN ||
167 xfrm6_tunnel_spi >= XFRM6_TUNNEL_SPI_MAX) 141 xfrm6_tn->spi >= XFRM6_TUNNEL_SPI_MAX)
168 xfrm6_tunnel_spi = XFRM6_TUNNEL_SPI_MIN; 142 xfrm6_tn->spi = XFRM6_TUNNEL_SPI_MIN;
169 else 143 else
170 xfrm6_tunnel_spi++; 144 xfrm6_tn->spi++;
171 145
172 for (spi = xfrm6_tunnel_spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) { 146 for (spi = xfrm6_tn->spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) {
173 index = __xfrm6_tunnel_spi_check(spi); 147 index = __xfrm6_tunnel_spi_check(net, spi);
174 if (index >= 0) 148 if (index >= 0)
175 goto alloc_spi; 149 goto alloc_spi;
176 } 150 }
177 for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tunnel_spi; spi++) { 151 for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tn->spi; spi++) {
178 index = __xfrm6_tunnel_spi_check(spi); 152 index = __xfrm6_tunnel_spi_check(net, spi);
179 if (index >= 0) 153 if (index >= 0)
180 goto alloc_spi; 154 goto alloc_spi;
181 } 155 }
182 spi = 0; 156 spi = 0;
183 goto out; 157 goto out;
184alloc_spi: 158alloc_spi:
185 xfrm6_tunnel_spi = spi; 159 xfrm6_tn->spi = spi;
186 x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC); 160 x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC);
187 if (!x6spi) 161 if (!x6spi)
188 goto out; 162 goto out;
189 163
190 INIT_RCU_HEAD(&x6spi->rcu_head);
191 memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr)); 164 memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr));
192 x6spi->spi = spi; 165 x6spi->spi = spi;
193 atomic_set(&x6spi->refcnt, 1); 166 atomic_set(&x6spi->refcnt, 1);
194 167
195 hlist_add_head_rcu(&x6spi->list_byspi, &xfrm6_tunnel_spi_byspi[index]); 168 hlist_add_head_rcu(&x6spi->list_byspi, &xfrm6_tn->spi_byspi[index]);
196 169
197 index = xfrm6_tunnel_spi_hash_byaddr(saddr); 170 index = xfrm6_tunnel_spi_hash_byaddr(saddr);
198 hlist_add_head_rcu(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]); 171 hlist_add_head_rcu(&x6spi->list_byaddr, &xfrm6_tn->spi_byaddr[index]);
199out: 172out:
200 return spi; 173 return spi;
201} 174}
202 175
203__be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) 176__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr)
204{ 177{
205 struct xfrm6_tunnel_spi *x6spi; 178 struct xfrm6_tunnel_spi *x6spi;
206 u32 spi; 179 u32 spi;
207 180
208 spin_lock_bh(&xfrm6_tunnel_spi_lock); 181 spin_lock_bh(&xfrm6_tunnel_spi_lock);
209 x6spi = __xfrm6_tunnel_spi_lookup(saddr); 182 x6spi = __xfrm6_tunnel_spi_lookup(net, saddr);
210 if (x6spi) { 183 if (x6spi) {
211 atomic_inc(&x6spi->refcnt); 184 atomic_inc(&x6spi->refcnt);
212 spi = x6spi->spi; 185 spi = x6spi->spi;
213 } else 186 } else
214 spi = __xfrm6_tunnel_alloc_spi(saddr); 187 spi = __xfrm6_tunnel_alloc_spi(net, saddr);
215 spin_unlock_bh(&xfrm6_tunnel_spi_lock); 188 spin_unlock_bh(&xfrm6_tunnel_spi_lock);
216 189
217 return htonl(spi); 190 return htonl(spi);
@@ -225,15 +198,16 @@ static void x6spi_destroy_rcu(struct rcu_head *head)
225 container_of(head, struct xfrm6_tunnel_spi, rcu_head)); 198 container_of(head, struct xfrm6_tunnel_spi, rcu_head));
226} 199}
227 200
228void xfrm6_tunnel_free_spi(xfrm_address_t *saddr) 201void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr)
229{ 202{
203 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
230 struct xfrm6_tunnel_spi *x6spi; 204 struct xfrm6_tunnel_spi *x6spi;
231 struct hlist_node *pos, *n; 205 struct hlist_node *pos, *n;
232 206
233 spin_lock_bh(&xfrm6_tunnel_spi_lock); 207 spin_lock_bh(&xfrm6_tunnel_spi_lock);
234 208
235 hlist_for_each_entry_safe(x6spi, pos, n, 209 hlist_for_each_entry_safe(x6spi, pos, n,
236 &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)], 210 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
237 list_byaddr) 211 list_byaddr)
238 { 212 {
239 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) { 213 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
@@ -263,10 +237,11 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
263 237
264static int xfrm6_tunnel_rcv(struct sk_buff *skb) 238static int xfrm6_tunnel_rcv(struct sk_buff *skb)
265{ 239{
240 struct net *net = dev_net(skb->dev);
266 struct ipv6hdr *iph = ipv6_hdr(skb); 241 struct ipv6hdr *iph = ipv6_hdr(skb);
267 __be32 spi; 242 __be32 spi;
268 243
269 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); 244 spi = xfrm6_tunnel_spi_lookup(net, (xfrm_address_t *)&iph->saddr);
270 return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0; 245 return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0;
271} 246}
272 247
@@ -326,7 +301,9 @@ static int xfrm6_tunnel_init_state(struct xfrm_state *x)
326 301
327static void xfrm6_tunnel_destroy(struct xfrm_state *x) 302static void xfrm6_tunnel_destroy(struct xfrm_state *x)
328{ 303{
329 xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr); 304 struct net *net = xs_net(x);
305
306 xfrm6_tunnel_free_spi(net, (xfrm_address_t *)&x->props.saddr);
330} 307}
331 308
332static const struct xfrm_type xfrm6_tunnel_type = { 309static const struct xfrm_type xfrm6_tunnel_type = {
@@ -351,34 +328,73 @@ static struct xfrm6_tunnel xfrm46_tunnel_handler = {
351 .priority = 2, 328 .priority = 2,
352}; 329};
353 330
331static int __net_init xfrm6_tunnel_net_init(struct net *net)
332{
333 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
334 unsigned int i;
335
336 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
337 INIT_HLIST_HEAD(&xfrm6_tn->spi_byaddr[i]);
338 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++)
339 INIT_HLIST_HEAD(&xfrm6_tn->spi_byspi[i]);
340 xfrm6_tn->spi = 0;
341
342 return 0;
343}
344
345static void __net_exit xfrm6_tunnel_net_exit(struct net *net)
346{
347}
348
349static struct pernet_operations xfrm6_tunnel_net_ops = {
350 .init = xfrm6_tunnel_net_init,
351 .exit = xfrm6_tunnel_net_exit,
352 .id = &xfrm6_tunnel_net_id,
353 .size = sizeof(struct xfrm6_tunnel_net),
354};
355
354static int __init xfrm6_tunnel_init(void) 356static int __init xfrm6_tunnel_init(void)
355{ 357{
356 if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) 358 int rv;
357 goto err; 359
358 if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) 360 xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
359 goto unreg; 361 sizeof(struct xfrm6_tunnel_spi),
360 if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) 362 0, SLAB_HWCACHE_ALIGN,
361 goto dereg6; 363 NULL);
362 if (xfrm6_tunnel_spi_init() < 0) 364 if (!xfrm6_tunnel_spi_kmem)
363 goto dereg46; 365 return -ENOMEM;
366 rv = register_pernet_subsys(&xfrm6_tunnel_net_ops);
367 if (rv < 0)
368 goto out_pernet;
369 rv = xfrm_register_type(&xfrm6_tunnel_type, AF_INET6);
370 if (rv < 0)
371 goto out_type;
372 rv = xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6);
373 if (rv < 0)
374 goto out_xfrm6;
375 rv = xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET);
376 if (rv < 0)
377 goto out_xfrm46;
364 return 0; 378 return 0;
365 379
366dereg46: 380out_xfrm46:
367 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
368dereg6:
369 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); 381 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
370unreg: 382out_xfrm6:
371 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 383 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
372err: 384out_type:
373 return -EAGAIN; 385 unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
386out_pernet:
387 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
388 return rv;
374} 389}
375 390
376static void __exit xfrm6_tunnel_fini(void) 391static void __exit xfrm6_tunnel_fini(void)
377{ 392{
378 xfrm6_tunnel_spi_fini();
379 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET); 393 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
380 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); 394 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
381 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 395 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
396 unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
397 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
382} 398}
383 399
384module_init(xfrm6_tunnel_init); 400module_init(xfrm6_tunnel_init);