nat: add ipfix rate-limiter for nat44-ed, nat44-ei and nat64
[vpp.git] / src / plugins / nat / lib / ipfix_logging.c
index 50dbb2b..5f40db8 100644 (file)
@@ -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