NAT44: endpoint-dependent mode session timeout improvement (VPP-1423) 49/14949/2
authorMatus Fabian <matfabia@cisco.com>
Mon, 24 Sep 2018 11:41:28 +0000 (04:41 -0700)
committerDamjan Marion <dmarion@me.com>
Mon, 24 Sep 2018 21:38:05 +0000 (21:38 +0000)
Change-Id: I630f3da1ea4e6e50a50f1352c097becef1efe3c0
Signed-off-by: Matus Fabian <matfabia@cisco.com>
src/plugins/nat/in2out_ed.c
src/plugins/nat/nat.c
src/plugins/nat/nat.h
src/plugins/nat/out2in_ed.c
test/test_nat.py

index d4f70f5..7763026 100644 (file)
@@ -315,7 +315,7 @@ slow_path_ed (snat_main_t * sm,
       return NAT_IN2OUT_ED_NEXT_DROP;
     }
 
-  s = nat_ed_session_alloc (sm, u, thread_index);
+  s = nat_ed_session_alloc (sm, u, thread_index, now);
   if (!s)
     {
       nat44_delete_user_with_no_session (sm, u, thread_index);
@@ -777,7 +777,7 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm,
        }
 
     create_ses:
-      s = nat_ed_session_alloc (sm, u, thread_index);
+      s = nat_ed_session_alloc (sm, u, thread_index, now);
       if (!s)
        {
          nat44_delete_user_with_no_session (sm, u, thread_index);
index efca440..0818332 100755 (executable)
@@ -388,37 +388,73 @@ nat_session_alloc_or_recycle (snat_main_t * sm, snat_user_t * u,
 }
 
 snat_session_t *
-nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u, u32 thread_index)
+nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u, u32 thread_index,
+                     f64 now)
 {
   snat_session_t *s;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
-  dlist_elt_t *per_user_translation_list_elt;
+  dlist_elt_t *per_user_translation_list_elt, *oldest_elt;
+  u32 oldest_index;
+  u64 sess_timeout_time;
 
   if ((u->nsessions + u->nstaticsessions) >= sm->max_translations_per_user)
     {
-      nat_log_warn ("max translations per user %U", format_ip4_address,
-                   &u->addr);
-      snat_ipfix_logging_max_entries_per_user (sm->max_translations_per_user,
-                                              u->addr.as_u32);
-      return 0;
+      oldest_index =
+       clib_dlist_remove_head (tsm->list_pool,
+                               u->sessions_per_user_list_head_index);
+      oldest_elt = pool_elt_at_index (tsm->list_pool, oldest_index);
+      s = pool_elt_at_index (tsm->sessions, oldest_elt->value);
+      sess_timeout_time =
+       s->last_heard + (f64) nat44_session_get_timeout (sm, s);
+      if (now >= sess_timeout_time)
+       {
+         clib_dlist_addtail (tsm->list_pool,
+                             u->sessions_per_user_list_head_index,
+                             oldest_index);
+         nat_free_session_data (sm, s, thread_index);
+         if (snat_is_session_static (s))
+           u->nstaticsessions--;
+         else
+           u->nsessions--;
+         s->flags = 0;
+         s->total_bytes = 0;
+         s->total_pkts = 0;
+         s->state = 0;
+         s->ext_host_addr.as_u32 = 0;
+         s->ext_host_port = 0;
+         s->ext_host_nat_addr.as_u32 = 0;
+         s->ext_host_nat_port = 0;
+       }
+      else
+       {
+         clib_dlist_addhead (tsm->list_pool,
+                             u->sessions_per_user_list_head_index,
+                             oldest_index);
+         nat_log_warn ("max translations per user %U", format_ip4_address,
+                       &u->addr);
+         snat_ipfix_logging_max_entries_per_user
+           (sm->max_translations_per_user, u->addr.as_u32);
+         return 0;
+       }
     }
+  else
+    {
+      pool_get (tsm->sessions, s);
+      memset (s, 0, sizeof (*s));
 
-  pool_get (tsm->sessions, s);
-  memset (s, 0, sizeof (*s));
-
-  /* Create list elts */
-  pool_get (tsm->list_pool, per_user_translation_list_elt);
-  clib_dlist_init (tsm->list_pool,
-                  per_user_translation_list_elt - tsm->list_pool);
-
-  per_user_translation_list_elt->value = s - tsm->sessions;
-  s->per_user_index = per_user_translation_list_elt - tsm->list_pool;
-  s->per_user_list_head_index = u->sessions_per_user_list_head_index;
+      /* Create list elts */
+      pool_get (tsm->list_pool, per_user_translation_list_elt);
+      clib_dlist_init (tsm->list_pool,
+                      per_user_translation_list_elt - tsm->list_pool);
 
-  clib_dlist_addtail (tsm->list_pool,
-                     s->per_user_list_head_index,
-                     per_user_translation_list_elt - tsm->list_pool);
+      per_user_translation_list_elt->value = s - tsm->sessions;
+      s->per_user_index = per_user_translation_list_elt - tsm->list_pool;
+      s->per_user_list_head_index = u->sessions_per_user_list_head_index;
 
+      clib_dlist_addtail (tsm->list_pool,
+                         s->per_user_list_head_index,
+                         per_user_translation_list_elt - tsm->list_pool);
+    }
   return s;
 }
 
