aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2008-11-25 20:33:06 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-25 20:33:06 -0500
commit1121994c803f4a4f471d617443ff2a09515725e7 (patch)
tree5d470f60fefd29b75dff5bb4a70b916904ccc879 /net/xfrm/xfrm_policy.c
parente92303f872600978796ff323bc229d911f905849 (diff)
netns xfrm: policy insertion in netns
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c46
1 files changed, 24 insertions, 22 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index aefbb56dad20..11fee87a0cc1 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -326,22 +326,22 @@ static inline unsigned int idx_hash(struct net *net, u32 index)
326 return __idx_hash(index, net->xfrm.policy_idx_hmask); 326 return __idx_hash(index, net->xfrm.policy_idx_hmask);
327} 327}
328 328
329static struct hlist_head *policy_hash_bysel(struct xfrm_selector *sel, unsigned short family, int dir) 329static struct hlist_head *policy_hash_bysel(struct net *net, struct xfrm_selector *sel, unsigned short family, int dir)
330{ 330{
331 unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask; 331 unsigned int hmask = net->xfrm.policy_bydst[dir].hmask;
332 unsigned int hash = __sel_hash(sel, family, hmask); 332 unsigned int hash = __sel_hash(sel, family, hmask);
333 333
334 return (hash == hmask + 1 ? 334 return (hash == hmask + 1 ?
335 &init_net.xfrm.policy_inexact[dir] : 335 &net->xfrm.policy_inexact[dir] :
336 init_net.xfrm.policy_bydst[dir].table + hash); 336 net->xfrm.policy_bydst[dir].table + hash);
337} 337}
338 338
339static struct hlist_head *policy_hash_direct(xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, int dir) 339static struct hlist_head *policy_hash_direct(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, int dir)
340{ 340{
341 unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask; 341 unsigned int hmask = net->xfrm.policy_bydst[dir].hmask;
342 unsigned int hash = __addr_hash(daddr, saddr, family, hmask); 342 unsigned int hash = __addr_hash(daddr, saddr, family, hmask);
343 343
344 return init_net.xfrm.policy_bydst[dir].table + hash; 344 return net->xfrm.policy_bydst[dir].table + hash;
345} 345}
346 346
347static void xfrm_dst_hash_transfer(struct hlist_head *list, 347static void xfrm_dst_hash_transfer(struct hlist_head *list,
@@ -508,7 +508,7 @@ static void xfrm_hash_resize(struct work_struct *work)
508 508
509/* Generate new index... KAME seems to generate them ordered by cost 509/* Generate new index... KAME seems to generate them ordered by cost
510 * of an absolute inpredictability of ordering of rules. This will not pass. */ 510 * of an absolute inpredictability of ordering of rules. This will not pass. */
511static u32 xfrm_gen_index(int dir) 511static u32 xfrm_gen_index(struct net *net, int dir)
512{ 512{
513 static u32 idx_generator; 513 static u32 idx_generator;
514 514
@@ -523,7 +523,7 @@ static u32 xfrm_gen_index(int dir)
523 idx_generator += 8; 523 idx_generator += 8;
524 if (idx == 0) 524 if (idx == 0)
525 idx = 8; 525 idx = 8;
526 list = init_net.xfrm.policy_byidx + idx_hash(&init_net, idx); 526 list = net->xfrm.policy_byidx + idx_hash(net, idx);
527 found = 0; 527 found = 0;
528 hlist_for_each_entry(p, entry, list, byidx) { 528 hlist_for_each_entry(p, entry, list, byidx) {
529 if (p->index == idx) { 529 if (p->index == idx) {
@@ -553,6 +553,7 @@ static inline int selector_cmp(struct xfrm_selector *s1, struct xfrm_selector *s
553 553
554int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) 554int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
555{ 555{
556 struct net *net = xp_net(policy);
556 struct xfrm_policy *pol; 557 struct xfrm_policy *pol;
557 struct xfrm_policy *delpol; 558 struct xfrm_policy *delpol;
558 struct hlist_head *chain; 559 struct hlist_head *chain;
@@ -560,7 +561,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
560 struct dst_entry *gc_list; 561 struct dst_entry *gc_list;
561 562
562 write_lock_bh(&xfrm_policy_lock); 563 write_lock_bh(&xfrm_policy_lock);
563 chain = policy_hash_bysel(&policy->selector, policy->family, dir); 564 chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
564 delpol = NULL; 565 delpol = NULL;
565 newpos = NULL; 566 newpos = NULL;
566 hlist_for_each_entry(pol, entry, chain, bydst) { 567 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 else 588 else
588 hlist_add_head(&policy->bydst, chain); 589 hlist_add_head(&policy->bydst, chain);
589 xfrm_pol_hold(policy); 590 xfrm_pol_hold(policy);
590 init_net.xfrm.policy_count[dir]++; 591 net->xfrm.policy_count[dir]++;
591 atomic_inc(&flow_cache_genid); 592 atomic_inc(&flow_cache_genid);
592 if (delpol) { 593 if (delpol) {
593 hlist_del(&delpol->bydst); 594 hlist_del(&delpol->bydst);
594 hlist_del(&delpol->byidx); 595 hlist_del(&delpol->byidx);
595 list_del(&delpol->walk.all); 596 list_del(&delpol->walk.all);
596 init_net.xfrm.policy_count[dir]--; 597 net->xfrm.policy_count[dir]--;
597 } 598 }
598 policy->index = delpol ? delpol->index : xfrm_gen_index(dir); 599 policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir);
599 hlist_add_head(&policy->byidx, init_net.xfrm.policy_byidx+idx_hash(&init_net, policy->index)); 600 hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index));
600 policy->curlft.add_time = get_seconds(); 601 policy->curlft.add_time = get_seconds();
601 policy->curlft.use_time = 0; 602 policy->curlft.use_time = 0;
602 if (!mod_timer(&policy->timer, jiffies + HZ)) 603 if (!mod_timer(&policy->timer, jiffies + HZ))
603 xfrm_pol_hold(policy); 604 xfrm_pol_hold(policy);
604 list_add(&policy->walk.all, &init_net.xfrm.policy_all); 605 list_add(&policy->walk.all, &net->xfrm.policy_all);
605 write_unlock_bh(&xfrm_policy_lock); 606 write_unlock_bh(&xfrm_policy_lock);
606 607
607 if (delpol) 608 if (delpol)
608 xfrm_policy_kill(delpol); 609 xfrm_policy_kill(delpol);
609 else if (xfrm_bydst_should_resize(&init_net, dir, NULL)) 610 else if (xfrm_bydst_should_resize(net, dir, NULL))
610 schedule_work(&init_net.xfrm.policy_hash_work); 611 schedule_work(&net->xfrm.policy_hash_work);
611 612
612 read_lock_bh(&xfrm_policy_lock); 613 read_lock_bh(&xfrm_policy_lock);
613 gc_list = NULL; 614 gc_list = NULL;
@@ -652,7 +653,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
652 653
653 *err = 0; 654 *err = 0;
654 write_lock_bh(&xfrm_policy_lock); 655 write_lock_bh(&xfrm_policy_lock);
655 chain = policy_hash_bysel(sel, sel->family, dir); 656 chain = policy_hash_bysel(&init_net, sel, sel->family, dir);
656 ret = NULL; 657 ret = NULL;
657 hlist_for_each_entry(pol, entry, chain, bydst) { 658 hlist_for_each_entry(pol, entry, chain, bydst) {
658 if (pol->type == type && 659 if (pol->type == type &&
@@ -955,7 +956,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
955 return NULL; 956 return NULL;
956 957
957 read_lock_bh(&xfrm_policy_lock); 958 read_lock_bh(&xfrm_policy_lock);
958 chain = policy_hash_direct(daddr, saddr, family, dir); 959 chain = policy_hash_direct(&init_net, daddr, saddr, family, dir);
959 ret = NULL; 960 ret = NULL;
960 hlist_for_each_entry(pol, entry, chain, bydst) { 961 hlist_for_each_entry(pol, entry, chain, bydst) {
961 err = xfrm_policy_match(pol, fl, type, family, dir); 962 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
1070static void __xfrm_policy_link(struct xfrm_policy *pol, int dir) 1071static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
1071{ 1072{
1072 struct net *net = xp_net(pol); 1073 struct net *net = xp_net(pol);
1073 struct hlist_head *chain = policy_hash_bysel(&pol->selector, 1074 struct hlist_head *chain = policy_hash_bysel(net, &pol->selector,
1074 pol->family, dir); 1075 pol->family, dir);
1075 1076
1076 list_add(&pol->walk.all, &net->xfrm.policy_all); 1077 list_add(&pol->walk.all, &net->xfrm.policy_all);
@@ -1116,6 +1117,7 @@ EXPORT_SYMBOL(xfrm_policy_delete);
1116 1117
1117int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) 1118int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
1118{ 1119{
1120 struct net *net = xp_net(pol);
1119 struct xfrm_policy *old_pol; 1121 struct xfrm_policy *old_pol;
1120 1122
1121#ifdef CONFIG_XFRM_SUB_POLICY 1123#ifdef CONFIG_XFRM_SUB_POLICY
@@ -1128,7 +1130,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
1128 sk->sk_policy[dir] = pol; 1130 sk->sk_policy[dir] = pol;
1129 if (pol) { 1131 if (pol) {
1130 pol->curlft.add_time = get_seconds(); 1132 pol->curlft.add_time = get_seconds();
1131 pol->index = xfrm_gen_index(XFRM_POLICY_MAX+dir); 1133 pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir);
1132 __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir); 1134 __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
1133 } 1135 }
1134 if (old_pol) 1136 if (old_pol)
@@ -2595,7 +2597,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(struct xfrm_selector *sel,
2595 u32 priority = ~0U; 2597 u32 priority = ~0U;
2596 2598
2597 read_lock_bh(&xfrm_policy_lock); 2599 read_lock_bh(&xfrm_policy_lock);
2598 chain = policy_hash_direct(&sel->daddr, &sel->saddr, sel->family, dir); 2600 chain = policy_hash_direct(&init_net, &sel->daddr, &sel->saddr, sel->family, dir);
2599 hlist_for_each_entry(pol, entry, chain, bydst) { 2601 hlist_for_each_entry(pol, entry, chain, bydst) {
2600 if (xfrm_migrate_selector_match(sel, &pol->selector) && 2602 if (xfrm_migrate_selector_match(sel, &pol->selector) &&
2601 pol->type == type) { 2603 pol->type == type) {