aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-02-10 08:17:10 -0500
committerPatrick McHardy <kaber@trash.net>2010-02-10 08:17:10 -0500
commit9ab99d5a43e9f283738fd9fd365539306d13eaac (patch)
tree0214a63e3f4f7f4f187f0139e4a5d8abe453902b /net/ipv6
parent76780373190d7e8ddfb6fed06aef068e2445c743 (diff)
parentb1109bf085c8dd69537b7876ea83f914dd1fe46a (diff)
Merge branch 'master' of /repos/git/net-next-2.6
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c8
-rw-r--r--net/ipv6/af_inet6.c4
-rw-r--r--net/ipv6/anycast.c2
-rw-r--r--net/ipv6/exthdrs.c7
-rw-r--r--net/ipv6/fib6_rules.c4
-rw-r--r--net/ipv6/icmp.c2
-rw-r--r--net/ipv6/ip6_fib.c6
-rw-r--r--net/ipv6/ip6_flowlabel.c9
-rw-r--r--net/ipv6/ip6_output.c3
-rw-r--r--net/ipv6/ip6_tunnel.c9
-rw-r--r--net/ipv6/ipcomp6.c13
-rw-r--r--net/ipv6/mcast.c13
-rw-r--r--net/ipv6/ndisc.c4
-rw-r--r--net/ipv6/netfilter/ip6_tables.c4
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c1
-rw-r--r--net/ipv6/proc.c18
-rw-r--r--net/ipv6/raw.c4
-rw-r--r--net/ipv6/reassembly.c8
-rw-r--r--net/ipv6/route.c6
-rw-r--r--net/ipv6/sit.c9
-rw-r--r--net/ipv6/sysctl_net_ipv6.c4
-rw-r--r--net/ipv6/tcp_ipv6.c22
-rw-r--r--net/ipv6/udp.c2
-rw-r--r--net/ipv6/udplite.c4
-rw-r--r--net/ipv6/xfrm6_policy.c25
-rw-r--r--net/ipv6/xfrm6_tunnel.c156
26 files changed, 197 insertions, 150 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index de7a194a64ab..1593289155ff 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3027,14 +3027,14 @@ static const struct file_operations if6_fops = {
3027 .release = seq_release_net, 3027 .release = seq_release_net,
3028}; 3028};
3029 3029
3030static int if6_proc_net_init(struct net *net) 3030static int __net_init if6_proc_net_init(struct net *net)
3031{ 3031{
3032 if (!proc_net_fops_create(net, "if_inet6", S_IRUGO, &if6_fops)) 3032 if (!proc_net_fops_create(net, "if_inet6", S_IRUGO, &if6_fops))
3033 return -ENOMEM; 3033 return -ENOMEM;
3034 return 0; 3034 return 0;
3035} 3035}
3036 3036
3037static void if6_proc_net_exit(struct net *net) 3037static void __net_exit if6_proc_net_exit(struct net *net)
3038{ 3038{
3039 proc_net_remove(net, "if_inet6"); 3039 proc_net_remove(net, "if_inet6");
3040} 3040}
@@ -4418,7 +4418,7 @@ static void addrconf_sysctl_unregister(struct inet6_dev *idev)
4418 4418
4419#endif 4419#endif
4420 4420
4421static int addrconf_init_net(struct net *net) 4421static int __net_init addrconf_init_net(struct net *net)
4422{ 4422{
4423 int err; 4423 int err;
4424 struct ipv6_devconf *all, *dflt; 4424 struct ipv6_devconf *all, *dflt;
@@ -4467,7 +4467,7 @@ err_alloc_all:
4467 return err; 4467 return err;
4468} 4468}
4469 4469
4470static void addrconf_exit_net(struct net *net) 4470static void __net_exit addrconf_exit_net(struct net *net)
4471{ 4471{
4472#ifdef CONFIG_SYSCTL 4472#ifdef CONFIG_SYSCTL
4473 __addrconf_sysctl_unregister(net->ipv6.devconf_dflt); 4473 __addrconf_sysctl_unregister(net->ipv6.devconf_dflt);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 12e69d364dd5..e29160ff4a0f 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -999,7 +999,7 @@ err_udplite_mib:
999 return -ENOMEM; 999 return -ENOMEM;
1000} 1000}
1001 1001
1002static void __net_exit ipv6_cleanup_mibs(struct net *net) 1002static void ipv6_cleanup_mibs(struct net *net)
1003{ 1003{
1004 snmp_mib_free((void **)net->mib.udp_stats_in6); 1004 snmp_mib_free((void **)net->mib.udp_stats_in6);
1005 snmp_mib_free((void **)net->mib.udplite_stats_in6); 1005 snmp_mib_free((void **)net->mib.udplite_stats_in6);
@@ -1042,7 +1042,7 @@ out:
1042#endif 1042#endif
1043} 1043}
1044 1044
1045static void inet6_net_exit(struct net *net) 1045static void __net_exit inet6_net_exit(struct net *net)
1046{ 1046{
1047#ifdef CONFIG_PROC_FS 1047#ifdef CONFIG_PROC_FS
1048 udp6_proc_exit(net); 1048 udp6_proc_exit(net);
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index f1c74c8ef9de..c4f6ca32fa74 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -538,7 +538,7 @@ static const struct file_operations ac6_seq_fops = {
538 .release = seq_release_net, 538 .release = seq_release_net,
539}; 539};
540 540
541int ac6_proc_init(struct net *net) 541int __net_init ac6_proc_init(struct net *net)
542{ 542{
543 if (!proc_net_fops_create(net, "anycast6", S_IRUGO, &ac6_seq_fops)) 543 if (!proc_net_fops_create(net, "anycast6", S_IRUGO, &ac6_seq_fops))
544 return -ENOMEM; 544 return -ENOMEM;
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index df159fffe4bc..4bac362b1335 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -559,6 +559,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); 559 return skb_dst(skb) ? ip6_dst_idev(skb_dst(skb)) : __in6_dev_get(skb->dev);
560} 560}
561 561
562static inline struct net *ipv6_skb_net(struct sk_buff *skb)
563{
564 return skb_dst(skb) ? dev_net(skb_dst(skb)->dev) : dev_net(skb->dev);
565}
566
562/* Router Alert as of RFC 2711 */ 567/* Router Alert as of RFC 2711 */
563 568
564static int ipv6_hop_ra(struct sk_buff *skb, int optoff) 569static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
@@ -580,8 +585,8 @@ static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
580static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff) 585static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
581{ 586{
582 const unsigned char *nh = skb_network_header(skb); 587 const unsigned char *nh = skb_network_header(skb);
588 struct net *net = ipv6_skb_net(skb);
583 u32 pkt_len; 589 u32 pkt_len;
584 struct net *net = dev_net(skb_dst(skb)->dev);
585 590
586 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { 591 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
587 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", 592 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 b7aa7c64cc4a..551882b9dfd6 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -262,7 +262,7 @@ static struct fib_rules_ops fib6_rules_ops_template = {
262 .fro_net = &init_net, 262 .fro_net = &init_net,
263}; 263};
264 264
265static int fib6_rules_net_init(struct net *net) 265static int __net_init fib6_rules_net_init(struct net *net)
266{ 266{
267 struct fib_rules_ops *ops; 267 struct fib_rules_ops *ops;
268 int err = -ENOMEM; 268 int err = -ENOMEM;
@@ -291,7 +291,7 @@ out_fib6_rules_ops:
291 goto out; 291 goto out;
292} 292}
293 293
294static void fib6_rules_net_exit(struct net *net) 294static void __net_exit fib6_rules_net_exit(struct net *net)
295{ 295{
296 fib_rules_unregister(net->ipv6.fib6_rules_ops); 296 fib_rules_unregister(net->ipv6.fib6_rules_ops);
297} 297}
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 4ae661bc3677..217dbc2e28d4 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -951,7 +951,7 @@ ctl_table ipv6_icmp_table_template[] = {
951 { }, 951 { },
952}; 952};
953 953
954struct ctl_table *ipv6_icmp_sysctl_init(struct net *net) 954struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
955{ 955{
956 struct ctl_table *table; 956 struct ctl_table *table;
957 957
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 0e93ca56eb69..f626ea2b304f 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -239,7 +239,7 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id)
239 return NULL; 239 return NULL;
240} 240}
241 241
242static void fib6_tables_init(struct net *net) 242static void __net_init fib6_tables_init(struct net *net)
243{ 243{
244 fib6_link_table(net, net->ipv6.fib6_main_tbl); 244 fib6_link_table(net, net->ipv6.fib6_main_tbl);
245 fib6_link_table(net, net->ipv6.fib6_local_tbl); 245 fib6_link_table(net, net->ipv6.fib6_local_tbl);
@@ -262,7 +262,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); 262 return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl, flags);
263} 263}
264 264
265static void fib6_tables_init(struct net *net) 265static void __net_init fib6_tables_init(struct net *net)
266{ 266{
267 fib6_link_table(net, net->ipv6.fib6_main_tbl); 267 fib6_link_table(net, net->ipv6.fib6_main_tbl);
268} 268}
@@ -1469,7 +1469,7 @@ static void fib6_gc_timer_cb(unsigned long arg)
1469 fib6_run_gc(0, (struct net *)arg); 1469 fib6_run_gc(0, (struct net *)arg);
1470} 1470}
1471 1471
1472static int fib6_net_init(struct net *net) 1472static int __net_init fib6_net_init(struct net *net)
1473{ 1473{
1474 setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net); 1474 setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net);
1475 1475
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 6e7bffa2205e..e41eba8aacf1 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -154,7 +154,7 @@ static void ip6_fl_gc(unsigned long dummy)
154 write_unlock(&ip6_fl_lock); 154 write_unlock(&ip6_fl_lock);
155} 155}
156 156
157static void ip6_fl_purge(struct net *net) 157static void __net_exit ip6_fl_purge(struct net *net)
158{ 158{
159 int i; 159 int i;
160 160
@@ -735,7 +735,7 @@ static const struct file_operations ip6fl_seq_fops = {
735 .release = seq_release_net, 735 .release = seq_release_net,
736}; 736};
737 737
738static int ip6_flowlabel_proc_init(struct net *net) 738static int __net_init ip6_flowlabel_proc_init(struct net *net)
739{ 739{
740 if (!proc_net_fops_create(net, "ip6_flowlabel", 740 if (!proc_net_fops_create(net, "ip6_flowlabel",
741 S_IRUGO, &ip6fl_seq_fops)) 741 S_IRUGO, &ip6fl_seq_fops))
@@ -743,7 +743,7 @@ static int ip6_flowlabel_proc_init(struct net *net)
743 return 0; 743 return 0;
744} 744}
745 745
746static void ip6_flowlabel_proc_fini(struct net *net) 746static void __net_exit ip6_flowlabel_proc_fini(struct net *net)
747{ 747{
748 proc_net_remove(net, "ip6_flowlabel"); 748 proc_net_remove(net, "ip6_flowlabel");
749} 749}
@@ -754,11 +754,10 @@ static inline int ip6_flowlabel_proc_init(struct net *net)
754} 754}
755static inline void ip6_flowlabel_proc_fini(struct net *net) 755static inline void ip6_flowlabel_proc_fini(struct net *net)
756{ 756{
757 return ;
758} 757}
759#endif 758#endif
760 759
761static inline void ip6_flowlabel_net_exit(struct net *net) 760static void __net_exit ip6_flowlabel_net_exit(struct net *net)
762{ 761{
763 ip6_fl_purge(net); 762 ip6_fl_purge(net);
764 ip6_flowlabel_proc_fini(net); 763 ip6_flowlabel_proc_fini(net);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index cd48801a8d6f..eb6d09728633 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -121,10 +121,9 @@ static int ip6_output2(struct sk_buff *skb)
121 skb->dev = dev; 121 skb->dev = dev;
122 122
123 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) { 123 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)); 124 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
126 125
127 if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && 126 if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(skb->sk) &&
128 ((mroute6_socket(dev_net(dev)) && 127 ((mroute6_socket(dev_net(dev)) &&
129 !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || 128 !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) ||
130 ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr, 129 ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index d453d07b0dfe..fbd786981aa9 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -74,7 +74,6 @@ MODULE_LICENSE("GPL");
74 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ 74 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \
75 (HASH_SIZE - 1)) 75 (HASH_SIZE - 1))
76 76
77static void ip6_fb_tnl_dev_init(struct net_device *dev);
78static void ip6_tnl_dev_init(struct net_device *dev); 77static void ip6_tnl_dev_init(struct net_device *dev);
79static void ip6_tnl_dev_setup(struct net_device *dev); 78static void ip6_tnl_dev_setup(struct net_device *dev);
80 79
@@ -1364,7 +1363,7 @@ static void ip6_tnl_dev_init(struct net_device *dev)
1364 * Return: 0 1363 * Return: 0
1365 **/ 1364 **/
1366 1365
1367static void ip6_fb_tnl_dev_init(struct net_device *dev) 1366static void __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
1368{ 1367{
1369 struct ip6_tnl *t = netdev_priv(dev); 1368 struct ip6_tnl *t = netdev_priv(dev);
1370 struct net *net = dev_net(dev); 1369 struct net *net = dev_net(dev);
@@ -1388,7 +1387,7 @@ static struct xfrm6_tunnel ip6ip6_handler = {
1388 .priority = 1, 1387 .priority = 1,
1389}; 1388};
1390 1389
1391static void ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n) 1390static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
1392{ 1391{
1393 int h; 1392 int h;
1394 struct ip6_tnl *t; 1393 struct ip6_tnl *t;
@@ -1407,7 +1406,7 @@ static void ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
1407 unregister_netdevice_many(&list); 1406 unregister_netdevice_many(&list);
1408} 1407}
1409 1408
1410static int ip6_tnl_init_net(struct net *net) 1409static int __net_init ip6_tnl_init_net(struct net *net)
1411{ 1410{
1412 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 1411 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1413 int err; 1412 int err;
@@ -1436,7 +1435,7 @@ err_alloc_dev:
1436 return err; 1435 return err;
1437} 1436}
1438 1437
1439static void ip6_tnl_exit_net(struct net *net) 1438static void __net_exit ip6_tnl_exit_net(struct net *net)
1440{ 1439{
1441 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 1440 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1442 1441
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 2f2a5ca2c878..a9fbb151bb79 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, (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
@@ -108,13 +110,14 @@ error:
108 110
109static int ipcomp6_tunnel_attach(struct xfrm_state *x) 111static int ipcomp6_tunnel_attach(struct xfrm_state *x)
110{ 112{
113 struct net *net = xs_net(x);
111 int err = 0; 114 int err = 0;
112 struct xfrm_state *t = NULL; 115 struct xfrm_state *t = NULL;
113 __be32 spi; 116 __be32 spi;
114 117
115 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr); 118 spi = xfrm6_tunnel_spi_lookup(net, (xfrm_address_t *)&x->props.saddr);
116 if (spi) 119 if (spi)
117 t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr, 120 t = xfrm_state_lookup(net, (xfrm_address_t *)&x->id.daddr,
118 spi, IPPROTO_IPV6, AF_INET6); 121 spi, IPPROTO_IPV6, AF_INET6);
119 if (!t) { 122 if (!t) {
120 t = ipcomp6_tunnel_create(x); 123 t = ipcomp6_tunnel_create(x);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 1f9c44442e65..25f6cca79e6b 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -2646,7 +2646,7 @@ static const struct file_operations igmp6_mcf_seq_fops = {
2646 .release = seq_release_net, 2646 .release = seq_release_net,
2647}; 2647};
2648 2648
2649static int igmp6_proc_init(struct net *net) 2649static int __net_init igmp6_proc_init(struct net *net)
2650{ 2650{
2651 int err; 2651 int err;
2652 2652
@@ -2666,23 +2666,22 @@ out_proc_net_igmp6:
2666 goto out; 2666 goto out;
2667} 2667}
2668 2668
2669static void igmp6_proc_exit(struct net *net) 2669static void __net_exit igmp6_proc_exit(struct net *net)
2670{ 2670{
2671 proc_net_remove(net, "mcfilter6"); 2671 proc_net_remove(net, "mcfilter6");
2672 proc_net_remove(net, "igmp6"); 2672 proc_net_remove(net, "igmp6");
2673} 2673}
2674#else 2674#else
2675static int igmp6_proc_init(struct net *net) 2675static inline int igmp6_proc_init(struct net *net)
2676{ 2676{
2677 return 0; 2677 return 0;
2678} 2678}
2679static void igmp6_proc_exit(struct net *net) 2679static inline void igmp6_proc_exit(struct net *net)
2680{ 2680{
2681 ;
2682} 2681}
2683#endif 2682#endif
2684 2683
2685static int igmp6_net_init(struct net *net) 2684static int __net_init igmp6_net_init(struct net *net)
2686{ 2685{
2687 int err; 2686 int err;
2688 2687
@@ -2708,7 +2707,7 @@ out_sock_create:
2708 goto out; 2707 goto out;
2709} 2708}
2710 2709
2711static void igmp6_net_exit(struct net *net) 2710static void __net_exit igmp6_net_exit(struct net *net)
2712{ 2711{
2713 inet_ctl_sock_destroy(net->ipv6.igmp_sk); 2712 inet_ctl_sock_destroy(net->ipv6.igmp_sk);
2714 igmp6_proc_exit(net); 2713 igmp6_proc_exit(net);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index c45852798092..2dfec6bb8ada 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1772,7 +1772,7 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, void __user *bu
1772 1772
1773#endif 1773#endif
1774 1774
1775static int ndisc_net_init(struct net *net) 1775static int __net_init ndisc_net_init(struct net *net)
1776{ 1776{
1777 struct ipv6_pinfo *np; 1777 struct ipv6_pinfo *np;
1778 struct sock *sk; 1778 struct sock *sk;
@@ -1797,7 +1797,7 @@ static int ndisc_net_init(struct net *net)
1797 return 0; 1797 return 0;
1798} 1798}
1799 1799
1800static void ndisc_net_exit(struct net *net) 1800static void __net_exit ndisc_net_exit(struct net *net)
1801{ 1801{
1802 inet_ctl_sock_destroy(net->ipv6.ndisc_sk); 1802 inet_ctl_sock_destroy(net->ipv6.ndisc_sk);
1803} 1803}
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 0376ed6d5594..4332f4591482 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1169,10 +1169,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
1169 if (t && !IS_ERR(t)) { 1169 if (t && !IS_ERR(t)) {
1170 struct ip6t_getinfo info; 1170 struct ip6t_getinfo info;
1171 const struct xt_table_info *private = t->private; 1171 const struct xt_table_info *private = t->private;
1172
1173#ifdef CONFIG_COMPAT 1172#ifdef CONFIG_COMPAT
1173 struct xt_table_info tmp;
1174
1174 if (compat) { 1175 if (compat) {
1175 struct xt_table_info tmp;
1176 ret = compat_table_info(private, &tmp); 1176 ret = compat_table_info(private, &tmp);
1177 xt_compat_flush_offsets(AF_INET6); 1177 xt_compat_flush_offsets(AF_INET6);
1178 private = &tmp; 1178 private = &tmp;
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 744ea49de356..ad1fcda6898b 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -60,6 +60,7 @@ struct nf_ct_frag6_queue
60 struct inet_frag_queue q; 60 struct inet_frag_queue q;
61 61
62 __be32 id; /* fragment id */ 62 __be32 id; /* fragment id */
63 u32 user;
63 struct in6_addr saddr; 64 struct in6_addr saddr;
64 struct in6_addr daddr; 65 struct in6_addr daddr;
65 66
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index c9605c3ad91f..bfe2598dd563 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),
@@ -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 **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++)
@@ -259,7 +259,7 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
259 struct net *net = dev_net(idev->dev); 259 struct net *net = dev_net(idev->dev);
260 if (!net->mib.proc_net_devsnmp6) 260 if (!net->mib.proc_net_devsnmp6)
261 return -ENOENT; 261 return -ENOENT;
262 if (!idev || !idev->stats.proc_dir_entry) 262 if (!idev->stats.proc_dir_entry)
263 return -EINVAL; 263 return -EINVAL;
264 remove_proc_entry(idev->stats.proc_dir_entry->name, 264 remove_proc_entry(idev->stats.proc_dir_entry->name,
265 net->mib.proc_net_devsnmp6); 265 net->mib.proc_net_devsnmp6);
@@ -267,7 +267,7 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
267 return 0; 267 return 0;
268} 268}
269 269
270static int ipv6_proc_init_net(struct net *net) 270static int __net_init ipv6_proc_init_net(struct net *net)
271{ 271{
272 if (!proc_net_fops_create(net, "sockstat6", S_IRUGO, 272 if (!proc_net_fops_create(net, "sockstat6", S_IRUGO,
273 &sockstat6_seq_fops)) 273 &sockstat6_seq_fops))
@@ -288,7 +288,7 @@ proc_dev_snmp6_fail:
288 return -ENOMEM; 288 return -ENOMEM;
289} 289}
290 290
291static void ipv6_proc_exit_net(struct net *net) 291static void __net_exit ipv6_proc_exit_net(struct net *net)
292{ 292{
293 proc_net_remove(net, "sockstat6"); 293 proc_net_remove(net, "sockstat6");
294 proc_net_remove(net, "dev_snmp6"); 294 proc_net_remove(net, "dev_snmp6");
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 926ce8eeffaf..ed31c37c6e39 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1275,7 +1275,7 @@ static const struct file_operations raw6_seq_fops = {
1275 .release = seq_release_net, 1275 .release = seq_release_net,
1276}; 1276};
1277 1277
1278static int raw6_init_net(struct net *net) 1278static int __net_init raw6_init_net(struct net *net)
1279{ 1279{
1280 if (!proc_net_fops_create(net, "raw6", S_IRUGO, &raw6_seq_fops)) 1280 if (!proc_net_fops_create(net, "raw6", S_IRUGO, &raw6_seq_fops))
1281 return -ENOMEM; 1281 return -ENOMEM;
@@ -1283,7 +1283,7 @@ static int raw6_init_net(struct net *net)
1283 return 0; 1283 return 0;
1284} 1284}
1285 1285
1286static void raw6_exit_net(struct net *net) 1286static void __net_exit raw6_exit_net(struct net *net)
1287{ 1287{
1288 proc_net_remove(net, "raw6"); 1288 proc_net_remove(net, "raw6");
1289} 1289}
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 15bb122e1ce4..d93812d09c13 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -672,7 +672,7 @@ static struct ctl_table ip6_frags_ctl_table[] = {
672 { } 672 { }
673}; 673};
674 674
675static int ip6_frags_ns_sysctl_register(struct net *net) 675static int __net_init ip6_frags_ns_sysctl_register(struct net *net)
676{ 676{
677 struct ctl_table *table; 677 struct ctl_table *table;
678 struct ctl_table_header *hdr; 678 struct ctl_table_header *hdr;
@@ -702,7 +702,7 @@ err_alloc:
702 return -ENOMEM; 702 return -ENOMEM;
703} 703}
704 704
705static void ip6_frags_ns_sysctl_unregister(struct net *net) 705static void __net_exit ip6_frags_ns_sysctl_unregister(struct net *net)
706{ 706{
707 struct ctl_table *table; 707 struct ctl_table *table;
708 708
@@ -745,7 +745,7 @@ static inline void ip6_frags_sysctl_unregister(void)
745} 745}
746#endif 746#endif
747 747
748static int ipv6_frags_init_net(struct net *net) 748static int __net_init ipv6_frags_init_net(struct net *net)
749{ 749{
750 net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH; 750 net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
751 net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH; 751 net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
@@ -756,7 +756,7 @@ static int ipv6_frags_init_net(struct net *net)
756 return ip6_frags_ns_sysctl_register(net); 756 return ip6_frags_ns_sysctl_register(net);
757} 757}
758 758
759static void ipv6_frags_exit_net(struct net *net) 759static void __net_exit ipv6_frags_exit_net(struct net *net)
760{ 760{
761 ip6_frags_ns_sysctl_unregister(net); 761 ip6_frags_ns_sysctl_unregister(net);
762 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags); 762 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c2bd74c5f8d9..8500156f2637 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2612,7 +2612,7 @@ ctl_table ipv6_route_table_template[] = {
2612 { } 2612 { }
2613}; 2613};
2614 2614
2615struct ctl_table *ipv6_route_sysctl_init(struct net *net) 2615struct ctl_table * __net_init ipv6_route_sysctl_init(struct net *net)
2616{ 2616{
2617 struct ctl_table *table; 2617 struct ctl_table *table;
2618 2618
@@ -2637,7 +2637,7 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net)
2637} 2637}
2638#endif 2638#endif
2639 2639
2640static int ip6_route_net_init(struct net *net) 2640static int __net_init ip6_route_net_init(struct net *net)
2641{ 2641{
2642 int ret = -ENOMEM; 2642 int ret = -ENOMEM;
2643 2643
@@ -2702,7 +2702,7 @@ out_ip6_dst_ops:
2702 goto out; 2702 goto out;
2703} 2703}
2704 2704
2705static void ip6_route_net_exit(struct net *net) 2705static void __net_exit ip6_route_net_exit(struct net *net)
2706{ 2706{
2707#ifdef CONFIG_PROC_FS 2707#ifdef CONFIG_PROC_FS
2708 proc_net_remove(net, "ipv6_route"); 2708 proc_net_remove(net, "ipv6_route");
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 976e68244b99..10207cc8cc0e 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -62,7 +62,6 @@
62#define HASH_SIZE 16 62#define HASH_SIZE 16
63#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) 63#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
64 64
65static void ipip6_fb_tunnel_init(struct net_device *dev);
66static void ipip6_tunnel_init(struct net_device *dev); 65static void ipip6_tunnel_init(struct net_device *dev);
67static void ipip6_tunnel_setup(struct net_device *dev); 66static void ipip6_tunnel_setup(struct net_device *dev);
68 67
@@ -1120,7 +1119,7 @@ static void ipip6_tunnel_init(struct net_device *dev)
1120 ipip6_tunnel_bind_dev(dev); 1119 ipip6_tunnel_bind_dev(dev);
1121} 1120}
1122 1121
1123static void ipip6_fb_tunnel_init(struct net_device *dev) 1122static void __net_init ipip6_fb_tunnel_init(struct net_device *dev)
1124{ 1123{
1125 struct ip_tunnel *tunnel = netdev_priv(dev); 1124 struct ip_tunnel *tunnel = netdev_priv(dev);
1126 struct iphdr *iph = &tunnel->parms.iph; 1125 struct iphdr *iph = &tunnel->parms.iph;
@@ -1145,7 +1144,7 @@ static struct xfrm_tunnel sit_handler = {
1145 .priority = 1, 1144 .priority = 1,
1146}; 1145};
1147 1146
1148static void sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head) 1147static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head)
1149{ 1148{
1150 int prio; 1149 int prio;
1151 1150
@@ -1162,7 +1161,7 @@ static void sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head)
1162 } 1161 }
1163} 1162}
1164 1163
1165static int sit_init_net(struct net *net) 1164static int __net_init sit_init_net(struct net *net)
1166{ 1165{
1167 struct sit_net *sitn = net_generic(net, sit_net_id); 1166 struct sit_net *sitn = net_generic(net, sit_net_id);
1168 int err; 1167 int err;
@@ -1195,7 +1194,7 @@ err_alloc_dev:
1195 return err; 1194 return err;
1196} 1195}
1197 1196
1198static void sit_exit_net(struct net *net) 1197static void __net_exit sit_exit_net(struct net *net)
1199{ 1198{
1200 struct sit_net *sitn = net_generic(net, sit_net_id); 1199 struct sit_net *sitn = net_generic(net, sit_net_id);
1201 LIST_HEAD(list); 1200 LIST_HEAD(list);
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index c690736885b4..f841d93bf987 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -55,7 +55,7 @@ struct ctl_path net_ipv6_ctl_path[] = {
55}; 55};
56EXPORT_SYMBOL_GPL(net_ipv6_ctl_path); 56EXPORT_SYMBOL_GPL(net_ipv6_ctl_path);
57 57
58static int ipv6_sysctl_net_init(struct net *net) 58static int __net_init ipv6_sysctl_net_init(struct net *net)
59{ 59{
60 struct ctl_table *ipv6_table; 60 struct ctl_table *ipv6_table;
61 struct ctl_table *ipv6_route_table; 61 struct ctl_table *ipv6_route_table;
@@ -98,7 +98,7 @@ out_ipv6_table:
98 goto out; 98 goto out;
99} 99}
100 100
101static void ipv6_sysctl_net_exit(struct net *net) 101static void __net_exit ipv6_sysctl_net_exit(struct net *net)
102{ 102{
103 struct ctl_table *ipv6_table; 103 struct ctl_table *ipv6_table;
104 struct ctl_table *ipv6_route_table; 104 struct ctl_table *ipv6_route_table;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index febfd595a40d..6963a6b6763e 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -520,6 +520,13 @@ done:
520 return err; 520 return err;
521} 521}
522 522
523static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req,
524 struct request_values *rvp)
525{
526 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
527 return tcp_v6_send_synack(sk, req, rvp);
528}
529
523static inline void syn_flood_warning(struct sk_buff *skb) 530static inline void syn_flood_warning(struct sk_buff *skb)
524{ 531{
525#ifdef CONFIG_SYN_COOKIES 532#ifdef CONFIG_SYN_COOKIES
@@ -876,7 +883,7 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
876 883
877 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 884 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
878 if (net_ratelimit()) { 885 if (net_ratelimit()) {
879 printk(KERN_INFO "MD5 Hash %s for (%pI6, %u)->(%pI6, %u)\n", 886 printk(KERN_INFO "MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u\n",
880 genhash ? "failed" : "mismatch", 887 genhash ? "failed" : "mismatch",
881 &ip6h->saddr, ntohs(th->source), 888 &ip6h->saddr, ntohs(th->source),
882 &ip6h->daddr, ntohs(th->dest)); 889 &ip6h->daddr, ntohs(th->dest));
@@ -890,10 +897,11 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
890struct request_sock_ops tcp6_request_sock_ops __read_mostly = { 897struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
891 .family = AF_INET6, 898 .family = AF_INET6,
892 .obj_size = sizeof(struct tcp6_request_sock), 899 .obj_size = sizeof(struct tcp6_request_sock),
893 .rtx_syn_ack = tcp_v6_send_synack, 900 .rtx_syn_ack = tcp_v6_rtx_synack,
894 .send_ack = tcp_v6_reqsk_send_ack, 901 .send_ack = tcp_v6_reqsk_send_ack,
895 .destructor = tcp_v6_reqsk_destructor, 902 .destructor = tcp_v6_reqsk_destructor,
896 .send_reset = tcp_v6_send_reset 903 .send_reset = tcp_v6_send_reset,
904 .syn_ack_timeout = tcp_syn_ack_timeout,
897}; 905};
898 906
899#ifdef CONFIG_TCP_MD5SIG 907#ifdef CONFIG_TCP_MD5SIG
@@ -2105,7 +2113,7 @@ static struct tcp_seq_afinfo tcp6_seq_afinfo = {
2105 }, 2113 },
2106}; 2114};
2107 2115
2108int tcp6_proc_init(struct net *net) 2116int __net_init tcp6_proc_init(struct net *net)
2109{ 2117{
2110 return tcp_proc_register(net, &tcp6_seq_afinfo); 2118 return tcp_proc_register(net, &tcp6_seq_afinfo);
2111} 2119}
@@ -2174,18 +2182,18 @@ static struct inet_protosw tcpv6_protosw = {
2174 INET_PROTOSW_ICSK, 2182 INET_PROTOSW_ICSK,
2175}; 2183};
2176 2184
2177static int tcpv6_net_init(struct net *net) 2185static int __net_init tcpv6_net_init(struct net *net)
2178{ 2186{
2179 return inet_ctl_sock_create(&net->ipv6.tcp_sk, PF_INET6, 2187 return inet_ctl_sock_create(&net->ipv6.tcp_sk, PF_INET6,
2180 SOCK_RAW, IPPROTO_TCP, net); 2188 SOCK_RAW, IPPROTO_TCP, net);
2181} 2189}
2182 2190
2183static void tcpv6_net_exit(struct net *net) 2191static void __net_exit tcpv6_net_exit(struct net *net)
2184{ 2192{
2185 inet_ctl_sock_destroy(net->ipv6.tcp_sk); 2193 inet_ctl_sock_destroy(net->ipv6.tcp_sk);
2186} 2194}
2187 2195
2188static void tcpv6_net_exit_batch(struct list_head *net_exit_list) 2196static void __net_exit tcpv6_net_exit_batch(struct list_head *net_exit_list)
2189{ 2197{
2190 inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET6); 2198 inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET6);
2191} 2199}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 69ebdbe78c47..34efb3589ffa 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1396,7 +1396,7 @@ static struct udp_seq_afinfo udp6_seq_afinfo = {
1396 }, 1396 },
1397}; 1397};
1398 1398
1399int udp6_proc_init(struct net *net) 1399int __net_init udp6_proc_init(struct net *net)
1400{ 1400{
1401 return udp_proc_register(net, &udp6_seq_afinfo); 1401 return udp_proc_register(net, &udp6_seq_afinfo);
1402} 1402}
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 6ea6938919e6..5f48fadc27f7 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -104,12 +104,12 @@ static struct udp_seq_afinfo udplite6_seq_afinfo = {
104 }, 104 },
105}; 105};
106 106
107static int udplite6_proc_init_net(struct net *net) 107static int __net_init udplite6_proc_init_net(struct net *net)
108{ 108{
109 return udp_proc_register(net, &udplite6_seq_afinfo); 109 return udp_proc_register(net, &udplite6_seq_afinfo);
110} 110}
111 111
112static void udplite6_proc_exit_net(struct net *net) 112static void __net_exit udplite6_proc_exit_net(struct net *net)
113{ 113{
114 udp_proc_unregister(net, &udplite6_seq_afinfo); 114 udp_proc_unregister(net, &udplite6_seq_afinfo);
115} 115}
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 7254e3f899a7..dbdc696f5fc5 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,
@@ -224,8 +223,10 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
224 223
225static inline int xfrm6_garbage_collect(struct dst_ops *ops) 224static inline int xfrm6_garbage_collect(struct dst_ops *ops)
226{ 225{
227 xfrm6_policy_afinfo.garbage_collect(&init_net); 226 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); 227
228 xfrm6_policy_afinfo.garbage_collect(net);
229 return (atomic_read(&ops->entries) > ops->gc_thresh * 2);
229} 230}
230 231
231static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) 232static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -310,7 +311,7 @@ static void xfrm6_policy_fini(void)
310static struct ctl_table xfrm6_policy_table[] = { 311static struct ctl_table xfrm6_policy_table[] = {
311 { 312 {
312 .procname = "xfrm6_gc_thresh", 313 .procname = "xfrm6_gc_thresh",
313 .data = &xfrm6_dst_ops.gc_thresh, 314 .data = &init_net.xfrm.xfrm6_dst_ops.gc_thresh,
314 .maxlen = sizeof(int), 315 .maxlen = sizeof(int),
315 .mode = 0644, 316 .mode = 0644,
316 .proc_handler = proc_dointvec, 317 .proc_handler = proc_dointvec,
@@ -326,13 +327,6 @@ int __init xfrm6_init(void)
326 int ret; 327 int ret;
327 unsigned int gc_thresh; 328 unsigned int gc_thresh;
328 329
329 ret = xfrm6_policy_init();
330 if (ret)
331 goto out;
332
333 ret = xfrm6_state_init();
334 if (ret)
335 goto out_policy;
336 /* 330 /*
337 * We need a good default value for the xfrm6 gc threshold. 331 * We need a good default value for the xfrm6 gc threshold.
338 * In ipv4 we set it to the route hash table size * 8, which 332 * In ipv4 we set it to the route hash table size * 8, which
@@ -346,6 +340,15 @@ int __init xfrm6_init(void)
346 */ 340 */
347 gc_thresh = FIB6_TABLE_HASHSZ * 8; 341 gc_thresh = FIB6_TABLE_HASHSZ * 8;
348 xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh; 342 xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh;
343
344 ret = xfrm6_policy_init();
345 if (ret)
346 goto out;
347
348 ret = xfrm6_state_init();
349 if (ret)
350 goto out_policy;
351
349#ifdef CONFIG_SYSCTL 352#ifdef CONFIG_SYSCTL
350 sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv6_ctl_path, 353 sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv6_ctl_path,
351 xfrm6_policy_table); 354 xfrm6_policy_table);
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 438831d33593..d6f9aeec69f7 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -30,6 +30,25 @@
30#include <linux/ipv6.h> 30#include <linux/ipv6.h>
31#include <linux/icmpv6.h> 31#include <linux/icmpv6.h>
32#include <linux/mutex.h> 32#include <linux/mutex.h>
33#include <net/netns/generic.h>
34
35#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
36#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256
37
38#define XFRM6_TUNNEL_SPI_MIN 1
39#define XFRM6_TUNNEL_SPI_MAX 0xffffffff
40
41struct xfrm6_tunnel_net {
42 struct hlist_head spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
43 struct hlist_head spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
44 u32 spi;
45};
46
47static int xfrm6_tunnel_net_id __read_mostly;
48static inline struct xfrm6_tunnel_net *xfrm6_tunnel_pernet(struct net *net)
49{
50 return net_generic(net, xfrm6_tunnel_net_id);
51}
33 52
34/* 53/*
35 * xfrm_tunnel_spi things are for allocating unique id ("spi") 54 * xfrm_tunnel_spi things are for allocating unique id ("spi")
@@ -46,19 +65,8 @@ struct xfrm6_tunnel_spi {
46 65
47static DEFINE_SPINLOCK(xfrm6_tunnel_spi_lock); 66static DEFINE_SPINLOCK(xfrm6_tunnel_spi_lock);
48 67
49static u32 xfrm6_tunnel_spi;
50
51#define XFRM6_TUNNEL_SPI_MIN 1
52#define XFRM6_TUNNEL_SPI_MAX 0xffffffff
53
54static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly; 68static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly;
55 69
56#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
57#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256
58
59static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
60static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
61
62static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr) 70static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
63{ 71{
64 unsigned h; 72 unsigned h;
@@ -77,49 +85,30 @@ static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi)
77} 85}
78 86
79 87
80static int xfrm6_tunnel_spi_init(void) 88static int __init xfrm6_tunnel_spi_init(void)
81{ 89{
82 int i;
83
84 xfrm6_tunnel_spi = 0;
85 xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi", 90 xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
86 sizeof(struct xfrm6_tunnel_spi), 91 sizeof(struct xfrm6_tunnel_spi),
87 0, SLAB_HWCACHE_ALIGN, 92 0, SLAB_HWCACHE_ALIGN,
88 NULL); 93 NULL);
89 if (!xfrm6_tunnel_spi_kmem) 94 if (!xfrm6_tunnel_spi_kmem)
90 return -ENOMEM; 95 return -ENOMEM;
91
92 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
93 INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byaddr[i]);
94 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++)
95 INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byspi[i]);
96 return 0; 96 return 0;
97} 97}
98 98
99static void xfrm6_tunnel_spi_fini(void) 99static void xfrm6_tunnel_spi_fini(void)
100{ 100{
101 int i;
102
103 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) {
104 if (!hlist_empty(&xfrm6_tunnel_spi_byaddr[i]))
105 return;
106 }
107 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++) {
108 if (!hlist_empty(&xfrm6_tunnel_spi_byspi[i]))
109 return;
110 }
111 rcu_barrier();
112 kmem_cache_destroy(xfrm6_tunnel_spi_kmem); 101 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
113 xfrm6_tunnel_spi_kmem = NULL;
114} 102}
115 103
116static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) 104static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr)
117{ 105{
106 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
118 struct xfrm6_tunnel_spi *x6spi; 107 struct xfrm6_tunnel_spi *x6spi;
119 struct hlist_node *pos; 108 struct hlist_node *pos;
120 109
121 hlist_for_each_entry_rcu(x6spi, pos, 110 hlist_for_each_entry_rcu(x6spi, pos,
122 &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)], 111 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
123 list_byaddr) { 112 list_byaddr) {
124 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) 113 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0)
125 return x6spi; 114 return x6spi;
@@ -128,13 +117,13 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
128 return NULL; 117 return NULL;
129} 118}
130 119
131__be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) 120__be32 xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr)
132{ 121{
133 struct xfrm6_tunnel_spi *x6spi; 122 struct xfrm6_tunnel_spi *x6spi;
134 u32 spi; 123 u32 spi;
135 124
136 rcu_read_lock_bh(); 125 rcu_read_lock_bh();
137 x6spi = __xfrm6_tunnel_spi_lookup(saddr); 126 x6spi = __xfrm6_tunnel_spi_lookup(net, saddr);
138 spi = x6spi ? x6spi->spi : 0; 127 spi = x6spi ? x6spi->spi : 0;
139 rcu_read_unlock_bh(); 128 rcu_read_unlock_bh();
140 return htonl(spi); 129 return htonl(spi);
@@ -142,14 +131,15 @@ __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
142 131
143EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); 132EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup);
144 133
145static int __xfrm6_tunnel_spi_check(u32 spi) 134static int __xfrm6_tunnel_spi_check(struct net *net, u32 spi)
146{ 135{
136 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
147 struct xfrm6_tunnel_spi *x6spi; 137 struct xfrm6_tunnel_spi *x6spi;
148 int index = xfrm6_tunnel_spi_hash_byspi(spi); 138 int index = xfrm6_tunnel_spi_hash_byspi(spi);
149 struct hlist_node *pos; 139 struct hlist_node *pos;
150 140
151 hlist_for_each_entry(x6spi, pos, 141 hlist_for_each_entry(x6spi, pos,
152 &xfrm6_tunnel_spi_byspi[index], 142 &xfrm6_tn->spi_byspi[index],
153 list_byspi) { 143 list_byspi) {
154 if (x6spi->spi == spi) 144 if (x6spi->spi == spi)
155 return -1; 145 return -1;
@@ -157,32 +147,33 @@ static int __xfrm6_tunnel_spi_check(u32 spi)
157 return index; 147 return index;
158} 148}
159 149
160static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) 150static u32 __xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr)
161{ 151{
152 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
162 u32 spi; 153 u32 spi;
163 struct xfrm6_tunnel_spi *x6spi; 154 struct xfrm6_tunnel_spi *x6spi;
164 int index; 155 int index;
165 156
166 if (xfrm6_tunnel_spi < XFRM6_TUNNEL_SPI_MIN || 157 if (xfrm6_tn->spi < XFRM6_TUNNEL_SPI_MIN ||
167 xfrm6_tunnel_spi >= XFRM6_TUNNEL_SPI_MAX) 158 xfrm6_tn->spi >= XFRM6_TUNNEL_SPI_MAX)
168 xfrm6_tunnel_spi = XFRM6_TUNNEL_SPI_MIN; 159 xfrm6_tn->spi = XFRM6_TUNNEL_SPI_MIN;
169 else 160 else
170 xfrm6_tunnel_spi++; 161 xfrm6_tn->spi++;
171 162
172 for (spi = xfrm6_tunnel_spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) { 163 for (spi = xfrm6_tn->spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) {
173 index = __xfrm6_tunnel_spi_check(spi); 164 index = __xfrm6_tunnel_spi_check(net, spi);
174 if (index >= 0) 165 if (index >= 0)
175 goto alloc_spi; 166 goto alloc_spi;
176 } 167 }
177 for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tunnel_spi; spi++) { 168 for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tn->spi; spi++) {
178 index = __xfrm6_tunnel_spi_check(spi); 169 index = __xfrm6_tunnel_spi_check(net, spi);
179 if (index >= 0) 170 if (index >= 0)
180 goto alloc_spi; 171 goto alloc_spi;
181 } 172 }
182 spi = 0; 173 spi = 0;
183 goto out; 174 goto out;
184alloc_spi: 175alloc_spi:
185 xfrm6_tunnel_spi = spi; 176 xfrm6_tn->spi = spi;
186 x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC); 177 x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC);
187 if (!x6spi) 178 if (!x6spi)
188 goto out; 179 goto out;
@@ -192,26 +183,26 @@ alloc_spi:
192 x6spi->spi = spi; 183 x6spi->spi = spi;
193 atomic_set(&x6spi->refcnt, 1); 184 atomic_set(&x6spi->refcnt, 1);
194 185
195 hlist_add_head_rcu(&x6spi->list_byspi, &xfrm6_tunnel_spi_byspi[index]); 186 hlist_add_head_rcu(&x6spi->list_byspi, &xfrm6_tn->spi_byspi[index]);
196 187
197 index = xfrm6_tunnel_spi_hash_byaddr(saddr); 188 index = xfrm6_tunnel_spi_hash_byaddr(saddr);
198 hlist_add_head_rcu(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]); 189 hlist_add_head_rcu(&x6spi->list_byaddr, &xfrm6_tn->spi_byaddr[index]);
199out: 190out:
200 return spi; 191 return spi;
201} 192}
202 193
203__be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) 194__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr)
204{ 195{
205 struct xfrm6_tunnel_spi *x6spi; 196 struct xfrm6_tunnel_spi *x6spi;
206 u32 spi; 197 u32 spi;
207 198
208 spin_lock_bh(&xfrm6_tunnel_spi_lock); 199 spin_lock_bh(&xfrm6_tunnel_spi_lock);
209 x6spi = __xfrm6_tunnel_spi_lookup(saddr); 200 x6spi = __xfrm6_tunnel_spi_lookup(net, saddr);
210 if (x6spi) { 201 if (x6spi) {
211 atomic_inc(&x6spi->refcnt); 202 atomic_inc(&x6spi->refcnt);
212 spi = x6spi->spi; 203 spi = x6spi->spi;
213 } else 204 } else
214 spi = __xfrm6_tunnel_alloc_spi(saddr); 205 spi = __xfrm6_tunnel_alloc_spi(net, saddr);
215 spin_unlock_bh(&xfrm6_tunnel_spi_lock); 206 spin_unlock_bh(&xfrm6_tunnel_spi_lock);
216 207
217 return htonl(spi); 208 return htonl(spi);
@@ -225,15 +216,16 @@ static void x6spi_destroy_rcu(struct rcu_head *head)
225 container_of(head, struct xfrm6_tunnel_spi, rcu_head)); 216 container_of(head, struct xfrm6_tunnel_spi, rcu_head));
226} 217}
227 218
228void xfrm6_tunnel_free_spi(xfrm_address_t *saddr) 219void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr)
229{ 220{
221 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
230 struct xfrm6_tunnel_spi *x6spi; 222 struct xfrm6_tunnel_spi *x6spi;
231 struct hlist_node *pos, *n; 223 struct hlist_node *pos, *n;
232 224
233 spin_lock_bh(&xfrm6_tunnel_spi_lock); 225 spin_lock_bh(&xfrm6_tunnel_spi_lock);
234 226
235 hlist_for_each_entry_safe(x6spi, pos, n, 227 hlist_for_each_entry_safe(x6spi, pos, n,
236 &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)], 228 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
237 list_byaddr) 229 list_byaddr)
238 { 230 {
239 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) { 231 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
@@ -263,10 +255,11 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
263 255
264static int xfrm6_tunnel_rcv(struct sk_buff *skb) 256static int xfrm6_tunnel_rcv(struct sk_buff *skb)
265{ 257{
258 struct net *net = dev_net(skb->dev);
266 struct ipv6hdr *iph = ipv6_hdr(skb); 259 struct ipv6hdr *iph = ipv6_hdr(skb);
267 __be32 spi; 260 __be32 spi;
268 261
269 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); 262 spi = xfrm6_tunnel_spi_lookup(net, (xfrm_address_t *)&iph->saddr);
270 return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0; 263 return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0;
271} 264}
272 265
@@ -326,7 +319,9 @@ static int xfrm6_tunnel_init_state(struct xfrm_state *x)
326 319
327static void xfrm6_tunnel_destroy(struct xfrm_state *x) 320static void xfrm6_tunnel_destroy(struct xfrm_state *x)
328{ 321{
329 xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr); 322 struct net *net = xs_net(x);
323
324 xfrm6_tunnel_free_spi(net, (xfrm_address_t *)&x->props.saddr);
330} 325}
331 326
332static const struct xfrm_type xfrm6_tunnel_type = { 327static const struct xfrm_type xfrm6_tunnel_type = {
@@ -351,18 +346,54 @@ static struct xfrm6_tunnel xfrm46_tunnel_handler = {
351 .priority = 2, 346 .priority = 2,
352}; 347};
353 348
349static int __net_init xfrm6_tunnel_net_init(struct net *net)
350{
351 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
352 unsigned int i;
353
354 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
355 INIT_HLIST_HEAD(&xfrm6_tn->spi_byaddr[i]);
356 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++)
357 INIT_HLIST_HEAD(&xfrm6_tn->spi_byspi[i]);
358 xfrm6_tn->spi = 0;
359
360 return 0;
361}
362
363static void __net_exit xfrm6_tunnel_net_exit(struct net *net)
364{
365}
366
367static struct pernet_operations xfrm6_tunnel_net_ops = {
368 .init = xfrm6_tunnel_net_init,
369 .exit = xfrm6_tunnel_net_exit,
370 .id = &xfrm6_tunnel_net_id,
371 .size = sizeof(struct xfrm6_tunnel_net),
372};
373
354static int __init xfrm6_tunnel_init(void) 374static int __init xfrm6_tunnel_init(void)
355{ 375{
356 if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) 376 int rv;
377
378 rv = xfrm_register_type(&xfrm6_tunnel_type, AF_INET6);
379 if (rv < 0)
357 goto err; 380 goto err;
358 if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) 381 rv = xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6);
382 if (rv < 0)
359 goto unreg; 383 goto unreg;
360 if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) 384 rv = xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET);
385 if (rv < 0)
361 goto dereg6; 386 goto dereg6;
362 if (xfrm6_tunnel_spi_init() < 0) 387 rv = xfrm6_tunnel_spi_init();
388 if (rv < 0)
363 goto dereg46; 389 goto dereg46;
390 rv = register_pernet_subsys(&xfrm6_tunnel_net_ops);
391 if (rv < 0)
392 goto deregspi;
364 return 0; 393 return 0;
365 394
395deregspi:
396 xfrm6_tunnel_spi_fini();
366dereg46: 397dereg46:
367 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET); 398 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
368dereg6: 399dereg6:
@@ -370,11 +401,12 @@ dereg6:
370unreg: 401unreg:
371 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 402 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
372err: 403err:
373 return -EAGAIN; 404 return rv;
374} 405}
375 406
376static void __exit xfrm6_tunnel_fini(void) 407static void __exit xfrm6_tunnel_fini(void)
377{ 408{
409 unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
378 xfrm6_tunnel_spi_fini(); 410 xfrm6_tunnel_spi_fini();
379 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET); 411 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
380 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); 412 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);