diff options
author | Nathan Skrzypczak <nathan.skrzypczak@gmail.com> | 2020-11-16 18:57:52 +0100 |
---|---|---|
committer | Beno�t Ganne <bganne@cisco.com> | 2021-01-28 13:34:15 +0000 |
commit | 208891c093468b753830d1e7ebdb4a69d4c192bf (patch) | |
tree | 1e184fd62916e483d2ccee673130ea5890b97ba1 /src/plugins/cnat/cnat_node.h | |
parent | 5214f3a2c89ed0858e9383dbaefd3202f354610d (diff) |
cnat: Fix throttle hash & cleanup
Type: fix
This fixes two issues :
- We used a hash to throttle RPC for adding fib entries,
but as we rely on a refcount, we cannot accept loosing an
entry, which could happen in case of a collision.
- On client cleanup we weren't freeing the fib entry correctly
which resulted in crashes when recreating an entry.
Added a test that ensures proper cleanup
Change-Id: Ie6660b0b02241f75092737410ae2299f8710d6b9
Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
Diffstat (limited to 'src/plugins/cnat/cnat_node.h')
-rw-r--r-- | src/plugins/cnat/cnat_node.h | 52 |
1 files changed, 22 insertions, 30 deletions
diff --git a/src/plugins/cnat/cnat_node.h b/src/plugins/cnat/cnat_node.h index 64c3db1e7cc..e2a9965b2a6 100644 --- a/src/plugins/cnat/cnat_node.h +++ b/src/plugins/cnat/cnat_node.h @@ -738,37 +738,31 @@ cnat_session_create (cnat_session_t * session, cnat_node_ctx_t * ctx, if (NULL == cc) { - u64 r0 = 17; - if (AF_IP4 == ctx->af) - r0 = (u64) session->value.cs_ip[VLIB_RX].ip4.as_u32; - else - { - r0 = r0 * 31 + session->value.cs_ip[VLIB_RX].ip6.as_u64[0]; - r0 = r0 * 31 + session->value.cs_ip[VLIB_RX].ip6.as_u64[1]; - } + ip_address_t addr; + uword *p; + u32 refcnt; + + addr.version = ctx->af; + ip46_address_copy (&addr.ip, &session->value.cs_ip[VLIB_RX]); + + /* Throttle */ + clib_spinlock_lock (&cnat_client_db.throttle_lock); - /* Rate limit */ - if (!throttle_check (&cnat_throttle, ctx->thread_index, r0, ctx->seed)) + p = hash_get_mem (cnat_client_db.throttle_mem, &addr); + if (p) { - cnat_learn_arg_t l; - l.addr.version = ctx->af; - ip46_address_copy (&l.addr.ip, &session->value.cs_ip[VLIB_RX]); - /* fire client create to the main thread */ - vl_api_rpc_call_main_thread (cnat_client_learn, - (u8 *) & l, sizeof (l)); + refcnt = p[0] + 1; + hash_set_mem (cnat_client_db.throttle_mem, &addr, refcnt); } else - { - /* Will still need to count those for session refcnt */ - ip_address_t *addr; - clib_spinlock_lock (&cnat_client_db.throttle_pool_lock - [ctx->thread_index]); - pool_get (cnat_client_db.throttle_pool[ctx->thread_index], addr); - addr->version = ctx->af; - ip46_address_copy (&addr->ip, &session->value.cs_ip[VLIB_RX]); - clib_spinlock_unlock (&cnat_client_db.throttle_pool_lock - [ctx->thread_index]); - } + hash_set_mem_alloc (&cnat_client_db.throttle_mem, &addr, 0); + + clib_spinlock_unlock (&cnat_client_db.throttle_lock); + + /* fire client create to the main thread */ + if (!p) + vl_api_rpc_call_main_thread (cnat_client_learn, (u8 *) &addr, + sizeof (addr)); } else { @@ -823,7 +817,6 @@ cnat_node_inline (vlib_main_t * vm, vlib_buffer_t **b = bufs; u16 nexts[VLIB_FRAME_SIZE], *next; f64 now; - u64 seed; thread_index = vm->thread_index; from = vlib_frame_vector_args (frame); @@ -831,13 +824,12 @@ cnat_node_inline (vlib_main_t * vm, next = nexts; vlib_get_buffers (vm, from, bufs, n_left); now = vlib_time_now (vm); - seed = throttle_seed (&cnat_throttle, thread_index, vlib_time_now (vm)); cnat_session_t *session[4]; clib_bihash_kv_40_48_t bkey[4], bvalue[4]; u64 hash[4]; int rv[4]; - cnat_node_ctx_t ctx = { now, seed, thread_index, af, do_trace }; + cnat_node_ctx_t ctx = { now, thread_index, af, do_trace }; if (n_left >= 8) { |