diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-08-24 07:45:07 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 18:08:48 -0400 |
commit | 2518c7c2b3d7f0a6b302b4efe17c911f8dd4049f (patch) | |
tree | 7de05ca17d76eee141d4feff3b7b27d850557ae6 /include/net | |
parent | c1969f294e624d5b642fc8e6ab9468b7c7791fa8 (diff) |
[XFRM]: Hash policies when non-prefixed.
This idea is from Alexey Kuznetsov.
It is common for policies to be non-prefixed. And for
that case we can optimize lookups, insert, etc. quite
a bit.
For each direction, we have a dynamically sized policy
hash table for non-prefixed policies. We also have a
hash table on policy->index.
For prefixed policies, we have a list per-direction which
we will consult on lookups when a non-prefix hashtable
lookup fails.
This still isn't as efficient as I would like it. There
are four immediate problems:
1) Lots of excessive refcounting, which can be fixed just
like xfrm_state was
2) We do 2 hash probes on insert, one to look for dups and
one to allocate a unique policy->index. Althought I wonder
how much this matters since xfrm_state inserts do up to
3 hash probes and that seems to perform fine.
3) xfrm_policy_insert() is very complex because of the priority
ordering and entry replacement logic.
4) Lots of counter bumping, in addition to policy refcounts,
in the form of xfrm_policy_count[]. This is merely used
to let code path(s) know that some IPSEC rules exist. So
this count is indexed per-direction, maybe that is overkill.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/xfrm.h | 23 |
1 files changed, 5 insertions, 18 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index c7870b6eae01..0acabf2a0a8f 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -331,7 +331,8 @@ struct xfrm_tmpl | |||
331 | struct xfrm_policy | 331 | struct xfrm_policy |
332 | { | 332 | { |
333 | struct xfrm_policy *next; | 333 | struct xfrm_policy *next; |
334 | struct list_head list; | 334 | struct hlist_node bydst; |
335 | struct hlist_node byidx; | ||
335 | 336 | ||
336 | /* This lock only affects elements except for entry. */ | 337 | /* This lock only affects elements except for entry. */ |
337 | rwlock_t lock; | 338 | rwlock_t lock; |
@@ -385,21 +386,7 @@ struct xfrm_mgr | |||
385 | extern int xfrm_register_km(struct xfrm_mgr *km); | 386 | extern int xfrm_register_km(struct xfrm_mgr *km); |
386 | extern int xfrm_unregister_km(struct xfrm_mgr *km); | 387 | extern int xfrm_unregister_km(struct xfrm_mgr *km); |
387 | 388 | ||
388 | 389 | extern unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2]; | |
389 | extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2]; | ||
390 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
391 | extern struct xfrm_policy *xfrm_policy_list_sub[XFRM_POLICY_MAX*2]; | ||
392 | |||
393 | static inline int xfrm_policy_lists_empty(int dir) | ||
394 | { | ||
395 | return (!xfrm_policy_list[dir] && !xfrm_policy_list_sub[dir]); | ||
396 | } | ||
397 | #else | ||
398 | static inline int xfrm_policy_lists_empty(int dir) | ||
399 | { | ||
400 | return (!xfrm_policy_list[dir]); | ||
401 | } | ||
402 | #endif | ||
403 | 390 | ||
404 | static inline void xfrm_pol_hold(struct xfrm_policy *policy) | 391 | static inline void xfrm_pol_hold(struct xfrm_policy *policy) |
405 | { | 392 | { |
@@ -678,7 +665,7 @@ static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *sk | |||
678 | if (sk && sk->sk_policy[XFRM_POLICY_IN]) | 665 | if (sk && sk->sk_policy[XFRM_POLICY_IN]) |
679 | return __xfrm_policy_check(sk, dir, skb, family); | 666 | return __xfrm_policy_check(sk, dir, skb, family); |
680 | 667 | ||
681 | return (xfrm_policy_lists_empty(dir) && !skb->sp) || | 668 | return (!xfrm_policy_count[dir] && !skb->sp) || |
682 | (skb->dst->flags & DST_NOPOLICY) || | 669 | (skb->dst->flags & DST_NOPOLICY) || |
683 | __xfrm_policy_check(sk, dir, skb, family); | 670 | __xfrm_policy_check(sk, dir, skb, family); |
684 | } | 671 | } |
@@ -698,7 +685,7 @@ extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family); | |||
698 | 685 | ||
699 | static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) | 686 | static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) |
700 | { | 687 | { |
701 | return xfrm_policy_lists_empty(XFRM_POLICY_OUT) || | 688 | return !xfrm_policy_count[XFRM_POLICY_OUT] || |
702 | (skb->dst->flags & DST_NOXFRM) || | 689 | (skb->dst->flags & DST_NOXFRM) || |
703 | __xfrm_route_forward(skb, family); | 690 | __xfrm_route_forward(skb, family); |
704 | } | 691 | } |