summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatus Fabian <matfabia@cisco.com>2017-06-20 01:45:49 -0700
committerOle Trøan <otroan@employees.org>2017-06-20 12:00:19 +0000
commit1e8db5fb6fd4c6cd168b0e6ec2f08b4af1e0093f (patch)
tree7d97da987b766c4c4830a7bde2bbd4151dd96f65
parent026c036dd4158f9f517a8dc7c79e3ad10d126b50 (diff)
SNAT: unknow protocol hairpinning fix
Change-Id: I15813167e7c8529f229143de4a8f64f0fb530951 Signed-off-by: Matus Fabian <matfabia@cisco.com>
-rw-r--r--src/plugins/snat/in2out.c2
-rw-r--r--test/test_snat.py59
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: