From 667bbcb6c099d1b74f95c6963ddf37a32e7afc29 Mon Sep 17 00:00:00 2001 From: Masahide NAKAMURA Date: Tue, 3 Oct 2006 15:56:09 -0700 Subject: [PATCH] [XFRM] STATE: Use destination address for src hash. Src hash is introduced for Mobile IPv6 route optimization usage. On current kenrel code it is calculated with source address only. It results we uses the same hash value for outbound state (when the node has only one address for Mobile IPv6). This patch use also destination address as peer information for src hash to be dispersed. Signed-off-by: Masahide NAKAMURA Signed-off-by: David S. Miller --- net/xfrm/xfrm_hash.h | 7 ++++--- net/xfrm/xfrm_state.c | 16 +++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/net/xfrm/xfrm_hash.h b/net/xfrm/xfrm_hash.h index 6ac4e4f033..d401dc8f05 100644 --- a/net/xfrm/xfrm_hash.h +++ b/net/xfrm/xfrm_hash.h @@ -41,17 +41,18 @@ static inline unsigned int __xfrm_dst_hash(xfrm_address_t *daddr, xfrm_address_t return (h ^ (h >> 16)) & hmask; } -static inline unsigned __xfrm_src_hash(xfrm_address_t *saddr, +static inline unsigned __xfrm_src_hash(xfrm_address_t *daddr, + xfrm_address_t *saddr, unsigned short family, unsigned int hmask) { unsigned int h = family; switch (family) { case AF_INET: - h ^= __xfrm4_addr_hash(saddr); + h ^= __xfrm4_daddr_saddr_hash(daddr, saddr); break; case AF_INET6: - h ^= __xfrm6_addr_hash(saddr); + h ^= __xfrm6_daddr_saddr_hash(daddr, saddr); break; }; return (h ^ (h >> 16)) & hmask; diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index f927b7330f..39b8bf3a9d 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -63,10 +63,11 @@ static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr, return __xfrm_dst_hash(daddr, saddr, reqid, family, xfrm_state_hmask); } -static inline unsigned int xfrm_src_hash(xfrm_address_t *addr, +static inline unsigned int xfrm_src_hash(xfrm_address_t *daddr, + xfrm_address_t *saddr, unsigned short family) { - return __xfrm_src_hash(addr, family, xfrm_state_hmask); + return __xfrm_src_hash(daddr, saddr, family, xfrm_state_hmask); } static inline unsigned int @@ -92,7 +93,8 @@ static void xfrm_hash_transfer(struct hlist_head *list, nhashmask); hlist_add_head(&x->bydst, ndsttable+h); - h = __xfrm_src_hash(&x->props.saddr, x->props.family, + h = __xfrm_src_hash(&x->id.daddr, &x->props.saddr, + x->props.family, nhashmask); hlist_add_head(&x->bysrc, nsrctable+h); @@ -458,7 +460,7 @@ static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family) { - unsigned int h = xfrm_src_hash(saddr, family); + unsigned int h = xfrm_src_hash(daddr, saddr, family); struct xfrm_state *x; struct hlist_node *entry; @@ -587,7 +589,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, if (km_query(x, tmpl, pol) == 0) { x->km.state = XFRM_STATE_ACQ; hlist_add_head(&x->bydst, xfrm_state_bydst+h); - h = xfrm_src_hash(saddr, family); + h = xfrm_src_hash(daddr, saddr, family); hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); if (x->id.spi) { h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family); @@ -622,7 +624,7 @@ static void __xfrm_state_insert(struct xfrm_state *x) x->props.reqid, x->props.family); hlist_add_head(&x->bydst, xfrm_state_bydst+h); - h = xfrm_src_hash(&x->props.saddr, x->props.family); + h = xfrm_src_hash(&x->id.daddr, &x->props.saddr, x->props.family); hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); if (x->id.spi) { @@ -748,7 +750,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; add_timer(&x->timer); hlist_add_head(&x->bydst, xfrm_state_bydst+h); - h = xfrm_src_hash(saddr, family); + h = xfrm_src_hash(daddr, saddr, family); hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); wake_up(&km_waitq); } -- 2.39.5