From 1e5a2c6f190f65263882086bdbc3daaed54fb501 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Wed, 19 Sep 2018 04:55:32 -0700 Subject: GRE: fix 4o6 and 6o4 adj stacking Change-Id: I13dc5eab8835c4f3b95906816d42dccfeee8b092 Signed-off-by: Neale Ranns (cherry picked from commit 2646c80db8d3d1a3cd7555328d5a0038798f861e) --- src/vnet/fib/fib_types.c | 16 +++++++++ src/vnet/fib/fib_types.h | 5 +++ src/vnet/gre/interface.c | 6 ++-- src/vnet/mfib/mfib_test.c | 17 --------- test/test_gre.py | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 20 deletions(-) diff --git a/src/vnet/fib/fib_types.c b/src/vnet/fib/fib_types.c index d54b5c4a19a..f6ae15b2349 100644 --- a/src/vnet/fib/fib_types.c +++ b/src/vnet/fib/fib_types.c @@ -305,6 +305,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) { diff --git a/src/vnet/fib/fib_types.h b/src/vnet/fib/fib_types.h index 7f186ac6f6a..3a270ef6d82 100644 --- a/src/vnet/fib/fib_types.h +++ b/src/vnet/fib/fib_types.h @@ -177,6 +177,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 */ diff --git a/src/vnet/gre/interface.c b/src/vnet/gre/interface.c index 70c6c4df3b3..8e9bb881328 100644 --- a/src/vnet/gre/interface.c +++ b/src/vnet/gre/interface.c @@ -127,7 +127,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; @@ -149,9 +151,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) diff --git a/src/vnet/mfib/mfib_test.c b/src/vnet/mfib/mfib_test.c index a94b308473e..4d519cd460f 100644 --- a/src/vnet/mfib/mfib_test.c +++ b/src/vnet/mfib/mfib_test.c @@ -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, diff --git a/test/test_gre.py b/test/test_gre.py index 2559381b1f4..1fb695ff281 100644 --- a/test/test_gre.py +++ b/test/test_gre.py @@ -229,6 +229,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)) @@ -501,11 +555,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() @@ -600,11 +672,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() -- cgit 1.2.3-korg