diff options
author | Timo Teräs <timo.teras@iki.fi> | 2010-04-06 20:30:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-07 06:43:19 -0400 |
commit | 80c802f3073e84c956846e921e8a0b02dfa3755f (patch) | |
tree | 895dc92dcf6b658d78838e0a23db3dd29c8be695 /include/net | |
parent | fe1a5f031e76bd8761a7803d75b95ee96e84a574 (diff) |
xfrm: cache bundles instead of policies for outgoing flows
__xfrm_lookup() is called for each packet transmitted out of
system. The xfrm_find_bundle() does a linear search which can
kill system performance depending on how many bundles are
required per policy.
This modifies __xfrm_lookup() to store bundles directly in
the flow cache. If we did not get a hit, we just create a new
bundle instead of doing slow search. This means that we can now
get multiple xfrm_dst's for same flow (on per-cpu basis).
Signed-off-by: Timo Teras <timo.teras@iki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/xfrm.h | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 35396e2dd1dc..625dd61ccbba 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -267,7 +267,6 @@ struct xfrm_policy_afinfo { | |||
267 | xfrm_address_t *saddr, | 267 | xfrm_address_t *saddr, |
268 | xfrm_address_t *daddr); | 268 | xfrm_address_t *daddr); |
269 | int (*get_saddr)(struct net *net, xfrm_address_t *saddr, xfrm_address_t *daddr); | 269 | int (*get_saddr)(struct net *net, xfrm_address_t *saddr, xfrm_address_t *daddr); |
270 | struct dst_entry *(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy); | ||
271 | void (*decode_session)(struct sk_buff *skb, | 270 | void (*decode_session)(struct sk_buff *skb, |
272 | struct flowi *fl, | 271 | struct flowi *fl, |
273 | int reverse); | 272 | int reverse); |
@@ -483,13 +482,13 @@ struct xfrm_policy { | |||
483 | struct timer_list timer; | 482 | struct timer_list timer; |
484 | 483 | ||
485 | struct flow_cache_object flo; | 484 | struct flow_cache_object flo; |
485 | atomic_t genid; | ||
486 | u32 priority; | 486 | u32 priority; |
487 | u32 index; | 487 | u32 index; |
488 | struct xfrm_mark mark; | 488 | struct xfrm_mark mark; |
489 | struct xfrm_selector selector; | 489 | struct xfrm_selector selector; |
490 | struct xfrm_lifetime_cfg lft; | 490 | struct xfrm_lifetime_cfg lft; |
491 | struct xfrm_lifetime_cur curlft; | 491 | struct xfrm_lifetime_cur curlft; |
492 | struct dst_entry *bundles; | ||
493 | struct xfrm_policy_walk_entry walk; | 492 | struct xfrm_policy_walk_entry walk; |
494 | u8 type; | 493 | u8 type; |
495 | u8 action; | 494 | u8 action; |
@@ -879,11 +878,15 @@ struct xfrm_dst { | |||
879 | struct rt6_info rt6; | 878 | struct rt6_info rt6; |
880 | } u; | 879 | } u; |
881 | struct dst_entry *route; | 880 | struct dst_entry *route; |
881 | struct flow_cache_object flo; | ||
882 | struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; | ||
883 | int num_pols, num_xfrms; | ||
882 | #ifdef CONFIG_XFRM_SUB_POLICY | 884 | #ifdef CONFIG_XFRM_SUB_POLICY |
883 | struct flowi *origin; | 885 | struct flowi *origin; |
884 | struct xfrm_selector *partner; | 886 | struct xfrm_selector *partner; |
885 | #endif | 887 | #endif |
886 | u32 genid; | 888 | u32 xfrm_genid; |
889 | u32 policy_genid; | ||
887 | u32 route_mtu_cached; | 890 | u32 route_mtu_cached; |
888 | u32 child_mtu_cached; | 891 | u32 child_mtu_cached; |
889 | u32 route_cookie; | 892 | u32 route_cookie; |
@@ -893,6 +896,7 @@ struct xfrm_dst { | |||
893 | #ifdef CONFIG_XFRM | 896 | #ifdef CONFIG_XFRM |
894 | static inline void xfrm_dst_destroy(struct xfrm_dst *xdst) | 897 | static inline void xfrm_dst_destroy(struct xfrm_dst *xdst) |
895 | { | 898 | { |
899 | xfrm_pols_put(xdst->pols, xdst->num_pols); | ||
896 | dst_release(xdst->route); | 900 | dst_release(xdst->route); |
897 | if (likely(xdst->u.dst.xfrm)) | 901 | if (likely(xdst->u.dst.xfrm)) |
898 | xfrm_state_put(xdst->u.dst.xfrm); | 902 | xfrm_state_put(xdst->u.dst.xfrm); |