From a73f2d6f53c224668bd6bbea1a980ee4313c794f Mon Sep 17 00:00:00 2001 From: Filip Varga Date: Tue, 25 Feb 2020 14:31:33 +0100 Subject: nat: timed out session scavenging upgrade Patch changes the behavior of session scavenging and fixes multiple nat issues. Allows proper session clearing and removes issue with lingering sessions in session db. Patch also updates and fixes CLI/API calls for better readability of session state metrics. Fixes security issue that would allow attacker to reuse timed out session in both directions (in2out/out2in). Type: improvement Signed-off-by: Filip Varga Change-Id: I78897585a2a57291fad5db6d457941aa0a0457bd --- src/plugins/nat/nat_format.c | 91 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 5 deletions(-) (limited to 'src/plugins/nat/nat_format.c') diff --git a/src/plugins/nat/nat_format.c b/src/plugins/nat/nat_format.c index 17f64b9b222..71bdaa6662c 100644 --- a/src/plugins/nat/nat_format.c +++ b/src/plugins/nat/nat_format.c @@ -18,6 +18,7 @@ */ #include +#include #include uword @@ -173,7 +174,9 @@ format_snat_session (u8 * s, va_list * args) u8 * format_snat_user (u8 * s, va_list * args) { - snat_main_per_thread_data_t *sm = + + snat_main_t *sm = &snat_main; + snat_main_per_thread_data_t *tsm = va_arg (*args, snat_main_per_thread_data_t *); snat_user_t *u = va_arg (*args, snat_user_t *); int verbose = va_arg (*args, int); @@ -191,20 +194,20 @@ format_snat_user (u8 * s, va_list * args) if (u->nsessions || u->nstaticsessions) { head_index = u->sessions_per_user_list_head_index; - head = pool_elt_at_index (sm->list_pool, head_index); + head = pool_elt_at_index (tsm->list_pool, head_index); elt_index = head->next; - elt = pool_elt_at_index (sm->list_pool, elt_index); + elt = pool_elt_at_index (tsm->list_pool, elt_index); session_index = elt->value; while (session_index != ~0) { - sess = pool_elt_at_index (sm->sessions, session_index); + sess = pool_elt_at_index (tsm->sessions, session_index); s = format (s, " %U\n", format_snat_session, sm, sess); elt_index = elt->next; - elt = pool_elt_at_index (sm->list_pool, elt_index); + elt = pool_elt_at_index (tsm->list_pool, elt_index); session_index = elt->value; } } @@ -212,6 +215,84 @@ format_snat_user (u8 * s, va_list * args) return s; } +u8 * +format_snat_user_v2 (u8 * s, va_list * args) +{ + + snat_main_t *sm = &snat_main; + snat_main_per_thread_data_t *tsm = + va_arg (*args, snat_main_per_thread_data_t *); + snat_user_t *u = va_arg (*args, snat_user_t *); + u64 now = va_arg (*args, u64); + + dlist_elt_t *head, *elt; + u32 elt_index, head_index; + u32 session_index; + snat_session_t *sess; + + u32 udp_sessions = 0; + u32 tcp_sessions = 0; + u32 icmp_sessions = 0; + + u32 timed_out = 0; + u32 transitory = 0; + u32 established = 0; + + u64 sess_timeout_time; + + if (u->nsessions || u->nstaticsessions) + { + head_index = u->sessions_per_user_list_head_index; + head = pool_elt_at_index (tsm->list_pool, head_index); + + elt_index = head->next; + elt = pool_elt_at_index (tsm->list_pool, elt_index); + session_index = elt->value; + + while (session_index != ~0) + { + sess = pool_elt_at_index (tsm->sessions, session_index); + + sess_timeout_time = sess->last_heard + + (f64) nat44_session_get_timeout (sm, sess); + if (now >= sess_timeout_time) + timed_out++; + + switch (sess->in2out.protocol) + { + case SNAT_PROTOCOL_ICMP: + icmp_sessions++; + break; + case SNAT_PROTOCOL_TCP: + tcp_sessions++; + if (sess->state) + transitory++; + else + established++; + break; + case SNAT_PROTOCOL_UDP: + default: + udp_sessions++; + break; + + } + + elt_index = elt->next; + elt = pool_elt_at_index (tsm->list_pool, elt_index); + session_index = elt->value; + } + } + + s = format (s, "%U: %d dynamic translations, %d static translations\n", + format_ip4_address, &u->addr, u->nsessions, u->nstaticsessions); + s = format (s, "\t%u timed out, %u transitory, %u established\n", + timed_out, transitory, established); + s = format (s, "\t%u tcp sessions, %u udp sessions, %u icmp sessions\n", + tcp_sessions, udp_sessions, icmp_sessions); + + return s; +} + u8 * format_snat_static_mapping (u8 * s, va_list * args) { -- cgit 1.2.3-korg