SNAT: added actual delete to snat_det_map
[vpp.git] / src / plugins / snat / snat_det.c
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* */