diff options
author | Vladislav Grishenko <themiron@yandex-team.ru> | 2023-09-14 22:14:38 +0500 |
---|---|---|
committer | Ole Tr�an <otroan@employees.org> | 2023-10-16 13:13:00 +0000 |
commit | da34f4add5f141d58670d81d53553986e9a472b4 (patch) | |
tree | da22aadb4d979440daf735ec8640f87a204fef55 /src/plugins | |
parent | ff344a98afd2057cd0df312a9d7277a95853fd0a (diff) |
nat: add ipfix rate-limiter for nat44-ed, nat44-ei and nat64
This prevents ipfix flood with the repeating events and allows
to enable nat64 max_session and max_bibs events. Also fix wrong
endian for det44 and nat64 ipfix tests, now should be fine with
extended tests enabled.
Max session per user event @ nat44-ei requires more precise rate
limiter per user address, probably with sparse vec, not handled.
Type: improvement
Signed-off-by: Vladislav Grishenko <themiron@yandex-team.ru>
Change-Id: Ib20cc1ee3f81e7acc88a415fe83b4e2deae2a836
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/nat/lib/ipfix_logging.c | 51 | ||||
-rw-r--r-- | src/plugins/nat/lib/ipfix_logging.h | 4 | ||||
-rw-r--r-- | src/plugins/nat/nat64/nat64_db.c | 4 |
3 files changed, 54 insertions, 5 deletions
diff --git a/src/plugins/nat/lib/ipfix_logging.c b/src/plugins/nat/lib/ipfix_logging.c index 50dbb2b327a..5f40db8d81c 100644 --- a/src/plugins/nat/lib/ipfix_logging.c +++ b/src/plugins/nat/lib/ipfix_logging.c @@ -1319,9 +1319,23 @@ nat_ipfix_logging_nat44_ses_delete (u32 thread_index, u32 src_ip, void nat_ipfix_logging_addresses_exhausted (u32 thread_index, u32 pool_id) { - //TODO: This event SHOULD be rate limited + nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main; + static f64 *last_sent = 0; + skip_if_disabled (); + /* TODO: make rate configurable, use 1pps so far */ + clib_spinlock_lock_if_init (&silm->addr_exhausted_lock); + f64 now = vlib_time_now (vlib_get_main ()); + vec_validate (last_sent, pool_id); + if (now < last_sent[pool_id] + 1.0) + { + clib_spinlock_unlock_if_init (&silm->addr_exhausted_lock); + return; + } + last_sent[pool_id] = now; + clib_spinlock_unlock_if_init (&silm->addr_exhausted_lock); + nat_ipfix_logging_addr_exhausted (thread_index, pool_id, 0); } @@ -1362,9 +1376,22 @@ deterministic_nat_data_callback void nat_ipfix_logging_max_sessions (u32 thread_index, u32 limit) { - //TODO: This event SHOULD be rate limited + nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main; + static f64 last_sent = 0; + skip_if_disabled (); + /* TODO: make rate configurable, use 1pps so far */ + clib_spinlock_lock_if_init (&silm->max_sessions_lock); + f64 now = vlib_time_now (vlib_get_main ()); + if (now < last_sent + 1.0) + { + clib_spinlock_unlock_if_init (&silm->max_sessions_lock); + return; + } + last_sent = now; + clib_spinlock_unlock_if_init (&silm->max_sessions_lock); + nat_ipfix_logging_max_ses (thread_index, limit, 0); } @@ -1377,9 +1404,22 @@ nat_ipfix_logging_max_sessions (u32 thread_index, u32 limit) void nat_ipfix_logging_max_bibs (u32 thread_index, u32 limit) { - //TODO: This event SHOULD be rate limited + nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main; + static f64 last_sent = 0; + skip_if_disabled (); + /* TODO: make rate configurable, use 1pps so far */ + clib_spinlock_lock_if_init (&silm->max_bibs_lock); + f64 now = vlib_time_now (vlib_get_main ()); + if (now < last_sent + 1.0) + { + clib_spinlock_unlock_if_init (&silm->max_bibs_lock); + return; + } + last_sent = now; + clib_spinlock_unlock_if_init (&silm->max_bibs_lock); + nat_ipfix_logging_max_bib (thread_index, limit, 0); } @@ -1574,6 +1614,11 @@ nat_ipfix_logging_init (vlib_main_t * vm) silm->milisecond_time_0 = unix_time_now_nsec () * 1e-6; vec_validate (silm->per_thread_data, tm->n_vlib_mains - 1); + + /* Set up rate-limit */ + clib_spinlock_init (&silm->addr_exhausted_lock); + clib_spinlock_init (&silm->max_sessions_lock); + clib_spinlock_init (&silm->max_bibs_lock); } static uword diff --git a/src/plugins/nat/lib/ipfix_logging.h b/src/plugins/nat/lib/ipfix_logging.h index 0b8f568e1b1..dc7927a160c 100644 --- a/src/plugins/nat/lib/ipfix_logging.h +++ b/src/plugins/nat/lib/ipfix_logging.h @@ -108,6 +108,10 @@ typedef struct { /** nat data callbacks call counter */ u16 call_counter; + /** rate-limit locks */ + clib_spinlock_t addr_exhausted_lock; + clib_spinlock_t max_sessions_lock; + clib_spinlock_t max_bibs_lock; } nat_ipfix_logging_main_t; extern nat_ipfix_logging_main_t nat_ipfix_logging_main; diff --git a/src/plugins/nat/nat64/nat64_db.c b/src/plugins/nat/nat64/nat64_db.c index 82ef70de5cf..24f7f571c01 100644 --- a/src/plugins/nat/nat64/nat64_db.c +++ b/src/plugins/nat/nat64/nat64_db.c @@ -82,7 +82,7 @@ nat64_db_bib_entry_create (u32 thread_index, nat64_db_t * db, if (db->bib.bib_entries_num >= db->bib.limit) { db->free_addr_port_cb (db, out_addr, out_port, proto); - //nat_ipfix_logging_max_bibs (thread_index, db->bib.limit); + nat_ipfix_logging_max_bibs (thread_index, db->bib.limit); return 0; } @@ -401,7 +401,7 @@ nat64_db_st_entry_create (u32 thread_index, nat64_db_t * db, if (db->st.st_entries_num >= db->st.limit) { - //nat_ipfix_logging_max_sessions (thread_index, db->st.limit); + nat_ipfix_logging_max_sessions (thread_index, db->st.limit); return 0; } |