aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/xfrm.h6
-rw-r--r--net/ipv4/xfrm4_policy.c14
-rw-r--r--net/ipv6/xfrm6_policy.c25
-rw-r--r--net/xfrm/xfrm_policy.c59
4 files changed, 84 insertions, 20 deletions
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 56f8e5585df7..74f119a2829a 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -5,6 +5,7 @@
5#include <linux/wait.h> 5#include <linux/wait.h>
6#include <linux/workqueue.h> 6#include <linux/workqueue.h>
7#include <linux/xfrm.h> 7#include <linux/xfrm.h>
8#include <net/dst_ops.h>
8 9
9struct ctl_table_header; 10struct ctl_table_header;
10 11
@@ -42,6 +43,11 @@ struct netns_xfrm {
42 unsigned int policy_count[XFRM_POLICY_MAX * 2]; 43 unsigned int policy_count[XFRM_POLICY_MAX * 2];
43 struct work_struct policy_hash_work; 44 struct work_struct policy_hash_work;
44 45
46 struct dst_ops xfrm4_dst_ops;
47#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
48 struct dst_ops xfrm6_dst_ops;
49#endif
50
45 struct sock *nlsk; 51 struct sock *nlsk;
46 struct sock *nlsk_stash; 52 struct sock *nlsk_stash;
47 53
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 8c08a28d8f83..67107d63c1cd 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -15,7 +15,6 @@
15#include <net/xfrm.h> 15#include <net/xfrm.h>
16#include <net/ip.h> 16#include <net/ip.h>
17 17
18static struct dst_ops xfrm4_dst_ops;
19static struct xfrm_policy_afinfo xfrm4_policy_afinfo; 18static struct xfrm_policy_afinfo xfrm4_policy_afinfo;
20 19
21static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, 20static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos,
@@ -190,8 +189,10 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
190 189
191static inline int xfrm4_garbage_collect(struct dst_ops *ops) 190static inline int xfrm4_garbage_collect(struct dst_ops *ops)
192{ 191{
193 xfrm4_policy_afinfo.garbage_collect(&init_net); 192 struct net *net = container_of(ops, struct net, xfrm.xfrm4_dst_ops);
194 return (atomic_read(&xfrm4_dst_ops.entries) > xfrm4_dst_ops.gc_thresh*2); 193
194 xfrm4_policy_afinfo.garbage_collect(net);
195 return (atomic_read(&ops->entries) > ops->gc_thresh * 2);
195} 196}
196 197
197static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu) 198static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -268,7 +269,7 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
268static struct ctl_table xfrm4_policy_table[] = { 269static struct ctl_table xfrm4_policy_table[] = {
269 { 270 {
270 .procname = "xfrm4_gc_thresh", 271 .procname = "xfrm4_gc_thresh",
271 .data = &xfrm4_dst_ops.gc_thresh, 272 .data = &init_net.xfrm.xfrm4_dst_ops.gc_thresh,
272 .maxlen = sizeof(int), 273 .maxlen = sizeof(int),
273 .mode = 0644, 274 .mode = 0644,
274 .proc_handler = proc_dointvec, 275 .proc_handler = proc_dointvec,
@@ -295,8 +296,6 @@ static void __exit xfrm4_policy_fini(void)
295 296
296void __init xfrm4_init(int rt_max_size) 297void __init xfrm4_init(int rt_max_size)
297{ 298{
298 xfrm4_state_init();
299 xfrm4_policy_init();
300 /* 299 /*
301 * Select a default value for the gc_thresh based on the main route 300 * Select a default value for the gc_thresh based on the main route
302 * table hash size. It seems to me the worst case scenario is when 301 * table hash size. It seems to me the worst case scenario is when
@@ -308,6 +307,9 @@ void __init xfrm4_init(int rt_max_size)
308 * and start cleaning when were 1/2 full 307 * and start cleaning when were 1/2 full
309 */ 308 */
310 xfrm4_dst_ops.gc_thresh = rt_max_size/2; 309 xfrm4_dst_ops.gc_thresh = rt_max_size/2;
310
311 xfrm4_state_init();
312 xfrm4_policy_init();
311#ifdef CONFIG_SYSCTL 313#ifdef CONFIG_SYSCTL
312 sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv4_ctl_path, 314 sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv4_ctl_path,
313 xfrm4_policy_table); 315 xfrm4_policy_table);
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/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d2c8cb57ee4c..0ecb16a9a883 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1309,15 +1309,28 @@ static inline int xfrm_get_tos(struct flowi *fl, int family)
1309 return tos; 1309 return tos;
1310} 1310}
1311 1311
1312static inline struct xfrm_dst *xfrm_alloc_dst(int family) 1312static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
1313{ 1313{
1314 struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family); 1314 struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
1315 struct dst_ops *dst_ops;
1315 struct xfrm_dst *xdst; 1316 struct xfrm_dst *xdst;
1316 1317
1317 if (!afinfo) 1318 if (!afinfo)
1318 return ERR_PTR(-EINVAL); 1319 return ERR_PTR(-EINVAL);
1319 1320
1320 xdst = dst_alloc(afinfo->dst_ops) ?: ERR_PTR(-ENOBUFS); 1321 switch (family) {
1322 case AF_INET:
1323 dst_ops = &net->xfrm.xfrm4_dst_ops;
1324 break;
1325#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1326 case AF_INET6:
1327 dst_ops = &net->xfrm.xfrm6_dst_ops;
1328 break;
1329#endif
1330 default:
1331 BUG();
1332 }
1333 xdst = dst_alloc(dst_ops) ?: ERR_PTR(-ENOBUFS);
1321 1334
1322 xfrm_policy_put_afinfo(afinfo); 1335 xfrm_policy_put_afinfo(afinfo);
1323 1336
@@ -1366,6 +1379,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
1366 struct flowi *fl, 1379 struct flowi *fl,
1367 struct dst_entry *dst) 1380 struct dst_entry *dst)
1368{ 1381{
1382 struct net *net = xp_net(policy);
1369 unsigned long now = jiffies; 1383 unsigned long now = jiffies;
1370 struct net_device *dev; 1384 struct net_device *dev;
1371 struct dst_entry *dst_prev = NULL; 1385 struct dst_entry *dst_prev = NULL;
@@ -1389,7 +1403,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
1389 dst_hold(dst); 1403 dst_hold(dst);
1390 1404
1391 for (; i < nx; i++) { 1405 for (; i < nx; i++) {
1392 struct xfrm_dst *xdst = xfrm_alloc_dst(family); 1406 struct xfrm_dst *xdst = xfrm_alloc_dst(net, family);
1393 struct dst_entry *dst1 = &xdst->u.dst; 1407 struct dst_entry *dst1 = &xdst->u.dst;
1394 1408
1395 err = PTR_ERR(xdst); 1409 err = PTR_ERR(xdst);
@@ -2279,6 +2293,7 @@ EXPORT_SYMBOL(xfrm_bundle_ok);
2279 2293
2280int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) 2294int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
2281{ 2295{
2296 struct net *net;
2282 int err = 0; 2297 int err = 0;
2283 if (unlikely(afinfo == NULL)) 2298 if (unlikely(afinfo == NULL))
2284 return -EINVAL; 2299 return -EINVAL;
@@ -2302,6 +2317,27 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
2302 xfrm_policy_afinfo[afinfo->family] = afinfo; 2317 xfrm_policy_afinfo[afinfo->family] = afinfo;
2303 } 2318 }
2304 write_unlock_bh(&xfrm_policy_afinfo_lock); 2319 write_unlock_bh(&xfrm_policy_afinfo_lock);
2320
2321 rtnl_lock();
2322 for_each_net(net) {
2323 struct dst_ops *xfrm_dst_ops;
2324
2325 switch (afinfo->family) {
2326 case AF_INET:
2327 xfrm_dst_ops = &net->xfrm.xfrm4_dst_ops;
2328 break;
2329#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2330 case AF_INET6:
2331 xfrm_dst_ops = &net->xfrm.xfrm6_dst_ops;
2332 break;
2333#endif
2334 default:
2335 BUG();
2336 }
2337 *xfrm_dst_ops = *afinfo->dst_ops;
2338 }
2339 rtnl_unlock();
2340
2305 return err; 2341 return err;
2306} 2342}
2307EXPORT_SYMBOL(xfrm_policy_register_afinfo); 2343EXPORT_SYMBOL(xfrm_policy_register_afinfo);
@@ -2332,6 +2368,22 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
2332} 2368}
2333EXPORT_SYMBOL(xfrm_policy_unregister_afinfo); 2369EXPORT_SYMBOL(xfrm_policy_unregister_afinfo);
2334 2370
2371static void __net_init xfrm_dst_ops_init(struct net *net)
2372{
2373 struct xfrm_policy_afinfo *afinfo;
2374
2375 read_lock_bh(&xfrm_policy_afinfo_lock);
2376 afinfo = xfrm_policy_afinfo[AF_INET];
2377 if (afinfo)
2378 net->xfrm.xfrm4_dst_ops = *afinfo->dst_ops;
2379#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2380 afinfo = xfrm_policy_afinfo[AF_INET6];
2381 if (afinfo)
2382 net->xfrm.xfrm6_dst_ops = *afinfo->dst_ops;
2383#endif
2384 read_unlock_bh(&xfrm_policy_afinfo_lock);
2385}
2386
2335static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family) 2387static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family)
2336{ 2388{
2337 struct xfrm_policy_afinfo *afinfo; 2389 struct xfrm_policy_afinfo *afinfo;
@@ -2494,6 +2546,7 @@ static int __net_init xfrm_net_init(struct net *net)
2494 rv = xfrm_policy_init(net); 2546 rv = xfrm_policy_init(net);
2495 if (rv < 0) 2547 if (rv < 0)
2496 goto out_policy; 2548 goto out_policy;
2549 xfrm_dst_ops_init(net);
2497 rv = xfrm_sysctl_init(net); 2550 rv = xfrm_sysctl_init(net);
2498 if (rv < 0) 2551 if (rv < 0)
2499 goto out_sysctl; 2552 goto out_sysctl;