diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:23:26 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:23:26 -0500 |
commit | 8b18f8eaf9207d53ba3e69f2b98d7290f4dec227 (patch) | |
tree | b4f323ac9aa6f1956c3ad4398a2230fc7a01d3e4 | |
parent | 8100bea7d619e8496ad8e545d1b41f536e076cd5 (diff) |
netns xfrm: per-netns inexact policies
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/netns/xfrm.h | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 20 |
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 | ||
8 | struct netns_xfrm { | 9 | struct 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 | ||
330 | static struct hlist_head xfrm_policy_inexact[XFRM_POLICY_MAX*2]; | ||
331 | static struct xfrm_policy_hash xfrm_policy_bydst[XFRM_POLICY_MAX*2] __read_mostly; | 330 | static struct xfrm_policy_hash xfrm_policy_bydst[XFRM_POLICY_MAX*2] __read_mostly; |
332 | static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024; | 331 | static 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: | |||
2435 | static void xfrm_policy_fini(struct net *net) | 2434 | static 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 && |