aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/Kconfig19
-rw-r--r--net/ipv6/addrconf.c493
-rw-r--r--net/ipv6/addrconf_core.c2
-rw-r--r--net/ipv6/addrlabel.c1
-rw-r--r--net/ipv6/af_inet6.c88
-rw-r--r--net/ipv6/ah6.c357
-rw-r--r--net/ipv6/anycast.c38
-rw-r--r--net/ipv6/datagram.c57
-rw-r--r--net/ipv6/esp6.c4
-rw-r--r--net/ipv6/exthdrs.c10
-rw-r--r--net/ipv6/fib6_rules.c39
-rw-r--r--net/ipv6/icmp.c17
-rw-r--r--net/ipv6/inet6_connection_sock.c11
-rw-r--r--net/ipv6/inet6_hashtables.c37
-rw-r--r--net/ipv6/ip6_fib.c53
-rw-r--r--net/ipv6/ip6_flowlabel.c27
-rw-r--r--net/ipv6/ip6_input.c4
-rw-r--r--net/ipv6/ip6_output.c29
-rw-r--r--net/ipv6/ip6_tunnel.c135
-rw-r--r--net/ipv6/ip6mr.c32
-rw-r--r--net/ipv6/ipcomp6.c21
-rw-r--r--net/ipv6/ipv6_sockglue.c10
-rw-r--r--net/ipv6/mcast.c84
-rw-r--r--net/ipv6/mip6.c2
-rw-r--r--net/ipv6/ndisc.c48
-rw-r--r--net/ipv6/netfilter/ip6_queue.c12
-rw-r--r--net/ipv6/netfilter/ip6_tables.c605
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c4
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c7
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c19
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c47
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c9
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c114
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c156
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c87
-rw-r--r--net/ipv6/netfilter/ip6table_security.c110
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c27
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c27
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c28
-rw-r--r--net/ipv6/proc.c39
-rw-r--r--net/ipv6/raw.c65
-rw-r--r--net/ipv6/reassembly.c59
-rw-r--r--net/ipv6/route.c63
-rw-r--r--net/ipv6/sit.c356
-rw-r--r--net/ipv6/syncookies.c11
-rw-r--r--net/ipv6/sysctl_net_ipv6.c17
-rw-r--r--net/ipv6/tcp_ipv6.c176
-rw-r--r--net/ipv6/tunnel6.c5
-rw-r--r--net/ipv6/udp.c300
-rw-r--r--net/ipv6/udplite.c5
-rw-r--r--net/ipv6/xfrm6_input.c2
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c1
-rw-r--r--net/ipv6/xfrm6_output.c2
-rw-r--r--net/ipv6/xfrm6_policy.c31
-rw-r--r--net/ipv6/xfrm6_tunnel.c234
55 files changed, 2315 insertions, 1921 deletions
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index ead6c7a42f44..a578096152ab 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -170,6 +170,25 @@ config IPV6_SIT
170 170
171 Saying M here will produce a module called sit. If unsure, say Y. 171 Saying M here will produce a module called sit. If unsure, say Y.
172 172
173config IPV6_SIT_6RD
174 bool "IPv6: IPv6 Rapid Deployment (6RD) (EXPERIMENTAL)"
175 depends on IPV6_SIT && EXPERIMENTAL
176 default n
177 ---help---
178 IPv6 Rapid Deployment (6rd; draft-ietf-softwire-ipv6-6rd) builds upon
179 mechanisms of 6to4 (RFC3056) to enable a service provider to rapidly
180 deploy IPv6 unicast service to IPv4 sites to which it provides
181 customer premise equipment. Like 6to4, it utilizes stateless IPv6 in
182 IPv4 encapsulation in order to transit IPv4-only network
183 infrastructure. Unlike 6to4, a 6rd service provider uses an IPv6
184 prefix of its own in place of the fixed 6to4 prefix.
185
186 With this option enabled, the SIT driver offers 6rd functionality by
187 providing additional ioctl API to configure the IPv6 Prefix for in
188 stead of static 2002::/16 for 6to4.
189
190 If unsure, say N.
191
173config IPV6_NDISC_NODETYPE 192config IPV6_NDISC_NODETYPE
174 bool 193 bool
175 194
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 1fd0a3d775d2..413054f02aab 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -53,6 +53,7 @@
53#include <linux/route.h> 53#include <linux/route.h>
54#include <linux/inetdevice.h> 54#include <linux/inetdevice.h>
55#include <linux/init.h> 55#include <linux/init.h>
56#include <linux/slab.h>
56#ifdef CONFIG_SYSCTL 57#ifdef CONFIG_SYSCTL
57#include <linux/sysctl.h> 58#include <linux/sysctl.h>
58#endif 59#endif
@@ -278,31 +279,31 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
278 279
279static int snmp6_alloc_dev(struct inet6_dev *idev) 280static int snmp6_alloc_dev(struct inet6_dev *idev)
280{ 281{
281 if (snmp_mib_init((void **)idev->stats.ipv6, 282 if (snmp_mib_init((void __percpu **)idev->stats.ipv6,
282 sizeof(struct ipstats_mib)) < 0) 283 sizeof(struct ipstats_mib)) < 0)
283 goto err_ip; 284 goto err_ip;
284 if (snmp_mib_init((void **)idev->stats.icmpv6, 285 if (snmp_mib_init((void __percpu **)idev->stats.icmpv6,
285 sizeof(struct icmpv6_mib)) < 0) 286 sizeof(struct icmpv6_mib)) < 0)
286 goto err_icmp; 287 goto err_icmp;
287 if (snmp_mib_init((void **)idev->stats.icmpv6msg, 288 if (snmp_mib_init((void __percpu **)idev->stats.icmpv6msg,
288 sizeof(struct icmpv6msg_mib)) < 0) 289 sizeof(struct icmpv6msg_mib)) < 0)
289 goto err_icmpmsg; 290 goto err_icmpmsg;
290 291
291 return 0; 292 return 0;
292 293
293err_icmpmsg: 294err_icmpmsg:
294 snmp_mib_free((void **)idev->stats.icmpv6); 295 snmp_mib_free((void __percpu **)idev->stats.icmpv6);
295err_icmp: 296err_icmp:
296 snmp_mib_free((void **)idev->stats.ipv6); 297 snmp_mib_free((void __percpu **)idev->stats.ipv6);
297err_ip: 298err_ip:
298 return -ENOMEM; 299 return -ENOMEM;
299} 300}
300 301
301static void snmp6_free_dev(struct inet6_dev *idev) 302static void snmp6_free_dev(struct inet6_dev *idev)
302{ 303{
303 snmp_mib_free((void **)idev->stats.icmpv6msg); 304 snmp_mib_free((void __percpu **)idev->stats.icmpv6msg);
304 snmp_mib_free((void **)idev->stats.icmpv6); 305 snmp_mib_free((void __percpu **)idev->stats.icmpv6);
305 snmp_mib_free((void **)idev->stats.ipv6); 306 snmp_mib_free((void __percpu **)idev->stats.ipv6);
306} 307}
307 308
308/* Nobody refers to this device, we may destroy it. */ 309/* Nobody refers to this device, we may destroy it. */
@@ -481,9 +482,8 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
481 struct net_device *dev; 482 struct net_device *dev;
482 struct inet6_dev *idev; 483 struct inet6_dev *idev;
483 484
484 read_lock(&dev_base_lock); 485 rcu_read_lock();
485 for_each_netdev(net, dev) { 486 for_each_netdev_rcu(net, dev) {
486 rcu_read_lock();
487 idev = __in6_dev_get(dev); 487 idev = __in6_dev_get(dev);
488 if (idev) { 488 if (idev) {
489 int changed = (!idev->cnf.forwarding) ^ (!newf); 489 int changed = (!idev->cnf.forwarding) ^ (!newf);
@@ -491,9 +491,8 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
491 if (changed) 491 if (changed)
492 dev_forward_change(idev); 492 dev_forward_change(idev);
493 } 493 }
494 rcu_read_unlock();
495 } 494 }
496 read_unlock(&dev_base_lock); 495 rcu_read_unlock();
497} 496}
498 497
499static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) 498static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
@@ -504,8 +503,11 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
504 if (p == &net->ipv6.devconf_dflt->forwarding) 503 if (p == &net->ipv6.devconf_dflt->forwarding)
505 return 0; 504 return 0;
506 505
507 if (!rtnl_trylock()) 506 if (!rtnl_trylock()) {
507 /* Restore the original values before restarting */
508 *p = old;
508 return restart_syscall(); 509 return restart_syscall();
510 }
509 511
510 if (p == &net->ipv6.devconf_all->forwarding) { 512 if (p == &net->ipv6.devconf_all->forwarding) {
511 __s32 newf = net->ipv6.devconf_all->forwarding; 513 __s32 newf = net->ipv6.devconf_all->forwarding;
@@ -991,8 +993,7 @@ struct ipv6_saddr_dst {
991 993
992static inline int ipv6_saddr_preferred(int type) 994static inline int ipv6_saddr_preferred(int type)
993{ 995{
994 if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4| 996 if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|IPV6_ADDR_LOOPBACK))
995 IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
996 return 1; 997 return 1;
997 return 0; 998 return 0;
998} 999}
@@ -1137,10 +1138,9 @@ int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
1137 hiscore->rule = -1; 1138 hiscore->rule = -1;
1138 hiscore->ifa = NULL; 1139 hiscore->ifa = NULL;
1139 1140
1140 read_lock(&dev_base_lock);
1141 rcu_read_lock(); 1141 rcu_read_lock();
1142 1142
1143 for_each_netdev(net, dev) { 1143 for_each_netdev_rcu(net, dev) {
1144 struct inet6_dev *idev; 1144 struct inet6_dev *idev;
1145 1145
1146 /* Candidate Source Address (section 4) 1146 /* Candidate Source Address (section 4)
@@ -1235,7 +1235,6 @@ try_nextdev:
1235 read_unlock_bh(&idev->lock); 1235 read_unlock_bh(&idev->lock);
1236 } 1236 }
1237 rcu_read_unlock(); 1237 rcu_read_unlock();
1238 read_unlock(&dev_base_lock);
1239 1238
1240 if (!hiscore->ifa) 1239 if (!hiscore->ifa)
1241 return -EADDRNOTAVAIL; 1240 return -EADDRNOTAVAIL;
@@ -1382,6 +1381,8 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
1382 if (dad_failed) 1381 if (dad_failed)
1383 ifp->flags |= IFA_F_DADFAILED; 1382 ifp->flags |= IFA_F_DADFAILED;
1384 spin_unlock_bh(&ifp->lock); 1383 spin_unlock_bh(&ifp->lock);
1384 if (dad_failed)
1385 ipv6_ifa_notify(0, ifp);
1385 in6_ifa_put(ifp); 1386 in6_ifa_put(ifp);
1386#ifdef CONFIG_IPV6_PRIVACY 1387#ifdef CONFIG_IPV6_PRIVACY
1387 } else if (ifp->flags&IFA_F_TEMPORARY) { 1388 } else if (ifp->flags&IFA_F_TEMPORARY) {
@@ -2617,7 +2618,7 @@ static void addrconf_bonding_change(struct net_device *dev, unsigned long event)
2617static int addrconf_ifdown(struct net_device *dev, int how) 2618static int addrconf_ifdown(struct net_device *dev, int how)
2618{ 2619{
2619 struct inet6_dev *idev; 2620 struct inet6_dev *idev;
2620 struct inet6_ifaddr *ifa, **bifa; 2621 struct inet6_ifaddr *ifa, *keep_list, **bifa;
2621 struct net *net = dev_net(dev); 2622 struct net *net = dev_net(dev);
2622 int i; 2623 int i;
2623 2624
@@ -2650,11 +2651,12 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2650 2651
2651 write_lock_bh(&addrconf_hash_lock); 2652 write_lock_bh(&addrconf_hash_lock);
2652 while ((ifa = *bifa) != NULL) { 2653 while ((ifa = *bifa) != NULL) {
2653 if (ifa->idev == idev) { 2654 if (ifa->idev == idev &&
2655 (how || !(ifa->flags&IFA_F_PERMANENT) ||
2656 ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
2654 *bifa = ifa->lst_next; 2657 *bifa = ifa->lst_next;
2655 ifa->lst_next = NULL; 2658 ifa->lst_next = NULL;
2656 addrconf_del_timer(ifa); 2659 __in6_ifa_put(ifa);
2657 in6_ifa_put(ifa);
2658 continue; 2660 continue;
2659 } 2661 }
2660 bifa = &ifa->lst_next; 2662 bifa = &ifa->lst_next;
@@ -2690,11 +2692,40 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2690 write_lock_bh(&idev->lock); 2692 write_lock_bh(&idev->lock);
2691 } 2693 }
2692#endif 2694#endif
2695 keep_list = NULL;
2696 bifa = &keep_list;
2693 while ((ifa = idev->addr_list) != NULL) { 2697 while ((ifa = idev->addr_list) != NULL) {
2694 idev->addr_list = ifa->if_next; 2698 idev->addr_list = ifa->if_next;
2695 ifa->if_next = NULL; 2699 ifa->if_next = NULL;
2696 ifa->dead = 1; 2700
2697 addrconf_del_timer(ifa); 2701 addrconf_del_timer(ifa);
2702
2703 /* If just doing link down, and address is permanent
2704 and not link-local, then retain it. */
2705 if (how == 0 &&
2706 (ifa->flags&IFA_F_PERMANENT) &&
2707 !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
2708
2709 /* Move to holding list */
2710 *bifa = ifa;
2711 bifa = &ifa->if_next;
2712
2713 /* If not doing DAD on this address, just keep it. */
2714 if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
2715 idev->cnf.accept_dad <= 0 ||
2716 (ifa->flags & IFA_F_NODAD))
2717 continue;
2718
2719 /* If it was tentative already, no need to notify */
2720 if (ifa->flags & IFA_F_TENTATIVE)
2721 continue;
2722
2723 /* Flag it for later restoration when link comes up */
2724 ifa->flags |= IFA_F_TENTATIVE;
2725 in6_ifa_hold(ifa);
2726 } else {
2727 ifa->dead = 1;
2728 }
2698 write_unlock_bh(&idev->lock); 2729 write_unlock_bh(&idev->lock);
2699 2730
2700 __ipv6_ifa_notify(RTM_DELADDR, ifa); 2731 __ipv6_ifa_notify(RTM_DELADDR, ifa);
@@ -2703,6 +2734,9 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2703 2734
2704 write_lock_bh(&idev->lock); 2735 write_lock_bh(&idev->lock);
2705 } 2736 }
2737
2738 idev->addr_list = keep_list;
2739
2706 write_unlock_bh(&idev->lock); 2740 write_unlock_bh(&idev->lock);
2707 2741
2708 /* Step 5: Discard multicast list */ 2742 /* Step 5: Discard multicast list */
@@ -2728,28 +2762,29 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2728static void addrconf_rs_timer(unsigned long data) 2762static void addrconf_rs_timer(unsigned long data)
2729{ 2763{
2730 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data; 2764 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data;
2765 struct inet6_dev *idev = ifp->idev;
2731 2766
2732 if (ifp->idev->cnf.forwarding) 2767 read_lock(&idev->lock);
2768 if (idev->dead || !(idev->if_flags & IF_READY))
2733 goto out; 2769 goto out;
2734 2770
2735 if (ifp->idev->if_flags & IF_RA_RCVD) { 2771 if (idev->cnf.forwarding)
2736 /* 2772 goto out;
2737 * Announcement received after solicitation 2773
2738 * was sent 2774 /* Announcement received after solicitation was sent */
2739 */ 2775 if (idev->if_flags & IF_RA_RCVD)
2740 goto out; 2776 goto out;
2741 }
2742 2777
2743 spin_lock(&ifp->lock); 2778 spin_lock(&ifp->lock);
2744 if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) { 2779 if (ifp->probes++ < idev->cnf.rtr_solicits) {
2745 /* The wait after the last probe can be shorter */ 2780 /* The wait after the last probe can be shorter */
2746 addrconf_mod_timer(ifp, AC_RS, 2781 addrconf_mod_timer(ifp, AC_RS,
2747 (ifp->probes == ifp->idev->cnf.rtr_solicits) ? 2782 (ifp->probes == idev->cnf.rtr_solicits) ?
2748 ifp->idev->cnf.rtr_solicit_delay : 2783 idev->cnf.rtr_solicit_delay :
2749 ifp->idev->cnf.rtr_solicit_interval); 2784 idev->cnf.rtr_solicit_interval);
2750 spin_unlock(&ifp->lock); 2785 spin_unlock(&ifp->lock);
2751 2786
2752 ndisc_send_rs(ifp->idev->dev, &ifp->addr, &in6addr_linklocal_allrouters); 2787 ndisc_send_rs(idev->dev, &ifp->addr, &in6addr_linklocal_allrouters);
2753 } else { 2788 } else {
2754 spin_unlock(&ifp->lock); 2789 spin_unlock(&ifp->lock);
2755 /* 2790 /*
@@ -2757,10 +2792,11 @@ static void addrconf_rs_timer(unsigned long data)
2757 * assumption any longer. 2792 * assumption any longer.
2758 */ 2793 */
2759 printk(KERN_DEBUG "%s: no IPv6 routers present\n", 2794 printk(KERN_DEBUG "%s: no IPv6 routers present\n",
2760 ifp->idev->dev->name); 2795 idev->dev->name);
2761 } 2796 }
2762 2797
2763out: 2798out:
2799 read_unlock(&idev->lock);
2764 in6_ifa_put(ifp); 2800 in6_ifa_put(ifp);
2765} 2801}
2766 2802
@@ -2793,14 +2829,14 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2793 read_lock_bh(&idev->lock); 2829 read_lock_bh(&idev->lock);
2794 if (ifp->dead) 2830 if (ifp->dead)
2795 goto out; 2831 goto out;
2796 spin_lock_bh(&ifp->lock);
2797 2832
2833 spin_lock(&ifp->lock);
2798 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || 2834 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
2799 idev->cnf.accept_dad < 1 || 2835 idev->cnf.accept_dad < 1 ||
2800 !(ifp->flags&IFA_F_TENTATIVE) || 2836 !(ifp->flags&IFA_F_TENTATIVE) ||
2801 ifp->flags & IFA_F_NODAD) { 2837 ifp->flags & IFA_F_NODAD) {
2802 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); 2838 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
2803 spin_unlock_bh(&ifp->lock); 2839 spin_unlock(&ifp->lock);
2804 read_unlock_bh(&idev->lock); 2840 read_unlock_bh(&idev->lock);
2805 2841
2806 addrconf_dad_completed(ifp); 2842 addrconf_dad_completed(ifp);
@@ -2808,7 +2844,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2808 } 2844 }
2809 2845
2810 if (!(idev->if_flags & IF_READY)) { 2846 if (!(idev->if_flags & IF_READY)) {
2811 spin_unlock_bh(&ifp->lock); 2847 spin_unlock(&ifp->lock);
2812 read_unlock_bh(&idev->lock); 2848 read_unlock_bh(&idev->lock);
2813 /* 2849 /*
2814 * If the device is not ready: 2850 * If the device is not ready:
@@ -2828,7 +2864,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2828 ip6_ins_rt(ifp->rt); 2864 ip6_ins_rt(ifp->rt);
2829 2865
2830 addrconf_dad_kick(ifp); 2866 addrconf_dad_kick(ifp);
2831 spin_unlock_bh(&ifp->lock); 2867 spin_unlock(&ifp->lock);
2832out: 2868out:
2833 read_unlock_bh(&idev->lock); 2869 read_unlock_bh(&idev->lock);
2834} 2870}
@@ -2839,20 +2875,21 @@ static void addrconf_dad_timer(unsigned long data)
2839 struct inet6_dev *idev = ifp->idev; 2875 struct inet6_dev *idev = ifp->idev;
2840 struct in6_addr mcaddr; 2876 struct in6_addr mcaddr;
2841 2877
2842 read_lock_bh(&idev->lock); 2878 read_lock(&idev->lock);
2843 if (idev->dead) { 2879 if (idev->dead || !(idev->if_flags & IF_READY)) {
2844 read_unlock_bh(&idev->lock); 2880 read_unlock(&idev->lock);
2845 goto out; 2881 goto out;
2846 } 2882 }
2847 spin_lock_bh(&ifp->lock); 2883
2884 spin_lock(&ifp->lock);
2848 if (ifp->probes == 0) { 2885 if (ifp->probes == 0) {
2849 /* 2886 /*
2850 * DAD was successful 2887 * DAD was successful
2851 */ 2888 */
2852 2889
2853 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); 2890 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
2854 spin_unlock_bh(&ifp->lock); 2891 spin_unlock(&ifp->lock);
2855 read_unlock_bh(&idev->lock); 2892 read_unlock(&idev->lock);
2856 2893
2857 addrconf_dad_completed(ifp); 2894 addrconf_dad_completed(ifp);
2858 2895
@@ -2861,8 +2898,8 @@ static void addrconf_dad_timer(unsigned long data)
2861 2898
2862 ifp->probes--; 2899 ifp->probes--;
2863 addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time); 2900 addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time);
2864 spin_unlock_bh(&ifp->lock); 2901 spin_unlock(&ifp->lock);
2865 read_unlock_bh(&idev->lock); 2902 read_unlock(&idev->lock);
2866 2903
2867 /* send a neighbour solicitation for our addr */ 2904 /* send a neighbour solicitation for our addr */
2868 addrconf_addr_solict_mult(&ifp->addr, &mcaddr); 2905 addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
@@ -2909,12 +2946,12 @@ static void addrconf_dad_run(struct inet6_dev *idev) {
2909 2946
2910 read_lock_bh(&idev->lock); 2947 read_lock_bh(&idev->lock);
2911 for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) { 2948 for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) {
2912 spin_lock_bh(&ifp->lock); 2949 spin_lock(&ifp->lock);
2913 if (!(ifp->flags & IFA_F_TENTATIVE)) { 2950 if (!(ifp->flags & IFA_F_TENTATIVE)) {
2914 spin_unlock_bh(&ifp->lock); 2951 spin_unlock(&ifp->lock);
2915 continue; 2952 continue;
2916 } 2953 }
2917 spin_unlock_bh(&ifp->lock); 2954 spin_unlock(&ifp->lock);
2918 addrconf_dad_kick(ifp); 2955 addrconf_dad_kick(ifp);
2919 } 2956 }
2920 read_unlock_bh(&idev->lock); 2957 read_unlock_bh(&idev->lock);
@@ -3031,14 +3068,14 @@ static const struct file_operations if6_fops = {
3031 .release = seq_release_net, 3068 .release = seq_release_net,
3032}; 3069};
3033 3070
3034static int if6_proc_net_init(struct net *net) 3071static int __net_init if6_proc_net_init(struct net *net)
3035{ 3072{
3036 if (!proc_net_fops_create(net, "if_inet6", S_IRUGO, &if6_fops)) 3073 if (!proc_net_fops_create(net, "if_inet6", S_IRUGO, &if6_fops))
3037 return -ENOMEM; 3074 return -ENOMEM;
3038 return 0; 3075 return 0;
3039} 3076}
3040 3077
3041static void if6_proc_net_exit(struct net *net) 3078static void __net_exit if6_proc_net_exit(struct net *net)
3042{ 3079{
3043 proc_net_remove(net, "if_inet6"); 3080 proc_net_remove(net, "if_inet6");
3044} 3081}
@@ -3485,85 +3522,114 @@ enum addr_type_t
3485 ANYCAST_ADDR, 3522 ANYCAST_ADDR,
3486}; 3523};
3487 3524
3525/* called with rcu_read_lock() */
3526static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3527 struct netlink_callback *cb, enum addr_type_t type,
3528 int s_ip_idx, int *p_ip_idx)
3529{
3530 struct inet6_ifaddr *ifa;
3531 struct ifmcaddr6 *ifmca;
3532 struct ifacaddr6 *ifaca;
3533 int err = 1;
3534 int ip_idx = *p_ip_idx;
3535
3536 read_lock_bh(&idev->lock);
3537 switch (type) {
3538 case UNICAST_ADDR:
3539 /* unicast address incl. temp addr */
3540 for (ifa = idev->addr_list; ifa;
3541 ifa = ifa->if_next, ip_idx++) {
3542 if (ip_idx < s_ip_idx)
3543 continue;
3544 err = inet6_fill_ifaddr(skb, ifa,
3545 NETLINK_CB(cb->skb).pid,
3546 cb->nlh->nlmsg_seq,
3547 RTM_NEWADDR,
3548 NLM_F_MULTI);
3549 if (err <= 0)
3550 break;
3551 }
3552 break;
3553 case MULTICAST_ADDR:
3554 /* multicast address */
3555 for (ifmca = idev->mc_list; ifmca;
3556 ifmca = ifmca->next, ip_idx++) {
3557 if (ip_idx < s_ip_idx)
3558 continue;
3559 err = inet6_fill_ifmcaddr(skb, ifmca,
3560 NETLINK_CB(cb->skb).pid,
3561 cb->nlh->nlmsg_seq,
3562 RTM_GETMULTICAST,
3563 NLM_F_MULTI);
3564 if (err <= 0)
3565 break;
3566 }
3567 break;
3568 case ANYCAST_ADDR:
3569 /* anycast address */
3570 for (ifaca = idev->ac_list; ifaca;
3571 ifaca = ifaca->aca_next, ip_idx++) {
3572 if (ip_idx < s_ip_idx)
3573 continue;
3574 err = inet6_fill_ifacaddr(skb, ifaca,
3575 NETLINK_CB(cb->skb).pid,
3576 cb->nlh->nlmsg_seq,
3577 RTM_GETANYCAST,
3578 NLM_F_MULTI);
3579 if (err <= 0)
3580 break;
3581 }
3582 break;
3583 default:
3584 break;
3585 }
3586 read_unlock_bh(&idev->lock);
3587 *p_ip_idx = ip_idx;
3588 return err;
3589}
3590
3488static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, 3591static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
3489 enum addr_type_t type) 3592 enum addr_type_t type)
3490{ 3593{
3594 struct net *net = sock_net(skb->sk);
3595 int h, s_h;
3491 int idx, ip_idx; 3596 int idx, ip_idx;
3492 int s_idx, s_ip_idx; 3597 int s_idx, s_ip_idx;
3493 int err = 1;
3494 struct net_device *dev; 3598 struct net_device *dev;
3495 struct inet6_dev *idev = NULL; 3599 struct inet6_dev *idev;
3496 struct inet6_ifaddr *ifa; 3600 struct hlist_head *head;
3497 struct ifmcaddr6 *ifmca; 3601 struct hlist_node *node;
3498 struct ifacaddr6 *ifaca;
3499 struct net *net = sock_net(skb->sk);
3500 3602
3501 s_idx = cb->args[0]; 3603 s_h = cb->args[0];
3502 s_ip_idx = ip_idx = cb->args[1]; 3604 s_idx = idx = cb->args[1];
3605 s_ip_idx = ip_idx = cb->args[2];
3503 3606
3504 idx = 0; 3607 rcu_read_lock();
3505 for_each_netdev(net, dev) { 3608 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
3506 if (idx < s_idx) 3609 idx = 0;
3507 goto cont; 3610 head = &net->dev_index_head[h];
3508 if (idx > s_idx) 3611 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
3509 s_ip_idx = 0; 3612 if (idx < s_idx)
3510 ip_idx = 0; 3613 goto cont;
3511 if ((idev = in6_dev_get(dev)) == NULL) 3614 if (h > s_h || idx > s_idx)
3512 goto cont; 3615 s_ip_idx = 0;
3513 read_lock_bh(&idev->lock); 3616 ip_idx = 0;
3514 switch (type) { 3617 if ((idev = __in6_dev_get(dev)) == NULL)
3515 case UNICAST_ADDR: 3618 goto cont;
3516 /* unicast address incl. temp addr */ 3619
3517 for (ifa = idev->addr_list; ifa; 3620 if (in6_dump_addrs(idev, skb, cb, type,
3518 ifa = ifa->if_next, ip_idx++) { 3621 s_ip_idx, &ip_idx) <= 0)
3519 if (ip_idx < s_ip_idx) 3622 goto done;
3520 continue;
3521 err = inet6_fill_ifaddr(skb, ifa,
3522 NETLINK_CB(cb->skb).pid,
3523 cb->nlh->nlmsg_seq,
3524 RTM_NEWADDR,
3525 NLM_F_MULTI);
3526 }
3527 break;
3528 case MULTICAST_ADDR:
3529 /* multicast address */
3530 for (ifmca = idev->mc_list; ifmca;
3531 ifmca = ifmca->next, ip_idx++) {
3532 if (ip_idx < s_ip_idx)
3533 continue;
3534 err = inet6_fill_ifmcaddr(skb, ifmca,
3535 NETLINK_CB(cb->skb).pid,
3536 cb->nlh->nlmsg_seq,
3537 RTM_GETMULTICAST,
3538 NLM_F_MULTI);
3539 }
3540 break;
3541 case ANYCAST_ADDR:
3542 /* anycast address */
3543 for (ifaca = idev->ac_list; ifaca;
3544 ifaca = ifaca->aca_next, ip_idx++) {
3545 if (ip_idx < s_ip_idx)
3546 continue;
3547 err = inet6_fill_ifacaddr(skb, ifaca,
3548 NETLINK_CB(cb->skb).pid,
3549 cb->nlh->nlmsg_seq,
3550 RTM_GETANYCAST,
3551 NLM_F_MULTI);
3552 }
3553 break;
3554 default:
3555 break;
3556 }
3557 read_unlock_bh(&idev->lock);
3558 in6_dev_put(idev);
3559
3560 if (err <= 0)
3561 break;
3562cont: 3623cont:
3563 idx++; 3624 idx++;
3625 }
3564 } 3626 }
3565 cb->args[0] = idx; 3627done:
3566 cb->args[1] = ip_idx; 3628 rcu_read_unlock();
3629 cb->args[0] = h;
3630 cb->args[1] = idx;
3631 cb->args[2] = ip_idx;
3632
3567 return skb->len; 3633 return skb->len;
3568} 3634}
3569 3635
@@ -3708,6 +3774,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
3708#endif 3774#endif
3709 array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6; 3775 array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
3710 array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad; 3776 array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
3777 array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
3711} 3778}
3712 3779
3713static inline size_t inet6_if_nlmsg_size(void) 3780static inline size_t inet6_if_nlmsg_size(void)
@@ -3726,8 +3793,8 @@ static inline size_t inet6_if_nlmsg_size(void)
3726 ); 3793 );
3727} 3794}
3728 3795
3729static inline void __snmp6_fill_stats(u64 *stats, void **mib, int items, 3796static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,
3730 int bytes) 3797 int items, int bytes)
3731{ 3798{
3732 int i; 3799 int i;
3733 int pad = bytes - sizeof(u64) * items; 3800 int pad = bytes - sizeof(u64) * items;
@@ -3746,10 +3813,10 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
3746{ 3813{
3747 switch(attrtype) { 3814 switch(attrtype) {
3748 case IFLA_INET6_STATS: 3815 case IFLA_INET6_STATS:
3749 __snmp6_fill_stats(stats, (void **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes); 3816 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
3750 break; 3817 break;
3751 case IFLA_INET6_ICMP6STATS: 3818 case IFLA_INET6_ICMP6STATS:
3752 __snmp6_fill_stats(stats, (void **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes); 3819 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
3753 break; 3820 break;
3754 } 3821 }
3755} 3822}
@@ -3826,28 +3893,39 @@ nla_put_failure:
3826static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 3893static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
3827{ 3894{
3828 struct net *net = sock_net(skb->sk); 3895 struct net *net = sock_net(skb->sk);
3829 int idx, err; 3896 int h, s_h;
3830 int s_idx = cb->args[0]; 3897 int idx = 0, s_idx;
3831 struct net_device *dev; 3898 struct net_device *dev;
3832 struct inet6_dev *idev; 3899 struct inet6_dev *idev;
3900 struct hlist_head *head;
3901 struct hlist_node *node;
3833 3902
3834 read_lock(&dev_base_lock); 3903 s_h = cb->args[0];
3835 idx = 0; 3904 s_idx = cb->args[1];
3836 for_each_netdev(net, dev) { 3905
3837 if (idx < s_idx) 3906 rcu_read_lock();
3838 goto cont; 3907 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
3839 if ((idev = in6_dev_get(dev)) == NULL) 3908 idx = 0;
3840 goto cont; 3909 head = &net->dev_index_head[h];
3841 err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, 3910 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
3842 cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI); 3911 if (idx < s_idx)
3843 in6_dev_put(idev); 3912 goto cont;
3844 if (err <= 0) 3913 idev = __in6_dev_get(dev);
3845 break; 3914 if (!idev)
3915 goto cont;
3916 if (inet6_fill_ifinfo(skb, idev,
3917 NETLINK_CB(cb->skb).pid,
3918 cb->nlh->nlmsg_seq,
3919 RTM_NEWLINK, NLM_F_MULTI) <= 0)
3920 goto out;
3846cont: 3921cont:
3847 idx++; 3922 idx++;
3923 }
3848 } 3924 }
3849 read_unlock(&dev_base_lock); 3925out:
3850 cb->args[0] = idx; 3926 rcu_read_unlock();
3927 cb->args[1] = idx;
3928 cb->args[0] = h;
3851 3929
3852 return skb->len; 3930 return skb->len;
3853} 3931}
@@ -3991,50 +4069,18 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write,
3991{ 4069{
3992 int *valp = ctl->data; 4070 int *valp = ctl->data;
3993 int val = *valp; 4071 int val = *valp;
4072 loff_t pos = *ppos;
3994 int ret; 4073 int ret;
3995 4074
3996 ret = proc_dointvec(ctl, write, buffer, lenp, ppos); 4075 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
3997 4076
3998 if (write) 4077 if (write)
3999 ret = addrconf_fixup_forwarding(ctl, valp, val); 4078 ret = addrconf_fixup_forwarding(ctl, valp, val);
4079 if (ret)
4080 *ppos = pos;
4000 return ret; 4081 return ret;
4001} 4082}
4002 4083
4003static int addrconf_sysctl_forward_strategy(ctl_table *table,
4004 void __user *oldval,
4005 size_t __user *oldlenp,
4006 void __user *newval, size_t newlen)
4007{
4008 int *valp = table->data;
4009 int val = *valp;
4010 int new;
4011
4012 if (!newval || !newlen)
4013 return 0;
4014 if (newlen != sizeof(int))
4015 return -EINVAL;
4016 if (get_user(new, (int __user *)newval))
4017 return -EFAULT;
4018 if (new == *valp)
4019 return 0;
4020 if (oldval && oldlenp) {
4021 size_t len;
4022 if (get_user(len, oldlenp))
4023 return -EFAULT;
4024 if (len) {
4025 if (len > table->maxlen)
4026 len = table->maxlen;
4027 if (copy_to_user(oldval, valp, len))
4028 return -EFAULT;
4029 if (put_user(len, oldlenp))
4030 return -EFAULT;
4031 }
4032 }
4033
4034 *valp = new;
4035 return addrconf_fixup_forwarding(table, valp, val);
4036}
4037
4038static void dev_disable_change(struct inet6_dev *idev) 4084static void dev_disable_change(struct inet6_dev *idev)
4039{ 4085{
4040 if (!idev || !idev->dev) 4086 if (!idev || !idev->dev)
@@ -4051,9 +4097,8 @@ static void addrconf_disable_change(struct net *net, __s32 newf)
4051 struct net_device *dev; 4097 struct net_device *dev;
4052 struct inet6_dev *idev; 4098 struct inet6_dev *idev;
4053 4099
4054 read_lock(&dev_base_lock); 4100 rcu_read_lock();
4055 for_each_netdev(net, dev) { 4101 for_each_netdev_rcu(net, dev) {
4056 rcu_read_lock();
4057 idev = __in6_dev_get(dev); 4102 idev = __in6_dev_get(dev);
4058 if (idev) { 4103 if (idev) {
4059 int changed = (!idev->cnf.disable_ipv6) ^ (!newf); 4104 int changed = (!idev->cnf.disable_ipv6) ^ (!newf);
@@ -4061,9 +4106,8 @@ static void addrconf_disable_change(struct net *net, __s32 newf)
4061 if (changed) 4106 if (changed)
4062 dev_disable_change(idev); 4107 dev_disable_change(idev);
4063 } 4108 }
4064 rcu_read_unlock();
4065 } 4109 }
4066 read_unlock(&dev_base_lock); 4110 rcu_read_unlock();
4067} 4111}
4068 4112
4069static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old) 4113static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
@@ -4075,8 +4119,11 @@ static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
4075 if (p == &net->ipv6.devconf_dflt->disable_ipv6) 4119 if (p == &net->ipv6.devconf_dflt->disable_ipv6)
4076 return 0; 4120 return 0;
4077 4121
4078 if (!rtnl_trylock()) 4122 if (!rtnl_trylock()) {
4123 /* Restore the original values before restarting */
4124 *p = old;
4079 return restart_syscall(); 4125 return restart_syscall();
4126 }
4080 4127
4081 if (p == &net->ipv6.devconf_all->disable_ipv6) { 4128 if (p == &net->ipv6.devconf_all->disable_ipv6) {
4082 __s32 newf = net->ipv6.devconf_all->disable_ipv6; 4129 __s32 newf = net->ipv6.devconf_all->disable_ipv6;
@@ -4095,12 +4142,15 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write,
4095{ 4142{
4096 int *valp = ctl->data; 4143 int *valp = ctl->data;
4097 int val = *valp; 4144 int val = *valp;
4145 loff_t pos = *ppos;
4098 int ret; 4146 int ret;
4099 4147
4100 ret = proc_dointvec(ctl, write, buffer, lenp, ppos); 4148 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
4101 4149
4102 if (write) 4150 if (write)
4103 ret = addrconf_disable_ipv6(ctl, valp, val); 4151 ret = addrconf_disable_ipv6(ctl, valp, val);
4152 if (ret)
4153 *ppos = pos;
4104 return ret; 4154 return ret;
4105} 4155}
4106 4156
@@ -4113,16 +4163,13 @@ static struct addrconf_sysctl_table
4113 .sysctl_header = NULL, 4163 .sysctl_header = NULL,
4114 .addrconf_vars = { 4164 .addrconf_vars = {
4115 { 4165 {
4116 .ctl_name = NET_IPV6_FORWARDING,
4117 .procname = "forwarding", 4166 .procname = "forwarding",
4118 .data = &ipv6_devconf.forwarding, 4167 .data = &ipv6_devconf.forwarding,
4119 .maxlen = sizeof(int), 4168 .maxlen = sizeof(int),
4120 .mode = 0644, 4169 .mode = 0644,
4121 .proc_handler = addrconf_sysctl_forward, 4170 .proc_handler = addrconf_sysctl_forward,
4122 .strategy = addrconf_sysctl_forward_strategy,
4123 }, 4171 },
4124 { 4172 {
4125 .ctl_name = NET_IPV6_HOP_LIMIT,
4126 .procname = "hop_limit", 4173 .procname = "hop_limit",
4127 .data = &ipv6_devconf.hop_limit, 4174 .data = &ipv6_devconf.hop_limit,
4128 .maxlen = sizeof(int), 4175 .maxlen = sizeof(int),
@@ -4130,7 +4177,6 @@ static struct addrconf_sysctl_table
4130 .proc_handler = proc_dointvec, 4177 .proc_handler = proc_dointvec,
4131 }, 4178 },
4132 { 4179 {
4133 .ctl_name = NET_IPV6_MTU,
4134 .procname = "mtu", 4180 .procname = "mtu",
4135 .data = &ipv6_devconf.mtu6, 4181 .data = &ipv6_devconf.mtu6,
4136 .maxlen = sizeof(int), 4182 .maxlen = sizeof(int),
@@ -4138,7 +4184,6 @@ static struct addrconf_sysctl_table
4138 .proc_handler = proc_dointvec, 4184 .proc_handler = proc_dointvec,
4139 }, 4185 },
4140 { 4186 {
4141 .ctl_name = NET_IPV6_ACCEPT_RA,
4142 .procname = "accept_ra", 4187 .procname = "accept_ra",
4143 .data = &ipv6_devconf.accept_ra, 4188 .data = &ipv6_devconf.accept_ra,
4144 .maxlen = sizeof(int), 4189 .maxlen = sizeof(int),
@@ -4146,7 +4191,6 @@ static struct addrconf_sysctl_table
4146 .proc_handler = proc_dointvec, 4191 .proc_handler = proc_dointvec,
4147 }, 4192 },
4148 { 4193 {
4149 .ctl_name = NET_IPV6_ACCEPT_REDIRECTS,
4150 .procname = "accept_redirects", 4194 .procname = "accept_redirects",
4151 .data = &ipv6_devconf.accept_redirects, 4195 .data = &ipv6_devconf.accept_redirects,
4152 .maxlen = sizeof(int), 4196 .maxlen = sizeof(int),
@@ -4154,7 +4198,6 @@ static struct addrconf_sysctl_table
4154 .proc_handler = proc_dointvec, 4198 .proc_handler = proc_dointvec,
4155 }, 4199 },
4156 { 4200 {
4157 .ctl_name = NET_IPV6_AUTOCONF,
4158 .procname = "autoconf", 4201 .procname = "autoconf",
4159 .data = &ipv6_devconf.autoconf, 4202 .data = &ipv6_devconf.autoconf,
4160 .maxlen = sizeof(int), 4203 .maxlen = sizeof(int),
@@ -4162,7 +4205,6 @@ static struct addrconf_sysctl_table
4162 .proc_handler = proc_dointvec, 4205 .proc_handler = proc_dointvec,
4163 }, 4206 },
4164 { 4207 {
4165 .ctl_name = NET_IPV6_DAD_TRANSMITS,
4166 .procname = "dad_transmits", 4208 .procname = "dad_transmits",
4167 .data = &ipv6_devconf.dad_transmits, 4209 .data = &ipv6_devconf.dad_transmits,
4168 .maxlen = sizeof(int), 4210 .maxlen = sizeof(int),
@@ -4170,7 +4212,6 @@ static struct addrconf_sysctl_table
4170 .proc_handler = proc_dointvec, 4212 .proc_handler = proc_dointvec,
4171 }, 4213 },
4172 { 4214 {
4173 .ctl_name = NET_IPV6_RTR_SOLICITS,
4174 .procname = "router_solicitations", 4215 .procname = "router_solicitations",
4175 .data = &ipv6_devconf.rtr_solicits, 4216 .data = &ipv6_devconf.rtr_solicits,
4176 .maxlen = sizeof(int), 4217 .maxlen = sizeof(int),
@@ -4178,25 +4219,20 @@ static struct addrconf_sysctl_table
4178 .proc_handler = proc_dointvec, 4219 .proc_handler = proc_dointvec,
4179 }, 4220 },
4180 { 4221 {
4181 .ctl_name = NET_IPV6_RTR_SOLICIT_INTERVAL,
4182 .procname = "router_solicitation_interval", 4222 .procname = "router_solicitation_interval",
4183 .data = &ipv6_devconf.rtr_solicit_interval, 4223 .data = &ipv6_devconf.rtr_solicit_interval,
4184 .maxlen = sizeof(int), 4224 .maxlen = sizeof(int),
4185 .mode = 0644, 4225 .mode = 0644,
4186 .proc_handler = proc_dointvec_jiffies, 4226 .proc_handler = proc_dointvec_jiffies,
4187 .strategy = sysctl_jiffies,
4188 }, 4227 },
4189 { 4228 {
4190 .ctl_name = NET_IPV6_RTR_SOLICIT_DELAY,
4191 .procname = "router_solicitation_delay", 4229 .procname = "router_solicitation_delay",
4192 .data = &ipv6_devconf.rtr_solicit_delay, 4230 .data = &ipv6_devconf.rtr_solicit_delay,
4193 .maxlen = sizeof(int), 4231 .maxlen = sizeof(int),
4194 .mode = 0644, 4232 .mode = 0644,
4195 .proc_handler = proc_dointvec_jiffies, 4233 .proc_handler = proc_dointvec_jiffies,
4196 .strategy = sysctl_jiffies,
4197 }, 4234 },
4198 { 4235 {
4199 .ctl_name = NET_IPV6_FORCE_MLD_VERSION,
4200 .procname = "force_mld_version", 4236 .procname = "force_mld_version",
4201 .data = &ipv6_devconf.force_mld_version, 4237 .data = &ipv6_devconf.force_mld_version,
4202 .maxlen = sizeof(int), 4238 .maxlen = sizeof(int),
@@ -4205,7 +4241,6 @@ static struct addrconf_sysctl_table
4205 }, 4241 },
4206#ifdef CONFIG_IPV6_PRIVACY 4242#ifdef CONFIG_IPV6_PRIVACY
4207 { 4243 {
4208 .ctl_name = NET_IPV6_USE_TEMPADDR,
4209 .procname = "use_tempaddr", 4244 .procname = "use_tempaddr",
4210 .data = &ipv6_devconf.use_tempaddr, 4245 .data = &ipv6_devconf.use_tempaddr,
4211 .maxlen = sizeof(int), 4246 .maxlen = sizeof(int),
@@ -4213,7 +4248,6 @@ static struct addrconf_sysctl_table
4213 .proc_handler = proc_dointvec, 4248 .proc_handler = proc_dointvec,
4214 }, 4249 },
4215 { 4250 {
4216 .ctl_name = NET_IPV6_TEMP_VALID_LFT,
4217 .procname = "temp_valid_lft", 4251 .procname = "temp_valid_lft",
4218 .data = &ipv6_devconf.temp_valid_lft, 4252 .data = &ipv6_devconf.temp_valid_lft,
4219 .maxlen = sizeof(int), 4253 .maxlen = sizeof(int),
@@ -4221,7 +4255,6 @@ static struct addrconf_sysctl_table
4221 .proc_handler = proc_dointvec, 4255 .proc_handler = proc_dointvec,
4222 }, 4256 },
4223 { 4257 {
4224 .ctl_name = NET_IPV6_TEMP_PREFERED_LFT,
4225 .procname = "temp_prefered_lft", 4258 .procname = "temp_prefered_lft",
4226 .data = &ipv6_devconf.temp_prefered_lft, 4259 .data = &ipv6_devconf.temp_prefered_lft,
4227 .maxlen = sizeof(int), 4260 .maxlen = sizeof(int),
@@ -4229,7 +4262,6 @@ static struct addrconf_sysctl_table
4229 .proc_handler = proc_dointvec, 4262 .proc_handler = proc_dointvec,
4230 }, 4263 },
4231 { 4264 {
4232 .ctl_name = NET_IPV6_REGEN_MAX_RETRY,
4233 .procname = "regen_max_retry", 4265 .procname = "regen_max_retry",
4234 .data = &ipv6_devconf.regen_max_retry, 4266 .data = &ipv6_devconf.regen_max_retry,
4235 .maxlen = sizeof(int), 4267 .maxlen = sizeof(int),
@@ -4237,7 +4269,6 @@ static struct addrconf_sysctl_table
4237 .proc_handler = proc_dointvec, 4269 .proc_handler = proc_dointvec,
4238 }, 4270 },
4239 { 4271 {
4240 .ctl_name = NET_IPV6_MAX_DESYNC_FACTOR,
4241 .procname = "max_desync_factor", 4272 .procname = "max_desync_factor",
4242 .data = &ipv6_devconf.max_desync_factor, 4273 .data = &ipv6_devconf.max_desync_factor,
4243 .maxlen = sizeof(int), 4274 .maxlen = sizeof(int),
@@ -4246,7 +4277,6 @@ static struct addrconf_sysctl_table
4246 }, 4277 },
4247#endif 4278#endif
4248 { 4279 {
4249 .ctl_name = NET_IPV6_MAX_ADDRESSES,
4250 .procname = "max_addresses", 4280 .procname = "max_addresses",
4251 .data = &ipv6_devconf.max_addresses, 4281 .data = &ipv6_devconf.max_addresses,
4252 .maxlen = sizeof(int), 4282 .maxlen = sizeof(int),
@@ -4254,7 +4284,6 @@ static struct addrconf_sysctl_table
4254 .proc_handler = proc_dointvec, 4284 .proc_handler = proc_dointvec,
4255 }, 4285 },
4256 { 4286 {
4257 .ctl_name = NET_IPV6_ACCEPT_RA_DEFRTR,
4258 .procname = "accept_ra_defrtr", 4287 .procname = "accept_ra_defrtr",
4259 .data = &ipv6_devconf.accept_ra_defrtr, 4288 .data = &ipv6_devconf.accept_ra_defrtr,
4260 .maxlen = sizeof(int), 4289 .maxlen = sizeof(int),
@@ -4262,7 +4291,6 @@ static struct addrconf_sysctl_table
4262 .proc_handler = proc_dointvec, 4291 .proc_handler = proc_dointvec,
4263 }, 4292 },
4264 { 4293 {
4265 .ctl_name = NET_IPV6_ACCEPT_RA_PINFO,
4266 .procname = "accept_ra_pinfo", 4294 .procname = "accept_ra_pinfo",
4267 .data = &ipv6_devconf.accept_ra_pinfo, 4295 .data = &ipv6_devconf.accept_ra_pinfo,
4268 .maxlen = sizeof(int), 4296 .maxlen = sizeof(int),
@@ -4271,7 +4299,6 @@ static struct addrconf_sysctl_table
4271 }, 4299 },
4272#ifdef CONFIG_IPV6_ROUTER_PREF 4300#ifdef CONFIG_IPV6_ROUTER_PREF
4273 { 4301 {
4274 .ctl_name = NET_IPV6_ACCEPT_RA_RTR_PREF,
4275 .procname = "accept_ra_rtr_pref", 4302 .procname = "accept_ra_rtr_pref",
4276 .data = &ipv6_devconf.accept_ra_rtr_pref, 4303 .data = &ipv6_devconf.accept_ra_rtr_pref,
4277 .maxlen = sizeof(int), 4304 .maxlen = sizeof(int),
@@ -4279,17 +4306,14 @@ static struct addrconf_sysctl_table
4279 .proc_handler = proc_dointvec, 4306 .proc_handler = proc_dointvec,
4280 }, 4307 },
4281 { 4308 {
4282 .ctl_name = NET_IPV6_RTR_PROBE_INTERVAL,
4283 .procname = "router_probe_interval", 4309 .procname = "router_probe_interval",
4284 .data = &ipv6_devconf.rtr_probe_interval, 4310 .data = &ipv6_devconf.rtr_probe_interval,
4285 .maxlen = sizeof(int), 4311 .maxlen = sizeof(int),
4286 .mode = 0644, 4312 .mode = 0644,
4287 .proc_handler = proc_dointvec_jiffies, 4313 .proc_handler = proc_dointvec_jiffies,
4288 .strategy = sysctl_jiffies,
4289 }, 4314 },
4290#ifdef CONFIG_IPV6_ROUTE_INFO 4315#ifdef CONFIG_IPV6_ROUTE_INFO
4291 { 4316 {
4292 .ctl_name = NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN,
4293 .procname = "accept_ra_rt_info_max_plen", 4317 .procname = "accept_ra_rt_info_max_plen",
4294 .data = &ipv6_devconf.accept_ra_rt_info_max_plen, 4318 .data = &ipv6_devconf.accept_ra_rt_info_max_plen,
4295 .maxlen = sizeof(int), 4319 .maxlen = sizeof(int),
@@ -4299,7 +4323,6 @@ static struct addrconf_sysctl_table
4299#endif 4323#endif
4300#endif 4324#endif
4301 { 4325 {
4302 .ctl_name = NET_IPV6_PROXY_NDP,
4303 .procname = "proxy_ndp", 4326 .procname = "proxy_ndp",
4304 .data = &ipv6_devconf.proxy_ndp, 4327 .data = &ipv6_devconf.proxy_ndp,
4305 .maxlen = sizeof(int), 4328 .maxlen = sizeof(int),
@@ -4307,7 +4330,6 @@ static struct addrconf_sysctl_table
4307 .proc_handler = proc_dointvec, 4330 .proc_handler = proc_dointvec,
4308 }, 4331 },
4309 { 4332 {
4310 .ctl_name = NET_IPV6_ACCEPT_SOURCE_ROUTE,
4311 .procname = "accept_source_route", 4333 .procname = "accept_source_route",
4312 .data = &ipv6_devconf.accept_source_route, 4334 .data = &ipv6_devconf.accept_source_route,
4313 .maxlen = sizeof(int), 4335 .maxlen = sizeof(int),
@@ -4316,7 +4338,6 @@ static struct addrconf_sysctl_table
4316 }, 4338 },
4317#ifdef CONFIG_IPV6_OPTIMISTIC_DAD 4339#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
4318 { 4340 {
4319 .ctl_name = CTL_UNNUMBERED,
4320 .procname = "optimistic_dad", 4341 .procname = "optimistic_dad",
4321 .data = &ipv6_devconf.optimistic_dad, 4342 .data = &ipv6_devconf.optimistic_dad,
4322 .maxlen = sizeof(int), 4343 .maxlen = sizeof(int),
@@ -4327,7 +4348,6 @@ static struct addrconf_sysctl_table
4327#endif 4348#endif
4328#ifdef CONFIG_IPV6_MROUTE 4349#ifdef CONFIG_IPV6_MROUTE
4329 { 4350 {
4330 .ctl_name = CTL_UNNUMBERED,
4331 .procname = "mc_forwarding", 4351 .procname = "mc_forwarding",
4332 .data = &ipv6_devconf.mc_forwarding, 4352 .data = &ipv6_devconf.mc_forwarding,
4333 .maxlen = sizeof(int), 4353 .maxlen = sizeof(int),
@@ -4336,16 +4356,13 @@ static struct addrconf_sysctl_table
4336 }, 4356 },
4337#endif 4357#endif
4338 { 4358 {
4339 .ctl_name = CTL_UNNUMBERED,
4340 .procname = "disable_ipv6", 4359 .procname = "disable_ipv6",
4341 .data = &ipv6_devconf.disable_ipv6, 4360 .data = &ipv6_devconf.disable_ipv6,
4342 .maxlen = sizeof(int), 4361 .maxlen = sizeof(int),
4343 .mode = 0644, 4362 .mode = 0644,
4344 .proc_handler = addrconf_sysctl_disable, 4363 .proc_handler = addrconf_sysctl_disable,
4345 .strategy = sysctl_intvec,
4346 }, 4364 },
4347 { 4365 {
4348 .ctl_name = CTL_UNNUMBERED,
4349 .procname = "accept_dad", 4366 .procname = "accept_dad",
4350 .data = &ipv6_devconf.accept_dad, 4367 .data = &ipv6_devconf.accept_dad,
4351 .maxlen = sizeof(int), 4368 .maxlen = sizeof(int),
@@ -4353,13 +4370,20 @@ static struct addrconf_sysctl_table
4353 .proc_handler = proc_dointvec, 4370 .proc_handler = proc_dointvec,
4354 }, 4371 },
4355 { 4372 {
4356 .ctl_name = 0, /* sentinel */ 4373 .procname = "force_tllao",
4374 .data = &ipv6_devconf.force_tllao,
4375 .maxlen = sizeof(int),
4376 .mode = 0644,
4377 .proc_handler = proc_dointvec
4378 },
4379 {
4380 /* sentinel */
4357 } 4381 }
4358 }, 4382 },
4359}; 4383};
4360 4384
4361static int __addrconf_sysctl_register(struct net *net, char *dev_name, 4385static int __addrconf_sysctl_register(struct net *net, char *dev_name,
4362 int ctl_name, struct inet6_dev *idev, struct ipv6_devconf *p) 4386 struct inet6_dev *idev, struct ipv6_devconf *p)
4363{ 4387{
4364 int i; 4388 int i;
4365 struct addrconf_sysctl_table *t; 4389 struct addrconf_sysctl_table *t;
@@ -4367,9 +4391,9 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
4367#define ADDRCONF_CTL_PATH_DEV 3 4391#define ADDRCONF_CTL_PATH_DEV 3
4368 4392
4369 struct ctl_path addrconf_ctl_path[] = { 4393 struct ctl_path addrconf_ctl_path[] = {
4370 { .procname = "net", .ctl_name = CTL_NET, }, 4394 { .procname = "net", },
4371 { .procname = "ipv6", .ctl_name = NET_IPV6, }, 4395 { .procname = "ipv6", },
4372 { .procname = "conf", .ctl_name = NET_IPV6_CONF, }, 4396 { .procname = "conf", },
4373 { /* to be set */ }, 4397 { /* to be set */ },
4374 { }, 4398 { },
4375 }; 4399 };
@@ -4395,7 +4419,6 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
4395 goto free; 4419 goto free;
4396 4420
4397 addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].procname = t->dev_name; 4421 addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].procname = t->dev_name;
4398 addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].ctl_name = ctl_name;
4399 4422
4400 t->sysctl_header = register_net_sysctl_table(net, addrconf_ctl_path, 4423 t->sysctl_header = register_net_sysctl_table(net, addrconf_ctl_path,
4401 t->addrconf_vars); 4424 t->addrconf_vars);
@@ -4429,12 +4452,10 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
4429 4452
4430static void addrconf_sysctl_register(struct inet6_dev *idev) 4453static void addrconf_sysctl_register(struct inet6_dev *idev)
4431{ 4454{
4432 neigh_sysctl_register(idev->dev, idev->nd_parms, NET_IPV6, 4455 neigh_sysctl_register(idev->dev, idev->nd_parms, "ipv6",
4433 NET_IPV6_NEIGH, "ipv6", 4456 &ndisc_ifinfo_sysctl_change);
4434 &ndisc_ifinfo_sysctl_change,
4435 ndisc_ifinfo_sysctl_strategy);
4436 __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name, 4457 __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name,
4437 idev->dev->ifindex, idev, &idev->cnf); 4458 idev, &idev->cnf);
4438} 4459}
4439 4460
4440static void addrconf_sysctl_unregister(struct inet6_dev *idev) 4461static void addrconf_sysctl_unregister(struct inet6_dev *idev)
@@ -4446,7 +4467,7 @@ static void addrconf_sysctl_unregister(struct inet6_dev *idev)
4446 4467
4447#endif 4468#endif
4448 4469
4449static int addrconf_init_net(struct net *net) 4470static int __net_init addrconf_init_net(struct net *net)
4450{ 4471{
4451 int err; 4472 int err;
4452 struct ipv6_devconf *all, *dflt; 4473 struct ipv6_devconf *all, *dflt;
@@ -4455,7 +4476,7 @@ static int addrconf_init_net(struct net *net)
4455 all = &ipv6_devconf; 4476 all = &ipv6_devconf;
4456 dflt = &ipv6_devconf_dflt; 4477 dflt = &ipv6_devconf_dflt;
4457 4478
4458 if (net != &init_net) { 4479 if (!net_eq(net, &init_net)) {
4459 all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL); 4480 all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL);
4460 if (all == NULL) 4481 if (all == NULL)
4461 goto err_alloc_all; 4482 goto err_alloc_all;
@@ -4473,13 +4494,11 @@ static int addrconf_init_net(struct net *net)
4473 net->ipv6.devconf_dflt = dflt; 4494 net->ipv6.devconf_dflt = dflt;
4474 4495
4475#ifdef CONFIG_SYSCTL 4496#ifdef CONFIG_SYSCTL
4476 err = __addrconf_sysctl_register(net, "all", NET_PROTO_CONF_ALL, 4497 err = __addrconf_sysctl_register(net, "all", NULL, all);
4477 NULL, all);
4478 if (err < 0) 4498 if (err < 0)
4479 goto err_reg_all; 4499 goto err_reg_all;
4480 4500
4481 err = __addrconf_sysctl_register(net, "default", NET_PROTO_CONF_DEFAULT, 4501 err = __addrconf_sysctl_register(net, "default", NULL, dflt);
4482 NULL, dflt);
4483 if (err < 0) 4502 if (err < 0)
4484 goto err_reg_dflt; 4503 goto err_reg_dflt;
4485#endif 4504#endif
@@ -4497,13 +4516,13 @@ err_alloc_all:
4497 return err; 4516 return err;
4498} 4517}
4499 4518
4500static void addrconf_exit_net(struct net *net) 4519static void __net_exit addrconf_exit_net(struct net *net)
4501{ 4520{
4502#ifdef CONFIG_SYSCTL 4521#ifdef CONFIG_SYSCTL
4503 __addrconf_sysctl_unregister(net->ipv6.devconf_dflt); 4522 __addrconf_sysctl_unregister(net->ipv6.devconf_dflt);
4504 __addrconf_sysctl_unregister(net->ipv6.devconf_all); 4523 __addrconf_sysctl_unregister(net->ipv6.devconf_all);
4505#endif 4524#endif
4506 if (net != &init_net) { 4525 if (!net_eq(net, &init_net)) {
4507 kfree(net->ipv6.devconf_dflt); 4526 kfree(net->ipv6.devconf_dflt);
4508 kfree(net->ipv6.devconf_all); 4527 kfree(net->ipv6.devconf_all);
4509 } 4528 }
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/addrlabel.c b/net/ipv6/addrlabel.c
index 6ff73c4c126a..ae404c9a746c 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -13,6 +13,7 @@
13#include <linux/list.h> 13#include <linux/list.h>
14#include <linux/rcupdate.h> 14#include <linux/rcupdate.h>
15#include <linux/in6.h> 15#include <linux/in6.h>
16#include <linux/slab.h>
16#include <net/addrconf.h> 17#include <net/addrconf.h>
17#include <linux/if_addrlabel.h> 18#include <linux/if_addrlabel.h>
18#include <linux/netlink.h> 19#include <linux/netlink.h>
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e127a32f9540..3f9e86b15e0d 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -36,6 +36,7 @@
36#include <linux/proc_fs.h> 36#include <linux/proc_fs.h>
37#include <linux/stat.h> 37#include <linux/stat.h>
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/slab.h>
39 40
40#include <linux/inet.h> 41#include <linux/inet.h>
41#include <linux/netdevice.h> 42#include <linux/netdevice.h>
@@ -95,7 +96,8 @@ static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
95 return (struct ipv6_pinfo *)(((u8 *)sk) + offset); 96 return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
96} 97}
97 98
98static int inet6_create(struct net *net, struct socket *sock, int protocol) 99static int inet6_create(struct net *net, struct socket *sock, int protocol,
100 int kern)
99{ 101{
100 struct inet_sock *inet; 102 struct inet_sock *inet;
101 struct ipv6_pinfo *np; 103 struct ipv6_pinfo *np;
@@ -158,7 +160,7 @@ lookup_protocol:
158 } 160 }
159 161
160 err = -EPERM; 162 err = -EPERM;
161 if (answer->capability > 0 && !capable(answer->capability)) 163 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
162 goto out_rcu_unlock; 164 goto out_rcu_unlock;
163 165
164 sock->ops = answer->ops; 166 sock->ops = answer->ops;
@@ -185,7 +187,7 @@ lookup_protocol:
185 inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0; 187 inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0;
186 188
187 if (SOCK_RAW == sock->type) { 189 if (SOCK_RAW == sock->type) {
188 inet->num = protocol; 190 inet->inet_num = protocol;
189 if (IPPROTO_RAW == protocol) 191 if (IPPROTO_RAW == protocol)
190 inet->hdrincl = 1; 192 inet->hdrincl = 1;
191 } 193 }
@@ -198,7 +200,7 @@ lookup_protocol:
198 200
199 inet_sk(sk)->pinet6 = np = inet6_sk_generic(sk); 201 inet_sk(sk)->pinet6 = np = inet6_sk_generic(sk);
200 np->hop_limit = -1; 202 np->hop_limit = -1;
201 np->mcast_hops = -1; 203 np->mcast_hops = IPV6_DEFAULT_MCASTHOPS;
202 np->mc_loop = 1; 204 np->mc_loop = 1;
203 np->pmtudisc = IPV6_PMTUDISC_WANT; 205 np->pmtudisc = IPV6_PMTUDISC_WANT;
204 np->ipv6only = net->ipv6.sysctl.bindv6only; 206 np->ipv6only = net->ipv6.sysctl.bindv6only;
@@ -228,12 +230,12 @@ lookup_protocol:
228 */ 230 */
229 sk_refcnt_debug_inc(sk); 231 sk_refcnt_debug_inc(sk);
230 232
231 if (inet->num) { 233 if (inet->inet_num) {
232 /* It assumes that any protocol which allows 234 /* It assumes that any protocol which allows
233 * the user to assign a number at socket 235 * the user to assign a number at socket
234 * creation time automatically shares. 236 * creation time automatically shares.
235 */ 237 */
236 inet->sport = htons(inet->num); 238 inet->inet_sport = htons(inet->inet_num);
237 sk->sk_prot->hash(sk); 239 sk->sk_prot->hash(sk);
238 } 240 }
239 if (sk->sk_prot->init) { 241 if (sk->sk_prot->init) {
@@ -281,7 +283,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
281 lock_sock(sk); 283 lock_sock(sk);
282 284
283 /* Check these errors (active socket, double bind). */ 285 /* Check these errors (active socket, double bind). */
284 if (sk->sk_state != TCP_CLOSE || inet->num) { 286 if (sk->sk_state != TCP_CLOSE || inet->inet_num) {
285 err = -EINVAL; 287 err = -EINVAL;
286 goto out; 288 goto out;
287 } 289 }
@@ -314,6 +316,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
314 if (addr_type != IPV6_ADDR_ANY) { 316 if (addr_type != IPV6_ADDR_ANY) {
315 struct net_device *dev = NULL; 317 struct net_device *dev = NULL;
316 318
319 rcu_read_lock();
317 if (addr_type & IPV6_ADDR_LINKLOCAL) { 320 if (addr_type & IPV6_ADDR_LINKLOCAL) {
318 if (addr_len >= sizeof(struct sockaddr_in6) && 321 if (addr_len >= sizeof(struct sockaddr_in6) &&
319 addr->sin6_scope_id) { 322 addr->sin6_scope_id) {
@@ -326,12 +329,12 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
326 /* Binding to link-local address requires an interface */ 329 /* Binding to link-local address requires an interface */
327 if (!sk->sk_bound_dev_if) { 330 if (!sk->sk_bound_dev_if) {
328 err = -EINVAL; 331 err = -EINVAL;
329 goto out; 332 goto out_unlock;
330 } 333 }
331 dev = dev_get_by_index(net, sk->sk_bound_dev_if); 334 dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if);
332 if (!dev) { 335 if (!dev) {
333 err = -ENODEV; 336 err = -ENODEV;
334 goto out; 337 goto out_unlock;
335 } 338 }
336 } 339 }
337 340
@@ -342,19 +345,16 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
342 if (!(addr_type & IPV6_ADDR_MULTICAST)) { 345 if (!(addr_type & IPV6_ADDR_MULTICAST)) {
343 if (!ipv6_chk_addr(net, &addr->sin6_addr, 346 if (!ipv6_chk_addr(net, &addr->sin6_addr,
344 dev, 0)) { 347 dev, 0)) {
345 if (dev)
346 dev_put(dev);
347 err = -EADDRNOTAVAIL; 348 err = -EADDRNOTAVAIL;
348 goto out; 349 goto out_unlock;
349 } 350 }
350 } 351 }
351 if (dev) 352 rcu_read_unlock();
352 dev_put(dev);
353 } 353 }
354 } 354 }
355 355
356 inet->rcv_saddr = v4addr; 356 inet->inet_rcv_saddr = v4addr;
357 inet->saddr = v4addr; 357 inet->inet_saddr = v4addr;
358 358
359 ipv6_addr_copy(&np->rcv_saddr, &addr->sin6_addr); 359 ipv6_addr_copy(&np->rcv_saddr, &addr->sin6_addr);
360 360
@@ -375,12 +375,15 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
375 } 375 }
376 if (snum) 376 if (snum)
377 sk->sk_userlocks |= SOCK_BINDPORT_LOCK; 377 sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
378 inet->sport = htons(inet->num); 378 inet->inet_sport = htons(inet->inet_num);
379 inet->dport = 0; 379 inet->inet_dport = 0;
380 inet->daddr = 0; 380 inet->inet_daddr = 0;
381out: 381out:
382 release_sock(sk); 382 release_sock(sk);
383 return err; 383 return err;
384out_unlock:
385 rcu_read_unlock();
386 goto out;
384} 387}
385 388
386EXPORT_SYMBOL(inet6_bind); 389EXPORT_SYMBOL(inet6_bind);
@@ -441,12 +444,12 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
441 sin->sin6_flowinfo = 0; 444 sin->sin6_flowinfo = 0;
442 sin->sin6_scope_id = 0; 445 sin->sin6_scope_id = 0;
443 if (peer) { 446 if (peer) {
444 if (!inet->dport) 447 if (!inet->inet_dport)
445 return -ENOTCONN; 448 return -ENOTCONN;
446 if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)) && 449 if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)) &&
447 peer == 1) 450 peer == 1)
448 return -ENOTCONN; 451 return -ENOTCONN;
449 sin->sin6_port = inet->dport; 452 sin->sin6_port = inet->inet_dport;
450 ipv6_addr_copy(&sin->sin6_addr, &np->daddr); 453 ipv6_addr_copy(&sin->sin6_addr, &np->daddr);
451 if (np->sndflow) 454 if (np->sndflow)
452 sin->sin6_flowinfo = np->flow_label; 455 sin->sin6_flowinfo = np->flow_label;
@@ -456,7 +459,7 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
456 else 459 else
457 ipv6_addr_copy(&sin->sin6_addr, &np->rcv_saddr); 460 ipv6_addr_copy(&sin->sin6_addr, &np->rcv_saddr);
458 461
459 sin->sin6_port = inet->sport; 462 sin->sin6_port = inet->inet_sport;
460 } 463 }
461 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) 464 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
462 sin->sin6_scope_id = sk->sk_bound_dev_if; 465 sin->sin6_scope_id = sk->sk_bound_dev_if;
@@ -552,7 +555,7 @@ const struct proto_ops inet6_dgram_ops = {
552#endif 555#endif
553}; 556};
554 557
555static struct net_proto_family inet6_family_ops = { 558static const struct net_proto_family inet6_family_ops = {
556 .family = PF_INET6, 559 .family = PF_INET6,
557 .create = inet6_create, 560 .create = inet6_create,
558 .owner = THIS_MODULE, 561 .owner = THIS_MODULE,
@@ -654,8 +657,9 @@ int inet6_sk_rebuild_header(struct sock *sk)
654 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 657 ipv6_addr_copy(&fl.fl6_src, &np->saddr);
655 fl.fl6_flowlabel = np->flow_label; 658 fl.fl6_flowlabel = np->flow_label;
656 fl.oif = sk->sk_bound_dev_if; 659 fl.oif = sk->sk_bound_dev_if;
657 fl.fl_ip_dport = inet->dport; 660 fl.mark = sk->sk_mark;
658 fl.fl_ip_sport = inet->sport; 661 fl.fl_ip_dport = inet->inet_dport;
662 fl.fl_ip_sport = inet->inet_sport;
659 security_sk_classify_flow(sk, &fl); 663 security_sk_classify_flow(sk, &fl);
660 664
661 if (np->opt && np->opt->srcrt) { 665 if (np->opt && np->opt->srcrt) {
@@ -968,41 +972,41 @@ static void ipv6_packet_cleanup(void)
968 972
969static int __net_init ipv6_init_mibs(struct net *net) 973static int __net_init ipv6_init_mibs(struct net *net)
970{ 974{
971 if (snmp_mib_init((void **)net->mib.udp_stats_in6, 975 if (snmp_mib_init((void __percpu **)net->mib.udp_stats_in6,
972 sizeof (struct udp_mib)) < 0) 976 sizeof (struct udp_mib)) < 0)
973 return -ENOMEM; 977 return -ENOMEM;
974 if (snmp_mib_init((void **)net->mib.udplite_stats_in6, 978 if (snmp_mib_init((void __percpu **)net->mib.udplite_stats_in6,
975 sizeof (struct udp_mib)) < 0) 979 sizeof (struct udp_mib)) < 0)
976 goto err_udplite_mib; 980 goto err_udplite_mib;
977 if (snmp_mib_init((void **)net->mib.ipv6_statistics, 981 if (snmp_mib_init((void __percpu **)net->mib.ipv6_statistics,
978 sizeof(struct ipstats_mib)) < 0) 982 sizeof(struct ipstats_mib)) < 0)
979 goto err_ip_mib; 983 goto err_ip_mib;
980 if (snmp_mib_init((void **)net->mib.icmpv6_statistics, 984 if (snmp_mib_init((void __percpu **)net->mib.icmpv6_statistics,
981 sizeof(struct icmpv6_mib)) < 0) 985 sizeof(struct icmpv6_mib)) < 0)
982 goto err_icmp_mib; 986 goto err_icmp_mib;
983 if (snmp_mib_init((void **)net->mib.icmpv6msg_statistics, 987 if (snmp_mib_init((void __percpu **)net->mib.icmpv6msg_statistics,
984 sizeof(struct icmpv6msg_mib)) < 0) 988 sizeof(struct icmpv6msg_mib)) < 0)
985 goto err_icmpmsg_mib; 989 goto err_icmpmsg_mib;
986 return 0; 990 return 0;
987 991
988err_icmpmsg_mib: 992err_icmpmsg_mib:
989 snmp_mib_free((void **)net->mib.icmpv6_statistics); 993 snmp_mib_free((void __percpu **)net->mib.icmpv6_statistics);
990err_icmp_mib: 994err_icmp_mib:
991 snmp_mib_free((void **)net->mib.ipv6_statistics); 995 snmp_mib_free((void __percpu **)net->mib.ipv6_statistics);
992err_ip_mib: 996err_ip_mib:
993 snmp_mib_free((void **)net->mib.udplite_stats_in6); 997 snmp_mib_free((void __percpu **)net->mib.udplite_stats_in6);
994err_udplite_mib: 998err_udplite_mib:
995 snmp_mib_free((void **)net->mib.udp_stats_in6); 999 snmp_mib_free((void __percpu **)net->mib.udp_stats_in6);
996 return -ENOMEM; 1000 return -ENOMEM;
997} 1001}
998 1002
999static void __net_exit ipv6_cleanup_mibs(struct net *net) 1003static void ipv6_cleanup_mibs(struct net *net)
1000{ 1004{
1001 snmp_mib_free((void **)net->mib.udp_stats_in6); 1005 snmp_mib_free((void __percpu **)net->mib.udp_stats_in6);
1002 snmp_mib_free((void **)net->mib.udplite_stats_in6); 1006 snmp_mib_free((void __percpu **)net->mib.udplite_stats_in6);
1003 snmp_mib_free((void **)net->mib.ipv6_statistics); 1007 snmp_mib_free((void __percpu **)net->mib.ipv6_statistics);
1004 snmp_mib_free((void **)net->mib.icmpv6_statistics); 1008 snmp_mib_free((void __percpu **)net->mib.icmpv6_statistics);
1005 snmp_mib_free((void **)net->mib.icmpv6msg_statistics); 1009 snmp_mib_free((void __percpu **)net->mib.icmpv6msg_statistics);
1006} 1010}
1007 1011
1008static int __net_init inet6_net_init(struct net *net) 1012static int __net_init inet6_net_init(struct net *net)
@@ -1039,7 +1043,7 @@ out:
1039#endif 1043#endif
1040} 1044}
1041 1045
1042static void inet6_net_exit(struct net *net) 1046static void __net_exit inet6_net_exit(struct net *net)
1043{ 1047{
1044#ifdef CONFIG_PROC_FS 1048#ifdef CONFIG_PROC_FS
1045 udp6_proc_exit(net); 1049 udp6_proc_exit(net);
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index c1589e2f1dc9..ee82d4ef26ce 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -24,18 +24,93 @@
24 * This file is derived from net/ipv4/ah.c. 24 * This file is derived from net/ipv4/ah.c.
25 */ 25 */
26 26
27#include <crypto/hash.h>
27#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/slab.h>
28#include <net/ip.h> 30#include <net/ip.h>
29#include <net/ah.h> 31#include <net/ah.h>
30#include <linux/crypto.h> 32#include <linux/crypto.h>
31#include <linux/pfkeyv2.h> 33#include <linux/pfkeyv2.h>
32#include <linux/spinlock.h>
33#include <linux/string.h> 34#include <linux/string.h>
35#include <linux/scatterlist.h>
34#include <net/icmp.h> 36#include <net/icmp.h>
35#include <net/ipv6.h> 37#include <net/ipv6.h>
36#include <net/protocol.h> 38#include <net/protocol.h>
37#include <net/xfrm.h> 39#include <net/xfrm.h>
38 40
41#define IPV6HDR_BASELEN 8
42
43struct tmp_ext {
44#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
45 struct in6_addr saddr;
46#endif
47 struct in6_addr daddr;
48 char hdrs[0];
49};
50
51struct ah_skb_cb {
52 struct xfrm_skb_cb xfrm;
53 void *tmp;
54};
55
56#define AH_SKB_CB(__skb) ((struct ah_skb_cb *)&((__skb)->cb[0]))
57
58static void *ah_alloc_tmp(struct crypto_ahash *ahash, int nfrags,
59 unsigned int size)
60{
61 unsigned int len;
62
63 len = size + crypto_ahash_digestsize(ahash) +
64 (crypto_ahash_alignmask(ahash) &
65 ~(crypto_tfm_ctx_alignment() - 1));
66
67 len = ALIGN(len, crypto_tfm_ctx_alignment());
68
69 len += sizeof(struct ahash_request) + crypto_ahash_reqsize(ahash);
70 len = ALIGN(len, __alignof__(struct scatterlist));
71
72 len += sizeof(struct scatterlist) * nfrags;
73
74 return kmalloc(len, GFP_ATOMIC);
75}
76
77static inline struct tmp_ext *ah_tmp_ext(void *base)
78{
79 return base + IPV6HDR_BASELEN;
80}
81
82static inline u8 *ah_tmp_auth(u8 *tmp, unsigned int offset)
83{
84 return tmp + offset;
85}
86
87static inline u8 *ah_tmp_icv(struct crypto_ahash *ahash, void *tmp,
88 unsigned int offset)
89{
90 return PTR_ALIGN((u8 *)tmp + offset, crypto_ahash_alignmask(ahash) + 1);
91}
92
93static inline struct ahash_request *ah_tmp_req(struct crypto_ahash *ahash,
94 u8 *icv)
95{
96 struct ahash_request *req;
97
98 req = (void *)PTR_ALIGN(icv + crypto_ahash_digestsize(ahash),
99 crypto_tfm_ctx_alignment());
100
101 ahash_request_set_tfm(req, ahash);
102
103 return req;
104}
105
106static inline struct scatterlist *ah_req_sg(struct crypto_ahash *ahash,
107 struct ahash_request *req)
108{
109 return (void *)ALIGN((unsigned long)(req + 1) +
110 crypto_ahash_reqsize(ahash),
111 __alignof__(struct scatterlist));
112}
113
39static int zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr) 114static int zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr)
40{ 115{
41 u8 *opt = (u8 *)opthdr; 116 u8 *opt = (u8 *)opthdr;
@@ -218,24 +293,85 @@ static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir)
218 return 0; 293 return 0;
219} 294}
220 295
296static void ah6_output_done(struct crypto_async_request *base, int err)
297{
298 int extlen;
299 u8 *iph_base;
300 u8 *icv;
301 struct sk_buff *skb = base->data;
302 struct xfrm_state *x = skb_dst(skb)->xfrm;
303 struct ah_data *ahp = x->data;
304 struct ipv6hdr *top_iph = ipv6_hdr(skb);
305 struct ip_auth_hdr *ah = ip_auth_hdr(skb);
306 struct tmp_ext *iph_ext;
307
308 extlen = skb_network_header_len(skb) - sizeof(struct ipv6hdr);
309 if (extlen)
310 extlen += sizeof(*iph_ext);
311
312 iph_base = AH_SKB_CB(skb)->tmp;
313 iph_ext = ah_tmp_ext(iph_base);
314 icv = ah_tmp_icv(ahp->ahash, iph_ext, extlen);
315
316 memcpy(ah->auth_data, icv, ahp->icv_trunc_len);
317 memcpy(top_iph, iph_base, IPV6HDR_BASELEN);
318
319 if (extlen) {
320#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
321 memcpy(&top_iph->saddr, iph_ext, extlen);
322#else
323 memcpy(&top_iph->daddr, iph_ext, extlen);
324#endif
325 }
326
327 err = ah->nexthdr;
328
329 kfree(AH_SKB_CB(skb)->tmp);
330 xfrm_output_resume(skb, err);
331}
332
221static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) 333static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
222{ 334{
223 int err; 335 int err;
336 int nfrags;
224 int extlen; 337 int extlen;
338 u8 *iph_base;
339 u8 *icv;
340 u8 nexthdr;
341 struct sk_buff *trailer;
342 struct crypto_ahash *ahash;
343 struct ahash_request *req;
344 struct scatterlist *sg;
225 struct ipv6hdr *top_iph; 345 struct ipv6hdr *top_iph;
226 struct ip_auth_hdr *ah; 346 struct ip_auth_hdr *ah;
227 struct ah_data *ahp; 347 struct ah_data *ahp;
228 u8 nexthdr; 348 struct tmp_ext *iph_ext;
229 char tmp_base[8]; 349
230 struct { 350 ahp = x->data;
231#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) 351 ahash = ahp->ahash;
232 struct in6_addr saddr; 352
233#endif 353 if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
234 struct in6_addr daddr; 354 goto out;
235 char hdrs[0]; 355 nfrags = err;
236 } *tmp_ext;
237 356
238 skb_push(skb, -skb_network_offset(skb)); 357 skb_push(skb, -skb_network_offset(skb));
358 extlen = skb_network_header_len(skb) - sizeof(struct ipv6hdr);
359 if (extlen)
360 extlen += sizeof(*iph_ext);
361
362 err = -ENOMEM;
363 iph_base = ah_alloc_tmp(ahash, nfrags, IPV6HDR_BASELEN + extlen);
364 if (!iph_base)
365 goto out;
366
367 iph_ext = ah_tmp_ext(iph_base);
368 icv = ah_tmp_icv(ahash, iph_ext, extlen);
369 req = ah_tmp_req(ahash, icv);
370 sg = ah_req_sg(ahash, req);
371
372 ah = ip_auth_hdr(skb);
373 memset(ah->auth_data, 0, ahp->icv_trunc_len);
374
239 top_iph = ipv6_hdr(skb); 375 top_iph = ipv6_hdr(skb);
240 top_iph->payload_len = htons(skb->len - sizeof(*top_iph)); 376 top_iph->payload_len = htons(skb->len - sizeof(*top_iph));
241 377
@@ -245,31 +381,22 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
245 /* When there are no extension headers, we only need to save the first 381 /* When there are no extension headers, we only need to save the first
246 * 8 bytes of the base IP header. 382 * 8 bytes of the base IP header.
247 */ 383 */
248 memcpy(tmp_base, top_iph, sizeof(tmp_base)); 384 memcpy(iph_base, top_iph, IPV6HDR_BASELEN);
249 385
250 tmp_ext = NULL;
251 extlen = skb_transport_offset(skb) - sizeof(struct ipv6hdr);
252 if (extlen) { 386 if (extlen) {
253 extlen += sizeof(*tmp_ext);
254 tmp_ext = kmalloc(extlen, GFP_ATOMIC);
255 if (!tmp_ext) {
256 err = -ENOMEM;
257 goto error;
258 }
259#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) 387#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
260 memcpy(tmp_ext, &top_iph->saddr, extlen); 388 memcpy(iph_ext, &top_iph->saddr, extlen);
261#else 389#else
262 memcpy(tmp_ext, &top_iph->daddr, extlen); 390 memcpy(iph_ext, &top_iph->daddr, extlen);
263#endif 391#endif
264 err = ipv6_clear_mutable_options(top_iph, 392 err = ipv6_clear_mutable_options(top_iph,
265 extlen - sizeof(*tmp_ext) + 393 extlen - sizeof(*iph_ext) +
266 sizeof(*top_iph), 394 sizeof(*top_iph),
267 XFRM_POLICY_OUT); 395 XFRM_POLICY_OUT);
268 if (err) 396 if (err)
269 goto error_free_iph; 397 goto out_free;
270 } 398 }
271 399
272 ah = ip_auth_hdr(skb);
273 ah->nexthdr = nexthdr; 400 ah->nexthdr = nexthdr;
274 401
275 top_iph->priority = 0; 402 top_iph->priority = 0;
@@ -278,36 +405,80 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
278 top_iph->flow_lbl[2] = 0; 405 top_iph->flow_lbl[2] = 0;
279 top_iph->hop_limit = 0; 406 top_iph->hop_limit = 0;
280 407
281 ahp = x->data;
282 ah->hdrlen = (XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len) >> 2) - 2; 408 ah->hdrlen = (XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len) >> 2) - 2;
283 409
284 ah->reserved = 0; 410 ah->reserved = 0;
285 ah->spi = x->id.spi; 411 ah->spi = x->id.spi;
286 ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output); 412 ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output);
287 413
288 spin_lock_bh(&x->lock); 414 sg_init_table(sg, nfrags);
289 err = ah_mac_digest(ahp, skb, ah->auth_data); 415 skb_to_sgvec(skb, sg, 0, skb->len);
290 memcpy(ah->auth_data, ahp->work_icv, ahp->icv_trunc_len);
291 spin_unlock_bh(&x->lock);
292 416
293 if (err) 417 ahash_request_set_crypt(req, sg, icv, skb->len);
294 goto error_free_iph; 418 ahash_request_set_callback(req, 0, ah6_output_done, skb);
419
420 AH_SKB_CB(skb)->tmp = iph_base;
295 421
296 memcpy(top_iph, tmp_base, sizeof(tmp_base)); 422 err = crypto_ahash_digest(req);
297 if (tmp_ext) { 423 if (err) {
424 if (err == -EINPROGRESS)
425 goto out;
426
427 if (err == -EBUSY)
428 err = NET_XMIT_DROP;
429 goto out_free;
430 }
431
432 memcpy(ah->auth_data, icv, ahp->icv_trunc_len);
433 memcpy(top_iph, iph_base, IPV6HDR_BASELEN);
434
435 if (extlen) {
298#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) 436#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
299 memcpy(&top_iph->saddr, tmp_ext, extlen); 437 memcpy(&top_iph->saddr, iph_ext, extlen);
300#else 438#else
301 memcpy(&top_iph->daddr, tmp_ext, extlen); 439 memcpy(&top_iph->daddr, iph_ext, extlen);
302#endif 440#endif
303error_free_iph:
304 kfree(tmp_ext);
305 } 441 }
306 442
307error: 443out_free:
444 kfree(iph_base);
445out:
308 return err; 446 return err;
309} 447}
310 448
449static void ah6_input_done(struct crypto_async_request *base, int err)
450{
451 u8 *auth_data;
452 u8 *icv;
453 u8 *work_iph;
454 struct sk_buff *skb = base->data;
455 struct xfrm_state *x = xfrm_input_state(skb);
456 struct ah_data *ahp = x->data;
457 struct ip_auth_hdr *ah = ip_auth_hdr(skb);
458 int hdr_len = skb_network_header_len(skb);
459 int ah_hlen = (ah->hdrlen + 2) << 2;
460
461 work_iph = AH_SKB_CB(skb)->tmp;
462 auth_data = ah_tmp_auth(work_iph, hdr_len);
463 icv = ah_tmp_icv(ahp->ahash, auth_data, ahp->icv_trunc_len);
464
465 err = memcmp(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG: 0;
466 if (err)
467 goto out;
468
469 skb->network_header += ah_hlen;
470 memcpy(skb_network_header(skb), work_iph, hdr_len);
471 __skb_pull(skb, ah_hlen + hdr_len);
472 skb_set_transport_header(skb, -hdr_len);
473
474 err = ah->nexthdr;
475out:
476 kfree(AH_SKB_CB(skb)->tmp);
477 xfrm_input_resume(skb, err);
478}
479
480
481
311static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) 482static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
312{ 483{
313 /* 484 /*
@@ -325,14 +496,21 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
325 * There is offset of AH before IPv6 header after the process. 496 * There is offset of AH before IPv6 header after the process.
326 */ 497 */
327 498
499 u8 *auth_data;
500 u8 *icv;
501 u8 *work_iph;
502 struct sk_buff *trailer;
503 struct crypto_ahash *ahash;
504 struct ahash_request *req;
505 struct scatterlist *sg;
328 struct ip_auth_hdr *ah; 506 struct ip_auth_hdr *ah;
329 struct ipv6hdr *ip6h; 507 struct ipv6hdr *ip6h;
330 struct ah_data *ahp; 508 struct ah_data *ahp;
331 unsigned char *tmp_hdr = NULL;
332 u16 hdr_len; 509 u16 hdr_len;
333 u16 ah_hlen; 510 u16 ah_hlen;
334 int nexthdr; 511 int nexthdr;
335 int err = -EINVAL; 512 int nfrags;
513 int err = -ENOMEM;
336 514
337 if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr))) 515 if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr)))
338 goto out; 516 goto out;
@@ -345,9 +523,11 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
345 523
346 skb->ip_summed = CHECKSUM_NONE; 524 skb->ip_summed = CHECKSUM_NONE;
347 525
348 hdr_len = skb->data - skb_network_header(skb); 526 hdr_len = skb_network_header_len(skb);
349 ah = (struct ip_auth_hdr *)skb->data; 527 ah = (struct ip_auth_hdr *)skb->data;
350 ahp = x->data; 528 ahp = x->data;
529 ahash = ahp->ahash;
530
351 nexthdr = ah->nexthdr; 531 nexthdr = ah->nexthdr;
352 ah_hlen = (ah->hdrlen + 2) << 2; 532 ah_hlen = (ah->hdrlen + 2) << 2;
353 533
@@ -358,48 +538,67 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
358 if (!pskb_may_pull(skb, ah_hlen)) 538 if (!pskb_may_pull(skb, ah_hlen))
359 goto out; 539 goto out;
360 540
361 tmp_hdr = kmemdup(skb_network_header(skb), hdr_len, GFP_ATOMIC);
362 if (!tmp_hdr)
363 goto out;
364 ip6h = ipv6_hdr(skb); 541 ip6h = ipv6_hdr(skb);
542
543 skb_push(skb, hdr_len);
544
545 if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
546 goto out;
547 nfrags = err;
548
549 work_iph = ah_alloc_tmp(ahash, nfrags, hdr_len + ahp->icv_trunc_len);
550 if (!work_iph)
551 goto out;
552
553 auth_data = ah_tmp_auth(work_iph, hdr_len);
554 icv = ah_tmp_icv(ahash, auth_data, ahp->icv_trunc_len);
555 req = ah_tmp_req(ahash, icv);
556 sg = ah_req_sg(ahash, req);
557
558 memcpy(work_iph, ip6h, hdr_len);
559 memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
560 memset(ah->auth_data, 0, ahp->icv_trunc_len);
561
365 if (ipv6_clear_mutable_options(ip6h, hdr_len, XFRM_POLICY_IN)) 562 if (ipv6_clear_mutable_options(ip6h, hdr_len, XFRM_POLICY_IN))
366 goto free_out; 563 goto out_free;
564
367 ip6h->priority = 0; 565 ip6h->priority = 0;
368 ip6h->flow_lbl[0] = 0; 566 ip6h->flow_lbl[0] = 0;
369 ip6h->flow_lbl[1] = 0; 567 ip6h->flow_lbl[1] = 0;
370 ip6h->flow_lbl[2] = 0; 568 ip6h->flow_lbl[2] = 0;
371 ip6h->hop_limit = 0; 569 ip6h->hop_limit = 0;
372 570
373 spin_lock(&x->lock); 571 sg_init_table(sg, nfrags);
374 { 572 skb_to_sgvec(skb, sg, 0, skb->len);
375 u8 auth_data[MAX_AH_AUTH_LEN];
376 573
377 memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); 574 ahash_request_set_crypt(req, sg, icv, skb->len);
378 memset(ah->auth_data, 0, ahp->icv_trunc_len); 575 ahash_request_set_callback(req, 0, ah6_input_done, skb);
379 skb_push(skb, hdr_len); 576
380 err = ah_mac_digest(ahp, skb, ah->auth_data); 577 AH_SKB_CB(skb)->tmp = work_iph;
381 if (err) 578
382 goto unlock; 579 err = crypto_ahash_digest(req);
383 if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) 580 if (err) {
384 err = -EBADMSG; 581 if (err == -EINPROGRESS)
582 goto out;
583
584 if (err == -EBUSY)
585 err = NET_XMIT_DROP;
586 goto out_free;
385 } 587 }
386unlock:
387 spin_unlock(&x->lock);
388 588
589 err = memcmp(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG: 0;
389 if (err) 590 if (err)
390 goto free_out; 591 goto out_free;
391 592
392 skb->network_header += ah_hlen; 593 skb->network_header += ah_hlen;
393 memcpy(skb_network_header(skb), tmp_hdr, hdr_len); 594 memcpy(skb_network_header(skb), work_iph, hdr_len);
394 skb->transport_header = skb->network_header; 595 skb->transport_header = skb->network_header;
395 __skb_pull(skb, ah_hlen + hdr_len); 596 __skb_pull(skb, ah_hlen + hdr_len);
396 597
397 kfree(tmp_hdr); 598 err = nexthdr;
398 599
399 return nexthdr; 600out_free:
400 601 kfree(work_iph);
401free_out:
402 kfree(tmp_hdr);
403out: 602out:
404 return err; 603 return err;
405} 604}
@@ -416,7 +615,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
416 type != ICMPV6_PKT_TOOBIG) 615 type != ICMPV6_PKT_TOOBIG)
417 return; 616 return;
418 617
419 x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6); 618 x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6);
420 if (!x) 619 if (!x)
421 return; 620 return;
422 621
@@ -430,7 +629,7 @@ static int ah6_init_state(struct xfrm_state *x)
430{ 629{
431 struct ah_data *ahp = NULL; 630 struct ah_data *ahp = NULL;
432 struct xfrm_algo_desc *aalg_desc; 631 struct xfrm_algo_desc *aalg_desc;
433 struct crypto_hash *tfm; 632 struct crypto_ahash *ahash;
434 633
435 if (!x->aalg) 634 if (!x->aalg)
436 goto error; 635 goto error;
@@ -442,12 +641,12 @@ static int ah6_init_state(struct xfrm_state *x)
442 if (ahp == NULL) 641 if (ahp == NULL)
443 return -ENOMEM; 642 return -ENOMEM;
444 643
445 tfm = crypto_alloc_hash(x->aalg->alg_name, 0, CRYPTO_ALG_ASYNC); 644 ahash = crypto_alloc_ahash(x->aalg->alg_name, 0, 0);
446 if (IS_ERR(tfm)) 645 if (IS_ERR(ahash))
447 goto error; 646 goto error;
448 647
449 ahp->tfm = tfm; 648 ahp->ahash = ahash;
450 if (crypto_hash_setkey(tfm, x->aalg->alg_key, 649 if (crypto_ahash_setkey(ahash, x->aalg->alg_key,
451 (x->aalg->alg_key_len + 7) / 8)) 650 (x->aalg->alg_key_len + 7) / 8))
452 goto error; 651 goto error;
453 652
@@ -461,22 +660,18 @@ static int ah6_init_state(struct xfrm_state *x)
461 BUG_ON(!aalg_desc); 660 BUG_ON(!aalg_desc);
462 661
463 if (aalg_desc->uinfo.auth.icv_fullbits/8 != 662 if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
464 crypto_hash_digestsize(tfm)) { 663 crypto_ahash_digestsize(ahash)) {
465 printk(KERN_INFO "AH: %s digestsize %u != %hu\n", 664 printk(KERN_INFO "AH: %s digestsize %u != %hu\n",
466 x->aalg->alg_name, crypto_hash_digestsize(tfm), 665 x->aalg->alg_name, crypto_ahash_digestsize(ahash),
467 aalg_desc->uinfo.auth.icv_fullbits/8); 666 aalg_desc->uinfo.auth.icv_fullbits/8);
468 goto error; 667 goto error;
469 } 668 }
470 669
471 ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8; 670 ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
472 ahp->icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8; 671 ahp->icv_trunc_len = x->aalg->alg_trunc_len/8;
473 672
474 BUG_ON(ahp->icv_trunc_len > MAX_AH_AUTH_LEN); 673 BUG_ON(ahp->icv_trunc_len > MAX_AH_AUTH_LEN);
475 674
476 ahp->work_icv = kmalloc(ahp->icv_full_len, GFP_KERNEL);
477 if (!ahp->work_icv)
478 goto error;
479
480 x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + 675 x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) +
481 ahp->icv_trunc_len); 676 ahp->icv_trunc_len);
482 switch (x->props.mode) { 677 switch (x->props.mode) {
@@ -495,8 +690,7 @@ static int ah6_init_state(struct xfrm_state *x)
495 690
496error: 691error:
497 if (ahp) { 692 if (ahp) {
498 kfree(ahp->work_icv); 693 crypto_free_ahash(ahp->ahash);
499 crypto_free_hash(ahp->tfm);
500 kfree(ahp); 694 kfree(ahp);
501 } 695 }
502 return -EINVAL; 696 return -EINVAL;
@@ -509,8 +703,7 @@ static void ah6_destroy(struct xfrm_state *x)
509 if (!ahp) 703 if (!ahp)
510 return; 704 return;
511 705
512 kfree(ahp->work_icv); 706 crypto_free_ahash(ahp->ahash);
513 crypto_free_hash(ahp->tfm);
514 kfree(ahp); 707 kfree(ahp);
515} 708}
516 709
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 1ae58bec1de0..b5b07054508a 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -29,6 +29,7 @@
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/slab.h>
32 33
33#include <net/net_namespace.h> 34#include <net/net_namespace.h>
34#include <net/sock.h> 35#include <net/sock.h>
@@ -404,13 +405,13 @@ int ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
404 405
405 if (dev) 406 if (dev)
406 return ipv6_chk_acast_dev(dev, addr); 407 return ipv6_chk_acast_dev(dev, addr);
407 read_lock(&dev_base_lock); 408 rcu_read_lock();
408 for_each_netdev(net, dev) 409 for_each_netdev_rcu(net, dev)
409 if (ipv6_chk_acast_dev(dev, addr)) { 410 if (ipv6_chk_acast_dev(dev, addr)) {
410 found = 1; 411 found = 1;
411 break; 412 break;
412 } 413 }
413 read_unlock(&dev_base_lock); 414 rcu_read_unlock();
414 return found; 415 return found;
415} 416}
416 417
@@ -431,9 +432,9 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq)
431 struct net *net = seq_file_net(seq); 432 struct net *net = seq_file_net(seq);
432 433
433 state->idev = NULL; 434 state->idev = NULL;
434 for_each_netdev(net, state->dev) { 435 for_each_netdev_rcu(net, state->dev) {
435 struct inet6_dev *idev; 436 struct inet6_dev *idev;
436 idev = in6_dev_get(state->dev); 437 idev = __in6_dev_get(state->dev);
437 if (!idev) 438 if (!idev)
438 continue; 439 continue;
439 read_lock_bh(&idev->lock); 440 read_lock_bh(&idev->lock);
@@ -443,7 +444,6 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq)
443 break; 444 break;
444 } 445 }
445 read_unlock_bh(&idev->lock); 446 read_unlock_bh(&idev->lock);
446 in6_dev_put(idev);
447 } 447 }
448 return im; 448 return im;
449} 449}
@@ -454,16 +454,15 @@ static struct ifacaddr6 *ac6_get_next(struct seq_file *seq, struct ifacaddr6 *im
454 454
455 im = im->aca_next; 455 im = im->aca_next;
456 while (!im) { 456 while (!im) {
457 if (likely(state->idev != NULL)) { 457 if (likely(state->idev != NULL))
458 read_unlock_bh(&state->idev->lock); 458 read_unlock_bh(&state->idev->lock);
459 in6_dev_put(state->idev); 459
460 } 460 state->dev = next_net_device_rcu(state->dev);
461 state->dev = next_net_device(state->dev);
462 if (!state->dev) { 461 if (!state->dev) {
463 state->idev = NULL; 462 state->idev = NULL;
464 break; 463 break;
465 } 464 }
466 state->idev = in6_dev_get(state->dev); 465 state->idev = __in6_dev_get(state->dev);
467 if (!state->idev) 466 if (!state->idev)
468 continue; 467 continue;
469 read_lock_bh(&state->idev->lock); 468 read_lock_bh(&state->idev->lock);
@@ -482,29 +481,30 @@ static struct ifacaddr6 *ac6_get_idx(struct seq_file *seq, loff_t pos)
482} 481}
483 482
484static void *ac6_seq_start(struct seq_file *seq, loff_t *pos) 483static void *ac6_seq_start(struct seq_file *seq, loff_t *pos)
485 __acquires(dev_base_lock) 484 __acquires(RCU)
486{ 485{
487 read_lock(&dev_base_lock); 486 rcu_read_lock();
488 return ac6_get_idx(seq, *pos); 487 return ac6_get_idx(seq, *pos);
489} 488}
490 489
491static void *ac6_seq_next(struct seq_file *seq, void *v, loff_t *pos) 490static void *ac6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
492{ 491{
493 struct ifacaddr6 *im; 492 struct ifacaddr6 *im = ac6_get_next(seq, v);
494 im = ac6_get_next(seq, v); 493
495 ++*pos; 494 ++*pos;
496 return im; 495 return im;
497} 496}
498 497
499static void ac6_seq_stop(struct seq_file *seq, void *v) 498static void ac6_seq_stop(struct seq_file *seq, void *v)
500 __releases(dev_base_lock) 499 __releases(RCU)
501{ 500{
502 struct ac6_iter_state *state = ac6_seq_private(seq); 501 struct ac6_iter_state *state = ac6_seq_private(seq);
502
503 if (likely(state->idev != NULL)) { 503 if (likely(state->idev != NULL)) {
504 read_unlock_bh(&state->idev->lock); 504 read_unlock_bh(&state->idev->lock);
505 in6_dev_put(state->idev); 505 state->idev = NULL;
506 } 506 }
507 read_unlock(&dev_base_lock); 507 rcu_read_unlock();
508} 508}
509 509
510static int ac6_seq_show(struct seq_file *seq, void *v) 510static int ac6_seq_show(struct seq_file *seq, void *v)
@@ -539,7 +539,7 @@ static const struct file_operations ac6_seq_fops = {
539 .release = seq_release_net, 539 .release = seq_release_net,
540}; 540};
541 541
542int ac6_proc_init(struct net *net) 542int __net_init ac6_proc_init(struct net *net)
543{ 543{
544 if (!proc_net_fops_create(net, "anycast6", S_IRUGO, &ac6_seq_fops)) 544 if (!proc_net_fops_create(net, "anycast6", S_IRUGO, &ac6_seq_fops))
545 return -ENOMEM; 545 return -ENOMEM;
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index e2bdc6d83a43..61573885e451 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -21,6 +21,7 @@
21#include <linux/in6.h> 21#include <linux/in6.h>
22#include <linux/ipv6.h> 22#include <linux/ipv6.h>
23#include <linux/route.h> 23#include <linux/route.h>
24#include <linux/slab.h>
24 25
25#include <net/ipv6.h> 26#include <net/ipv6.h>
26#include <net/ndisc.h> 27#include <net/ndisc.h>
@@ -98,17 +99,15 @@ ipv4_connected:
98 if (err) 99 if (err)
99 goto out; 100 goto out;
100 101
101 ipv6_addr_set(&np->daddr, 0, 0, htonl(0x0000ffff), inet->daddr); 102 ipv6_addr_set_v4mapped(inet->inet_daddr, &np->daddr);
102 103
103 if (ipv6_addr_any(&np->saddr)) { 104 if (ipv6_addr_any(&np->saddr))
104 ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000ffff), 105 ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);
105 inet->saddr); 106
106 } 107 if (ipv6_addr_any(&np->rcv_saddr))
108 ipv6_addr_set_v4mapped(inet->inet_rcv_saddr,
109 &np->rcv_saddr);
107 110
108 if (ipv6_addr_any(&np->rcv_saddr)) {
109 ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000ffff),
110 inet->rcv_saddr);
111 }
112 goto out; 111 goto out;
113 } 112 }
114 113
@@ -136,7 +135,7 @@ ipv4_connected:
136 ipv6_addr_copy(&np->daddr, daddr); 135 ipv6_addr_copy(&np->daddr, daddr);
137 np->flow_label = fl.fl6_flowlabel; 136 np->flow_label = fl.fl6_flowlabel;
138 137
139 inet->dport = usin->sin6_port; 138 inet->inet_dport = usin->sin6_port;
140 139
141 /* 140 /*
142 * Check for a route to destination an obtain the 141 * Check for a route to destination an obtain the
@@ -147,8 +146,9 @@ ipv4_connected:
147 ipv6_addr_copy(&fl.fl6_dst, &np->daddr); 146 ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
148 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 147 ipv6_addr_copy(&fl.fl6_src, &np->saddr);
149 fl.oif = sk->sk_bound_dev_if; 148 fl.oif = sk->sk_bound_dev_if;
150 fl.fl_ip_dport = inet->dport; 149 fl.mark = sk->sk_mark;
151 fl.fl_ip_sport = inet->sport; 150 fl.fl_ip_dport = inet->inet_dport;
151 fl.fl_ip_sport = inet->inet_sport;
152 152
153 if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST)) 153 if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST))
154 fl.oif = np->mcast_oif; 154 fl.oif = np->mcast_oif;
@@ -190,7 +190,7 @@ ipv4_connected:
190 190
191 if (ipv6_addr_any(&np->rcv_saddr)) { 191 if (ipv6_addr_any(&np->rcv_saddr)) {
192 ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src); 192 ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src);
193 inet->rcv_saddr = LOOPBACK4_IPV6; 193 inet->inet_rcv_saddr = LOOPBACK4_IPV6;
194 } 194 }
195 195
196 ip6_dst_store(sk, dst, 196 ip6_dst_store(sk, dst,
@@ -222,6 +222,8 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
222 if (!skb) 222 if (!skb)
223 return; 223 return;
224 224
225 skb->protocol = htons(ETH_P_IPV6);
226
225 serr = SKB_EXT_ERR(skb); 227 serr = SKB_EXT_ERR(skb);
226 serr->ee.ee_errno = err; 228 serr->ee.ee_errno = err;
227 serr->ee.ee_origin = SO_EE_ORIGIN_ICMP6; 229 serr->ee.ee_origin = SO_EE_ORIGIN_ICMP6;
@@ -255,6 +257,8 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info)
255 if (!skb) 257 if (!skb)
256 return; 258 return;
257 259
260 skb->protocol = htons(ETH_P_IPV6);
261
258 skb_put(skb, sizeof(struct ipv6hdr)); 262 skb_put(skb, sizeof(struct ipv6hdr));
259 skb_reset_network_header(skb); 263 skb_reset_network_header(skb);
260 iph = ipv6_hdr(skb); 264 iph = ipv6_hdr(skb);
@@ -319,7 +323,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
319 sin->sin6_flowinfo = 0; 323 sin->sin6_flowinfo = 0;
320 sin->sin6_port = serr->port; 324 sin->sin6_port = serr->port;
321 sin->sin6_scope_id = 0; 325 sin->sin6_scope_id = 0;
322 if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) { 326 if (skb->protocol == htons(ETH_P_IPV6)) {
323 ipv6_addr_copy(&sin->sin6_addr, 327 ipv6_addr_copy(&sin->sin6_addr,
324 (struct in6_addr *)(nh + serr->addr_offset)); 328 (struct in6_addr *)(nh + serr->addr_offset));
325 if (np->sndflow) 329 if (np->sndflow)
@@ -329,9 +333,8 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
329 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) 333 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
330 sin->sin6_scope_id = IP6CB(skb)->iif; 334 sin->sin6_scope_id = IP6CB(skb)->iif;
331 } else { 335 } else {
332 ipv6_addr_set(&sin->sin6_addr, 0, 0, 336 ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset),
333 htonl(0xffff), 337 &sin->sin6_addr);
334 *(__be32 *)(nh + serr->addr_offset));
335 } 338 }
336 } 339 }
337 340
@@ -342,7 +345,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
342 sin->sin6_family = AF_INET6; 345 sin->sin6_family = AF_INET6;
343 sin->sin6_flowinfo = 0; 346 sin->sin6_flowinfo = 0;
344 sin->sin6_scope_id = 0; 347 sin->sin6_scope_id = 0;
345 if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) { 348 if (skb->protocol == htons(ETH_P_IPV6)) {
346 ipv6_addr_copy(&sin->sin6_addr, &ipv6_hdr(skb)->saddr); 349 ipv6_addr_copy(&sin->sin6_addr, &ipv6_hdr(skb)->saddr);
347 if (np->rxopt.all) 350 if (np->rxopt.all)
348 datagram_recv_ctl(sk, msg, skb); 351 datagram_recv_ctl(sk, msg, skb);
@@ -351,8 +354,8 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
351 } else { 354 } else {
352 struct inet_sock *inet = inet_sk(sk); 355 struct inet_sock *inet = inet_sk(sk);
353 356
354 ipv6_addr_set(&sin->sin6_addr, 0, 0, 357 ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr,
355 htonl(0xffff), ip_hdr(skb)->saddr); 358 &sin->sin6_addr);
356 if (inet->cmsg_flags) 359 if (inet->cmsg_flags)
357 ip_cmsg_recv(msg, skb); 360 ip_cmsg_recv(msg, skb);
358 } 361 }
@@ -539,12 +542,17 @@ int datagram_send_ctl(struct net *net,
539 542
540 addr_type = __ipv6_addr_type(&src_info->ipi6_addr); 543 addr_type = __ipv6_addr_type(&src_info->ipi6_addr);
541 544
545 rcu_read_lock();
542 if (fl->oif) { 546 if (fl->oif) {
543 dev = dev_get_by_index(net, fl->oif); 547 dev = dev_get_by_index_rcu(net, fl->oif);
544 if (!dev) 548 if (!dev) {
549 rcu_read_unlock();
545 return -ENODEV; 550 return -ENODEV;
546 } else if (addr_type & IPV6_ADDR_LINKLOCAL) 551 }
552 } else if (addr_type & IPV6_ADDR_LINKLOCAL) {
553 rcu_read_unlock();
547 return -EINVAL; 554 return -EINVAL;
555 }
548 556
549 if (addr_type != IPV6_ADDR_ANY) { 557 if (addr_type != IPV6_ADDR_ANY) {
550 int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL; 558 int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL;
@@ -555,8 +563,7 @@ int datagram_send_ctl(struct net *net,
555 ipv6_addr_copy(&fl->fl6_src, &src_info->ipi6_addr); 563 ipv6_addr_copy(&fl->fl6_src, &src_info->ipi6_addr);
556 } 564 }
557 565
558 if (dev) 566 rcu_read_unlock();
559 dev_put(dev);
560 567
561 if (err) 568 if (err)
562 goto exit_f; 569 goto exit_f;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index af597c73ebe9..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",
@@ -473,7 +473,7 @@ static int esp_init_authenc(struct xfrm_state *x)
473 } 473 }
474 474
475 err = crypto_aead_setauthsize( 475 err = crypto_aead_setauthsize(
476 aead, aalg_desc->uinfo.auth.icv_truncbits / 8); 476 aead, x->aalg->alg_trunc_len / 8);
477 if (err) 477 if (err)
478 goto free_key; 478 goto free_key;
479 } 479 }
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index df159fffe4bc..8a659f92d17a 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -29,6 +29,7 @@
29#include <linux/netdevice.h> 29#include <linux/netdevice.h>
30#include <linux/in6.h> 30#include <linux/in6.h>
31#include <linux/icmpv6.h> 31#include <linux/icmpv6.h>
32#include <linux/slab.h>
32 33
33#include <net/dst.h> 34#include <net/dst.h>
34#include <net/sock.h> 35#include <net/sock.h>
@@ -481,7 +482,7 @@ looped_back:
481 IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), 482 IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
482 IPSTATS_MIB_INHDRERRORS); 483 IPSTATS_MIB_INHDRERRORS);
483 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 484 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
484 0, skb->dev); 485 0);
485 kfree_skb(skb); 486 kfree_skb(skb);
486 return -1; 487 return -1;
487 } 488 }
@@ -559,6 +560,11 @@ static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb)
559 return skb_dst(skb) ? ip6_dst_idev(skb_dst(skb)) : __in6_dev_get(skb->dev); 560 return skb_dst(skb) ? ip6_dst_idev(skb_dst(skb)) : __in6_dev_get(skb->dev);
560} 561}
561 562
563static inline struct net *ipv6_skb_net(struct sk_buff *skb)
564{
565 return skb_dst(skb) ? dev_net(skb_dst(skb)->dev) : dev_net(skb->dev);
566}
567
562/* Router Alert as of RFC 2711 */ 568/* Router Alert as of RFC 2711 */
563 569
564static int ipv6_hop_ra(struct sk_buff *skb, int optoff) 570static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
@@ -580,8 +586,8 @@ static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
580static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff) 586static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
581{ 587{
582 const unsigned char *nh = skb_network_header(skb); 588 const unsigned char *nh = skb_network_header(skb);
589 struct net *net = ipv6_skb_net(skb);
583 u32 pkt_len; 590 u32 pkt_len;
584 struct net *net = dev_net(skb_dst(skb)->dev);
585 591
586 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { 592 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
587 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", 593 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 00a7a5e4ac97..5e463c43fcc2 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -84,18 +84,11 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
84 if ((rule->flags & FIB_RULE_FIND_SADDR) && 84 if ((rule->flags & FIB_RULE_FIND_SADDR) &&
85 r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) { 85 r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) {
86 struct in6_addr saddr; 86 struct in6_addr saddr;
87 unsigned int srcprefs = 0;
88
89 if (flags & RT6_LOOKUP_F_SRCPREF_TMP)
90 srcprefs |= IPV6_PREFER_SRC_TMP;
91 if (flags & RT6_LOOKUP_F_SRCPREF_PUBLIC)
92 srcprefs |= IPV6_PREFER_SRC_PUBLIC;
93 if (flags & RT6_LOOKUP_F_SRCPREF_COA)
94 srcprefs |= IPV6_PREFER_SRC_COA;
95 87
96 if (ipv6_dev_get_saddr(net, 88 if (ipv6_dev_get_saddr(net,
97 ip6_dst_idev(&rt->u.dst)->dev, 89 ip6_dst_idev(&rt->u.dst)->dev,
98 &flp->fl6_dst, srcprefs, 90 &flp->fl6_dst,
91 rt6_flags2srcprefs(flags),
99 &saddr)) 92 &saddr))
100 goto again; 93 goto again;
101 if (!ipv6_prefix_equal(&saddr, &r->src.addr, 94 if (!ipv6_prefix_equal(&saddr, &r->src.addr,
@@ -262,46 +255,38 @@ static struct fib_rules_ops fib6_rules_ops_template = {
262 .fro_net = &init_net, 255 .fro_net = &init_net,
263}; 256};
264 257
265static int fib6_rules_net_init(struct net *net) 258static int __net_init fib6_rules_net_init(struct net *net)
266{ 259{
260 struct fib_rules_ops *ops;
267 int err = -ENOMEM; 261 int err = -ENOMEM;
268 262
269 net->ipv6.fib6_rules_ops = kmemdup(&fib6_rules_ops_template, 263 ops = fib_rules_register(&fib6_rules_ops_template, net);
270 sizeof(*net->ipv6.fib6_rules_ops), 264 if (IS_ERR(ops))
271 GFP_KERNEL); 265 return PTR_ERR(ops);
272 if (!net->ipv6.fib6_rules_ops) 266 net->ipv6.fib6_rules_ops = ops;
273 goto out;
274 267
275 net->ipv6.fib6_rules_ops->fro_net = net;
276 INIT_LIST_HEAD(&net->ipv6.fib6_rules_ops->rules_list);
277 268
278 err = fib_default_rule_add(net->ipv6.fib6_rules_ops, 0, 269 err = fib_default_rule_add(net->ipv6.fib6_rules_ops, 0,
279 RT6_TABLE_LOCAL, FIB_RULE_PERMANENT); 270 RT6_TABLE_LOCAL, 0);
280 if (err) 271 if (err)
281 goto out_fib6_rules_ops; 272 goto out_fib6_rules_ops;
282 273
283 err = fib_default_rule_add(net->ipv6.fib6_rules_ops, 274 err = fib_default_rule_add(net->ipv6.fib6_rules_ops,
284 0x7FFE, RT6_TABLE_MAIN, 0); 275 0x7FFE, RT6_TABLE_MAIN, 0);
285 if (err) 276 if (err)
286 goto out_fib6_default_rule_add; 277 goto out_fib6_rules_ops;
287 278
288 err = fib_rules_register(net->ipv6.fib6_rules_ops);
289 if (err)
290 goto out_fib6_default_rule_add;
291out: 279out:
292 return err; 280 return err;
293 281
294out_fib6_default_rule_add:
295 fib_rules_cleanup_ops(net->ipv6.fib6_rules_ops);
296out_fib6_rules_ops: 282out_fib6_rules_ops:
297 kfree(net->ipv6.fib6_rules_ops); 283 fib_rules_unregister(ops);
298 goto out; 284 goto out;
299} 285}
300 286
301static void fib6_rules_net_exit(struct net *net) 287static void __net_exit fib6_rules_net_exit(struct net *net)
302{ 288{
303 fib_rules_unregister(net->ipv6.fib6_rules_ops); 289 fib_rules_unregister(net->ipv6.fib6_rules_ops);
304 kfree(net->ipv6.fib6_rules_ops);
305} 290}
306 291
307static struct pernet_operations fib6_rules_net_ops = { 292static struct pernet_operations fib6_rules_net_ops = {
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index f23ebbec0631..3330a4bd6157 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -40,6 +40,7 @@
40#include <linux/skbuff.h> 40#include <linux/skbuff.h>
41#include <linux/init.h> 41#include <linux/init.h>
42#include <linux/netfilter.h> 42#include <linux/netfilter.h>
43#include <linux/slab.h>
43 44
44#ifdef CONFIG_SYSCTL 45#ifdef CONFIG_SYSCTL
45#include <linux/sysctl.h> 46#include <linux/sysctl.h>
@@ -67,11 +68,6 @@
67#include <asm/uaccess.h> 68#include <asm/uaccess.h>
68#include <asm/system.h> 69#include <asm/system.h>
69 70
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/* 71/*
76 * The ICMP socket(s). This is the most convenient way to flow control 72 * 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 73 * our ICMP output as well as maintain a clean interface throughout
@@ -119,7 +115,7 @@ static __inline__ void icmpv6_xmit_unlock(struct sock *sk)
119 */ 115 */
120void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos) 116void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
121{ 117{
122 icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos, skb->dev); 118 icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos);
123 kfree_skb(skb); 119 kfree_skb(skb);
124} 120}
125 121
@@ -305,8 +301,7 @@ static inline void mip6_addr_swap(struct sk_buff *skb) {}
305/* 301/*
306 * Send an ICMP message in response to a packet in error 302 * Send an ICMP message in response to a packet in error
307 */ 303 */
308void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, 304void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
309 struct net_device *dev)
310{ 305{
311 struct net *net = dev_net(skb->dev); 306 struct net *net = dev_net(skb->dev);
312 struct inet6_dev *idev = NULL; 307 struct inet6_dev *idev = NULL;
@@ -942,18 +937,16 @@ EXPORT_SYMBOL(icmpv6_err_convert);
942#ifdef CONFIG_SYSCTL 937#ifdef CONFIG_SYSCTL
943ctl_table ipv6_icmp_table_template[] = { 938ctl_table ipv6_icmp_table_template[] = {
944 { 939 {
945 .ctl_name = NET_IPV6_ICMP_RATELIMIT,
946 .procname = "ratelimit", 940 .procname = "ratelimit",
947 .data = &init_net.ipv6.sysctl.icmpv6_time, 941 .data = &init_net.ipv6.sysctl.icmpv6_time,
948 .maxlen = sizeof(int), 942 .maxlen = sizeof(int),
949 .mode = 0644, 943 .mode = 0644,
950 .proc_handler = proc_dointvec_ms_jiffies, 944 .proc_handler = proc_dointvec_ms_jiffies,
951 .strategy = sysctl_ms_jiffies
952 }, 945 },
953 { .ctl_name = 0 }, 946 { },
954}; 947};
955 948
956struct ctl_table *ipv6_icmp_sysctl_init(struct net *net) 949struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
957{ 950{
958 struct ctl_table *table; 951 struct ctl_table *table;
959 952
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index cc4797dd8325..628db24bcf22 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -17,6 +17,7 @@
17#include <linux/in6.h> 17#include <linux/in6.h>
18#include <linux/ipv6.h> 18#include <linux/ipv6.h>
19#include <linux/jhash.h> 19#include <linux/jhash.h>
20#include <linux/slab.h>
20 21
21#include <net/addrconf.h> 22#include <net/addrconf.h>
22#include <net/inet_connection_sock.h> 23#include <net/inet_connection_sock.h>
@@ -132,7 +133,7 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
132 133
133 sin6->sin6_family = AF_INET6; 134 sin6->sin6_family = AF_INET6;
134 ipv6_addr_copy(&sin6->sin6_addr, &np->daddr); 135 ipv6_addr_copy(&sin6->sin6_addr, &np->daddr);
135 sin6->sin6_port = inet_sk(sk)->dport; 136 sin6->sin6_port = inet_sk(sk)->inet_dport;
136 /* We do not store received flowlabel for TCP */ 137 /* We do not store received flowlabel for TCP */
137 sin6->sin6_flowinfo = 0; 138 sin6->sin6_flowinfo = 0;
138 sin6->sin6_scope_id = 0; 139 sin6->sin6_scope_id = 0;
@@ -168,8 +169,7 @@ struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
168 if (dst) { 169 if (dst) {
169 struct rt6_info *rt = (struct rt6_info *)dst; 170 struct rt6_info *rt = (struct rt6_info *)dst;
170 if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) { 171 if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) {
171 sk->sk_dst_cache = NULL; 172 __sk_dst_reset(sk);
172 dst_release(dst);
173 dst = NULL; 173 dst = NULL;
174 } 174 }
175 } 175 }
@@ -194,8 +194,9 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
194 fl.fl6_flowlabel = np->flow_label; 194 fl.fl6_flowlabel = np->flow_label;
195 IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel); 195 IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
196 fl.oif = sk->sk_bound_dev_if; 196 fl.oif = sk->sk_bound_dev_if;
197 fl.fl_ip_sport = inet->sport; 197 fl.mark = sk->sk_mark;
198 fl.fl_ip_dport = inet->dport; 198 fl.fl_ip_sport = inet->inet_sport;
199 fl.fl_ip_dport = inet->inet_dport;
199 security_sk_classify_flow(sk, &fl); 200 security_sk_classify_flow(sk, &fl);
200 201
201 if (np->opt && np->opt->srcrt) { 202 if (np->opt && np->opt->srcrt) {
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 1bcc3431859e..633a6c266136 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -22,9 +22,10 @@
22#include <net/inet6_hashtables.h> 22#include <net/inet6_hashtables.h>
23#include <net/ip.h> 23#include <net/ip.h>
24 24
25void __inet6_hash(struct sock *sk) 25int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw)
26{ 26{
27 struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; 27 struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
28 int twrefcnt = 0;
28 29
29 WARN_ON(!sk_unhashed(sk)); 30 WARN_ON(!sk_unhashed(sk));
30 31
@@ -45,10 +46,15 @@ void __inet6_hash(struct sock *sk)
45 lock = inet_ehash_lockp(hashinfo, hash); 46 lock = inet_ehash_lockp(hashinfo, hash);
46 spin_lock(lock); 47 spin_lock(lock);
47 __sk_nulls_add_node_rcu(sk, list); 48 __sk_nulls_add_node_rcu(sk, list);
49 if (tw) {
50 WARN_ON(sk->sk_hash != tw->tw_hash);
51 twrefcnt = inet_twsk_unhash(tw);
52 }
48 spin_unlock(lock); 53 spin_unlock(lock);
49 } 54 }
50 55
51 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 56 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
57 return twrefcnt;
52} 58}
53EXPORT_SYMBOL(__inet6_hash); 59EXPORT_SYMBOL(__inet6_hash);
54 60
@@ -73,7 +79,7 @@ struct sock *__inet6_lookup_established(struct net *net,
73 * have wildcards anyways. 79 * have wildcards anyways.
74 */ 80 */
75 unsigned int hash = inet6_ehashfn(net, daddr, hnum, saddr, sport); 81 unsigned int hash = inet6_ehashfn(net, daddr, hnum, saddr, sport);
76 unsigned int slot = hash & (hashinfo->ehash_size - 1); 82 unsigned int slot = hash & hashinfo->ehash_mask;
77 struct inet_ehash_bucket *head = &hashinfo->ehash[slot]; 83 struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
78 84
79 85
@@ -125,7 +131,7 @@ static int inline compute_score(struct sock *sk, struct net *net,
125{ 131{
126 int score = -1; 132 int score = -1;
127 133
128 if (net_eq(sock_net(sk), net) && inet_sk(sk)->num == hnum && 134 if (net_eq(sock_net(sk), net) && inet_sk(sk)->inet_num == hnum &&
129 sk->sk_family == PF_INET6) { 135 sk->sk_family == PF_INET6) {
130 const struct ipv6_pinfo *np = inet6_sk(sk); 136 const struct ipv6_pinfo *np = inet6_sk(sk);
131 137
@@ -214,15 +220,16 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
214 const struct in6_addr *daddr = &np->rcv_saddr; 220 const struct in6_addr *daddr = &np->rcv_saddr;
215 const struct in6_addr *saddr = &np->daddr; 221 const struct in6_addr *saddr = &np->daddr;
216 const int dif = sk->sk_bound_dev_if; 222 const int dif = sk->sk_bound_dev_if;
217 const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport); 223 const __portpair ports = INET_COMBINED_PORTS(inet->inet_dport, lport);
218 struct net *net = sock_net(sk); 224 struct net *net = sock_net(sk);
219 const unsigned int hash = inet6_ehashfn(net, daddr, lport, saddr, 225 const unsigned int hash = inet6_ehashfn(net, daddr, lport, saddr,
220 inet->dport); 226 inet->inet_dport);
221 struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); 227 struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
222 spinlock_t *lock = inet_ehash_lockp(hinfo, hash); 228 spinlock_t *lock = inet_ehash_lockp(hinfo, hash);
223 struct sock *sk2; 229 struct sock *sk2;
224 const struct hlist_nulls_node *node; 230 const struct hlist_nulls_node *node;
225 struct inet_timewait_sock *tw; 231 struct inet_timewait_sock *tw;
232 int twrefcnt = 0;
226 233
227 spin_lock(lock); 234 spin_lock(lock);
228 235
@@ -248,21 +255,25 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
248unique: 255unique:
249 /* Must record num and sport now. Otherwise we will see 256 /* Must record num and sport now. Otherwise we will see
250 * in hash table socket with a funny identity. */ 257 * in hash table socket with a funny identity. */
251 inet->num = lport; 258 inet->inet_num = lport;
252 inet->sport = htons(lport); 259 inet->inet_sport = htons(lport);
260 sk->sk_hash = hash;
253 WARN_ON(!sk_unhashed(sk)); 261 WARN_ON(!sk_unhashed(sk));
254 __sk_nulls_add_node_rcu(sk, &head->chain); 262 __sk_nulls_add_node_rcu(sk, &head->chain);
255 sk->sk_hash = hash; 263 if (tw) {
264 twrefcnt = inet_twsk_unhash(tw);
265 NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED);
266 }
256 spin_unlock(lock); 267 spin_unlock(lock);
268 if (twrefcnt)
269 inet_twsk_put(tw);
257 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 270 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
258 271
259 if (twp != NULL) { 272 if (twp) {
260 *twp = tw; 273 *twp = tw;
261 NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED); 274 } else if (tw) {
262 } else if (tw != NULL) {
263 /* Silly. Should hash-dance instead... */ 275 /* Silly. Should hash-dance instead... */
264 inet_twsk_deschedule(tw, death_row); 276 inet_twsk_deschedule(tw, death_row);
265 NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED);
266 277
267 inet_twsk_put(tw); 278 inet_twsk_put(tw);
268 } 279 }
@@ -279,7 +290,7 @@ static inline u32 inet6_sk_port_offset(const struct sock *sk)
279 const struct ipv6_pinfo *np = inet6_sk(sk); 290 const struct ipv6_pinfo *np = inet6_sk(sk);
280 return secure_ipv6_port_ephemeral(np->rcv_saddr.s6_addr32, 291 return secure_ipv6_port_ephemeral(np->rcv_saddr.s6_addr32,
281 np->daddr.s6_addr32, 292 np->daddr.s6_addr32,
282 inet->dport); 293 inet->inet_dport);
283} 294}
284 295
285int inet6_hash_connect(struct inet_timewait_death_row *death_row, 296int inet6_hash_connect(struct inet_timewait_death_row *death_row,
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 0e93ca56eb69..6b82e02158c6 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -26,6 +26,7 @@
26#include <linux/in6.h> 26#include <linux/in6.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/slab.h>
29 30
30#ifdef CONFIG_PROC_FS 31#ifdef CONFIG_PROC_FS
31#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
@@ -93,29 +94,20 @@ static __u32 rt_sernum;
93 94
94static void fib6_gc_timer_cb(unsigned long arg); 95static void fib6_gc_timer_cb(unsigned long arg);
95 96
96static struct fib6_walker_t fib6_walker_list = { 97static LIST_HEAD(fib6_walkers);
97 .prev = &fib6_walker_list, 98#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 99
103static inline void fib6_walker_link(struct fib6_walker_t *w) 100static inline void fib6_walker_link(struct fib6_walker_t *w)
104{ 101{
105 write_lock_bh(&fib6_walker_lock); 102 write_lock_bh(&fib6_walker_lock);
106 w->next = fib6_walker_list.next; 103 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); 104 write_unlock_bh(&fib6_walker_lock);
111} 105}
112 106
113static inline void fib6_walker_unlink(struct fib6_walker_t *w) 107static inline void fib6_walker_unlink(struct fib6_walker_t *w)
114{ 108{
115 write_lock_bh(&fib6_walker_lock); 109 write_lock_bh(&fib6_walker_lock);
116 w->next->prev = w->prev; 110 list_del(&w->lh);
117 w->prev->next = w->next;
118 w->prev = w->next = w;
119 write_unlock_bh(&fib6_walker_lock); 111 write_unlock_bh(&fib6_walker_lock);
120} 112}
121static __inline__ u32 fib6_new_sernum(void) 113static __inline__ u32 fib6_new_sernum(void)
@@ -239,7 +231,7 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id)
239 return NULL; 231 return NULL;
240} 232}
241 233
242static void fib6_tables_init(struct net *net) 234static void __net_init fib6_tables_init(struct net *net)
243{ 235{
244 fib6_link_table(net, net->ipv6.fib6_main_tbl); 236 fib6_link_table(net, net->ipv6.fib6_main_tbl);
245 fib6_link_table(net, net->ipv6.fib6_local_tbl); 237 fib6_link_table(net, net->ipv6.fib6_local_tbl);
@@ -262,7 +254,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); 254 return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl, flags);
263} 255}
264 256
265static void fib6_tables_init(struct net *net) 257static void __net_init fib6_tables_init(struct net *net)
266{ 258{
267 fib6_link_table(net, net->ipv6.fib6_main_tbl); 259 fib6_link_table(net, net->ipv6.fib6_main_tbl);
268} 260}
@@ -319,12 +311,26 @@ static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb,
319 w->root = &table->tb6_root; 311 w->root = &table->tb6_root;
320 312
321 if (cb->args[4] == 0) { 313 if (cb->args[4] == 0) {
314 w->count = 0;
315 w->skip = 0;
316
322 read_lock_bh(&table->tb6_lock); 317 read_lock_bh(&table->tb6_lock);
323 res = fib6_walk(w); 318 res = fib6_walk(w);
324 read_unlock_bh(&table->tb6_lock); 319 read_unlock_bh(&table->tb6_lock);
325 if (res > 0) 320 if (res > 0) {
326 cb->args[4] = 1; 321 cb->args[4] = 1;
322 cb->args[5] = w->root->fn_sernum;
323 }
327 } else { 324 } else {
325 if (cb->args[5] != w->root->fn_sernum) {
326 /* Begin at the root if the tree changed */
327 cb->args[5] = w->root->fn_sernum;
328 w->state = FWS_INIT;
329 w->node = w->root;
330 w->skip = w->count;
331 } else
332 w->skip = 0;
333
328 read_lock_bh(&table->tb6_lock); 334 read_lock_bh(&table->tb6_lock);
329 res = fib6_walk_continue(w); 335 res = fib6_walk_continue(w);
330 read_unlock_bh(&table->tb6_lock); 336 read_unlock_bh(&table->tb6_lock);
@@ -1250,9 +1256,18 @@ static int fib6_walk_continue(struct fib6_walker_t *w)
1250 w->leaf = fn->leaf; 1256 w->leaf = fn->leaf;
1251 case FWS_C: 1257 case FWS_C:
1252 if (w->leaf && fn->fn_flags&RTN_RTINFO) { 1258 if (w->leaf && fn->fn_flags&RTN_RTINFO) {
1253 int err = w->func(w); 1259 int err;
1260
1261 if (w->count < w->skip) {
1262 w->count++;
1263 continue;
1264 }
1265
1266 err = w->func(w);
1254 if (err) 1267 if (err)
1255 return err; 1268 return err;
1269
1270 w->count++;
1256 continue; 1271 continue;
1257 } 1272 }
1258 w->state = FWS_U; 1273 w->state = FWS_U;
@@ -1346,6 +1361,8 @@ static void fib6_clean_tree(struct net *net, struct fib6_node *root,
1346 c.w.root = root; 1361 c.w.root = root;
1347 c.w.func = fib6_clean_node; 1362 c.w.func = fib6_clean_node;
1348 c.w.prune = prune; 1363 c.w.prune = prune;
1364 c.w.count = 0;
1365 c.w.skip = 0;
1349 c.func = func; 1366 c.func = func;
1350 c.arg = arg; 1367 c.arg = arg;
1351 c.net = net; 1368 c.net = net;
@@ -1469,7 +1486,7 @@ static void fib6_gc_timer_cb(unsigned long arg)
1469 fib6_run_gc(0, (struct net *)arg); 1486 fib6_run_gc(0, (struct net *)arg);
1470} 1487}
1471 1488
1472static int fib6_net_init(struct net *net) 1489static int __net_init fib6_net_init(struct net *net)
1473{ 1490{
1474 setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net); 1491 setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net);
1475 1492
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 7712578bdc66..14e23216eb28 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -20,6 +20,7 @@
20#include <linux/route.h> 20#include <linux/route.h>
21#include <linux/proc_fs.h> 21#include <linux/proc_fs.h>
22#include <linux/seq_file.h> 22#include <linux/seq_file.h>
23#include <linux/slab.h>
23 24
24#include <net/net_namespace.h> 25#include <net/net_namespace.h>
25#include <net/sock.h> 26#include <net/sock.h>
@@ -67,7 +68,7 @@ static inline struct ip6_flowlabel *__fl_lookup(struct net *net, __be32 label)
67 struct ip6_flowlabel *fl; 68 struct ip6_flowlabel *fl;
68 69
69 for (fl=fl_ht[FL_HASH(label)]; fl; fl = fl->next) { 70 for (fl=fl_ht[FL_HASH(label)]; fl; fl = fl->next) {
70 if (fl->label == label && fl->fl_net == net) 71 if (fl->label == label && net_eq(fl->fl_net, net))
71 return fl; 72 return fl;
72 } 73 }
73 return NULL; 74 return NULL;
@@ -154,7 +155,7 @@ static void ip6_fl_gc(unsigned long dummy)
154 write_unlock(&ip6_fl_lock); 155 write_unlock(&ip6_fl_lock);
155} 156}
156 157
157static void ip6_fl_purge(struct net *net) 158static void __net_exit ip6_fl_purge(struct net *net)
158{ 159{
159 int i; 160 int i;
160 161
@@ -163,7 +164,8 @@ static void ip6_fl_purge(struct net *net)
163 struct ip6_flowlabel *fl, **flp; 164 struct ip6_flowlabel *fl, **flp;
164 flp = &fl_ht[i]; 165 flp = &fl_ht[i];
165 while ((fl = *flp) != NULL) { 166 while ((fl = *flp) != NULL) {
166 if (fl->fl_net == net && atomic_read(&fl->users) == 0) { 167 if (net_eq(fl->fl_net, net) &&
168 atomic_read(&fl->users) == 0) {
167 *flp = fl->next; 169 *flp = fl->next;
168 fl_free(fl); 170 fl_free(fl);
169 atomic_dec(&fl_size); 171 atomic_dec(&fl_size);
@@ -377,8 +379,8 @@ fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval,
377 goto done; 379 goto done;
378 fl->share = freq->flr_share; 380 fl->share = freq->flr_share;
379 addr_type = ipv6_addr_type(&freq->flr_dst); 381 addr_type = ipv6_addr_type(&freq->flr_dst);
380 if ((addr_type&IPV6_ADDR_MAPPED) 382 if ((addr_type & IPV6_ADDR_MAPPED) ||
381 || addr_type == IPV6_ADDR_ANY) { 383 addr_type == IPV6_ADDR_ANY) {
382 err = -EINVAL; 384 err = -EINVAL;
383 goto done; 385 goto done;
384 } 386 }
@@ -421,8 +423,8 @@ static int mem_check(struct sock *sk)
421 423
422 if (room <= 0 || 424 if (room <= 0 ||
423 ((count >= FL_MAX_PER_SOCK || 425 ((count >= FL_MAX_PER_SOCK ||
424 (count > 0 && room < FL_MAX_SIZE/2) || room < FL_MAX_SIZE/4) 426 (count > 0 && room < FL_MAX_SIZE/2) || room < FL_MAX_SIZE/4) &&
425 && !capable(CAP_NET_ADMIN))) 427 !capable(CAP_NET_ADMIN)))
426 return -ENOBUFS; 428 return -ENOBUFS;
427 429
428 return 0; 430 return 0;
@@ -630,7 +632,7 @@ static struct ip6_flowlabel *ip6fl_get_first(struct seq_file *seq)
630 for (state->bucket = 0; state->bucket <= FL_HASH_MASK; ++state->bucket) { 632 for (state->bucket = 0; state->bucket <= FL_HASH_MASK; ++state->bucket) {
631 fl = fl_ht[state->bucket]; 633 fl = fl_ht[state->bucket];
632 634
633 while (fl && fl->fl_net != net) 635 while (fl && !net_eq(fl->fl_net, net))
634 fl = fl->next; 636 fl = fl->next;
635 if (fl) 637 if (fl)
636 break; 638 break;
@@ -645,7 +647,7 @@ static struct ip6_flowlabel *ip6fl_get_next(struct seq_file *seq, struct ip6_flo
645 647
646 fl = fl->next; 648 fl = fl->next;
647try_again: 649try_again:
648 while (fl && fl->fl_net != net) 650 while (fl && !net_eq(fl->fl_net, net))
649 fl = fl->next; 651 fl = fl->next;
650 652
651 while (!fl) { 653 while (!fl) {
@@ -734,7 +736,7 @@ static const struct file_operations ip6fl_seq_fops = {
734 .release = seq_release_net, 736 .release = seq_release_net,
735}; 737};
736 738
737static int ip6_flowlabel_proc_init(struct net *net) 739static int __net_init ip6_flowlabel_proc_init(struct net *net)
738{ 740{
739 if (!proc_net_fops_create(net, "ip6_flowlabel", 741 if (!proc_net_fops_create(net, "ip6_flowlabel",
740 S_IRUGO, &ip6fl_seq_fops)) 742 S_IRUGO, &ip6fl_seq_fops))
@@ -742,7 +744,7 @@ static int ip6_flowlabel_proc_init(struct net *net)
742 return 0; 744 return 0;
743} 745}
744 746
745static void ip6_flowlabel_proc_fini(struct net *net) 747static void __net_exit ip6_flowlabel_proc_fini(struct net *net)
746{ 748{
747 proc_net_remove(net, "ip6_flowlabel"); 749 proc_net_remove(net, "ip6_flowlabel");
748} 750}
@@ -753,11 +755,10 @@ static inline int ip6_flowlabel_proc_init(struct net *net)
753} 755}
754static inline void ip6_flowlabel_proc_fini(struct net *net) 756static inline void ip6_flowlabel_proc_fini(struct net *net)
755{ 757{
756 return ;
757} 758}
758#endif 759#endif
759 760
760static inline void ip6_flowlabel_net_exit(struct net *net) 761static void __net_exit ip6_flowlabel_net_exit(struct net *net)
761{ 762{
762 ip6_fl_purge(net); 763 ip6_fl_purge(net);
763 ip6_flowlabel_proc_fini(net); 764 ip6_flowlabel_proc_fini(net);
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 237e2dba6e94..6aa7ee1295c2 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -28,6 +28,7 @@
28#include <linux/in6.h> 28#include <linux/in6.h>
29#include <linux/icmpv6.h> 29#include <linux/icmpv6.h>
30#include <linux/mroute6.h> 30#include <linux/mroute6.h>
31#include <linux/slab.h>
31 32
32#include <linux/netfilter.h> 33#include <linux/netfilter.h>
33#include <linux/netfilter_ipv6.h> 34#include <linux/netfilter_ipv6.h>
@@ -216,8 +217,7 @@ resubmit:
216 IP6_INC_STATS_BH(net, idev, 217 IP6_INC_STATS_BH(net, idev,
217 IPSTATS_MIB_INUNKNOWNPROTOS); 218 IPSTATS_MIB_INUNKNOWNPROTOS);
218 icmpv6_send(skb, ICMPV6_PARAMPROB, 219 icmpv6_send(skb, ICMPV6_PARAMPROB,
219 ICMPV6_UNK_NEXTHDR, nhoff, 220 ICMPV6_UNK_NEXTHDR, nhoff);
220 skb->dev);
221 } 221 }
222 } else 222 } else
223 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS); 223 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index cd48801a8d6f..75d5ef830097 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -37,6 +37,7 @@
37#include <linux/tcp.h> 37#include <linux/tcp.h>
38#include <linux/route.h> 38#include <linux/route.h>
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/slab.h>
40 41
41#include <linux/netfilter.h> 42#include <linux/netfilter.h>
42#include <linux/netfilter_ipv6.h> 43#include <linux/netfilter_ipv6.h>
@@ -107,7 +108,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
107 newskb->ip_summed = CHECKSUM_UNNECESSARY; 108 newskb->ip_summed = CHECKSUM_UNNECESSARY;
108 WARN_ON(!skb_dst(newskb)); 109 WARN_ON(!skb_dst(newskb));
109 110
110 netif_rx(newskb); 111 netif_rx_ni(newskb);
111 return 0; 112 return 0;
112} 113}
113 114
@@ -121,10 +122,9 @@ static int ip6_output2(struct sk_buff *skb)
121 skb->dev = dev; 122 skb->dev = dev;
122 123
123 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) { 124 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
124 struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL;
125 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); 125 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
126 126
127 if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && 127 if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(skb->sk) &&
128 ((mroute6_socket(dev_net(dev)) && 128 ((mroute6_socket(dev_net(dev)) &&
129 !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || 129 !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) ||
130 ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr, 130 ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,
@@ -268,7 +268,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
268 if (net_ratelimit()) 268 if (net_ratelimit())
269 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); 269 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
270 skb->dev = dst->dev; 270 skb->dev = dst->dev;
271 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 271 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
272 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); 272 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS);
273 kfree_skb(skb); 273 kfree_skb(skb);
274 return -EMSGSIZE; 274 return -EMSGSIZE;
@@ -403,6 +403,7 @@ int ip6_forward(struct sk_buff *skb)
403 struct ipv6hdr *hdr = ipv6_hdr(skb); 403 struct ipv6hdr *hdr = ipv6_hdr(skb);
404 struct inet6_skb_parm *opt = IP6CB(skb); 404 struct inet6_skb_parm *opt = IP6CB(skb);
405 struct net *net = dev_net(dst->dev); 405 struct net *net = dev_net(dst->dev);
406 u32 mtu;
406 407
407 if (net->ipv6.devconf_all->forwarding == 0) 408 if (net->ipv6.devconf_all->forwarding == 0)
408 goto error; 409 goto error;
@@ -442,8 +443,7 @@ int ip6_forward(struct sk_buff *skb)
442 if (hdr->hop_limit <= 1) { 443 if (hdr->hop_limit <= 1) {
443 /* Force OUTPUT device used as source address */ 444 /* Force OUTPUT device used as source address */
444 skb->dev = dst->dev; 445 skb->dev = dst->dev;
445 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 446 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0);
446 0, skb->dev);
447 IP6_INC_STATS_BH(net, 447 IP6_INC_STATS_BH(net,
448 ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); 448 ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
449 449
@@ -505,15 +505,19 @@ int ip6_forward(struct sk_buff *skb)
505 goto error; 505 goto error;
506 if (addrtype & IPV6_ADDR_LINKLOCAL) { 506 if (addrtype & IPV6_ADDR_LINKLOCAL) {
507 icmpv6_send(skb, ICMPV6_DEST_UNREACH, 507 icmpv6_send(skb, ICMPV6_DEST_UNREACH,
508 ICMPV6_NOT_NEIGHBOUR, 0, skb->dev); 508 ICMPV6_NOT_NEIGHBOUR, 0);
509 goto error; 509 goto error;
510 } 510 }
511 } 511 }
512 512
513 if (skb->len > dst_mtu(dst)) { 513 mtu = dst_mtu(dst);
514 if (mtu < IPV6_MIN_MTU)
515 mtu = IPV6_MIN_MTU;
516
517 if (skb->len > mtu) {
514 /* Again, force OUTPUT device used as source address */ 518 /* Again, force OUTPUT device used as source address */
515 skb->dev = dst->dev; 519 skb->dev = dst->dev;
516 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); 520 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
517 IP6_INC_STATS_BH(net, 521 IP6_INC_STATS_BH(net,
518 ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); 522 ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS);
519 IP6_INC_STATS_BH(net, 523 IP6_INC_STATS_BH(net,
@@ -623,12 +627,11 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
623 mtu = ip6_skb_dst_mtu(skb); 627 mtu = ip6_skb_dst_mtu(skb);
624 628
625 /* We must not fragment if the socket is set to force MTU discovery 629 /* We must not fragment if the socket is set to force MTU discovery
626 * or if the skb it not generated by a local socket. (This last 630 * or if the skb it not generated by a local socket.
627 * check should be redundant, but it's free.)
628 */ 631 */
629 if (!skb->local_df) { 632 if (!skb->local_df && skb->len > mtu) {
630 skb->dev = skb_dst(skb)->dev; 633 skb->dev = skb_dst(skb)->dev;
631 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 634 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
632 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 635 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
633 IPSTATS_MIB_FRAGFAILS); 636 IPSTATS_MIB_FRAGFAILS);
634 kfree_skb(skb); 637 kfree_skb(skb);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index c595bbe1ed99..2599870747ec 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -37,6 +37,7 @@
37#include <linux/route.h> 37#include <linux/route.h>
38#include <linux/rtnetlink.h> 38#include <linux/rtnetlink.h>
39#include <linux/netfilter_ipv6.h> 39#include <linux/netfilter_ipv6.h>
40#include <linux/slab.h>
40 41
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42#include <asm/atomic.h> 43#include <asm/atomic.h>
@@ -74,11 +75,10 @@ MODULE_LICENSE("GPL");
74 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ 75 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \
75 (HASH_SIZE - 1)) 76 (HASH_SIZE - 1))
76 77
77static void ip6_fb_tnl_dev_init(struct net_device *dev);
78static void ip6_tnl_dev_init(struct net_device *dev); 78static void ip6_tnl_dev_init(struct net_device *dev);
79static void ip6_tnl_dev_setup(struct net_device *dev); 79static void ip6_tnl_dev_setup(struct net_device *dev);
80 80
81static int ip6_tnl_net_id; 81static int ip6_tnl_net_id __read_mostly;
82struct ip6_tnl_net { 82struct ip6_tnl_net {
83 /* the IPv6 tunnel fallback device */ 83 /* the IPv6 tunnel fallback device */
84 struct net_device *fb_tnl_dev; 84 struct net_device *fb_tnl_dev;
@@ -88,8 +88,10 @@ struct ip6_tnl_net {
88 struct ip6_tnl **tnls[2]; 88 struct ip6_tnl **tnls[2];
89}; 89};
90 90
91/* lock for the tunnel lists */ 91/*
92static DEFINE_RWLOCK(ip6_tnl_lock); 92 * Locking : hash tables are protected by RCU and a spinlock
93 */
94static DEFINE_SPINLOCK(ip6_tnl_lock);
93 95
94static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t) 96static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t)
95{ 97{
@@ -130,6 +132,9 @@ static inline void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst)
130 * else %NULL 132 * else %NULL
131 **/ 133 **/
132 134
135#define for_each_ip6_tunnel_rcu(start) \
136 for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
137
133static struct ip6_tnl * 138static struct ip6_tnl *
134ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local) 139ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local)
135{ 140{
@@ -138,13 +143,14 @@ ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local)
138 struct ip6_tnl *t; 143 struct ip6_tnl *t;
139 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 144 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
140 145
141 for (t = ip6n->tnls_r_l[h0 ^ h1]; t; t = t->next) { 146 for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[h0 ^ h1]) {
142 if (ipv6_addr_equal(local, &t->parms.laddr) && 147 if (ipv6_addr_equal(local, &t->parms.laddr) &&
143 ipv6_addr_equal(remote, &t->parms.raddr) && 148 ipv6_addr_equal(remote, &t->parms.raddr) &&
144 (t->dev->flags & IFF_UP)) 149 (t->dev->flags & IFF_UP))
145 return t; 150 return t;
146 } 151 }
147 if ((t = ip6n->tnls_wc[0]) != NULL && (t->dev->flags & IFF_UP)) 152 t = rcu_dereference(ip6n->tnls_wc[0]);
153 if (t && (t->dev->flags & IFF_UP))
148 return t; 154 return t;
149 155
150 return NULL; 156 return NULL;
@@ -186,10 +192,10 @@ ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
186{ 192{
187 struct ip6_tnl **tp = ip6_tnl_bucket(ip6n, &t->parms); 193 struct ip6_tnl **tp = ip6_tnl_bucket(ip6n, &t->parms);
188 194
195 spin_lock_bh(&ip6_tnl_lock);
189 t->next = *tp; 196 t->next = *tp;
190 write_lock_bh(&ip6_tnl_lock); 197 rcu_assign_pointer(*tp, t);
191 *tp = t; 198 spin_unlock_bh(&ip6_tnl_lock);
192 write_unlock_bh(&ip6_tnl_lock);
193} 199}
194 200
195/** 201/**
@@ -204,9 +210,9 @@ ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
204 210
205 for (tp = ip6_tnl_bucket(ip6n, &t->parms); *tp; tp = &(*tp)->next) { 211 for (tp = ip6_tnl_bucket(ip6n, &t->parms); *tp; tp = &(*tp)->next) {
206 if (t == *tp) { 212 if (t == *tp) {
207 write_lock_bh(&ip6_tnl_lock); 213 spin_lock_bh(&ip6_tnl_lock);
208 *tp = t->next; 214 *tp = t->next;
209 write_unlock_bh(&ip6_tnl_lock); 215 spin_unlock_bh(&ip6_tnl_lock);
210 break; 216 break;
211 } 217 }
212 } 218 }
@@ -313,9 +319,9 @@ ip6_tnl_dev_uninit(struct net_device *dev)
313 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 319 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
314 320
315 if (dev == ip6n->fb_tnl_dev) { 321 if (dev == ip6n->fb_tnl_dev) {
316 write_lock_bh(&ip6_tnl_lock); 322 spin_lock_bh(&ip6_tnl_lock);
317 ip6n->tnls_wc[0] = NULL; 323 ip6n->tnls_wc[0] = NULL;
318 write_unlock_bh(&ip6_tnl_lock); 324 spin_unlock_bh(&ip6_tnl_lock);
319 } else { 325 } else {
320 ip6_tnl_unlink(ip6n, t); 326 ip6_tnl_unlink(ip6n, t);
321 } 327 }
@@ -409,7 +415,7 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
409 in trouble since we might need the source address for further 415 in trouble since we might need the source address for further
410 processing of the error. */ 416 processing of the error. */
411 417
412 read_lock(&ip6_tnl_lock); 418 rcu_read_lock();
413 if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->daddr, 419 if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->daddr,
414 &ipv6h->saddr)) == NULL) 420 &ipv6h->saddr)) == NULL)
415 goto out; 421 goto out;
@@ -482,7 +488,7 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
482 *msg = rel_msg; 488 *msg = rel_msg;
483 489
484out: 490out:
485 read_unlock(&ip6_tnl_lock); 491 rcu_read_unlock();
486 return err; 492 return err;
487} 493}
488 494
@@ -617,7 +623,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
617 if (rt && rt->rt6i_dev) 623 if (rt && rt->rt6i_dev)
618 skb2->dev = rt->rt6i_dev; 624 skb2->dev = rt->rt6i_dev;
619 625
620 icmpv6_send(skb2, rel_type, rel_code, rel_info, skb2->dev); 626 icmpv6_send(skb2, rel_type, rel_code, rel_info);
621 627
622 if (rt) 628 if (rt)
623 dst_release(&rt->u.dst); 629 dst_release(&rt->u.dst);
@@ -652,6 +658,7 @@ static void ip6ip6_dscp_ecn_decapsulate(struct ip6_tnl *t,
652 IP6_ECN_set_ce(ipv6_hdr(skb)); 658 IP6_ECN_set_ce(ipv6_hdr(skb));
653} 659}
654 660
661/* called with rcu_read_lock() */
655static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t) 662static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
656{ 663{
657 struct ip6_tnl_parm *p = &t->parms; 664 struct ip6_tnl_parm *p = &t->parms;
@@ -662,15 +669,13 @@ static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
662 struct net_device *ldev = NULL; 669 struct net_device *ldev = NULL;
663 670
664 if (p->link) 671 if (p->link)
665 ldev = dev_get_by_index(net, p->link); 672 ldev = dev_get_by_index_rcu(net, p->link);
666 673
667 if ((ipv6_addr_is_multicast(&p->laddr) || 674 if ((ipv6_addr_is_multicast(&p->laddr) ||
668 likely(ipv6_chk_addr(net, &p->laddr, ldev, 0))) && 675 likely(ipv6_chk_addr(net, &p->laddr, ldev, 0))) &&
669 likely(!ipv6_chk_addr(net, &p->raddr, NULL, 0))) 676 likely(!ipv6_chk_addr(net, &p->raddr, NULL, 0)))
670 ret = 1; 677 ret = 1;
671 678
672 if (ldev)
673 dev_put(ldev);
674 } 679 }
675 return ret; 680 return ret;
676} 681}
@@ -693,23 +698,23 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
693 struct ip6_tnl *t; 698 struct ip6_tnl *t;
694 struct ipv6hdr *ipv6h = ipv6_hdr(skb); 699 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
695 700
696 read_lock(&ip6_tnl_lock); 701 rcu_read_lock();
697 702
698 if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, 703 if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr,
699 &ipv6h->daddr)) != NULL) { 704 &ipv6h->daddr)) != NULL) {
700 if (t->parms.proto != ipproto && t->parms.proto != 0) { 705 if (t->parms.proto != ipproto && t->parms.proto != 0) {
701 read_unlock(&ip6_tnl_lock); 706 rcu_read_unlock();
702 goto discard; 707 goto discard;
703 } 708 }
704 709
705 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 710 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
706 read_unlock(&ip6_tnl_lock); 711 rcu_read_unlock();
707 goto discard; 712 goto discard;
708 } 713 }
709 714
710 if (!ip6_tnl_rcv_ctl(t)) { 715 if (!ip6_tnl_rcv_ctl(t)) {
711 t->dev->stats.rx_dropped++; 716 t->dev->stats.rx_dropped++;
712 read_unlock(&ip6_tnl_lock); 717 rcu_read_unlock();
713 goto discard; 718 goto discard;
714 } 719 }
715 secpath_reset(skb); 720 secpath_reset(skb);
@@ -727,10 +732,10 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
727 t->dev->stats.rx_packets++; 732 t->dev->stats.rx_packets++;
728 t->dev->stats.rx_bytes += skb->len; 733 t->dev->stats.rx_bytes += skb->len;
729 netif_rx(skb); 734 netif_rx(skb);
730 read_unlock(&ip6_tnl_lock); 735 rcu_read_unlock();
731 return 0; 736 return 0;
732 } 737 }
733 read_unlock(&ip6_tnl_lock); 738 rcu_read_unlock();
734 return 1; 739 return 1;
735 740
736discard: 741discard:
@@ -798,8 +803,9 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
798 if (p->flags & IP6_TNL_F_CAP_XMIT) { 803 if (p->flags & IP6_TNL_F_CAP_XMIT) {
799 struct net_device *ldev = NULL; 804 struct net_device *ldev = NULL;
800 805
806 rcu_read_lock();
801 if (p->link) 807 if (p->link)
802 ldev = dev_get_by_index(net, p->link); 808 ldev = dev_get_by_index_rcu(net, p->link);
803 809
804 if (unlikely(!ipv6_chk_addr(net, &p->laddr, ldev, 0))) 810 if (unlikely(!ipv6_chk_addr(net, &p->laddr, ldev, 0)))
805 printk(KERN_WARNING 811 printk(KERN_WARNING
@@ -813,8 +819,7 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
813 p->name); 819 p->name);
814 else 820 else
815 ret = 1; 821 ret = 1;
816 if (ldev) 822 rcu_read_unlock();
817 dev_put(ldev);
818 } 823 }
819 return ret; 824 return ret;
820} 825}
@@ -1010,7 +1015,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1010 tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset]; 1015 tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset];
1011 if (tel->encap_limit == 0) { 1016 if (tel->encap_limit == 0) {
1012 icmpv6_send(skb, ICMPV6_PARAMPROB, 1017 icmpv6_send(skb, ICMPV6_PARAMPROB,
1013 ICMPV6_HDR_FIELD, offset + 2, skb->dev); 1018 ICMPV6_HDR_FIELD, offset + 2);
1014 return -1; 1019 return -1;
1015 } 1020 }
1016 encap_limit = tel->encap_limit - 1; 1021 encap_limit = tel->encap_limit - 1;
@@ -1029,7 +1034,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1029 err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu); 1034 err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu);
1030 if (err != 0) { 1035 if (err != 0) {
1031 if (err == -EMSGSIZE) 1036 if (err == -EMSGSIZE)
1032 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); 1037 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
1033 return -1; 1038 return -1;
1034 } 1039 }
1035 1040
@@ -1359,7 +1364,7 @@ static void ip6_tnl_dev_init(struct net_device *dev)
1359 * Return: 0 1364 * Return: 0
1360 **/ 1365 **/
1361 1366
1362static void ip6_fb_tnl_dev_init(struct net_device *dev) 1367static void __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
1363{ 1368{
1364 struct ip6_tnl *t = netdev_priv(dev); 1369 struct ip6_tnl *t = netdev_priv(dev);
1365 struct net *net = dev_net(dev); 1370 struct net *net = dev_net(dev);
@@ -1383,33 +1388,29 @@ static struct xfrm6_tunnel ip6ip6_handler = {
1383 .priority = 1, 1388 .priority = 1,
1384}; 1389};
1385 1390
1386static void ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n) 1391static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
1387{ 1392{
1388 int h; 1393 int h;
1389 struct ip6_tnl *t; 1394 struct ip6_tnl *t;
1395 LIST_HEAD(list);
1390 1396
1391 for (h = 0; h < HASH_SIZE; h++) { 1397 for (h = 0; h < HASH_SIZE; h++) {
1392 while ((t = ip6n->tnls_r_l[h]) != NULL) 1398 t = ip6n->tnls_r_l[h];
1393 unregister_netdevice(t->dev); 1399 while (t != NULL) {
1400 unregister_netdevice_queue(t->dev, &list);
1401 t = t->next;
1402 }
1394 } 1403 }
1395 1404
1396 t = ip6n->tnls_wc[0]; 1405 t = ip6n->tnls_wc[0];
1397 unregister_netdevice(t->dev); 1406 unregister_netdevice_queue(t->dev, &list);
1407 unregister_netdevice_many(&list);
1398} 1408}
1399 1409
1400static int ip6_tnl_init_net(struct net *net) 1410static int __net_init ip6_tnl_init_net(struct net *net)
1401{ 1411{
1412 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1402 int err; 1413 int err;
1403 struct ip6_tnl_net *ip6n;
1404
1405 err = -ENOMEM;
1406 ip6n = kzalloc(sizeof(struct ip6_tnl_net), GFP_KERNEL);
1407 if (ip6n == NULL)
1408 goto err_alloc;
1409
1410 err = net_assign_generic(net, ip6_tnl_net_id, ip6n);
1411 if (err < 0)
1412 goto err_assign;
1413 1414
1414 ip6n->tnls[0] = ip6n->tnls_wc; 1415 ip6n->tnls[0] = ip6n->tnls_wc;
1415 ip6n->tnls[1] = ip6n->tnls_r_l; 1416 ip6n->tnls[1] = ip6n->tnls_r_l;
@@ -1432,27 +1433,23 @@ static int ip6_tnl_init_net(struct net *net)
1432err_register: 1433err_register:
1433 free_netdev(ip6n->fb_tnl_dev); 1434 free_netdev(ip6n->fb_tnl_dev);
1434err_alloc_dev: 1435err_alloc_dev:
1435 /* nothing */
1436err_assign:
1437 kfree(ip6n);
1438err_alloc:
1439 return err; 1436 return err;
1440} 1437}
1441 1438
1442static void ip6_tnl_exit_net(struct net *net) 1439static void __net_exit ip6_tnl_exit_net(struct net *net)
1443{ 1440{
1444 struct ip6_tnl_net *ip6n; 1441 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1445 1442
1446 ip6n = net_generic(net, ip6_tnl_net_id);
1447 rtnl_lock(); 1443 rtnl_lock();
1448 ip6_tnl_destroy_tunnels(ip6n); 1444 ip6_tnl_destroy_tunnels(ip6n);
1449 rtnl_unlock(); 1445 rtnl_unlock();
1450 kfree(ip6n);
1451} 1446}
1452 1447
1453static struct pernet_operations ip6_tnl_net_ops = { 1448static struct pernet_operations ip6_tnl_net_ops = {
1454 .init = ip6_tnl_init_net, 1449 .init = ip6_tnl_init_net,
1455 .exit = ip6_tnl_exit_net, 1450 .exit = ip6_tnl_exit_net,
1451 .id = &ip6_tnl_net_id,
1452 .size = sizeof(struct ip6_tnl_net),
1456}; 1453};
1457 1454
1458/** 1455/**
@@ -1465,27 +1462,29 @@ static int __init ip6_tunnel_init(void)
1465{ 1462{
1466 int err; 1463 int err;
1467 1464
1468 if (xfrm6_tunnel_register(&ip4ip6_handler, AF_INET)) { 1465 err = register_pernet_device(&ip6_tnl_net_ops);
1466 if (err < 0)
1467 goto out_pernet;
1468
1469 err = xfrm6_tunnel_register(&ip4ip6_handler, AF_INET);
1470 if (err < 0) {
1469 printk(KERN_ERR "ip6_tunnel init: can't register ip4ip6\n"); 1471 printk(KERN_ERR "ip6_tunnel init: can't register ip4ip6\n");
1470 err = -EAGAIN; 1472 goto out_ip4ip6;
1471 goto out;
1472 } 1473 }
1473 1474
1474 if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) { 1475 err = xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6);
1476 if (err < 0) {
1475 printk(KERN_ERR "ip6_tunnel init: can't register ip6ip6\n"); 1477 printk(KERN_ERR "ip6_tunnel init: can't register ip6ip6\n");
1476 err = -EAGAIN; 1478 goto out_ip6ip6;
1477 goto unreg_ip4ip6;
1478 } 1479 }
1479 1480
1480 err = register_pernet_gen_device(&ip6_tnl_net_id, &ip6_tnl_net_ops);
1481 if (err < 0)
1482 goto err_pernet;
1483 return 0; 1481 return 0;
1484err_pernet: 1482
1485 xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6); 1483out_ip6ip6:
1486unreg_ip4ip6:
1487 xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET); 1484 xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET);
1488out: 1485out_ip4ip6:
1486 unregister_pernet_device(&ip6_tnl_net_ops);
1487out_pernet:
1489 return err; 1488 return err;
1490} 1489}
1491 1490
@@ -1501,7 +1500,7 @@ static void __exit ip6_tunnel_cleanup(void)
1501 if (xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6)) 1500 if (xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6))
1502 printk(KERN_INFO "ip6_tunnel close: can't deregister ip6ip6\n"); 1501 printk(KERN_INFO "ip6_tunnel close: can't deregister ip6ip6\n");
1503 1502
1504 unregister_pernet_gen_device(ip6_tnl_net_id, &ip6_tnl_net_ops); 1503 unregister_pernet_device(&ip6_tnl_net_ops);
1505} 1504}
1506 1505
1507module_init(ip6_tunnel_init); 1506module_init(ip6_tunnel_init);
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 716153941fc4..3e333268db89 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -33,6 +33,7 @@
33#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
34#include <linux/seq_file.h> 34#include <linux/seq_file.h>
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/slab.h>
36#include <net/protocol.h> 37#include <net/protocol.h>
37#include <linux/skbuff.h> 38#include <linux/skbuff.h>
38#include <net/sock.h> 39#include <net/sock.h>
@@ -477,7 +478,7 @@ failure:
477 * Delete a VIF entry 478 * Delete a VIF entry
478 */ 479 */
479 480
480static int mif6_delete(struct net *net, int vifi) 481static int mif6_delete(struct net *net, int vifi, struct list_head *head)
481{ 482{
482 struct mif_device *v; 483 struct mif_device *v;
483 struct net_device *dev; 484 struct net_device *dev;
@@ -519,7 +520,7 @@ static int mif6_delete(struct net *net, int vifi)
519 in6_dev->cnf.mc_forwarding--; 520 in6_dev->cnf.mc_forwarding--;
520 521
521 if (v->flags & MIFF_REGISTER) 522 if (v->flags & MIFF_REGISTER)
522 unregister_netdevice(dev); 523 unregister_netdevice_queue(dev, head);
523 524
524 dev_put(dev); 525 dev_put(dev);
525 return 0; 526 return 0;
@@ -976,6 +977,7 @@ static int ip6mr_device_event(struct notifier_block *this,
976 struct net *net = dev_net(dev); 977 struct net *net = dev_net(dev);
977 struct mif_device *v; 978 struct mif_device *v;
978 int ct; 979 int ct;
980 LIST_HEAD(list);
979 981
980 if (event != NETDEV_UNREGISTER) 982 if (event != NETDEV_UNREGISTER)
981 return NOTIFY_DONE; 983 return NOTIFY_DONE;
@@ -983,8 +985,10 @@ static int ip6mr_device_event(struct notifier_block *this,
983 v = &net->ipv6.vif6_table[0]; 985 v = &net->ipv6.vif6_table[0];
984 for (ct = 0; ct < net->ipv6.maxvif; ct++, v++) { 986 for (ct = 0; ct < net->ipv6.maxvif; ct++, v++) {
985 if (v->dev == dev) 987 if (v->dev == dev)
986 mif6_delete(net, ct); 988 mif6_delete(net, ct, &list);
987 } 989 }
990 unregister_netdevice_many(&list);
991
988 return NOTIFY_DONE; 992 return NOTIFY_DONE;
989} 993}
990 994
@@ -1110,6 +1114,9 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock)
1110 unsigned char ttls[MAXMIFS]; 1114 unsigned char ttls[MAXMIFS];
1111 int i; 1115 int i;
1112 1116
1117 if (mfc->mf6cc_parent >= MAXMIFS)
1118 return -ENFILE;
1119
1113 memset(ttls, 255, MAXMIFS); 1120 memset(ttls, 255, MAXMIFS);
1114 for (i = 0; i < MAXMIFS; i++) { 1121 for (i = 0; i < MAXMIFS; i++) {
1115 if (IF_ISSET(i, &mfc->mf6cc_ifset)) 1122 if (IF_ISSET(i, &mfc->mf6cc_ifset))
@@ -1188,14 +1195,16 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock)
1188static void mroute_clean_tables(struct net *net) 1195static void mroute_clean_tables(struct net *net)
1189{ 1196{
1190 int i; 1197 int i;
1198 LIST_HEAD(list);
1191 1199
1192 /* 1200 /*
1193 * Shut down all active vif entries 1201 * Shut down all active vif entries
1194 */ 1202 */
1195 for (i = 0; i < net->ipv6.maxvif; i++) { 1203 for (i = 0; i < net->ipv6.maxvif; i++) {
1196 if (!(net->ipv6.vif6_table[i].flags & VIFF_STATIC)) 1204 if (!(net->ipv6.vif6_table[i].flags & VIFF_STATIC))
1197 mif6_delete(net, i); 1205 mif6_delete(net, i, &list);
1198 } 1206 }
1207 unregister_netdevice_many(&list);
1199 1208
1200 /* 1209 /*
1201 * Wipe the cache 1210 * Wipe the cache
@@ -1297,7 +1306,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
1297 switch (optname) { 1306 switch (optname) {
1298 case MRT6_INIT: 1307 case MRT6_INIT:
1299 if (sk->sk_type != SOCK_RAW || 1308 if (sk->sk_type != SOCK_RAW ||
1300 inet_sk(sk)->num != IPPROTO_ICMPV6) 1309 inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1301 return -EOPNOTSUPP; 1310 return -EOPNOTSUPP;
1302 if (optlen < sizeof(int)) 1311 if (optlen < sizeof(int))
1303 return -EINVAL; 1312 return -EINVAL;
@@ -1325,7 +1334,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
1325 if (copy_from_user(&mifi, optval, sizeof(mifi_t))) 1334 if (copy_from_user(&mifi, optval, sizeof(mifi_t)))
1326 return -EFAULT; 1335 return -EFAULT;
1327 rtnl_lock(); 1336 rtnl_lock();
1328 ret = mif6_delete(net, mifi); 1337 ret = mif6_delete(net, mifi, NULL);
1329 rtnl_unlock(); 1338 rtnl_unlock();
1330 return ret; 1339 return ret;
1331 1340
@@ -1687,17 +1696,20 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm)
1687 int ct; 1696 int ct;
1688 struct rtnexthop *nhp; 1697 struct rtnexthop *nhp;
1689 struct net *net = mfc6_net(c); 1698 struct net *net = mfc6_net(c);
1690 struct net_device *dev = net->ipv6.vif6_table[c->mf6c_parent].dev;
1691 u8 *b = skb_tail_pointer(skb); 1699 u8 *b = skb_tail_pointer(skb);
1692 struct rtattr *mp_head; 1700 struct rtattr *mp_head;
1693 1701
1694 if (dev) 1702 /* If cache is unresolved, don't try to parse IIF and OIF */
1695 RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex); 1703 if (c->mf6c_parent > MAXMIFS)
1704 return -ENOENT;
1705
1706 if (MIF_EXISTS(net, c->mf6c_parent))
1707 RTA_PUT(skb, RTA_IIF, 4, &net->ipv6.vif6_table[c->mf6c_parent].dev->ifindex);
1696 1708
1697 mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); 1709 mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0));
1698 1710
1699 for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { 1711 for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
1700 if (c->mfc_un.res.ttls[ct] < 255) { 1712 if (MIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) {
1701 if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) 1713 if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4))
1702 goto rtattr_failure; 1714 goto rtattr_failure;
1703 nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); 1715 nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
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/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 4f7aaf6996a3..33f60fca7aa7 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -36,6 +36,7 @@
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/sysctl.h> 37#include <linux/sysctl.h>
38#include <linux/netfilter.h> 38#include <linux/netfilter.h>
39#include <linux/slab.h>
39 40
40#include <net/sock.h> 41#include <net/sock.h>
41#include <net/snmp.h> 42#include <net/snmp.h>
@@ -64,7 +65,7 @@ int ip6_ra_control(struct sock *sk, int sel)
64 struct ip6_ra_chain *ra, *new_ra, **rap; 65 struct ip6_ra_chain *ra, *new_ra, **rap;
65 66
66 /* RA packet may be delivered ONLY to IPPROTO_RAW socket */ 67 /* RA packet may be delivered ONLY to IPPROTO_RAW socket */
67 if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num != IPPROTO_RAW) 68 if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num != IPPROTO_RAW)
68 return -ENOPROTOOPT; 69 return -ENOPROTOOPT;
69 70
70 new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; 71 new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
@@ -106,7 +107,7 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
106 if (inet_sk(sk)->is_icsk) { 107 if (inet_sk(sk)->is_icsk) {
107 if (opt && 108 if (opt &&
108 !((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) && 109 !((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) &&
109 inet_sk(sk)->daddr != LOOPBACK4_IPV6) { 110 inet_sk(sk)->inet_daddr != LOOPBACK4_IPV6) {
110 struct inet_connection_sock *icsk = inet_csk(sk); 111 struct inet_connection_sock *icsk = inet_csk(sk);
111 icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; 112 icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
112 icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); 113 icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
@@ -234,7 +235,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
234 235
235 case IPV6_V6ONLY: 236 case IPV6_V6ONLY:
236 if (optlen < sizeof(int) || 237 if (optlen < sizeof(int) ||
237 inet_sk(sk)->num) 238 inet_sk(sk)->inet_num)
238 goto e_inval; 239 goto e_inval;
239 np->ipv6only = valbool; 240 np->ipv6only = valbool;
240 retv = 0; 241 retv = 0;
@@ -424,6 +425,7 @@ sticky_done:
424 425
425 fl.fl6_flowlabel = 0; 426 fl.fl6_flowlabel = 0;
426 fl.oif = sk->sk_bound_dev_if; 427 fl.oif = sk->sk_bound_dev_if;
428 fl.mark = sk->sk_mark;
427 429
428 if (optlen == 0) 430 if (optlen == 0)
429 goto update; 431 goto update;
@@ -665,7 +667,7 @@ done:
665 case IPV6_MTU_DISCOVER: 667 case IPV6_MTU_DISCOVER:
666 if (optlen < sizeof(int)) 668 if (optlen < sizeof(int))
667 goto e_inval; 669 goto e_inval;
668 if (val<0 || val>3) 670 if (val < IP_PMTUDISC_DONT || val > IP_PMTUDISC_PROBE)
669 goto e_inval; 671 goto e_inval;
670 np->pmtudisc = val; 672 np->pmtudisc = val;
671 retv = 0; 673 retv = 0;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index f9fcf690bd5d..c483ab9fd67b 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -43,6 +43,7 @@
43#include <linux/init.h> 43#include <linux/init.h>
44#include <linux/proc_fs.h> 44#include <linux/proc_fs.h>
45#include <linux/seq_file.h> 45#include <linux/seq_file.h>
46#include <linux/slab.h>
46 47
47#include <linux/netfilter.h> 48#include <linux/netfilter.h>
48#include <linux/netfilter_ipv6.h> 49#include <linux/netfilter_ipv6.h>
@@ -793,10 +794,10 @@ static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
793 } 794 }
794 spin_unlock_bh(&im->mca_lock); 795 spin_unlock_bh(&im->mca_lock);
795 796
796 write_lock_bh(&idev->mc_lock); 797 spin_lock_bh(&idev->mc_lock);
797 pmc->next = idev->mc_tomb; 798 pmc->next = idev->mc_tomb;
798 idev->mc_tomb = pmc; 799 idev->mc_tomb = pmc;
799 write_unlock_bh(&idev->mc_lock); 800 spin_unlock_bh(&idev->mc_lock);
800} 801}
801 802
802static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca) 803static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca)
@@ -804,7 +805,7 @@ static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca)
804 struct ifmcaddr6 *pmc, *pmc_prev; 805 struct ifmcaddr6 *pmc, *pmc_prev;
805 struct ip6_sf_list *psf, *psf_next; 806 struct ip6_sf_list *psf, *psf_next;
806 807
807 write_lock_bh(&idev->mc_lock); 808 spin_lock_bh(&idev->mc_lock);
808 pmc_prev = NULL; 809 pmc_prev = NULL;
809 for (pmc=idev->mc_tomb; pmc; pmc=pmc->next) { 810 for (pmc=idev->mc_tomb; pmc; pmc=pmc->next) {
810 if (ipv6_addr_equal(&pmc->mca_addr, pmca)) 811 if (ipv6_addr_equal(&pmc->mca_addr, pmca))
@@ -817,7 +818,8 @@ static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca)
817 else 818 else
818 idev->mc_tomb = pmc->next; 819 idev->mc_tomb = pmc->next;
819 } 820 }
820 write_unlock_bh(&idev->mc_lock); 821 spin_unlock_bh(&idev->mc_lock);
822
821 if (pmc) { 823 if (pmc) {
822 for (psf=pmc->mca_tomb; psf; psf=psf_next) { 824 for (psf=pmc->mca_tomb; psf; psf=psf_next) {
823 psf_next = psf->sf_next; 825 psf_next = psf->sf_next;
@@ -832,10 +834,10 @@ static void mld_clear_delrec(struct inet6_dev *idev)
832{ 834{
833 struct ifmcaddr6 *pmc, *nextpmc; 835 struct ifmcaddr6 *pmc, *nextpmc;
834 836
835 write_lock_bh(&idev->mc_lock); 837 spin_lock_bh(&idev->mc_lock);
836 pmc = idev->mc_tomb; 838 pmc = idev->mc_tomb;
837 idev->mc_tomb = NULL; 839 idev->mc_tomb = NULL;
838 write_unlock_bh(&idev->mc_lock); 840 spin_unlock_bh(&idev->mc_lock);
839 841
840 for (; pmc; pmc = nextpmc) { 842 for (; pmc; pmc = nextpmc) {
841 nextpmc = pmc->next; 843 nextpmc = pmc->next;
@@ -1696,7 +1698,7 @@ static void mld_send_cr(struct inet6_dev *idev)
1696 int type, dtype; 1698 int type, dtype;
1697 1699
1698 read_lock_bh(&idev->lock); 1700 read_lock_bh(&idev->lock);
1699 write_lock_bh(&idev->mc_lock); 1701 spin_lock(&idev->mc_lock);
1700 1702
1701 /* deleted MCA's */ 1703 /* deleted MCA's */
1702 pmc_prev = NULL; 1704 pmc_prev = NULL;
@@ -1730,7 +1732,7 @@ static void mld_send_cr(struct inet6_dev *idev)
1730 } else 1732 } else
1731 pmc_prev = pmc; 1733 pmc_prev = pmc;
1732 } 1734 }
1733 write_unlock_bh(&idev->mc_lock); 1735 spin_unlock(&idev->mc_lock);
1734 1736
1735 /* change recs */ 1737 /* change recs */
1736 for (pmc=idev->mc_list; pmc; pmc=pmc->next) { 1738 for (pmc=idev->mc_list; pmc; pmc=pmc->next) {
@@ -2311,7 +2313,7 @@ void ipv6_mc_up(struct inet6_dev *idev)
2311void ipv6_mc_init_dev(struct inet6_dev *idev) 2313void ipv6_mc_init_dev(struct inet6_dev *idev)
2312{ 2314{
2313 write_lock_bh(&idev->lock); 2315 write_lock_bh(&idev->lock);
2314 rwlock_init(&idev->mc_lock); 2316 spin_lock_init(&idev->mc_lock);
2315 idev->mc_gq_running = 0; 2317 idev->mc_gq_running = 0;
2316 setup_timer(&idev->mc_gq_timer, mld_gq_timer_expire, 2318 setup_timer(&idev->mc_gq_timer, mld_gq_timer_expire,
2317 (unsigned long)idev); 2319 (unsigned long)idev);
@@ -2375,9 +2377,9 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
2375 struct net *net = seq_file_net(seq); 2377 struct net *net = seq_file_net(seq);
2376 2378
2377 state->idev = NULL; 2379 state->idev = NULL;
2378 for_each_netdev(net, state->dev) { 2380 for_each_netdev_rcu(net, state->dev) {
2379 struct inet6_dev *idev; 2381 struct inet6_dev *idev;
2380 idev = in6_dev_get(state->dev); 2382 idev = __in6_dev_get(state->dev);
2381 if (!idev) 2383 if (!idev)
2382 continue; 2384 continue;
2383 read_lock_bh(&idev->lock); 2385 read_lock_bh(&idev->lock);
@@ -2387,7 +2389,6 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
2387 break; 2389 break;
2388 } 2390 }
2389 read_unlock_bh(&idev->lock); 2391 read_unlock_bh(&idev->lock);
2390 in6_dev_put(idev);
2391 } 2392 }
2392 return im; 2393 return im;
2393} 2394}
@@ -2398,16 +2399,15 @@ static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr
2398 2399
2399 im = im->next; 2400 im = im->next;
2400 while (!im) { 2401 while (!im) {
2401 if (likely(state->idev != NULL)) { 2402 if (likely(state->idev != NULL))
2402 read_unlock_bh(&state->idev->lock); 2403 read_unlock_bh(&state->idev->lock);
2403 in6_dev_put(state->idev); 2404
2404 } 2405 state->dev = next_net_device_rcu(state->dev);
2405 state->dev = next_net_device(state->dev);
2406 if (!state->dev) { 2406 if (!state->dev) {
2407 state->idev = NULL; 2407 state->idev = NULL;
2408 break; 2408 break;
2409 } 2409 }
2410 state->idev = in6_dev_get(state->dev); 2410 state->idev = __in6_dev_get(state->dev);
2411 if (!state->idev) 2411 if (!state->idev)
2412 continue; 2412 continue;
2413 read_lock_bh(&state->idev->lock); 2413 read_lock_bh(&state->idev->lock);
@@ -2426,31 +2426,31 @@ static struct ifmcaddr6 *igmp6_mc_get_idx(struct seq_file *seq, loff_t pos)
2426} 2426}
2427 2427
2428static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos) 2428static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos)
2429 __acquires(dev_base_lock) 2429 __acquires(RCU)
2430{ 2430{
2431 read_lock(&dev_base_lock); 2431 rcu_read_lock();
2432 return igmp6_mc_get_idx(seq, *pos); 2432 return igmp6_mc_get_idx(seq, *pos);
2433} 2433}
2434 2434
2435static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos) 2435static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2436{ 2436{
2437 struct ifmcaddr6 *im; 2437 struct ifmcaddr6 *im = igmp6_mc_get_next(seq, v);
2438 im = igmp6_mc_get_next(seq, v); 2438
2439 ++*pos; 2439 ++*pos;
2440 return im; 2440 return im;
2441} 2441}
2442 2442
2443static void igmp6_mc_seq_stop(struct seq_file *seq, void *v) 2443static void igmp6_mc_seq_stop(struct seq_file *seq, void *v)
2444 __releases(dev_base_lock) 2444 __releases(RCU)
2445{ 2445{
2446 struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq); 2446 struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
2447
2447 if (likely(state->idev != NULL)) { 2448 if (likely(state->idev != NULL)) {
2448 read_unlock_bh(&state->idev->lock); 2449 read_unlock_bh(&state->idev->lock);
2449 in6_dev_put(state->idev);
2450 state->idev = NULL; 2450 state->idev = NULL;
2451 } 2451 }
2452 state->dev = NULL; 2452 state->dev = NULL;
2453 read_unlock(&dev_base_lock); 2453 rcu_read_unlock();
2454} 2454}
2455 2455
2456static int igmp6_mc_seq_show(struct seq_file *seq, void *v) 2456static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
@@ -2507,9 +2507,9 @@ static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq)
2507 2507
2508 state->idev = NULL; 2508 state->idev = NULL;
2509 state->im = NULL; 2509 state->im = NULL;
2510 for_each_netdev(net, state->dev) { 2510 for_each_netdev_rcu(net, state->dev) {
2511 struct inet6_dev *idev; 2511 struct inet6_dev *idev;
2512 idev = in6_dev_get(state->dev); 2512 idev = __in6_dev_get(state->dev);
2513 if (unlikely(idev == NULL)) 2513 if (unlikely(idev == NULL))
2514 continue; 2514 continue;
2515 read_lock_bh(&idev->lock); 2515 read_lock_bh(&idev->lock);
@@ -2525,7 +2525,6 @@ static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq)
2525 spin_unlock_bh(&im->mca_lock); 2525 spin_unlock_bh(&im->mca_lock);
2526 } 2526 }
2527 read_unlock_bh(&idev->lock); 2527 read_unlock_bh(&idev->lock);
2528 in6_dev_put(idev);
2529 } 2528 }
2530 return psf; 2529 return psf;
2531} 2530}
@@ -2539,16 +2538,15 @@ static struct ip6_sf_list *igmp6_mcf_get_next(struct seq_file *seq, struct ip6_s
2539 spin_unlock_bh(&state->im->mca_lock); 2538 spin_unlock_bh(&state->im->mca_lock);
2540 state->im = state->im->next; 2539 state->im = state->im->next;
2541 while (!state->im) { 2540 while (!state->im) {
2542 if (likely(state->idev != NULL)) { 2541 if (likely(state->idev != NULL))
2543 read_unlock_bh(&state->idev->lock); 2542 read_unlock_bh(&state->idev->lock);
2544 in6_dev_put(state->idev); 2543
2545 } 2544 state->dev = next_net_device_rcu(state->dev);
2546 state->dev = next_net_device(state->dev);
2547 if (!state->dev) { 2545 if (!state->dev) {
2548 state->idev = NULL; 2546 state->idev = NULL;
2549 goto out; 2547 goto out;
2550 } 2548 }
2551 state->idev = in6_dev_get(state->dev); 2549 state->idev = __in6_dev_get(state->dev);
2552 if (!state->idev) 2550 if (!state->idev)
2553 continue; 2551 continue;
2554 read_lock_bh(&state->idev->lock); 2552 read_lock_bh(&state->idev->lock);
@@ -2573,9 +2571,9 @@ static struct ip6_sf_list *igmp6_mcf_get_idx(struct seq_file *seq, loff_t pos)
2573} 2571}
2574 2572
2575static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos) 2573static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos)
2576 __acquires(dev_base_lock) 2574 __acquires(RCU)
2577{ 2575{
2578 read_lock(&dev_base_lock); 2576 rcu_read_lock();
2579 return *pos ? igmp6_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; 2577 return *pos ? igmp6_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
2580} 2578}
2581 2579
@@ -2591,7 +2589,7 @@ static void *igmp6_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2591} 2589}
2592 2590
2593static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v) 2591static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v)
2594 __releases(dev_base_lock) 2592 __releases(RCU)
2595{ 2593{
2596 struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq); 2594 struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
2597 if (likely(state->im != NULL)) { 2595 if (likely(state->im != NULL)) {
@@ -2600,11 +2598,10 @@ static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v)
2600 } 2598 }
2601 if (likely(state->idev != NULL)) { 2599 if (likely(state->idev != NULL)) {
2602 read_unlock_bh(&state->idev->lock); 2600 read_unlock_bh(&state->idev->lock);
2603 in6_dev_put(state->idev);
2604 state->idev = NULL; 2601 state->idev = NULL;
2605 } 2602 }
2606 state->dev = NULL; 2603 state->dev = NULL;
2607 read_unlock(&dev_base_lock); 2604 rcu_read_unlock();
2608} 2605}
2609 2606
2610static int igmp6_mcf_seq_show(struct seq_file *seq, void *v) 2607static int igmp6_mcf_seq_show(struct seq_file *seq, void *v)
@@ -2651,7 +2648,7 @@ static const struct file_operations igmp6_mcf_seq_fops = {
2651 .release = seq_release_net, 2648 .release = seq_release_net,
2652}; 2649};
2653 2650
2654static int igmp6_proc_init(struct net *net) 2651static int __net_init igmp6_proc_init(struct net *net)
2655{ 2652{
2656 int err; 2653 int err;
2657 2654
@@ -2671,23 +2668,22 @@ out_proc_net_igmp6:
2671 goto out; 2668 goto out;
2672} 2669}
2673 2670
2674static void igmp6_proc_exit(struct net *net) 2671static void __net_exit igmp6_proc_exit(struct net *net)
2675{ 2672{
2676 proc_net_remove(net, "mcfilter6"); 2673 proc_net_remove(net, "mcfilter6");
2677 proc_net_remove(net, "igmp6"); 2674 proc_net_remove(net, "igmp6");
2678} 2675}
2679#else 2676#else
2680static int igmp6_proc_init(struct net *net) 2677static inline int igmp6_proc_init(struct net *net)
2681{ 2678{
2682 return 0; 2679 return 0;
2683} 2680}
2684static void igmp6_proc_exit(struct net *net) 2681static inline void igmp6_proc_exit(struct net *net)
2685{ 2682{
2686 ;
2687} 2683}
2688#endif 2684#endif
2689 2685
2690static int igmp6_net_init(struct net *net) 2686static int __net_init igmp6_net_init(struct net *net)
2691{ 2687{
2692 int err; 2688 int err;
2693 2689
@@ -2713,7 +2709,7 @@ out_sock_create:
2713 goto out; 2709 goto out;
2714} 2710}
2715 2711
2716static void igmp6_net_exit(struct net *net) 2712static void __net_exit igmp6_net_exit(struct net *net)
2717{ 2713{
2718 inet_ctl_sock_destroy(net->ipv6.igmp_sk); 2714 inet_ctl_sock_destroy(net->ipv6.igmp_sk);
2719 igmp6_proc_exit(net); 2715 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 f74e4e2cdd06..da0a4d2adc69 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -59,6 +59,7 @@
59#include <linux/route.h> 59#include <linux/route.h>
60#include <linux/init.h> 60#include <linux/init.h>
61#include <linux/rcupdate.h> 61#include <linux/rcupdate.h>
62#include <linux/slab.h>
62#ifdef CONFIG_SYSCTL 63#ifdef CONFIG_SYSCTL
63#include <linux/sysctl.h> 64#include <linux/sysctl.h>
64#endif 65#endif
@@ -598,6 +599,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
598 icmp6h.icmp6_solicited = solicited; 599 icmp6h.icmp6_solicited = solicited;
599 icmp6h.icmp6_override = override; 600 icmp6h.icmp6_override = override;
600 601
602 inc_opt |= ifp->idev->cnf.force_tllao;
601 __ndisc_send(dev, neigh, daddr, src_addr, 603 __ndisc_send(dev, neigh, daddr, src_addr,
602 &icmp6h, solicited_addr, 604 &icmp6h, solicited_addr,
603 inc_opt ? ND_OPT_TARGET_LL_ADDR : 0); 605 inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
@@ -1768,46 +1770,10 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, void __user *bu
1768 return ret; 1770 return ret;
1769} 1771}
1770 1772
1771int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl,
1772 void __user *oldval, size_t __user *oldlenp,
1773 void __user *newval, size_t newlen)
1774{
1775 struct net_device *dev = ctl->extra1;
1776 struct inet6_dev *idev;
1777 int ret;
1778
1779 if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1780 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1781 ndisc_warn_deprecated_sysctl(ctl, "procfs", dev ? dev->name : "default");
1782
1783 switch (ctl->ctl_name) {
1784 case NET_NEIGH_REACHABLE_TIME:
1785 ret = sysctl_jiffies(ctl, oldval, oldlenp, newval, newlen);
1786 break;
1787 case NET_NEIGH_RETRANS_TIME_MS:
1788 case NET_NEIGH_REACHABLE_TIME_MS:
1789 ret = sysctl_ms_jiffies(ctl, oldval, oldlenp, newval, newlen);
1790 break;
1791 default:
1792 ret = 0;
1793 }
1794
1795 if (newval && newlen && ret > 0 &&
1796 dev && (idev = in6_dev_get(dev)) != NULL) {
1797 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1798 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1799 idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1800 idev->tstamp = jiffies;
1801 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1802 in6_dev_put(idev);
1803 }
1804
1805 return ret;
1806}
1807 1773
1808#endif 1774#endif
1809 1775
1810static int ndisc_net_init(struct net *net) 1776static int __net_init ndisc_net_init(struct net *net)
1811{ 1777{
1812 struct ipv6_pinfo *np; 1778 struct ipv6_pinfo *np;
1813 struct sock *sk; 1779 struct sock *sk;
@@ -1832,7 +1798,7 @@ static int ndisc_net_init(struct net *net)
1832 return 0; 1798 return 0;
1833} 1799}
1834 1800
1835static void ndisc_net_exit(struct net *net) 1801static void __net_exit ndisc_net_exit(struct net *net)
1836{ 1802{
1837 inet_ctl_sock_destroy(net->ipv6.ndisc_sk); 1803 inet_ctl_sock_destroy(net->ipv6.ndisc_sk);
1838} 1804}
@@ -1855,10 +1821,8 @@ int __init ndisc_init(void)
1855 neigh_table_init(&nd_tbl); 1821 neigh_table_init(&nd_tbl);
1856 1822
1857#ifdef CONFIG_SYSCTL 1823#ifdef CONFIG_SYSCTL
1858 err = neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, 1824 err = neigh_sysctl_register(NULL, &nd_tbl.parms, "ipv6",
1859 NET_IPV6_NEIGH, "ipv6", 1825 &ndisc_ifinfo_sysctl_change);
1860 &ndisc_ifinfo_sysctl_change,
1861 &ndisc_ifinfo_sysctl_strategy);
1862 if (err) 1826 if (err)
1863 goto out_unregister_pernet; 1827 goto out_unregister_pernet;
1864#endif 1828#endif
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 1cf3f0c6a959..6a68a74d14a3 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -25,6 +25,7 @@
25#include <linux/proc_fs.h> 25#include <linux/proc_fs.h>
26#include <linux/seq_file.h> 26#include <linux/seq_file.h>
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/slab.h>
28#include <net/net_namespace.h> 29#include <net/net_namespace.h>
29#include <net/sock.h> 30#include <net/sock.h>
30#include <net/ipv6.h> 31#include <net/ipv6.h>
@@ -36,7 +37,6 @@
36 37
37#define IPQ_QMAX_DEFAULT 1024 38#define IPQ_QMAX_DEFAULT 1024
38#define IPQ_PROC_FS_NAME "ip6_queue" 39#define IPQ_PROC_FS_NAME "ip6_queue"
39#define NET_IPQ_QMAX 2088
40#define NET_IPQ_QMAX_NAME "ip6_queue_maxlen" 40#define NET_IPQ_QMAX_NAME "ip6_queue_maxlen"
41 41
42typedef int (*ipq_cmpfn)(struct nf_queue_entry *, unsigned long); 42typedef int (*ipq_cmpfn)(struct nf_queue_entry *, unsigned long);
@@ -499,10 +499,9 @@ ipq_rcv_nl_event(struct notifier_block *this,
499{ 499{
500 struct netlink_notify *n = ptr; 500 struct netlink_notify *n = ptr;
501 501
502 if (event == NETLINK_URELEASE && 502 if (event == NETLINK_URELEASE && n->protocol == NETLINK_IP6_FW) {
503 n->protocol == NETLINK_IP6_FW && n->pid) {
504 write_lock_bh(&queue_lock); 503 write_lock_bh(&queue_lock);
505 if ((n->net == &init_net) && (n->pid == peer_pid)) 504 if ((net_eq(n->net, &init_net)) && (n->pid == peer_pid))
506 __ipq_reset(); 505 __ipq_reset();
507 write_unlock_bh(&queue_lock); 506 write_unlock_bh(&queue_lock);
508 } 507 }
@@ -518,14 +517,13 @@ static struct ctl_table_header *ipq_sysctl_header;
518 517
519static ctl_table ipq_table[] = { 518static ctl_table ipq_table[] = {
520 { 519 {
521 .ctl_name = NET_IPQ_QMAX,
522 .procname = NET_IPQ_QMAX_NAME, 520 .procname = NET_IPQ_QMAX_NAME,
523 .data = &queue_maxlen, 521 .data = &queue_maxlen,
524 .maxlen = sizeof(queue_maxlen), 522 .maxlen = sizeof(queue_maxlen),
525 .mode = 0644, 523 .mode = 0644,
526 .proc_handler = proc_dointvec 524 .proc_handler = proc_dointvec
527 }, 525 },
528 { .ctl_name = 0 } 526 { }
529}; 527};
530#endif 528#endif
531 529
@@ -625,7 +623,7 @@ cleanup_netlink_notifier:
625static void __exit ip6_queue_fini(void) 623static void __exit ip6_queue_fini(void)
626{ 624{
627 nf_unregister_queue_handlers(&nfqh); 625 nf_unregister_queue_handlers(&nfqh);
628 synchronize_net(); 626
629 ipq_flush(NULL, 0); 627 ipq_flush(NULL, 0);
630 628
631#ifdef CONFIG_SYSCTL 629#ifdef CONFIG_SYSCTL
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index cc9f8ef303fd..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
@@ -105,9 +112,9 @@ ip6_packet_match(const struct sk_buff *skb,
105#define FWINV(bool, invflg) ((bool) ^ !!(ip6info->invflags & (invflg))) 112#define FWINV(bool, invflg) ((bool) ^ !!(ip6info->invflags & (invflg)))
106 113
107 if (FWINV(ipv6_masked_addr_cmp(&ipv6->saddr, &ip6info->smsk, 114 if (FWINV(ipv6_masked_addr_cmp(&ipv6->saddr, &ip6info->smsk,
108 &ip6info->src), IP6T_INV_SRCIP) 115 &ip6info->src), IP6T_INV_SRCIP) ||
109 || FWINV(ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk, 116 FWINV(ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk,
110 &ip6info->dst), IP6T_INV_DSTIP)) { 117 &ip6info->dst), IP6T_INV_DSTIP)) {
111 dprintf("Source or dest mismatch.\n"); 118 dprintf("Source or dest mismatch.\n");
112/* 119/*
113 dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr, 120 dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr,
@@ -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 */
@@ -277,11 +290,11 @@ get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
277 } else if (s == e) { 290 } else if (s == e) {
278 (*rulenum)++; 291 (*rulenum)++;
279 292
280 if (s->target_offset == sizeof(struct ip6t_entry) 293 if (s->target_offset == sizeof(struct ip6t_entry) &&
281 && strcmp(t->target.u.kernel.target->name, 294 strcmp(t->target.u.kernel.target->name,
282 IP6T_STANDARD_TARGET) == 0 295 IP6T_STANDARD_TARGET) == 0 &&
283 && t->verdict < 0 296 t->verdict < 0 &&
284 && unconditional(&s->ipv6)) { 297 unconditional(&s->ipv6)) {
285 /* Tail of chains: STANDARD target (return/policy) */ 298 /* Tail of chains: STANDARD target (return/policy) */
286 *comment = *chainname == hookname 299 *comment = *chainname == hookname
287 ? comments[NF_IP6_TRACE_COMMENT_POLICY] 300 ? comments[NF_IP6_TRACE_COMMENT_POLICY]
@@ -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) || \
@@ -418,8 +437,8 @@ ip6t_do_table(struct sk_buff *skb,
418 back = get_entry(table_base, back->comefrom); 437 back = get_entry(table_base, back->comefrom);
419 continue; 438 continue;
420 } 439 }
421 if (table_base + v != ip6t_next_entry(e) 440 if (table_base + v != ip6t_next_entry(e) &&
422 && !(e->ipv6.flags & IP6T_F_GOTO)) { 441 !(e->ipv6.flags & IP6T_F_GOTO)) {
423 /* Save old back ptr in next entry */ 442 /* Save old back ptr in next entry */
424 struct ip6t_entry *next = ip6t_next_entry(e); 443 struct ip6t_entry *next = ip6t_next_entry(e);
425 next->comefrom = (void *)back - table_base; 444 next->comefrom = (void *)back - table_base;
@@ -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)) {
@@ -505,11 +524,11 @@ mark_source_chains(struct xt_table_info *newinfo,
505 e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); 524 e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
506 525
507 /* Unconditional return/END. */ 526 /* Unconditional return/END. */
508 if ((e->target_offset == sizeof(struct ip6t_entry) 527 if ((e->target_offset == sizeof(struct ip6t_entry) &&
509 && (strcmp(t->target.u.user.name, 528 (strcmp(t->target.u.user.name,
510 IP6T_STANDARD_TARGET) == 0) 529 IP6T_STANDARD_TARGET) == 0) &&
511 && t->verdict < 0 530 t->verdict < 0 &&
512 && unconditional(&e->ipv6)) || visited) { 531 unconditional(&e->ipv6)) || visited) {
513 unsigned int oldpos, size; 532 unsigned int oldpos, size;
514 533
515 if ((strcmp(t->target.u.user.name, 534 if ((strcmp(t->target.u.user.name,
@@ -556,8 +575,8 @@ mark_source_chains(struct xt_table_info *newinfo,
556 int newpos = t->verdict; 575 int newpos = t->verdict;
557 576
558 if (strcmp(t->target.u.user.name, 577 if (strcmp(t->target.u.user.name,
559 IP6T_STANDARD_TARGET) == 0 578 IP6T_STANDARD_TARGET) == 0 &&
560 && newpos >= 0) { 579 newpos >= 0) {
561 if (newpos > newinfo->size - 580 if (newpos > newinfo->size -
562 sizeof(struct ip6t_entry)) { 581 sizeof(struct ip6t_entry)) {
563 duprintf("mark_source_chains: " 582 duprintf("mark_source_chains: "
@@ -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,17 +778,16 @@ 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
770 if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 789 if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 ||
771 || (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) { 790 (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) {
772 duprintf("Bad offset %p\n", e); 791 duprintf("Bad offset %p\n", e);
773 return -EINVAL; 792 return -EINVAL;
774 } 793 }
@@ -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;
@@ -1584,8 +1552,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
1584 int ret, off, h; 1552 int ret, off, h;
1585 1553
1586 duprintf("check_compat_entry_size_and_hooks %p\n", e); 1554 duprintf("check_compat_entry_size_and_hooks %p\n", e);
1587 if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 1555 if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 ||
1588 || (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) { 1556 (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) {
1589 duprintf("Bad offset %p, limit = %p\n", e, limit); 1557 duprintf("Bad offset %p, limit = %p\n", e, limit);
1590 return -EINVAL; 1558 return -EINVAL;
1591 } 1559 }
@@ -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_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 7018cac4fddc..b285fdf19050 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -249,8 +249,8 @@ static void dump_packet(const struct nf_loginfo *info,
249 /* Max length: 11 "URGP=65535 " */ 249 /* Max length: 11 "URGP=65535 " */
250 printk("URGP=%u ", ntohs(th->urg_ptr)); 250 printk("URGP=%u ", ntohs(th->urg_ptr));
251 251
252 if ((logflags & IP6T_LOG_TCPOPT) 252 if ((logflags & IP6T_LOG_TCPOPT) &&
253 && th->doff * 4 > sizeof(struct tcphdr)) { 253 th->doff * 4 > sizeof(struct tcphdr)) {
254 u_int8_t _opt[60 - sizeof(struct tcphdr)]; 254 u_int8_t _opt[60 - sizeof(struct tcphdr)];
255 const u_int8_t *op; 255 const u_int8_t *op;
256 unsigned int i; 256 unsigned int i;
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 5a7f00cd15ce..39b50c3768e8 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -15,6 +15,7 @@
15 * 2 of the License, or (at your option) any later version. 15 * 2 of the License, or (at your option) any later version.
16 */ 16 */
17 17
18#include <linux/gfp.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/skbuff.h> 20#include <linux/skbuff.h>
20#include <linux/icmpv6.h> 21#include <linux/icmpv6.h>
@@ -169,7 +170,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) 170 if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
170 skb_in->dev = net->loopback_dev; 171 skb_in->dev = net->loopback_dev;
171 172
172 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL); 173 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0);
173} 174}
174 175
175static unsigned int 176static unsigned int
@@ -223,8 +224,8 @@ static bool reject_tg6_check(const struct xt_tgchk_param *par)
223 return false; 224 return false;
224 } else if (rejinfo->with == IP6T_TCP_RESET) { 225 } else if (rejinfo->with == IP6T_TCP_RESET) {
225 /* Must specify that it's a TCP packet */ 226 /* Must specify that it's a TCP packet */
226 if (e->ipv6.proto != IPPROTO_TCP 227 if (e->ipv6.proto != IPPROTO_TCP ||
227 || (e->ipv6.invflags & XT_INV_PROTO)) { 228 (e->ipv6.invflags & XT_INV_PROTO)) {
228 printk("ip6t_REJECT: TCP_RESET illegal for non-tcp\n"); 229 printk("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
229 return false; 230 return false;
230 } 231 }
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index 3a82f24746b9..ac0b7c629d78 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -77,17 +77,14 @@ static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
77 ahinfo->hdrres, ah->reserved, 77 ahinfo->hdrres, ah->reserved,
78 !(ahinfo->hdrres && ah->reserved)); 78 !(ahinfo->hdrres && ah->reserved));
79 79
80 return (ah != NULL) 80 return (ah != NULL) &&
81 && 81 spi_match(ahinfo->spis[0], ahinfo->spis[1],
82 spi_match(ahinfo->spis[0], ahinfo->spis[1], 82 ntohl(ah->spi),
83 ntohl(ah->spi), 83 !!(ahinfo->invflags & IP6T_AH_INV_SPI)) &&
84 !!(ahinfo->invflags & IP6T_AH_INV_SPI)) 84 (!ahinfo->hdrlen ||
85 && 85 (ahinfo->hdrlen == hdrlen) ^
86 (!ahinfo->hdrlen || 86 !!(ahinfo->invflags & IP6T_AH_INV_LEN)) &&
87 (ahinfo->hdrlen == hdrlen) ^ 87 !(ahinfo->hdrres && ah->reserved);
88 !!(ahinfo->invflags & IP6T_AH_INV_LEN))
89 &&
90 !(ahinfo->hdrres && ah->reserved);
91} 88}
92 89
93static bool ah_mt6_check(const struct xt_mtchk_param *par) 90static bool ah_mt6_check(const struct xt_mtchk_param *par)
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index 673aa0a5084e..7b91c2598ed5 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -70,41 +70,36 @@ frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
70 pr_debug("res %02X %02X%04X %02X ", 70 pr_debug("res %02X %02X%04X %02X ",
71 fraginfo->flags & IP6T_FRAG_RES, fh->reserved, 71 fraginfo->flags & IP6T_FRAG_RES, fh->reserved,
72 ntohs(fh->frag_off) & 0x6, 72 ntohs(fh->frag_off) & 0x6,
73 !((fraginfo->flags & IP6T_FRAG_RES) 73 !((fraginfo->flags & IP6T_FRAG_RES) &&
74 && (fh->reserved || (ntohs(fh->frag_off) & 0x06)))); 74 (fh->reserved || (ntohs(fh->frag_off) & 0x06))));
75 pr_debug("first %02X %02X %02X ", 75 pr_debug("first %02X %02X %02X ",
76 fraginfo->flags & IP6T_FRAG_FST, 76 fraginfo->flags & IP6T_FRAG_FST,
77 ntohs(fh->frag_off) & ~0x7, 77 ntohs(fh->frag_off) & ~0x7,
78 !((fraginfo->flags & IP6T_FRAG_FST) 78 !((fraginfo->flags & IP6T_FRAG_FST) &&
79 && (ntohs(fh->frag_off) & ~0x7))); 79 (ntohs(fh->frag_off) & ~0x7)));
80 pr_debug("mf %02X %02X %02X ", 80 pr_debug("mf %02X %02X %02X ",
81 fraginfo->flags & IP6T_FRAG_MF, 81 fraginfo->flags & IP6T_FRAG_MF,
82 ntohs(fh->frag_off) & IP6_MF, 82 ntohs(fh->frag_off) & IP6_MF,
83 !((fraginfo->flags & IP6T_FRAG_MF) 83 !((fraginfo->flags & IP6T_FRAG_MF) &&
84 && !((ntohs(fh->frag_off) & IP6_MF)))); 84 !((ntohs(fh->frag_off) & IP6_MF))));
85 pr_debug("last %02X %02X %02X\n", 85 pr_debug("last %02X %02X %02X\n",
86 fraginfo->flags & IP6T_FRAG_NMF, 86 fraginfo->flags & IP6T_FRAG_NMF,
87 ntohs(fh->frag_off) & IP6_MF, 87 ntohs(fh->frag_off) & IP6_MF,
88 !((fraginfo->flags & IP6T_FRAG_NMF) 88 !((fraginfo->flags & IP6T_FRAG_NMF) &&
89 && (ntohs(fh->frag_off) & IP6_MF))); 89 (ntohs(fh->frag_off) & IP6_MF)));
90 90
91 return (fh != NULL) 91 return (fh != NULL) &&
92 && 92 id_match(fraginfo->ids[0], fraginfo->ids[1],
93 id_match(fraginfo->ids[0], fraginfo->ids[1], 93 ntohl(fh->identification),
94 ntohl(fh->identification), 94 !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)) &&
95 !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)) 95 !((fraginfo->flags & IP6T_FRAG_RES) &&
96 && 96 (fh->reserved || (ntohs(fh->frag_off) & 0x6))) &&
97 !((fraginfo->flags & IP6T_FRAG_RES) 97 !((fraginfo->flags & IP6T_FRAG_FST) &&
98 && (fh->reserved || (ntohs(fh->frag_off) & 0x6))) 98 (ntohs(fh->frag_off) & ~0x7)) &&
99 && 99 !((fraginfo->flags & IP6T_FRAG_MF) &&
100 !((fraginfo->flags & IP6T_FRAG_FST) 100 !(ntohs(fh->frag_off) & IP6_MF)) &&
101 && (ntohs(fh->frag_off) & ~0x7)) 101 !((fraginfo->flags & IP6T_FRAG_NMF) &&
102 && 102 (ntohs(fh->frag_off) & IP6_MF));
103 !((fraginfo->flags & IP6T_FRAG_MF)
104 && !(ntohs(fh->frag_off) & IP6_MF))
105 &&
106 !((fraginfo->flags & IP6T_FRAG_NMF)
107 && (ntohs(fh->frag_off) & IP6_MF));
108} 103}
109 104
110static bool frag_mt6_check(const struct xt_mtchk_param *par) 105static bool frag_mt6_check(const struct xt_mtchk_param *par)
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 356b8d6f6baa..b77307fc8743 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -92,16 +92,13 @@ static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
92 !((rtinfo->flags & IP6T_RT_RES) && 92 !((rtinfo->flags & IP6T_RT_RES) &&
93 (((const struct rt0_hdr *)rh)->reserved))); 93 (((const struct rt0_hdr *)rh)->reserved)));
94 94
95 ret = (rh != NULL) 95 ret = (rh != NULL) &&
96 &&
97 (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1], 96 (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
98 rh->segments_left, 97 rh->segments_left,
99 !!(rtinfo->invflags & IP6T_RT_INV_SGS))) 98 !!(rtinfo->invflags & IP6T_RT_INV_SGS))) &&
100 &&
101 (!(rtinfo->flags & IP6T_RT_LEN) || 99 (!(rtinfo->flags & IP6T_RT_LEN) ||
102 ((rtinfo->hdrlen == hdrlen) ^ 100 ((rtinfo->hdrlen == hdrlen) ^
103 !!(rtinfo->invflags & IP6T_RT_INV_LEN))) 101 !!(rtinfo->invflags & IP6T_RT_INV_LEN))) &&
104 &&
105 (!(rtinfo->flags & IP6T_RT_TYP) || 102 (!(rtinfo->flags & IP6T_RT_TYP) ||
106 ((rtinfo->rt_type == rh->type) ^ 103 ((rtinfo->rt_type == rh->type) ^
107 !!(rtinfo->invflags & IP6T_RT_INV_TYP))); 104 !!(rtinfo->invflags & IP6T_RT_INV_TYP)));
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 6f4383ad86f9..d6fc9aff3163 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -12,6 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/moduleparam.h> 13#include <linux/moduleparam.h>
14#include <linux/netfilter_ipv6/ip6_tables.h> 14#include <linux/netfilter_ipv6/ip6_tables.h>
15#include <linux/slab.h>
15 16
16MODULE_LICENSE("GPL"); 17MODULE_LICENSE("GPL");
17MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 18MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
@@ -21,99 +22,26 @@ MODULE_DESCRIPTION("ip6tables filter table");
21 (1 << NF_INET_FORWARD) | \ 22 (1 << NF_INET_FORWARD) | \
22 (1 << NF_INET_LOCAL_OUT)) 23 (1 << NF_INET_LOCAL_OUT))
23 24
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 = { 25static const struct xt_table packet_filter = {
55 .name = "filter", 26 .name = "filter",
56 .valid_hooks = FILTER_VALID_HOOKS, 27 .valid_hooks = FILTER_VALID_HOOKS,
57 .me = THIS_MODULE, 28 .me = THIS_MODULE,
58 .af = NFPROTO_IPV6, 29 .af = NFPROTO_IPV6,
30 .priority = NF_IP6_PRI_FILTER,
59}; 31};
60 32
61/* The work comes in here from netfilter.c. */ 33/* The work comes in here from netfilter.c. */
62static unsigned int 34static unsigned int
63ip6t_in_hook(unsigned int hook, 35ip6table_filter_hook(unsigned int hook, struct sk_buff *skb,
64 struct sk_buff *skb, 36 const struct net_device *in, const struct net_device *out,
65 const struct net_device *in, 37 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{ 38{
80#if 0 39 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 40
90 return ip6t_do_table(skb, hook, in, out, 41 return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_filter);
91 dev_net(out)->ipv6.ip6table_filter);
92} 42}
93 43
94static struct nf_hook_ops ip6t_ops[] __read_mostly = { 44static 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 45
118/* Default to forward because I got too much mail already. */ 46/* Default to forward because I got too much mail already. */
119static int forward = NF_ACCEPT; 47static int forward = NF_ACCEPT;
@@ -121,9 +49,18 @@ module_param(forward, bool, 0000);
121 49
122static int __net_init ip6table_filter_net_init(struct net *net) 50static int __net_init ip6table_filter_net_init(struct net *net)
123{ 51{
124 /* Register table */ 52 struct ip6t_replace *repl;
53
54 repl = ip6t_alloc_initial_table(&packet_filter);
55 if (repl == NULL)
56 return -ENOMEM;
57 /* Entry 1 is the FORWARD hook */
58 ((struct ip6t_standard *)repl->entries)[1].target.verdict =
59 -forward - 1;
60
125 net->ipv6.ip6table_filter = 61 net->ipv6.ip6table_filter =
126 ip6t_register_table(net, &packet_filter, &initial_table.repl); 62 ip6t_register_table(net, &packet_filter, repl);
63 kfree(repl);
127 if (IS_ERR(net->ipv6.ip6table_filter)) 64 if (IS_ERR(net->ipv6.ip6table_filter))
128 return PTR_ERR(net->ipv6.ip6table_filter); 65 return PTR_ERR(net->ipv6.ip6table_filter);
129 return 0; 66 return 0;
@@ -131,7 +68,7 @@ static int __net_init ip6table_filter_net_init(struct net *net)
131 68
132static void __net_exit ip6table_filter_net_exit(struct net *net) 69static void __net_exit ip6table_filter_net_exit(struct net *net)
133{ 70{
134 ip6t_unregister_table(net->ipv6.ip6table_filter); 71 ip6t_unregister_table(net, net->ipv6.ip6table_filter);
135} 72}
136 73
137static struct pernet_operations ip6table_filter_net_ops = { 74static struct pernet_operations ip6table_filter_net_ops = {
@@ -148,17 +85,16 @@ static int __init ip6table_filter_init(void)
148 return -EINVAL; 85 return -EINVAL;
149 } 86 }
150 87
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); 88 ret = register_pernet_subsys(&ip6table_filter_net_ops);
155 if (ret < 0) 89 if (ret < 0)
156 return ret; 90 return ret;
157 91
158 /* Register hooks */ 92 /* Register hooks */
159 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 93 filter_ops = xt_hook_link(&packet_filter, ip6table_filter_hook);
160 if (ret < 0) 94 if (IS_ERR(filter_ops)) {
95 ret = PTR_ERR(filter_ops);
161 goto cleanup_table; 96 goto cleanup_table;
97 }
162 98
163 return ret; 99 return ret;
164 100
@@ -169,7 +105,7 @@ static int __init ip6table_filter_init(void)
169 105
170static void __exit ip6table_filter_fini(void) 106static void __exit ip6table_filter_fini(void)
171{ 107{
172 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 108 xt_hook_unlink(&packet_filter, filter_ops);
173 unregister_pernet_subsys(&ip6table_filter_net_ops); 109 unregister_pernet_subsys(&ip6table_filter_net_ops);
174} 110}
175 111
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 0ad91433ed61..6a102b57f356 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -10,6 +10,7 @@
10 */ 10 */
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/netfilter_ipv6/ip6_tables.h> 12#include <linux/netfilter_ipv6/ip6_tables.h>
13#include <linux/slab.h>
13 14
14MODULE_LICENSE("GPL"); 15MODULE_LICENSE("GPL");
15MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 16MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
@@ -21,80 +22,17 @@ MODULE_DESCRIPTION("ip6tables mangle table");
21 (1 << NF_INET_LOCAL_OUT) | \ 22 (1 << NF_INET_LOCAL_OUT) | \
22 (1 << NF_INET_POST_ROUTING)) 23 (1 << NF_INET_POST_ROUTING))
23 24
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 = { 25static const struct xt_table packet_mangler = {
61 .name = "mangle", 26 .name = "mangle",
62 .valid_hooks = MANGLE_VALID_HOOKS, 27 .valid_hooks = MANGLE_VALID_HOOKS,
63 .me = THIS_MODULE, 28 .me = THIS_MODULE,
64 .af = NFPROTO_IPV6, 29 .af = NFPROTO_IPV6,
30 .priority = NF_IP6_PRI_MANGLE,
65}; 31};
66 32
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 33static unsigned int
91ip6t_local_out_hook(unsigned int hook, 34ip6t_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{ 35{
97
98 unsigned int ret; 36 unsigned int ret;
99 struct in6_addr saddr, daddr; 37 struct in6_addr saddr, daddr;
100 u_int8_t hop_limit; 38 u_int8_t hop_limit;
@@ -102,8 +40,8 @@ ip6t_local_out_hook(unsigned int hook,
102 40
103#if 0 41#if 0
104 /* root is playing with raw sockets. */ 42 /* root is playing with raw sockets. */
105 if (skb->len < sizeof(struct iphdr) 43 if (skb->len < sizeof(struct iphdr) ||
106 || ip_hdrlen(skb) < sizeof(struct iphdr)) { 44 ip_hdrlen(skb) < sizeof(struct iphdr)) {
107 if (net_ratelimit()) 45 if (net_ratelimit())
108 printk("ip6t_hook: happy cracking.\n"); 46 printk("ip6t_hook: happy cracking.\n");
109 return NF_ACCEPT; 47 return NF_ACCEPT;
@@ -119,62 +57,46 @@ ip6t_local_out_hook(unsigned int hook,
119 /* flowlabel and prio (includes version, which shouldn't change either */ 57 /* flowlabel and prio (includes version, which shouldn't change either */
120 flowlabel = *((u_int32_t *)ipv6_hdr(skb)); 58 flowlabel = *((u_int32_t *)ipv6_hdr(skb));
121 59
122 ret = ip6t_do_table(skb, hook, in, out, 60 ret = ip6t_do_table(skb, NF_INET_LOCAL_OUT, NULL, out,
123 dev_net(out)->ipv6.ip6table_mangle); 61 dev_net(out)->ipv6.ip6table_mangle);
124 62
125 if (ret != NF_DROP && ret != NF_STOLEN 63 if (ret != NF_DROP && ret != NF_STOLEN &&
126 && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) 64 (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) ||
127 || memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) 65 memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) ||
128 || skb->mark != mark 66 skb->mark != mark ||
129 || ipv6_hdr(skb)->hop_limit != hop_limit)) 67 ipv6_hdr(skb)->hop_limit != hop_limit))
130 return ip6_route_me_harder(skb) == 0 ? ret : NF_DROP; 68 return ip6_route_me_harder(skb) == 0 ? ret : NF_DROP;
131 69
132 return ret; 70 return ret;
133} 71}
134 72
135static struct nf_hook_ops ip6t_ops[] __read_mostly = { 73/* The work comes in here from netfilter.c. */
136 { 74static unsigned int
137 .hook = ip6t_in_hook, 75ip6table_mangle_hook(unsigned int hook, struct sk_buff *skb,
138 .owner = THIS_MODULE, 76 const struct net_device *in, const struct net_device *out,
139 .pf = NFPROTO_IPV6, 77 int (*okfn)(struct sk_buff *))
140 .hooknum = NF_INET_PRE_ROUTING, 78{
141 .priority = NF_IP6_PRI_MANGLE, 79 if (hook == NF_INET_LOCAL_OUT)
142 }, 80 return ip6t_mangle_out(skb, out);
143 { 81 if (hook == NF_INET_POST_ROUTING)
144 .hook = ip6t_in_hook, 82 return ip6t_do_table(skb, hook, in, out,
145 .owner = THIS_MODULE, 83 dev_net(out)->ipv6.ip6table_mangle);
146 .pf = NFPROTO_IPV6, 84 /* INPUT/FORWARD */
147 .hooknum = NF_INET_LOCAL_IN, 85 return ip6t_do_table(skb, hook, in, out,
148 .priority = NF_IP6_PRI_MANGLE, 86 dev_net(in)->ipv6.ip6table_mangle);
149 }, 87}
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 88
89static struct nf_hook_ops *mangle_ops __read_mostly;
173static int __net_init ip6table_mangle_net_init(struct net *net) 90static int __net_init ip6table_mangle_net_init(struct net *net)
174{ 91{
175 /* Register table */ 92 struct ip6t_replace *repl;
93
94 repl = ip6t_alloc_initial_table(&packet_mangler);
95 if (repl == NULL)
96 return -ENOMEM;
176 net->ipv6.ip6table_mangle = 97 net->ipv6.ip6table_mangle =
177 ip6t_register_table(net, &packet_mangler, &initial_table.repl); 98 ip6t_register_table(net, &packet_mangler, repl);
99 kfree(repl);
178 if (IS_ERR(net->ipv6.ip6table_mangle)) 100 if (IS_ERR(net->ipv6.ip6table_mangle))
179 return PTR_ERR(net->ipv6.ip6table_mangle); 101 return PTR_ERR(net->ipv6.ip6table_mangle);
180 return 0; 102 return 0;
@@ -182,7 +104,7 @@ static int __net_init ip6table_mangle_net_init(struct net *net)
182 104
183static void __net_exit ip6table_mangle_net_exit(struct net *net) 105static void __net_exit ip6table_mangle_net_exit(struct net *net)
184{ 106{
185 ip6t_unregister_table(net->ipv6.ip6table_mangle); 107 ip6t_unregister_table(net, net->ipv6.ip6table_mangle);
186} 108}
187 109
188static struct pernet_operations ip6table_mangle_net_ops = { 110static struct pernet_operations ip6table_mangle_net_ops = {
@@ -199,9 +121,11 @@ static int __init ip6table_mangle_init(void)
199 return ret; 121 return ret;
200 122
201 /* Register hooks */ 123 /* Register hooks */
202 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 124 mangle_ops = xt_hook_link(&packet_mangler, ip6table_mangle_hook);
203 if (ret < 0) 125 if (IS_ERR(mangle_ops)) {
126 ret = PTR_ERR(mangle_ops);
204 goto cleanup_table; 127 goto cleanup_table;
128 }
205 129
206 return ret; 130 return ret;
207 131
@@ -212,7 +136,7 @@ static int __init ip6table_mangle_init(void)
212 136
213static void __exit ip6table_mangle_fini(void) 137static void __exit ip6table_mangle_fini(void)
214{ 138{
215 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 139 xt_hook_unlink(&packet_mangler, mangle_ops);
216 unregister_pernet_subsys(&ip6table_mangle_net_ops); 140 unregister_pernet_subsys(&ip6table_mangle_net_ops);
217} 141}
218 142
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index ed1a1180f3b3..5b9926a011bd 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -5,88 +5,41 @@
5 */ 5 */
6#include <linux/module.h> 6#include <linux/module.h>
7#include <linux/netfilter_ipv6/ip6_tables.h> 7#include <linux/netfilter_ipv6/ip6_tables.h>
8#include <linux/slab.h>
8 9
9#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT)) 10#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
10 11
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 = { 12static const struct xt_table packet_raw = {
39 .name = "raw", 13 .name = "raw",
40 .valid_hooks = RAW_VALID_HOOKS, 14 .valid_hooks = RAW_VALID_HOOKS,
41 .me = THIS_MODULE, 15 .me = THIS_MODULE,
42 .af = NFPROTO_IPV6, 16 .af = NFPROTO_IPV6,
17 .priority = NF_IP6_PRI_RAW,
43}; 18};
44 19
45/* The work comes in here from netfilter.c. */ 20/* The work comes in here from netfilter.c. */
46static unsigned int 21static unsigned int
47ip6t_pre_routing_hook(unsigned int hook, 22ip6table_raw_hook(unsigned int hook, struct sk_buff *skb,
48 struct sk_buff *skb, 23 const struct net_device *in, const struct net_device *out,
49 const struct net_device *in, 24 int (*okfn)(struct sk_buff *))
50 const struct net_device *out,
51 int (*okfn)(struct sk_buff *))
52{ 25{
53 return ip6t_do_table(skb, hook, in, out, 26 const struct net *net = dev_net((in != NULL) ? in : out);
54 dev_net(in)->ipv6.ip6table_raw);
55}
56 27
57static unsigned int 28 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} 29}
67 30
68static struct nf_hook_ops ip6t_ops[] __read_mostly = { 31static 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 32
85static int __net_init ip6table_raw_net_init(struct net *net) 33static int __net_init ip6table_raw_net_init(struct net *net)
86{ 34{
87 /* Register table */ 35 struct ip6t_replace *repl;
36
37 repl = ip6t_alloc_initial_table(&packet_raw);
38 if (repl == NULL)
39 return -ENOMEM;
88 net->ipv6.ip6table_raw = 40 net->ipv6.ip6table_raw =
89 ip6t_register_table(net, &packet_raw, &initial_table.repl); 41 ip6t_register_table(net, &packet_raw, repl);
42 kfree(repl);
90 if (IS_ERR(net->ipv6.ip6table_raw)) 43 if (IS_ERR(net->ipv6.ip6table_raw))
91 return PTR_ERR(net->ipv6.ip6table_raw); 44 return PTR_ERR(net->ipv6.ip6table_raw);
92 return 0; 45 return 0;
@@ -94,7 +47,7 @@ static int __net_init ip6table_raw_net_init(struct net *net)
94 47
95static void __net_exit ip6table_raw_net_exit(struct net *net) 48static void __net_exit ip6table_raw_net_exit(struct net *net)
96{ 49{
97 ip6t_unregister_table(net->ipv6.ip6table_raw); 50 ip6t_unregister_table(net, net->ipv6.ip6table_raw);
98} 51}
99 52
100static struct pernet_operations ip6table_raw_net_ops = { 53static struct pernet_operations ip6table_raw_net_ops = {
@@ -111,9 +64,11 @@ static int __init ip6table_raw_init(void)
111 return ret; 64 return ret;
112 65
113 /* Register hooks */ 66 /* Register hooks */
114 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 67 rawtable_ops = xt_hook_link(&packet_raw, ip6table_raw_hook);
115 if (ret < 0) 68 if (IS_ERR(rawtable_ops)) {
69 ret = PTR_ERR(rawtable_ops);
116 goto cleanup_table; 70 goto cleanup_table;
71 }
117 72
118 return ret; 73 return ret;
119 74
@@ -124,7 +79,7 @@ static int __init ip6table_raw_init(void)
124 79
125static void __exit ip6table_raw_fini(void) 80static void __exit ip6table_raw_fini(void)
126{ 81{
127 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 82 xt_hook_unlink(&packet_raw, rawtable_ops);
128 unregister_pernet_subsys(&ip6table_raw_net_ops); 83 unregister_pernet_subsys(&ip6table_raw_net_ops);
129} 84}
130 85
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 41b444c60934..91aa2b4d83c9 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -17,6 +17,7 @@
17 */ 17 */
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/netfilter_ipv6/ip6_tables.h> 19#include <linux/netfilter_ipv6/ip6_tables.h>
20#include <linux/slab.h>
20 21
21MODULE_LICENSE("GPL"); 22MODULE_LICENSE("GPL");
22MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>"); 23MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>");
@@ -26,106 +27,37 @@ MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
26 (1 << NF_INET_FORWARD) | \ 27 (1 << NF_INET_FORWARD) | \
27 (1 << NF_INET_LOCAL_OUT) 28 (1 << NF_INET_LOCAL_OUT)
28 29
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 = { 30static const struct xt_table security_table = {
60 .name = "security", 31 .name = "security",
61 .valid_hooks = SECURITY_VALID_HOOKS, 32 .valid_hooks = SECURITY_VALID_HOOKS,
62 .me = THIS_MODULE, 33 .me = THIS_MODULE,
63 .af = NFPROTO_IPV6, 34 .af = NFPROTO_IPV6,
35 .priority = NF_IP6_PRI_SECURITY,
64}; 36};
65 37
66static unsigned int 38static unsigned int
67ip6t_local_in_hook(unsigned int hook, 39ip6table_security_hook(unsigned int hook, struct sk_buff *skb,
68 struct sk_buff *skb, 40 const struct net_device *in,
69 const struct net_device *in, 41 const struct net_device *out,
70 const struct net_device *out, 42 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{ 43{
84 return ip6t_do_table(skb, hook, in, out, 44 const struct net *net = dev_net((in != NULL) ? in : out);
85 dev_net(in)->ipv6.ip6table_security);
86}
87 45
88static unsigned int 46 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} 47}
99 48
100static struct nf_hook_ops ip6t_ops[] __read_mostly = { 49static 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 50
124static int __net_init ip6table_security_net_init(struct net *net) 51static int __net_init ip6table_security_net_init(struct net *net)
125{ 52{
126 net->ipv6.ip6table_security = 53 struct ip6t_replace *repl;
127 ip6t_register_table(net, &security_table, &initial_table.repl);
128 54
55 repl = ip6t_alloc_initial_table(&security_table);
56 if (repl == NULL)
57 return -ENOMEM;
58 net->ipv6.ip6table_security =
59 ip6t_register_table(net, &security_table, repl);
60 kfree(repl);
129 if (IS_ERR(net->ipv6.ip6table_security)) 61 if (IS_ERR(net->ipv6.ip6table_security))
130 return PTR_ERR(net->ipv6.ip6table_security); 62 return PTR_ERR(net->ipv6.ip6table_security);
131 63
@@ -134,7 +66,7 @@ static int __net_init ip6table_security_net_init(struct net *net)
134 66
135static void __net_exit ip6table_security_net_exit(struct net *net) 67static void __net_exit ip6table_security_net_exit(struct net *net)
136{ 68{
137 ip6t_unregister_table(net->ipv6.ip6table_security); 69 ip6t_unregister_table(net, net->ipv6.ip6table_security);
138} 70}
139 71
140static struct pernet_operations ip6table_security_net_ops = { 72static struct pernet_operations ip6table_security_net_ops = {
@@ -150,9 +82,11 @@ static int __init ip6table_security_init(void)
150 if (ret < 0) 82 if (ret < 0)
151 return ret; 83 return ret;
152 84
153 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 85 sectbl_ops = xt_hook_link(&security_table, ip6table_security_hook);
154 if (ret < 0) 86 if (IS_ERR(sectbl_ops)) {
87 ret = PTR_ERR(sectbl_ops);
155 goto cleanup_table; 88 goto cleanup_table;
89 }
156 90
157 return ret; 91 return ret;
158 92
@@ -163,7 +97,7 @@ cleanup_table:
163 97
164static void __exit ip6table_security_fini(void) 98static void __exit ip6table_security_fini(void)
165{ 99{
166 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 100 xt_hook_unlink(&security_table, sectbl_ops);
167 unregister_pernet_subsys(&ip6table_security_net_ops); 101 unregister_pernet_subsys(&ip6table_security_net_ops);
168} 102}
169 103
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 5f2ec208a8c3..996c3f41fecd 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -20,12 +20,14 @@
20#include <net/ipv6.h> 20#include <net/ipv6.h>
21#include <net/inet_frag.h> 21#include <net/inet_frag.h>
22 22
23#include <linux/netfilter_bridge.h>
23#include <linux/netfilter_ipv6.h> 24#include <linux/netfilter_ipv6.h>
24#include <net/netfilter/nf_conntrack.h> 25#include <net/netfilter/nf_conntrack.h>
25#include <net/netfilter/nf_conntrack_helper.h> 26#include <net/netfilter/nf_conntrack_helper.h>
26#include <net/netfilter/nf_conntrack_l4proto.h> 27#include <net/netfilter/nf_conntrack_l4proto.h>
27#include <net/netfilter/nf_conntrack_l3proto.h> 28#include <net/netfilter/nf_conntrack_l3proto.h>
28#include <net/netfilter/nf_conntrack_core.h> 29#include <net/netfilter/nf_conntrack_core.h>
30#include <net/netfilter/nf_conntrack_zones.h>
29#include <net/netfilter/ipv6/nf_conntrack_ipv6.h> 31#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
30#include <net/netfilter/nf_log.h> 32#include <net/netfilter/nf_log.h>
31 33
@@ -187,6 +189,26 @@ out:
187 return nf_conntrack_confirm(skb); 189 return nf_conntrack_confirm(skb);
188} 190}
189 191
192static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
193 struct sk_buff *skb)
194{
195 u16 zone = NF_CT_DEFAULT_ZONE;
196
197 if (skb->nfct)
198 zone = nf_ct_zone((struct nf_conn *)skb->nfct);
199
200#ifdef CONFIG_BRIDGE_NETFILTER
201 if (skb->nf_bridge &&
202 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
203 return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
204#endif
205 if (hooknum == NF_INET_PRE_ROUTING)
206 return IP6_DEFRAG_CONNTRACK_IN + zone;
207 else
208 return IP6_DEFRAG_CONNTRACK_OUT + zone;
209
210}
211
190static unsigned int ipv6_defrag(unsigned int hooknum, 212static unsigned int ipv6_defrag(unsigned int hooknum,
191 struct sk_buff *skb, 213 struct sk_buff *skb,
192 const struct net_device *in, 214 const struct net_device *in,
@@ -196,11 +218,10 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
196 struct sk_buff *reasm; 218 struct sk_buff *reasm;
197 219
198 /* Previously seen (loopback)? */ 220 /* Previously seen (loopback)? */
199 if (skb->nfct) 221 if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
200 return NF_ACCEPT; 222 return NF_ACCEPT;
201 223
202 reasm = nf_ct_frag6_gather(skb); 224 reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
203
204 /* queued */ 225 /* queued */
205 if (reasm == NULL) 226 if (reasm == NULL)
206 return NF_STOLEN; 227 return NF_STOLEN;
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 642dcb127bab..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)
@@ -244,18 +247,18 @@ static const struct nla_policy icmpv6_nla_policy[CTA_PROTO_MAX+1] = {
244static int icmpv6_nlattr_to_tuple(struct nlattr *tb[], 247static int icmpv6_nlattr_to_tuple(struct nlattr *tb[],
245 struct nf_conntrack_tuple *tuple) 248 struct nf_conntrack_tuple *tuple)
246{ 249{
247 if (!tb[CTA_PROTO_ICMPV6_TYPE] 250 if (!tb[CTA_PROTO_ICMPV6_TYPE] ||
248 || !tb[CTA_PROTO_ICMPV6_CODE] 251 !tb[CTA_PROTO_ICMPV6_CODE] ||
249 || !tb[CTA_PROTO_ICMPV6_ID]) 252 !tb[CTA_PROTO_ICMPV6_ID])
250 return -EINVAL; 253 return -EINVAL;
251 254
252 tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]); 255 tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]);
253 tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]); 256 tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]);
254 tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMPV6_ID]); 257 tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMPV6_ID]);
255 258
256 if (tuple->dst.u.icmp.type < 128 259 if (tuple->dst.u.icmp.type < 128 ||
257 || tuple->dst.u.icmp.type - 128 >= sizeof(invmap) 260 tuple->dst.u.icmp.type - 128 >= sizeof(invmap) ||
258 || !invmap[tuple->dst.u.icmp.type - 128]) 261 !invmap[tuple->dst.u.icmp.type - 128])
259 return -EINVAL; 262 return -EINVAL;
260 263
261 return 0; 264 return 0;
@@ -277,9 +280,7 @@ static struct ctl_table icmpv6_sysctl_table[] = {
277 .mode = 0644, 280 .mode = 0644,
278 .proc_handler = proc_dointvec_jiffies, 281 .proc_handler = proc_dointvec_jiffies,
279 }, 282 },
280 { 283 { }
281 .ctl_name = 0
282 }
283}; 284};
284#endif /* CONFIG_SYSCTL */ 285#endif /* CONFIG_SYSCTL */
285 286
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index f3aba255ad9f..dd5b9bd61c62 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -27,6 +27,7 @@
27#include <linux/ipv6.h> 27#include <linux/ipv6.h>
28#include <linux/icmpv6.h> 28#include <linux/icmpv6.h>
29#include <linux/random.h> 29#include <linux/random.h>
30#include <linux/slab.h>
30 31
31#include <net/sock.h> 32#include <net/sock.h>
32#include <net/snmp.h> 33#include <net/snmp.h>
@@ -45,9 +46,6 @@
45#include <linux/kernel.h> 46#include <linux/kernel.h>
46#include <linux/module.h> 47#include <linux/module.h>
47 48
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 49
52struct nf_ct_frag6_skb_cb 50struct nf_ct_frag6_skb_cb
53{ 51{
@@ -63,6 +61,7 @@ struct nf_ct_frag6_queue
63 struct inet_frag_queue q; 61 struct inet_frag_queue q;
64 62
65 __be32 id; /* fragment id */ 63 __be32 id; /* fragment id */
64 u32 user;
66 struct in6_addr saddr; 65 struct in6_addr saddr;
67 struct in6_addr daddr; 66 struct in6_addr daddr;
68 67
@@ -83,7 +82,6 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
83 .proc_handler = proc_dointvec_jiffies, 82 .proc_handler = proc_dointvec_jiffies,
84 }, 83 },
85 { 84 {
86 .ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH,
87 .procname = "nf_conntrack_frag6_low_thresh", 85 .procname = "nf_conntrack_frag6_low_thresh",
88 .data = &nf_init_frags.low_thresh, 86 .data = &nf_init_frags.low_thresh,
89 .maxlen = sizeof(unsigned int), 87 .maxlen = sizeof(unsigned int),
@@ -91,14 +89,13 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
91 .proc_handler = proc_dointvec, 89 .proc_handler = proc_dointvec,
92 }, 90 },
93 { 91 {
94 .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
95 .procname = "nf_conntrack_frag6_high_thresh", 92 .procname = "nf_conntrack_frag6_high_thresh",
96 .data = &nf_init_frags.high_thresh, 93 .data = &nf_init_frags.high_thresh,
97 .maxlen = sizeof(unsigned int), 94 .maxlen = sizeof(unsigned int),
98 .mode = 0644, 95 .mode = 0644,
99 .proc_handler = proc_dointvec, 96 .proc_handler = proc_dointvec,
100 }, 97 },
101 { .ctl_name = 0 } 98 { }
102}; 99};
103#endif 100#endif
104 101
@@ -170,13 +167,14 @@ out:
170/* Creation primitives. */ 167/* Creation primitives. */
171 168
172static __inline__ struct nf_ct_frag6_queue * 169static __inline__ struct nf_ct_frag6_queue *
173fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) 170fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
174{ 171{
175 struct inet_frag_queue *q; 172 struct inet_frag_queue *q;
176 struct ip6_create_arg arg; 173 struct ip6_create_arg arg;
177 unsigned int hash; 174 unsigned int hash;
178 175
179 arg.id = id; 176 arg.id = id;
177 arg.user = user;
180 arg.src = src; 178 arg.src = src;
181 arg.dst = dst; 179 arg.dst = dst;
182 180
@@ -472,7 +470,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
472 470
473 /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */ 471 /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */
474 fp = skb_shinfo(head)->frag_list; 472 fp = skb_shinfo(head)->frag_list;
475 if (NFCT_FRAG6_CB(fp)->orig == NULL) 473 if (fp && NFCT_FRAG6_CB(fp)->orig == NULL)
476 /* at above code, head skb is divided into two skbs. */ 474 /* at above code, head skb is divided into two skbs. */
477 fp = fp->next; 475 fp = fp->next;
478 476
@@ -561,7 +559,7 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
561 return 0; 559 return 0;
562} 560}
563 561
564struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb) 562struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
565{ 563{
566 struct sk_buff *clone; 564 struct sk_buff *clone;
567 struct net_device *dev = skb->dev; 565 struct net_device *dev = skb->dev;
@@ -598,16 +596,10 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
598 hdr = ipv6_hdr(clone); 596 hdr = ipv6_hdr(clone);
599 fhdr = (struct frag_hdr *)skb_transport_header(clone); 597 fhdr = (struct frag_hdr *)skb_transport_header(clone);
600 598
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) 599 if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
608 nf_ct_frag6_evictor(); 600 nf_ct_frag6_evictor();
609 601
610 fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr); 602 fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr);
611 if (fq == NULL) { 603 if (fq == NULL) {
612 pr_debug("Can't find and can't create new queue\n"); 604 pr_debug("Can't find and can't create new queue\n");
613 goto ret_orig; 605 goto ret_orig;
@@ -670,8 +662,8 @@ int nf_ct_frag6_init(void)
670 nf_frags.frag_expire = nf_ct_frag6_expire; 662 nf_frags.frag_expire = nf_ct_frag6_expire;
671 nf_frags.secret_interval = 10 * 60 * HZ; 663 nf_frags.secret_interval = 10 * 60 * HZ;
672 nf_init_frags.timeout = IPV6_FRAG_TIMEOUT; 664 nf_init_frags.timeout = IPV6_FRAG_TIMEOUT;
673 nf_init_frags.high_thresh = 256 * 1024; 665 nf_init_frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
674 nf_init_frags.low_thresh = 192 * 1024; 666 nf_init_frags.low_thresh = IPV6_FRAG_LOW_THRESH;
675 inet_frags_init_net(&nf_init_frags); 667 inet_frags_init_net(&nf_init_frags);
676 inet_frags_init(&nf_frags); 668 inet_frags_init(&nf_frags);
677 669
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 4f24570b0869..8763b1a0814a 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -21,6 +21,7 @@
21#include <linux/errno.h> 21#include <linux/errno.h>
22#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/socket.h> 23#include <linux/socket.h>
24#include <linux/slab.h>
24#include <linux/sockios.h> 25#include <linux/sockios.h>
25#include <linux/net.h> 26#include <linux/net.h>
26#include <linux/in6.h> 27#include <linux/in6.h>
@@ -72,7 +73,7 @@ static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
72 int is_multicast = ipv6_addr_is_multicast(loc_addr); 73 int is_multicast = ipv6_addr_is_multicast(loc_addr);
73 74
74 sk_for_each_from(sk, node) 75 sk_for_each_from(sk, node)
75 if (inet_sk(sk)->num == num) { 76 if (inet_sk(sk)->inet_num == num) {
76 struct ipv6_pinfo *np = inet6_sk(sk); 77 struct ipv6_pinfo *np = inet6_sk(sk);
77 78
78 if (!net_eq(sock_net(sk), net)) 79 if (!net_eq(sock_net(sk), net))
@@ -249,7 +250,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
249 250
250 /* Raw sockets are IPv6 only */ 251 /* Raw sockets are IPv6 only */
251 if (addr_type == IPV6_ADDR_MAPPED) 252 if (addr_type == IPV6_ADDR_MAPPED)
252 return(-EADDRNOTAVAIL); 253 return -EADDRNOTAVAIL;
253 254
254 lock_sock(sk); 255 lock_sock(sk);
255 256
@@ -257,6 +258,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
257 if (sk->sk_state != TCP_CLOSE) 258 if (sk->sk_state != TCP_CLOSE)
258 goto out; 259 goto out;
259 260
261 rcu_read_lock();
260 /* Check if the address belongs to the host. */ 262 /* Check if the address belongs to the host. */
261 if (addr_type != IPV6_ADDR_ANY) { 263 if (addr_type != IPV6_ADDR_ANY) {
262 struct net_device *dev = NULL; 264 struct net_device *dev = NULL;
@@ -272,13 +274,13 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
272 274
273 /* Binding to link-local address requires an interface */ 275 /* Binding to link-local address requires an interface */
274 if (!sk->sk_bound_dev_if) 276 if (!sk->sk_bound_dev_if)
275 goto out; 277 goto out_unlock;
276 278
277 dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if); 279 err = -ENODEV;
278 if (!dev) { 280 dev = dev_get_by_index_rcu(sock_net(sk),
279 err = -ENODEV; 281 sk->sk_bound_dev_if);
280 goto out; 282 if (!dev)
281 } 283 goto out_unlock;
282 } 284 }
283 285
284 /* ipv4 addr of the socket is invalid. Only the 286 /* ipv4 addr of the socket is invalid. Only the
@@ -289,20 +291,18 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
289 err = -EADDRNOTAVAIL; 291 err = -EADDRNOTAVAIL;
290 if (!ipv6_chk_addr(sock_net(sk), &addr->sin6_addr, 292 if (!ipv6_chk_addr(sock_net(sk), &addr->sin6_addr,
291 dev, 0)) { 293 dev, 0)) {
292 if (dev) 294 goto out_unlock;
293 dev_put(dev);
294 goto out;
295 } 295 }
296 } 296 }
297 if (dev)
298 dev_put(dev);
299 } 297 }
300 298
301 inet->rcv_saddr = inet->saddr = v4addr; 299 inet->inet_rcv_saddr = inet->inet_saddr = v4addr;
302 ipv6_addr_copy(&np->rcv_saddr, &addr->sin6_addr); 300 ipv6_addr_copy(&np->rcv_saddr, &addr->sin6_addr);
303 if (!(addr_type & IPV6_ADDR_MULTICAST)) 301 if (!(addr_type & IPV6_ADDR_MULTICAST))
304 ipv6_addr_copy(&np->saddr, &addr->sin6_addr); 302 ipv6_addr_copy(&np->saddr, &addr->sin6_addr);
305 err = 0; 303 err = 0;
304out_unlock:
305 rcu_read_unlock();
306out: 306out:
307 release_sock(sk); 307 release_sock(sk);
308 return err; 308 return err;
@@ -381,8 +381,7 @@ static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
381 } 381 }
382 382
383 /* Charge it to the socket. */ 383 /* Charge it to the socket. */
384 if (sock_queue_rcv_skb(sk,skb)<0) { 384 if (sock_queue_rcv_skb(sk, skb) < 0) {
385 atomic_inc(&sk->sk_drops);
386 kfree_skb(skb); 385 kfree_skb(skb);
387 return NET_RX_DROP; 386 return NET_RX_DROP;
388 } 387 }
@@ -416,14 +415,14 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
416 skb_network_header_len(skb)); 415 skb_network_header_len(skb));
417 if (!csum_ipv6_magic(&ipv6_hdr(skb)->saddr, 416 if (!csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
418 &ipv6_hdr(skb)->daddr, 417 &ipv6_hdr(skb)->daddr,
419 skb->len, inet->num, skb->csum)) 418 skb->len, inet->inet_num, skb->csum))
420 skb->ip_summed = CHECKSUM_UNNECESSARY; 419 skb->ip_summed = CHECKSUM_UNNECESSARY;
421 } 420 }
422 if (!skb_csum_unnecessary(skb)) 421 if (!skb_csum_unnecessary(skb))
423 skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr, 422 skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
424 &ipv6_hdr(skb)->daddr, 423 &ipv6_hdr(skb)->daddr,
425 skb->len, 424 skb->len,
426 inet->num, 0)); 425 inet->inet_num, 0));
427 426
428 if (inet->hdrincl) { 427 if (inet->hdrincl) {
429 if (skb_checksum_complete(skb)) { 428 if (skb_checksum_complete(skb)) {
@@ -497,7 +496,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
497 sin6->sin6_scope_id = IP6CB(skb)->iif; 496 sin6->sin6_scope_id = IP6CB(skb)->iif;
498 } 497 }
499 498
500 sock_recv_timestamp(msg, sk, skb); 499 sock_recv_ts_and_drops(msg, sk, skb);
501 500
502 if (np->rxopt.all) 501 if (np->rxopt.all)
503 datagram_recv_ctl(sk, msg, skb); 502 datagram_recv_ctl(sk, msg, skb);
@@ -518,7 +517,6 @@ csum_copy_err:
518 as some normal condition. 517 as some normal condition.
519 */ 518 */
520 err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH; 519 err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
521 atomic_inc(&sk->sk_drops);
522 goto out; 520 goto out;
523} 521}
524 522
@@ -766,8 +764,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
766 proto = ntohs(sin6->sin6_port); 764 proto = ntohs(sin6->sin6_port);
767 765
768 if (!proto) 766 if (!proto)
769 proto = inet->num; 767 proto = inet->inet_num;
770 else if (proto != inet->num) 768 else if (proto != inet->inet_num)
771 return(-EINVAL); 769 return(-EINVAL);
772 770
773 if (proto > 255) 771 if (proto > 255)
@@ -800,7 +798,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
800 if (sk->sk_state != TCP_ESTABLISHED) 798 if (sk->sk_state != TCP_ESTABLISHED)
801 return -EDESTADDRREQ; 799 return -EDESTADDRREQ;
802 800
803 proto = inet->num; 801 proto = inet->inet_num;
804 daddr = &np->daddr; 802 daddr = &np->daddr;
805 fl.fl6_flowlabel = np->flow_label; 803 fl.fl6_flowlabel = np->flow_label;
806 } 804 }
@@ -967,7 +965,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
967 965
968 switch (optname) { 966 switch (optname) {
969 case IPV6_CHECKSUM: 967 case IPV6_CHECKSUM:
970 if (inet_sk(sk)->num == IPPROTO_ICMPV6 && 968 if (inet_sk(sk)->inet_num == IPPROTO_ICMPV6 &&
971 level == IPPROTO_IPV6) { 969 level == IPPROTO_IPV6) {
972 /* 970 /*
973 * RFC3542 tells that IPV6_CHECKSUM socket 971 * RFC3542 tells that IPV6_CHECKSUM socket
@@ -1007,7 +1005,7 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname,
1007 break; 1005 break;
1008 1006
1009 case SOL_ICMPV6: 1007 case SOL_ICMPV6:
1010 if (inet_sk(sk)->num != IPPROTO_ICMPV6) 1008 if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1011 return -EOPNOTSUPP; 1009 return -EOPNOTSUPP;
1012 return rawv6_seticmpfilter(sk, level, optname, optval, 1010 return rawv6_seticmpfilter(sk, level, optname, optval,
1013 optlen); 1011 optlen);
@@ -1030,7 +1028,7 @@ static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname,
1030 case SOL_RAW: 1028 case SOL_RAW:
1031 break; 1029 break;
1032 case SOL_ICMPV6: 1030 case SOL_ICMPV6:
1033 if (inet_sk(sk)->num != IPPROTO_ICMPV6) 1031 if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1034 return -EOPNOTSUPP; 1032 return -EOPNOTSUPP;
1035 return rawv6_seticmpfilter(sk, level, optname, optval, optlen); 1033 return rawv6_seticmpfilter(sk, level, optname, optval, optlen);
1036 case SOL_IPV6: 1034 case SOL_IPV6:
@@ -1087,7 +1085,7 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname,
1087 break; 1085 break;
1088 1086
1089 case SOL_ICMPV6: 1087 case SOL_ICMPV6:
1090 if (inet_sk(sk)->num != IPPROTO_ICMPV6) 1088 if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1091 return -EOPNOTSUPP; 1089 return -EOPNOTSUPP;
1092 return rawv6_geticmpfilter(sk, level, optname, optval, 1090 return rawv6_geticmpfilter(sk, level, optname, optval,
1093 optlen); 1091 optlen);
@@ -1110,7 +1108,7 @@ static int compat_rawv6_getsockopt(struct sock *sk, int level, int optname,
1110 case SOL_RAW: 1108 case SOL_RAW:
1111 break; 1109 break;
1112 case SOL_ICMPV6: 1110 case SOL_ICMPV6:
1113 if (inet_sk(sk)->num != IPPROTO_ICMPV6) 1111 if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1114 return -EOPNOTSUPP; 1112 return -EOPNOTSUPP;
1115 return rawv6_geticmpfilter(sk, level, optname, optval, optlen); 1113 return rawv6_geticmpfilter(sk, level, optname, optval, optlen);
1116 case SOL_IPV6: 1114 case SOL_IPV6:
@@ -1157,7 +1155,7 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
1157 1155
1158static void rawv6_close(struct sock *sk, long timeout) 1156static void rawv6_close(struct sock *sk, long timeout)
1159{ 1157{
1160 if (inet_sk(sk)->num == IPPROTO_RAW) 1158 if (inet_sk(sk)->inet_num == IPPROTO_RAW)
1161 ip6_ra_control(sk, -1); 1159 ip6_ra_control(sk, -1);
1162 ip6mr_sk_done(sk); 1160 ip6mr_sk_done(sk);
1163 sk_common_release(sk); 1161 sk_common_release(sk);
@@ -1176,7 +1174,7 @@ static int rawv6_init_sk(struct sock *sk)
1176{ 1174{
1177 struct raw6_sock *rp = raw6_sk(sk); 1175 struct raw6_sock *rp = raw6_sk(sk);
1178 1176
1179 switch (inet_sk(sk)->num) { 1177 switch (inet_sk(sk)->inet_num) {
1180 case IPPROTO_ICMPV6: 1178 case IPPROTO_ICMPV6:
1181 rp->checksum = 1; 1179 rp->checksum = 1;
1182 rp->offset = 2; 1180 rp->offset = 2;
@@ -1226,7 +1224,7 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
1226 dest = &np->daddr; 1224 dest = &np->daddr;
1227 src = &np->rcv_saddr; 1225 src = &np->rcv_saddr;
1228 destp = 0; 1226 destp = 0;
1229 srcp = inet_sk(sp)->num; 1227 srcp = inet_sk(sp)->inet_num;
1230 seq_printf(seq, 1228 seq_printf(seq,
1231 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " 1229 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
1232 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", 1230 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n",
@@ -1278,7 +1276,7 @@ static const struct file_operations raw6_seq_fops = {
1278 .release = seq_release_net, 1276 .release = seq_release_net,
1279}; 1277};
1280 1278
1281static int raw6_init_net(struct net *net) 1279static int __net_init raw6_init_net(struct net *net)
1282{ 1280{
1283 if (!proc_net_fops_create(net, "raw6", S_IRUGO, &raw6_seq_fops)) 1281 if (!proc_net_fops_create(net, "raw6", S_IRUGO, &raw6_seq_fops))
1284 return -ENOMEM; 1282 return -ENOMEM;
@@ -1286,7 +1284,7 @@ static int raw6_init_net(struct net *net)
1286 return 0; 1284 return 0;
1287} 1285}
1288 1286
1289static void raw6_exit_net(struct net *net) 1287static void __net_exit raw6_exit_net(struct net *net)
1290{ 1288{
1291 proc_net_remove(net, "raw6"); 1289 proc_net_remove(net, "raw6");
1292} 1290}
@@ -1338,7 +1336,6 @@ static struct inet_protosw rawv6_protosw = {
1338 .protocol = IPPROTO_IP, /* wild card */ 1336 .protocol = IPPROTO_IP, /* wild card */
1339 .prot = &rawv6_prot, 1337 .prot = &rawv6_prot,
1340 .ops = &inet6_sockraw_ops, 1338 .ops = &inet6_sockraw_ops,
1341 .capability = CAP_NET_RAW,
1342 .no_check = UDP_CSUM_DEFAULT, 1339 .no_check = UDP_CSUM_DEFAULT,
1343 .flags = INET_PROTOSW_REUSE, 1340 .flags = INET_PROTOSW_REUSE,
1344}; 1341};
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index da5bd0ed83df..6d4292ff5854 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -41,6 +41,7 @@
41#include <linux/random.h> 41#include <linux/random.h>
42#include <linux/jhash.h> 42#include <linux/jhash.h>
43#include <linux/skbuff.h> 43#include <linux/skbuff.h>
44#include <linux/slab.h>
44 45
45#include <net/sock.h> 46#include <net/sock.h>
46#include <net/snmp.h> 47#include <net/snmp.h>
@@ -72,6 +73,7 @@ struct frag_queue
72 struct inet_frag_queue q; 73 struct inet_frag_queue q;
73 74
74 __be32 id; /* fragment id */ 75 __be32 id; /* fragment id */
76 u32 user;
75 struct in6_addr saddr; 77 struct in6_addr saddr;
76 struct in6_addr daddr; 78 struct in6_addr daddr;
77 79
@@ -141,7 +143,7 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a)
141 struct ip6_create_arg *arg = a; 143 struct ip6_create_arg *arg = a;
142 144
143 fq = container_of(q, struct frag_queue, q); 145 fq = container_of(q, struct frag_queue, q);
144 return (fq->id == arg->id && 146 return (fq->id == arg->id && fq->user == arg->user &&
145 ipv6_addr_equal(&fq->saddr, arg->src) && 147 ipv6_addr_equal(&fq->saddr, arg->src) &&
146 ipv6_addr_equal(&fq->daddr, arg->dst)); 148 ipv6_addr_equal(&fq->daddr, arg->dst));
147} 149}
@@ -163,6 +165,7 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
163 struct ip6_create_arg *arg = a; 165 struct ip6_create_arg *arg = a;
164 166
165 fq->id = arg->id; 167 fq->id = arg->id;
168 fq->user = arg->user;
166 ipv6_addr_copy(&fq->saddr, arg->src); 169 ipv6_addr_copy(&fq->saddr, arg->src);
167 ipv6_addr_copy(&fq->daddr, arg->dst); 170 ipv6_addr_copy(&fq->daddr, arg->dst);
168} 171}
@@ -208,18 +211,17 @@ static void ip6_frag_expire(unsigned long data)
208 fq_kill(fq); 211 fq_kill(fq);
209 212
210 net = container_of(fq->q.net, struct net, ipv6.frags); 213 net = container_of(fq->q.net, struct net, ipv6.frags);
211 dev = dev_get_by_index(net, fq->iif); 214 rcu_read_lock();
215 dev = dev_get_by_index_rcu(net, fq->iif);
212 if (!dev) 216 if (!dev)
213 goto out; 217 goto out_rcu_unlock;
214 218
215 rcu_read_lock();
216 IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); 219 IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT);
217 IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); 220 IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
218 rcu_read_unlock();
219 221
220 /* Don't send error if the first segment did not arrive. */ 222 /* Don't send error if the first segment did not arrive. */
221 if (!(fq->q.last_in & INET_FRAG_FIRST_IN) || !fq->q.fragments) 223 if (!(fq->q.last_in & INET_FRAG_FIRST_IN) || !fq->q.fragments)
222 goto out; 224 goto out_rcu_unlock;
223 225
224 /* 226 /*
225 But use as source device on which LAST ARRIVED 227 But use as source device on which LAST ARRIVED
@@ -227,23 +229,23 @@ static void ip6_frag_expire(unsigned long data)
227 pointer directly, device might already disappeared. 229 pointer directly, device might already disappeared.
228 */ 230 */
229 fq->q.fragments->dev = dev; 231 fq->q.fragments->dev = dev;
230 icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev); 232 icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0);
233out_rcu_unlock:
234 rcu_read_unlock();
231out: 235out:
232 if (dev)
233 dev_put(dev);
234 spin_unlock(&fq->q.lock); 236 spin_unlock(&fq->q.lock);
235 fq_put(fq); 237 fq_put(fq);
236} 238}
237 239
238static __inline__ struct frag_queue * 240static __inline__ struct frag_queue *
239fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst, 241fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst)
240 struct inet6_dev *idev)
241{ 242{
242 struct inet_frag_queue *q; 243 struct inet_frag_queue *q;
243 struct ip6_create_arg arg; 244 struct ip6_create_arg arg;
244 unsigned int hash; 245 unsigned int hash;
245 246
246 arg.id = id; 247 arg.id = id;
248 arg.user = IP6_DEFRAG_LOCAL_DELIVER;
247 arg.src = src; 249 arg.src = src;
248 arg.dst = dst; 250 arg.dst = dst;
249 251
@@ -252,13 +254,9 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
252 254
253 q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); 255 q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
254 if (q == NULL) 256 if (q == NULL)
255 goto oom; 257 return NULL;
256 258
257 return container_of(q, struct frag_queue, q); 259 return container_of(q, struct frag_queue, q);
258
259oom:
260 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS);
261 return NULL;
262} 260}
263 261
264static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, 262static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
@@ -604,8 +602,8 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
604 if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh) 602 if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
605 ip6_evictor(net, ip6_dst_idev(skb_dst(skb))); 603 ip6_evictor(net, ip6_dst_idev(skb_dst(skb)));
606 604
607 if ((fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr, 605 fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr);
608 ip6_dst_idev(skb_dst(skb)))) != NULL) { 606 if (fq != NULL) {
609 int ret; 607 int ret;
610 608
611 spin_lock(&fq->q.lock); 609 spin_lock(&fq->q.lock);
@@ -636,7 +634,6 @@ static const struct inet6_protocol frag_protocol =
636#ifdef CONFIG_SYSCTL 634#ifdef CONFIG_SYSCTL
637static struct ctl_table ip6_frags_ns_ctl_table[] = { 635static struct ctl_table ip6_frags_ns_ctl_table[] = {
638 { 636 {
639 .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH,
640 .procname = "ip6frag_high_thresh", 637 .procname = "ip6frag_high_thresh",
641 .data = &init_net.ipv6.frags.high_thresh, 638 .data = &init_net.ipv6.frags.high_thresh,
642 .maxlen = sizeof(int), 639 .maxlen = sizeof(int),
@@ -644,7 +641,6 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = {
644 .proc_handler = proc_dointvec 641 .proc_handler = proc_dointvec
645 }, 642 },
646 { 643 {
647 .ctl_name = NET_IPV6_IP6FRAG_LOW_THRESH,
648 .procname = "ip6frag_low_thresh", 644 .procname = "ip6frag_low_thresh",
649 .data = &init_net.ipv6.frags.low_thresh, 645 .data = &init_net.ipv6.frags.low_thresh,
650 .maxlen = sizeof(int), 646 .maxlen = sizeof(int),
@@ -652,37 +648,33 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = {
652 .proc_handler = proc_dointvec 648 .proc_handler = proc_dointvec
653 }, 649 },
654 { 650 {
655 .ctl_name = NET_IPV6_IP6FRAG_TIME,
656 .procname = "ip6frag_time", 651 .procname = "ip6frag_time",
657 .data = &init_net.ipv6.frags.timeout, 652 .data = &init_net.ipv6.frags.timeout,
658 .maxlen = sizeof(int), 653 .maxlen = sizeof(int),
659 .mode = 0644, 654 .mode = 0644,
660 .proc_handler = proc_dointvec_jiffies, 655 .proc_handler = proc_dointvec_jiffies,
661 .strategy = sysctl_jiffies,
662 }, 656 },
663 { } 657 { }
664}; 658};
665 659
666static struct ctl_table ip6_frags_ctl_table[] = { 660static struct ctl_table ip6_frags_ctl_table[] = {
667 { 661 {
668 .ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL,
669 .procname = "ip6frag_secret_interval", 662 .procname = "ip6frag_secret_interval",
670 .data = &ip6_frags.secret_interval, 663 .data = &ip6_frags.secret_interval,
671 .maxlen = sizeof(int), 664 .maxlen = sizeof(int),
672 .mode = 0644, 665 .mode = 0644,
673 .proc_handler = proc_dointvec_jiffies, 666 .proc_handler = proc_dointvec_jiffies,
674 .strategy = sysctl_jiffies
675 }, 667 },
676 { } 668 { }
677}; 669};
678 670
679static int ip6_frags_ns_sysctl_register(struct net *net) 671static int __net_init ip6_frags_ns_sysctl_register(struct net *net)
680{ 672{
681 struct ctl_table *table; 673 struct ctl_table *table;
682 struct ctl_table_header *hdr; 674 struct ctl_table_header *hdr;
683 675
684 table = ip6_frags_ns_ctl_table; 676 table = ip6_frags_ns_ctl_table;
685 if (net != &init_net) { 677 if (!net_eq(net, &init_net)) {
686 table = kmemdup(table, sizeof(ip6_frags_ns_ctl_table), GFP_KERNEL); 678 table = kmemdup(table, sizeof(ip6_frags_ns_ctl_table), GFP_KERNEL);
687 if (table == NULL) 679 if (table == NULL)
688 goto err_alloc; 680 goto err_alloc;
@@ -700,19 +692,20 @@ static int ip6_frags_ns_sysctl_register(struct net *net)
700 return 0; 692 return 0;
701 693
702err_reg: 694err_reg:
703 if (net != &init_net) 695 if (!net_eq(net, &init_net))
704 kfree(table); 696 kfree(table);
705err_alloc: 697err_alloc:
706 return -ENOMEM; 698 return -ENOMEM;
707} 699}
708 700
709static void ip6_frags_ns_sysctl_unregister(struct net *net) 701static void __net_exit ip6_frags_ns_sysctl_unregister(struct net *net)
710{ 702{
711 struct ctl_table *table; 703 struct ctl_table *table;
712 704
713 table = net->ipv6.sysctl.frags_hdr->ctl_table_arg; 705 table = net->ipv6.sysctl.frags_hdr->ctl_table_arg;
714 unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr); 706 unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr);
715 kfree(table); 707 if (!net_eq(net, &init_net))
708 kfree(table);
716} 709}
717 710
718static struct ctl_table_header *ip6_ctl_header; 711static struct ctl_table_header *ip6_ctl_header;
@@ -748,10 +741,10 @@ static inline void ip6_frags_sysctl_unregister(void)
748} 741}
749#endif 742#endif
750 743
751static int ipv6_frags_init_net(struct net *net) 744static int __net_init ipv6_frags_init_net(struct net *net)
752{ 745{
753 net->ipv6.frags.high_thresh = 256 * 1024; 746 net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
754 net->ipv6.frags.low_thresh = 192 * 1024; 747 net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
755 net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT; 748 net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
756 749
757 inet_frags_init_net(&net->ipv6.frags); 750 inet_frags_init_net(&net->ipv6.frags);
@@ -759,7 +752,7 @@ static int ipv6_frags_init_net(struct net *net)
759 return ip6_frags_ns_sysctl_register(net); 752 return ip6_frags_ns_sysctl_register(net);
760} 753}
761 754
762static void ipv6_frags_exit_net(struct net *net) 755static void __net_exit ipv6_frags_exit_net(struct net *net)
763{ 756{
764 ip6_frags_ns_sysctl_unregister(net); 757 ip6_frags_ns_sysctl_unregister(net);
765 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags); 758 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index d6fe7646a8ff..05ebd7833043 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -40,6 +40,7 @@
40#include <linux/proc_fs.h> 40#include <linux/proc_fs.h>
41#include <linux/seq_file.h> 41#include <linux/seq_file.h>
42#include <linux/nsproxy.h> 42#include <linux/nsproxy.h>
43#include <linux/slab.h>
43#include <net/net_namespace.h> 44#include <net/net_namespace.h>
44#include <net/snmp.h> 45#include <net/snmp.h>
45#include <net/ipv6.h> 46#include <net/ipv6.h>
@@ -814,20 +815,13 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
814{ 815{
815 int flags = 0; 816 int flags = 0;
816 817
817 if (rt6_need_strict(&fl->fl6_dst)) 818 if (fl->oif || rt6_need_strict(&fl->fl6_dst))
818 flags |= RT6_LOOKUP_F_IFACE; 819 flags |= RT6_LOOKUP_F_IFACE;
819 820
820 if (!ipv6_addr_any(&fl->fl6_src)) 821 if (!ipv6_addr_any(&fl->fl6_src))
821 flags |= RT6_LOOKUP_F_HAS_SADDR; 822 flags |= RT6_LOOKUP_F_HAS_SADDR;
822 else if (sk) { 823 else if (sk)
823 unsigned int prefs = inet6_sk(sk)->srcprefs; 824 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
824 if (prefs & IPV6_PREFER_SRC_TMP)
825 flags |= RT6_LOOKUP_F_SRCPREF_TMP;
826 if (prefs & IPV6_PREFER_SRC_PUBLIC)
827 flags |= RT6_LOOKUP_F_SRCPREF_PUBLIC;
828 if (prefs & IPV6_PREFER_SRC_COA)
829 flags |= RT6_LOOKUP_F_SRCPREF_COA;
830 }
831 825
832 return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); 826 return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output);
833} 827}
@@ -886,7 +880,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
886 880
887 rt = (struct rt6_info *) dst; 881 rt = (struct rt6_info *) dst;
888 882
889 if (rt && rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) 883 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
890 return dst; 884 return dst;
891 885
892 return NULL; 886 return NULL;
@@ -897,19 +891,24 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
897 struct rt6_info *rt = (struct rt6_info *) dst; 891 struct rt6_info *rt = (struct rt6_info *) dst;
898 892
899 if (rt) { 893 if (rt) {
900 if (rt->rt6i_flags & RTF_CACHE) 894 if (rt->rt6i_flags & RTF_CACHE) {
901 ip6_del_rt(rt); 895 if (rt6_check_expired(rt)) {
902 else 896 ip6_del_rt(rt);
897 dst = NULL;
898 }
899 } else {
903 dst_release(dst); 900 dst_release(dst);
901 dst = NULL;
902 }
904 } 903 }
905 return NULL; 904 return dst;
906} 905}
907 906
908static void ip6_link_failure(struct sk_buff *skb) 907static void ip6_link_failure(struct sk_buff *skb)
909{ 908{
910 struct rt6_info *rt; 909 struct rt6_info *rt;
911 910
912 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, skb->dev); 911 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
913 912
914 rt = (struct rt6_info *) skb_dst(skb); 913 rt = (struct rt6_info *) skb_dst(skb);
915 if (rt) { 914 if (rt) {
@@ -1471,9 +1470,10 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1471 }, 1470 },
1472 }, 1471 },
1473 }, 1472 },
1474 .gateway = *gateway,
1475 }; 1473 };
1476 1474
1475 ipv6_addr_copy(&rdfl.gateway, gateway);
1476
1477 if (rt6_need_strict(dest)) 1477 if (rt6_need_strict(dest))
1478 flags |= RT6_LOOKUP_F_IFACE; 1478 flags |= RT6_LOOKUP_F_IFACE;
1479 1479
@@ -1872,7 +1872,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes)
1872 switch (ipstats_mib_noroutes) { 1872 switch (ipstats_mib_noroutes) {
1873 case IPSTATS_MIB_INNOROUTES: 1873 case IPSTATS_MIB_INNOROUTES:
1874 type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); 1874 type = ipv6_addr_type(&ipv6_hdr(skb)->daddr);
1875 if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) { 1875 if (type == IPV6_ADDR_ANY) {
1876 IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), 1876 IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst),
1877 IPSTATS_MIB_INADDRERRORS); 1877 IPSTATS_MIB_INADDRERRORS);
1878 break; 1878 break;
@@ -1883,7 +1883,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes)
1883 ipstats_mib_noroutes); 1883 ipstats_mib_noroutes);
1884 break; 1884 break;
1885 } 1885 }
1886 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); 1886 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0);
1887 kfree_skb(skb); 1887 kfree_skb(skb);
1888 return 0; 1888 return 0;
1889} 1889}
@@ -2546,7 +2546,6 @@ ctl_table ipv6_route_table_template[] = {
2546 .proc_handler = ipv6_sysctl_rtcache_flush 2546 .proc_handler = ipv6_sysctl_rtcache_flush
2547 }, 2547 },
2548 { 2548 {
2549 .ctl_name = NET_IPV6_ROUTE_GC_THRESH,
2550 .procname = "gc_thresh", 2549 .procname = "gc_thresh",
2551 .data = &ip6_dst_ops_template.gc_thresh, 2550 .data = &ip6_dst_ops_template.gc_thresh,
2552 .maxlen = sizeof(int), 2551 .maxlen = sizeof(int),
@@ -2554,7 +2553,6 @@ ctl_table ipv6_route_table_template[] = {
2554 .proc_handler = proc_dointvec, 2553 .proc_handler = proc_dointvec,
2555 }, 2554 },
2556 { 2555 {
2557 .ctl_name = NET_IPV6_ROUTE_MAX_SIZE,
2558 .procname = "max_size", 2556 .procname = "max_size",
2559 .data = &init_net.ipv6.sysctl.ip6_rt_max_size, 2557 .data = &init_net.ipv6.sysctl.ip6_rt_max_size,
2560 .maxlen = sizeof(int), 2558 .maxlen = sizeof(int),
@@ -2562,72 +2560,58 @@ ctl_table ipv6_route_table_template[] = {
2562 .proc_handler = proc_dointvec, 2560 .proc_handler = proc_dointvec,
2563 }, 2561 },
2564 { 2562 {
2565 .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL,
2566 .procname = "gc_min_interval", 2563 .procname = "gc_min_interval",
2567 .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, 2564 .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
2568 .maxlen = sizeof(int), 2565 .maxlen = sizeof(int),
2569 .mode = 0644, 2566 .mode = 0644,
2570 .proc_handler = proc_dointvec_jiffies, 2567 .proc_handler = proc_dointvec_jiffies,
2571 .strategy = sysctl_jiffies,
2572 }, 2568 },
2573 { 2569 {
2574 .ctl_name = NET_IPV6_ROUTE_GC_TIMEOUT,
2575 .procname = "gc_timeout", 2570 .procname = "gc_timeout",
2576 .data = &init_net.ipv6.sysctl.ip6_rt_gc_timeout, 2571 .data = &init_net.ipv6.sysctl.ip6_rt_gc_timeout,
2577 .maxlen = sizeof(int), 2572 .maxlen = sizeof(int),
2578 .mode = 0644, 2573 .mode = 0644,
2579 .proc_handler = proc_dointvec_jiffies, 2574 .proc_handler = proc_dointvec_jiffies,
2580 .strategy = sysctl_jiffies,
2581 }, 2575 },
2582 { 2576 {
2583 .ctl_name = NET_IPV6_ROUTE_GC_INTERVAL,
2584 .procname = "gc_interval", 2577 .procname = "gc_interval",
2585 .data = &init_net.ipv6.sysctl.ip6_rt_gc_interval, 2578 .data = &init_net.ipv6.sysctl.ip6_rt_gc_interval,
2586 .maxlen = sizeof(int), 2579 .maxlen = sizeof(int),
2587 .mode = 0644, 2580 .mode = 0644,
2588 .proc_handler = proc_dointvec_jiffies, 2581 .proc_handler = proc_dointvec_jiffies,
2589 .strategy = sysctl_jiffies,
2590 }, 2582 },
2591 { 2583 {
2592 .ctl_name = NET_IPV6_ROUTE_GC_ELASTICITY,
2593 .procname = "gc_elasticity", 2584 .procname = "gc_elasticity",
2594 .data = &init_net.ipv6.sysctl.ip6_rt_gc_elasticity, 2585 .data = &init_net.ipv6.sysctl.ip6_rt_gc_elasticity,
2595 .maxlen = sizeof(int), 2586 .maxlen = sizeof(int),
2596 .mode = 0644, 2587 .mode = 0644,
2597 .proc_handler = proc_dointvec_jiffies, 2588 .proc_handler = proc_dointvec_jiffies,
2598 .strategy = sysctl_jiffies,
2599 }, 2589 },
2600 { 2590 {
2601 .ctl_name = NET_IPV6_ROUTE_MTU_EXPIRES,
2602 .procname = "mtu_expires", 2591 .procname = "mtu_expires",
2603 .data = &init_net.ipv6.sysctl.ip6_rt_mtu_expires, 2592 .data = &init_net.ipv6.sysctl.ip6_rt_mtu_expires,
2604 .maxlen = sizeof(int), 2593 .maxlen = sizeof(int),
2605 .mode = 0644, 2594 .mode = 0644,
2606 .proc_handler = proc_dointvec_jiffies, 2595 .proc_handler = proc_dointvec_jiffies,
2607 .strategy = sysctl_jiffies,
2608 }, 2596 },
2609 { 2597 {
2610 .ctl_name = NET_IPV6_ROUTE_MIN_ADVMSS,
2611 .procname = "min_adv_mss", 2598 .procname = "min_adv_mss",
2612 .data = &init_net.ipv6.sysctl.ip6_rt_min_advmss, 2599 .data = &init_net.ipv6.sysctl.ip6_rt_min_advmss,
2613 .maxlen = sizeof(int), 2600 .maxlen = sizeof(int),
2614 .mode = 0644, 2601 .mode = 0644,
2615 .proc_handler = proc_dointvec_jiffies, 2602 .proc_handler = proc_dointvec_jiffies,
2616 .strategy = sysctl_jiffies,
2617 }, 2603 },
2618 { 2604 {
2619 .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS,
2620 .procname = "gc_min_interval_ms", 2605 .procname = "gc_min_interval_ms",
2621 .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, 2606 .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
2622 .maxlen = sizeof(int), 2607 .maxlen = sizeof(int),
2623 .mode = 0644, 2608 .mode = 0644,
2624 .proc_handler = proc_dointvec_ms_jiffies, 2609 .proc_handler = proc_dointvec_ms_jiffies,
2625 .strategy = sysctl_ms_jiffies,
2626 }, 2610 },
2627 { .ctl_name = 0 } 2611 { }
2628}; 2612};
2629 2613
2630struct ctl_table *ipv6_route_sysctl_init(struct net *net) 2614struct ctl_table * __net_init ipv6_route_sysctl_init(struct net *net)
2631{ 2615{
2632 struct ctl_table *table; 2616 struct ctl_table *table;
2633 2617
@@ -2645,13 +2629,14 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net)
2645 table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity; 2629 table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity;
2646 table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires; 2630 table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires;
2647 table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss; 2631 table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss;
2632 table[9].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
2648 } 2633 }
2649 2634
2650 return table; 2635 return table;
2651} 2636}
2652#endif 2637#endif
2653 2638
2654static int ip6_route_net_init(struct net *net) 2639static int __net_init ip6_route_net_init(struct net *net)
2655{ 2640{
2656 int ret = -ENOMEM; 2641 int ret = -ENOMEM;
2657 2642
@@ -2716,7 +2701,7 @@ out_ip6_dst_ops:
2716 goto out; 2701 goto out;
2717} 2702}
2718 2703
2719static void ip6_route_net_exit(struct net *net) 2704static void __net_exit ip6_route_net_exit(struct net *net)
2720{ 2705{
2721#ifdef CONFIG_PROC_FS 2706#ifdef CONFIG_PROC_FS
2722 proc_net_remove(net, "ipv6_route"); 2707 proc_net_remove(net, "ipv6_route");
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index dbd19a78ca73..5abae10cd884 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -28,6 +28,7 @@
28#include <linux/netdevice.h> 28#include <linux/netdevice.h>
29#include <linux/if_arp.h> 29#include <linux/if_arp.h>
30#include <linux/icmp.h> 30#include <linux/icmp.h>
31#include <linux/slab.h>
31#include <asm/uaccess.h> 32#include <asm/uaccess.h>
32#include <linux/init.h> 33#include <linux/init.h>
33#include <linux/netfilter_ipv4.h> 34#include <linux/netfilter_ipv4.h>
@@ -62,11 +63,10 @@
62#define HASH_SIZE 16 63#define HASH_SIZE 16
63#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) 64#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
64 65
65static void ipip6_fb_tunnel_init(struct net_device *dev);
66static void ipip6_tunnel_init(struct net_device *dev); 66static void ipip6_tunnel_init(struct net_device *dev);
67static void ipip6_tunnel_setup(struct net_device *dev); 67static void ipip6_tunnel_setup(struct net_device *dev);
68 68
69static int sit_net_id; 69static int sit_net_id __read_mostly;
70struct sit_net { 70struct sit_net {
71 struct ip_tunnel *tunnels_r_l[HASH_SIZE]; 71 struct ip_tunnel *tunnels_r_l[HASH_SIZE];
72 struct ip_tunnel *tunnels_r[HASH_SIZE]; 72 struct ip_tunnel *tunnels_r[HASH_SIZE];
@@ -77,8 +77,17 @@ struct sit_net {
77 struct net_device *fb_tunnel_dev; 77 struct net_device *fb_tunnel_dev;
78}; 78};
79 79
80static DEFINE_RWLOCK(ipip6_lock); 80/*
81 * Locking : hash tables are protected by RCU and a spinlock
82 */
83static DEFINE_SPINLOCK(ipip6_lock);
84
85#define for_each_ip_tunnel_rcu(start) \
86 for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
81 87
88/*
89 * Must be invoked with rcu_read_lock
90 */
82static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net, 91static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
83 struct net_device *dev, __be32 remote, __be32 local) 92 struct net_device *dev, __be32 remote, __be32 local)
84{ 93{
@@ -87,26 +96,26 @@ static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
87 struct ip_tunnel *t; 96 struct ip_tunnel *t;
88 struct sit_net *sitn = net_generic(net, sit_net_id); 97 struct sit_net *sitn = net_generic(net, sit_net_id);
89 98
90 for (t = sitn->tunnels_r_l[h0^h1]; t; t = t->next) { 99 for_each_ip_tunnel_rcu(sitn->tunnels_r_l[h0 ^ h1]) {
91 if (local == t->parms.iph.saddr && 100 if (local == t->parms.iph.saddr &&
92 remote == t->parms.iph.daddr && 101 remote == t->parms.iph.daddr &&
93 (!dev || !t->parms.link || dev->iflink == t->parms.link) && 102 (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
94 (t->dev->flags & IFF_UP)) 103 (t->dev->flags & IFF_UP))
95 return t; 104 return t;
96 } 105 }
97 for (t = sitn->tunnels_r[h0]; t; t = t->next) { 106 for_each_ip_tunnel_rcu(sitn->tunnels_r[h0]) {
98 if (remote == t->parms.iph.daddr && 107 if (remote == t->parms.iph.daddr &&
99 (!dev || !t->parms.link || dev->iflink == t->parms.link) && 108 (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
100 (t->dev->flags & IFF_UP)) 109 (t->dev->flags & IFF_UP))
101 return t; 110 return t;
102 } 111 }
103 for (t = sitn->tunnels_l[h1]; t; t = t->next) { 112 for_each_ip_tunnel_rcu(sitn->tunnels_l[h1]) {
104 if (local == t->parms.iph.saddr && 113 if (local == t->parms.iph.saddr &&
105 (!dev || !t->parms.link || dev->iflink == t->parms.link) && 114 (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
106 (t->dev->flags & IFF_UP)) 115 (t->dev->flags & IFF_UP))
107 return t; 116 return t;
108 } 117 }
109 t = sitn->tunnels_wc[0]; 118 t = rcu_dereference(sitn->tunnels_wc[0]);
110 if ((t != NULL) && (t->dev->flags & IFF_UP)) 119 if ((t != NULL) && (t->dev->flags & IFF_UP))
111 return t; 120 return t;
112 return NULL; 121 return NULL;
@@ -143,9 +152,9 @@ static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t)
143 152
144 for (tp = ipip6_bucket(sitn, t); *tp; tp = &(*tp)->next) { 153 for (tp = ipip6_bucket(sitn, t); *tp; tp = &(*tp)->next) {
145 if (t == *tp) { 154 if (t == *tp) {
146 write_lock_bh(&ipip6_lock); 155 spin_lock_bh(&ipip6_lock);
147 *tp = t->next; 156 *tp = t->next;
148 write_unlock_bh(&ipip6_lock); 157 spin_unlock_bh(&ipip6_lock);
149 break; 158 break;
150 } 159 }
151 } 160 }
@@ -155,10 +164,27 @@ static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t)
155{ 164{
156 struct ip_tunnel **tp = ipip6_bucket(sitn, t); 165 struct ip_tunnel **tp = ipip6_bucket(sitn, t);
157 166
167 spin_lock_bh(&ipip6_lock);
158 t->next = *tp; 168 t->next = *tp;
159 write_lock_bh(&ipip6_lock); 169 rcu_assign_pointer(*tp, t);
160 *tp = t; 170 spin_unlock_bh(&ipip6_lock);
161 write_unlock_bh(&ipip6_lock); 171}
172
173static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
174{
175#ifdef CONFIG_IPV6_SIT_6RD
176 struct ip_tunnel *t = netdev_priv(dev);
177
178 if (t->dev == sitn->fb_tunnel_dev) {
179 ipv6_addr_set(&t->ip6rd.prefix, htonl(0x20020000), 0, 0, 0);
180 t->ip6rd.relay_prefix = 0;
181 t->ip6rd.prefixlen = 16;
182 t->ip6rd.relay_prefixlen = 0;
183 } else {
184 struct ip_tunnel *t0 = netdev_priv(sitn->fb_tunnel_dev);
185 memcpy(&t->ip6rd, &t0->ip6rd, sizeof(t->ip6rd));
186 }
187#endif
162} 188}
163 189
164static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, 190static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
@@ -204,6 +230,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
204 230
205 nt->parms = *parms; 231 nt->parms = *parms;
206 ipip6_tunnel_init(dev); 232 ipip6_tunnel_init(dev);
233 ipip6_tunnel_clone_6rd(dev, sitn);
207 234
208 if (parms->i_flags & SIT_ISATAP) 235 if (parms->i_flags & SIT_ISATAP)
209 dev->priv_flags |= IFF_ISATAP; 236 dev->priv_flags |= IFF_ISATAP;
@@ -222,15 +249,22 @@ failed:
222 return NULL; 249 return NULL;
223} 250}
224 251
252static DEFINE_SPINLOCK(ipip6_prl_lock);
253
254#define for_each_prl_rcu(start) \
255 for (prl = rcu_dereference(start); \
256 prl; \
257 prl = rcu_dereference(prl->next))
258
225static struct ip_tunnel_prl_entry * 259static struct ip_tunnel_prl_entry *
226__ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr) 260__ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr)
227{ 261{
228 struct ip_tunnel_prl_entry *p = (struct ip_tunnel_prl_entry *)NULL; 262 struct ip_tunnel_prl_entry *prl;
229 263
230 for (p = t->prl; p; p = p->next) 264 for_each_prl_rcu(t->prl)
231 if (p->addr == addr) 265 if (prl->addr == addr)
232 break; 266 break;
233 return p; 267 return prl;
234 268
235} 269}
236 270
@@ -255,7 +289,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
255 kcalloc(cmax, sizeof(*kp), GFP_KERNEL) : 289 kcalloc(cmax, sizeof(*kp), GFP_KERNEL) :
256 NULL; 290 NULL;
257 291
258 read_lock(&ipip6_lock); 292 rcu_read_lock();
259 293
260 ca = t->prl_count < cmax ? t->prl_count : cmax; 294 ca = t->prl_count < cmax ? t->prl_count : cmax;
261 295
@@ -273,7 +307,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
273 } 307 }
274 308
275 c = 0; 309 c = 0;
276 for (prl = t->prl; prl; prl = prl->next) { 310 for_each_prl_rcu(t->prl) {
277 if (c >= cmax) 311 if (c >= cmax)
278 break; 312 break;
279 if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr) 313 if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr)
@@ -285,7 +319,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
285 break; 319 break;
286 } 320 }
287out: 321out:
288 read_unlock(&ipip6_lock); 322 rcu_read_unlock();
289 323
290 len = sizeof(*kp) * c; 324 len = sizeof(*kp) * c;
291 ret = 0; 325 ret = 0;
@@ -306,12 +340,14 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
306 if (a->addr == htonl(INADDR_ANY)) 340 if (a->addr == htonl(INADDR_ANY))
307 return -EINVAL; 341 return -EINVAL;
308 342
309 write_lock(&ipip6_lock); 343 spin_lock(&ipip6_prl_lock);
310 344
311 for (p = t->prl; p; p = p->next) { 345 for (p = t->prl; p; p = p->next) {
312 if (p->addr == a->addr) { 346 if (p->addr == a->addr) {
313 if (chg) 347 if (chg) {
314 goto update; 348 p->flags = a->flags;
349 goto out;
350 }
315 err = -EEXIST; 351 err = -EEXIST;
316 goto out; 352 goto out;
317 } 353 }
@@ -329,45 +365,61 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
329 } 365 }
330 366
331 p->next = t->prl; 367 p->next = t->prl;
332 t->prl = p;
333 t->prl_count++;
334update:
335 p->addr = a->addr; 368 p->addr = a->addr;
336 p->flags = a->flags; 369 p->flags = a->flags;
370 t->prl_count++;
371 rcu_assign_pointer(t->prl, p);
337out: 372out:
338 write_unlock(&ipip6_lock); 373 spin_unlock(&ipip6_prl_lock);
339 return err; 374 return err;
340} 375}
341 376
377static void prl_entry_destroy_rcu(struct rcu_head *head)
378{
379 kfree(container_of(head, struct ip_tunnel_prl_entry, rcu_head));
380}
381
382static void prl_list_destroy_rcu(struct rcu_head *head)
383{
384 struct ip_tunnel_prl_entry *p, *n;
385
386 p = container_of(head, struct ip_tunnel_prl_entry, rcu_head);
387 do {
388 n = p->next;
389 kfree(p);
390 p = n;
391 } while (p);
392}
393
342static int 394static int
343ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) 395ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
344{ 396{
345 struct ip_tunnel_prl_entry *x, **p; 397 struct ip_tunnel_prl_entry *x, **p;
346 int err = 0; 398 int err = 0;
347 399
348 write_lock(&ipip6_lock); 400 spin_lock(&ipip6_prl_lock);
349 401
350 if (a && a->addr != htonl(INADDR_ANY)) { 402 if (a && a->addr != htonl(INADDR_ANY)) {
351 for (p = &t->prl; *p; p = &(*p)->next) { 403 for (p = &t->prl; *p; p = &(*p)->next) {
352 if ((*p)->addr == a->addr) { 404 if ((*p)->addr == a->addr) {
353 x = *p; 405 x = *p;
354 *p = x->next; 406 *p = x->next;
355 kfree(x); 407 call_rcu(&x->rcu_head, prl_entry_destroy_rcu);
356 t->prl_count--; 408 t->prl_count--;
357 goto out; 409 goto out;
358 } 410 }
359 } 411 }
360 err = -ENXIO; 412 err = -ENXIO;
361 } else { 413 } else {
362 while (t->prl) { 414 if (t->prl) {
415 t->prl_count = 0;
363 x = t->prl; 416 x = t->prl;
364 t->prl = t->prl->next; 417 call_rcu(&x->rcu_head, prl_list_destroy_rcu);
365 kfree(x); 418 t->prl = NULL;
366 t->prl_count--;
367 } 419 }
368 } 420 }
369out: 421out:
370 write_unlock(&ipip6_lock); 422 spin_unlock(&ipip6_prl_lock);
371 return err; 423 return err;
372} 424}
373 425
@@ -377,7 +429,7 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
377 struct ip_tunnel_prl_entry *p; 429 struct ip_tunnel_prl_entry *p;
378 int ok = 1; 430 int ok = 1;
379 431
380 read_lock(&ipip6_lock); 432 rcu_read_lock();
381 p = __ipip6_tunnel_locate_prl(t, iph->saddr); 433 p = __ipip6_tunnel_locate_prl(t, iph->saddr);
382 if (p) { 434 if (p) {
383 if (p->flags & PRL_DEFAULT) 435 if (p->flags & PRL_DEFAULT)
@@ -393,7 +445,7 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
393 else 445 else
394 ok = 0; 446 ok = 0;
395 } 447 }
396 read_unlock(&ipip6_lock); 448 rcu_read_unlock();
397 return ok; 449 return ok;
398} 450}
399 451
@@ -403,9 +455,9 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
403 struct sit_net *sitn = net_generic(net, sit_net_id); 455 struct sit_net *sitn = net_generic(net, sit_net_id);
404 456
405 if (dev == sitn->fb_tunnel_dev) { 457 if (dev == sitn->fb_tunnel_dev) {
406 write_lock_bh(&ipip6_lock); 458 spin_lock_bh(&ipip6_lock);
407 sitn->tunnels_wc[0] = NULL; 459 sitn->tunnels_wc[0] = NULL;
408 write_unlock_bh(&ipip6_lock); 460 spin_unlock_bh(&ipip6_lock);
409 dev_put(dev); 461 dev_put(dev);
410 } else { 462 } else {
411 ipip6_tunnel_unlink(sitn, netdev_priv(dev)); 463 ipip6_tunnel_unlink(sitn, netdev_priv(dev));
@@ -458,7 +510,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
458 510
459 err = -ENOENT; 511 err = -ENOENT;
460 512
461 read_lock(&ipip6_lock); 513 rcu_read_lock();
462 t = ipip6_tunnel_lookup(dev_net(skb->dev), 514 t = ipip6_tunnel_lookup(dev_net(skb->dev),
463 skb->dev, 515 skb->dev,
464 iph->daddr, 516 iph->daddr,
@@ -476,7 +528,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
476 t->err_count = 1; 528 t->err_count = 1;
477 t->err_time = jiffies; 529 t->err_time = jiffies;
478out: 530out:
479 read_unlock(&ipip6_lock); 531 rcu_read_unlock();
480 return err; 532 return err;
481} 533}
482 534
@@ -496,7 +548,7 @@ static int ipip6_rcv(struct sk_buff *skb)
496 548
497 iph = ip_hdr(skb); 549 iph = ip_hdr(skb);
498 550
499 read_lock(&ipip6_lock); 551 rcu_read_lock();
500 tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, 552 tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
501 iph->saddr, iph->daddr); 553 iph->saddr, iph->daddr);
502 if (tunnel != NULL) { 554 if (tunnel != NULL) {
@@ -510,7 +562,7 @@ static int ipip6_rcv(struct sk_buff *skb)
510 if ((tunnel->dev->priv_flags & IFF_ISATAP) && 562 if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
511 !isatap_chksrc(skb, iph, tunnel)) { 563 !isatap_chksrc(skb, iph, tunnel)) {
512 tunnel->dev->stats.rx_errors++; 564 tunnel->dev->stats.rx_errors++;
513 read_unlock(&ipip6_lock); 565 rcu_read_unlock();
514 kfree_skb(skb); 566 kfree_skb(skb);
515 return 0; 567 return 0;
516 } 568 }
@@ -521,28 +573,52 @@ static int ipip6_rcv(struct sk_buff *skb)
521 nf_reset(skb); 573 nf_reset(skb);
522 ipip6_ecn_decapsulate(iph, skb); 574 ipip6_ecn_decapsulate(iph, skb);
523 netif_rx(skb); 575 netif_rx(skb);
524 read_unlock(&ipip6_lock); 576 rcu_read_unlock();
525 return 0; 577 return 0;
526 } 578 }
527 579
528 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 580 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
529 read_unlock(&ipip6_lock); 581 rcu_read_unlock();
530out: 582out:
531 kfree_skb(skb); 583 kfree_skb(skb);
532 return 0; 584 return 0;
533} 585}
534 586
535/* Returns the embedded IPv4 address if the IPv6 address 587/*
536 comes from 6to4 (RFC 3056) addr space */ 588 * Returns the embedded IPv4 address if the IPv6 address
537 589 * comes from 6rd / 6to4 (RFC 3056) addr space.
538static inline __be32 try_6to4(struct in6_addr *v6dst) 590 */
591static inline
592__be32 try_6rd(struct in6_addr *v6dst, struct ip_tunnel *tunnel)
539{ 593{
540 __be32 dst = 0; 594 __be32 dst = 0;
541 595
596#ifdef CONFIG_IPV6_SIT_6RD
597 if (ipv6_prefix_equal(v6dst, &tunnel->ip6rd.prefix,
598 tunnel->ip6rd.prefixlen)) {
599 unsigned pbw0, pbi0;
600 int pbi1;
601 u32 d;
602
603 pbw0 = tunnel->ip6rd.prefixlen >> 5;
604 pbi0 = tunnel->ip6rd.prefixlen & 0x1f;
605
606 d = (ntohl(v6dst->s6_addr32[pbw0]) << pbi0) >>
607 tunnel->ip6rd.relay_prefixlen;
608
609 pbi1 = pbi0 - tunnel->ip6rd.relay_prefixlen;
610 if (pbi1 > 0)
611 d |= ntohl(v6dst->s6_addr32[pbw0 + 1]) >>
612 (32 - pbi1);
613
614 dst = tunnel->ip6rd.relay_prefix | htonl(d);
615 }
616#else
542 if (v6dst->s6_addr16[0] == htons(0x2002)) { 617 if (v6dst->s6_addr16[0] == htons(0x2002)) {
543 /* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */ 618 /* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */
544 memcpy(&dst, &v6dst->s6_addr16[1], 4); 619 memcpy(&dst, &v6dst->s6_addr16[1], 4);
545 } 620 }
621#endif
546 return dst; 622 return dst;
547} 623}
548 624
@@ -555,10 +631,12 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
555 struct net_device *dev) 631 struct net_device *dev)
556{ 632{
557 struct ip_tunnel *tunnel = netdev_priv(dev); 633 struct ip_tunnel *tunnel = netdev_priv(dev);
558 struct net_device_stats *stats = &tunnel->dev->stats; 634 struct net_device_stats *stats = &dev->stats;
635 struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
559 struct iphdr *tiph = &tunnel->parms.iph; 636 struct iphdr *tiph = &tunnel->parms.iph;
560 struct ipv6hdr *iph6 = ipv6_hdr(skb); 637 struct ipv6hdr *iph6 = ipv6_hdr(skb);
561 u8 tos = tunnel->parms.iph.tos; 638 u8 tos = tunnel->parms.iph.tos;
639 __be16 df = tiph->frag_off;
562 struct rtable *rt; /* Route to the other host */ 640 struct rtable *rt; /* Route to the other host */
563 struct net_device *tdev; /* Device to other host */ 641 struct net_device *tdev; /* Device to other host */
564 struct iphdr *iph; /* Our new IP header */ 642 struct iphdr *iph; /* Our new IP header */
@@ -595,7 +673,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
595 } 673 }
596 674
597 if (!dst) 675 if (!dst)
598 dst = try_6to4(&iph6->daddr); 676 dst = try_6rd(&iph6->daddr, tunnel);
599 677
600 if (!dst) { 678 if (!dst) {
601 struct neighbour *neigh = NULL; 679 struct neighbour *neigh = NULL;
@@ -648,25 +726,28 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
648 goto tx_error; 726 goto tx_error;
649 } 727 }
650 728
651 if (tiph->frag_off) 729 if (df) {
652 mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); 730 mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
653 else
654 mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
655 731
656 if (mtu < 68) { 732 if (mtu < 68) {
657 stats->collisions++; 733 stats->collisions++;
658 ip_rt_put(rt); 734 ip_rt_put(rt);
659 goto tx_error; 735 goto tx_error;
660 } 736 }
661 if (mtu < IPV6_MIN_MTU)
662 mtu = IPV6_MIN_MTU;
663 if (tunnel->parms.iph.daddr && skb_dst(skb))
664 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
665 737
666 if (skb->len > mtu) { 738 if (mtu < IPV6_MIN_MTU) {
667 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); 739 mtu = IPV6_MIN_MTU;
668 ip_rt_put(rt); 740 df = 0;
669 goto tx_error; 741 }
742
743 if (tunnel->parms.iph.daddr && skb_dst(skb))
744 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
745
746 if (skb->len > mtu) {
747 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
748 ip_rt_put(rt);
749 goto tx_error;
750 }
670 } 751 }
671 752
672 if (tunnel->err_count > 0) { 753 if (tunnel->err_count > 0) {
@@ -688,7 +769,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
688 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); 769 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
689 if (!new_skb) { 770 if (!new_skb) {
690 ip_rt_put(rt); 771 ip_rt_put(rt);
691 stats->tx_dropped++; 772 txq->tx_dropped++;
692 dev_kfree_skb(skb); 773 dev_kfree_skb(skb);
693 return NETDEV_TX_OK; 774 return NETDEV_TX_OK;
694 } 775 }
@@ -714,11 +795,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
714 iph = ip_hdr(skb); 795 iph = ip_hdr(skb);
715 iph->version = 4; 796 iph->version = 4;
716 iph->ihl = sizeof(struct iphdr)>>2; 797 iph->ihl = sizeof(struct iphdr)>>2;
717 if (mtu > IPV6_MIN_MTU) 798 iph->frag_off = df;
718 iph->frag_off = tiph->frag_off;
719 else
720 iph->frag_off = 0;
721
722 iph->protocol = IPPROTO_IPV6; 799 iph->protocol = IPPROTO_IPV6;
723 iph->tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); 800 iph->tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
724 iph->daddr = rt->rt_dst; 801 iph->daddr = rt->rt_dst;
@@ -785,9 +862,15 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
785 struct ip_tunnel *t; 862 struct ip_tunnel *t;
786 struct net *net = dev_net(dev); 863 struct net *net = dev_net(dev);
787 struct sit_net *sitn = net_generic(net, sit_net_id); 864 struct sit_net *sitn = net_generic(net, sit_net_id);
865#ifdef CONFIG_IPV6_SIT_6RD
866 struct ip_tunnel_6rd ip6rd;
867#endif
788 868
789 switch (cmd) { 869 switch (cmd) {
790 case SIOCGETTUNNEL: 870 case SIOCGETTUNNEL:
871#ifdef CONFIG_IPV6_SIT_6RD
872 case SIOCGET6RD:
873#endif
791 t = NULL; 874 t = NULL;
792 if (dev == sitn->fb_tunnel_dev) { 875 if (dev == sitn->fb_tunnel_dev) {
793 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { 876 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
@@ -798,9 +881,25 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
798 } 881 }
799 if (t == NULL) 882 if (t == NULL)
800 t = netdev_priv(dev); 883 t = netdev_priv(dev);
801 memcpy(&p, &t->parms, sizeof(p)); 884
802 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 885 err = -EFAULT;
803 err = -EFAULT; 886 if (cmd == SIOCGETTUNNEL) {
887 memcpy(&p, &t->parms, sizeof(p));
888 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p,
889 sizeof(p)))
890 goto done;
891#ifdef CONFIG_IPV6_SIT_6RD
892 } else {
893 ipv6_addr_copy(&ip6rd.prefix, &t->ip6rd.prefix);
894 ip6rd.relay_prefix = t->ip6rd.relay_prefix;
895 ip6rd.prefixlen = t->ip6rd.prefixlen;
896 ip6rd.relay_prefixlen = t->ip6rd.relay_prefixlen;
897 if (copy_to_user(ifr->ifr_ifru.ifru_data, &ip6rd,
898 sizeof(ip6rd)))
899 goto done;
900#endif
901 }
902 err = 0;
804 break; 903 break;
805 904
806 case SIOCADDTUNNEL: 905 case SIOCADDTUNNEL:
@@ -921,6 +1020,54 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
921 netdev_state_change(dev); 1020 netdev_state_change(dev);
922 break; 1021 break;
923 1022
1023#ifdef CONFIG_IPV6_SIT_6RD
1024 case SIOCADD6RD:
1025 case SIOCCHG6RD:
1026 case SIOCDEL6RD:
1027 err = -EPERM;
1028 if (!capable(CAP_NET_ADMIN))
1029 goto done;
1030
1031 err = -EFAULT;
1032 if (copy_from_user(&ip6rd, ifr->ifr_ifru.ifru_data,
1033 sizeof(ip6rd)))
1034 goto done;
1035
1036 t = netdev_priv(dev);
1037
1038 if (cmd != SIOCDEL6RD) {
1039 struct in6_addr prefix;
1040 __be32 relay_prefix;
1041
1042 err = -EINVAL;
1043 if (ip6rd.relay_prefixlen > 32 ||
1044 ip6rd.prefixlen + (32 - ip6rd.relay_prefixlen) > 64)
1045 goto done;
1046
1047 ipv6_addr_prefix(&prefix, &ip6rd.prefix,
1048 ip6rd.prefixlen);
1049 if (!ipv6_addr_equal(&prefix, &ip6rd.prefix))
1050 goto done;
1051 if (ip6rd.relay_prefixlen)
1052 relay_prefix = ip6rd.relay_prefix &
1053 htonl(0xffffffffUL <<
1054 (32 - ip6rd.relay_prefixlen));
1055 else
1056 relay_prefix = 0;
1057 if (relay_prefix != ip6rd.relay_prefix)
1058 goto done;
1059
1060 ipv6_addr_copy(&t->ip6rd.prefix, &prefix);
1061 t->ip6rd.relay_prefix = relay_prefix;
1062 t->ip6rd.prefixlen = ip6rd.prefixlen;
1063 t->ip6rd.relay_prefixlen = ip6rd.relay_prefixlen;
1064 } else
1065 ipip6_tunnel_clone_6rd(dev, sitn);
1066
1067 err = 0;
1068 break;
1069#endif
1070
924 default: 1071 default:
925 err = -EINVAL; 1072 err = -EINVAL;
926 } 1073 }
@@ -972,7 +1119,7 @@ static void ipip6_tunnel_init(struct net_device *dev)
972 ipip6_tunnel_bind_dev(dev); 1119 ipip6_tunnel_bind_dev(dev);
973} 1120}
974 1121
975static void ipip6_fb_tunnel_init(struct net_device *dev) 1122static void __net_init ipip6_fb_tunnel_init(struct net_device *dev)
976{ 1123{
977 struct ip_tunnel *tunnel = netdev_priv(dev); 1124 struct ip_tunnel *tunnel = netdev_priv(dev);
978 struct iphdr *iph = &tunnel->parms.iph; 1125 struct iphdr *iph = &tunnel->parms.iph;
@@ -997,33 +1144,27 @@ static struct xfrm_tunnel sit_handler = {
997 .priority = 1, 1144 .priority = 1,
998}; 1145};
999 1146
1000static void sit_destroy_tunnels(struct sit_net *sitn) 1147static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head)
1001{ 1148{
1002 int prio; 1149 int prio;
1003 1150
1004 for (prio = 1; prio < 4; prio++) { 1151 for (prio = 1; prio < 4; prio++) {
1005 int h; 1152 int h;
1006 for (h = 0; h < HASH_SIZE; h++) { 1153 for (h = 0; h < HASH_SIZE; h++) {
1007 struct ip_tunnel *t; 1154 struct ip_tunnel *t = sitn->tunnels[prio][h];
1008 while ((t = sitn->tunnels[prio][h]) != NULL) 1155
1009 unregister_netdevice(t->dev); 1156 while (t != NULL) {
1157 unregister_netdevice_queue(t->dev, head);
1158 t = t->next;
1159 }
1010 } 1160 }
1011 } 1161 }
1012} 1162}
1013 1163
1014static int sit_init_net(struct net *net) 1164static int __net_init sit_init_net(struct net *net)
1015{ 1165{
1166 struct sit_net *sitn = net_generic(net, sit_net_id);
1016 int err; 1167 int err;
1017 struct sit_net *sitn;
1018
1019 err = -ENOMEM;
1020 sitn = kzalloc(sizeof(struct sit_net), GFP_KERNEL);
1021 if (sitn == NULL)
1022 goto err_alloc;
1023
1024 err = net_assign_generic(net, sit_net_id, sitn);
1025 if (err < 0)
1026 goto err_assign;
1027 1168
1028 sitn->tunnels[0] = sitn->tunnels_wc; 1169 sitn->tunnels[0] = sitn->tunnels_wc;
1029 sitn->tunnels[1] = sitn->tunnels_l; 1170 sitn->tunnels[1] = sitn->tunnels_l;
@@ -1039,6 +1180,7 @@ static int sit_init_net(struct net *net)
1039 dev_net_set(sitn->fb_tunnel_dev, net); 1180 dev_net_set(sitn->fb_tunnel_dev, net);
1040 1181
1041 ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); 1182 ipip6_fb_tunnel_init(sitn->fb_tunnel_dev);
1183 ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn);
1042 1184
1043 if ((err = register_netdev(sitn->fb_tunnel_dev))) 1185 if ((err = register_netdev(sitn->fb_tunnel_dev)))
1044 goto err_reg_dev; 1186 goto err_reg_dev;
@@ -1049,35 +1191,34 @@ err_reg_dev:
1049 dev_put(sitn->fb_tunnel_dev); 1191 dev_put(sitn->fb_tunnel_dev);
1050 free_netdev(sitn->fb_tunnel_dev); 1192 free_netdev(sitn->fb_tunnel_dev);
1051err_alloc_dev: 1193err_alloc_dev:
1052 /* nothing */
1053err_assign:
1054 kfree(sitn);
1055err_alloc:
1056 return err; 1194 return err;
1057} 1195}
1058 1196
1059static void sit_exit_net(struct net *net) 1197static void __net_exit sit_exit_net(struct net *net)
1060{ 1198{
1061 struct sit_net *sitn; 1199 struct sit_net *sitn = net_generic(net, sit_net_id);
1200 LIST_HEAD(list);
1062 1201
1063 sitn = net_generic(net, sit_net_id);
1064 rtnl_lock(); 1202 rtnl_lock();
1065 sit_destroy_tunnels(sitn); 1203 sit_destroy_tunnels(sitn, &list);
1066 unregister_netdevice(sitn->fb_tunnel_dev); 1204 unregister_netdevice_queue(sitn->fb_tunnel_dev, &list);
1205 unregister_netdevice_many(&list);
1067 rtnl_unlock(); 1206 rtnl_unlock();
1068 kfree(sitn);
1069} 1207}
1070 1208
1071static struct pernet_operations sit_net_ops = { 1209static struct pernet_operations sit_net_ops = {
1072 .init = sit_init_net, 1210 .init = sit_init_net,
1073 .exit = sit_exit_net, 1211 .exit = sit_exit_net,
1212 .id = &sit_net_id,
1213 .size = sizeof(struct sit_net),
1074}; 1214};
1075 1215
1076static void __exit sit_cleanup(void) 1216static void __exit sit_cleanup(void)
1077{ 1217{
1078 xfrm4_tunnel_deregister(&sit_handler, AF_INET6); 1218 xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
1079 1219
1080 unregister_pernet_gen_device(sit_net_id, &sit_net_ops); 1220 unregister_pernet_device(&sit_net_ops);
1221 rcu_barrier(); /* Wait for completion of call_rcu()'s */
1081} 1222}
1082 1223
1083static int __init sit_init(void) 1224static int __init sit_init(void)
@@ -1086,15 +1227,14 @@ static int __init sit_init(void)
1086 1227
1087 printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); 1228 printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n");
1088 1229
1089 if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) { 1230 err = register_pernet_device(&sit_net_ops);
1231 if (err < 0)
1232 return err;
1233 err = xfrm4_tunnel_register(&sit_handler, AF_INET6);
1234 if (err < 0) {
1235 unregister_pernet_device(&sit_net_ops);
1090 printk(KERN_INFO "sit init: Can't add protocol\n"); 1236 printk(KERN_INFO "sit init: Can't add protocol\n");
1091 return -EAGAIN;
1092 } 1237 }
1093
1094 err = register_pernet_gen_device(&sit_net_id, &sit_net_ops);
1095 if (err < 0)
1096 xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
1097
1098 return err; 1238 return err;
1099} 1239}
1100 1240
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 6b6ae913b5d4..34d1f0690d7e 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -159,6 +159,8 @@ static inline int cookie_check(struct sk_buff *skb, __u32 cookie)
159 159
160struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) 160struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
161{ 161{
162 struct tcp_options_received tcp_opt;
163 u8 *hash_location;
162 struct inet_request_sock *ireq; 164 struct inet_request_sock *ireq;
163 struct inet6_request_sock *ireq6; 165 struct inet6_request_sock *ireq6;
164 struct tcp_request_sock *treq; 166 struct tcp_request_sock *treq;
@@ -171,7 +173,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
171 int mss; 173 int mss;
172 struct dst_entry *dst; 174 struct dst_entry *dst;
173 __u8 rcv_wscale; 175 __u8 rcv_wscale;
174 struct tcp_options_received tcp_opt;
175 176
176 if (!sysctl_tcp_syncookies || !th->ack) 177 if (!sysctl_tcp_syncookies || !th->ack)
177 goto out; 178 goto out;
@@ -186,7 +187,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
186 187
187 /* check for timestamp cookie support */ 188 /* check for timestamp cookie support */
188 memset(&tcp_opt, 0, sizeof(tcp_opt)); 189 memset(&tcp_opt, 0, sizeof(tcp_opt));
189 tcp_parse_options(skb, &tcp_opt, 0); 190 tcp_parse_options(skb, &tcp_opt, &hash_location, 0);
190 191
191 if (tcp_opt.saw_tstamp) 192 if (tcp_opt.saw_tstamp)
192 cookie_check_timestamp(&tcp_opt); 193 cookie_check_timestamp(&tcp_opt);
@@ -252,8 +253,9 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
252 } 253 }
253 ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); 254 ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
254 fl.oif = sk->sk_bound_dev_if; 255 fl.oif = sk->sk_bound_dev_if;
256 fl.mark = sk->sk_mark;
255 fl.fl_ip_dport = inet_rsk(req)->rmt_port; 257 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
256 fl.fl_ip_sport = inet_sk(sk)->sport; 258 fl.fl_ip_sport = inet_sk(sk)->inet_sport;
257 security_req_classify_flow(req, &fl); 259 security_req_classify_flow(req, &fl);
258 if (ip6_dst_lookup(sk, &dst, &fl)) 260 if (ip6_dst_lookup(sk, &dst, &fl))
259 goto out_free; 261 goto out_free;
@@ -267,7 +269,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
267 req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); 269 req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
268 tcp_select_initial_window(tcp_full_space(sk), req->mss, 270 tcp_select_initial_window(tcp_full_space(sk), req->mss,
269 &req->rcv_wnd, &req->window_clamp, 271 &req->rcv_wnd, &req->window_clamp,
270 ireq->wscale_ok, &rcv_wscale); 272 ireq->wscale_ok, &rcv_wscale,
273 dst_metric(dst, RTAX_INITRWND));
271 274
272 ireq->rcv_wscale = rcv_wscale; 275 ireq->rcv_wscale = rcv_wscale;
273 276
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 0dc6a4e5ed4a..fa1d8f4e0051 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -9,6 +9,7 @@
9#include <linux/sysctl.h> 9#include <linux/sysctl.h>
10#include <linux/in6.h> 10#include <linux/in6.h>
11#include <linux/ipv6.h> 11#include <linux/ipv6.h>
12#include <linux/slab.h>
12#include <net/ndisc.h> 13#include <net/ndisc.h>
13#include <net/ipv6.h> 14#include <net/ipv6.h>
14#include <net/addrconf.h> 15#include <net/addrconf.h>
@@ -16,50 +17,46 @@
16 17
17static ctl_table ipv6_table_template[] = { 18static ctl_table ipv6_table_template[] = {
18 { 19 {
19 .ctl_name = NET_IPV6_ROUTE,
20 .procname = "route", 20 .procname = "route",
21 .maxlen = 0, 21 .maxlen = 0,
22 .mode = 0555, 22 .mode = 0555,
23 .child = ipv6_route_table_template 23 .child = ipv6_route_table_template
24 }, 24 },
25 { 25 {
26 .ctl_name = NET_IPV6_ICMP,
27 .procname = "icmp", 26 .procname = "icmp",
28 .maxlen = 0, 27 .maxlen = 0,
29 .mode = 0555, 28 .mode = 0555,
30 .child = ipv6_icmp_table_template 29 .child = ipv6_icmp_table_template
31 }, 30 },
32 { 31 {
33 .ctl_name = NET_IPV6_BINDV6ONLY,
34 .procname = "bindv6only", 32 .procname = "bindv6only",
35 .data = &init_net.ipv6.sysctl.bindv6only, 33 .data = &init_net.ipv6.sysctl.bindv6only,
36 .maxlen = sizeof(int), 34 .maxlen = sizeof(int),
37 .mode = 0644, 35 .mode = 0644,
38 .proc_handler = proc_dointvec 36 .proc_handler = proc_dointvec
39 }, 37 },
40 { .ctl_name = 0 } 38 { }
41}; 39};
42 40
43static ctl_table ipv6_rotable[] = { 41static ctl_table ipv6_rotable[] = {
44 { 42 {
45 .ctl_name = NET_IPV6_MLD_MAX_MSF,
46 .procname = "mld_max_msf", 43 .procname = "mld_max_msf",
47 .data = &sysctl_mld_max_msf, 44 .data = &sysctl_mld_max_msf,
48 .maxlen = sizeof(int), 45 .maxlen = sizeof(int),
49 .mode = 0644, 46 .mode = 0644,
50 .proc_handler = proc_dointvec 47 .proc_handler = proc_dointvec
51 }, 48 },
52 { .ctl_name = 0 } 49 { }
53}; 50};
54 51
55struct ctl_path net_ipv6_ctl_path[] = { 52struct ctl_path net_ipv6_ctl_path[] = {
56 { .procname = "net", .ctl_name = CTL_NET, }, 53 { .procname = "net", },
57 { .procname = "ipv6", .ctl_name = NET_IPV6, }, 54 { .procname = "ipv6", },
58 { }, 55 { },
59}; 56};
60EXPORT_SYMBOL_GPL(net_ipv6_ctl_path); 57EXPORT_SYMBOL_GPL(net_ipv6_ctl_path);
61 58
62static int ipv6_sysctl_net_init(struct net *net) 59static int __net_init ipv6_sysctl_net_init(struct net *net)
63{ 60{
64 struct ctl_table *ipv6_table; 61 struct ctl_table *ipv6_table;
65 struct ctl_table *ipv6_route_table; 62 struct ctl_table *ipv6_route_table;
@@ -102,7 +99,7 @@ out_ipv6_table:
102 goto out; 99 goto out;
103} 100}
104 101
105static void ipv6_sysctl_net_exit(struct net *net) 102static void __net_exit ipv6_sysctl_net_exit(struct net *net)
106{ 103{
107 struct ctl_table *ipv6_table; 104 struct ctl_table *ipv6_table;
108 struct ctl_table *ipv6_route_table; 105 struct ctl_table *ipv6_route_table;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 21d100b68b19..075f540ec197 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -38,6 +38,7 @@
38#include <linux/jhash.h> 38#include <linux/jhash.h>
39#include <linux/ipsec.h> 39#include <linux/ipsec.h>
40#include <linux/times.h> 40#include <linux/times.h>
41#include <linux/slab.h>
41 42
42#include <linux/ipv6.h> 43#include <linux/ipv6.h>
43#include <linux/icmpv6.h> 44#include <linux/icmpv6.h>
@@ -96,7 +97,7 @@ static void tcp_v6_hash(struct sock *sk)
96 return; 97 return;
97 } 98 }
98 local_bh_disable(); 99 local_bh_disable();
99 __inet6_hash(sk); 100 __inet6_hash(sk, NULL);
100 local_bh_enable(); 101 local_bh_enable();
101 } 102 }
102} 103}
@@ -226,10 +227,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
226#endif 227#endif
227 goto failure; 228 goto failure;
228 } else { 229 } else {
229 ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF), 230 ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);
230 inet->saddr); 231 ipv6_addr_set_v4mapped(inet->inet_rcv_saddr,
231 ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF), 232 &np->rcv_saddr);
232 inet->rcv_saddr);
233 } 233 }
234 234
235 return err; 235 return err;
@@ -243,8 +243,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
243 ipv6_addr_copy(&fl.fl6_src, 243 ipv6_addr_copy(&fl.fl6_src,
244 (saddr ? saddr : &np->saddr)); 244 (saddr ? saddr : &np->saddr));
245 fl.oif = sk->sk_bound_dev_if; 245 fl.oif = sk->sk_bound_dev_if;
246 fl.mark = sk->sk_mark;
246 fl.fl_ip_dport = usin->sin6_port; 247 fl.fl_ip_dport = usin->sin6_port;
247 fl.fl_ip_sport = inet->sport; 248 fl.fl_ip_sport = inet->inet_sport;
248 249
249 if (np->opt && np->opt->srcrt) { 250 if (np->opt && np->opt->srcrt) {
250 struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; 251 struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
@@ -276,7 +277,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
276 277
277 /* set the source address */ 278 /* set the source address */
278 ipv6_addr_copy(&np->saddr, saddr); 279 ipv6_addr_copy(&np->saddr, saddr);
279 inet->rcv_saddr = LOOPBACK4_IPV6; 280 inet->inet_rcv_saddr = LOOPBACK4_IPV6;
280 281
281 sk->sk_gso_type = SKB_GSO_TCPV6; 282 sk->sk_gso_type = SKB_GSO_TCPV6;
282 __ip6_dst_store(sk, dst, NULL, NULL); 283 __ip6_dst_store(sk, dst, NULL, NULL);
@@ -288,7 +289,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
288 289
289 tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 290 tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
290 291
291 inet->dport = usin->sin6_port; 292 inet->inet_dport = usin->sin6_port;
292 293
293 tcp_set_state(sk, TCP_SYN_SENT); 294 tcp_set_state(sk, TCP_SYN_SENT);
294 err = inet6_hash_connect(&tcp_death_row, sk); 295 err = inet6_hash_connect(&tcp_death_row, sk);
@@ -298,8 +299,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
298 if (!tp->write_seq) 299 if (!tp->write_seq)
299 tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32, 300 tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32,
300 np->daddr.s6_addr32, 301 np->daddr.s6_addr32,
301 inet->sport, 302 inet->inet_sport,
302 inet->dport); 303 inet->inet_dport);
303 304
304 err = tcp_connect(sk); 305 err = tcp_connect(sk);
305 if (err) 306 if (err)
@@ -311,7 +312,7 @@ late_failure:
311 tcp_set_state(sk, TCP_CLOSE); 312 tcp_set_state(sk, TCP_CLOSE);
312 __sk_dst_reset(sk); 313 __sk_dst_reset(sk);
313failure: 314failure:
314 inet->dport = 0; 315 inet->inet_dport = 0;
315 sk->sk_route_caps = 0; 316 sk->sk_route_caps = 0;
316 return err; 317 return err;
317} 318}
@@ -383,8 +384,9 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
383 ipv6_addr_copy(&fl.fl6_dst, &np->daddr); 384 ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
384 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 385 ipv6_addr_copy(&fl.fl6_src, &np->saddr);
385 fl.oif = sk->sk_bound_dev_if; 386 fl.oif = sk->sk_bound_dev_if;
386 fl.fl_ip_dport = inet->dport; 387 fl.mark = sk->sk_mark;
387 fl.fl_ip_sport = inet->sport; 388 fl.fl_ip_dport = inet->inet_dport;
389 fl.fl_ip_sport = inet->inet_sport;
388 security_skb_classify_flow(skb, &fl); 390 security_skb_classify_flow(skb, &fl);
389 391
390 if ((err = ip6_dst_lookup(sk, &dst, &fl))) { 392 if ((err = ip6_dst_lookup(sk, &dst, &fl))) {
@@ -460,7 +462,8 @@ out:
460} 462}
461 463
462 464
463static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req) 465static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
466 struct request_values *rvp)
464{ 467{
465 struct inet6_request_sock *treq = inet6_rsk(req); 468 struct inet6_request_sock *treq = inet6_rsk(req);
466 struct ipv6_pinfo *np = inet6_sk(sk); 469 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -477,6 +480,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
477 ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); 480 ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
478 fl.fl6_flowlabel = 0; 481 fl.fl6_flowlabel = 0;
479 fl.oif = treq->iif; 482 fl.oif = treq->iif;
483 fl.mark = sk->sk_mark;
480 fl.fl_ip_dport = inet_rsk(req)->rmt_port; 484 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
481 fl.fl_ip_sport = inet_rsk(req)->loc_port; 485 fl.fl_ip_sport = inet_rsk(req)->loc_port;
482 security_req_classify_flow(req, &fl); 486 security_req_classify_flow(req, &fl);
@@ -497,7 +501,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
497 if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) 501 if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
498 goto done; 502 goto done;
499 503
500 skb = tcp_make_synack(sk, dst, req); 504 skb = tcp_make_synack(sk, dst, req, rvp);
501 if (skb) { 505 if (skb) {
502 struct tcphdr *th = tcp_hdr(skb); 506 struct tcphdr *th = tcp_hdr(skb);
503 507
@@ -517,6 +521,13 @@ done:
517 return err; 521 return err;
518} 522}
519 523
524static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req,
525 struct request_values *rvp)
526{
527 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
528 return tcp_v6_send_synack(sk, req, rvp);
529}
530
520static inline void syn_flood_warning(struct sk_buff *skb) 531static inline void syn_flood_warning(struct sk_buff *skb)
521{ 532{
522#ifdef CONFIG_SYN_COOKIES 533#ifdef CONFIG_SYN_COOKIES
@@ -873,7 +884,7 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
873 884
874 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 885 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
875 if (net_ratelimit()) { 886 if (net_ratelimit()) {
876 printk(KERN_INFO "MD5 Hash %s for (%pI6, %u)->(%pI6, %u)\n", 887 printk(KERN_INFO "MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u\n",
877 genhash ? "failed" : "mismatch", 888 genhash ? "failed" : "mismatch",
878 &ip6h->saddr, ntohs(th->source), 889 &ip6h->saddr, ntohs(th->source),
879 &ip6h->daddr, ntohs(th->dest)); 890 &ip6h->daddr, ntohs(th->dest));
@@ -887,10 +898,11 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
887struct request_sock_ops tcp6_request_sock_ops __read_mostly = { 898struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
888 .family = AF_INET6, 899 .family = AF_INET6,
889 .obj_size = sizeof(struct tcp6_request_sock), 900 .obj_size = sizeof(struct tcp6_request_sock),
890 .rtx_syn_ack = tcp_v6_send_synack, 901 .rtx_syn_ack = tcp_v6_rtx_synack,
891 .send_ack = tcp_v6_reqsk_send_ack, 902 .send_ack = tcp_v6_reqsk_send_ack,
892 .destructor = tcp_v6_reqsk_destructor, 903 .destructor = tcp_v6_reqsk_destructor,
893 .send_reset = tcp_v6_send_reset 904 .send_reset = tcp_v6_send_reset,
905 .syn_ack_timeout = tcp_syn_ack_timeout,
894}; 906};
895 907
896#ifdef CONFIG_TCP_MD5SIG 908#ifdef CONFIG_TCP_MD5SIG
@@ -1003,7 +1015,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
1003 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); 1015 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
1004 1016
1005 t1 = (struct tcphdr *) skb_push(buff, tot_len); 1017 t1 = (struct tcphdr *) skb_push(buff, tot_len);
1006 skb_reset_transport_header(skb); 1018 skb_reset_transport_header(buff);
1007 1019
1008 /* Swap the send and the receive. */ 1020 /* Swap the send and the receive. */
1009 memset(t1, 0, sizeof(*t1)); 1021 memset(t1, 0, sizeof(*t1));
@@ -1159,11 +1171,13 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
1159 */ 1171 */
1160static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) 1172static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1161{ 1173{
1174 struct tcp_extend_values tmp_ext;
1175 struct tcp_options_received tmp_opt;
1176 u8 *hash_location;
1177 struct request_sock *req;
1162 struct inet6_request_sock *treq; 1178 struct inet6_request_sock *treq;
1163 struct ipv6_pinfo *np = inet6_sk(sk); 1179 struct ipv6_pinfo *np = inet6_sk(sk);
1164 struct tcp_options_received tmp_opt;
1165 struct tcp_sock *tp = tcp_sk(sk); 1180 struct tcp_sock *tp = tcp_sk(sk);
1166 struct request_sock *req = NULL;
1167 __u32 isn = TCP_SKB_CB(skb)->when; 1181 __u32 isn = TCP_SKB_CB(skb)->when;
1168#ifdef CONFIG_SYN_COOKIES 1182#ifdef CONFIG_SYN_COOKIES
1169 int want_cookie = 0; 1183 int want_cookie = 0;
@@ -1202,8 +1216,52 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1202 tcp_clear_options(&tmp_opt); 1216 tcp_clear_options(&tmp_opt);
1203 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 1217 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
1204 tmp_opt.user_mss = tp->rx_opt.user_mss; 1218 tmp_opt.user_mss = tp->rx_opt.user_mss;
1219 tcp_parse_options(skb, &tmp_opt, &hash_location, 0);
1220
1221 if (tmp_opt.cookie_plus > 0 &&
1222 tmp_opt.saw_tstamp &&
1223 !tp->rx_opt.cookie_out_never &&
1224 (sysctl_tcp_cookie_size > 0 ||
1225 (tp->cookie_values != NULL &&
1226 tp->cookie_values->cookie_desired > 0))) {
1227 u8 *c;
1228 u32 *d;
1229 u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS];
1230 int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE;
1231
1232 if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0)
1233 goto drop_and_free;
1234
1235 /* Secret recipe starts with IP addresses */
1236 d = &ipv6_hdr(skb)->daddr.s6_addr32[0];
1237 *mess++ ^= *d++;
1238 *mess++ ^= *d++;
1239 *mess++ ^= *d++;
1240 *mess++ ^= *d++;
1241 d = &ipv6_hdr(skb)->saddr.s6_addr32[0];
1242 *mess++ ^= *d++;
1243 *mess++ ^= *d++;
1244 *mess++ ^= *d++;
1245 *mess++ ^= *d++;
1246
1247 /* plus variable length Initiator Cookie */
1248 c = (u8 *)mess;
1249 while (l-- > 0)
1250 *c++ ^= *hash_location++;
1205 1251
1206 tcp_parse_options(skb, &tmp_opt, 0); 1252#ifdef CONFIG_SYN_COOKIES
1253 want_cookie = 0; /* not our kind of cookie */
1254#endif
1255 tmp_ext.cookie_out_never = 0; /* false */
1256 tmp_ext.cookie_plus = tmp_opt.cookie_plus;
1257 } else if (!tp->rx_opt.cookie_in_always) {
1258 /* redundant indications, but ensure initialization. */
1259 tmp_ext.cookie_out_never = 1; /* true */
1260 tmp_ext.cookie_plus = 0;
1261 } else {
1262 goto drop_and_free;
1263 }
1264 tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always;
1207 1265
1208 if (want_cookie && !tmp_opt.saw_tstamp) 1266 if (want_cookie && !tmp_opt.saw_tstamp)
1209 tcp_clear_options(&tmp_opt); 1267 tcp_clear_options(&tmp_opt);
@@ -1236,23 +1294,21 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1236 1294
1237 isn = tcp_v6_init_sequence(skb); 1295 isn = tcp_v6_init_sequence(skb);
1238 } 1296 }
1239
1240 tcp_rsk(req)->snt_isn = isn; 1297 tcp_rsk(req)->snt_isn = isn;
1241 1298
1242 security_inet_conn_request(sk, skb, req); 1299 security_inet_conn_request(sk, skb, req);
1243 1300
1244 if (tcp_v6_send_synack(sk, req)) 1301 if (tcp_v6_send_synack(sk, req,
1245 goto drop; 1302 (struct request_values *)&tmp_ext) ||
1303 want_cookie)
1304 goto drop_and_free;
1246 1305
1247 if (!want_cookie) { 1306 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
1248 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); 1307 return 0;
1249 return 0;
1250 }
1251 1308
1309drop_and_free:
1310 reqsk_free(req);
1252drop: 1311drop:
1253 if (req)
1254 reqsk_free(req);
1255
1256 return 0; /* don't send reset */ 1312 return 0; /* don't send reset */
1257} 1313}
1258 1314
@@ -1290,11 +1346,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1290 1346
1291 memcpy(newnp, np, sizeof(struct ipv6_pinfo)); 1347 memcpy(newnp, np, sizeof(struct ipv6_pinfo));
1292 1348
1293 ipv6_addr_set(&newnp->daddr, 0, 0, htonl(0x0000FFFF), 1349 ipv6_addr_set_v4mapped(newinet->inet_daddr, &newnp->daddr);
1294 newinet->daddr);
1295 1350
1296 ipv6_addr_set(&newnp->saddr, 0, 0, htonl(0x0000FFFF), 1351 ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr);
1297 newinet->saddr);
1298 1352
1299 ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr); 1353 ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr);
1300 1354
@@ -1345,6 +1399,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1345 } 1399 }
1346 ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); 1400 ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
1347 fl.oif = sk->sk_bound_dev_if; 1401 fl.oif = sk->sk_bound_dev_if;
1402 fl.mark = sk->sk_mark;
1348 fl.fl_ip_dport = inet_rsk(req)->rmt_port; 1403 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
1349 fl.fl_ip_sport = inet_rsk(req)->loc_port; 1404 fl.fl_ip_sport = inet_rsk(req)->loc_port;
1350 security_req_classify_flow(req, &fl); 1405 security_req_classify_flow(req, &fl);
@@ -1431,7 +1486,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1431 newtp->advmss = dst_metric(dst, RTAX_ADVMSS); 1486 newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
1432 tcp_initialize_rcv_mss(newsk); 1487 tcp_initialize_rcv_mss(newsk);
1433 1488
1434 newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; 1489 newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
1490 newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
1435 1491
1436#ifdef CONFIG_TCP_MD5SIG 1492#ifdef CONFIG_TCP_MD5SIG
1437 /* Copy over the MD5 key from the original socket */ 1493 /* Copy over the MD5 key from the original socket */
@@ -1448,7 +1504,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1448 } 1504 }
1449#endif 1505#endif
1450 1506
1451 __inet6_hash(newsk); 1507 __inet6_hash(newsk, NULL);
1452 __inet_inherit_port(sk, newsk); 1508 __inet_inherit_port(sk, newsk);
1453 1509
1454 return newsk; 1510 return newsk;
@@ -1685,8 +1741,11 @@ process:
1685 if (!tcp_prequeue(sk, skb)) 1741 if (!tcp_prequeue(sk, skb))
1686 ret = tcp_v6_do_rcv(sk, skb); 1742 ret = tcp_v6_do_rcv(sk, skb);
1687 } 1743 }
1688 } else 1744 } else if (unlikely(sk_add_backlog(sk, skb))) {
1689 sk_add_backlog(sk, skb); 1745 bh_unlock_sock(sk);
1746 NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
1747 goto discard_and_relse;
1748 }
1690 bh_unlock_sock(sk); 1749 bh_unlock_sock(sk);
1691 1750
1692 sock_put(sk); 1751 sock_put(sk);
@@ -1848,7 +1907,7 @@ static int tcp_v6_init_sock(struct sock *sk)
1848 */ 1907 */
1849 tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; 1908 tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
1850 tp->snd_cwnd_clamp = ~0; 1909 tp->snd_cwnd_clamp = ~0;
1851 tp->mss_cache = 536; 1910 tp->mss_cache = TCP_MSS_DEFAULT;
1852 1911
1853 tp->reordering = sysctl_tcp_reordering; 1912 tp->reordering = sysctl_tcp_reordering;
1854 1913
@@ -1864,6 +1923,19 @@ static int tcp_v6_init_sock(struct sock *sk)
1864 tp->af_specific = &tcp_sock_ipv6_specific; 1923 tp->af_specific = &tcp_sock_ipv6_specific;
1865#endif 1924#endif
1866 1925
1926 /* TCP Cookie Transactions */
1927 if (sysctl_tcp_cookie_size > 0) {
1928 /* Default, cookies without s_data_payload. */
1929 tp->cookie_values =
1930 kzalloc(sizeof(*tp->cookie_values),
1931 sk->sk_allocation);
1932 if (tp->cookie_values != NULL)
1933 kref_init(&tp->cookie_values->kref);
1934 }
1935 /* Presumed zeroed, in order of appearance:
1936 * cookie_in_always, cookie_out_never,
1937 * s_data_constant, s_data_in, s_data_out
1938 */
1867 sk->sk_sndbuf = sysctl_tcp_wmem[1]; 1939 sk->sk_sndbuf = sysctl_tcp_wmem[1];
1868 sk->sk_rcvbuf = sysctl_tcp_rmem[1]; 1940 sk->sk_rcvbuf = sysctl_tcp_rmem[1];
1869 1941
@@ -1931,8 +2003,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
1931 2003
1932 dest = &np->daddr; 2004 dest = &np->daddr;
1933 src = &np->rcv_saddr; 2005 src = &np->rcv_saddr;
1934 destp = ntohs(inet->dport); 2006 destp = ntohs(inet->inet_dport);
1935 srcp = ntohs(inet->sport); 2007 srcp = ntohs(inet->inet_sport);
1936 2008
1937 if (icsk->icsk_pending == ICSK_TIME_RETRANS) { 2009 if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
1938 timer_active = 1; 2010 timer_active = 1;
@@ -2045,7 +2117,7 @@ static struct tcp_seq_afinfo tcp6_seq_afinfo = {
2045 }, 2117 },
2046}; 2118};
2047 2119
2048int tcp6_proc_init(struct net *net) 2120int __net_init tcp6_proc_init(struct net *net)
2049{ 2121{
2050 return tcp_proc_register(net, &tcp6_seq_afinfo); 2122 return tcp_proc_register(net, &tcp6_seq_afinfo);
2051} 2123}
@@ -2109,27 +2181,31 @@ static struct inet_protosw tcpv6_protosw = {
2109 .protocol = IPPROTO_TCP, 2181 .protocol = IPPROTO_TCP,
2110 .prot = &tcpv6_prot, 2182 .prot = &tcpv6_prot,
2111 .ops = &inet6_stream_ops, 2183 .ops = &inet6_stream_ops,
2112 .capability = -1,
2113 .no_check = 0, 2184 .no_check = 0,
2114 .flags = INET_PROTOSW_PERMANENT | 2185 .flags = INET_PROTOSW_PERMANENT |
2115 INET_PROTOSW_ICSK, 2186 INET_PROTOSW_ICSK,
2116}; 2187};
2117 2188
2118static int tcpv6_net_init(struct net *net) 2189static int __net_init tcpv6_net_init(struct net *net)
2119{ 2190{
2120 return inet_ctl_sock_create(&net->ipv6.tcp_sk, PF_INET6, 2191 return inet_ctl_sock_create(&net->ipv6.tcp_sk, PF_INET6,
2121 SOCK_RAW, IPPROTO_TCP, net); 2192 SOCK_RAW, IPPROTO_TCP, net);
2122} 2193}
2123 2194
2124static void tcpv6_net_exit(struct net *net) 2195static void __net_exit tcpv6_net_exit(struct net *net)
2125{ 2196{
2126 inet_ctl_sock_destroy(net->ipv6.tcp_sk); 2197 inet_ctl_sock_destroy(net->ipv6.tcp_sk);
2127 inet_twsk_purge(net, &tcp_hashinfo, &tcp_death_row, AF_INET6); 2198}
2199
2200static void __net_exit tcpv6_net_exit_batch(struct list_head *net_exit_list)
2201{
2202 inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET6);
2128} 2203}
2129 2204
2130static struct pernet_operations tcpv6_net_ops = { 2205static struct pernet_operations tcpv6_net_ops = {
2131 .init = tcpv6_net_init, 2206 .init = tcpv6_net_init,
2132 .exit = tcpv6_net_exit, 2207 .exit = tcpv6_net_exit,
2208 .exit_batch = tcpv6_net_exit_batch,
2133}; 2209};
2134 2210
2135int __init tcpv6_init(void) 2211int __init tcpv6_init(void)
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index 51e2832d13a6..fc3c86a47452 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -25,6 +25,7 @@
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/netdevice.h> 26#include <linux/netdevice.h>
27#include <linux/skbuff.h> 27#include <linux/skbuff.h>
28#include <linux/slab.h>
28#include <net/ipv6.h> 29#include <net/ipv6.h>
29#include <net/protocol.h> 30#include <net/protocol.h>
30#include <net/xfrm.h> 31#include <net/xfrm.h>
@@ -98,7 +99,7 @@ static int tunnel6_rcv(struct sk_buff *skb)
98 if (!handler->handler(skb)) 99 if (!handler->handler(skb))
99 return 0; 100 return 0;
100 101
101 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev); 102 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
102 103
103drop: 104drop:
104 kfree_skb(skb); 105 kfree_skb(skb);
@@ -116,7 +117,7 @@ static int tunnel46_rcv(struct sk_buff *skb)
116 if (!handler->handler(skb)) 117 if (!handler->handler(skb))
117 return 0; 118 return 0;
118 119
119 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev); 120 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
120 121
121drop: 122drop:
122 kfree_skb(skb); 123 kfree_skb(skb);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index cf538ed5ef6a..90824852f598 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -34,6 +34,7 @@
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/skbuff.h> 36#include <linux/skbuff.h>
37#include <linux/slab.h>
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
38 39
39#include <net/ndisc.h> 40#include <net/ndisc.h>
@@ -53,7 +54,7 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
53{ 54{
54 const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr; 55 const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
55 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2); 56 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
56 __be32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr; 57 __be32 sk1_rcv_saddr = inet_sk(sk)->inet_rcv_saddr;
57 __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2); 58 __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
58 int sk_ipv6only = ipv6_only_sock(sk); 59 int sk_ipv6only = ipv6_only_sock(sk);
59 int sk2_ipv6only = inet_v6_ipv6only(sk2); 60 int sk2_ipv6only = inet_v6_ipv6only(sk2);
@@ -63,8 +64,8 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
63 /* if both are mapped, treat as IPv4 */ 64 /* if both are mapped, treat as IPv4 */
64 if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) 65 if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED)
65 return (!sk2_ipv6only && 66 return (!sk2_ipv6only &&
66 (!sk_rcv_saddr || !sk2_rcv_saddr || 67 (!sk1_rcv_saddr || !sk2_rcv_saddr ||
67 sk_rcv_saddr == sk2_rcv_saddr)); 68 sk1_rcv_saddr == sk2_rcv_saddr));
68 69
69 if (addr_type2 == IPV6_ADDR_ANY && 70 if (addr_type2 == IPV6_ADDR_ANY &&
70 !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED)) 71 !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
@@ -81,9 +82,33 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
81 return 0; 82 return 0;
82} 83}
83 84
85static unsigned int udp6_portaddr_hash(struct net *net,
86 const struct in6_addr *addr6,
87 unsigned int port)
88{
89 unsigned int hash, mix = net_hash_mix(net);
90
91 if (ipv6_addr_any(addr6))
92 hash = jhash_1word(0, mix);
93 else if (ipv6_addr_v4mapped(addr6))
94 hash = jhash_1word(addr6->s6_addr32[3], mix);
95 else
96 hash = jhash2(addr6->s6_addr32, 4, mix);
97
98 return hash ^ port;
99}
100
101
84int udp_v6_get_port(struct sock *sk, unsigned short snum) 102int udp_v6_get_port(struct sock *sk, unsigned short snum)
85{ 103{
86 return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal); 104 unsigned int hash2_nulladdr =
105 udp6_portaddr_hash(sock_net(sk), &in6addr_any, snum);
106 unsigned int hash2_partial =
107 udp6_portaddr_hash(sock_net(sk), &inet6_sk(sk)->rcv_saddr, 0);
108
109 /* precompute partial secondary hash */
110 udp_sk(sk)->udp_portaddr_hash = hash2_partial;
111 return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal, hash2_nulladdr);
87} 112}
88 113
89static inline int compute_score(struct sock *sk, struct net *net, 114static inline int compute_score(struct sock *sk, struct net *net,
@@ -94,14 +119,14 @@ static inline int compute_score(struct sock *sk, struct net *net,
94{ 119{
95 int score = -1; 120 int score = -1;
96 121
97 if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && 122 if (net_eq(sock_net(sk), net) && udp_sk(sk)->udp_port_hash == hnum &&
98 sk->sk_family == PF_INET6) { 123 sk->sk_family == PF_INET6) {
99 struct ipv6_pinfo *np = inet6_sk(sk); 124 struct ipv6_pinfo *np = inet6_sk(sk);
100 struct inet_sock *inet = inet_sk(sk); 125 struct inet_sock *inet = inet_sk(sk);
101 126
102 score = 0; 127 score = 0;
103 if (inet->dport) { 128 if (inet->inet_dport) {
104 if (inet->dport != sport) 129 if (inet->inet_dport != sport)
105 return -1; 130 return -1;
106 score++; 131 score++;
107 } 132 }
@@ -124,6 +149,86 @@ static inline int compute_score(struct sock *sk, struct net *net,
124 return score; 149 return score;
125} 150}
126 151
152#define SCORE2_MAX (1 + 1 + 1)
153static inline int compute_score2(struct sock *sk, struct net *net,
154 const struct in6_addr *saddr, __be16 sport,
155 const struct in6_addr *daddr, unsigned short hnum,
156 int dif)
157{
158 int score = -1;
159
160 if (net_eq(sock_net(sk), net) && udp_sk(sk)->udp_port_hash == hnum &&
161 sk->sk_family == PF_INET6) {
162 struct ipv6_pinfo *np = inet6_sk(sk);
163 struct inet_sock *inet = inet_sk(sk);
164
165 if (!ipv6_addr_equal(&np->rcv_saddr, daddr))
166 return -1;
167 score = 0;
168 if (inet->inet_dport) {
169 if (inet->inet_dport != sport)
170 return -1;
171 score++;
172 }
173 if (!ipv6_addr_any(&np->daddr)) {
174 if (!ipv6_addr_equal(&np->daddr, saddr))
175 return -1;
176 score++;
177 }
178 if (sk->sk_bound_dev_if) {
179 if (sk->sk_bound_dev_if != dif)
180 return -1;
181 score++;
182 }
183 }
184 return score;
185}
186
187
188/* called with read_rcu_lock() */
189static struct sock *udp6_lib_lookup2(struct net *net,
190 const struct in6_addr *saddr, __be16 sport,
191 const struct in6_addr *daddr, unsigned int hnum, int dif,
192 struct udp_hslot *hslot2, unsigned int slot2)
193{
194 struct sock *sk, *result;
195 struct hlist_nulls_node *node;
196 int score, badness;
197
198begin:
199 result = NULL;
200 badness = -1;
201 udp_portaddr_for_each_entry_rcu(sk, node, &hslot2->head) {
202 score = compute_score2(sk, net, saddr, sport,
203 daddr, hnum, dif);
204 if (score > badness) {
205 result = sk;
206 badness = score;
207 if (score == SCORE2_MAX)
208 goto exact_match;
209 }
210 }
211 /*
212 * if the nulls value we got at the end of this lookup is
213 * not the expected one, we must restart lookup.
214 * We probably met an item that was moved to another chain.
215 */
216 if (get_nulls_value(node) != slot2)
217 goto begin;
218
219 if (result) {
220exact_match:
221 if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))
222 result = NULL;
223 else if (unlikely(compute_score2(result, net, saddr, sport,
224 daddr, hnum, dif) < badness)) {
225 sock_put(result);
226 goto begin;
227 }
228 }
229 return result;
230}
231
127static struct sock *__udp6_lib_lookup(struct net *net, 232static struct sock *__udp6_lib_lookup(struct net *net,
128 struct in6_addr *saddr, __be16 sport, 233 struct in6_addr *saddr, __be16 sport,
129 struct in6_addr *daddr, __be16 dport, 234 struct in6_addr *daddr, __be16 dport,
@@ -132,11 +237,35 @@ static struct sock *__udp6_lib_lookup(struct net *net,
132 struct sock *sk, *result; 237 struct sock *sk, *result;
133 struct hlist_nulls_node *node; 238 struct hlist_nulls_node *node;
134 unsigned short hnum = ntohs(dport); 239 unsigned short hnum = ntohs(dport);
135 unsigned int hash = udp_hashfn(net, hnum); 240 unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask);
136 struct udp_hslot *hslot = &udptable->hash[hash]; 241 struct udp_hslot *hslot2, *hslot = &udptable->hash[slot];
137 int score, badness; 242 int score, badness;
138 243
139 rcu_read_lock(); 244 rcu_read_lock();
245 if (hslot->count > 10) {
246 hash2 = udp6_portaddr_hash(net, daddr, hnum);
247 slot2 = hash2 & udptable->mask;
248 hslot2 = &udptable->hash2[slot2];
249 if (hslot->count < hslot2->count)
250 goto begin;
251
252 result = udp6_lib_lookup2(net, saddr, sport,
253 daddr, hnum, dif,
254 hslot2, slot2);
255 if (!result) {
256 hash2 = udp6_portaddr_hash(net, &in6addr_any, hnum);
257 slot2 = hash2 & udptable->mask;
258 hslot2 = &udptable->hash2[slot2];
259 if (hslot->count < hslot2->count)
260 goto begin;
261
262 result = udp6_lib_lookup2(net, saddr, sport,
263 &in6addr_any, hnum, dif,
264 hslot2, slot2);
265 }
266 rcu_read_unlock();
267 return result;
268 }
140begin: 269begin:
141 result = NULL; 270 result = NULL;
142 badness = -1; 271 badness = -1;
@@ -152,7 +281,7 @@ begin:
152 * not the expected one, we must restart lookup. 281 * not the expected one, we must restart lookup.
153 * We probably met an item that was moved to another chain. 282 * We probably met an item that was moved to another chain.
154 */ 283 */
155 if (get_nulls_value(node) != hash) 284 if (get_nulls_value(node) != slot)
156 goto begin; 285 goto begin;
157 286
158 if (result) { 287 if (result) {
@@ -194,7 +323,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
194 struct ipv6_pinfo *np = inet6_sk(sk); 323 struct ipv6_pinfo *np = inet6_sk(sk);
195 struct inet_sock *inet = inet_sk(sk); 324 struct inet_sock *inet = inet_sk(sk);
196 struct sk_buff *skb; 325 struct sk_buff *skb;
197 unsigned int ulen, copied; 326 unsigned int ulen;
198 int peeked; 327 int peeked;
199 int err; 328 int err;
200 int is_udplite = IS_UDPLITE(sk); 329 int is_udplite = IS_UDPLITE(sk);
@@ -213,10 +342,9 @@ try_again:
213 goto out; 342 goto out;
214 343
215 ulen = skb->len - sizeof(struct udphdr); 344 ulen = skb->len - sizeof(struct udphdr);
216 copied = len; 345 if (len > ulen)
217 if (copied > ulen) 346 len = ulen;
218 copied = ulen; 347 else if (len < ulen)
219 else if (copied < ulen)
220 msg->msg_flags |= MSG_TRUNC; 348 msg->msg_flags |= MSG_TRUNC;
221 349
222 is_udp4 = (skb->protocol == htons(ETH_P_IP)); 350 is_udp4 = (skb->protocol == htons(ETH_P_IP));
@@ -227,14 +355,14 @@ try_again:
227 * coverage checksum (UDP-Lite), do it before the copy. 355 * coverage checksum (UDP-Lite), do it before the copy.
228 */ 356 */
229 357
230 if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) { 358 if (len < ulen || UDP_SKB_CB(skb)->partial_cov) {
231 if (udp_lib_checksum_complete(skb)) 359 if (udp_lib_checksum_complete(skb))
232 goto csum_copy_err; 360 goto csum_copy_err;
233 } 361 }
234 362
235 if (skb_csum_unnecessary(skb)) 363 if (skb_csum_unnecessary(skb))
236 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), 364 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
237 msg->msg_iov, copied ); 365 msg->msg_iov,len);
238 else { 366 else {
239 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); 367 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
240 if (err == -EINVAL) 368 if (err == -EINVAL)
@@ -252,7 +380,7 @@ try_again:
252 UDP_MIB_INDATAGRAMS, is_udplite); 380 UDP_MIB_INDATAGRAMS, is_udplite);
253 } 381 }
254 382
255 sock_recv_timestamp(msg, sk, skb); 383 sock_recv_ts_and_drops(msg, sk, skb);
256 384
257 /* Copy the address. */ 385 /* Copy the address. */
258 if (msg->msg_name) { 386 if (msg->msg_name) {
@@ -265,8 +393,8 @@ try_again:
265 sin6->sin6_scope_id = 0; 393 sin6->sin6_scope_id = 0;
266 394
267 if (is_udp4) 395 if (is_udp4)
268 ipv6_addr_set(&sin6->sin6_addr, 0, 0, 396 ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr,
269 htonl(0xffff), ip_hdr(skb)->saddr); 397 &sin6->sin6_addr);
270 else { 398 else {
271 ipv6_addr_copy(&sin6->sin6_addr, 399 ipv6_addr_copy(&sin6->sin6_addr,
272 &ipv6_hdr(skb)->saddr); 400 &ipv6_hdr(skb)->saddr);
@@ -283,7 +411,7 @@ try_again:
283 datagram_recv_ctl(sk, msg, skb); 411 datagram_recv_ctl(sk, msg, skb);
284 } 412 }
285 413
286 err = copied; 414 err = len;
287 if (flags & MSG_TRUNC) 415 if (flags & MSG_TRUNC)
288 err = ulen; 416 err = ulen;
289 417
@@ -383,18 +511,18 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
383 goto drop; 511 goto drop;
384 } 512 }
385 513
386 if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { 514 if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) {
387 /* Note that an ENOMEM error is charged twice */ 515 /* Note that an ENOMEM error is charged twice */
388 if (rc == -ENOMEM) { 516 if (rc == -ENOMEM)
389 UDP6_INC_STATS_BH(sock_net(sk), 517 UDP6_INC_STATS_BH(sock_net(sk),
390 UDP_MIB_RCVBUFERRORS, is_udplite); 518 UDP_MIB_RCVBUFERRORS, is_udplite);
391 atomic_inc(&sk->sk_drops); 519 goto drop_no_sk_drops_inc;
392 }
393 goto drop;
394 } 520 }
395 521
396 return 0; 522 return 0;
397drop: 523drop:
524 atomic_inc(&sk->sk_drops);
525drop_no_sk_drops_inc:
398 UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite); 526 UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
399 kfree_skb(skb); 527 kfree_skb(skb);
400 return -1; 528 return -1;
@@ -415,10 +543,11 @@ static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk,
415 if (!net_eq(sock_net(s), net)) 543 if (!net_eq(sock_net(s), net))
416 continue; 544 continue;
417 545
418 if (s->sk_hash == num && s->sk_family == PF_INET6) { 546 if (udp_sk(s)->udp_port_hash == num &&
547 s->sk_family == PF_INET6) {
419 struct ipv6_pinfo *np = inet6_sk(s); 548 struct ipv6_pinfo *np = inet6_sk(s);
420 if (inet->dport) { 549 if (inet->inet_dport) {
421 if (inet->dport != rmt_port) 550 if (inet->inet_dport != rmt_port)
422 continue; 551 continue;
423 } 552 }
424 if (!ipv6_addr_any(&np->daddr) && 553 if (!ipv6_addr_any(&np->daddr) &&
@@ -440,6 +569,37 @@ static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk,
440 return NULL; 569 return NULL;
441} 570}
442 571
572static void flush_stack(struct sock **stack, unsigned int count,
573 struct sk_buff *skb, unsigned int final)
574{
575 unsigned int i;
576 struct sock *sk;
577 struct sk_buff *skb1;
578
579 for (i = 0; i < count; i++) {
580 skb1 = (i == final) ? skb : skb_clone(skb, GFP_ATOMIC);
581
582 sk = stack[i];
583 if (skb1) {
584 bh_lock_sock(sk);
585 if (!sock_owned_by_user(sk))
586 udpv6_queue_rcv_skb(sk, skb1);
587 else if (sk_add_backlog(sk, skb1)) {
588 kfree_skb(skb1);
589 bh_unlock_sock(sk);
590 goto drop;
591 }
592 bh_unlock_sock(sk);
593 continue;
594 }
595drop:
596 atomic_inc(&sk->sk_drops);
597 UDP6_INC_STATS_BH(sock_net(sk),
598 UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk));
599 UDP6_INC_STATS_BH(sock_net(sk),
600 UDP_MIB_INERRORS, IS_UDPLITE(sk));
601 }
602}
443/* 603/*
444 * Note: called only from the BH handler context, 604 * Note: called only from the BH handler context,
445 * so we don't need to lock the hashes. 605 * so we don't need to lock the hashes.
@@ -448,41 +608,43 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
448 struct in6_addr *saddr, struct in6_addr *daddr, 608 struct in6_addr *saddr, struct in6_addr *daddr,
449 struct udp_table *udptable) 609 struct udp_table *udptable)
450{ 610{
451 struct sock *sk, *sk2; 611 struct sock *sk, *stack[256 / sizeof(struct sock *)];
452 const struct udphdr *uh = udp_hdr(skb); 612 const struct udphdr *uh = udp_hdr(skb);
453 struct udp_hslot *hslot = &udptable->hash[udp_hashfn(net, ntohs(uh->dest))]; 613 struct udp_hslot *hslot = udp_hashslot(udptable, net, ntohs(uh->dest));
454 int dif; 614 int dif;
615 unsigned int i, count = 0;
455 616
456 spin_lock(&hslot->lock); 617 spin_lock(&hslot->lock);
457 sk = sk_nulls_head(&hslot->head); 618 sk = sk_nulls_head(&hslot->head);
458 dif = inet6_iif(skb); 619 dif = inet6_iif(skb);
459 sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif); 620 sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif);
460 if (!sk) { 621 while (sk) {
461 kfree_skb(skb); 622 stack[count++] = sk;
462 goto out; 623 sk = udp_v6_mcast_next(net, sk_nulls_next(sk), uh->dest, daddr,
463 } 624 uh->source, saddr, dif);
464 625 if (unlikely(count == ARRAY_SIZE(stack))) {
465 sk2 = sk; 626 if (!sk)
466 while ((sk2 = udp_v6_mcast_next(net, sk_nulls_next(sk2), uh->dest, daddr, 627 break;
467 uh->source, saddr, dif))) { 628 flush_stack(stack, count, skb, ~0);
468 struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); 629 count = 0;
469 if (buff) {
470 bh_lock_sock(sk2);
471 if (!sock_owned_by_user(sk2))
472 udpv6_queue_rcv_skb(sk2, buff);
473 else
474 sk_add_backlog(sk2, buff);
475 bh_unlock_sock(sk2);
476 } 630 }
477 } 631 }
478 bh_lock_sock(sk); 632 /*
479 if (!sock_owned_by_user(sk)) 633 * before releasing the lock, we must take reference on sockets
480 udpv6_queue_rcv_skb(sk, skb); 634 */
481 else 635 for (i = 0; i < count; i++)
482 sk_add_backlog(sk, skb); 636 sock_hold(stack[i]);
483 bh_unlock_sock(sk); 637
484out:
485 spin_unlock(&hslot->lock); 638 spin_unlock(&hslot->lock);
639
640 if (count) {
641 flush_stack(stack, count, skb, count - 1);
642
643 for (i = 0; i < count; i++)
644 sock_put(stack[i]);
645 } else {
646 kfree_skb(skb);
647 }
486 return 0; 648 return 0;
487} 649}
488 650
@@ -523,12 +685,11 @@ static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh,
523int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, 685int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
524 int proto) 686 int proto)
525{ 687{
688 struct net *net = dev_net(skb->dev);
526 struct sock *sk; 689 struct sock *sk;
527 struct udphdr *uh; 690 struct udphdr *uh;
528 struct net_device *dev = skb->dev;
529 struct in6_addr *saddr, *daddr; 691 struct in6_addr *saddr, *daddr;
530 u32 ulen = 0; 692 u32 ulen = 0;
531 struct net *net = dev_net(skb->dev);
532 693
533 if (!pskb_may_pull(skb, sizeof(struct udphdr))) 694 if (!pskb_may_pull(skb, sizeof(struct udphdr)))
534 goto short_packet; 695 goto short_packet;
@@ -587,7 +748,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
587 UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, 748 UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS,
588 proto == IPPROTO_UDPLITE); 749 proto == IPPROTO_UDPLITE);
589 750
590 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev); 751 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
591 752
592 kfree_skb(skb); 753 kfree_skb(skb);
593 return 0; 754 return 0;
@@ -598,8 +759,12 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
598 bh_lock_sock(sk); 759 bh_lock_sock(sk);
599 if (!sock_owned_by_user(sk)) 760 if (!sock_owned_by_user(sk))
600 udpv6_queue_rcv_skb(sk, skb); 761 udpv6_queue_rcv_skb(sk, skb);
601 else 762 else if (sk_add_backlog(sk, skb)) {
602 sk_add_backlog(sk, skb); 763 atomic_inc(&sk->sk_drops);
764 bh_unlock_sock(sk);
765 sock_put(sk);
766 goto discard;
767 }
603 bh_unlock_sock(sk); 768 bh_unlock_sock(sk);
604 sock_put(sk); 769 sock_put(sk);
605 return 0; 770 return 0;
@@ -792,7 +957,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
792 if (ipv6_addr_v4mapped(daddr)) { 957 if (ipv6_addr_v4mapped(daddr)) {
793 struct sockaddr_in sin; 958 struct sockaddr_in sin;
794 sin.sin_family = AF_INET; 959 sin.sin_family = AF_INET;
795 sin.sin_port = sin6 ? sin6->sin6_port : inet->dport; 960 sin.sin_port = sin6 ? sin6->sin6_port : inet->inet_dport;
796 sin.sin_addr.s_addr = daddr->s6_addr32[3]; 961 sin.sin_addr.s_addr = daddr->s6_addr32[3];
797 msg->msg_name = &sin; 962 msg->msg_name = &sin;
798 msg->msg_namelen = sizeof(sin); 963 msg->msg_namelen = sizeof(sin);
@@ -865,7 +1030,7 @@ do_udp_sendmsg:
865 if (sk->sk_state != TCP_ESTABLISHED) 1030 if (sk->sk_state != TCP_ESTABLISHED)
866 return -EDESTADDRREQ; 1031 return -EDESTADDRREQ;
867 1032
868 fl.fl_ip_dport = inet->dport; 1033 fl.fl_ip_dport = inet->inet_dport;
869 daddr = &np->daddr; 1034 daddr = &np->daddr;
870 fl.fl6_flowlabel = np->flow_label; 1035 fl.fl6_flowlabel = np->flow_label;
871 connected = 1; 1036 connected = 1;
@@ -877,6 +1042,8 @@ do_udp_sendmsg:
877 if (!fl.oif) 1042 if (!fl.oif)
878 fl.oif = np->sticky_pktinfo.ipi6_ifindex; 1043 fl.oif = np->sticky_pktinfo.ipi6_ifindex;
879 1044
1045 fl.mark = sk->sk_mark;
1046
880 if (msg->msg_controllen) { 1047 if (msg->msg_controllen) {
881 opt = &opt_space; 1048 opt = &opt_space;
882 memset(opt, 0, sizeof(struct ipv6_txoptions)); 1049 memset(opt, 0, sizeof(struct ipv6_txoptions));
@@ -909,7 +1076,7 @@ do_udp_sendmsg:
909 fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ 1076 fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
910 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) 1077 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
911 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 1078 ipv6_addr_copy(&fl.fl6_src, &np->saddr);
912 fl.fl_ip_sport = inet->sport; 1079 fl.fl_ip_sport = inet->inet_sport;
913 1080
914 /* merge ip6_build_xmit from ip6_output */ 1081 /* merge ip6_build_xmit from ip6_output */
915 if (opt && opt->srcrt) { 1082 if (opt && opt->srcrt) {
@@ -1190,10 +1357,10 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
1190 1357
1191 dest = &np->daddr; 1358 dest = &np->daddr;
1192 src = &np->rcv_saddr; 1359 src = &np->rcv_saddr;
1193 destp = ntohs(inet->dport); 1360 destp = ntohs(inet->inet_dport);
1194 srcp = ntohs(inet->sport); 1361 srcp = ntohs(inet->inet_sport);
1195 seq_printf(seq, 1362 seq_printf(seq,
1196 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " 1363 "%5d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
1197 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", 1364 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n",
1198 bucket, 1365 bucket,
1199 src->s6_addr32[0], src->s6_addr32[1], 1366 src->s6_addr32[0], src->s6_addr32[1],
@@ -1236,7 +1403,7 @@ static struct udp_seq_afinfo udp6_seq_afinfo = {
1236 }, 1403 },
1237}; 1404};
1238 1405
1239int udp6_proc_init(struct net *net) 1406int __net_init udp6_proc_init(struct net *net)
1240{ 1407{
1241 return udp_proc_register(net, &udp6_seq_afinfo); 1408 return udp_proc_register(net, &udp6_seq_afinfo);
1242} 1409}
@@ -1282,7 +1449,6 @@ static struct inet_protosw udpv6_protosw = {
1282 .protocol = IPPROTO_UDP, 1449 .protocol = IPPROTO_UDP,
1283 .prot = &udpv6_prot, 1450 .prot = &udpv6_prot,
1284 .ops = &inet6_dgram_ops, 1451 .ops = &inet6_dgram_ops,
1285 .capability =-1,
1286 .no_check = UDP_CSUM_DEFAULT, 1452 .no_check = UDP_CSUM_DEFAULT,
1287 .flags = INET_PROTOSW_PERMANENT, 1453 .flags = INET_PROTOSW_PERMANENT,
1288}; 1454};
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index d737a27ee010..5f48fadc27f7 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -62,7 +62,6 @@ static struct inet_protosw udplite6_protosw = {
62 .protocol = IPPROTO_UDPLITE, 62 .protocol = IPPROTO_UDPLITE,
63 .prot = &udplitev6_prot, 63 .prot = &udplitev6_prot,
64 .ops = &inet6_dgram_ops, 64 .ops = &inet6_dgram_ops,
65 .capability = -1,
66 .no_check = 0, 65 .no_check = 0,
67 .flags = INET_PROTOSW_PERMANENT, 66 .flags = INET_PROTOSW_PERMANENT,
68}; 67};
@@ -105,12 +104,12 @@ static struct udp_seq_afinfo udplite6_seq_afinfo = {
105 }, 104 },
106}; 105};
107 106
108static int udplite6_proc_init_net(struct net *net) 107static int __net_init udplite6_proc_init_net(struct net *net)
109{ 108{
110 return udp_proc_register(net, &udplite6_seq_afinfo); 109 return udp_proc_register(net, &udplite6_seq_afinfo);
111} 110}
112 111
113static void udplite6_proc_exit_net(struct net *net) 112static void __net_exit udplite6_proc_exit_net(struct net *net)
114{ 113{
115 udp_proc_unregister(net, &udplite6_seq_afinfo); 114 udp_proc_unregister(net, &udplite6_seq_afinfo);
116} 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_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 3927832227b9..b809812c8d30 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -5,6 +5,7 @@
5 * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au> 5 * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
6 */ 6 */
7 7
8#include <linux/gfp.h>
8#include <linux/init.h> 9#include <linux/init.h>
9#include <linux/kernel.h> 10#include <linux/kernel.h>
10#include <linux/module.h> 11#include <linux/module.h>
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_policy.c b/net/ipv6/xfrm6_policy.c
index 8ec3d45cd1d9..00bf7c962b7e 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -24,7 +24,6 @@
24#include <net/mip6.h> 24#include <net/mip6.h>
25#endif 25#endif
26 26
27static struct dst_ops xfrm6_dst_ops;
28static struct xfrm_policy_afinfo xfrm6_policy_afinfo; 27static struct xfrm_policy_afinfo xfrm6_policy_afinfo;
29 28
30static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, 29static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos,
@@ -117,14 +116,15 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
117 return 0; 116 return 0;
118} 117}
119 118
120static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) 119static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
120 struct flowi *fl)
121{ 121{
122 struct rt6_info *rt = (struct rt6_info*)xdst->route; 122 struct rt6_info *rt = (struct rt6_info*)xdst->route;
123 123
124 xdst->u.dst.dev = dev; 124 xdst->u.dst.dev = dev;
125 dev_hold(dev); 125 dev_hold(dev);
126 126
127 xdst->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev); 127 xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
128 if (!xdst->u.rt6.rt6i_idev) 128 if (!xdst->u.rt6.rt6i_idev)
129 return -ENODEV; 129 return -ENODEV;
130 130
@@ -224,8 +224,10 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
224 224
225static inline int xfrm6_garbage_collect(struct dst_ops *ops) 225static inline int xfrm6_garbage_collect(struct dst_ops *ops)
226{ 226{
227 xfrm6_policy_afinfo.garbage_collect(&init_net); 227 struct net *net = container_of(ops, struct net, xfrm.xfrm6_dst_ops);
228 return (atomic_read(&xfrm6_dst_ops.entries) > xfrm6_dst_ops.gc_thresh*2); 228
229 xfrm6_policy_afinfo.garbage_collect(net);
230 return (atomic_read(&ops->entries) > ops->gc_thresh * 2);
229} 231}
230 232
231static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) 233static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -309,9 +311,8 @@ static void xfrm6_policy_fini(void)
309#ifdef CONFIG_SYSCTL 311#ifdef CONFIG_SYSCTL
310static struct ctl_table xfrm6_policy_table[] = { 312static struct ctl_table xfrm6_policy_table[] = {
311 { 313 {
312 .ctl_name = CTL_UNNUMBERED,
313 .procname = "xfrm6_gc_thresh", 314 .procname = "xfrm6_gc_thresh",
314 .data = &xfrm6_dst_ops.gc_thresh, 315 .data = &init_net.xfrm.xfrm6_dst_ops.gc_thresh,
315 .maxlen = sizeof(int), 316 .maxlen = sizeof(int),
316 .mode = 0644, 317 .mode = 0644,
317 .proc_handler = proc_dointvec, 318 .proc_handler = proc_dointvec,
@@ -327,13 +328,6 @@ int __init xfrm6_init(void)
327 int ret; 328 int ret;
328 unsigned int gc_thresh; 329 unsigned int gc_thresh;
329 330
330 ret = xfrm6_policy_init();
331 if (ret)
332 goto out;
333
334 ret = xfrm6_state_init();
335 if (ret)
336 goto out_policy;
337 /* 331 /*
338 * We need a good default value for the xfrm6 gc threshold. 332 * We need a good default value for the xfrm6 gc threshold.
339 * In ipv4 we set it to the route hash table size * 8, which 333 * In ipv4 we set it to the route hash table size * 8, which
@@ -347,6 +341,15 @@ int __init xfrm6_init(void)
347 */ 341 */
348 gc_thresh = FIB6_TABLE_HASHSZ * 8; 342 gc_thresh = FIB6_TABLE_HASHSZ * 8;
349 xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh; 343 xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh;
344
345 ret = xfrm6_policy_init();
346 if (ret)
347 goto out;
348
349 ret = xfrm6_state_init();
350 if (ret)
351 goto out_policy;
352
350#ifdef CONFIG_SYSCTL 353#ifdef CONFIG_SYSCTL
351 sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv6_ctl_path, 354 sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv6_ctl_path,
352 xfrm6_policy_table); 355 xfrm6_policy_table);
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 81a95c00e503..2ce3a8278f26 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -23,41 +23,51 @@
23 */ 23 */
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/xfrm.h> 25#include <linux/xfrm.h>
26#include <linux/list.h> 26#include <linux/slab.h>
27#include <linux/rculist.h>
27#include <net/ip.h> 28#include <net/ip.h>
28#include <net/xfrm.h> 29#include <net/xfrm.h>
29#include <net/ipv6.h> 30#include <net/ipv6.h>
30#include <linux/ipv6.h> 31#include <linux/ipv6.h>
31#include <linux/icmpv6.h> 32#include <linux/icmpv6.h>
32#include <linux/mutex.h> 33#include <linux/mutex.h>
34#include <net/netns/generic.h>
35
36#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
37#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256
38
39#define XFRM6_TUNNEL_SPI_MIN 1
40#define XFRM6_TUNNEL_SPI_MAX 0xffffffff
41
42struct xfrm6_tunnel_net {
43 struct hlist_head spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
44 struct hlist_head spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
45 u32 spi;
46};
47
48static int xfrm6_tunnel_net_id __read_mostly;
49static inline struct xfrm6_tunnel_net *xfrm6_tunnel_pernet(struct net *net)
50{
51 return net_generic(net, xfrm6_tunnel_net_id);
52}
33 53
34/* 54/*
35 * xfrm_tunnel_spi things are for allocating unique id ("spi") 55 * xfrm_tunnel_spi things are for allocating unique id ("spi")
36 * per xfrm_address_t. 56 * per xfrm_address_t.
37 */ 57 */
38struct xfrm6_tunnel_spi { 58struct xfrm6_tunnel_spi {
39 struct hlist_node list_byaddr; 59 struct hlist_node list_byaddr;
40 struct hlist_node list_byspi; 60 struct hlist_node list_byspi;
41 xfrm_address_t addr; 61 xfrm_address_t addr;
42 u32 spi; 62 u32 spi;
43 atomic_t refcnt; 63 atomic_t refcnt;
64 struct rcu_head rcu_head;
44}; 65};
45 66
46static DEFINE_RWLOCK(xfrm6_tunnel_spi_lock); 67static DEFINE_SPINLOCK(xfrm6_tunnel_spi_lock);
47
48static u32 xfrm6_tunnel_spi;
49
50#define XFRM6_TUNNEL_SPI_MIN 1
51#define XFRM6_TUNNEL_SPI_MAX 0xffffffff
52 68
53static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly; 69static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly;
54 70
55#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
56#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256
57
58static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
59static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
60
61static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr) 71static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
62{ 72{
63 unsigned h; 73 unsigned h;
@@ -75,49 +85,14 @@ static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi)
75 return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE; 85 return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
76} 86}
77 87
78 88static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr)
79static int xfrm6_tunnel_spi_init(void)
80{
81 int i;
82
83 xfrm6_tunnel_spi = 0;
84 xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
85 sizeof(struct xfrm6_tunnel_spi),
86 0, SLAB_HWCACHE_ALIGN,
87 NULL);
88 if (!xfrm6_tunnel_spi_kmem)
89 return -ENOMEM;
90
91 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
92 INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byaddr[i]);
93 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++)
94 INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byspi[i]);
95 return 0;
96}
97
98static void xfrm6_tunnel_spi_fini(void)
99{
100 int i;
101
102 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) {
103 if (!hlist_empty(&xfrm6_tunnel_spi_byaddr[i]))
104 return;
105 }
106 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++) {
107 if (!hlist_empty(&xfrm6_tunnel_spi_byspi[i]))
108 return;
109 }
110 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
111 xfrm6_tunnel_spi_kmem = NULL;
112}
113
114static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
115{ 89{
90 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
116 struct xfrm6_tunnel_spi *x6spi; 91 struct xfrm6_tunnel_spi *x6spi;
117 struct hlist_node *pos; 92 struct hlist_node *pos;
118 93
119 hlist_for_each_entry(x6spi, pos, 94 hlist_for_each_entry_rcu(x6spi, pos,
120 &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)], 95 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
121 list_byaddr) { 96 list_byaddr) {
122 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) 97 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0)
123 return x6spi; 98 return x6spi;
@@ -126,28 +101,29 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
126 return NULL; 101 return NULL;
127} 102}
128 103
129__be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) 104__be32 xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr)
130{ 105{
131 struct xfrm6_tunnel_spi *x6spi; 106 struct xfrm6_tunnel_spi *x6spi;
132 u32 spi; 107 u32 spi;
133 108
134 read_lock_bh(&xfrm6_tunnel_spi_lock); 109 rcu_read_lock_bh();
135 x6spi = __xfrm6_tunnel_spi_lookup(saddr); 110 x6spi = __xfrm6_tunnel_spi_lookup(net, saddr);
136 spi = x6spi ? x6spi->spi : 0; 111 spi = x6spi ? x6spi->spi : 0;
137 read_unlock_bh(&xfrm6_tunnel_spi_lock); 112 rcu_read_unlock_bh();
138 return htonl(spi); 113 return htonl(spi);
139} 114}
140 115
141EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); 116EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup);
142 117
143static int __xfrm6_tunnel_spi_check(u32 spi) 118static int __xfrm6_tunnel_spi_check(struct net *net, u32 spi)
144{ 119{
120 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
145 struct xfrm6_tunnel_spi *x6spi; 121 struct xfrm6_tunnel_spi *x6spi;
146 int index = xfrm6_tunnel_spi_hash_byspi(spi); 122 int index = xfrm6_tunnel_spi_hash_byspi(spi);
147 struct hlist_node *pos; 123 struct hlist_node *pos;
148 124
149 hlist_for_each_entry(x6spi, pos, 125 hlist_for_each_entry(x6spi, pos,
150 &xfrm6_tunnel_spi_byspi[index], 126 &xfrm6_tn->spi_byspi[index],
151 list_byspi) { 127 list_byspi) {
152 if (x6spi->spi == spi) 128 if (x6spi->spi == spi)
153 return -1; 129 return -1;
@@ -155,32 +131,33 @@ static int __xfrm6_tunnel_spi_check(u32 spi)
155 return index; 131 return index;
156} 132}
157 133
158static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) 134static u32 __xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr)
159{ 135{
136 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
160 u32 spi; 137 u32 spi;
161 struct xfrm6_tunnel_spi *x6spi; 138 struct xfrm6_tunnel_spi *x6spi;
162 int index; 139 int index;
163 140
164 if (xfrm6_tunnel_spi < XFRM6_TUNNEL_SPI_MIN || 141 if (xfrm6_tn->spi < XFRM6_TUNNEL_SPI_MIN ||
165 xfrm6_tunnel_spi >= XFRM6_TUNNEL_SPI_MAX) 142 xfrm6_tn->spi >= XFRM6_TUNNEL_SPI_MAX)
166 xfrm6_tunnel_spi = XFRM6_TUNNEL_SPI_MIN; 143 xfrm6_tn->spi = XFRM6_TUNNEL_SPI_MIN;
167 else 144 else
168 xfrm6_tunnel_spi++; 145 xfrm6_tn->spi++;
169 146
170 for (spi = xfrm6_tunnel_spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) { 147 for (spi = xfrm6_tn->spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) {
171 index = __xfrm6_tunnel_spi_check(spi); 148 index = __xfrm6_tunnel_spi_check(net, spi);
172 if (index >= 0) 149 if (index >= 0)
173 goto alloc_spi; 150 goto alloc_spi;
174 } 151 }
175 for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tunnel_spi; spi++) { 152 for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tn->spi; spi++) {
176 index = __xfrm6_tunnel_spi_check(spi); 153 index = __xfrm6_tunnel_spi_check(net, spi);
177 if (index >= 0) 154 if (index >= 0)
178 goto alloc_spi; 155 goto alloc_spi;
179 } 156 }
180 spi = 0; 157 spi = 0;
181 goto out; 158 goto out;
182alloc_spi: 159alloc_spi:
183 xfrm6_tunnel_spi = spi; 160 xfrm6_tn->spi = spi;
184 x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC); 161 x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC);
185 if (!x6spi) 162 if (!x6spi)
186 goto out; 163 goto out;
@@ -189,54 +166,61 @@ alloc_spi:
189 x6spi->spi = spi; 166 x6spi->spi = spi;
190 atomic_set(&x6spi->refcnt, 1); 167 atomic_set(&x6spi->refcnt, 1);
191 168
192 hlist_add_head(&x6spi->list_byspi, &xfrm6_tunnel_spi_byspi[index]); 169 hlist_add_head_rcu(&x6spi->list_byspi, &xfrm6_tn->spi_byspi[index]);
193 170
194 index = xfrm6_tunnel_spi_hash_byaddr(saddr); 171 index = xfrm6_tunnel_spi_hash_byaddr(saddr);
195 hlist_add_head(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]); 172 hlist_add_head_rcu(&x6spi->list_byaddr, &xfrm6_tn->spi_byaddr[index]);
196out: 173out:
197 return spi; 174 return spi;
198} 175}
199 176
200__be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) 177__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr)
201{ 178{
202 struct xfrm6_tunnel_spi *x6spi; 179 struct xfrm6_tunnel_spi *x6spi;
203 u32 spi; 180 u32 spi;
204 181
205 write_lock_bh(&xfrm6_tunnel_spi_lock); 182 spin_lock_bh(&xfrm6_tunnel_spi_lock);
206 x6spi = __xfrm6_tunnel_spi_lookup(saddr); 183 x6spi = __xfrm6_tunnel_spi_lookup(net, saddr);
207 if (x6spi) { 184 if (x6spi) {
208 atomic_inc(&x6spi->refcnt); 185 atomic_inc(&x6spi->refcnt);
209 spi = x6spi->spi; 186 spi = x6spi->spi;
210 } else 187 } else
211 spi = __xfrm6_tunnel_alloc_spi(saddr); 188 spi = __xfrm6_tunnel_alloc_spi(net, saddr);
212 write_unlock_bh(&xfrm6_tunnel_spi_lock); 189 spin_unlock_bh(&xfrm6_tunnel_spi_lock);
213 190
214 return htonl(spi); 191 return htonl(spi);
215} 192}
216 193
217EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi); 194EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi);
218 195
219void xfrm6_tunnel_free_spi(xfrm_address_t *saddr) 196static void x6spi_destroy_rcu(struct rcu_head *head)
197{
198 kmem_cache_free(xfrm6_tunnel_spi_kmem,
199 container_of(head, struct xfrm6_tunnel_spi, rcu_head));
200}
201
202void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr)
220{ 203{
204 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
221 struct xfrm6_tunnel_spi *x6spi; 205 struct xfrm6_tunnel_spi *x6spi;
222 struct hlist_node *pos, *n; 206 struct hlist_node *pos, *n;
223 207
224 write_lock_bh(&xfrm6_tunnel_spi_lock); 208 spin_lock_bh(&xfrm6_tunnel_spi_lock);
225 209
226 hlist_for_each_entry_safe(x6spi, pos, n, 210 hlist_for_each_entry_safe(x6spi, pos, n,
227 &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)], 211 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
228 list_byaddr) 212 list_byaddr)
229 { 213 {
230 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) { 214 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
231 if (atomic_dec_and_test(&x6spi->refcnt)) { 215 if (atomic_dec_and_test(&x6spi->refcnt)) {
232 hlist_del(&x6spi->list_byaddr); 216 hlist_del_rcu(&x6spi->list_byaddr);
233 hlist_del(&x6spi->list_byspi); 217 hlist_del_rcu(&x6spi->list_byspi);
234 kmem_cache_free(xfrm6_tunnel_spi_kmem, x6spi); 218 call_rcu(&x6spi->rcu_head, x6spi_destroy_rcu);
235 break; 219 break;
236 } 220 }
237 } 221 }
238 } 222 }
239 write_unlock_bh(&xfrm6_tunnel_spi_lock); 223 spin_unlock_bh(&xfrm6_tunnel_spi_lock);
240} 224}
241 225
242EXPORT_SYMBOL(xfrm6_tunnel_free_spi); 226EXPORT_SYMBOL(xfrm6_tunnel_free_spi);
@@ -254,10 +238,11 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
254 238
255static int xfrm6_tunnel_rcv(struct sk_buff *skb) 239static int xfrm6_tunnel_rcv(struct sk_buff *skb)
256{ 240{
241 struct net *net = dev_net(skb->dev);
257 struct ipv6hdr *iph = ipv6_hdr(skb); 242 struct ipv6hdr *iph = ipv6_hdr(skb);
258 __be32 spi; 243 __be32 spi;
259 244
260 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); 245 spi = xfrm6_tunnel_spi_lookup(net, (xfrm_address_t *)&iph->saddr);
261 return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0; 246 return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0;
262} 247}
263 248
@@ -317,7 +302,9 @@ static int xfrm6_tunnel_init_state(struct xfrm_state *x)
317 302
318static void xfrm6_tunnel_destroy(struct xfrm_state *x) 303static void xfrm6_tunnel_destroy(struct xfrm_state *x)
319{ 304{
320 xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr); 305 struct net *net = xs_net(x);
306
307 xfrm6_tunnel_free_spi(net, (xfrm_address_t *)&x->props.saddr);
321} 308}
322 309
323static const struct xfrm_type xfrm6_tunnel_type = { 310static const struct xfrm_type xfrm6_tunnel_type = {
@@ -342,34 +329,73 @@ static struct xfrm6_tunnel xfrm46_tunnel_handler = {
342 .priority = 2, 329 .priority = 2,
343}; 330};
344 331
332static int __net_init xfrm6_tunnel_net_init(struct net *net)
333{
334 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
335 unsigned int i;
336
337 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
338 INIT_HLIST_HEAD(&xfrm6_tn->spi_byaddr[i]);
339 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++)
340 INIT_HLIST_HEAD(&xfrm6_tn->spi_byspi[i]);
341 xfrm6_tn->spi = 0;
342
343 return 0;
344}
345
346static void __net_exit xfrm6_tunnel_net_exit(struct net *net)
347{
348}
349
350static struct pernet_operations xfrm6_tunnel_net_ops = {
351 .init = xfrm6_tunnel_net_init,
352 .exit = xfrm6_tunnel_net_exit,
353 .id = &xfrm6_tunnel_net_id,
354 .size = sizeof(struct xfrm6_tunnel_net),
355};
356
345static int __init xfrm6_tunnel_init(void) 357static int __init xfrm6_tunnel_init(void)
346{ 358{
347 if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) 359 int rv;
348 goto err; 360
349 if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) 361 xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
350 goto unreg; 362 sizeof(struct xfrm6_tunnel_spi),
351 if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) 363 0, SLAB_HWCACHE_ALIGN,
352 goto dereg6; 364 NULL);
353 if (xfrm6_tunnel_spi_init() < 0) 365 if (!xfrm6_tunnel_spi_kmem)
354 goto dereg46; 366 return -ENOMEM;
367 rv = register_pernet_subsys(&xfrm6_tunnel_net_ops);
368 if (rv < 0)
369 goto out_pernet;
370 rv = xfrm_register_type(&xfrm6_tunnel_type, AF_INET6);
371 if (rv < 0)
372 goto out_type;
373 rv = xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6);
374 if (rv < 0)
375 goto out_xfrm6;
376 rv = xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET);
377 if (rv < 0)
378 goto out_xfrm46;
355 return 0; 379 return 0;
356 380
357dereg46: 381out_xfrm46:
358 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
359dereg6:
360 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); 382 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
361unreg: 383out_xfrm6:
362 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 384 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
363err: 385out_type:
364 return -EAGAIN; 386 unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
387out_pernet:
388 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
389 return rv;
365} 390}
366 391
367static void __exit xfrm6_tunnel_fini(void) 392static void __exit xfrm6_tunnel_fini(void)
368{ 393{
369 xfrm6_tunnel_spi_fini();
370 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET); 394 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
371 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); 395 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
372 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 396 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
397 unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
398 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
373} 399}
374 400
375module_init(xfrm6_tunnel_init); 401module_init(xfrm6_tunnel_init);