Commit 1121994c authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by David S. Miller

netns xfrm: policy insertion in netns

Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e92303f8
...@@ -326,22 +326,22 @@ static inline unsigned int idx_hash(struct net *net, u32 index) ...@@ -326,22 +326,22 @@ static inline unsigned int idx_hash(struct net *net, u32 index)
return __idx_hash(index, net->xfrm.policy_idx_hmask); return __idx_hash(index, net->xfrm.policy_idx_hmask);
} }
static struct hlist_head *policy_hash_bysel(struct xfrm_selector *sel, unsigned short family, int dir) static struct hlist_head *policy_hash_bysel(struct net *net, struct xfrm_selector *sel, unsigned short family, int dir)
{ {
unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask; unsigned int hmask = net->xfrm.policy_bydst[dir].hmask;
unsigned int hash = __sel_hash(sel, family, hmask); unsigned int hash = __sel_hash(sel, family, hmask);
return (hash == hmask + 1 ? return (hash == hmask + 1 ?
&init_net.xfrm.policy_inexact[dir] : &net->xfrm.policy_inexact[dir] :
init_net.xfrm.policy_bydst[dir].table + hash); net->xfrm.policy_bydst[dir].table + hash);
} }
static struct hlist_head *policy_hash_direct(xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, int dir) static struct hlist_head *policy_hash_direct(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, int dir)
{ {
unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask; unsigned int hmask = net->xfrm.policy_bydst[dir].hmask;
unsigned int hash = __addr_hash(daddr, saddr, family, hmask); unsigned int hash = __addr_hash(daddr, saddr, family, hmask);
return init_net.xfrm.policy_bydst[dir].table + hash; return net->xfrm.policy_bydst[dir].table + hash;
} }
static void xfrm_dst_hash_transfer(struct hlist_head *list, static void xfrm_dst_hash_transfer(struct hlist_head *list,
...@@ -508,7 +508,7 @@ static void xfrm_hash_resize(struct work_struct *work) ...@@ -508,7 +508,7 @@ static void xfrm_hash_resize(struct work_struct *work)
/* Generate new index... KAME seems to generate them ordered by cost /* Generate new index... KAME seems to generate them ordered by cost
* of an absolute inpredictability of ordering of rules. This will not pass. */ * of an absolute inpredictability of ordering of rules. This will not pass. */
static u32 xfrm_gen_index(int dir) static u32 xfrm_gen_index(struct net *net, int dir)
{ {
static u32 idx_generator; static u32 idx_generator;
...@@ -523,7 +523,7 @@ static u32 xfrm_gen_index(int dir) ...@@ -523,7 +523,7 @@ static u32 xfrm_gen_index(int dir)
idx_generator += 8; idx_generator += 8;
if (idx == 0) if (idx == 0)
idx = 8; idx = 8;
list = init_net.xfrm.policy_byidx + idx_hash(&init_net, idx); list = net->xfrm.policy_byidx + idx_hash(net, idx);
found = 0; found = 0;
hlist_for_each_entry(p, entry, list, byidx) { hlist_for_each_entry(p, entry, list, byidx) {
if (p->index == idx) { if (p->index == idx) {
...@@ -553,6 +553,7 @@ static inline int selector_cmp(struct xfrm_selector *s1, struct xfrm_selector *s ...@@ -553,6 +553,7 @@ static inline int selector_cmp(struct xfrm_selector *s1, struct xfrm_selector *s
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
{ {
struct net *net = xp_net(policy);
struct xfrm_policy *pol; struct xfrm_policy *pol;
struct xfrm_policy *delpol; struct xfrm_policy *delpol;
struct hlist_head *chain; struct hlist_head *chain;
...@@ -560,7 +561,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) ...@@ -560,7 +561,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
struct dst_entry *gc_list; struct dst_entry *gc_list;
write_lock_bh(&xfrm_policy_lock); write_lock_bh(&xfrm_policy_lock);
chain = policy_hash_bysel(&policy->selector, policy->family, dir); chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
delpol = NULL; delpol = NULL;
newpos = NULL; newpos = NULL;
hlist_for_each_entry(pol, entry, chain, bydst) { hlist_for_each_entry(pol, entry, chain, bydst) {
...@@ -587,27 +588,27 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) ...@@ -587,27 +588,27 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
else else
hlist_add_head(&policy->bydst, chain); hlist_add_head(&policy->bydst, chain);
xfrm_pol_hold(policy); xfrm_pol_hold(policy);
init_net.xfrm.policy_count[dir]++; net->xfrm.policy_count[dir]++;
atomic_inc(&flow_cache_genid); atomic_inc(&flow_cache_genid);
if (delpol) { if (delpol) {
hlist_del(&delpol->bydst); hlist_del(&delpol->bydst);
hlist_del(&delpol->byidx); hlist_del(&delpol->byidx);
list_del(&delpol->walk.all); list_del(&delpol->walk.all);
init_net.xfrm.policy_count[dir]--; net->xfrm.policy_count[dir]--;
} }
policy->index = delpol ? delpol->index : xfrm_gen_index(dir); policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir);
hlist_add_head(&policy->byidx, init_net.xfrm.policy_byidx+idx_hash(&init_net, policy->index)); hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index));
policy->curlft.add_time = get_seconds(); policy->curlft.add_time = get_seconds();
policy->curlft.use_time = 0; policy->curlft.use_time = 0;
if (!mod_timer(&policy->timer, jiffies + HZ)) if (!mod_timer(&policy->timer, jiffies + HZ))
xfrm_pol_hold(policy); xfrm_pol_hold(policy);
list_add(&policy->walk.all, &init_net.xfrm.policy_all); list_add(&policy->walk.all, &net->xfrm.policy_all);
write_unlock_bh(&xfrm_policy_lock); write_unlock_bh(&xfrm_policy_lock);
if (delpol) if (delpol)
xfrm_policy_kill(delpol); xfrm_policy_kill(delpol);
else if (xfrm_bydst_should_resize(&init_net, dir, NULL)) else if (xfrm_bydst_should_resize(net, dir, NULL))
schedule_work(&init_net.xfrm.policy_hash_work); schedule_work(&net->xfrm.policy_hash_work);
read_lock_bh(&xfrm_policy_lock); read_lock_bh(&xfrm_policy_lock);
gc_list = NULL; gc_list = NULL;
...@@ -652,7 +653,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, ...@@ -652,7 +653,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
*err = 0; *err = 0;
write_lock_bh(&xfrm_policy_lock); write_lock_bh(&xfrm_policy_lock);
chain = policy_hash_bysel(sel, sel->family, dir); chain = policy_hash_bysel(&init_net, sel, sel->family, dir);
ret = NULL; ret = NULL;
hlist_for_each_entry(pol, entry, chain, bydst) { hlist_for_each_entry(pol, entry, chain, bydst) {
if (pol->type == type && if (pol->type == type &&
...@@ -955,7 +956,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, ...@@ -955,7 +956,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
return NULL; return NULL;
read_lock_bh(&xfrm_policy_lock); read_lock_bh(&xfrm_policy_lock);
chain = policy_hash_direct(daddr, saddr, family, dir); chain = policy_hash_direct(&init_net, daddr, saddr, family, dir);
ret = NULL; ret = NULL;
hlist_for_each_entry(pol, entry, chain, bydst) { hlist_for_each_entry(pol, entry, chain, bydst) {
err = xfrm_policy_match(pol, fl, type, family, dir); err = xfrm_policy_match(pol, fl, type, family, dir);
...@@ -1070,7 +1071,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc ...@@ -1070,7 +1071,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc
static void __xfrm_policy_link(struct xfrm_policy *pol, int dir) static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
{ {
struct net *net = xp_net(pol); struct net *net = xp_net(pol);
struct hlist_head *chain = policy_hash_bysel(&pol->selector, struct hlist_head *chain = policy_hash_bysel(net, &pol->selector,
pol->family, dir); pol->family, dir);
list_add(&pol->walk.all, &net->xfrm.policy_all); list_add(&pol->walk.all, &net->xfrm.policy_all);
...@@ -1116,6 +1117,7 @@ EXPORT_SYMBOL(xfrm_policy_delete); ...@@ -1116,6 +1117,7 @@ EXPORT_SYMBOL(xfrm_policy_delete);
int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
{ {
struct net *net = xp_net(pol);
struct xfrm_policy *old_pol; struct xfrm_policy *old_pol;
#ifdef CONFIG_XFRM_SUB_POLICY #ifdef CONFIG_XFRM_SUB_POLICY
...@@ -1128,7 +1130,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) ...@@ -1128,7 +1130,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
sk->sk_policy[dir] = pol; sk->sk_policy[dir] = pol;
if (pol) { if (pol) {
pol->curlft.add_time = get_seconds(); pol->curlft.add_time = get_seconds();
pol->index = xfrm_gen_index(XFRM_POLICY_MAX+dir); pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir);
__xfrm_policy_link(pol, XFRM_POLICY_MAX+dir); __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
} }
if (old_pol) if (old_pol)
...@@ -2595,7 +2597,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(struct xfrm_selector *sel, ...@@ -2595,7 +2597,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(struct xfrm_selector *sel,
u32 priority = ~0U; u32 priority = ~0U;
read_lock_bh(&xfrm_policy_lock); read_lock_bh(&xfrm_policy_lock);
chain = policy_hash_direct(&sel->daddr, &sel->saddr, sel->family, dir); chain = policy_hash_direct(&init_net, &sel->daddr, &sel->saddr, sel->family, dir);
hlist_for_each_entry(pol, entry, chain, bydst) { hlist_for_each_entry(pol, entry, chain, bydst) {
if (xfrm_migrate_selector_match(sel, &pol->selector) && if (xfrm_migrate_selector_match(sel, &pol->selector) &&
pol->type == type) { pol->type == type) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment