aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-01-23 14:00:16 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-23 14:00:16 -0500
commit93b9c1ddd3fb4a5b67d512e534b30070f9ecec28 (patch)
treef9584c9b3ff6873b2be043ea08c0fbb354c040df
parent4c133c39ae1bc541b3db5903a680da738a0c57e3 (diff)
parent02bfd8ecf5cf980ede53e30a903b102924fc32f4 (diff)
Merge branch 'testing' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next
Steffen Klassert says: ==================== 1) Add a statistic counter for invalid output states and remove a superfluous state valid check, from Li RongQing. 2) Probe for asynchronous block ciphers instead of synchronous block ciphers to make the asynchronous variants available even if no synchronous block ciphers are found, from Jussi Kivilinna. 3) Make rfc3686 asynchronous block cipher and make use of the new asynchronous variant, from Jussi Kivilinna. 4) Replace some rwlocks by rcu, from Cong Wang. 5) Remove some unused defines. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c37
-rw-r--r--crypto/ctr.c173
-rw-r--r--crypto/tcrypt.c4
-rw-r--r--crypto/tcrypt.h1
-rw-r--r--include/net/xfrm.h4
-rw-r--r--include/uapi/linux/snmp.h1
-rw-r--r--net/xfrm/xfrm_algo.c3
-rw-r--r--net/xfrm/xfrm_output.c6
-rw-r--r--net/xfrm/xfrm_proc.c1
-rw-r--r--net/xfrm/xfrm_state.c131
10 files changed, 185 insertions, 176 deletions
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 1b9c22bea8a7..a0795da22c02 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -40,10 +40,6 @@
40#include <linux/workqueue.h> 40#include <linux/workqueue.h>
41#include <linux/spinlock.h> 41#include <linux/spinlock.h>
42 42
43#if defined(CONFIG_CRYPTO_CTR) || defined(CONFIG_CRYPTO_CTR_MODULE)
44#define HAS_CTR
45#endif
46
47#if defined(CONFIG_CRYPTO_PCBC) || defined(CONFIG_CRYPTO_PCBC_MODULE) 43#if defined(CONFIG_CRYPTO_PCBC) || defined(CONFIG_CRYPTO_PCBC_MODULE)
48#define HAS_PCBC 44#define HAS_PCBC
49#endif 45#endif
@@ -395,12 +391,6 @@ static int ablk_ctr_init(struct crypto_tfm *tfm)
395 return ablk_init_common(tfm, "__driver-ctr-aes-aesni"); 391 return ablk_init_common(tfm, "__driver-ctr-aes-aesni");
396} 392}
397 393
398#ifdef HAS_CTR
399static int ablk_rfc3686_ctr_init(struct crypto_tfm *tfm)
400{
401 return ablk_init_common(tfm, "rfc3686(__driver-ctr-aes-aesni)");
402}
403#endif
404#endif 394#endif
405 395
406#ifdef HAS_PCBC 396#ifdef HAS_PCBC
@@ -1158,33 +1148,6 @@ static struct crypto_alg aesni_algs[] = { {
1158 .maxauthsize = 16, 1148 .maxauthsize = 16,
1159 }, 1149 },
1160 }, 1150 },
1161#ifdef HAS_CTR
1162}, {
1163 .cra_name = "rfc3686(ctr(aes))",
1164 .cra_driver_name = "rfc3686-ctr-aes-aesni",
1165 .cra_priority = 400,
1166 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
1167 .cra_blocksize = 1,
1168 .cra_ctxsize = sizeof(struct async_helper_ctx),
1169 .cra_alignmask = 0,
1170 .cra_type = &crypto_ablkcipher_type,
1171 .cra_module = THIS_MODULE,
1172 .cra_init = ablk_rfc3686_ctr_init,
1173 .cra_exit = ablk_exit,
1174 .cra_u = {
1175 .ablkcipher = {
1176 .min_keysize = AES_MIN_KEY_SIZE +
1177 CTR_RFC3686_NONCE_SIZE,
1178 .max_keysize = AES_MAX_KEY_SIZE +
1179 CTR_RFC3686_NONCE_SIZE,
1180 .ivsize = CTR_RFC3686_IV_SIZE,
1181 .setkey = ablk_set_key,
1182 .encrypt = ablk_encrypt,
1183 .decrypt = ablk_decrypt,
1184 .geniv = "seqiv",
1185 },
1186 },
1187#endif
1188#endif 1151#endif
1189#ifdef HAS_PCBC 1152#ifdef HAS_PCBC
1190}, { 1153}, {
diff --git a/crypto/ctr.c b/crypto/ctr.c
index 4ca7222cfeb6..1f2997cbfdd4 100644
--- a/crypto/ctr.c
+++ b/crypto/ctr.c
@@ -12,6 +12,7 @@
12 12
13#include <crypto/algapi.h> 13#include <crypto/algapi.h>
14#include <crypto/ctr.h> 14#include <crypto/ctr.h>
15#include <crypto/internal/skcipher.h>
15#include <linux/err.h> 16#include <linux/err.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
@@ -25,10 +26,15 @@ struct crypto_ctr_ctx {
25}; 26};
26 27
27struct crypto_rfc3686_ctx { 28struct crypto_rfc3686_ctx {
28 struct crypto_blkcipher *child; 29 struct crypto_ablkcipher *child;
29 u8 nonce[CTR_RFC3686_NONCE_SIZE]; 30 u8 nonce[CTR_RFC3686_NONCE_SIZE];
30}; 31};
31 32
33struct crypto_rfc3686_req_ctx {
34 u8 iv[CTR_RFC3686_BLOCK_SIZE];
35 struct ablkcipher_request subreq CRYPTO_MINALIGN_ATTR;
36};
37
32static int crypto_ctr_setkey(struct crypto_tfm *parent, const u8 *key, 38static int crypto_ctr_setkey(struct crypto_tfm *parent, const u8 *key,
33 unsigned int keylen) 39 unsigned int keylen)
34{ 40{
@@ -243,11 +249,11 @@ static struct crypto_template crypto_ctr_tmpl = {
243 .module = THIS_MODULE, 249 .module = THIS_MODULE,
244}; 250};
245 251
246static int crypto_rfc3686_setkey(struct crypto_tfm *parent, const u8 *key, 252static int crypto_rfc3686_setkey(struct crypto_ablkcipher *parent,
247 unsigned int keylen) 253 const u8 *key, unsigned int keylen)
248{ 254{
249 struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(parent); 255 struct crypto_rfc3686_ctx *ctx = crypto_ablkcipher_ctx(parent);
250 struct crypto_blkcipher *child = ctx->child; 256 struct crypto_ablkcipher *child = ctx->child;
251 int err; 257 int err;
252 258
253 /* the nonce is stored in bytes at end of key */ 259 /* the nonce is stored in bytes at end of key */
@@ -259,59 +265,64 @@ static int crypto_rfc3686_setkey(struct crypto_tfm *parent, const u8 *key,
259 265
260 keylen -= CTR_RFC3686_NONCE_SIZE; 266 keylen -= CTR_RFC3686_NONCE_SIZE;
261 267
262 crypto_blkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); 268 crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
263 crypto_blkcipher_set_flags(child, crypto_tfm_get_flags(parent) & 269 crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(parent) &
264 CRYPTO_TFM_REQ_MASK); 270 CRYPTO_TFM_REQ_MASK);
265 err = crypto_blkcipher_setkey(child, key, keylen); 271 err = crypto_ablkcipher_setkey(child, key, keylen);
266 crypto_tfm_set_flags(parent, crypto_blkcipher_get_flags(child) & 272 crypto_ablkcipher_set_flags(parent, crypto_ablkcipher_get_flags(child) &
267 CRYPTO_TFM_RES_MASK); 273 CRYPTO_TFM_RES_MASK);
268 274
269 return err; 275 return err;
270} 276}
271 277
272static int crypto_rfc3686_crypt(struct blkcipher_desc *desc, 278static int crypto_rfc3686_crypt(struct ablkcipher_request *req)
273 struct scatterlist *dst,
274 struct scatterlist *src, unsigned int nbytes)
275{ 279{
276 struct crypto_blkcipher *tfm = desc->tfm; 280 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
277 struct crypto_rfc3686_ctx *ctx = crypto_blkcipher_ctx(tfm); 281 struct crypto_rfc3686_ctx *ctx = crypto_ablkcipher_ctx(tfm);
278 struct crypto_blkcipher *child = ctx->child; 282 struct crypto_ablkcipher *child = ctx->child;
279 unsigned long alignmask = crypto_blkcipher_alignmask(tfm); 283 unsigned long align = crypto_ablkcipher_alignmask(tfm);
280 u8 ivblk[CTR_RFC3686_BLOCK_SIZE + alignmask]; 284 struct crypto_rfc3686_req_ctx *rctx =
281 u8 *iv = PTR_ALIGN(ivblk + 0, alignmask + 1); 285 (void *)PTR_ALIGN((u8 *)ablkcipher_request_ctx(req), align + 1);
282 u8 *info = desc->info; 286 struct ablkcipher_request *subreq = &rctx->subreq;
283 int err; 287 u8 *iv = rctx->iv;
284 288
285 /* set up counter block */ 289 /* set up counter block */
286 memcpy(iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE); 290 memcpy(iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
287 memcpy(iv + CTR_RFC3686_NONCE_SIZE, info, CTR_RFC3686_IV_SIZE); 291 memcpy(iv + CTR_RFC3686_NONCE_SIZE, req->info, CTR_RFC3686_IV_SIZE);
288 292
289 /* initialize counter portion of counter block */ 293 /* initialize counter portion of counter block */
290 *(__be32 *)(iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) = 294 *(__be32 *)(iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
291 cpu_to_be32(1); 295 cpu_to_be32(1);
292 296
293 desc->tfm = child; 297 ablkcipher_request_set_tfm(subreq, child);
294 desc->info = iv; 298 ablkcipher_request_set_callback(subreq, req->base.flags,
295 err = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes); 299 req->base.complete, req->base.data);
296 desc->tfm = tfm; 300 ablkcipher_request_set_crypt(subreq, req->src, req->dst, req->nbytes,
297 desc->info = info; 301 iv);
298 302
299 return err; 303 return crypto_ablkcipher_encrypt(subreq);
300} 304}
301 305
302static int crypto_rfc3686_init_tfm(struct crypto_tfm *tfm) 306static int crypto_rfc3686_init_tfm(struct crypto_tfm *tfm)
303{ 307{
304 struct crypto_instance *inst = (void *)tfm->__crt_alg; 308 struct crypto_instance *inst = (void *)tfm->__crt_alg;
305 struct crypto_spawn *spawn = crypto_instance_ctx(inst); 309 struct crypto_skcipher_spawn *spawn = crypto_instance_ctx(inst);
306 struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm); 310 struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm);
307 struct crypto_blkcipher *cipher; 311 struct crypto_ablkcipher *cipher;
312 unsigned long align;
308 313
309 cipher = crypto_spawn_blkcipher(spawn); 314 cipher = crypto_spawn_skcipher(spawn);
310 if (IS_ERR(cipher)) 315 if (IS_ERR(cipher))
311 return PTR_ERR(cipher); 316 return PTR_ERR(cipher);
312 317
313 ctx->child = cipher; 318 ctx->child = cipher;
314 319
320 align = crypto_tfm_alg_alignmask(tfm);
321 align &= ~(crypto_tfm_ctx_alignment() - 1);
322 tfm->crt_ablkcipher.reqsize = align +
323 sizeof(struct crypto_rfc3686_req_ctx) +
324 crypto_ablkcipher_reqsize(cipher);
325
315 return 0; 326 return 0;
316} 327}
317 328
@@ -319,74 +330,110 @@ static void crypto_rfc3686_exit_tfm(struct crypto_tfm *tfm)
319{ 330{
320 struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm); 331 struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm);
321 332
322 crypto_free_blkcipher(ctx->child); 333 crypto_free_ablkcipher(ctx->child);
323} 334}
324 335
325static struct crypto_instance *crypto_rfc3686_alloc(struct rtattr **tb) 336static struct crypto_instance *crypto_rfc3686_alloc(struct rtattr **tb)
326{ 337{
338 struct crypto_attr_type *algt;
327 struct crypto_instance *inst; 339 struct crypto_instance *inst;
328 struct crypto_alg *alg; 340 struct crypto_alg *alg;
341 struct crypto_skcipher_spawn *spawn;
342 const char *cipher_name;
329 int err; 343 int err;
330 344
331 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER); 345 algt = crypto_get_attr_type(tb);
332 if (err) 346 err = PTR_ERR(algt);
347 if (IS_ERR(algt))
333 return ERR_PTR(err); 348 return ERR_PTR(err);
334 349
335 alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_BLKCIPHER, 350 if ((algt->type ^ CRYPTO_ALG_TYPE_BLKCIPHER) & algt->mask)
336 CRYPTO_ALG_TYPE_MASK); 351 return ERR_PTR(-EINVAL);
337 err = PTR_ERR(alg); 352
338 if (IS_ERR(alg)) 353 cipher_name = crypto_attr_alg_name(tb[1]);
354 err = PTR_ERR(cipher_name);
355 if (IS_ERR(cipher_name))
339 return ERR_PTR(err); 356 return ERR_PTR(err);
340 357
358 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
359 if (!inst)
360 return ERR_PTR(-ENOMEM);
361
362 spawn = crypto_instance_ctx(inst);
363
364 crypto_set_skcipher_spawn(spawn, inst);
365 err = crypto_grab_skcipher(spawn, cipher_name, 0,
366 crypto_requires_sync(algt->type,
367 algt->mask));
368 if (err)
369 goto err_free_inst;
370
371 alg = crypto_skcipher_spawn_alg(spawn);
372
341 /* We only support 16-byte blocks. */ 373 /* We only support 16-byte blocks. */
342 err = -EINVAL; 374 err = -EINVAL;
343 if (alg->cra_blkcipher.ivsize != CTR_RFC3686_BLOCK_SIZE) 375 if (alg->cra_ablkcipher.ivsize != CTR_RFC3686_BLOCK_SIZE)
344 goto out_put_alg; 376 goto err_drop_spawn;
345 377
346 /* Not a stream cipher? */ 378 /* Not a stream cipher? */
347 if (alg->cra_blocksize != 1) 379 if (alg->cra_blocksize != 1)
348 goto out_put_alg; 380 goto err_drop_spawn;
349 381
350 inst = crypto_alloc_instance("rfc3686", alg); 382 err = -ENAMETOOLONG;
351 if (IS_ERR(inst)) 383 if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "rfc3686(%s)",
352 goto out; 384 alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
385 goto err_drop_spawn;
386 if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
387 "rfc3686(%s)", alg->cra_driver_name) >=
388 CRYPTO_MAX_ALG_NAME)
389 goto err_drop_spawn;
353 390
354 inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
355 inst->alg.cra_priority = alg->cra_priority; 391 inst->alg.cra_priority = alg->cra_priority;
356 inst->alg.cra_blocksize = 1; 392 inst->alg.cra_blocksize = 1;
357 inst->alg.cra_alignmask = alg->cra_alignmask; 393 inst->alg.cra_alignmask = alg->cra_alignmask;
358 inst->alg.cra_type = &crypto_blkcipher_type;
359 394
360 inst->alg.cra_blkcipher.ivsize = CTR_RFC3686_IV_SIZE; 395 inst->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
361 inst->alg.cra_blkcipher.min_keysize = alg->cra_blkcipher.min_keysize 396 (alg->cra_flags & CRYPTO_ALG_ASYNC);
362 + CTR_RFC3686_NONCE_SIZE; 397 inst->alg.cra_type = &crypto_ablkcipher_type;
363 inst->alg.cra_blkcipher.max_keysize = alg->cra_blkcipher.max_keysize 398
364 + CTR_RFC3686_NONCE_SIZE; 399 inst->alg.cra_ablkcipher.ivsize = CTR_RFC3686_IV_SIZE;
400 inst->alg.cra_ablkcipher.min_keysize =
401 alg->cra_ablkcipher.min_keysize + CTR_RFC3686_NONCE_SIZE;
402 inst->alg.cra_ablkcipher.max_keysize =
403 alg->cra_ablkcipher.max_keysize + CTR_RFC3686_NONCE_SIZE;
365 404
366 inst->alg.cra_blkcipher.geniv = "seqiv"; 405 inst->alg.cra_ablkcipher.geniv = "seqiv";
406
407 inst->alg.cra_ablkcipher.setkey = crypto_rfc3686_setkey;
408 inst->alg.cra_ablkcipher.encrypt = crypto_rfc3686_crypt;
409 inst->alg.cra_ablkcipher.decrypt = crypto_rfc3686_crypt;
367 410
368 inst->alg.cra_ctxsize = sizeof(struct crypto_rfc3686_ctx); 411 inst->alg.cra_ctxsize = sizeof(struct crypto_rfc3686_ctx);
369 412
370 inst->alg.cra_init = crypto_rfc3686_init_tfm; 413 inst->alg.cra_init = crypto_rfc3686_init_tfm;
371 inst->alg.cra_exit = crypto_rfc3686_exit_tfm; 414 inst->alg.cra_exit = crypto_rfc3686_exit_tfm;
372 415
373 inst->alg.cra_blkcipher.setkey = crypto_rfc3686_setkey;
374 inst->alg.cra_blkcipher.encrypt = crypto_rfc3686_crypt;
375 inst->alg.cra_blkcipher.decrypt = crypto_rfc3686_crypt;
376
377out:
378 crypto_mod_put(alg);
379 return inst; 416 return inst;
380 417
381out_put_alg: 418err_drop_spawn:
382 inst = ERR_PTR(err); 419 crypto_drop_skcipher(spawn);
383 goto out; 420err_free_inst:
421 kfree(inst);
422 return ERR_PTR(err);
423}
424
425static void crypto_rfc3686_free(struct crypto_instance *inst)
426{
427 struct crypto_skcipher_spawn *spawn = crypto_instance_ctx(inst);
428
429 crypto_drop_skcipher(spawn);
430 kfree(inst);
384} 431}
385 432
386static struct crypto_template crypto_rfc3686_tmpl = { 433static struct crypto_template crypto_rfc3686_tmpl = {
387 .name = "rfc3686", 434 .name = "rfc3686",
388 .alloc = crypto_rfc3686_alloc, 435 .alloc = crypto_rfc3686_alloc,
389 .free = crypto_ctr_free, 436 .free = crypto_rfc3686_free,
390 .module = THIS_MODULE, 437 .module = THIS_MODULE,
391}; 438};
392 439
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 7ae2130e1b00..87ef7d66bc20 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -1591,6 +1591,10 @@ static int do_test(int m)
1591 speed_template_16_24_32); 1591 speed_template_16_24_32);
1592 test_acipher_speed("ofb(aes)", DECRYPT, sec, NULL, 0, 1592 test_acipher_speed("ofb(aes)", DECRYPT, sec, NULL, 0,
1593 speed_template_16_24_32); 1593 speed_template_16_24_32);
1594 test_acipher_speed("rfc3686(ctr(aes))", ENCRYPT, sec, NULL, 0,
1595 speed_template_20_28_36);
1596 test_acipher_speed("rfc3686(ctr(aes))", DECRYPT, sec, NULL, 0,
1597 speed_template_20_28_36);
1594 break; 1598 break;
1595 1599
1596 case 501: 1600 case 501:
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index cd2068524f3f..ecdeeb1a7b05 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -51,6 +51,7 @@ static u8 speed_template_8_16[] = {8, 16, 0};
51static u8 speed_template_8_32[] = {8, 32, 0}; 51static u8 speed_template_8_32[] = {8, 32, 0};
52static u8 speed_template_16_32[] = {16, 32, 0}; 52static u8 speed_template_16_32[] = {16, 32, 0};
53static u8 speed_template_16_24_32[] = {16, 24, 32, 0}; 53static u8 speed_template_16_24_32[] = {16, 24, 32, 0};
54static u8 speed_template_20_28_36[] = {20, 28, 36, 0};
54static u8 speed_template_32_40_48[] = {32, 40, 48, 0}; 55static u8 speed_template_32_40_48[] = {32, 40, 48, 0};
55static u8 speed_template_32_48[] = {32, 48, 0}; 56static u8 speed_template_32_48[] = {32, 48, 0};
56static u8 speed_template_32_48_64[] = {32, 48, 64, 0}; 57static u8 speed_template_32_48_64[] = {32, 48, 64, 0};
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 63445ede48bb..421f764794d5 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -557,10 +557,6 @@ struct xfrm_migrate {
557}; 557};
558 558
559#define XFRM_KM_TIMEOUT 30 559#define XFRM_KM_TIMEOUT 30
560/* which seqno */
561#define XFRM_REPLAY_SEQ 1
562#define XFRM_REPLAY_OSEQ 2
563#define XFRM_REPLAY_SEQ_MASK 3
564/* what happened */ 560/* what happened */
565#define XFRM_REPLAY_UPDATE XFRM_AE_CR 561#define XFRM_REPLAY_UPDATE XFRM_AE_CR
566#define XFRM_REPLAY_TIMEOUT XFRM_AE_CE 562#define XFRM_REPLAY_TIMEOUT XFRM_AE_CE
diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
index fdfba235f9f1..b49eab89c9fd 100644
--- a/include/uapi/linux/snmp.h
+++ b/include/uapi/linux/snmp.h
@@ -278,6 +278,7 @@ enum
278 LINUX_MIB_XFRMOUTPOLDEAD, /* XfrmOutPolDead */ 278 LINUX_MIB_XFRMOUTPOLDEAD, /* XfrmOutPolDead */
279 LINUX_MIB_XFRMOUTPOLERROR, /* XfrmOutPolError */ 279 LINUX_MIB_XFRMOUTPOLERROR, /* XfrmOutPolError */
280 LINUX_MIB_XFRMFWDHDRERROR, /* XfrmFwdHdrError*/ 280 LINUX_MIB_XFRMFWDHDRERROR, /* XfrmFwdHdrError*/
281 LINUX_MIB_XFRMOUTSTATEINVALID, /* XfrmOutStateInvalid */
281 __LINUX_MIB_XFRMMAX 282 __LINUX_MIB_XFRMMAX
282}; 283};
283 284
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 4ce2d93162c1..f9a549554740 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -700,8 +700,7 @@ void xfrm_probe_algs(void)
700 } 700 }
701 701
702 for (i = 0; i < ealg_entries(); i++) { 702 for (i = 0; i < ealg_entries(); i++) {
703 status = crypto_has_blkcipher(ealg_list[i].name, 0, 703 status = crypto_has_ablkcipher(ealg_list[i].name, 0, 0);
704 CRYPTO_ALG_ASYNC);
705 if (ealg_list[i].available != status) 704 if (ealg_list[i].available != status)
706 ealg_list[i].available = status; 705 ealg_list[i].available = status;
707 } 706 }
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 95a338c89f99..3670526e70b9 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -61,6 +61,12 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
61 } 61 }
62 62
63 spin_lock_bh(&x->lock); 63 spin_lock_bh(&x->lock);
64
65 if (unlikely(x->km.state != XFRM_STATE_VALID)) {
66 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID);
67 goto error_nolock;
68 }
69
64 err = xfrm_state_check_expire(x); 70 err = xfrm_state_check_expire(x);
65 if (err) { 71 if (err) {
66 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEEXPIRED); 72 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEEXPIRED);
diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
index d0a1af8ed584..603903853e89 100644
--- a/net/xfrm/xfrm_proc.c
+++ b/net/xfrm/xfrm_proc.c
@@ -43,6 +43,7 @@ static const struct snmp_mib xfrm_mib_list[] = {
43 SNMP_MIB_ITEM("XfrmOutPolDead", LINUX_MIB_XFRMOUTPOLDEAD), 43 SNMP_MIB_ITEM("XfrmOutPolDead", LINUX_MIB_XFRMOUTPOLDEAD),
44 SNMP_MIB_ITEM("XfrmOutPolError", LINUX_MIB_XFRMOUTPOLERROR), 44 SNMP_MIB_ITEM("XfrmOutPolError", LINUX_MIB_XFRMOUTPOLERROR),
45 SNMP_MIB_ITEM("XfrmFwdHdrError", LINUX_MIB_XFRMFWDHDRERROR), 45 SNMP_MIB_ITEM("XfrmFwdHdrError", LINUX_MIB_XFRMFWDHDRERROR),
46 SNMP_MIB_ITEM("XfrmOutStateInvalid", LINUX_MIB_XFRMOUTSTATEINVALID),
46 SNMP_MIB_SENTINEL 47 SNMP_MIB_SENTINEL
47}; 48};
48 49
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 3459692092ec..0adae918a7a2 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -158,8 +158,8 @@ out_unlock:
158 mutex_unlock(&hash_resize_mutex); 158 mutex_unlock(&hash_resize_mutex);
159} 159}
160 160
161static DEFINE_RWLOCK(xfrm_state_afinfo_lock); 161static DEFINE_SPINLOCK(xfrm_state_afinfo_lock);
162static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO]; 162static struct xfrm_state_afinfo __rcu *xfrm_state_afinfo[NPROTO];
163 163
164static DEFINE_SPINLOCK(xfrm_state_gc_lock); 164static DEFINE_SPINLOCK(xfrm_state_gc_lock);
165 165
@@ -168,58 +168,45 @@ int __xfrm_state_delete(struct xfrm_state *x);
168int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); 168int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
169void km_state_expired(struct xfrm_state *x, int hard, u32 portid); 169void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
170 170
171static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family) 171static DEFINE_SPINLOCK(xfrm_type_lock);
172{
173 struct xfrm_state_afinfo *afinfo;
174 if (unlikely(family >= NPROTO))
175 return NULL;
176 write_lock_bh(&xfrm_state_afinfo_lock);
177 afinfo = xfrm_state_afinfo[family];
178 if (unlikely(!afinfo))
179 write_unlock_bh(&xfrm_state_afinfo_lock);
180 return afinfo;
181}
182
183static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
184 __releases(xfrm_state_afinfo_lock)
185{
186 write_unlock_bh(&xfrm_state_afinfo_lock);
187}
188
189int xfrm_register_type(const struct xfrm_type *type, unsigned short family) 172int xfrm_register_type(const struct xfrm_type *type, unsigned short family)
190{ 173{
191 struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family); 174 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
192 const struct xfrm_type **typemap; 175 const struct xfrm_type **typemap;
193 int err = 0; 176 int err = 0;
194 177
195 if (unlikely(afinfo == NULL)) 178 if (unlikely(afinfo == NULL))
196 return -EAFNOSUPPORT; 179 return -EAFNOSUPPORT;
197 typemap = afinfo->type_map; 180 typemap = afinfo->type_map;
181 spin_lock_bh(&xfrm_type_lock);
198 182
199 if (likely(typemap[type->proto] == NULL)) 183 if (likely(typemap[type->proto] == NULL))
200 typemap[type->proto] = type; 184 typemap[type->proto] = type;
201 else 185 else
202 err = -EEXIST; 186 err = -EEXIST;
203 xfrm_state_unlock_afinfo(afinfo); 187 spin_unlock_bh(&xfrm_type_lock);
188 xfrm_state_put_afinfo(afinfo);
204 return err; 189 return err;
205} 190}
206EXPORT_SYMBOL(xfrm_register_type); 191EXPORT_SYMBOL(xfrm_register_type);
207 192
208int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family) 193int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family)
209{ 194{
210 struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family); 195 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
211 const struct xfrm_type **typemap; 196 const struct xfrm_type **typemap;
212 int err = 0; 197 int err = 0;
213 198
214 if (unlikely(afinfo == NULL)) 199 if (unlikely(afinfo == NULL))
215 return -EAFNOSUPPORT; 200 return -EAFNOSUPPORT;
216 typemap = afinfo->type_map; 201 typemap = afinfo->type_map;
202 spin_lock_bh(&xfrm_type_lock);
217 203
218 if (unlikely(typemap[type->proto] != type)) 204 if (unlikely(typemap[type->proto] != type))
219 err = -ENOENT; 205 err = -ENOENT;
220 else 206 else
221 typemap[type->proto] = NULL; 207 typemap[type->proto] = NULL;
222 xfrm_state_unlock_afinfo(afinfo); 208 spin_unlock_bh(&xfrm_type_lock);
209 xfrm_state_put_afinfo(afinfo);
223 return err; 210 return err;
224} 211}
225EXPORT_SYMBOL(xfrm_unregister_type); 212EXPORT_SYMBOL(xfrm_unregister_type);
@@ -256,6 +243,7 @@ static void xfrm_put_type(const struct xfrm_type *type)
256 module_put(type->owner); 243 module_put(type->owner);
257} 244}
258 245
246static DEFINE_SPINLOCK(xfrm_mode_lock);
259int xfrm_register_mode(struct xfrm_mode *mode, int family) 247int xfrm_register_mode(struct xfrm_mode *mode, int family)
260{ 248{
261 struct xfrm_state_afinfo *afinfo; 249 struct xfrm_state_afinfo *afinfo;
@@ -265,12 +253,13 @@ int xfrm_register_mode(struct xfrm_mode *mode, int family)
265 if (unlikely(mode->encap >= XFRM_MODE_MAX)) 253 if (unlikely(mode->encap >= XFRM_MODE_MAX))
266 return -EINVAL; 254 return -EINVAL;
267 255
268 afinfo = xfrm_state_lock_afinfo(family); 256 afinfo = xfrm_state_get_afinfo(family);
269 if (unlikely(afinfo == NULL)) 257 if (unlikely(afinfo == NULL))
270 return -EAFNOSUPPORT; 258 return -EAFNOSUPPORT;
271 259
272 err = -EEXIST; 260 err = -EEXIST;
273 modemap = afinfo->mode_map; 261 modemap = afinfo->mode_map;
262 spin_lock_bh(&xfrm_mode_lock);
274 if (modemap[mode->encap]) 263 if (modemap[mode->encap])
275 goto out; 264 goto out;
276 265
@@ -283,7 +272,8 @@ int xfrm_register_mode(struct xfrm_mode *mode, int family)
283 err = 0; 272 err = 0;
284 273
285out: 274out:
286 xfrm_state_unlock_afinfo(afinfo); 275 spin_unlock_bh(&xfrm_mode_lock);
276 xfrm_state_put_afinfo(afinfo);
287 return err; 277 return err;
288} 278}
289EXPORT_SYMBOL(xfrm_register_mode); 279EXPORT_SYMBOL(xfrm_register_mode);
@@ -297,19 +287,21 @@ int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
297 if (unlikely(mode->encap >= XFRM_MODE_MAX)) 287 if (unlikely(mode->encap >= XFRM_MODE_MAX))
298 return -EINVAL; 288 return -EINVAL;
299 289
300 afinfo = xfrm_state_lock_afinfo(family); 290 afinfo = xfrm_state_get_afinfo(family);
301 if (unlikely(afinfo == NULL)) 291 if (unlikely(afinfo == NULL))
302 return -EAFNOSUPPORT; 292 return -EAFNOSUPPORT;
303 293
304 err = -ENOENT; 294 err = -ENOENT;
305 modemap = afinfo->mode_map; 295 modemap = afinfo->mode_map;
296 spin_lock_bh(&xfrm_mode_lock);
306 if (likely(modemap[mode->encap] == mode)) { 297 if (likely(modemap[mode->encap] == mode)) {
307 modemap[mode->encap] = NULL; 298 modemap[mode->encap] = NULL;
308 module_put(mode->afinfo->owner); 299 module_put(mode->afinfo->owner);
309 err = 0; 300 err = 0;
310 } 301 }
311 302
312 xfrm_state_unlock_afinfo(afinfo); 303 spin_unlock_bh(&xfrm_mode_lock);
304 xfrm_state_put_afinfo(afinfo);
313 return err; 305 return err;
314} 306}
315EXPORT_SYMBOL(xfrm_unregister_mode); 307EXPORT_SYMBOL(xfrm_unregister_mode);
@@ -1370,9 +1362,6 @@ int xfrm_state_check_expire(struct xfrm_state *x)
1370 if (!x->curlft.use_time) 1362 if (!x->curlft.use_time)
1371 x->curlft.use_time = get_seconds(); 1363 x->curlft.use_time = get_seconds();
1372 1364
1373 if (x->km.state != XFRM_STATE_VALID)
1374 return -EINVAL;
1375
1376 if (x->curlft.bytes >= x->lft.hard_byte_limit || 1365 if (x->curlft.bytes >= x->lft.hard_byte_limit ||
1377 x->curlft.packets >= x->lft.hard_packet_limit) { 1366 x->curlft.packets >= x->lft.hard_packet_limit) {
1378 x->km.state = XFRM_STATE_EXPIRED; 1367 x->km.state = XFRM_STATE_EXPIRED;
@@ -1648,27 +1637,26 @@ static void xfrm_replay_timer_handler(unsigned long data)
1648} 1637}
1649 1638
1650static LIST_HEAD(xfrm_km_list); 1639static LIST_HEAD(xfrm_km_list);
1651static DEFINE_RWLOCK(xfrm_km_lock);
1652 1640
1653void km_policy_notify(struct xfrm_policy *xp, int dir, const struct km_event *c) 1641void km_policy_notify(struct xfrm_policy *xp, int dir, const struct km_event *c)
1654{ 1642{
1655 struct xfrm_mgr *km; 1643 struct xfrm_mgr *km;
1656 1644
1657 read_lock(&xfrm_km_lock); 1645 rcu_read_lock();
1658 list_for_each_entry(km, &xfrm_km_list, list) 1646 list_for_each_entry_rcu(km, &xfrm_km_list, list)
1659 if (km->notify_policy) 1647 if (km->notify_policy)
1660 km->notify_policy(xp, dir, c); 1648 km->notify_policy(xp, dir, c);
1661 read_unlock(&xfrm_km_lock); 1649 rcu_read_unlock();
1662} 1650}
1663 1651
1664void km_state_notify(struct xfrm_state *x, const struct km_event *c) 1652void km_state_notify(struct xfrm_state *x, const struct km_event *c)
1665{ 1653{
1666 struct xfrm_mgr *km; 1654 struct xfrm_mgr *km;
1667 read_lock(&xfrm_km_lock); 1655 rcu_read_lock();
1668 list_for_each_entry(km, &xfrm_km_list, list) 1656 list_for_each_entry_rcu(km, &xfrm_km_list, list)
1669 if (km->notify) 1657 if (km->notify)
1670 km->notify(x, c); 1658 km->notify(x, c);
1671 read_unlock(&xfrm_km_lock); 1659 rcu_read_unlock();
1672} 1660}
1673 1661
1674EXPORT_SYMBOL(km_policy_notify); 1662EXPORT_SYMBOL(km_policy_notify);
@@ -1698,13 +1686,13 @@ int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol)
1698 int err = -EINVAL, acqret; 1686 int err = -EINVAL, acqret;
1699 struct xfrm_mgr *km; 1687 struct xfrm_mgr *km;
1700 1688
1701 read_lock(&xfrm_km_lock); 1689 rcu_read_lock();
1702 list_for_each_entry(km, &xfrm_km_list, list) { 1690 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1703 acqret = km->acquire(x, t, pol); 1691 acqret = km->acquire(x, t, pol);
1704 if (!acqret) 1692 if (!acqret)
1705 err = acqret; 1693 err = acqret;
1706 } 1694 }
1707 read_unlock(&xfrm_km_lock); 1695 rcu_read_unlock();
1708 return err; 1696 return err;
1709} 1697}
1710EXPORT_SYMBOL(km_query); 1698EXPORT_SYMBOL(km_query);
@@ -1714,14 +1702,14 @@ int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport)
1714 int err = -EINVAL; 1702 int err = -EINVAL;
1715 struct xfrm_mgr *km; 1703 struct xfrm_mgr *km;
1716 1704
1717 read_lock(&xfrm_km_lock); 1705 rcu_read_lock();
1718 list_for_each_entry(km, &xfrm_km_list, list) { 1706 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1719 if (km->new_mapping) 1707 if (km->new_mapping)
1720 err = km->new_mapping(x, ipaddr, sport); 1708 err = km->new_mapping(x, ipaddr, sport);
1721 if (!err) 1709 if (!err)
1722 break; 1710 break;
1723 } 1711 }
1724 read_unlock(&xfrm_km_lock); 1712 rcu_read_unlock();
1725 return err; 1713 return err;
1726} 1714}
1727EXPORT_SYMBOL(km_new_mapping); 1715EXPORT_SYMBOL(km_new_mapping);
@@ -1750,15 +1738,15 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1750 int ret; 1738 int ret;
1751 struct xfrm_mgr *km; 1739 struct xfrm_mgr *km;
1752 1740
1753 read_lock(&xfrm_km_lock); 1741 rcu_read_lock();
1754 list_for_each_entry(km, &xfrm_km_list, list) { 1742 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1755 if (km->migrate) { 1743 if (km->migrate) {
1756 ret = km->migrate(sel, dir, type, m, num_migrate, k); 1744 ret = km->migrate(sel, dir, type, m, num_migrate, k);
1757 if (!ret) 1745 if (!ret)
1758 err = ret; 1746 err = ret;
1759 } 1747 }
1760 } 1748 }
1761 read_unlock(&xfrm_km_lock); 1749 rcu_read_unlock();
1762 return err; 1750 return err;
1763} 1751}
1764EXPORT_SYMBOL(km_migrate); 1752EXPORT_SYMBOL(km_migrate);
@@ -1770,15 +1758,15 @@ int km_report(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address
1770 int ret; 1758 int ret;
1771 struct xfrm_mgr *km; 1759 struct xfrm_mgr *km;
1772 1760
1773 read_lock(&xfrm_km_lock); 1761 rcu_read_lock();
1774 list_for_each_entry(km, &xfrm_km_list, list) { 1762 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1775 if (km->report) { 1763 if (km->report) {
1776 ret = km->report(net, proto, sel, addr); 1764 ret = km->report(net, proto, sel, addr);
1777 if (!ret) 1765 if (!ret)
1778 err = ret; 1766 err = ret;
1779 } 1767 }
1780 } 1768 }
1781 read_unlock(&xfrm_km_lock); 1769 rcu_read_unlock();
1782 return err; 1770 return err;
1783} 1771}
1784EXPORT_SYMBOL(km_report); 1772EXPORT_SYMBOL(km_report);
@@ -1802,14 +1790,14 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen
1802 goto out; 1790 goto out;
1803 1791
1804 err = -EINVAL; 1792 err = -EINVAL;
1805 read_lock(&xfrm_km_lock); 1793 rcu_read_lock();
1806 list_for_each_entry(km, &xfrm_km_list, list) { 1794 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1807 pol = km->compile_policy(sk, optname, data, 1795 pol = km->compile_policy(sk, optname, data,
1808 optlen, &err); 1796 optlen, &err);
1809 if (err >= 0) 1797 if (err >= 0)
1810 break; 1798 break;
1811 } 1799 }
1812 read_unlock(&xfrm_km_lock); 1800 rcu_read_unlock();
1813 1801
1814 if (err >= 0) { 1802 if (err >= 0) {
1815 xfrm_sk_policy_insert(sk, err, pol); 1803 xfrm_sk_policy_insert(sk, err, pol);
@@ -1823,20 +1811,23 @@ out:
1823} 1811}
1824EXPORT_SYMBOL(xfrm_user_policy); 1812EXPORT_SYMBOL(xfrm_user_policy);
1825 1813
1814static DEFINE_SPINLOCK(xfrm_km_lock);
1815
1826int xfrm_register_km(struct xfrm_mgr *km) 1816int xfrm_register_km(struct xfrm_mgr *km)
1827{ 1817{
1828 write_lock_bh(&xfrm_km_lock); 1818 spin_lock_bh(&xfrm_km_lock);
1829 list_add_tail(&km->list, &xfrm_km_list); 1819 list_add_tail_rcu(&km->list, &xfrm_km_list);
1830 write_unlock_bh(&xfrm_km_lock); 1820 spin_unlock_bh(&xfrm_km_lock);
1831 return 0; 1821 return 0;
1832} 1822}
1833EXPORT_SYMBOL(xfrm_register_km); 1823EXPORT_SYMBOL(xfrm_register_km);
1834 1824
1835int xfrm_unregister_km(struct xfrm_mgr *km) 1825int xfrm_unregister_km(struct xfrm_mgr *km)
1836{ 1826{
1837 write_lock_bh(&xfrm_km_lock); 1827 spin_lock_bh(&xfrm_km_lock);
1838 list_del(&km->list); 1828 list_del_rcu(&km->list);
1839 write_unlock_bh(&xfrm_km_lock); 1829 spin_unlock_bh(&xfrm_km_lock);
1830 synchronize_rcu();
1840 return 0; 1831 return 0;
1841} 1832}
1842EXPORT_SYMBOL(xfrm_unregister_km); 1833EXPORT_SYMBOL(xfrm_unregister_km);
@@ -1848,12 +1839,12 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
1848 return -EINVAL; 1839 return -EINVAL;
1849 if (unlikely(afinfo->family >= NPROTO)) 1840 if (unlikely(afinfo->family >= NPROTO))
1850 return -EAFNOSUPPORT; 1841 return -EAFNOSUPPORT;
1851 write_lock_bh(&xfrm_state_afinfo_lock); 1842 spin_lock_bh(&xfrm_state_afinfo_lock);
1852 if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL)) 1843 if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL))
1853 err = -ENOBUFS; 1844 err = -ENOBUFS;
1854 else 1845 else
1855 xfrm_state_afinfo[afinfo->family] = afinfo; 1846 rcu_assign_pointer(xfrm_state_afinfo[afinfo->family], afinfo);
1856 write_unlock_bh(&xfrm_state_afinfo_lock); 1847 spin_unlock_bh(&xfrm_state_afinfo_lock);
1857 return err; 1848 return err;
1858} 1849}
1859EXPORT_SYMBOL(xfrm_state_register_afinfo); 1850EXPORT_SYMBOL(xfrm_state_register_afinfo);
@@ -1865,14 +1856,15 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
1865 return -EINVAL; 1856 return -EINVAL;
1866 if (unlikely(afinfo->family >= NPROTO)) 1857 if (unlikely(afinfo->family >= NPROTO))
1867 return -EAFNOSUPPORT; 1858 return -EAFNOSUPPORT;
1868 write_lock_bh(&xfrm_state_afinfo_lock); 1859 spin_lock_bh(&xfrm_state_afinfo_lock);
1869 if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) { 1860 if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) {
1870 if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo)) 1861 if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo))
1871 err = -EINVAL; 1862 err = -EINVAL;
1872 else 1863 else
1873 xfrm_state_afinfo[afinfo->family] = NULL; 1864 RCU_INIT_POINTER(xfrm_state_afinfo[afinfo->family], NULL);
1874 } 1865 }
1875 write_unlock_bh(&xfrm_state_afinfo_lock); 1866 spin_unlock_bh(&xfrm_state_afinfo_lock);
1867 synchronize_rcu();
1876 return err; 1868 return err;
1877} 1869}
1878EXPORT_SYMBOL(xfrm_state_unregister_afinfo); 1870EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
@@ -1882,17 +1874,16 @@ static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
1882 struct xfrm_state_afinfo *afinfo; 1874 struct xfrm_state_afinfo *afinfo;
1883 if (unlikely(family >= NPROTO)) 1875 if (unlikely(family >= NPROTO))
1884 return NULL; 1876 return NULL;
1885 read_lock(&xfrm_state_afinfo_lock); 1877 rcu_read_lock();
1886 afinfo = xfrm_state_afinfo[family]; 1878 afinfo = rcu_dereference(xfrm_state_afinfo[family]);
1887 if (unlikely(!afinfo)) 1879 if (unlikely(!afinfo))
1888 read_unlock(&xfrm_state_afinfo_lock); 1880 rcu_read_unlock();
1889 return afinfo; 1881 return afinfo;
1890} 1882}
1891 1883
1892static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo) 1884static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
1893 __releases(xfrm_state_afinfo_lock)
1894{ 1885{
1895 read_unlock(&xfrm_state_afinfo_lock); 1886 rcu_read_unlock();
1896} 1887}
1897 1888
1898/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */ 1889/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */