diff options
Diffstat (limited to 'src/plugins/snat')
-rw-r--r-- | src/plugins/snat/snat_det.c | 57 |
1 files changed, 45 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* */ |