- 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);
+ }