SNAT: unknow protocol hairpinning fix 00/7200/2
authorMatus Fabian <matfabia@cisco.com>
Tue, 20 Jun 2017 08:45:49 +0000 (01:45 -0700)
committerOle Trøan <otroan@employees.org>
Tue, 20 Jun 2017 12:00:19 +0000 (12:00 +0000)
Change-Id: I15813167e7c8529f229143de4a8f64f0fb530951
Signed-off-by: Matus Fabian <matfabia@cisco.com>
src/plugins/snat/in2out.c
test/test_snat.py

index d396c79..661ddeb 100644 (file)
@@ -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
index e148fba..7544582 100644 (file)
@@ -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: