SNAT: added actual delete to snat_det_map 40/5740/5
authorMartin <magalik@cisco.com>
Tue, 14 Mar 2017 09:25:45 +0000 (02:25 -0700)
committerOle Trøan <otroan@employees.org>
Wed, 22 Mar 2017 07:27:39 +0000 (07:27 +0000)
Change-Id: I8187b43129b80fadd90ea493afb922064f79abbe
Signed-off-by: Martin <magalik@cisco.com>
src/plugins/snat/snat_det.c
test/test_snat.py

index d54bca6..2d6fce8 100644 (file)
@@ -43,19 +43,52 @@ snat_det_add_map (snat_main_t * sm, ip4_address_t * in_addr, u8 in_plen,
   snat_det_map_t *det_map;
   static snat_det_session_t empty_snat_det_session = { 0 };
   snat_interface_t *i;
+  ip4_address_t in_cmp, out_cmp;
+  u8 found = 0;
 
-  pool_get (sm->det_maps, det_map);
-  memset (det_map, 0, sizeof (*det_map));
-  det_map->in_addr.as_u32 = in_addr->as_u32 & ip4_main.fib_masks[in_plen];
-  det_map->in_plen = in_plen;
-  det_map->out_addr.as_u32 = out_addr->as_u32 & ip4_main.fib_masks[out_plen];
-  det_map->out_plen = out_plen;
-  det_map->sharing_ratio = (1 << (32 - in_plen)) / (1 << (32 - out_plen));
-  det_map->ports_per_host = (65535 - 1023) / det_map->sharing_ratio;
-
-  vec_validate_init_empty (det_map->sessions,
-                          SNAT_DET_SES_PER_USER * (1 << (32 - in_plen)) - 1,
-                          empty_snat_det_session);
+  in_cmp.as_u32 = in_addr->as_u32 & ip4_main.fib_masks[in_plen];
+  out_cmp.as_u32 = out_addr->as_u32 & ip4_main.fib_masks[out_plen];
+  vec_foreach (det_map, sm->det_maps)
+  {
+    /* Checking for overlapping addresses to be added here */
+    if (det_map->in_addr.as_u32 == in_cmp.as_u32 &&
+       det_map->in_plen == in_plen &&
+       det_map->out_addr.as_u32 == out_cmp.as_u32 &&
+       det_map->out_plen == out_plen)
+      {
+       found = 1;
+       break;
+      }
+  }
+
+  /* If found, don't add again */
+  if (found && is_add)
+    return VNET_API_ERROR_VALUE_EXIST;
+
+  /* If not found, don't delete */
+  if (!found && !is_add)
+    return VNET_API_ERROR_NO_SUCH_ENTRY;
+
+  if (is_add)
+    {
+      pool_get (sm->det_maps, det_map);
+      memset (det_map, 0, sizeof (*det_map));
+      det_map->in_addr.as_u32 = in_cmp.as_u32;
+      det_map->in_plen = in_plen;
+      det_map->out_addr.as_u32 = out_cmp.as_u32;
+      det_map->out_plen = out_plen;
+      det_map->sharing_ratio = (1 << (32 - in_plen)) / (1 << (32 - out_plen));
+      det_map->ports_per_host = (65535 - 1023) / det_map->sharing_ratio;
+
+      vec_validate_init_empty (det_map->sessions,
+                              SNAT_DET_SES_PER_USER * (1 << (32 - in_plen)) -
+                              1, empty_snat_det_session);
+    }
+  else
+    {
+      vec_free (det_map->sessions);
+      vec_del1 (sm->det_maps, det_map - sm->det_maps);
+    }
 
   /* Add/del external address range to FIB */
   /* *INDENT-OFF* */
index 7084f00..e1dd576 100644 (file)
@@ -1330,6 +1330,10 @@ class TestDeterministicNAT(VppTestCase):
         self.assertEqual(out_addr_n, dsm.out_addr[:4])
         self.assertEqual(out_plen, dsm.out_plen)
 
+        self.clear_snat()
+        deterministic_mappings = self.vapi.snat_det_map_dump()
+        self.assertEqual(len(deterministic_mappings), 0)
+
     def clear_snat(self):
         """
         Clear SNAT configuration.