ip: reassembly - pacing reassembly timeouts

Type: fix

Pace the main thread activity for reassembly timeouts, to avoid barrier syncs

Signed-off-by: Vijayabhaskar Katamreddy <vkatamre@cisco.com>
Change-Id: If8c62a05c7d28bfa6ac530c2cd5124834b4e8a70
This commit is contained in:
Vijayabhaskar Katamreddy 2022-05-13 13:07:19 +00:00 committed by Ole Tr�an
parent add6a384e9
commit 8b874fc6a8
2 changed files with 45 additions and 9 deletions

View File

@ -29,8 +29,12 @@
#include <stddef.h>
#define MSEC_PER_SEC 1000
#define IP4_REASS_TIMEOUT_DEFAULT_MS 100
#define IP4_REASS_EXPIRE_WALK_INTERVAL_DEFAULT_MS 10000 // 10 seconds default
#define IP4_REASS_TIMEOUT_DEFAULT_MS 200
/* As there are only 1024 reass context per thread, either the DDOS attacks
* or fractions of real timeouts, would consume these contexts quickly and
* running out context space and unable to perform reassembly */
#define IP4_REASS_EXPIRE_WALK_INTERVAL_DEFAULT_MS 50 // 50 ms default
#define IP4_REASS_MAX_REASSEMBLIES_DEFAULT 1024
#define IP4_REASS_MAX_REASSEMBLY_LENGTH_DEFAULT 3
#define IP4_REASS_HT_LOAD_FACTOR (0.75)
@ -155,6 +159,8 @@ typedef struct
ip4_full_reass_t *pool;
u32 reass_n;
u32 id_counter;
// for pacing the main thread timeouts
u32 last_id;
clib_spinlock_t lock;
} ip4_full_reass_per_thread_t;
@ -1699,14 +1705,33 @@ ip4_full_reass_walk_expired (vlib_main_t *vm, vlib_node_runtime_t *node,
vec_reset_length (pool_indexes_to_free);
pool_foreach_index (index, rt->pool)
/* Pace the number of timeouts handled per thread,to avoid barrier
* sync issues in real world scenarios */
u32 beg = rt->last_id;
/* to ensure we walk at least once per sec per context */
u32 end =
beg + (IP4_REASS_MAX_REASSEMBLIES_DEFAULT *
IP4_REASS_EXPIRE_WALK_INTERVAL_DEFAULT_MS / MSEC_PER_SEC +
1);
if (end > vec_len (rt->pool))
{
end = vec_len (rt->pool);
rt->last_id = 0;
}
else
{
rt->last_id = end;
}
pool_foreach_stepping_index (
index, beg, end, rt->pool, ({
reass = pool_elt_at_index (rt->pool, index);
if (now > reass->last_heard + rm->timeout)
{
vec_add1 (pool_indexes_to_free, index);
}
}
}));
if (vec_len (pool_indexes_to_free))
vlib_node_increment_counter (vm, node->node_index,

View File

@ -555,11 +555,22 @@ do { \
_pool_var(rv); \
})
#define pool_foreach_index(i,v) \
if (v) \
for (i = pool_get_first_index (v); \
i < vec_len (v); \
i = pool_get_next_index (v, i)) \
#define pool_foreach_index(i, v) \
if (v) \
for (i = pool_get_first_index (v); i < vec_len (v); \
i = pool_get_next_index (v, i))
/* Iterate pool by index from s to e */
#define pool_foreach_stepping_index(i, s, e, v, body) \
for ((i) = (s); (i) < (e); (i) = pool_get_next_index (v, i)) \
{ \
if (!pool_is_free_index ((v), (i))) \
do \
{ \
body; \
} \
while (0); \
}
/**
* @brief Remove all elements from a pool in a safe way