summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeale Ranns <neale@graphiant.com>2021-03-15 14:42:30 +0000
committerNeale Ranns <neale@graphiant.com>2021-03-21 18:55:01 +0000
commitbd8e43dfa045b4aec4ecf4ad3e5503924b5c9c38 (patch)
treefe91b63cc88910c5497dd34a0f3c6e1d20a3ea9e /src
parent8d8150262b00435c365a43c8f859584901736aff (diff)
gre: Multipoint GRE fixes
Type: fix - the CLI was broken when a nh-table-id was present, since it overwrote the next-hop address - bouncing interface state stacked the adjacencies on the tunnel's destination (which is all zeros) - don't crash in the switch path if the interface has no hw-address Signed-off-by: Neale Ranns <neale@graphiant.com> Change-Id: I1ba9fdc9b2185899b753a2d40f23afa847a3ef4f
Diffstat (limited to 'src')
-rw-r--r--src/vnet/gre/interface.c54
-rw-r--r--src/vnet/gre/test/test_gre.py28
-rw-r--r--src/vnet/ip-neighbor/ip4_neighbor.h7
-rw-r--r--src/vnet/teib/teib_cli.c4
4 files changed, 86 insertions, 7 deletions
diff --git a/src/vnet/gre/interface.c b/src/vnet/gre/interface.c
index 30c8dc479c2..30dfa3057b1 100644
--- a/src/vnet/gre/interface.c
+++ b/src/vnet/gre/interface.c
@@ -156,6 +156,45 @@ gre_tunnel_stack (adj_index_t ai)
}
/**
+ * mgre_tunnel_stack
+ *
+ * 'stack' (resolve the recursion for) the tunnel's midchain adjacency
+ */
+static void
+mgre_tunnel_stack (adj_index_t ai)
+{
+ gre_main_t *gm = &gre_main;
+ const ip_adjacency_t *adj;
+ const gre_tunnel_t *gt;
+ u32 sw_if_index;
+
+ adj = adj_get (ai);
+ sw_if_index = adj->rewrite_header.sw_if_index;
+
+ if ((vec_len (gm->tunnel_index_by_sw_if_index) <= sw_if_index) ||
+ (~0 == gm->tunnel_index_by_sw_if_index[sw_if_index]))
+ return;
+
+ gt = pool_elt_at_index (gm->tunnels,
+ gm->tunnel_index_by_sw_if_index[sw_if_index]);
+
+ if ((vnet_hw_interface_get_flags (vnet_get_main (), gt->hw_if_index) &
+ VNET_HW_INTERFACE_FLAG_LINK_UP) == 0)
+ {
+ adj_midchain_delegate_unstack (ai);
+ }
+ else
+ {
+ const teib_entry_t *ne;
+
+ ne = teib_entry_find_46 (sw_if_index, adj->ia_nh_proto,
+ &adj->sub_type.nbr.next_hop);
+ if (NULL != ne)
+ teib_entry_adj_stack (ne, ai);
+ }
+}
+
+/**
* @brief Call back when restacking all adjacencies on a GRE interface
*/
static adj_walk_rc_t
@@ -165,6 +204,13 @@ gre_adj_walk_cb (adj_index_t ai, void *ctx)
return (ADJ_WALK_RC_CONTINUE);
}
+static adj_walk_rc_t
+mgre_adj_walk_cb (adj_index_t ai, void *ctx)
+{
+ mgre_tunnel_stack (ai);
+
+ return (ADJ_WALK_RC_CONTINUE);
+}
static void
gre_tunnel_restack (gre_tunnel_t * gt)
@@ -176,7 +222,13 @@ gre_tunnel_restack (gre_tunnel_t * gt)
*/
FOR_EACH_FIB_IP_PROTOCOL (proto)
{
- adj_nbr_walk (gt->sw_if_index, proto, gre_adj_walk_cb, NULL);
+ switch (gt->mode)
+ {
+ case TUNNEL_MODE_P2P:
+ return (adj_nbr_walk (gt->sw_if_index, proto, gre_adj_walk_cb, NULL));
+ case TUNNEL_MODE_MP:
+ return (adj_nbr_walk (gt->sw_if_index, proto, mgre_adj_walk_cb, NULL));
+ }
}
}
diff --git a/src/vnet/gre/test/test_gre.py b/src/vnet/gre/test/test_gre.py
index 828fb731006..3192fee0e8a 100644
--- a/src/vnet/gre/test/test_gre.py
+++ b/src/vnet/gre/test/test_gre.py
@@ -1121,6 +1121,7 @@ class TestGRE(VppTestCase):
#
for ii in range(1, 4):
route_addr = "4.4.4.%d" % ii
+ tx_e = self.create_stream_ip4(self.pg0, "5.5.5.5", route_addr)
#
# route traffic via the peer
@@ -1131,6 +1132,15 @@ class TestGRE(VppTestCase):
gre_if.sw_if_index)])
route_via_tun.add_vpp_config()
+ # all packets dropped at this point
+ self.logger.error(self.vapi.cli("sh adj 19"))
+ rx = self.send_and_assert_no_replies(self.pg0, tx_e)
+
+ gre_if.admin_down()
+ gre_if.admin_up()
+ self.logger.error(self.vapi.cli("sh adj 19"))
+ rx = self.send_and_assert_no_replies(self.pg0, tx_e)
+
#
# Add a TEIB entry resolves the peer
#
@@ -1143,8 +1153,10 @@ class TestGRE(VppTestCase):
# Send a packet stream that is routed into the tunnel
# - packets are GRE encapped
#
- tx_e = self.create_stream_ip4(self.pg0, "5.5.5.5", route_addr)
- rx = self.send_and_expect(self.pg0, tx_e, itf)
+ try:
+ rx = self.send_and_expect(self.pg0, tx_e, itf)
+ finally:
+ self.logger.error(self.vapi.cli("sh adj 19"))
self.verify_tunneled_4o4(self.pg0, rx, tx_e,
itf.local_ip4,
itf._remote_hosts[ii].ip4)
@@ -1172,6 +1184,18 @@ class TestGRE(VppTestCase):
rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
self.verify_decapped_4o4(self.pg0, rx, tx_i)
+ #
+ # bounce the interface state and try packets again
+ #
+ gre_if.admin_down()
+ gre_if.admin_up()
+ rx = self.send_and_expect(self.pg0, tx_e, itf)
+ self.verify_tunneled_4o4(self.pg0, rx, tx_e,
+ itf.local_ip4,
+ itf._remote_hosts[ii].ip4)
+ rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
+ self.verify_decapped_4o4(self.pg0, rx, tx_i)
+
gre_if.admin_down()
gre_if.unconfig_ip4()
diff --git a/src/vnet/ip-neighbor/ip4_neighbor.h b/src/vnet/ip-neighbor/ip4_neighbor.h
index 8805beadf23..11309af82d5 100644
--- a/src/vnet/ip-neighbor/ip4_neighbor.h
+++ b/src/vnet/ip-neighbor/ip4_neighbor.h
@@ -37,6 +37,11 @@ ip4_neighbor_probe (vlib_main_t * vm,
vlib_buffer_t *b0;
u32 bi0;
+ hw_if0 = vnet_get_sup_hw_interface (vnm, adj0->rewrite_header.sw_if_index);
+
+ /* if (NULL == hw_if0->hw_address) */
+ /* return (NULL); */
+
/* Send ARP request. */
h0 = vlib_packet_template_get_packet (vm,
&ip4_main.ip4_arp_request_packet_template,
@@ -50,8 +55,6 @@ ip4_neighbor_probe (vlib_main_t * vm,
/* Add rewrite/encap string for ARP packet. */
vnet_rewrite_one_header (adj0[0], h0, sizeof (ethernet_header_t));
- hw_if0 = vnet_get_sup_hw_interface (vnm, adj0->rewrite_header.sw_if_index);
-
/* Src ethernet address in ARP header. */
mac_address_from_bytes (&h0->ip4_over_ethernet[0].mac, hw_if0->hw_address);
diff --git a/src/vnet/teib/teib_cli.c b/src/vnet/teib/teib_cli.c
index fd9e55ed742..a23902e0f60 100644
--- a/src/vnet/teib/teib_cli.c
+++ b/src/vnet/teib/teib_cli.c
@@ -40,10 +40,10 @@ teib_add (vlib_main_t * vm,
;
else if (unformat (line_input, "peer %U", unformat_ip_address, &peer))
;
- else if (unformat (line_input, "nh %U", unformat_ip_address, &nh))
- ;
else if (unformat (line_input, "nh-table-id %d", &nh_table_id))
;
+ else if (unformat (line_input, "nh %U", unformat_ip_address, &nh))
+ ;
else
{
error = clib_error_return (0, "unknown input `%U'",