aboutsummaryrefslogtreecommitdiffstats
path: root/net/key
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-10-09 16:29:52 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:55:01 -0400
commit658b219e9379d75fbdc578b9630b598098471258 (patch)
treefe802c4e1ee6468a9c2558a5e529b2380845a003 /net/key
parent75ba28c633952f7994a7117c98ae6515b58f8d30 (diff)
[IPSEC]: Move common code into xfrm_alloc_spi
This patch moves some common code that conceptually belongs to the xfrm core from af_key/xfrm_user into xfrm_alloc_spi. In particular, the spin lock on the state is now taken inside xfrm_alloc_spi. Previously it also protected the construction of the response PF_KEY/XFRM messages to user-space. This is inconsistent as other identical constructions are not protected by the state lock. This is bad because they in fact should be protected but only in certain spots (so as not to hold the lock for too long which may cause packet drops). The SPI byte order conversion has also been moved. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/key')
-rw-r--r--net/key/af_key.c29
1 files changed, 12 insertions, 17 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index ff5c3d03005e..143d46f6329a 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1253,8 +1253,11 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1253 struct sadb_x_sa2 *sa2; 1253 struct sadb_x_sa2 *sa2;
1254 struct sadb_address *saddr, *daddr; 1254 struct sadb_address *saddr, *daddr;
1255 struct sadb_msg *out_hdr; 1255 struct sadb_msg *out_hdr;
1256 struct sadb_spirange *range;
1256 struct xfrm_state *x = NULL; 1257 struct xfrm_state *x = NULL;
1257 int mode; 1258 int mode;
1259 int err;
1260 u32 min_spi, max_spi;
1258 u32 reqid; 1261 u32 reqid;
1259 u8 proto; 1262 u8 proto;
1260 unsigned short family; 1263 unsigned short family;
@@ -1309,25 +1312,17 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1309 if (x == NULL) 1312 if (x == NULL)
1310 return -ENOENT; 1313 return -ENOENT;
1311 1314
1312 resp_skb = ERR_PTR(-ENOENT); 1315 min_spi = 0x100;
1313 1316 max_spi = 0x0fffffff;
1314 spin_lock_bh(&x->lock);
1315 if (x->km.state != XFRM_STATE_DEAD) {
1316 struct sadb_spirange *range = ext_hdrs[SADB_EXT_SPIRANGE-1];
1317 u32 min_spi, max_spi;
1318 1317
1319 if (range != NULL) { 1318 range = ext_hdrs[SADB_EXT_SPIRANGE-1];
1320 min_spi = range->sadb_spirange_min; 1319 if (range) {
1321 max_spi = range->sadb_spirange_max; 1320 min_spi = range->sadb_spirange_min;
1322 } else { 1321 max_spi = range->sadb_spirange_max;
1323 min_spi = 0x100;
1324 max_spi = 0x0fffffff;
1325 }
1326 xfrm_alloc_spi(x, htonl(min_spi), htonl(max_spi));
1327 if (x->id.spi)
1328 resp_skb = pfkey_xfrm_state2msg(x, 0, 3);
1329 } 1322 }
1330 spin_unlock_bh(&x->lock); 1323
1324 err = xfrm_alloc_spi(x, min_spi, max_spi);
1325 resp_skb = err ? ERR_PTR(err) : pfkey_xfrm_state2msg(x, 0, 3);
1331 1326
1332 if (IS_ERR(resp_skb)) { 1327 if (IS_ERR(resp_skb)) {
1333 xfrm_state_put(x); 1328 xfrm_state_put(x);