Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[IPSEC] pfkey: Load specific algorithm in pfkey_add rather than all

This is a natural extension of the changeset

[XFRM]: Probe selected algorithm only.

which only removed the probe call for xfrm_user. This patch does exactly
the same thing for af_key. In other words, we load the algorithm requested
by the user rather than everything when adding xfrm states in af_key.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Herbert Xu and committed by
David S. Miller
c92b3a2f 580e572a

+79 -71
-2
net/key/af_key.c
··· 1448 1448 int err; 1449 1449 struct km_event c; 1450 1450 1451 - xfrm_probe_algs(); 1452 - 1453 1451 x = pfkey_msg2xfrm_state(hdr, ext_hdrs); 1454 1452 if (IS_ERR(x)) 1455 1453 return PTR_ERR(x);
+79 -69
net/xfrm/xfrm_algo.c
··· 347 347 return ARRAY_SIZE(calg_list); 348 348 } 349 349 350 - /* Todo: generic iterators */ 351 - struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) 350 + struct xfrm_algo_list { 351 + struct xfrm_algo_desc *algs; 352 + int entries; 353 + u32 type; 354 + u32 mask; 355 + }; 356 + 357 + static const struct xfrm_algo_list xfrm_aalg_list = { 358 + .algs = aalg_list, 359 + .entries = ARRAY_SIZE(aalg_list), 360 + .type = CRYPTO_ALG_TYPE_HASH, 361 + .mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC, 362 + }; 363 + 364 + static const struct xfrm_algo_list xfrm_ealg_list = { 365 + .algs = ealg_list, 366 + .entries = ARRAY_SIZE(ealg_list), 367 + .type = CRYPTO_ALG_TYPE_BLKCIPHER, 368 + .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC, 369 + }; 370 + 371 + static const struct xfrm_algo_list xfrm_calg_list = { 372 + .algs = calg_list, 373 + .entries = ARRAY_SIZE(calg_list), 374 + .type = CRYPTO_ALG_TYPE_COMPRESS, 375 + .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC, 376 + }; 377 + 378 + static struct xfrm_algo_desc *xfrm_find_algo( 379 + const struct xfrm_algo_list *algo_list, 380 + int match(const struct xfrm_algo_desc *entry, const void *data), 381 + const void *data, int probe) 352 382 { 353 - int i; 354 - 355 - for (i = 0; i < aalg_entries(); i++) { 356 - if (aalg_list[i].desc.sadb_alg_id == alg_id) { 357 - if (aalg_list[i].available) 358 - return &aalg_list[i]; 359 - else 360 - break; 361 - } 362 - } 363 - return NULL; 364 - } 365 - EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); 366 - 367 - struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id) 368 - { 369 - int i; 370 - 371 - for (i = 0; i < ealg_entries(); i++) { 372 - if (ealg_list[i].desc.sadb_alg_id == alg_id) { 373 - if (ealg_list[i].available) 374 - return &ealg_list[i]; 375 - else 376 - break; 377 - } 378 - } 379 - return NULL; 380 - } 381 - EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); 382 - 383 - struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) 384 - { 385 - int i; 386 - 387 - for (i = 0; i < calg_entries(); i++) { 388 - if (calg_list[i].desc.sadb_alg_id == alg_id) { 389 - if (calg_list[i].available) 390 - return &calg_list[i]; 391 - else 392 - break; 393 - } 394 - } 395 - return NULL; 396 - } 397 - EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); 398 - 399 - static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, 400 - int entries, u32 type, u32 mask, 401 - char *name, int probe) 402 - { 383 + struct xfrm_algo_desc *list = algo_list->algs; 403 384 int i, status; 404 385 405 - if (!name) 406 - return NULL; 407 - 408 - for (i = 0; i < entries; i++) { 409 - if (strcmp(name, list[i].name) && 410 - (!list[i].compat || strcmp(name, list[i].compat))) 386 + for (i = 0; i < algo_list->entries; i++) { 387 + if (!match(list + i, data)) 411 388 continue; 412 389 413 390 if (list[i].available) ··· 393 416 if (!probe) 394 417 break; 395 418 396 - status = crypto_has_alg(list[i].name, type, 397 - mask | CRYPTO_ALG_ASYNC); 419 + status = crypto_has_alg(list[i].name, algo_list->type, 420 + algo_list->mask); 398 421 if (!status) 399 422 break; 400 423 ··· 404 427 return NULL; 405 428 } 406 429 430 + static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry, 431 + const void *data) 432 + { 433 + return entry->desc.sadb_alg_id == (int)data; 434 + } 435 + 436 + struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) 437 + { 438 + return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match, 439 + (void *)alg_id, 1); 440 + } 441 + EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); 442 + 443 + struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id) 444 + { 445 + return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match, 446 + (void *)alg_id, 1); 447 + } 448 + EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); 449 + 450 + struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) 451 + { 452 + return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match, 453 + (void *)alg_id, 1); 454 + } 455 + EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); 456 + 457 + static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry, 458 + const void *data) 459 + { 460 + const char *name = data; 461 + 462 + return name && (!strcmp(name, entry->name) || 463 + (entry->compat && !strcmp(name, entry->compat))); 464 + } 465 + 407 466 struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe) 408 467 { 409 - return xfrm_get_byname(aalg_list, aalg_entries(), 410 - CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK, 411 - name, probe); 468 + return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name, 469 + probe); 412 470 } 413 471 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); 414 472 415 473 struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe) 416 474 { 417 - return xfrm_get_byname(ealg_list, ealg_entries(), 418 - CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK, 419 - name, probe); 475 + return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name, 476 + probe); 420 477 } 421 478 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); 422 479 423 480 struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) 424 481 { 425 - return xfrm_get_byname(calg_list, calg_entries(), 426 - CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK, 427 - name, probe); 482 + return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name, 483 + probe); 428 484 } 429 485 EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); 430 486