summaryrefslogtreecommitdiffstats
path: root/src/plugins/nat
diff options
context:
space:
mode:
authorMatus Fabian <matfabia@cisco.com>2018-01-11 04:09:17 -0800
committerMatus Fabian <matfabia@cisco.com>2018-01-11 04:10:26 -0800
commit240b5ef57cc79cf32934ba8f218de29b6685406b (patch)
treef7fb27adbc53bfa26b6fef986f11976e3345debb /src/plugins/nat
parent0ae15ed43aaa600a75ca4c154bc62478820c00b4 (diff)
NAT44: asymmetrical load balancing static mapping rule (VPP-1132)
Add option to NAT44 load balancing static mapping API/CLI to make rule asymmetrical (rule match only in out2in direction). Change-Id: I325ecef5591e4bf44ce4469a24d44fe56c3bb2e9 Signed-off-by: Matus Fabian <matfabia@cisco.com>
Diffstat (limited to 'src/plugins/nat')
-rwxr-xr-xsrc/plugins/nat/in2out.c6
-rw-r--r--src/plugins/nat/nat.api4
-rw-r--r--src/plugins/nat/nat.c40
-rw-r--r--src/plugins/nat/nat.h3
-rw-r--r--src/plugins/nat/nat_api.c7
5 files changed, 38 insertions, 22 deletions
diff --git a/src/plugins/nat/in2out.c b/src/plugins/nat/in2out.c
index 5f2f43f7f81..0b87ba47812 100755
--- a/src/plugins/nat/in2out.c
+++ b/src/plugins/nat/in2out.c
@@ -1467,7 +1467,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
{
s0 = snat_in2out_lb(sm, b0, ip0, rx_fib_index0,
thread_index, now, vm, node);
- if (!s0)
+ if (!s0 && !sm->forwarding_enabled)
next0 = SNAT_IN2OUT_NEXT_DROP;
goto trace00;
}
@@ -1646,7 +1646,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
{
s1 = snat_in2out_lb(sm, b1, ip1, rx_fib_index1,
thread_index, now, vm, node);
- if (!s1)
+ if (!s1 && !sm->forwarding_enabled)
next1 = SNAT_IN2OUT_NEXT_DROP;
goto trace01;
}
@@ -1858,7 +1858,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
{
s0 = snat_in2out_lb(sm, b0, ip0, rx_fib_index0,
thread_index, now, vm, node);
- if (!s0)
+ if (!s0 && !sm->forwarding_enabled)
next0 = SNAT_IN2OUT_NEXT_DROP;
goto trace0;
}
diff --git a/src/plugins/nat/nat.api b/src/plugins/nat/nat.api
index 6ebe4e37933..78f34509b69 100644
--- a/src/plugins/nat/nat.api
+++ b/src/plugins/nat/nat.api
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-vl_api_version 2.1.0
+vl_api_version 2.2.0
/**
* @file nat.api
@@ -567,6 +567,7 @@ autoreply manual_endian define nat44_add_del_lb_static_mapping {
u8 protocol;
u32 vrf_id;
u8 twice_nat;
+ u8 out2in_only;
u8 local_num;
vl_api_nat44_lb_addr_port_t locals[local_num];
};
@@ -583,6 +584,7 @@ manual_endian define nat44_lb_static_mapping_details {
u8 protocol;
u32 vrf_id;
u8 twice_nat;
+ u8 out2in_only;
u8 local_num;
vl_api_nat44_lb_addr_port_t locals[local_num];
};
diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c
index 90515acc5b6..99c5f63cf12 100644
--- a/src/plugins/nat/nat.c
+++ b/src/plugins/nat/nat.c
@@ -973,7 +973,7 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr,
int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
snat_protocol_t proto, u32 vrf_id,
nat44_lb_addr_port_t *locals, u8 is_add,
- u8 twice_nat)
+ u8 twice_nat, u8 out2in_only)
{
snat_main_t * sm = &snat_main;
snat_static_mapping_t *m;
@@ -1014,7 +1014,7 @@ int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
/* Find external address in allocated addresses and reserve port for
address and port pair mapping when dynamic translations enabled */
- if (!sm->static_mapping_only)
+ if (!(sm->static_mapping_only || out2in_only))
{
for (i = 0; i < vec_len (sm->addresses); i++)
{
@@ -1058,6 +1058,7 @@ int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
m->external_port = e_port;
m->proto = proto;
m->twice_nat = twice_nat;
+ m->out2in_only = out2in_only;
m_key.addr = m->external_addr;
m_key.port = m->external_port;
@@ -1095,10 +1096,13 @@ int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
for (i = 0; i < vec_len (locals); i++)
{
m_key.addr = locals[i].addr;
- m_key.port = locals[i].port;
- kv.key = m_key.as_u64;
- kv.value = m - sm->static_mappings;
- clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 1);
+ if (!out2in_only)
+ {
+ m_key.port = locals[i].port;
+ kv.key = m_key.as_u64;
+ kv.value = m - sm->static_mappings;
+ clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 1);
+ }
locals[i].prefix = (i == 0) ? locals[i].probability :\
(locals[i - 1].prefix + locals[i].probability);
vec_add1 (m->locals, locals[i]);
@@ -1121,7 +1125,7 @@ int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
fib_table_unlock (m->fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_PLUGIN_HI);
/* Free external address port */
- if (!sm->static_mapping_only)
+ if (!(sm->static_mapping_only || out2in_only))
{
for (i = 0; i < vec_len (sm->addresses); i++)
{
@@ -1173,13 +1177,16 @@ int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
vec_foreach (local, m->locals)
{
m_key.addr = local->addr;
- m_key.port = local->port;
- m_key.fib_index = m->fib_index;
- kv.key = m_key.as_u64;
- if (clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 0))
+ if (!out2in_only)
{
- clib_warning ("static_mapping_by_local key del failed");
- return VNET_API_ERROR_UNSPECIFIED;
+ m_key.port = local->port;
+ m_key.fib_index = m->fib_index;
+ kv.key = m_key.as_u64;
+ if (clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 0))
+ {
+ clib_warning ("static_mapping_by_local key del failed");
+ return VNET_API_ERROR_UNSPECIFIED;
+ }
}
m_key.port = clib_host_to_net_u16 (local->port);
@@ -2509,6 +2516,7 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm,
u8 proto_set = 0;
nat44_lb_addr_port_t *locals = 0, local;
u8 twice_nat = 0;
+ u8 out2in_only = 0;
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
@@ -2535,6 +2543,8 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm,
proto_set = 1;
else if (unformat (line_input, "twice-nat"))
twice_nat = 1;
+ else if (unformat (line_input, "out2in-only"))
+ out2in_only = 1;
else if (unformat (line_input, "del"))
is_add = 0;
else
@@ -2558,7 +2568,7 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm,
}
rv = nat44_add_del_lb_static_mapping (e_addr, (u16) e_port, proto, vrf_id,
- locals, is_add, twice_nat);
+ locals, is_add, twice_nat, out2in_only);
switch (rv)
{
@@ -2591,7 +2601,7 @@ VLIB_CLI_COMMAND (add_lb_static_mapping_command, static) = {
.short_help =
"nat44 add load-balancing static mapping protocol tcp|udp "
"external <addr>:<port> local <addr>:<port> probability <n> [twice-nat] "
- "[vrf <table-id>] [del]",
+ "[vrf <table-id>] [out2in-only] [del]",
};
static clib_error_t *
diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h
index 614668d8421..ff7888a9128 100644
--- a/src/plugins/nat/nat.h
+++ b/src/plugins/nat/nat.h
@@ -217,6 +217,7 @@ typedef struct {
u16 external_port;
u8 addr_only;
u8 twice_nat;
+ u8 out2in_only;
u32 vrf_id;
u32 fib_index;
snat_protocol_t proto;
@@ -557,7 +558,7 @@ u8 * format_snat_protocol(u8 * s, va_list * args);
int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
snat_protocol_t proto, u32 vrf_id,
nat44_lb_addr_port_t *locals, u8 is_add,
- u8 twice_nat);
+ u8 twice_nat, u8 out2in_only);
int nat44_del_session (snat_main_t *sm, ip4_address_t *addr, u16 port,
snat_protocol_t proto, u32 vrf_id, int is_in);
void nat_free_session_data (snat_main_t * sm, snat_session_t * s,
diff --git a/src/plugins/nat/nat_api.c b/src/plugins/nat/nat_api.c
index d9f8bbd41be..dc9fc5d9a6d 100644
--- a/src/plugins/nat/nat_api.c
+++ b/src/plugins/nat/nat_api.c
@@ -1238,7 +1238,8 @@ static void
nat44_add_del_lb_static_mapping (e_addr,
clib_net_to_host_u16 (mp->external_port),
proto, clib_net_to_host_u32 (mp->vrf_id),
- locals, mp->is_add, mp->twice_nat);
+ locals, mp->is_add, mp->twice_nat,
+ mp->out2in_only);
vec_free (locals);
@@ -1251,7 +1252,8 @@ static void *vl_api_nat44_add_del_lb_static_mapping_t_print
u8 *s;
s = format (0, "SCRIPT: nat44_add_del_lb_static_mapping ");
- s = format (s, "is_add %d twice_nat %d", mp->is_add, mp->twice_nat);
+ s = format (s, "is_add %d twice_nat %d out2in_only ",
+ mp->is_add, mp->twice_nat, mp->out2in_only);
FINISH;
}
@@ -1278,6 +1280,7 @@ send_nat44_lb_static_mapping_details (snat_static_mapping_t * m,
rmp->vrf_id = ntohl (m->vrf_id);
rmp->context = context;
rmp->twice_nat = m->twice_nat;
+ rmp->out2in_only = m->out2in_only;
locals = (vl_api_nat44_lb_addr_port_t *) rmp->locals;
vec_foreach (ap, m->locals)