diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-05-19 17:21:18 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-05-19 17:21:18 -0400 |
commit | c92b3a2f1f11655ecf6774b745017a414241d07c (patch) | |
tree | 822a53d289b6848992b9476eb6e451f32b8daa5e /net/xfrm/xfrm_algo.c | |
parent | 580e572a4a1bfea2f42af63ba4785ac7dfbcb45d (diff) |
[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>
Diffstat (limited to 'net/xfrm/xfrm_algo.c')
-rw-r--r-- | net/xfrm/xfrm_algo.c | 140 |
1 files changed, 75 insertions, 65 deletions
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 6249a9405bb8..8a72def25a34 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c | |||
@@ -347,67 +347,44 @@ static inline int calg_entries(void) | |||
347 | return ARRAY_SIZE(calg_list); | 347 | return ARRAY_SIZE(calg_list); |
348 | } | 348 | } |
349 | 349 | ||
350 | /* Todo: generic iterators */ | 350 | struct xfrm_algo_list { |
351 | struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) | 351 | struct xfrm_algo_desc *algs; |
352 | { | 352 | int entries; |
353 | int i; | 353 | u32 type; |
354 | 354 | u32 mask; | |
355 | for (i = 0; i < aalg_entries(); i++) { | 355 | }; |
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 | 356 | ||
371 | for (i = 0; i < ealg_entries(); i++) { | 357 | static const struct xfrm_algo_list xfrm_aalg_list = { |
372 | if (ealg_list[i].desc.sadb_alg_id == alg_id) { | 358 | .algs = aalg_list, |
373 | if (ealg_list[i].available) | 359 | .entries = ARRAY_SIZE(aalg_list), |
374 | return &ealg_list[i]; | 360 | .type = CRYPTO_ALG_TYPE_HASH, |
375 | else | 361 | .mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC, |
376 | break; | 362 | }; |
377 | } | ||
378 | } | ||
379 | return NULL; | ||
380 | } | ||
381 | EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); | ||
382 | 363 | ||
383 | struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) | 364 | static const struct xfrm_algo_list xfrm_ealg_list = { |
384 | { | 365 | .algs = ealg_list, |
385 | int i; | 366 | .entries = ARRAY_SIZE(ealg_list), |
367 | .type = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
368 | .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC, | ||
369 | }; | ||
386 | 370 | ||
387 | for (i = 0; i < calg_entries(); i++) { | 371 | static const struct xfrm_algo_list xfrm_calg_list = { |
388 | if (calg_list[i].desc.sadb_alg_id == alg_id) { | 372 | .algs = calg_list, |
389 | if (calg_list[i].available) | 373 | .entries = ARRAY_SIZE(calg_list), |
390 | return &calg_list[i]; | 374 | .type = CRYPTO_ALG_TYPE_COMPRESS, |
391 | else | 375 | .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC, |
392 | break; | 376 | }; |
393 | } | ||
394 | } | ||
395 | return NULL; | ||
396 | } | ||
397 | EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); | ||
398 | 377 | ||
399 | static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, | 378 | static struct xfrm_algo_desc *xfrm_find_algo( |
400 | int entries, u32 type, u32 mask, | 379 | const struct xfrm_algo_list *algo_list, |
401 | char *name, int probe) | 380 | int match(const struct xfrm_algo_desc *entry, const void *data), |
381 | const void *data, int probe) | ||
402 | { | 382 | { |
383 | struct xfrm_algo_desc *list = algo_list->algs; | ||
403 | int i, status; | 384 | int i, status; |
404 | 385 | ||
405 | if (!name) | 386 | for (i = 0; i < algo_list->entries; i++) { |
406 | return NULL; | 387 | if (!match(list + i, data)) |
407 | |||
408 | for (i = 0; i < entries; i++) { | ||
409 | if (strcmp(name, list[i].name) && | ||
410 | (!list[i].compat || strcmp(name, list[i].compat))) | ||
411 | continue; | 388 | continue; |
412 | 389 | ||
413 | if (list[i].available) | 390 | if (list[i].available) |
@@ -416,8 +393,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, | |||
416 | if (!probe) | 393 | if (!probe) |
417 | break; | 394 | break; |
418 | 395 | ||
419 | status = crypto_has_alg(list[i].name, type, | 396 | status = crypto_has_alg(list[i].name, algo_list->type, |
420 | mask | CRYPTO_ALG_ASYNC); | 397 | algo_list->mask); |
421 | if (!status) | 398 | if (!status) |
422 | break; | 399 | break; |
423 | 400 | ||
@@ -427,27 +404,60 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, | |||
427 | return NULL; | 404 | return NULL; |
428 | } | 405 | } |
429 | 406 | ||
407 | static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry, | ||
408 | const void *data) | ||
409 | { | ||
410 | return entry->desc.sadb_alg_id == (int)data; | ||
411 | } | ||
412 | |||
413 | struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) | ||
414 | { | ||
415 | return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match, | ||
416 | (void *)alg_id, 1); | ||
417 | } | ||
418 | EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); | ||
419 | |||
420 | struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id) | ||
421 | { | ||
422 | return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match, | ||
423 | (void *)alg_id, 1); | ||
424 | } | ||
425 | EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); | ||
426 | |||
427 | struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) | ||
428 | { | ||
429 | return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match, | ||
430 | (void *)alg_id, 1); | ||
431 | } | ||
432 | EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); | ||
433 | |||
434 | static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry, | ||
435 | const void *data) | ||
436 | { | ||
437 | const char *name = data; | ||
438 | |||
439 | return name && (!strcmp(name, entry->name) || | ||
440 | (entry->compat && !strcmp(name, entry->compat))); | ||
441 | } | ||
442 | |||
430 | struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe) | 443 | struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe) |
431 | { | 444 | { |
432 | return xfrm_get_byname(aalg_list, aalg_entries(), | 445 | return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name, |
433 | CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK, | 446 | probe); |
434 | name, probe); | ||
435 | } | 447 | } |
436 | EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); | 448 | EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); |
437 | 449 | ||
438 | struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe) | 450 | struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe) |
439 | { | 451 | { |
440 | return xfrm_get_byname(ealg_list, ealg_entries(), | 452 | return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name, |
441 | CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK, | 453 | probe); |
442 | name, probe); | ||
443 | } | 454 | } |
444 | EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); | 455 | EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); |
445 | 456 | ||
446 | struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) | 457 | struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) |
447 | { | 458 | { |
448 | return xfrm_get_byname(calg_list, calg_entries(), | 459 | return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name, |
449 | CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK, | 460 | probe); |
450 | name, probe); | ||
451 | } | 461 | } |
452 | EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); | 462 | EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); |
453 | 463 | ||