cnat: add ip/client bihash
This replace the cnat ip4/ip6 to client lookups previously done with a regular hash, by a bihash lookup. Type: improvement Do the client lookup in a bihash instead of a hash. Change-Id: I730c1893525c002b44ada8e290a36802835e88e9 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
This commit is contained in:
committed by
Beno�t Ganne
parent
878a9f5706
commit
897844d1e9
@@ -34,10 +34,42 @@ cnat_client_is_clone (cnat_client_t * cc)
|
||||
static void
|
||||
cnat_client_db_remove (cnat_client_t * cc)
|
||||
{
|
||||
clib_bihash_kv_16_8_t bkey;
|
||||
if (ip_addr_version (&cc->cc_ip) == AF_IP4)
|
||||
hash_unset (cnat_client_db.crd_cip4, ip_addr_v4 (&cc->cc_ip).as_u32);
|
||||
{
|
||||
bkey.key[0] = ip_addr_v4 (&cc->cc_ip).as_u32;
|
||||
bkey.key[1] = 0;
|
||||
}
|
||||
else
|
||||
hash_unset_mem_free (&cnat_client_db.crd_cip6, &ip_addr_v6 (&cc->cc_ip));
|
||||
{
|
||||
bkey.key[0] = ip_addr_v6 (&cc->cc_ip).as_u64[0];
|
||||
bkey.key[1] = ip_addr_v6 (&cc->cc_ip).as_u64[1];
|
||||
}
|
||||
|
||||
clib_bihash_add_del_16_8 (&cnat_client_db.cc_ip_id_hash, &bkey, 0 /* del */);
|
||||
}
|
||||
|
||||
static void
|
||||
cnat_client_db_add (cnat_client_t *cc)
|
||||
{
|
||||
index_t cci;
|
||||
|
||||
cci = cc - cnat_client_pool;
|
||||
|
||||
clib_bihash_kv_16_8_t bkey;
|
||||
bkey.value = cci;
|
||||
if (ip_addr_version (&cc->cc_ip) == AF_IP4)
|
||||
{
|
||||
bkey.key[0] = ip_addr_v4 (&cc->cc_ip).as_u32;
|
||||
bkey.key[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bkey.key[0] = ip_addr_v6 (&cc->cc_ip).as_u64[0];
|
||||
bkey.key[1] = ip_addr_v6 (&cc->cc_ip).as_u64[1];
|
||||
}
|
||||
|
||||
clib_bihash_add_del_16_8 (&cnat_client_db.cc_ip_id_hash, &bkey, 1 /* add */);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -118,21 +150,6 @@ cnat_client_translation_deleted (index_t cci)
|
||||
cnat_client_destroy (cc);
|
||||
}
|
||||
|
||||
static void
|
||||
cnat_client_db_add (cnat_client_t * cc)
|
||||
{
|
||||
index_t cci;
|
||||
|
||||
cci = cc - cnat_client_pool;
|
||||
|
||||
if (ip_addr_version (&cc->cc_ip) == AF_IP4)
|
||||
hash_set (cnat_client_db.crd_cip4, ip_addr_v4 (&cc->cc_ip).as_u32, cci);
|
||||
else
|
||||
hash_set_mem_alloc (&cnat_client_db.crd_cip6,
|
||||
&ip_addr_v6 (&cc->cc_ip), cci);
|
||||
}
|
||||
|
||||
|
||||
index_t
|
||||
cnat_client_add (const ip_address_t * ip, u8 flags)
|
||||
{
|
||||
@@ -228,12 +245,6 @@ int
|
||||
cnat_client_purge (void)
|
||||
{
|
||||
int rv = 0, rrv = 0;
|
||||
if ((rv = hash_elts (cnat_client_db.crd_cip6)))
|
||||
clib_warning ("len(crd_cip6) isnt 0 but %d", rv);
|
||||
rrv |= rv;
|
||||
if ((rv = hash_elts (cnat_client_db.crd_cip4)))
|
||||
clib_warning ("len(crd_cip4) isnt 0 but %d", rv);
|
||||
rrv |= rv;
|
||||
if ((rv = pool_elts (cnat_client_pool)))
|
||||
clib_warning ("len(cnat_client_pool) isnt 0 but %d", rv);
|
||||
rrv |= rv;
|
||||
@@ -371,12 +382,12 @@ const static dpo_vft_t cnat_client_dpo_vft = {
|
||||
static clib_error_t *
|
||||
cnat_client_init (vlib_main_t * vm)
|
||||
{
|
||||
cnat_main_t *cm = &cnat_main;
|
||||
cnat_client_dpo = dpo_register_new_type (&cnat_client_dpo_vft,
|
||||
cnat_client_dpo_nodes);
|
||||
|
||||
cnat_client_db.crd_cip6 = hash_create_mem (0,
|
||||
sizeof (ip6_address_t),
|
||||
sizeof (uword));
|
||||
clib_bihash_init_16_8 (&cnat_client_db.cc_ip_id_hash, "CNat client DB",
|
||||
cm->client_hash_buckets, cm->client_hash_memory);
|
||||
|
||||
clib_spinlock_init (&cnat_client_db.throttle_lock);
|
||||
cnat_client_db.throttle_mem =
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#define __CNAT_CLIENT_H__
|
||||
|
||||
#include <cnat/cnat_types.h>
|
||||
#include <vppinfra/bihash_16_8.h>
|
||||
|
||||
/**
|
||||
* A client is a representation of an IP address behind the NAT.
|
||||
@@ -132,8 +133,7 @@ extern void cnat_client_throttle_pool_process ();
|
||||
*/
|
||||
typedef struct cnat_client_db_t_
|
||||
{
|
||||
uword *crd_cip4;
|
||||
uword *crd_cip6;
|
||||
clib_bihash_16_8_t cc_ip_id_hash;
|
||||
/* Pool of addresses that have been throttled
|
||||
and need to be refcounted before calling
|
||||
cnat_client_free_by_ip */
|
||||
@@ -149,27 +149,15 @@ extern cnat_client_db_t cnat_client_db;
|
||||
static_always_inline cnat_client_t *
|
||||
cnat_client_ip4_find (const ip4_address_t * ip)
|
||||
{
|
||||
uword *p;
|
||||
clib_bihash_kv_16_8_t bkey, bval;
|
||||
|
||||
p = hash_get (cnat_client_db.crd_cip4, ip->as_u32);
|
||||
bkey.key[0] = ip->as_u32;
|
||||
bkey.key[1] = 0;
|
||||
|
||||
if (p)
|
||||
return (pool_elt_at_index (cnat_client_pool, p[0]));
|
||||
if (clib_bihash_search_16_8 (&cnat_client_db.cc_ip_id_hash, &bkey, &bval))
|
||||
return (NULL);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static_always_inline u32
|
||||
cnat_client_ip4_find_index (const ip4_address_t * ip)
|
||||
{
|
||||
uword *p;
|
||||
|
||||
p = hash_get (cnat_client_db.crd_cip4, ip->as_u32);
|
||||
|
||||
if (p)
|
||||
return p[0];
|
||||
|
||||
return -1;
|
||||
return (pool_elt_at_index (cnat_client_pool, bval.value));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,14 +166,15 @@ cnat_client_ip4_find_index (const ip4_address_t * ip)
|
||||
static_always_inline cnat_client_t *
|
||||
cnat_client_ip6_find (const ip6_address_t * ip)
|
||||
{
|
||||
uword *p;
|
||||
clib_bihash_kv_16_8_t bkey, bval;
|
||||
|
||||
p = hash_get_mem (cnat_client_db.crd_cip6, ip);
|
||||
bkey.key[0] = ip->as_u64[0];
|
||||
bkey.key[1] = ip->as_u64[1];
|
||||
|
||||
if (p)
|
||||
return (pool_elt_at_index (cnat_client_pool, p[0]));
|
||||
if (clib_bihash_search_16_8 (&cnat_client_db.cc_ip_id_hash, &bkey, &bval))
|
||||
return (NULL);
|
||||
|
||||
return (NULL);
|
||||
return (pool_elt_at_index (cnat_client_pool, bval.value));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -191,6 +191,8 @@ cnat_config (vlib_main_t * vm, unformat_input_t * input)
|
||||
cm->session_hash_buckets = CNAT_DEFAULT_SESSION_BUCKETS;
|
||||
cm->translation_hash_memory = CNAT_DEFAULT_TRANSLATION_MEMORY;
|
||||
cm->translation_hash_buckets = CNAT_DEFAULT_TRANSLATION_BUCKETS;
|
||||
cm->client_hash_memory = CNAT_DEFAULT_CLIENT_MEMORY;
|
||||
cm->client_hash_buckets = CNAT_DEFAULT_CLIENT_BUCKETS;
|
||||
cm->snat_hash_memory = CNAT_DEFAULT_SNAT_MEMORY;
|
||||
cm->snat_hash_buckets = CNAT_DEFAULT_SNAT_BUCKETS;
|
||||
cm->snat_if_map_length = CNAT_DEFAULT_SNAT_IF_MAP_LEN;
|
||||
@@ -215,6 +217,12 @@ cnat_config (vlib_main_t * vm, unformat_input_t * input)
|
||||
else if (unformat (input, "translation-db-memory %U",
|
||||
unformat_memory_size, &cm->translation_hash_memory))
|
||||
;
|
||||
else if (unformat (input, "client-db-buckets %u",
|
||||
&cm->client_hash_buckets))
|
||||
;
|
||||
else if (unformat (input, "client-db-memory %U", unformat_memory_size,
|
||||
&cm->client_hash_memory))
|
||||
;
|
||||
else if (unformat (input, "snat-db-buckets %u", &cm->snat_hash_buckets))
|
||||
;
|
||||
else if (unformat (input, "snat-if-map-len %u", &cm->snat_if_map_length))
|
||||
|
||||
@@ -36,12 +36,14 @@
|
||||
|
||||
#define CNAT_DEFAULT_SESSION_BUCKETS 1024
|
||||
#define CNAT_DEFAULT_TRANSLATION_BUCKETS 1024
|
||||
#define CNAT_DEFAULT_CLIENT_BUCKETS 1024
|
||||
#define CNAT_DEFAULT_SNAT_BUCKETS 1024
|
||||
#define CNAT_DEFAULT_SNAT_IF_MAP_LEN 4096
|
||||
|
||||
#define CNAT_DEFAULT_SESSION_MEMORY (1 << 20)
|
||||
#define CNAT_DEFAULT_TRANSLATION_MEMORY (256 << 10)
|
||||
#define CNAT_DEFAULT_SNAT_MEMORY (64 << 20)
|
||||
#define CNAT_DEFAULT_CLIENT_MEMORY (256 << 10)
|
||||
#define CNAT_DEFAULT_SNAT_MEMORY (64 << 10)
|
||||
|
||||
/* Should be prime >~ 100 * numBackends */
|
||||
#define CNAT_DEFAULT_MAGLEV_LEN 1009
|
||||
@@ -120,6 +122,12 @@ typedef struct cnat_main_
|
||||
/* Number of buckets of the translation bihash */
|
||||
u32 translation_hash_buckets;
|
||||
|
||||
/* Memory size of the client bihash */
|
||||
uword client_hash_memory;
|
||||
|
||||
/* Number of buckets of the client bihash */
|
||||
u32 client_hash_buckets;
|
||||
|
||||
/* Memory size of the source NAT prefix bihash */
|
||||
uword snat_hash_memory;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user