index 865d27e..1baf10f 100644 (file)
@@ -933,7 +933,7 @@ snat_session_t *nat_session_alloc_or_recycle (snat_main_t * sm,
  * @return session data structure on success otherwise zero value
  */
 snat_session_t *nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u,
-                                     u32 thread_index);
+                                     u32 thread_index, f64 now);
 
 /**
  * @brief Set address and port assignment algorithm for MAP-E CE
index 4236285..ef77233 100644 (file)
@@ -233,7 +233,7 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
       return 0;
     }
 
-  s = nat_ed_session_alloc (sm, u, thread_index);
+  s = nat_ed_session_alloc (sm, u, thread_index, now);
   if (!s)
     {
       nat44_delete_user_with_no_session (sm, u, thread_index);
@@ -421,7 +421,7 @@ create_bypass_for_fwd (snat_main_t * sm, ip4_header_t * ip, u32 rx_fib_index,
          return;
        }
 
-      s = nat_ed_session_alloc (sm, u, thread_index);
+      s = nat_ed_session_alloc (sm, u, thread_index, now);
       if (!s)
        {
          nat44_delete_user_with_no_session (sm, u, thread_index);
@@ -623,7 +623,7 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm,
        }
 
       /* Create a new session */
-      s = nat_ed_session_alloc (sm, u, thread_index);
+      s = nat_ed_session_alloc (sm, u, thread_index, now);
       if (!s)
        {
          nat44_delete_user_with_no_session (sm, u, thread_index);
index f3b5205..9092b47 100644 (file)
@@ -5657,6 +5657,7 @@ class TestNAT44EndpointDependent(MethodHolder):
                                      src_address=self.pg2.local_ip4n,
                                      path_mtu=512,
                                      template_interval=10)
+        self.vapi.nat_set_timeouts(udp=5)
 
         # get maximum number of translations per user
         nat44_config = self.vapi.nat_show_config()
@@ -5703,6 +5704,15 @@ class TestNAT44EndpointDependent(MethodHolder):
                     nat44_config.max_translations_per_user,
                     self.pg0.remote_ip4n)
 
+        sleep(6)
+        p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
+             IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
+             UDP(sport=3001, dport=3002))
+        self.pg0.add_stream(p)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        self.pg1.get_capture(1)
+
     def tearDown(self):
         super(TestNAT44EndpointDependent, self).tearDown()
         if not self.vpp_dead: