aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-05-19 17:21:18 -0400
committerDavid S. Miller <davem@davemloft.net>2007-05-19 17:21:18 -0400
commitc92b3a2f1f11655ecf6774b745017a414241d07c (patch)
tree822a53d289b6848992b9476eb6e451f32b8daa5e
parent580e572a4a1bfea2f42af63ba4785ac7dfbcb45d (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>
-rw-r--r--net/key/af_key.c2
-rw-r--r--net/xfrm/xfrm_algo.c140
2 files changed, 75 insertions, 67 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index a99444142dc7..d302ddae580c 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1448,8 +1448,6 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
1448 int err; 1448 int err;
1449 struct km_event c; 1449 struct km_event c;
1450 1450
1451 xfrm_probe_algs();
1452
1453 x = pfkey_msg2xfrm_state(hdr, ext_hdrs); 1451 x = pfkey_msg2xfrm_state(hdr, ext_hdrs);
1454 if (IS_ERR(x)) 1452 if (IS_ERR(x))
1455 return PTR_ERR(x); 1453 return PTR_ERR(x);
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 */ 350struct xfrm_algo_list {
351struct 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}
365EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
366
367struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
368{
369 int i;
370 356
371 for (i = 0; i < ealg_entries(); i++) { 357static 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}
381EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
382 363
383struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) 364static 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++) { 371static 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}
397EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
398 377
399static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, 378static 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
407static 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
413struct 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}
418EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
419
420struct 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}
425EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
426
427struct 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}
432EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
433
434static 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
430struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe) 443struct 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}
436EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); 448EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
437 449
438struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe) 450struct 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}
444EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); 455EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
445 456
446struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) 457struct 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}
452EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); 462EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
453 463