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;
 
        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
                                    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);
 
 
 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;
 
                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);
                          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) {
                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);
        }