diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-08-24 07:50:50 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 18:08:49 -0400 |
commit | 44e36b42a8378be1dcf7e6f8a1cb2710a8903387 (patch) | |
tree | 2c057957a4e4dc7f679ac671a9f091f3fe366b92 /net/xfrm/xfrm_policy.c | |
parent | 2518c7c2b3d7f0a6b302b4efe17c911f8dd4049f (diff) |
[XFRM]: Extract common hashing code into xfrm_hash.[ch]
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 95 |
1 files changed, 8 insertions, 87 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 087a5443b051..b446ca31fecc 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -22,12 +22,12 @@ | |||
22 | #include <linux/netdevice.h> | 22 | #include <linux/netdevice.h> |
23 | #include <linux/netfilter.h> | 23 | #include <linux/netfilter.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/bootmem.h> | ||
26 | #include <linux/vmalloc.h> | ||
27 | #include <linux/cache.h> | 25 | #include <linux/cache.h> |
28 | #include <net/xfrm.h> | 26 | #include <net/xfrm.h> |
29 | #include <net/ip.h> | 27 | #include <net/ip.h> |
30 | 28 | ||
29 | #include "xfrm_hash.h" | ||
30 | |||
31 | DEFINE_MUTEX(xfrm_cfg_mutex); | 31 | DEFINE_MUTEX(xfrm_cfg_mutex); |
32 | EXPORT_SYMBOL(xfrm_cfg_mutex); | 32 | EXPORT_SYMBOL(xfrm_cfg_mutex); |
33 | 33 | ||
@@ -409,62 +409,11 @@ static struct hlist_head *xfrm_policy_byidx __read_mostly; | |||
409 | static unsigned int xfrm_idx_hmask __read_mostly; | 409 | static unsigned int xfrm_idx_hmask __read_mostly; |
410 | static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024; | 410 | static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024; |
411 | 411 | ||
412 | static inline unsigned int __idx_hash(u32 index, unsigned int hmask) | ||
413 | { | ||
414 | return (index ^ (index >> 8)) & hmask; | ||
415 | } | ||
416 | |||
417 | static inline unsigned int idx_hash(u32 index) | 412 | static inline unsigned int idx_hash(u32 index) |
418 | { | 413 | { |
419 | return __idx_hash(index, xfrm_idx_hmask); | 414 | return __idx_hash(index, xfrm_idx_hmask); |
420 | } | 415 | } |
421 | 416 | ||
422 | static inline unsigned int __sel_hash(struct xfrm_selector *sel, unsigned short family, unsigned int hmask) | ||
423 | { | ||
424 | xfrm_address_t *daddr = &sel->daddr; | ||
425 | xfrm_address_t *saddr = &sel->saddr; | ||
426 | unsigned int h = 0; | ||
427 | |||
428 | switch (family) { | ||
429 | case AF_INET: | ||
430 | if (sel->prefixlen_d != 32 || | ||
431 | sel->prefixlen_s != 32) | ||
432 | return hmask + 1; | ||
433 | |||
434 | h = ntohl(daddr->a4 ^ saddr->a4); | ||
435 | break; | ||
436 | |||
437 | case AF_INET6: | ||
438 | if (sel->prefixlen_d != 128 || | ||
439 | sel->prefixlen_s != 128) | ||
440 | return hmask + 1; | ||
441 | |||
442 | h = ntohl(daddr->a6[2] ^ daddr->a6[3] ^ | ||
443 | saddr->a6[2] ^ saddr->a6[3]); | ||
444 | break; | ||
445 | }; | ||
446 | h ^= (h >> 16); | ||
447 | return h & hmask; | ||
448 | } | ||
449 | |||
450 | static inline unsigned int __addr_hash(xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, unsigned int hmask) | ||
451 | { | ||
452 | unsigned int h = 0; | ||
453 | |||
454 | switch (family) { | ||
455 | case AF_INET: | ||
456 | h = ntohl(daddr->a4 ^ saddr->a4); | ||
457 | break; | ||
458 | |||
459 | case AF_INET6: | ||
460 | h = ntohl(daddr->a6[2] ^ daddr->a6[3] ^ | ||
461 | saddr->a6[2] ^ saddr->a6[3]); | ||
462 | break; | ||
463 | }; | ||
464 | h ^= (h >> 16); | ||
465 | return h & hmask; | ||
466 | } | ||
467 | |||
468 | static struct hlist_head *policy_hash_bysel(struct xfrm_selector *sel, unsigned short family, int dir) | 417 | static struct hlist_head *policy_hash_bysel(struct xfrm_selector *sel, unsigned short family, int dir) |
469 | { | 418 | { |
470 | unsigned int hmask = xfrm_policy_bydst[dir].hmask; | 419 | unsigned int hmask = xfrm_policy_bydst[dir].hmask; |
@@ -483,34 +432,6 @@ static struct hlist_head *policy_hash_direct(xfrm_address_t *daddr, xfrm_address | |||
483 | return xfrm_policy_bydst[dir].table + hash; | 432 | return xfrm_policy_bydst[dir].table + hash; |
484 | } | 433 | } |
485 | 434 | ||
486 | static struct hlist_head *xfrm_policy_hash_alloc(unsigned int sz) | ||
487 | { | ||
488 | struct hlist_head *n; | ||
489 | |||
490 | if (sz <= PAGE_SIZE) | ||
491 | n = kmalloc(sz, GFP_KERNEL); | ||
492 | else if (hashdist) | ||
493 | n = __vmalloc(sz, GFP_KERNEL, PAGE_KERNEL); | ||
494 | else | ||
495 | n = (struct hlist_head *) | ||
496 | __get_free_pages(GFP_KERNEL, get_order(sz)); | ||
497 | |||
498 | if (n) | ||
499 | memset(n, 0, sz); | ||
500 | |||
501 | return n; | ||
502 | } | ||
503 | |||
504 | static void xfrm_policy_hash_free(struct hlist_head *n, unsigned int sz) | ||
505 | { | ||
506 | if (sz <= PAGE_SIZE) | ||
507 | kfree(n); | ||
508 | else if (hashdist) | ||
509 | vfree(n); | ||
510 | else | ||
511 | free_pages((unsigned long)n, get_order(sz)); | ||
512 | } | ||
513 | |||
514 | static void xfrm_dst_hash_transfer(struct hlist_head *list, | 435 | static void xfrm_dst_hash_transfer(struct hlist_head *list, |
515 | struct hlist_head *ndsttable, | 436 | struct hlist_head *ndsttable, |
516 | unsigned int nhashmask) | 437 | unsigned int nhashmask) |
@@ -553,7 +474,7 @@ static void xfrm_bydst_resize(int dir) | |||
553 | unsigned int nhashmask = xfrm_new_hash_mask(hmask); | 474 | unsigned int nhashmask = xfrm_new_hash_mask(hmask); |
554 | unsigned int nsize = (nhashmask + 1) * sizeof(struct hlist_head); | 475 | unsigned int nsize = (nhashmask + 1) * sizeof(struct hlist_head); |
555 | struct hlist_head *odst = xfrm_policy_bydst[dir].table; | 476 | struct hlist_head *odst = xfrm_policy_bydst[dir].table; |
556 | struct hlist_head *ndst = xfrm_policy_hash_alloc(nsize); | 477 | struct hlist_head *ndst = xfrm_hash_alloc(nsize); |
557 | int i; | 478 | int i; |
558 | 479 | ||
559 | if (!ndst) | 480 | if (!ndst) |
@@ -569,7 +490,7 @@ static void xfrm_bydst_resize(int dir) | |||
569 | 490 | ||
570 | write_unlock_bh(&xfrm_policy_lock); | 491 | write_unlock_bh(&xfrm_policy_lock); |
571 | 492 | ||
572 | xfrm_policy_hash_free(odst, (hmask + 1) * sizeof(struct hlist_head)); | 493 | xfrm_hash_free(odst, (hmask + 1) * sizeof(struct hlist_head)); |
573 | } | 494 | } |
574 | 495 | ||
575 | static void xfrm_byidx_resize(int total) | 496 | static void xfrm_byidx_resize(int total) |
@@ -578,7 +499,7 @@ static void xfrm_byidx_resize(int total) | |||
578 | unsigned int nhashmask = xfrm_new_hash_mask(hmask); | 499 | unsigned int nhashmask = xfrm_new_hash_mask(hmask); |
579 | unsigned int nsize = (nhashmask + 1) * sizeof(struct hlist_head); | 500 | unsigned int nsize = (nhashmask + 1) * sizeof(struct hlist_head); |
580 | struct hlist_head *oidx = xfrm_policy_byidx; | 501 | struct hlist_head *oidx = xfrm_policy_byidx; |
581 | struct hlist_head *nidx = xfrm_policy_hash_alloc(nsize); | 502 | struct hlist_head *nidx = xfrm_hash_alloc(nsize); |
582 | int i; | 503 | int i; |
583 | 504 | ||
584 | if (!nidx) | 505 | if (!nidx) |
@@ -594,7 +515,7 @@ static void xfrm_byidx_resize(int total) | |||
594 | 515 | ||
595 | write_unlock_bh(&xfrm_policy_lock); | 516 | write_unlock_bh(&xfrm_policy_lock); |
596 | 517 | ||
597 | xfrm_policy_hash_free(oidx, (hmask + 1) * sizeof(struct hlist_head)); | 518 | xfrm_hash_free(oidx, (hmask + 1) * sizeof(struct hlist_head)); |
598 | } | 519 | } |
599 | 520 | ||
600 | static inline int xfrm_bydst_should_resize(int dir, int *total) | 521 | static inline int xfrm_bydst_should_resize(int dir, int *total) |
@@ -2071,7 +1992,7 @@ static void __init xfrm_policy_init(void) | |||
2071 | hmask = 8 - 1; | 1992 | hmask = 8 - 1; |
2072 | sz = (hmask+1) * sizeof(struct hlist_head); | 1993 | sz = (hmask+1) * sizeof(struct hlist_head); |
2073 | 1994 | ||
2074 | xfrm_policy_byidx = xfrm_policy_hash_alloc(sz); | 1995 | xfrm_policy_byidx = xfrm_hash_alloc(sz); |
2075 | xfrm_idx_hmask = hmask; | 1996 | xfrm_idx_hmask = hmask; |
2076 | if (!xfrm_policy_byidx) | 1997 | if (!xfrm_policy_byidx) |
2077 | panic("XFRM: failed to allocate byidx hash\n"); | 1998 | panic("XFRM: failed to allocate byidx hash\n"); |
@@ -2082,7 +2003,7 @@ static void __init xfrm_policy_init(void) | |||
2082 | INIT_HLIST_HEAD(&xfrm_policy_inexact[dir]); | 2003 | INIT_HLIST_HEAD(&xfrm_policy_inexact[dir]); |
2083 | 2004 | ||
2084 | htab = &xfrm_policy_bydst[dir]; | 2005 | htab = &xfrm_policy_bydst[dir]; |
2085 | htab->table = xfrm_policy_hash_alloc(sz); | 2006 | htab->table = xfrm_hash_alloc(sz); |
2086 | htab->hmask = hmask; | 2007 | htab->hmask = hmask; |
2087 | if (!htab->table) | 2008 | if (!htab->table) |
2088 | panic("XFRM: failed to allocate bydst hash\n"); | 2009 | panic("XFRM: failed to allocate bydst hash\n"); |