From: Matus Fabian Date: Mon, 11 Sep 2017 05:17:47 +0000 (-0700) Subject: NAT: fixed hairpinning for in2out translation as an output feature (VPP-976) X-Git-Tag: v17.10-rc1~101 X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=b2d2fc7f581101261f59708eaf7a8ad5272a56cb;p=vpp.git 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 --- 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"