aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/xfrm.h2
-rw-r--r--net/xfrm/xfrm_policy.c20
2 files changed, 14 insertions, 8 deletions
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 42dc318fe3de..c7568315f16c 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -4,6 +4,7 @@
4#include <linux/list.h> 4#include <linux/list.h>
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 8
8struct netns_xfrm { 9struct netns_xfrm {
9 struct list_head state_all; 10 struct list_head state_all;
@@ -29,6 +30,7 @@ struct netns_xfrm {
29 struct list_head policy_all; 30 struct list_head policy_all;
30 struct hlist_head *policy_byidx; 31 struct hlist_head *policy_byidx;
31 unsigned int policy_idx_hmask; 32 unsigned int policy_idx_hmask;
33 struct hlist_head policy_inexact[XFRM_POLICY_MAX * 2];
32}; 34};
33 35
34#endif 36#endif
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 9e37a44f148e..ba4e95b8e24e 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -327,7 +327,6 @@ struct xfrm_policy_hash {
327 unsigned int hmask; 327 unsigned int hmask;
328}; 328};
329 329
330static struct hlist_head xfrm_policy_inexact[XFRM_POLICY_MAX*2];
331static struct xfrm_policy_hash xfrm_policy_bydst[XFRM_POLICY_MAX*2] __read_mostly; 330static struct xfrm_policy_hash xfrm_policy_bydst[XFRM_POLICY_MAX*2] __read_mostly;
332static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024; 331static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024;
333 332
@@ -342,7 +341,7 @@ static struct hlist_head *policy_hash_bysel(struct xfrm_selector *sel, unsigned
342 unsigned int hash = __sel_hash(sel, family, hmask); 341 unsigned int hash = __sel_hash(sel, family, hmask);
343 342
344 return (hash == hmask + 1 ? 343 return (hash == hmask + 1 ?
345 &xfrm_policy_inexact[dir] : 344 &init_net.xfrm.policy_inexact[dir] :
346 xfrm_policy_bydst[dir].table + hash); 345 xfrm_policy_bydst[dir].table + hash);
347} 346}
348 347
@@ -752,7 +751,7 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
752 int i; 751 int i;
753 752
754 hlist_for_each_entry(pol, entry, 753 hlist_for_each_entry(pol, entry,
755 &xfrm_policy_inexact[dir], bydst) { 754 &init_net.xfrm.policy_inexact[dir], bydst) {
756 if (pol->type != type) 755 if (pol->type != type)
757 continue; 756 continue;
758 err = security_xfrm_policy_delete(pol->security); 757 err = security_xfrm_policy_delete(pol->security);
@@ -810,7 +809,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
810 killed = 0; 809 killed = 0;
811 again1: 810 again1:
812 hlist_for_each_entry(pol, entry, 811 hlist_for_each_entry(pol, entry,
813 &xfrm_policy_inexact[dir], bydst) { 812 &init_net.xfrm.policy_inexact[dir], bydst) {
814 if (pol->type != type) 813 if (pol->type != type)
815 continue; 814 continue;
816 hlist_del(&pol->bydst); 815 hlist_del(&pol->bydst);
@@ -983,7 +982,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
983 break; 982 break;
984 } 983 }
985 } 984 }
986 chain = &xfrm_policy_inexact[dir]; 985 chain = &init_net.xfrm.policy_inexact[dir];
987 hlist_for_each_entry(pol, entry, chain, bydst) { 986 hlist_for_each_entry(pol, entry, chain, bydst) {
988 err = xfrm_policy_match(pol, fl, type, family, dir); 987 err = xfrm_policy_match(pol, fl, type, family, dir);
989 if (err) { 988 if (err) {
@@ -2152,7 +2151,7 @@ static void xfrm_prune_bundles(int (*func)(struct dst_entry *))
2152 int i; 2151 int i;
2153 2152
2154 hlist_for_each_entry(pol, entry, 2153 hlist_for_each_entry(pol, entry,
2155 &xfrm_policy_inexact[dir], bydst) 2154 &init_net.xfrm.policy_inexact[dir], bydst)
2156 prune_one_bundle(pol, func, &gc_list); 2155 prune_one_bundle(pol, func, &gc_list);
2157 2156
2158 table = xfrm_policy_bydst[dir].table; 2157 table = xfrm_policy_bydst[dir].table;
@@ -2414,7 +2413,7 @@ static int __net_init xfrm_policy_init(struct net *net)
2414 for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) { 2413 for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
2415 struct xfrm_policy_hash *htab; 2414 struct xfrm_policy_hash *htab;
2416 2415
2417 INIT_HLIST_HEAD(&xfrm_policy_inexact[dir]); 2416 INIT_HLIST_HEAD(&net->xfrm.policy_inexact[dir]);
2418 2417
2419 htab = &xfrm_policy_bydst[dir]; 2418 htab = &xfrm_policy_bydst[dir];
2420 htab->table = xfrm_hash_alloc(sz); 2419 htab->table = xfrm_hash_alloc(sz);
@@ -2435,9 +2434,14 @@ out_byidx:
2435static void xfrm_policy_fini(struct net *net) 2434static void xfrm_policy_fini(struct net *net)
2436{ 2435{
2437 unsigned int sz; 2436 unsigned int sz;
2437 int dir;
2438 2438
2439 WARN_ON(!list_empty(&net->xfrm.policy_all)); 2439 WARN_ON(!list_empty(&net->xfrm.policy_all));
2440 2440
2441 for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
2442 WARN_ON(!hlist_empty(&net->xfrm.policy_inexact[dir]));
2443 }
2444
2441 sz = (net->xfrm.policy_idx_hmask + 1) * sizeof(struct hlist_head); 2445 sz = (net->xfrm.policy_idx_hmask + 1) * sizeof(struct hlist_head);
2442 WARN_ON(!hlist_empty(net->xfrm.policy_byidx)); 2446 WARN_ON(!hlist_empty(net->xfrm.policy_byidx));
2443 xfrm_hash_free(net->xfrm.policy_byidx, sz); 2447 xfrm_hash_free(net->xfrm.policy_byidx, sz);
@@ -2590,7 +2594,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(struct xfrm_selector *sel,
2590 break; 2594 break;
2591 } 2595 }
2592 } 2596 }
2593 chain = &xfrm_policy_inexact[dir]; 2597 chain = &init_net.xfrm.policy_inexact[dir];
2594 hlist_for_each_entry(pol, entry, chain, bydst) { 2598 hlist_for_each_entry(pol, entry, chain, bydst) {
2595 if (xfrm_migrate_selector_match(sel, &pol->selector) && 2599 if (xfrm_migrate_selector_match(sel, &pol->selector) &&
2596 pol->type == type && 2600 pol->type == type &&