diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:24:15 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:24:15 -0500 |
commit | dc2caba7b321289e7d02e63d7216961ccecfa103 (patch) | |
tree | 639c3da4e2a2b35af3b4dfe980994ce7f9a27c0e | |
parent | a35f6c5de32664d82c072a7e2c7d5c5234de4158 (diff) |
netns xfrm: per-netns policy counts
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 | 1 | ||||
-rw-r--r-- | include/net/xfrm.h | 6 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 34 |
3 files changed, 19 insertions, 22 deletions
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index 39cfa799fa90..d5aadf06be46 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h | |||
@@ -37,6 +37,7 @@ struct netns_xfrm { | |||
37 | unsigned int policy_idx_hmask; | 37 | unsigned int policy_idx_hmask; |
38 | struct hlist_head policy_inexact[XFRM_POLICY_MAX * 2]; | 38 | struct hlist_head policy_inexact[XFRM_POLICY_MAX * 2]; |
39 | struct xfrm_policy_hash policy_bydst[XFRM_POLICY_MAX * 2]; | 39 | struct xfrm_policy_hash policy_bydst[XFRM_POLICY_MAX * 2]; |
40 | unsigned int policy_count[XFRM_POLICY_MAX * 2]; | ||
40 | }; | 41 | }; |
41 | 42 | ||
42 | #endif | 43 | #endif |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 1ab17565f01c..8699620f8c2d 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -559,8 +559,6 @@ struct xfrm_mgr | |||
559 | extern int xfrm_register_km(struct xfrm_mgr *km); | 559 | extern int xfrm_register_km(struct xfrm_mgr *km); |
560 | extern int xfrm_unregister_km(struct xfrm_mgr *km); | 560 | extern int xfrm_unregister_km(struct xfrm_mgr *km); |
561 | 561 | ||
562 | extern unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2]; | ||
563 | |||
564 | /* | 562 | /* |
565 | * This structure is used for the duration where packets are being | 563 | * This structure is used for the duration where packets are being |
566 | * transformed by IPsec. As soon as the packet leaves IPsec the | 564 | * transformed by IPsec. As soon as the packet leaves IPsec the |
@@ -999,7 +997,7 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir, | |||
999 | if (sk && sk->sk_policy[XFRM_POLICY_IN]) | 997 | if (sk && sk->sk_policy[XFRM_POLICY_IN]) |
1000 | return __xfrm_policy_check(sk, ndir, skb, family); | 998 | return __xfrm_policy_check(sk, ndir, skb, family); |
1001 | 999 | ||
1002 | return (!xfrm_policy_count[dir] && !skb->sp) || | 1000 | return (!init_net.xfrm.policy_count[dir] && !skb->sp) || |
1003 | (skb->dst->flags & DST_NOPOLICY) || | 1001 | (skb->dst->flags & DST_NOPOLICY) || |
1004 | __xfrm_policy_check(sk, ndir, skb, family); | 1002 | __xfrm_policy_check(sk, ndir, skb, family); |
1005 | } | 1003 | } |
@@ -1051,7 +1049,7 @@ extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family); | |||
1051 | 1049 | ||
1052 | static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) | 1050 | static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) |
1053 | { | 1051 | { |
1054 | return !xfrm_policy_count[XFRM_POLICY_OUT] || | 1052 | return !init_net.xfrm.policy_count[XFRM_POLICY_OUT] || |
1055 | (skb->dst->flags & DST_NOXFRM) || | 1053 | (skb->dst->flags & DST_NOXFRM) || |
1056 | __xfrm_route_forward(skb, family); | 1054 | __xfrm_route_forward(skb, family); |
1057 | } | 1055 | } |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 929b2fdaa2ef..630ec048a0d3 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -46,9 +46,6 @@ EXPORT_SYMBOL(xfrm_cfg_mutex); | |||
46 | 46 | ||
47 | static DEFINE_RWLOCK(xfrm_policy_lock); | 47 | static DEFINE_RWLOCK(xfrm_policy_lock); |
48 | 48 | ||
49 | unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2]; | ||
50 | EXPORT_SYMBOL(xfrm_policy_count); | ||
51 | |||
52 | static DEFINE_RWLOCK(xfrm_policy_afinfo_lock); | 49 | static DEFINE_RWLOCK(xfrm_policy_afinfo_lock); |
53 | static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO]; | 50 | static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO]; |
54 | 51 | ||
@@ -451,7 +448,7 @@ static void xfrm_byidx_resize(int total) | |||
451 | 448 | ||
452 | static inline int xfrm_bydst_should_resize(int dir, int *total) | 449 | static inline int xfrm_bydst_should_resize(int dir, int *total) |
453 | { | 450 | { |
454 | unsigned int cnt = xfrm_policy_count[dir]; | 451 | unsigned int cnt = init_net.xfrm.policy_count[dir]; |
455 | unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask; | 452 | unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask; |
456 | 453 | ||
457 | if (total) | 454 | if (total) |
@@ -478,12 +475,12 @@ static inline int xfrm_byidx_should_resize(int total) | |||
478 | void xfrm_spd_getinfo(struct xfrmk_spdinfo *si) | 475 | void xfrm_spd_getinfo(struct xfrmk_spdinfo *si) |
479 | { | 476 | { |
480 | read_lock_bh(&xfrm_policy_lock); | 477 | read_lock_bh(&xfrm_policy_lock); |
481 | si->incnt = xfrm_policy_count[XFRM_POLICY_IN]; | 478 | si->incnt = init_net.xfrm.policy_count[XFRM_POLICY_IN]; |
482 | si->outcnt = xfrm_policy_count[XFRM_POLICY_OUT]; | 479 | si->outcnt = init_net.xfrm.policy_count[XFRM_POLICY_OUT]; |
483 | si->fwdcnt = xfrm_policy_count[XFRM_POLICY_FWD]; | 480 | si->fwdcnt = init_net.xfrm.policy_count[XFRM_POLICY_FWD]; |
484 | si->inscnt = xfrm_policy_count[XFRM_POLICY_IN+XFRM_POLICY_MAX]; | 481 | si->inscnt = init_net.xfrm.policy_count[XFRM_POLICY_IN+XFRM_POLICY_MAX]; |
485 | si->outscnt = xfrm_policy_count[XFRM_POLICY_OUT+XFRM_POLICY_MAX]; | 482 | si->outscnt = init_net.xfrm.policy_count[XFRM_POLICY_OUT+XFRM_POLICY_MAX]; |
486 | si->fwdscnt = xfrm_policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX]; | 483 | si->fwdscnt = init_net.xfrm.policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX]; |
487 | si->spdhcnt = init_net.xfrm.policy_idx_hmask; | 484 | si->spdhcnt = init_net.xfrm.policy_idx_hmask; |
488 | si->spdhmcnt = xfrm_policy_hashmax; | 485 | si->spdhmcnt = xfrm_policy_hashmax; |
489 | read_unlock_bh(&xfrm_policy_lock); | 486 | read_unlock_bh(&xfrm_policy_lock); |
@@ -591,13 +588,13 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
591 | else | 588 | else |
592 | hlist_add_head(&policy->bydst, chain); | 589 | hlist_add_head(&policy->bydst, chain); |
593 | xfrm_pol_hold(policy); | 590 | xfrm_pol_hold(policy); |
594 | xfrm_policy_count[dir]++; | 591 | init_net.xfrm.policy_count[dir]++; |
595 | atomic_inc(&flow_cache_genid); | 592 | atomic_inc(&flow_cache_genid); |
596 | if (delpol) { | 593 | if (delpol) { |
597 | hlist_del(&delpol->bydst); | 594 | hlist_del(&delpol->bydst); |
598 | hlist_del(&delpol->byidx); | 595 | hlist_del(&delpol->byidx); |
599 | list_del(&delpol->walk.all); | 596 | list_del(&delpol->walk.all); |
600 | xfrm_policy_count[dir]--; | 597 | init_net.xfrm.policy_count[dir]--; |
601 | } | 598 | } |
602 | policy->index = delpol ? delpol->index : xfrm_gen_index(dir); | 599 | policy->index = delpol ? delpol->index : xfrm_gen_index(dir); |
603 | hlist_add_head(&policy->byidx, init_net.xfrm.policy_byidx+idx_hash(policy->index)); | 600 | hlist_add_head(&policy->byidx, init_net.xfrm.policy_byidx+idx_hash(policy->index)); |
@@ -673,7 +670,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, | |||
673 | hlist_del(&pol->bydst); | 670 | hlist_del(&pol->bydst); |
674 | hlist_del(&pol->byidx); | 671 | hlist_del(&pol->byidx); |
675 | list_del(&pol->walk.all); | 672 | list_del(&pol->walk.all); |
676 | xfrm_policy_count[dir]--; | 673 | init_net.xfrm.policy_count[dir]--; |
677 | } | 674 | } |
678 | ret = pol; | 675 | ret = pol; |
679 | break; | 676 | break; |
@@ -717,7 +714,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, | |||
717 | hlist_del(&pol->bydst); | 714 | hlist_del(&pol->bydst); |
718 | hlist_del(&pol->byidx); | 715 | hlist_del(&pol->byidx); |
719 | list_del(&pol->walk.all); | 716 | list_del(&pol->walk.all); |
720 | xfrm_policy_count[dir]--; | 717 | init_net.xfrm.policy_count[dir]--; |
721 | } | 718 | } |
722 | ret = pol; | 719 | ret = pol; |
723 | break; | 720 | break; |
@@ -845,7 +842,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | |||
845 | } | 842 | } |
846 | } | 843 | } |
847 | 844 | ||
848 | xfrm_policy_count[dir] -= killed; | 845 | init_net.xfrm.policy_count[dir] -= killed; |
849 | } | 846 | } |
850 | atomic_inc(&flow_cache_genid); | 847 | atomic_inc(&flow_cache_genid); |
851 | out: | 848 | out: |
@@ -1079,7 +1076,7 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir) | |||
1079 | list_add(&pol->walk.all, &init_net.xfrm.policy_all); | 1076 | list_add(&pol->walk.all, &init_net.xfrm.policy_all); |
1080 | hlist_add_head(&pol->bydst, chain); | 1077 | hlist_add_head(&pol->bydst, chain); |
1081 | hlist_add_head(&pol->byidx, init_net.xfrm.policy_byidx+idx_hash(pol->index)); | 1078 | hlist_add_head(&pol->byidx, init_net.xfrm.policy_byidx+idx_hash(pol->index)); |
1082 | xfrm_policy_count[dir]++; | 1079 | init_net.xfrm.policy_count[dir]++; |
1083 | xfrm_pol_hold(pol); | 1080 | xfrm_pol_hold(pol); |
1084 | 1081 | ||
1085 | if (xfrm_bydst_should_resize(dir, NULL)) | 1082 | if (xfrm_bydst_should_resize(dir, NULL)) |
@@ -1095,7 +1092,7 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, | |||
1095 | hlist_del(&pol->bydst); | 1092 | hlist_del(&pol->bydst); |
1096 | hlist_del(&pol->byidx); | 1093 | hlist_del(&pol->byidx); |
1097 | list_del(&pol->walk.all); | 1094 | list_del(&pol->walk.all); |
1098 | xfrm_policy_count[dir]--; | 1095 | init_net.xfrm.policy_count[dir]--; |
1099 | 1096 | ||
1100 | return pol; | 1097 | return pol; |
1101 | } | 1098 | } |
@@ -1574,7 +1571,7 @@ restart: | |||
1574 | if (!policy) { | 1571 | if (!policy) { |
1575 | /* To accelerate a bit... */ | 1572 | /* To accelerate a bit... */ |
1576 | if ((dst_orig->flags & DST_NOXFRM) || | 1573 | if ((dst_orig->flags & DST_NOXFRM) || |
1577 | !xfrm_policy_count[XFRM_POLICY_OUT]) | 1574 | !init_net.xfrm.policy_count[XFRM_POLICY_OUT]) |
1578 | goto nopol; | 1575 | goto nopol; |
1579 | 1576 | ||
1580 | policy = flow_cache_lookup(fl, dst_orig->ops->family, | 1577 | policy = flow_cache_lookup(fl, dst_orig->ops->family, |
@@ -2407,6 +2404,7 @@ static int __net_init xfrm_policy_init(struct net *net) | |||
2407 | for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) { | 2404 | for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) { |
2408 | struct xfrm_policy_hash *htab; | 2405 | struct xfrm_policy_hash *htab; |
2409 | 2406 | ||
2407 | net->xfrm.policy_count[dir] = 0; | ||
2410 | INIT_HLIST_HEAD(&net->xfrm.policy_inexact[dir]); | 2408 | INIT_HLIST_HEAD(&net->xfrm.policy_inexact[dir]); |
2411 | 2409 | ||
2412 | htab = &net->xfrm.policy_bydst[dir]; | 2410 | htab = &net->xfrm.policy_bydst[dir]; |