summaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/in2out.c
diff options
context:
space:
mode:
authorMatus Fabian <matfabia@cisco.com>2018-03-22 05:50:47 -0700
committerMatus Fabian <matfabia@cisco.com>2018-03-26 22:27:54 -0700
commitdd2f9865c1cb73a4d687941d52d220294f4a63d9 (patch)
treed1b9550f7508a212507827e182b204cf183367b9 /src/plugins/nat/in2out.c
parentef25e1d0daf7ae2bbc1d75ec937419c8bef7305e (diff)
NAT44: interface output feature and dst NAT (VPP-1200)
Do not translate packet which go out via nat44-in2out-output and was tranlated in nat44-out2in before. On way back forward packet to nat44-in2out node. Change-Id: I934d69856f0178c86ff879bc691c9e074b8485c8 Signed-off-by: Matus Fabian <matfabia@cisco.com> (cherry picked from commit 4d023c8c930b2a4220998d4c211d751e33324faa)
Diffstat (limited to 'src/plugins/nat/in2out.c')
-rwxr-xr-xsrc/plugins/nat/in2out.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/plugins/nat/in2out.c b/src/plugins/nat/in2out.c
index f81efb7bdeb..f731b81b74b 100755
--- a/src/plugins/nat/in2out.c
+++ b/src/plugins/nat/in2out.c
@@ -251,11 +251,14 @@ snat_not_translate (snat_main_t * sm, vlib_node_runtime_t *node,
static inline int
nat_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip0,
- u32 proto0, u16 src_port, u32 thread_index)
+ u32 proto0, u16 src_port, u16 dst_port,
+ u32 thread_index, u32 sw_if_index)
{
snat_session_key_t key0;
clib_bihash_kv_8_8_t kv0, value0;
+ snat_interface_t *i;
+ /* src NAT check */
key0.addr = ip0->src_address;
key0.port = src_port;
key0.protocol = proto0;
@@ -263,8 +266,26 @@ nat_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip0,
kv0.key = key0.as_u64;
if (!clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].out2in, &kv0,
- &value0))
+ &value0))
+ return 1;
+
+ /* dst NAT check */
+ key0.addr = ip0->dst_address;
+ key0.port = dst_port;
+ key0.protocol = proto0;
+ key0.fib_index = sm->inside_fib_index;
+ kv0.key = key0.as_u64;
+ if (!clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].in2out, &kv0,
+ &value0))
+ {
+ /* hairpinning */
+ pool_foreach (i, sm->output_feature_interfaces,
+ ({
+ if ((nat_interface_is_inside(i)) && (sw_if_index == i->sw_if_index))
+ return 0;
+ }));
return 1;
+ }
return 0;
}
@@ -556,7 +577,7 @@ u32 icmp_match_in2out_slow(snat_main_t *sm, vlib_node_runtime_t *node,
if (vnet_buffer(b0)->sw_if_index[VLIB_TX] != ~0)
{
if (PREDICT_FALSE(nat_not_translate_output_feature(sm,
- ip0, SNAT_PROTOCOL_ICMP, key0.port, thread_index)))
+ ip0, SNAT_PROTOCOL_ICMP, key0.port, key0.port, thread_index, sw_if_index0)))
{
dont_translate = 1;
goto out;
@@ -1591,7 +1612,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
if (is_output_feature)
{
if (PREDICT_FALSE(nat_not_translate_output_feature(sm,
- ip0, proto0, udp0->src_port, thread_index)))
+ ip0, proto0, udp0->src_port, udp0->dst_port, thread_index, sw_if_index0)))
goto trace00;
}
else
@@ -1783,7 +1804,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
if (is_output_feature)
{
if (PREDICT_FALSE(nat_not_translate_output_feature(sm,
- ip1, proto1, udp1->src_port, thread_index)))
+ ip1, proto1, udp1->src_port, udp1->dst_port, thread_index, sw_if_index1)))
goto trace01;
}
else
@@ -2011,7 +2032,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
if (is_output_feature)
{
if (PREDICT_FALSE(nat_not_translate_output_feature(sm,
- ip0, proto0, udp0->src_port, thread_index)))
+ ip0, proto0, udp0->src_port, udp0->dst_port, thread_index, sw_if_index0)))
goto trace0;
}
else