diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:33:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:33:06 -0500 |
commit | 1121994c803f4a4f471d617443ff2a09515725e7 (patch) | |
tree | 5d470f60fefd29b75dff5bb4a70b916904ccc879 | |
parent | e92303f872600978796ff323bc229d911f905849 (diff) |
netns xfrm: policy insertion in netns
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/xfrm/xfrm_policy.c | 46 |
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 | ||
329 | static struct hlist_head *policy_hash_bysel(struct xfrm_selector *sel, unsigned short family, int dir) | 329 | static 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 | ||
339 | static struct hlist_head *policy_hash_direct(xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, int dir) | 339 | static 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 | ||
347 | static void xfrm_dst_hash_transfer(struct hlist_head *list, | 347 | static 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. */ |
511 | static u32 xfrm_gen_index(int dir) | 511 | static 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 | ||
554 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | 554 | int 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 | |||
1070 | static void __xfrm_policy_link(struct xfrm_policy *pol, int dir) | 1071 | static 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 | ||
1117 | int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) | 1118 | int 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) { |