GRE: fix 4o6 and 6o4 adj stacking 91/14891/2
authorNeale Ranns <nranns@cisco.com>
Wed, 19 Sep 2018 11:55:32 +0000 (04:55 -0700)
committerOle Trøan <otroan@employees.org>
Wed, 19 Sep 2018 15:53:46 +0000 (15:53 +0000)
Change-Id: I13dc5eab8835c4f3b95906816d42dccfeee8b092
Signed-off-by: Neale Ranns <nranns@cisco.com>
src/vnet/fib/fib_types.c
src/vnet/fib/fib_types.h
src/vnet/gre/interface.c
src/vnet/mfib/mfib_test.c
test/test_gre.py

index a71f419..2560643 100644 (file)
@@ -339,6 +339,22 @@ fib_forw_chain_type_from_dpo_proto (dpo_proto_t proto)
     return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
 }
 
+fib_forward_chain_type_t
+fib_forw_chain_type_from_fib_proto (fib_protocol_t proto)
+{
+    switch (proto)
+    {
+    case FIB_PROTOCOL_IP4:
+       return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
+    case FIB_PROTOCOL_IP6:
+       return (FIB_FORW_CHAIN_TYPE_UNICAST_IP6);
+    case FIB_PROTOCOL_MPLS:
+       return (FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS);
+    }
+    ASSERT(0);
+    return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
+}
+
 vnet_link_t
 fib_forw_chain_type_to_link_type (fib_forward_chain_type_t fct)
 {
index 805f8e1..cd6ef7e 100644 (file)
@@ -187,6 +187,11 @@ extern fib_forward_chain_type_t fib_forw_chain_type_from_link_type(vnet_link_t l
  */
 extern fib_forward_chain_type_t fib_forw_chain_type_from_dpo_proto(dpo_proto_t proto);
 
+/**
+ * @brief Convert from a fib-protocol to a chain type.
+ */
+extern fib_forward_chain_type_t fib_forw_chain_type_from_fib_proto(fib_protocol_t proto);
+
 /**
  * @brief Convert from a chain type to the DPO proto it will install
  */
index cd7f952..0215f9b 100644 (file)
@@ -128,7 +128,9 @@ gre_tunnel_from_fib_node (fib_node_t * node)
 void
 gre_tunnel_stack (adj_index_t ai)
 {
+  fib_forward_chain_type_t fib_fwd;
   gre_main_t *gm = &gre_main;
+  dpo_id_t tmp = DPO_INVALID;
   ip_adjacency_t *adj;
   gre_tunnel_t *gt;
   u32 sw_if_index;
@@ -150,9 +152,7 @@ gre_tunnel_stack (adj_index_t ai)
       return;
     }
 
-  dpo_id_t tmp = DPO_INVALID;
-  fib_forward_chain_type_t fib_fwd = (FIB_PROTOCOL_IP6 == adj->ia_nh_proto) ?
-    FIB_FORW_CHAIN_TYPE_UNICAST_IP6 : FIB_FORW_CHAIN_TYPE_UNICAST_IP4;
+  fib_fwd = fib_forw_chain_type_from_fib_proto (gt->tunnel_dst.fp_proto);
 
   fib_entry_contribute_forwarding (gt->fib_entry_index, fib_fwd, &tmp);
   if (DPO_LOAD_BALANCE == tmp.dpoi_type)
index a94b308..4d519cd 100644 (file)
@@ -217,23 +217,6 @@ mfib_test_validate_rep_v (const replicate_t *rep,
     return (res);
 }
 
-static fib_forward_chain_type_t
-fib_forw_chain_type_from_fib_proto (fib_protocol_t proto)
-{
-    switch (proto)
-    {
-    case FIB_PROTOCOL_IP4:
-        return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
-    case FIB_PROTOCOL_IP6:
-        return (FIB_FORW_CHAIN_TYPE_UNICAST_IP6);
-    default:
-        break;
-    }
-    ASSERT(0);
-    return (0);
-}
-
-
 static int
 mfib_test_entry (fib_node_index_t fei,
                  mfib_entry_flags_t eflags,
index 4d40b3b..df3d2b4 100644 (file)
@@ -230,6 +230,60 @@ class TestGRE(VppTestCase):
                 self.logger.error(ppp("Tx:", tx))
                 raise
 
+    def verify_tunneled_4o6(self, src_if, capture, sent,
+                            tunnel_src, tunnel_dst):
+
+        self.assertEqual(len(capture), len(sent))
+
+        for i in range(len(capture)):
+            try:
+                tx = sent[i]
+                rx = capture[i]
+
+                rx_ip = rx[IPv6]
+
+                self.assertEqual(rx_ip.src, tunnel_src)
+                self.assertEqual(rx_ip.dst, tunnel_dst)
+
+                rx_gre = GRE(str(rx_ip[IPv6].payload))
+                tx_ip = tx[IP]
+                rx_ip = rx_gre[IP]
+
+                self.assertEqual(rx_ip.src, tx_ip.src)
+                self.assertEqual(rx_ip.dst, tx_ip.dst)
+
+            except:
+                self.logger.error(ppp("Rx:", rx))
+                self.logger.error(ppp("Tx:", tx))
+                raise
+
+    def verify_tunneled_6o4(self, src_if, capture, sent,
+                            tunnel_src, tunnel_dst):
+
+        self.assertEqual(len(capture), len(sent))
+
+        for i in range(len(capture)):
+            try:
+                tx = sent[i]
+                rx = capture[i]
+
+                rx_ip = rx[IP]
+
+                self.assertEqual(rx_ip.src, tunnel_src)
+                self.assertEqual(rx_ip.dst, tunnel_dst)
+
+                rx_gre = GRE(str(rx_ip[IP].payload))
+                rx_ip = rx_gre[IPv6]
+                tx_ip = tx[IPv6]
+
+                self.assertEqual(rx_ip.src, tx_ip.src)
+                self.assertEqual(rx_ip.dst, tx_ip.dst)
+
+            except:
+                self.logger.error(ppp("Rx:", rx))
+                self.logger.error(ppp("Tx:", tx))
+                raise
+
     def verify_tunneled_l2o4(self, src_if, capture, sent,
                              tunnel_src, tunnel_dst):
         self.assertEqual(len(capture), len(sent))
@@ -502,11 +556,29 @@ class TestGRE(VppTestCase):
         rx = self.pg0.get_capture(len(tx))
         self.verify_decapped_6o4(self.pg0, rx, tx)
 
+        #
+        # Send v6 packets for v4 encap
+        #
+        route6_via_tun = VppIpRoute(
+            self, "2001::1", 128,
+            [VppRoutePath("::",
+                          gre_if.sw_if_index,
+                          proto=DpoProto.DPO_PROTO_IP6)],
+            is_ip6=1)
+        route6_via_tun.add_vpp_config()
+
+        tx = self.create_stream_ip6(self.pg0, "2001::2", "2001::1")
+        rx = self.send_and_expect(self.pg0, tx, self.pg0)
+
+        self.verify_tunneled_6o4(self.pg0, rx, tx,
+                                 self.pg0.local_ip4, "1.1.1.2")
+
         #
         # test case cleanup
         #
         route_tun_dst.remove_vpp_config()
         route_via_tun.remove_vpp_config()
+        route6_via_tun.remove_vpp_config()
         gre_if.remove_vpp_config()
 
         self.pg0.unconfig_ip6()
@@ -601,11 +673,26 @@ class TestGRE(VppTestCase):
         self.assertFalse(rx[0].haslayer(GRE))
         self.assertEqual(rx[0][IPv6].dst, self.pg1.remote_ip6)
 
+        #
+        # Send v4 over v6
+        #
+        route4_via_tun = VppIpRoute(self, "1.1.1.1", 32,
+                                    [VppRoutePath("0.0.0.0",
+                                                  gre_if.sw_if_index)])
+        route4_via_tun.add_vpp_config()
+
+        tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "1.1.1.1")
+        rx = self.send_and_expect(self.pg0, tx, self.pg2)
+
+        self.verify_tunneled_4o6(self.pg0, rx, tx,
+                                 self.pg2.local_ip6, "1002::1")
+
         #
         # test case cleanup
         #
         route_tun_dst.remove_vpp_config()
         route_via_tun.remove_vpp_config()
+        route4_via_tun.remove_vpp_config()
         gre_if.remove_vpp_config()
 
         self.pg2.unconfig_ip6()