summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_nht.c8
-rw-r--r--bgpd/bgp_route.c1
-rw-r--r--bgpd/bgp_routemap.c5
-rw-r--r--bgpd/bgp_updgrp_packet.c19
-rw-r--r--bgpd/bgp_vty.c8
-rw-r--r--lib/command_match.c2
-rw-r--r--lib/event.c20
-rw-r--r--pimd/pim_msg.c27
-rw-r--r--pimd/pim_nht.c41
-rw-r--r--pimd/pim_upstream.c1
-rw-r--r--pimd/pim_vxlan.c36
-rw-r--r--pimd/pim_vxlan.h3
-rw-r--r--tests/topotests/bgp_evpn_mh/leaf1/evpn.conf21
-rw-r--r--tests/topotests/bgp_evpn_mh/leaf1/pim.conf26
-rw-r--r--tests/topotests/bgp_evpn_mh/leaf1/zebra.conf30
-rw-r--r--tests/topotests/bgp_evpn_mh/leaf2/evpn.conf21
-rw-r--r--tests/topotests/bgp_evpn_mh/leaf2/pim.conf20
-rw-r--r--tests/topotests/bgp_evpn_mh/leaf2/zebra.conf24
-rw-r--r--tests/topotests/bgp_evpn_mh/spine1/evpn.conf12
-rw-r--r--tests/topotests/bgp_evpn_mh/spine1/pim.conf12
-rw-r--r--tests/topotests/bgp_evpn_mh/spine1/zebra.conf12
-rw-r--r--tests/topotests/bgp_evpn_mh/spine2/evpn.conf12
-rw-r--r--tests/topotests/bgp_evpn_mh/spine2/pim.conf7
-rw-r--r--tests/topotests/bgp_evpn_mh/spine2/zebra.conf14
-rw-r--r--tests/topotests/bgp_evpn_mh/test_evpn_mh.py79
-rw-r--r--tests/topotests/bgp_evpn_mh/torm11/pim.conf6
-rw-r--r--tests/topotests/bgp_evpn_mh/torm12/pim.conf6
-rw-r--r--tests/topotests/bgp_evpn_mh/torm21/pim.conf6
-rw-r--r--tests/topotests/bgp_evpn_mh/torm22/pim.conf6
-rw-r--r--tests/topotests/bgp_labeled_unicast_default_originate/r1/bgpd.conf14
-rw-r--r--tests/topotests/bgp_labeled_unicast_default_originate/r1/zebra.conf1
-rw-r--r--tests/topotests/bgp_labeled_unicast_default_originate/r2/bgpd.conf8
-rw-r--r--tests/topotests/bgp_labeled_unicast_default_originate/r2/zebra.conf1
-rw-r--r--tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py27
-rw-r--r--vtysh/vtysh_config.c12
-rw-r--r--zebra/interface.c5
36 files changed, 429 insertions, 124 deletions
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index bbc30365c7..733dcc72a2 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -316,6 +316,14 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
if (make_prefix(afi, pi, &p) < 0)
return 1;
+ /*
+ * If path is learnt from an interface based peer,
+ * set the ifindex to peer's interface index so that
+ * correct nexthop can be found in nexthop tree.
+ */
+ if (pi->peer->conf_if)
+ ifindex = pi->peer->su.sin6.sin6_scope_id;
+
if (!is_bgp_static_route && orig_prefix
&& prefix_same(&p, orig_prefix)) {
if (BGP_DEBUG(nht, NHT)) {
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 457db79c43..3b3cbb28a9 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -6610,6 +6610,7 @@ int bgp_static_set(struct vty *vty, bool negate, const char *ip_str,
}
if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN) {
+ memset(&prd, 0, sizeof(prd));
ret = str2prefix_rd(rd_str, &prd);
if (!ret) {
vty_out(vty, "%% Malformed rd\n");
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 1c99495e6c..4e142faad4 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -6163,6 +6163,7 @@ DEFPY_YANG(
char xpath_value[XPATH_MAXLEN];
as_t as_configured_value;
char replace_value[ASN_STRING_MAX_SIZE * 2];
+ int ret;
if (configured_asn_str &&
!asn_str2asn(configured_asn_str, &as_configured_value)) {
@@ -6181,7 +6182,9 @@ DEFPY_YANG(
"%s/rmap-set-action/frr-bgp-route-map:replace-as-path", xpath);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
- return nb_cli_apply_changes(vty, NULL);
+ ret = nb_cli_apply_changes(vty, NULL);
+ XFREE(MTYPE_TMP, str);
+ return ret;
}
DEFPY_YANG(
diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c
index 49b7f51286..7502bf2ec6 100644
--- a/bgpd/bgp_updgrp_packet.c
+++ b/bgpd/bgp_updgrp_packet.c
@@ -1080,8 +1080,7 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp,
safi_t safi;
struct bpacket_attr_vec_arr vecarr;
bool addpath_capable = false;
- uint8_t default_originate_label[4] = {0x80, 0x00, 0x00};
- mpls_label_t *label = NULL;
+ mpls_label_t label = MPLS_LABEL_IMPLICIT_NULL;
uint32_t num_labels = 0;
if (DISABLE_BGP_ANNOUNCE)
@@ -1097,7 +1096,11 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp,
addpath_capable = bgp_addpath_encode_tx(peer, afi, safi);
if (safi == SAFI_LABELED_UNICAST) {
- label = (mpls_label_t *)default_originate_label;
+ label = mpls_lse_encode((afi == AFI_IP)
+ ? MPLS_LABEL_IPV4_EXPLICIT_NULL
+ : MPLS_LABEL_IPV6_EXPLICIT_NULL,
+ 0, 0, 1);
+ bgp_set_valid_label(&label);
num_labels = 1;
}
@@ -1142,10 +1145,12 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp,
/* Make place for total attribute length. */
pos = stream_get_endp(s);
stream_putw(s, 0);
- total_attr_len = bgp_packet_attribute(
- NULL, peer, s, attr, &vecarr, &p, afi, safi, from, NULL, label,
- num_labels, addpath_capable,
- BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE, NULL);
+ total_attr_len =
+ bgp_packet_attribute(NULL, peer, s, attr, &vecarr, &p, afi,
+ safi, from, NULL, &label, num_labels,
+ addpath_capable,
+ BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE,
+ NULL);
/* Set Total Path Attribute Length. */
stream_putw_at(s, pos, total_attr_len);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 9c09ca0efd..be0fe42837 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -2001,8 +2001,8 @@ DEFUN (bgp_confederation_identifier,
"bgp confederation identifier ASNUM",
BGP_STR
"AS confederation parameters\n"
- AS_STR
- "Set routing domain confederation AS\n")
+ "Set routing domain confederation AS\n"
+ AS_STR)
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_number = 3;
@@ -2024,8 +2024,8 @@ DEFUN (no_bgp_confederation_identifier,
NO_STR
BGP_STR
"AS confederation parameters\n"
- AS_STR
- "Set routing domain confederation AS\n")
+ "Set routing domain confederation AS\n"
+ AS_STR)
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_confederation_id_unset(bgp);
diff --git a/lib/command_match.c b/lib/command_match.c
index ff3c48fc31..f740b72600 100644
--- a/lib/command_match.c
+++ b/lib/command_match.c
@@ -566,9 +566,9 @@ static int score_precedence(enum cmd_token_type type)
case IPV6_PREFIX_TKN:
case MAC_TKN:
case MAC_PREFIX_TKN:
- case ASNUM_TKN:
case RANGE_TKN:
return 2;
+ case ASNUM_TKN:
case WORD_TKN:
return 3;
case VARIABLE_TKN:
diff --git a/lib/event.c b/lib/event.c
index b971bd70e6..4b4ca9d7ea 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -355,7 +355,7 @@ DEFPY (service_cputime_stats,
DEFPY (service_cputime_warning,
service_cputime_warning_cmd,
- "[no] service cputime-warning (1-4294967295)",
+ "[no] service cputime-warning ![(1-4294967295)]",
NO_STR
"Set up miscellaneous service\n"
"Warn for tasks exceeding CPU usage threshold\n"
@@ -368,16 +368,9 @@ DEFPY (service_cputime_warning,
return CMD_SUCCESS;
}
-ALIAS (service_cputime_warning,
- no_service_cputime_warning_cmd,
- "no service cputime-warning",
- NO_STR
- "Set up miscellaneous service\n"
- "Warn for tasks exceeding CPU usage threshold\n")
-
DEFPY (service_walltime_warning,
service_walltime_warning_cmd,
- "[no] service walltime-warning (1-4294967295)",
+ "[no] service walltime-warning ![(1-4294967295)]",
NO_STR
"Set up miscellaneous service\n"
"Warn for tasks exceeding total wallclock threshold\n"
@@ -390,13 +383,6 @@ DEFPY (service_walltime_warning,
return CMD_SUCCESS;
}
-ALIAS (service_walltime_warning,
- no_service_walltime_warning_cmd,
- "no service walltime-warning",
- NO_STR
- "Set up miscellaneous service\n"
- "Warn for tasks exceeding total wallclock threshold\n")
-
static void show_thread_poll_helper(struct vty *vty, struct event_loop *m)
{
const char *name = m->name ? m->name : "main";
@@ -525,9 +511,7 @@ void event_cmd_init(void)
install_element(CONFIG_NODE, &service_cputime_stats_cmd);
install_element(CONFIG_NODE, &service_cputime_warning_cmd);
- install_element(CONFIG_NODE, &no_service_cputime_warning_cmd);
install_element(CONFIG_NODE, &service_walltime_warning_cmd);
- install_element(CONFIG_NODE, &no_service_walltime_warning_cmd);
install_element(VIEW_NODE, &show_thread_timers_cmd);
}
diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c
index 5d1f08314b..6814798bf5 100644
--- a/pimd/pim_msg.c
+++ b/pimd/pim_msg.c
@@ -196,7 +196,32 @@ size_t pim_msg_get_jp_group_size(struct list *sources)
__func__, up->sg_str);
for (ALL_LIST_ELEMENTS_RO(up->sources, up_node, child)) {
- if (!PIM_UPSTREAM_FLAG_TEST_USE_RPT(child->flags)) {
+ /*
+ * PIM VXLAN is weird
+ * It auto creates the S,G and populates a bunch
+ * of flags that make it look like a SPT prune should
+ * be sent. But this regularly scheduled join
+ * for the *,G in the VXLAN setup can happen at
+ * scheduled times *before* the null register
+ * is received by the RP to cause it to initiate
+ * the S,G joins toward the source. Let's just
+ * assume that if this is a SRC VXLAN ORIG route
+ * and no actual ifchannels( joins ) have been
+ * created then do not send the embedded prune
+ * Why you may ask? Well if the prune is S,G
+ * RPT Prune is received *before* the join
+ * from the RP( if it flows to this routers
+ * upstream interface ) then we'll just wisely
+ * create a mroute with an empty oil on
+ * the upstream intermediate router preventing
+ * packets from flowing to the RP
+ */
+ if (PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(child->flags) &&
+ listcount(child->ifchannels) == 0) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("%s: %s Vxlan originated S,G route with no ifchannels, not adding prune to compound message",
+ __func__, child->sg_str);
+ } else if (!PIM_UPSTREAM_FLAG_TEST_USE_RPT(child->flags)) {
/* If we are using SPT and the SPT and RPT IIFs
* are different we can prune the source off
* of the RPT.
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 5f0f2a5933..4e8e5f0df7 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -31,6 +31,8 @@
#include "pim_zlookup.h"
#include "pim_rp.h"
#include "pim_addr.h"
+#include "pim_register.h"
+#include "pim_vxlan.h"
/**
* pim_sendmsg_zebra_rnh -- Format and send a nexthop register/Unregister
@@ -399,17 +401,28 @@ static void pim_update_rp_nh(struct pim_instance *pim,
{
struct listnode *node = NULL;
struct rp_info *rp_info = NULL;
+ struct interface *ifp;
/*Traverse RP list and update each RP Nexthop info */
for (ALL_LIST_ELEMENTS_RO(pnc->rp_list, node, rp_info)) {
if (pim_rpf_addr_is_inaddr_any(&rp_info->rp))
continue;
+ ifp = rp_info->rp.source_nexthop.interface;
// Compute PIM RPF using cached nexthop
if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
rp_info->rp.rpf_addr,
&rp_info->group, 1))
pim_rp_nexthop_del(rp_info);
+
+ /*
+ * If we transition from no path to a path
+ * we need to search through all the vxlan's
+ * that use this rp and send NULL registers
+ * for all the vxlan S,G streams
+ */
+ if (!ifp && rp_info->rp.source_nexthop.interface)
+ pim_vxlan_rp_info_is_alive(pim, &rp_info->rp);
}
}
@@ -436,17 +449,27 @@ static int pim_update_upstream_nh_helper(struct hash_bucket *bucket, void *arg)
(rpf_result == PIM_RPF_FAILURE && old.source_nexthop.interface))
pim_zebra_upstream_rpf_changed(pim, up, &old);
+ /*
+ * If we are a VXLAN source and we are transitioning from not
+ * having an outgoing interface to having an outgoing interface
+ * let's immediately send the null pim register
+ */
+ if (!old.source_nexthop.interface && up->rpf.source_nexthop.interface &&
+ PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(up->flags) &&
+ (up->reg_state == PIM_REG_NOINFO || up->reg_state == PIM_REG_JOIN)) {
+ pim_null_register_send(up);
+ }
if (PIM_DEBUG_PIM_NHT) {
- zlog_debug(
- "%s: NHT upstream %s(%s) old ifp %s new ifp %s",
- __func__, up->sg_str, pim->vrf->name,
- old.source_nexthop.interface ? old.source_nexthop
- .interface->name
- : "Unknown",
- up->rpf.source_nexthop.interface ? up->rpf.source_nexthop
- .interface->name
- : "Unknown");
+ zlog_debug("%s: NHT upstream %s(%s) old ifp %s new ifp %s rpf_result: %d",
+ __func__, up->sg_str, pim->vrf->name,
+ old.source_nexthop.interface ? old.source_nexthop
+ .interface->name
+ : "Unknown",
+ up->rpf.source_nexthop.interface ? up->rpf.source_nexthop
+ .interface->name
+ : "Unknown",
+ rpf_result);
}
return HASHWALK_CONTINUE;
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index a8d087bf49..fd99e77761 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -912,6 +912,7 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
false /*update_mroute*/);
rpf_result = pim_rpf_update(pim, up, NULL, __func__);
if (rpf_result == PIM_RPF_FAILURE) {
+ up->channel_oil->oil_inherited_rescan = 1;
if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
"%s: Attempting to create upstream(%s), Unable to RPF for source",
diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c
index 8df3c90f00..9650da89a8 100644
--- a/pimd/pim_vxlan.c
+++ b/pimd/pim_vxlan.c
@@ -32,6 +32,41 @@ static void pim_vxlan_work_timer_setup(bool start);
static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim,
struct interface *ifp);
+/*
+ * The rp info has gone from no path to having a
+ * path. Let's immediately send out the null pim register
+ * as that else we will be sitting for up to 60 seconds waiting
+ * for it too pop. Which is not cool.
+ */
+void pim_vxlan_rp_info_is_alive(struct pim_instance *pim,
+ struct pim_rpf *rpg_changed)
+{
+ struct listnode *listnode;
+ struct pim_vxlan_sg *vxlan_sg;
+ struct pim_rpf *rpg;
+
+ /*
+ * No vxlan here, move along, nothing to see
+ */
+ if (!vxlan_info.work_list)
+ return;
+
+ for (listnode = vxlan_info.work_list->head; listnode;
+ listnode = listnode->next) {
+ vxlan_sg = listgetdata(listnode);
+
+ rpg = RP(pim, vxlan_sg->up->sg.grp);
+
+ /*
+ * If the rp is the same we should send
+ */
+ if (rpg == rpg_changed) {
+ zlog_debug("VXLAN RP INFO is alive sending");
+ pim_null_register_send(vxlan_sg->up);
+ }
+ }
+}
+
/*************************** vxlan work list **********************************
* A work list is maintained for staggered generation of pim null register
* messages for vxlan SG entries that are in a reg_join state.
@@ -66,6 +101,7 @@ static void pim_vxlan_do_reg_work(void)
for (; listnode; listnode = listnode->next) {
vxlan_sg = (struct pim_vxlan_sg *)listnode->data;
+
if (vxlan_sg->up && (vxlan_sg->up->reg_state == PIM_REG_JOIN)) {
if (PIM_DEBUG_VXLAN)
zlog_debug("vxlan SG %s periodic NULL register",
diff --git a/pimd/pim_vxlan.h b/pimd/pim_vxlan.h
index 9a135ca6b8..5039bf6540 100644
--- a/pimd/pim_vxlan.h
+++ b/pimd/pim_vxlan.h
@@ -135,6 +135,9 @@ extern bool pim_vxlan_do_mlag_reg(void);
extern void pim_vxlan_inherit_mlag_flags(struct pim_instance *pim,
struct pim_upstream *up, bool inherit);
+extern void pim_vxlan_rp_info_is_alive(struct pim_instance *pim,
+ struct pim_rpf *rpg_changed);
+
/* Shutdown of PIM stop the thread */
extern void pim_vxlan_terminate(void);
#endif /* PIM_VXLAN_H */
diff --git a/tests/topotests/bgp_evpn_mh/leaf1/evpn.conf b/tests/topotests/bgp_evpn_mh/leaf1/evpn.conf
new file mode 100644
index 0000000000..33b6d08aba
--- /dev/null
+++ b/tests/topotests/bgp_evpn_mh/leaf1/evpn.conf
@@ -0,0 +1,21 @@
+frr defaults datacenter
+!
+router bgp 65101
+ bgp router-id 192.168.100.13
+ no bgp ebgp-requires-policy
+ neighbor 192.168.50.1 remote-as external
+ neighbor 192.168.51.1 remote-as external
+ neighbor 192.168.1.2 remote-as external
+ neighbor 192.168.2.2 remote-as external
+ neighbor 192.168.3.2 remote-as external
+ neighbor 192.168.4.2 remote-as external
+ redistribute connected
+ address-family l2vpn evpn
+ neighbor 192.168.50.1 activate
+ neighbor 192.168.51.1 activate
+ neighbor 192.168.1.2 activate
+ neighbor 192.168.2.2 activate
+ neighbor 192.168.3.2 activate
+ neighbor 192.168.4.2 activate
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_evpn_mh/leaf1/pim.conf b/tests/topotests/bgp_evpn_mh/leaf1/pim.conf
new file mode 100644
index 0000000000..a4de64d1fb
--- /dev/null
+++ b/tests/topotests/bgp_evpn_mh/leaf1/pim.conf
@@ -0,0 +1,26 @@
+#debug pim packet
+#debug pim packet register
+#debug pim event
+#debug pim trace
+ip pim ecmp
+ip pim rp 192.168.100.13
+ip pim spt-switchover infinity-and-beyond
+!
+int leaf1-eth0
+ ip pim
+!
+int leaf1-eth1
+ ip pim
+!
+int leaf1-eth2
+ ip pim
+!
+int leaf1-eth3
+ ip pim
+!
+int leaf1-eth4
+ ip pim
+!
+int leaf1-eth5
+ ip pim
+!
diff --git a/tests/topotests/bgp_evpn_mh/leaf1/zebra.conf b/tests/topotests/bgp_evpn_mh/leaf1/zebra.conf
new file mode 100644
index 0000000000..f666f98abc
--- /dev/null
+++ b/tests/topotests/bgp_evpn_mh/leaf1/zebra.conf
@@ -0,0 +1,30 @@
+# spine 1 connection
+int leaf1-eth0
+ description spine1 connection
+ ip addr 192.168.50.2/24
+
+#spine 2 connection
+int leaf1-eth1
+ description spine2 connection
+ ip addr 192.168.51.2/24
+
+#torm11 connection
+int leaf1-eth2
+ description torm11 connection
+ ip addr 192.168.1.1/24
+!
+#torm12 connection
+int leaf1-eth3
+ description torm12 connection
+ ip addr 192.168.2.1/24
+!
+#torm21 connection
+int leaf1-eth4
+ description torm21 connection
+ ip addr 192.168.3.1/24
+!
+#torm22 connection
+int leaf1-eth5
+ descriptoin torm22 connection
+ ip addr 192.168.4.1/24
+!
diff --git a/tests/topotests/bgp_evpn_mh/leaf2/evpn.conf b/tests/topotests/bgp_evpn_mh/leaf2/evpn.conf
new file mode 100644
index 0000000000..428998b0fe
--- /dev/null
+++ b/tests/topotests/bgp_evpn_mh/leaf2/evpn.conf
@@ -0,0 +1,21 @@
+frr defaults datacenter
+!
+router bgp 65101
+ bgp router-id 192.168.100.14
+ no bgp ebgp-requires-policy
+ neighbor 192.168.61.1 remote-as external
+ neighbor 192.168.51.1 remote-as external
+ neighbor 192.168.5.2 remote-as external
+ neighbor 192.168.6.2 remote-as external
+ neighbor 192.168.7.2 remote-as external
+ neighbor 192.168.8.2 remote-as external
+ redistribute connected
+ address-family l2vpn evpn
+ neighbor 192.168.61.1 activate
+ neighbor 192.168.51.1 activate
+ neighbor 192.168.5.2 activate
+ neighbor 192.168.6.2 activate
+ neighbor 192.168.7.2 activate
+ neighbor 192.168.8.2 activate
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_evpn_mh/leaf2/pim.conf b/tests/topotests/bgp_evpn_mh/leaf2/pim.conf
new file mode 100644
index 0000000000..3abd9698f5
--- /dev/null
+++ b/tests/topotests/bgp_evpn_mh/leaf2/pim.conf
@@ -0,0 +1,20 @@
+#debug pim packet register
+#debug pim packet
+#debug pim event
+#debug pim trace
+ip pim ecmp
+ip pim rp 192.168.100.13
+ip pim spt-switchover infinity-and-beyond
+!
+int leaf2-eth0
+ ip pim
+!
+int leaf2-eth1
+ ip pim
+!
+int leaf2-eth2
+ ip pim
+!
+int leaf2-eth3
+ ip pim
+!
diff --git a/tests/topotests/bgp_evpn_mh/leaf2/zebra.conf b/tests/topotests/bgp_evpn_mh/leaf2/zebra.conf
new file mode 100644
index 0000000000..ff680cf764
--- /dev/null
+++ b/tests/topotests/bgp_evpn_mh/leaf2/zebra.conf
@@ -0,0 +1,24 @@
+# spine1 connection
+int leaf2-eth0
+ ip addr 192.168.51.2/24
+!
+# spine2 connection
+int leaf2-eth1
+ ip addr 192.168.61.2/24
+!
+#torm11 connection
+int leaf2-eth2
+ ip addr 192.168.5.1/24
+!
+#torm12 connection
+int leaf2-eth3
+ ip addr 192.168.6.1/24
+!
+#torm21 connection
+int leaf2-eth4
+ ip addr 192.168.7.1/24
+!
+#torm22 connection
+int leaf2-eth5
+ ip addr 192.168.8.1/24
+!
diff --git a/tests/topotests/bgp_evpn_mh/spine1/evpn.conf b/tests/topotests/bgp_evpn_mh/spine1/evpn.conf
index 2e26f60f44..b9fce46ea4 100644
--- a/tests/topotests/bgp_evpn_mh/spine1/evpn.conf
+++ b/tests/topotests/bgp_evpn_mh/spine1/evpn.conf
@@ -3,15 +3,11 @@ frr defaults datacenter
router bgp 65001
bgp router-id 192.168.100.13
no bgp ebgp-requires-policy
- neighbor 192.168.1.2 remote-as external
- neighbor 192.168.2.2 remote-as external
- neighbor 192.168.3.2 remote-as external
- neighbor 192.168.4.2 remote-as external
+ neighbor 192.168.50.2 remote-as external
+ neighbor 192.168.51.2 remote-as external
redistribute connected
address-family l2vpn evpn
- neighbor 192.168.1.2 activate
- neighbor 192.168.2.2 activate
- neighbor 192.168.3.2 activate
- neighbor 192.168.4.2 activate
+ neighbor 192.168.50.2 activate
+ neighbor 192.168.51.2 activate
exit-address-family
!
diff --git a/tests/topotests/bgp_evpn_mh/spine1/pim.conf b/tests/topotests/bgp_evpn_mh/spine1/pim.conf
index 68e686e8c7..018d244e4d 100644
--- a/tests/topotests/bgp_evpn_mh/spine1/pim.conf
+++ b/tests/topotests/bgp_evpn_mh/spine1/pim.conf
@@ -1,4 +1,10 @@
+ip pim ecmp
ip pim rp 192.168.100.13
+#debug pim packets
+#debug pim packet register
+#debug pim event
+#debug pim trace
+#debug pim vxlan
ip pim spt-switchover infinity-and-beyond
!
int lo
@@ -10,9 +16,3 @@ int spine1-eth0
int spine1-eth1
ip pim
!
-int spine1-eth2
- ip pim
-!
-int spine1-eth3
- ip pim
-!
diff --git a/tests/topotests/bgp_evpn_mh/spine1/zebra.conf b/tests/topotests/bgp_evpn_mh/spine1/zebra.conf
index 80e9e5a263..607a5e8e32 100644
--- a/tests/topotests/bgp_evpn_mh/spine1/zebra.conf
+++ b/tests/topotests/bgp_evpn_mh/spine1/zebra.conf
@@ -1,14 +1,10 @@
+# leaf1 connection
int spine1-eth0
- ip addr 192.168.1.1/24
+ ip addr 192.168.50.1/24
!
+# leaf2 connection
int spine1-eth1
- ip addr 192.168.2.1/24
-!
-int spine1-eth2
- ip addr 192.168.3.1/24
-!
-int spine1-eth3
- ip addr 192.168.4.1/24
+ ip addr 192.168.51.1/24
!
int lo
ip addr 192.168.100.13/32
diff --git a/tests/topotests/bgp_evpn_mh/spine2/evpn.conf b/tests/topotests/bgp_evpn_mh/spine2/evpn.conf
index ec2e789276..1430e10b68 100644
--- a/tests/topotests/bgp_evpn_mh/spine2/evpn.conf
+++ b/tests/topotests/bgp_evpn_mh/spine2/evpn.conf
@@ -3,15 +3,11 @@ frr defaults datacenter
router bgp 65001
bgp router-id 192.168.100.14
no bgp ebgp-requires-policy
- neighbor 192.168.5.2 remote-as external
- neighbor 192.168.6.2 remote-as external
- neighbor 192.168.7.2 remote-as external
- neighbor 192.168.8.2 remote-as external
+ neighbor 192.168.60.2 remote-as external
+ neighbor 192.168.61.2 remote-as external
redistribute connected
address-family l2vpn evpn
- neighbor 192.168.5.2 activate
- neighbor 192.168.6.2 activate
- neighbor 192.168.7.2 activate
- neighbor 192.168.8.2 activate
+ neighbor 192.168.60.2 activate
+ neighbor 192.168.61.2 activate
exit-address-family
!
diff --git a/tests/topotests/bgp_evpn_mh/spine2/pim.conf b/tests/topotests/bgp_evpn_mh/spine2/pim.conf
index c1566240e6..0ece2ff539 100644
--- a/tests/topotests/bgp_evpn_mh/spine2/pim.conf
+++ b/tests/topotests/bgp_evpn_mh/spine2/pim.conf
@@ -1,3 +1,4 @@
+ip pim ecmp
ip pim rp 192.168.100.13
ip pim spt-switchover infinity-and-beyond
!
@@ -10,9 +11,3 @@ int spine2-eth0
int spine2-eth1
ip pim
!
-int spine2-eth2
- ip pim
-!
-int spine2-eth3
- ip pim
-!
diff --git a/tests/topotests/bgp_evpn_mh/spine2/zebra.conf b/tests/topotests/bgp_evpn_mh/spine2/zebra.conf
index 1cd1df8c81..c8cec14e62 100644
--- a/tests/topotests/bgp_evpn_mh/spine2/zebra.conf
+++ b/tests/topotests/bgp_evpn_mh/spine2/zebra.conf
@@ -1,14 +1,12 @@
+# leaf1 connection
int spine2-eth0
- ip addr 192.168.5.1/24
+ description leaf1 connection
+ ip addr 192.168.60.1/24
!
+# leaf2 connection
int spine2-eth1
- ip addr 192.168.6.1/24
-!
-int spine2-eth2
- ip addr 192.168.7.1/24
-!
-int spine2-eth3
- ip addr 192.168.8.1/24
+ description leaf2 connection
+ ip addr 192.168.61.1/24
!
int lo
ip addr 192.168.100.14/32
diff --git a/tests/topotests/bgp_evpn_mh/test_evpn_mh.py b/tests/topotests/bgp_evpn_mh/test_evpn_mh.py
index 0bde5d5a9f..ec5227809e 100644
--- a/tests/topotests/bgp_evpn_mh/test_evpn_mh.py
+++ b/tests/topotests/bgp_evpn_mh/test_evpn_mh.py
@@ -58,6 +58,8 @@ def build_topo(tgen):
tgen.add_router("spine1")
tgen.add_router("spine2")
+ tgen.add_router("leaf1")
+ tgen.add_router("leaf2")
tgen.add_router("torm11")
tgen.add_router("torm12")
tgen.add_router("torm21")
@@ -71,88 +73,109 @@ def build_topo(tgen):
# First switch is for a dummy interface (for local network)
##################### spine1 ########################
- # spine1-eth0 is connected to torm11-eth0
+ # spine1-eth0 is connected to leaf1-eth0
switch = tgen.add_switch("sw1")
switch.add_link(tgen.gears["spine1"])
- switch.add_link(tgen.gears["torm11"])
+ switch.add_link(tgen.gears["leaf1"])
- # spine1-eth1 is connected to torm12-eth0
+ # spine1-eth1 is connected to leaf2-eth0
switch = tgen.add_switch("sw2")
switch.add_link(tgen.gears["spine1"])
- switch.add_link(tgen.gears["torm12"])
+ switch.add_link(tgen.gears["leaf2"])
- # spine1-eth2 is connected to torm21-eth0
+ # spine2-eth0 is connected to leaf1-eth1
switch = tgen.add_switch("sw3")
- switch.add_link(tgen.gears["spine1"])
- switch.add_link(tgen.gears["torm21"])
+ switch.add_link(tgen.gears["spine2"])
+ switch.add_link(tgen.gears["leaf1"])
- # spine1-eth3 is connected to torm22-eth0
+ # spine2-eth1 is connected to leaf2-eth1
switch = tgen.add_switch("sw4")
- switch.add_link(tgen.gears["spine1"])
- switch.add_link(tgen.gears["torm22"])
+ switch.add_link(tgen.gears["spine2"])
+ switch.add_link(tgen.gears["leaf2"])
- ##################### spine2 ########################
- # spine2-eth0 is connected to torm11-eth1
+ ################## leaf1 ##########################
+ # leaf1-eth2 is connected to torm11-eth0
switch = tgen.add_switch("sw5")
- switch.add_link(tgen.gears["spine2"])
+ switch.add_link(tgen.gears["leaf1"])
switch.add_link(tgen.gears["torm11"])
- # spine2-eth1 is connected to torm12-eth1
+ # leaf1-eth3 is connected to torm12-eth0
switch = tgen.add_switch("sw6")
- switch.add_link(tgen.gears["spine2"])
+ switch.add_link(tgen.gears["leaf1"])
switch.add_link(tgen.gears["torm12"])
- # spine2-eth2 is connected to torm21-eth1
+ # leaf1-eth4 is connected to torm21-eth0
switch = tgen.add_switch("sw7")
- switch.add_link(tgen.gears["spine2"])
+ switch.add_link(tgen.gears["leaf1"])
switch.add_link(tgen.gears["torm21"])
- # spine2-eth3 is connected to torm22-eth1
+ # leaf1-eth5 is connected to torm22-eth0
switch = tgen.add_switch("sw8")
- switch.add_link(tgen.gears["spine2"])
+ switch.add_link(tgen.gears["leaf1"])
+ switch.add_link(tgen.gears["torm22"])
+
+ ##################### leaf2 ########################
+ # leaf2-eth2 is connected to torm11-eth1
+ switch = tgen.add_switch("sw9")
+ switch.add_link(tgen.gears["leaf2"])
+ switch.add_link(tgen.gears["torm11"])
+
+ # leaf2-eth3 is connected to torm12-eth1
+ switch = tgen.add_switch("sw10")
+ switch.add_link(tgen.gears["leaf2"])
+ switch.add_link(tgen.gears["torm12"])
+
+ # leaf2-eth4 is connected to torm21-eth1
+ switch = tgen.add_switch("sw11")
+ switch.add_link(tgen.gears["leaf2"])
+ switch.add_link(tgen.gears["torm21"])
+
+ # leaf2-eth5 is connected to torm22-eth1
+ switch = tgen.add_switch("sw12")
+ switch.add_link(tgen.gears["leaf2"])
switch.add_link(tgen.gears["torm22"])
##################### torm11 ########################
# torm11-eth2 is connected to hostd11-eth0
- switch = tgen.add_switch("sw9")
+ switch = tgen.add_switch("sw13")
switch.add_link(tgen.gears["torm11"])
switch.add_link(tgen.gears["hostd11"])
# torm11-eth3 is connected to hostd12-eth0
- switch = tgen.add_switch("sw10")
+ switch = tgen.add_switch("sw14")
switch.add_link(tgen.gears["torm11"])
switch.add_link(tgen.gears["hostd12"])
##################### torm12 ########################
# torm12-eth2 is connected to hostd11-eth1
- switch = tgen.add_switch("sw11")
+ switch = tgen.add_switch("sw15")
switch.add_link(tgen.gears["torm12"])
switch.add_link(tgen.gears["hostd11"])
# torm12-eth3 is connected to hostd12-eth1
- switch = tgen.add_switch("sw12")
+ switch = tgen.add_switch("sw16")
switch.add_link(tgen.gears["torm12"])
switch.add_link(tgen.gears["hostd12"])
##################### torm21 ########################
# torm21-eth2 is connected to hostd21-eth0
- switch = tgen.add_switch("sw13")
+ switch = tgen.add_switch("sw17")
switch.add_link(tgen.gears["torm21"])
switch.add_link(tgen.gears["hostd21"])
# torm21-eth3 is connected to hostd22-eth0
- switch = tgen.add_switch("sw14")
+ switch = tgen.add_switch("sw18")
switch.add_link(tgen.gears["torm21"])
switch.add_link(tgen.gears["hostd22"])
##################### torm22 ########################
# torm22-eth2 is connected to hostd21-eth1
- switch = tgen.add_switch("sw15")
+ switch = tgen.add_switch("sw19")
switch.add_link(tgen.gears["torm22"])
switch.add_link(tgen.gears["hostd21"])
# torm22-eth3 is connected to hostd22-eth1
- switch = tgen.add_switch("sw16")
+ switch = tgen.add_switch("sw20")
switch.add_link(tgen.gears["torm22"])
switch.add_link(tgen.gears["hostd22"])
@@ -591,7 +614,7 @@ def ping_anycast_gw(tgen):
"--interface=" + intf,
'Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="{}")'.format(ipaddr),
]
- for name in ("hostd11", "hostd21"):
+ for name in ("hostd11", "hostd21", "hostd12", "hostd22"):
host = tgen.net.hosts[name]
_, stdout, _ = host.cmd_status(ping_cmd, warn=False, stderr=subprocess.STDOUT)
stdout = stdout.strip()
diff --git a/tests/topotests/bgp_evpn_mh/torm11/pim.conf b/tests/topotests/bgp_evpn_mh/torm11/pim.conf
index fbba735873..a5d45dabc7 100644
--- a/tests/topotests/bgp_evpn_mh/torm11/pim.conf
+++ b/tests/topotests/bgp_evpn_mh/torm11/pim.conf
@@ -1,4 +1,10 @@
!
+#debug pim packet
+#debug pim packet register
+#debug pim trace
+#debug pim event
+#debug pim vxlan
+ip pim ecmp
ip pim rp 192.168.100.13 239.1.1.0/24
ip pim spt-switchover infinity-and-beyond
!
diff --git a/tests/topotests/bgp_evpn_mh/torm12/pim.conf b/tests/topotests/bgp_evpn_mh/torm12/pim.conf
index 3dd63b44ca..7e09ba7e21 100644
--- a/tests/topotests/bgp_evpn_mh/torm12/pim.conf
+++ b/tests/topotests/bgp_evpn_mh/torm12/pim.conf
@@ -1,4 +1,10 @@
+#debug pim packet
+#debug pim packet register
+#debug pim trace
+#debug pim event
+#debug pim vxlan
!
+ip pim ecmp
ip pim rp 192.168.100.13 239.1.1.0/24
ip pim spt-switchover infinity-and-beyond
!
diff --git a/tests/topotests/bgp_evpn_mh/torm21/pim.conf b/tests/topotests/bgp_evpn_mh/torm21/pim.conf
index 71aa91a06d..6996d74ad8 100644
--- a/tests/topotests/bgp_evpn_mh/torm21/pim.conf
+++ b/tests/topotests/bgp_evpn_mh/torm21/pim.conf
@@ -1,4 +1,10 @@
+#debug pim packet
+#debug pim packet register
+#debug pim trace
+#debug pim event
+#debug pim vxlan
!
+ip pim ecmp
ip pim rp 192.168.100.13 239.1.1.0/24
ip pim spt-switchover infinity-and-beyond
!
diff --git a/tests/topotests/bgp_evpn_mh/torm22/pim.conf b/tests/topotests/bgp_evpn_mh/torm22/pim.conf
index 46f330f5cd..6256e0e8cf 100644
--- a/tests/topotests/bgp_evpn_mh/torm22/pim.conf
+++ b/tests/topotests/bgp_evpn_mh/torm22/pim.conf
@@ -1,4 +1,10 @@
+#debug pim packet
+#debug pim packet register
+#debug pim trace
+#debug pim event
+#debug pim vxlan
!
+ip pim ecmp
ip pim rp 192.168.100.13 239.1.1.0/24
ip pim spt-switchover infinity-and-beyond
!
diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/r1/bgpd.conf b/tests/topotests/bgp_labeled_unicast_default_originate/r1/bgpd.conf
index 75a4aa6ab3..d0d13909a7 100644
--- a/tests/topotests/bgp_labeled_unicast_default_originate/r1/bgpd.conf
+++ b/tests/topotests/bgp_labeled_unicast_default_originate/r1/bgpd.conf
@@ -1,18 +1,32 @@
!
router bgp 65001
no bgp default ipv4-unicast
+ no bgp default ipv6-unicast
no bgp ebgp-requires-policy
neighbor 192.168.12.2 remote-as external
neighbor 192.168.12.2 timers 1 3
neighbor 192.168.12.2 timers connect 1
+ neighbor 2001:db8:12::2 remote-as external
+ neighbor 2001:db8:12::2 timers 1 3
+ neighbor 2001:db8:12::2 timers connect 1
address-family ipv4 unicast
redistribute connected
exit-address-family
+ !
+ address-family ipv6 unicast
+ redistribute connected
+ exit-address-family
+ !
address-family ipv4 labeled-unicast
neighbor 192.168.12.2 activate
neighbor 192.168.12.2 default-originate route-map r2
exit-address-family
!
+ address-family ipv6 labeled-unicast
+ neighbor 2001:db8:12::2 activate
+ neighbor 2001:db8:12::2 default-originate route-map r2
+ exit-address-family
+ !
!
route-map r2 permit 10
set community 65001:65001
diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/r1/zebra.conf b/tests/topotests/bgp_labeled_unicast_default_originate/r1/zebra.conf
index 8eab7805df..686b0755c3 100644
--- a/tests/topotests/bgp_labeled_unicast_default_originate/r1/zebra.conf
+++ b/tests/topotests/bgp_labeled_unicast_default_originate/r1/zebra.conf
@@ -1,4 +1,5 @@
!
interface r1-eth0
ip address 192.168.12.1/24
+ ipv6 address 2001:db8:12::1/64
!
diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/r2/bgpd.conf b/tests/topotests/bgp_labeled_unicast_default_originate/r2/bgpd.conf
index c81ba9fe02..1498dffc93 100644
--- a/tests/topotests/bgp_labeled_unicast_default_originate/r2/bgpd.conf
+++ b/tests/topotests/bgp_labeled_unicast_default_originate/r2/bgpd.conf
@@ -2,10 +2,18 @@
router bgp 65002
no bgp ebgp-requires-policy
no bgp default ipv4-unicast
+ no bgp default ipv6-unicast
neighbor 192.168.12.1 remote-as external
neighbor 192.168.12.1 timers 1 3
neighbor 192.168.12.1 timers connect 1
+ neighbor 2001:db8:12::1 remote-as external
+ neighbor 2001:db8:12::1 timers 1 3
+ neighbor 2001:db8:12::1 timers connect 1
address-family ipv4 labeled-unicast
neighbor 192.168.12.1 activate
exit-address-family
+ !
+ address-family ipv6 labeled-unicast
+ neighbor 2001:db8:12::1 activate
+ exit-address-family
!
diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/r2/zebra.conf b/tests/topotests/bgp_labeled_unicast_default_originate/r2/zebra.conf
index d7dfd899cc..cb5c55ef0f 100644
--- a/tests/topotests/bgp_labeled_unicast_default_originate/r2/zebra.conf
+++ b/tests/topotests/bgp_labeled_unicast_default_originate/r2/zebra.conf
@@ -1,4 +1,5 @@
!
interface r2-eth0
ip address 192.168.12.2/24
+ ipv6 address 2001:db8:12::2/64
!
diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py b/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py
index c3ccefb569..34c23d9b6f 100644
--- a/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py
+++ b/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py
@@ -82,7 +82,7 @@ def test_bgp_labeled_unicast_default_originate():
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result is None, "Failed to advertise default route for labeled-unicast"
- def _bgp_check_received_routes():
+ def _bgp_check_received_ipv4_routes():
output = json.loads(
r2.vtysh_cmd("show bgp ipv4 labeled-unicast 0.0.0.0/0 json")
)
@@ -94,14 +94,35 @@ def test_bgp_labeled_unicast_default_originate():
"community": {
"string": "65001:65001",
},
+ "remoteLabel": 0,
}
]
}
return topotest.json_cmp(output, expected)
- test_func = functools.partial(_bgp_check_received_routes)
+ test_func = functools.partial(_bgp_check_received_ipv4_routes)
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
- assert result is None, "Failed to receive default route for labeled-unicast"
+ assert result is None, "Failed to receive IPv4 default route for labeled-unicast"
+
+ def _bgp_check_received_ipv6_routes():
+ output = json.loads(r2.vtysh_cmd("show bgp ipv6 labeled-unicast ::/0 json"))
+ expected = {
+ "paths": [
+ {
+ "valid": True,
+ "metric": 666,
+ "community": {
+ "string": "65001:65001",
+ },
+ "remoteLabel": 2,
+ }
+ ]
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_check_received_ipv6_routes)
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "Failed to receive IPv6 default route for labeled-unicast"
if __name__ == "__main__":
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index 6254a93766..ae64d51283 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -484,8 +484,7 @@ void vtysh_config_parse_line(void *arg, const char *line)
config = config_get(RPKI_NODE, line);
else {
if (strncmp(line, "log", strlen("log")) == 0 ||
- strncmp(line, "hostname", strlen("hostname")) ==
- 0 ||
+ strncmp(line, "hostname", strlen("hostname")) == 0 ||
strncmp(line, "domainname", strlen("domainname")) ==
0 ||
strncmp(line, "allow-reserved-ranges",
@@ -497,12 +496,9 @@ void vtysh_config_parse_line(void *arg, const char *line)
strlen("no ip prefix-list")) == 0 ||
strncmp(line, "no ipv6 prefix-list",
strlen("no ipv6 prefix-list")) == 0 ||
- strncmp(line, "service ", strlen("service ")) ==
- 0 ||
- strncmp(line, "no service cputime-stats",
- strlen("no service cputime-stats")) == 0 ||
- strncmp(line, "service cputime-warning",
- strlen("service cputime-warning")) == 0)
+ strncmp(line, "service ", strlen("service ")) == 0 ||
+ strncmp(line, "no service ",
+ strlen("no service ")) == 0)
config_add_line_uniq(config_top, line);
else
config_add_line(config_top, line);
diff --git a/zebra/interface.c b/zebra/interface.c
index 2157680d58..90787f3aa0 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -200,6 +200,7 @@ static void if_nhg_dependents_release(const struct interface *ifp)
static int if_zebra_delete_hook(struct interface *ifp)
{
struct zebra_if *zebra_if;
+ struct zebra_l2info_bond *bond;
if (ifp->info) {
zebra_if = ifp->info;
@@ -217,6 +218,10 @@ static int if_zebra_delete_hook(struct interface *ifp)
rtadv_if_fini(zebra_if);
+ bond = &zebra_if->bond_info;
+ if (bond && bond->mbr_zifs)
+ list_delete(&bond->mbr_zifs);
+
zebra_l2_bridge_if_cleanup(ifp);
zebra_evpn_if_cleanup(zebra_if);
zebra_evpn_mac_ifp_del(ifp);