summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei.c95
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei.h2
2 files changed, 80 insertions, 17 deletions
diff --git a/src/plugins/nat/nat44-ei/nat44_ei.c b/src/plugins/nat/nat44-ei/nat44_ei.c
index 4f2fa6112d5..8446011ec92 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei.c
@@ -185,6 +185,69 @@ static int nat44_ei_del_static_mapping_internal (
ip4_address_t l_addr, ip4_address_t e_addr, u16 l_port, u16 e_port,
nat_protocol_t proto, u32 vrf_id, u32 sw_if_index, u32 flags);
+always_inline void
+nat44_ei_port_get (nat44_ei_address_t *a, u8 proto, u16 port)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+#define _(N, i, n, s) \
+ case NAT_PROTOCOL_##N: \
+ a->busy_##n##_port_bitmap = \
+ clib_bitmap_set (a->busy_##n##_port_bitmap, port, 1); \
+ break;
+
+ switch (proto)
+ {
+ foreach_nat_protocol;
+ default:
+ nat_elog_info (nm, "unknown protocol");
+ }
+
+#undef _
+}
+
+always_inline void
+nat44_ei_port_put (nat44_ei_address_t *a, u8 proto, u16 port)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+#define _(N, i, n, s) \
+ case NAT_PROTOCOL_##N: \
+ a->busy_##n##_port_bitmap = \
+ clib_bitmap_set (a->busy_##n##_port_bitmap, port, 0); \
+ break;
+
+ switch (proto)
+ {
+ foreach_nat_protocol;
+ default:
+ nat_elog_info (nm, "unknown protocol");
+ }
+
+#undef _
+}
+
+always_inline bool
+nat44_ei_port_is_used (nat44_ei_address_t *a, u8 proto, u16 port)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+#define _(N, i, n, s) \
+ case NAT_PROTOCOL_##N: \
+ return clib_bitmap_get (a->busy_##n##_port_bitmap, port);
+
+ switch (proto)
+ {
+ foreach_nat_protocol;
+ default:
+ nat_elog_info (nm, "unknown protocol");
+ }
+
+#undef _
+
+ return 0;
+}
+
static u8 *
format_nat44_ei_classify_trace (u8 *s, va_list *args)
{
@@ -1256,9 +1319,9 @@ nat44_ei_set_outside_address_and_port (nat44_ei_address_t *addresses,
{
#define _(N, j, n, s) \
case NAT_PROTOCOL_##N: \
- if (a->busy_##n##_port_refcounts[port_host_byte_order]) \
+ if (nat44_ei_port_is_used (a, NAT_PROTOCOL_##N, port_host_byte_order)) \
return VNET_API_ERROR_INSTANCE_IN_USE; \
- ++a->busy_##n##_port_refcounts[port_host_byte_order]; \
+ nat44_ei_port_get (a, NAT_PROTOCOL_##N, port_host_byte_order); \
a->busy_##n##_ports_per_thread[thread_index]++; \
a->busy_##n##_ports++; \
return 0;
@@ -1320,8 +1383,9 @@ nat44_ei_free_outside_address_and_port (nat44_ei_address_t *addresses,
{
#define _(N, i, n, s) \
case NAT_PROTOCOL_##N: \
- ASSERT (a->busy_##n##_port_refcounts[port_host_byte_order] >= 1); \
- --a->busy_##n##_port_refcounts[port_host_byte_order]; \
+ ASSERT ( \
+ nat44_ei_port_is_used (a, NAT_PROTOCOL_##N, port_host_byte_order)); \
+ nat44_ei_port_put (a, NAT_PROTOCOL_##N, port_host_byte_order); \
a->busy_##n##_ports--; \
a->busy_##n##_ports_per_thread[thread_index]--; \
break;
@@ -1814,9 +1878,9 @@ nat44_ei_alloc_default_cb (nat44_ei_address_t *addresses, u32 fib_index,
nat_random_port (&nm->random_seed, 0, \
port_per_thread - 1) + \
1024; \
- if (a->busy_##n##_port_refcounts[portnum]) \
+ if (nat44_ei_port_is_used (a, NAT_PROTOCOL_##N, portnum)) \
continue; \
- --a->busy_##n##_port_refcounts[portnum]; \
+ nat44_ei_port_get (a, NAT_PROTOCOL_##N, portnum); \
a->busy_##n##_ports_per_thread[thread_index]++; \
a->busy_##n##_ports++; \
*addr = a->addr; \
@@ -1894,9 +1958,9 @@ nat44_ei_alloc_range_cb (nat44_ei_address_t *addresses, u32 fib_index,
{ \
portnum = nat_random_port (&nm->random_seed, nm->start_port, \
nm->end_port); \
- if (a->busy_##n##_port_refcounts[portnum]) \
+ if (nat44_ei_port_is_used (a, NAT_PROTOCOL_##N, portnum)) \
continue; \
- ++a->busy_##n##_port_refcounts[portnum]; \
+ nat44_ei_port_get (a, NAT_PROTOCOL_##N, portnum); \
a->busy_##n##_ports++; \
*addr = a->addr; \
*port = clib_host_to_net_u16 (portnum); \
@@ -1943,9 +2007,9 @@ nat44_ei_alloc_mape_cb (nat44_ei_address_t *addresses, u32 fib_index,
pow2_mask (nm->psid_offset)); \
j = nat_random_port (&nm->random_seed, 0, pow2_mask (m)); \
portnum = A | (nm->psid << nm->psid_offset) | (j << (16 - m)); \
- if (a->busy_##n##_port_refcounts[portnum]) \
+ if (nat44_ei_port_is_used (a, NAT_PROTOCOL_##N, portnum)) \
continue; \
- ++a->busy_##n##_port_refcounts[portnum]; \
+ nat44_ei_port_get (a, NAT_PROTOCOL_##N, portnum); \
a->busy_##n##_ports++; \
*addr = a->addr; \
*port = clib_host_to_net_u16 (portnum); \
@@ -2111,9 +2175,9 @@ nat44_ei_reserve_port (ip4_address_t addr, u16 port, nat_protocol_t proto)
{
#define _(N, j, n, s) \
case NAT_PROTOCOL_##N: \
- if (a->busy_##n##_port_refcounts[port]) \
- goto done; \
- ++a->busy_##n##_port_refcounts[port]; \
+ if (nat44_ei_port_is_used (a, NAT_PROTOCOL_##N, port)) \
+ continue; \
+ nat44_ei_port_get (a, NAT_PROTOCOL_##N, port); \
if (port > 1024) \
{ \
a->busy_##n##_ports++; \
@@ -2152,7 +2216,7 @@ nat44_ei_free_port (ip4_address_t addr, u16 port, nat_protocol_t proto)
{
#define _(N, j, n, s) \
case NAT_PROTOCOL_##N: \
- --a->busy_##n##_port_refcounts[port]; \
+ nat44_ei_port_put (a, NAT_PROTOCOL_##N, port); \
if (port > 1024) \
{ \
a->busy_##n##_ports--; \
@@ -2990,8 +3054,7 @@ nat44_ei_add_address (ip4_address_t *addr, u32 vrf_id)
}
#define _(N, i, n, s) \
- clib_memset (ap->busy_##n##_port_refcounts, 0, \
- sizeof (ap->busy_##n##_port_refcounts)); \
+ ap->busy_##n##_port_bitmap = 0; \
ap->busy_##n##_ports = 0; \
ap->busy_##n##_ports_per_thread = 0; \
vec_validate_init_empty (ap->busy_##n##_ports_per_thread, \
diff --git a/src/plugins/nat/nat44-ei/nat44_ei.h b/src/plugins/nat/nat44-ei/nat44_ei.h
index f353f48c482..c79cbfe5d57 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei.h
+++ b/src/plugins/nat/nat44-ei/nat44_ei.h
@@ -74,7 +74,7 @@ typedef struct
#define _(N, i, n, s) \
u32 busy_##n##_ports; \
u32 *busy_##n##_ports_per_thread; \
- u32 busy_##n##_port_refcounts[0xffff + 1];
+ uword *busy_##n##_port_bitmap;
foreach_nat_protocol
#undef _
} nat44_ei_address_t;