nat: avoid running pointless session cleanups
[vpp.git] / src / plugins / nat / nat44 / inlines.h
index a7bb469..52dd37c 100644 (file)
@@ -65,7 +65,11 @@ nat44_user_try_cleanup (snat_user_t * u, u32 thread_index, f64 now)
        (f64) nat44_session_get_timeout (sm, s);
 
       if (now < sess_timeout_time)
-       continue;
+       {
+         tsm->min_session_timeout =
+           clib_min (sess_timeout_time, tsm->min_session_timeout);
+         continue;
+       }
 
       nat44_session_cleanup (s, thread_index);
     }
@@ -93,19 +97,70 @@ nat44_session_try_cleanup (ip4_address_t * addr,
       if (PREDICT_TRUE (pool_elts (tsm->sessions) < sm->max_translations))
        return;
 
-      // there is no place so we try to cleanup all users in this thread
+      if (now >= tsm->min_session_timeout)
+       {
+         tsm->min_session_timeout = ~0;
+         // there is no place so we try to cleanup all users in this thread
+          /* *INDENT-OFF* */
+          pool_foreach (u, tsm->users,
+                        ({ nat44_user_try_cleanup (u, thread_index, now); }));
+          /* *INDENT-ON* */
+         if (~0 == tsm->min_session_timeout)
+           {
+             tsm->min_session_timeout = 0;
+           }
+       }
+      return;
+    }
+
+  if (now >= tsm->min_session_timeout)
+    {
+      tsm->min_session_timeout = ~0;
+      // each time user creates a new session we try to cleanup expired sessions
+      nat44_user_try_cleanup (pool_elt_at_index (tsm->users, value.value),
+                             thread_index, now);
+      if (~0 == tsm->min_session_timeout)
+       {
+         tsm->min_session_timeout = 0;
+       }
+    }
+}
+
+static_always_inline void
+nat44_force_session_cleanup (void)
+{
+  snat_user_t *u = 0;
+
+  snat_main_t *sm = &snat_main;
+  snat_main_per_thread_data_t *tsm;
+
+  vlib_main_t *vm = vlib_get_main ();
+  f64 now = vlib_time_now (vm);
+
+  // TODO: consider own timeouts
+
+  if (sm->num_workers > 1)
+    {
+      /* *INDENT-OFF* */
+      vec_foreach (tsm, sm->per_thread_data)
+        {
+          pool_foreach (u, tsm->users,
+          ({
+            nat44_user_try_cleanup (u, tsm->thread_index, now);
+          }));
+        }
+      /* *INDENT-ON* */
+    }
+  else
+    {
+      tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
       /* *INDENT-OFF* */
       pool_foreach (u, tsm->users,
       ({
-        nat44_user_try_cleanup (u, thread_index, now);
+        nat44_user_try_cleanup (u, tsm->thread_index, now);
       }));
       /* *INDENT-ON* */
-      return;
     }
-
-  // each time user creates a new session we try to cleanup expired sessions
-  nat44_user_try_cleanup (pool_elt_at_index (tsm->users, value.value),
-                         thread_index, now);
 }
 
 #endif /* included_nat44_inlines_h__ */