summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatus Fabian <matfabia@cisco.com>2017-09-10 22:17:47 -0700
committerMatus Fabian <matfabia@cisco.com>2017-09-10 22:17:47 -0700
commitb2d2fc7f581101261f59708eaf7a8ad5272a56cb (patch)
treefde30cee7ddb8097cd884b53e2a5953942009b56
parent56dd5438b04b869065d8e901c315496bb6777455 (diff)
NAT: fixed hairpinning for in2out translation as an output feature (VPP-976)
Test whether the hairpinning flag is set only for packets from NAT inside interface. Change-Id: I4a4fdd2084a76a70ce9dfe3e2b8332c02fa2eccd Signed-off-by: Matus Fabian <matfabia@cisco.com>
-rw-r--r--src/plugins/nat/in2out.c26
-rw-r--r--test/test_nat.py19
2 files changed, 33 insertions, 12 deletions
diff --git a/src/plugins/nat/in2out.c b/src/plugins/nat/in2out.c
index c51d4fb4717..efb3856bfa1 100644
--- a/src/plugins/nat/in2out.c
+++ b/src/plugins/nat/in2out.c
@@ -3412,6 +3412,8 @@ snat_hairpin_src_fn (vlib_main_t * vm,
u32 bi0;
vlib_buffer_t * b0;
u32 next0;
+ snat_interface_t *i;
+ u32 sw_if_index0;
/* speculatively enqueue b0 to the current next frame */
bi0 = from[0];
@@ -3422,15 +3424,25 @@ snat_hairpin_src_fn (vlib_main_t * vm,
n_left_to_next -= 1;
b0 = vlib_get_buffer (vm, bi0);
+ sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
next0 = SNAT_HAIRPIN_SRC_NEXT_INTERFACE_OUTPUT;
- if (PREDICT_FALSE ((vnet_buffer (b0)->snat.flags) & SNAT_FLAG_HAIRPINNING))
- {
- if (PREDICT_TRUE (sm->num_workers > 1))
- next0 = SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT_WH;
- else
- next0 = SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT;
- }
+ pool_foreach (i, sm->output_feature_interfaces,
+ ({
+ /* Only packets from NAT inside interface */
+ if ((i->is_inside == 1) && (sw_if_index0 == i->sw_if_index))
+ {
+ if (PREDICT_FALSE ((vnet_buffer (b0)->snat.flags) &
+ SNAT_FLAG_HAIRPINNING))
+ {
+ if (PREDICT_TRUE (sm->num_workers > 1))
+ next0 = SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT_WH;
+ else
+ next0 = SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT;
+ }
+ break;
+ }
+ }));
pkts_processed += next0 != SNAT_IN2OUT_NEXT_DROP;
diff --git a/test/test_nat.py b/test/test_nat.py
index de07019f050..1f2d17ab101 100644
--- a/test/test_nat.py
+++ b/test/test_nat.py
@@ -2221,25 +2221,34 @@ class TestNAT44(MethodHolder):
""" NAT44 interface output feature (in2out postrouting) """
self.nat44_add_address(self.nat_addr)
self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
- self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
+ self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
+ self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
is_inside=0)
# in2out
- pkts = self.create_stream_in(self.pg0, self.pg1)
+ pkts = self.create_stream_in(self.pg0, self.pg3)
self.pg0.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
- capture = self.pg1.get_capture(len(pkts))
+ capture = self.pg3.get_capture(len(pkts))
self.verify_capture_out(capture)
# out2in
- pkts = self.create_stream_out(self.pg1)
- self.pg1.add_stream(pkts)
+ pkts = self.create_stream_out(self.pg3)
+ self.pg3.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
capture = self.pg0.get_capture(len(pkts))
self.verify_capture_in(capture, self.pg0)
+ # from non-NAT interface to NAT inside interface
+ pkts = self.create_stream_in(self.pg2, self.pg0)
+ self.pg2.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg0.get_capture(len(pkts))
+ self.verify_capture_no_translation(capture, self.pg2, self.pg0)
+
def test_output_feature_vrf_aware(self):
""" NAT44 interface output feature VRF aware (in2out postrouting) """
nat_ip_vrf10 = "10.0.0.10"