aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/snat/snat_det.c57
-rw-r--r--test/test_snat.py4
2 files changed, 49 insertions, 12 deletions
diff --git a/src/plugins/snat/snat_det.c b/src/plugins/snat/snat_det.c
index d54bca66cac..2d6fce85c0a 100644
--- a/src/plugins/snat/snat_det.c
+++ b/src/plugins/snat/snat_det.c
@@ -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* */
diff --git a/test/test_snat.py b/test/test_snat.py
index 7084f00208f..e1dd576e991 100644
--- a/test/test_snat.py
+++ b/test/test_snat.py
@@ -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.