aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-08-24 07:45:07 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:08:48 -0400
commit2518c7c2b3d7f0a6b302b4efe17c911f8dd4049f (patch)
tree7de05ca17d76eee141d4feff3b7b27d850557ae6 /include/net
parentc1969f294e624d5b642fc8e6ab9468b7c7791fa8 (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.h23
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
331struct xfrm_policy 331struct 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
385extern int xfrm_register_km(struct xfrm_mgr *km); 386extern int xfrm_register_km(struct xfrm_mgr *km);
386extern int xfrm_unregister_km(struct xfrm_mgr *km); 387extern int xfrm_unregister_km(struct xfrm_mgr *km);
387 388
388 389extern unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
389extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2];
390#ifdef CONFIG_XFRM_SUB_POLICY
391extern struct xfrm_policy *xfrm_policy_list_sub[XFRM_POLICY_MAX*2];
392
393static inline int xfrm_policy_lists_empty(int dir)
394{
395 return (!xfrm_policy_list[dir] && !xfrm_policy_list_sub[dir]);
396}
397#else
398static inline int xfrm_policy_lists_empty(int dir)
399{
400 return (!xfrm_policy_list[dir]);
401}
402#endif
403 390
404static inline void xfrm_pol_hold(struct xfrm_policy *policy) 391static 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
699static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) 686static 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}