From patchwork Fri Sep 24 19:21:26 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Ebalard X-Patchwork-Id: 65678 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41AF0B7105 for ; Sat, 25 Sep 2010 05:21:40 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757650Ab0IXTU6 (ORCPT ); Fri, 24 Sep 2010 15:20:58 -0400 Received: from copper.chdir.org ([88.191.97.87]:40710 "EHLO copper.chdir.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757643Ab0IXTU4 (ORCPT ); Fri, 24 Sep 2010 15:20:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=natisbad.org; s=mail; h=From:To:Cc:Subject:References:Date: Message-ID:MIME-Version:Content-Type; bh=Xct4Dmpx8zA/eaxoU+Gyfyt zyBK87hHMEp6nN8gcmOk=; b=PKhozoDh/fUEpJVCMhIVz8SttIbQSgqVGCONiRq TNS6ayBvX8NIXzlP8SXn5BLWszczHMT5wa5dArewwZkCG1QiL2kNt6nrgp70rYZy q+MnYJklRZeTpIHNECJQ1x3k7R1zqUpa2Kc4/7RU/qzgky+uKgDwyCH/ZAbsLINC Aews= Received: from [2001:7a8:78df:2:20d:93ff:fe55:8f79] (helo=small.ssi.corp) by copper.chdir.org with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.69) (envelope-from ) id 1OzDpF-0008PR-TS; Fri, 24 Sep 2010 21:20:55 +0200 X-Hashcash: 1:20:100924:davem@davemloft.net::yUwJib1GUfxSrm80:0000000000000000000000000000000000000000005kw6 X-Hashcash: 1:20:100924:eric.dumazet@gmail.com::84FYwvOOyJszWa1R:0000000000000000000000000000000000000005LZT X-Hashcash: 1:20:100924:herbert@gondor.apana.org.au::U1vSiUAkK/gGbqxK:00000000000000000000000000000000006cAI X-Hashcash: 1:20:100924:yoshfuji@linux-ipv6.org::sf/U/me/uluF+x1R:000000000000000000000000000000000000001I6r X-Hashcash: 1:20:100924:netdev@vger.kernel.org::m+jk4x1MRgXwyG+V:00000000000000000000000000000000000000033As From: arno@natisbad.org (Arnaud Ebalard) To: "David S. Miller" , Eric Dumazet , Herbert Xu , Hideaki YOSHIFUJI Cc: netdev@vger.kernel.org Subject: [PATCH net-next-2.6 1/5] XFRM, IPv6: Remove xfrm_spi_hash() dependency on destination address References: <87bp7nrlvy.fsf@small.ssi.corp> X-PGP-Key-URL: http://natisbad.org/arno@natisbad.org.asc X-Fingerprint: D3A5 B68A 839B 38A5 815A 781B B77C 0748 A7AE 341B Date: Fri, 24 Sep 2010 21:21:26 +0200 Message-ID: <874odfrlqh.fsf@small.ssi.corp> User-Agent: Gnus/5.110009 (No Gnus v0.9) Emacs/23.1.50 (gnu/linux) MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In the new IPsec architecture [RFC4301], "for an SA used to carry unicast traffic, the Security Parameters Index (SPI) by itself suffices to specify an SA". Section 4.1 of [RFC4301] provides additional guidance on the topic. In the old IPsec architecture [RFC2401], a SA "is uniquely identified by a triple consisting of a Security Parameter Index (SPI), an IP Destination Address and a security protocol (AH or ESP) identifier". If an IPsec stack only supports the behavior mandated by the old IPsec architecture, SAD lookup on inbound packets require the use of both the SPI and the destination address of the SA. For inbound IPsec traffic, IRO remapping rules may exist on the MN to remap the destination address (CoA) into the HoA. In that case, by design, the address found in the destination address field of the packet (CoA) does not match the one in the SA (HoA). At the moment, Linux XFRM stack includes the address when computing the hash to perform state lookup by SPI. This patch changes XFRM state hash computation to prevent destination address to be used. This will later allow finding states for packets w/ mangled destination addresses. Signed-off-by: Arnaud Ebalard --- net/xfrm/xfrm_hash.h | 21 +-------------------- net/xfrm/xfrm_state.c | 20 ++++++++------------ 2 files changed, 9 insertions(+), 32 deletions(-) diff --git a/net/xfrm/xfrm_hash.h b/net/xfrm/xfrm_hash.h index 8e69533..19eeee7 100644 --- a/net/xfrm/xfrm_hash.h +++ b/net/xfrm/xfrm_hash.h @@ -4,16 +4,6 @@ #include #include -static inline unsigned int __xfrm4_addr_hash(xfrm_address_t *addr) -{ - return ntohl(addr->a4); -} - -static inline unsigned int __xfrm6_addr_hash(xfrm_address_t *addr) -{ - return ntohl(addr->a6[2] ^ addr->a6[3]); -} - static inline unsigned int __xfrm4_daddr_saddr_hash(xfrm_address_t *daddr, xfrm_address_t *saddr) { u32 sum = (__force u32)daddr->a4 + (__force u32)saddr->a4; @@ -60,18 +50,9 @@ static inline unsigned __xfrm_src_hash(xfrm_address_t *daddr, } static inline unsigned int -__xfrm_spi_hash(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family, - unsigned int hmask) +__xfrm_spi_hash(__be32 spi, u8 proto, unsigned int hmask) { unsigned int h = (__force u32)spi ^ proto; - switch (family) { - case AF_INET: - h ^= __xfrm4_addr_hash(daddr); - break; - case AF_INET6: - h ^= __xfrm6_addr_hash(daddr); - break; - } return (h ^ (h >> 10) ^ (h >> 20)) & hmask; } diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 5208b12..7ad4462 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -30,7 +30,7 @@ /* Each xfrm_state may be linked to two tables: - 1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl) + 1. Hash table by (spi,ah/esp) to find SA by SPI. (input,ctl) 2. Hash table by (daddr,family,reqid) to find what SAs exist for given destination/tunnel endpoint. (output) */ @@ -67,9 +67,9 @@ static inline unsigned int xfrm_src_hash(struct net *net, } static inline unsigned int -xfrm_spi_hash(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) +xfrm_spi_hash(struct net *net, __be32 spi, u8 proto) { - return __xfrm_spi_hash(daddr, spi, proto, family, net->xfrm.state_hmask); + return __xfrm_spi_hash(spi, proto, net->xfrm.state_hmask); } static void xfrm_hash_transfer(struct hlist_head *list, @@ -95,9 +95,7 @@ static void xfrm_hash_transfer(struct hlist_head *list, hlist_add_head(&x->bysrc, nsrctable+h); if (x->id.spi) { - h = __xfrm_spi_hash(&x->id.daddr, x->id.spi, - x->id.proto, x->props.family, - nhashmask); + h = __xfrm_spi_hash(x->id.spi, x->id.proto, nhashmask); hlist_add_head(&x->byspi, nspitable+h); } } @@ -671,7 +669,7 @@ xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl, static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) { - unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family); + unsigned int h = xfrm_spi_hash(net, spi, proto); struct xfrm_state *x; struct hlist_node *entry; @@ -859,7 +857,7 @@ found: h = xfrm_src_hash(net, daddr, saddr, family); hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h); if (x->id.spi) { - h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, family); + h = xfrm_spi_hash(net, x->id.spi, x->id.proto); hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); } x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; @@ -933,9 +931,7 @@ static void __xfrm_state_insert(struct xfrm_state *x) hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h); if (x->id.spi) { - h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, - x->props.family); - + h = xfrm_spi_hash(net, x->id.spi, x->id.proto); hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); } @@ -1526,7 +1522,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) } if (x->id.spi) { spin_lock_bh(&xfrm_state_lock); - h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family); + h = xfrm_spi_hash(net, x->id.spi, x->id.proto); hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); spin_unlock_bh(&xfrm_state_lock);