From 1e8db5fb6fd4c6cd168b0e6ec2f08b4af1e0093f Mon Sep 17 00:00:00 2001 From: Matus Fabian Date: Tue, 20 Jun 2017 01:45:49 -0700 Subject: SNAT: unknow protocol hairpinning fix Change-Id: I15813167e7c8529f229143de4a8f64f0fb530951 Signed-off-by: Matus Fabian --- src/plugins/snat/in2out.c | 2 +- test/test_snat.py | 59 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/plugins/snat/in2out.c b/src/plugins/snat/in2out.c index d396c79c1b2..661ddeb1185 100644 --- a/src/plugins/snat/in2out.c +++ b/src/plugins/snat/in2out.c @@ -1013,7 +1013,7 @@ snat_in2out_unknown_proto (snat_main_t *sm, sum = ip_csum_update (sum, old_addr, new_addr, ip4_header_t, dst_address); ip->checksum = ip_csum_fold (sum); - vnet_buffer(b)->sw_if_index[VLIB_TX] = vnet_buffer(b)->sw_if_index[VLIB_RX]; + vnet_buffer(b)->sw_if_index[VLIB_TX] = m->fib_index; } static inline uword diff --git a/test/test_snat.py b/test/test_snat.py index e148fbae56c..75445820a2f 100644 --- a/test/test_snat.py +++ b/test/test_snat.py @@ -1847,7 +1847,7 @@ class TestSNAT(MethodHolder): p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) / GRE() / - IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) / + IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) / TCP(sport=1234, dport=1234)) self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) @@ -1867,7 +1867,7 @@ class TestSNAT(MethodHolder): p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) / IP(src=self.pg1.remote_ip4, dst=nat_ip) / GRE() / - IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) / + IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) / TCP(sport=1234, dport=1234)) self.pg1.add_stream(p) self.pg_enable_capture(self.pg_interfaces) @@ -1883,6 +1883,61 @@ class TestSNAT(MethodHolder): self.logger.error(ppp("Unexpected or invalid packet:", packet)) raise + def test_hairpinning_unknown_proto(self): + """ 1:1 NAT translate packet with unknown protocol - hairpinning """ + + host = self.pg0.remote_hosts[0] + server = self.pg0.remote_hosts[1] + + host_nat_ip = "10.0.0.10" + server_nat_ip = "10.0.0.11" + + self.snat_add_static_mapping(host.ip4, host_nat_ip) + self.snat_add_static_mapping(server.ip4, server_nat_ip) + self.vapi.snat_interface_add_del_feature(self.pg0.sw_if_index) + self.vapi.snat_interface_add_del_feature(self.pg1.sw_if_index, + is_inside=0) + + # host to server + p = (Ether(dst=self.pg0.local_mac, src=host.mac) / + IP(src=host.ip4, dst=server_nat_ip) / + GRE() / + IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) / + TCP(sport=1234, dport=1234)) + self.pg0.add_stream(p) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + p = self.pg0.get_capture(1) + packet = p[0] + try: + self.assertEqual(packet[IP].src, host_nat_ip) + self.assertEqual(packet[IP].dst, server.ip4) + self.assertTrue(packet.haslayer(GRE)) + self.check_ip_checksum(packet) + except: + self.logger.error(ppp("Unexpected or invalid packet:", packet)) + raise + + # server to host + p = (Ether(dst=self.pg0.local_mac, src=server.mac) / + IP(src=server.ip4, dst=host_nat_ip) / + GRE() / + IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) / + TCP(sport=1234, dport=1234)) + self.pg0.add_stream(p) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + p = self.pg0.get_capture(1) + packet = p[0] + try: + self.assertEqual(packet[IP].src, server_nat_ip) + self.assertEqual(packet[IP].dst, host.ip4) + self.assertTrue(packet.haslayer(GRE)) + self.check_ip_checksum(packet) + except: + self.logger.error(ppp("Unexpected or invalid packet:", packet)) + raise + def tearDown(self): super(TestSNAT, self).tearDown() if not self.vpp_dead: -- cgit 1.2.3-korg