aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/nat44-ei/nat44_ei.c
diff options
context:
space:
mode:
authorKlement Sekera <ksekera@cisco.com>2021-02-25 16:47:23 +0100
committerKlement Sekera <ksekera@cisco.com>2021-03-01 13:03:20 +0100
commitdc243ee2bcc4926ec23e71a687bb62b5c52c2fbb (patch)
treeeb4a57e84f45b5bbdfd4385976ce20974b797c5a /src/plugins/nat/nat44-ei/nat44_ei.c
parentf1af21c9d7c2d4f4e138b5dd0dd40e7f881b46ae (diff)
nat: pick outside addr based on local addr
Use outside addresses more evenly by using local address to pick from pool of addresses. This ensures stability from POV of remote host - an internal host always gets translated using the same outside address, so it doesn't appear to be "hopping". Also, this avoids all hosts being translated using the first address, which helps avoid needless recaptchas and the like. Exact assignment depends on internal ordering of addresses - local address is used to pick an offset into internal vector. If that address cannot be used, a linear search is performed as a fallback mechanism to find a possible translation. Type: improvement Signed-off-by: Klement Sekera <ksekera@cisco.com> Change-Id: I7ccb1da1dda5537f5d30d2f4cb48024f4b51c1a4
Diffstat (limited to 'src/plugins/nat/nat44-ei/nat44_ei.c')
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei.c68
1 files changed, 36 insertions, 32 deletions
diff --git a/src/plugins/nat/nat44-ei/nat44_ei.c b/src/plugins/nat/nat44-ei/nat44_ei.c
index fdf90708a09..d361060a42e 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei.c
@@ -1468,7 +1468,8 @@ nat44_ei_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip0,
static int
nat44_ei_alloc_default_cb (nat44_ei_address_t *addresses, u32 fib_index,
u32 thread_index, nat_protocol_t proto,
- ip4_address_t *addr, u16 *port, u16 port_per_thread,
+ ip4_address_t s_addr, ip4_address_t *addr,
+ u16 *port, u16 port_per_thread,
u32 snat_thread_index)
{
nat44_ei_main_t *nm = &nat44_ei_main;
@@ -1476,11 +1477,16 @@ nat44_ei_alloc_default_cb (nat44_ei_address_t *addresses, u32 fib_index,
u32 portnum;
int i;
- for (i = 0; i < vec_len (addresses); i++)
+ if (vec_len (addresses) > 0)
{
- a = addresses + i;
- switch (proto)
+
+ int s_addr_offset = s_addr.as_u32 % vec_len (addresses);
+
+ for (i = s_addr_offset; i < vec_len (addresses); ++i)
{
+ a = addresses + i;
+ switch (proto)
+ {
#define _(N, j, n, s) \
case NAT_PROTOCOL_##N: \
if (a->busy_##n##_ports_per_thread[thread_index] < port_per_thread) \
@@ -1509,41 +1515,39 @@ nat44_ei_alloc_default_cb (nat44_ei_address_t *addresses, u32 fib_index,
} \
} \
break;
- foreach_nat_protocol
-#undef _
- default : nat_elog_info (nm, "unknown protocol");
- return 1;
+ foreach_nat_protocol;
+ default:
+ nat_elog_info (nm, "unknown protocol");
+ return 1;
+ }
}
- }
+ for (i = 0; i < s_addr_offset; ++i)
+ {
+ a = addresses + i;
+ switch (proto)
+ {
+ foreach_nat_protocol;
+ default:
+ nat_elog_info (nm, "unknown protocol");
+ return 1;
+ }
+ }
if (ga)
{
a = ga;
+ // fake fib index to reuse macro
+ fib_index = ~0;
switch (proto)
{
-#define _(N, j, n, s) \
- case NAT_PROTOCOL_##N: \
- while (1) \
- { \
- portnum = \
- (port_per_thread * snat_thread_index) + \
- nat_random_port (&nm->random_seed, 0, port_per_thread - 1) + 1024; \
- if (a->busy_##n##_port_refcounts[portnum]) \
- continue; \
- ++a->busy_##n##_port_refcounts[portnum]; \
- a->busy_##n##_ports_per_thread[thread_index]++; \
- a->busy_##n##_ports++; \
- *addr = a->addr; \
- *port = clib_host_to_net_u16 (portnum); \
- return 0; \
- }
- break;
- foreach_nat_protocol
-#undef _
+ foreach_nat_protocol;
default : nat_elog_info (nm, "unknown protocol");
return 1;
}
}
+ }
+
+#undef _
/* Totally out of translations to use... */
nat_ipfix_logging_addresses_exhausted (thread_index, 0);
@@ -1553,8 +1557,8 @@ nat44_ei_alloc_default_cb (nat44_ei_address_t *addresses, u32 fib_index,
static int
nat44_ei_alloc_range_cb (nat44_ei_address_t *addresses, u32 fib_index,
u32 thread_index, nat_protocol_t proto,
- ip4_address_t *addr, u16 *port, u16 port_per_thread,
- u32 snat_thread_index)
+ ip4_address_t s_addr, ip4_address_t *addr, u16 *port,
+ u16 port_per_thread, u32 snat_thread_index)
{
nat44_ei_main_t *nm = &nat44_ei_main;
nat44_ei_address_t *a = addresses;
@@ -1600,8 +1604,8 @@ exhausted:
static int
nat44_ei_alloc_mape_cb (nat44_ei_address_t *addresses, u32 fib_index,
u32 thread_index, nat_protocol_t proto,
- ip4_address_t *addr, u16 *port, u16 port_per_thread,
- u32 snat_thread_index)
+ ip4_address_t s_addr, ip4_address_t *addr, u16 *port,
+ u16 port_per_thread, u32 snat_thread_index)
{
nat44_ei_main_t *nm = &nat44_ei_main;
nat44_ei_address_t *a = addresses;