summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2018-11-08 18:13:27 -0500
committerGitHub <noreply@github.com>2018-11-08 18:13:27 -0500
commit2379dbecbd3b56ef1affc9127b8eb44f61d591fa (patch)
tree7e78f6ccdc06870afebe0ddcb83966a9b1e596a5
parent08d2b7fce98ad78a5be880695bc0bd2f722ea16d (diff)
parent9a8897aa9a51c2151a1629c9c491ddc6d0dfb589 (diff)
Merge pull request #3202 from donaldsharp/evpn_dump
Evpn dump
-rw-r--r--bgpd/bgp_evpn.c69
-rw-r--r--bgpd/bgp_evpn_vty.c20
-rw-r--r--bgpd/bgp_route.c23
-rw-r--r--bgpd/bgp_routemap.c4
-rw-r--r--bgpd/bgp_vty.c85
-rw-r--r--lib/command.h1
-rw-r--r--vtysh/vtysh.c2
-rw-r--r--zebra/zebra_vty.c3
-rw-r--r--zebra/zebra_vxlan.c36
9 files changed, 210 insertions, 33 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index c91a2ab6bd..cff050a9ef 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -1693,6 +1693,58 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
}
/*
+ * If the local route was not selected evict it and tell zebra to re-add
+ * the best remote dest.
+ *
+ * Typically a local path added by zebra is expected to be selected as
+ * best. In which case when a remote path wins as best (later)
+ * evpn_route_select_install itself evicts the older-local-best path.
+ *
+ * However if bgp's add and zebra's add cross paths (race condition) it
+ * is possible that the local path is no longer the "older" best path.
+ * It is a path that was never designated as best and hence requires
+ * additional handling to prevent bgp from injecting and holding on to a
+ * non-best local path.
+ */
+static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
+ struct bgpevpn *vpn,
+ struct bgp_node *rn,
+ struct bgp_path_info *local_pi)
+{
+ struct bgp_path_info *tmp_pi;
+ struct bgp_path_info *curr_select = NULL;
+ uint8_t flags = 0;
+ char buf[PREFIX_STRLEN];
+
+ /* local path was not picked as the winner; kick it out */
+ if (bgp_debug_zebra(NULL)) {
+ zlog_debug("evicting local evpn prefix %s as remote won",
+ prefix2str(&rn->p, buf, sizeof(buf)));
+ }
+ evpn_delete_old_local_route(bgp, vpn, rn, local_pi);
+ bgp_path_info_reap(rn, local_pi);
+
+ /* tell zebra to re-add the best remote path */
+ for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+ if (CHECK_FLAG(tmp_pi->flags, BGP_PATH_SELECTED)) {
+ curr_select = tmp_pi;
+ break;
+ }
+ }
+ if (curr_select &&
+ curr_select->type == ZEBRA_ROUTE_BGP
+ && curr_select->sub_type == BGP_ROUTE_IMPORTED) {
+ if (curr_select->attr->sticky)
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
+ if (curr_select->attr->default_gw)
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+ evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
+ curr_select->attr->nexthop, flags,
+ mac_mobility_seqnum(curr_select->attr));
+ }
+}
+
+/*
* Create or update EVPN route (of type based on prefix) for specified VNI
* and schedule for processing.
*/
@@ -1754,10 +1806,23 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
assert(pi);
attr_new = pi->attr;
+ /* lock ri to prevent freeing in evpn_route_select_install */
+ bgp_path_info_lock(pi);
/* Perform route selection; this is just to set the flags correctly
* as local route in the VNI always wins.
*/
evpn_route_select_install(bgp, vpn, rn);
+ /*
+ * If the new local route was not selected evict it and tell zebra
+ * to re-add the best remote dest. BGP doesn't retain non-best local
+ * routes.
+ */
+ if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
+ route_change = 0;
+ evpn_cleanup_local_non_best_route(bgp, vpn, rn, pi);
+ }
+ bgp_path_info_unlock(pi);
+
bgp_unlock_node(rn);
/* If this is a new route or some attribute has changed, export the
@@ -1928,8 +1993,10 @@ static int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
/* Delete route entry in the VNI route table. This can just be removed.
*/
delete_evpn_route_entry(bgp, afi, safi, rn, &pi);
- if (pi)
+ if (pi) {
bgp_path_info_reap(rn, pi);
+ evpn_route_select_install(bgp, vpn, rn);
+ }
bgp_unlock_node(rn);
return 0;
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 29f9f64cca..aa5eabeade 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -3195,7 +3195,7 @@ DEFUN (no_bgp_evpn_advertise_type5,
*/
DEFUN(show_bgp_l2vpn_evpn_vni,
show_bgp_l2vpn_evpn_vni_cmd,
- "show bgp l2vpn evpn vni [(1-16777215)] [json]",
+ "show bgp l2vpn evpn vni [" CMD_VNI_RANGE "] [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -3623,7 +3623,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_esi,
* Display per-VNI EVPN routing table.
*/
DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd,
- "show bgp l2vpn evpn route vni (1-16777215) [<type <macip|multicast> | vtep A.B.C.D>] [json]",
+ "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " [<type <macip|multicast> | vtep A.B.C.D>] [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -3696,7 +3696,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd,
*/
DEFUN(show_bgp_l2vpn_evpn_route_vni_macip,
show_bgp_l2vpn_evpn_route_vni_macip_cmd,
- "show bgp l2vpn evpn route vni (1-16777215) mac WORD [ip WORD] [json]",
+ "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " mac WORD [ip WORD] [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -3766,7 +3766,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_macip,
*/
DEFUN(show_bgp_l2vpn_evpn_route_vni_multicast,
show_bgp_l2vpn_evpn_route_vni_multicast_cmd,
- "show bgp l2vpn evpn route vni (1-16777215) multicast A.B.C.D [json]",
+ "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " multicast A.B.C.D [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -4019,7 +4019,7 @@ DEFUN(test_withdraw_evpn_type4_route,
}
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_vni, show_bgp_evpn_vni_cmd,
- "show bgp evpn vni [(1-16777215)]", SHOW_STR BGP_STR EVPN_HELP_STR
+ "show bgp evpn vni [" CMD_VNI_RANGE "]", SHOW_STR BGP_STR EVPN_HELP_STR
"Show VNI\n"
"VNI number\n")
@@ -4060,7 +4060,7 @@ ALIAS_HIDDEN(
ALIAS_HIDDEN(
show_bgp_l2vpn_evpn_route_vni, show_bgp_evpn_route_vni_cmd,
- "show bgp evpn route vni (1-16777215) [<type <macip|multicast> | vtep A.B.C.D>]",
+ "show bgp evpn route vni " CMD_VNI_RANGE " [<type <macip|multicast> | vtep A.B.C.D>]",
SHOW_STR BGP_STR EVPN_HELP_STR
"EVPN route information\n"
"VXLAN Network Identifier\n"
@@ -4073,7 +4073,7 @@ ALIAS_HIDDEN(
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_macip,
show_bgp_evpn_route_vni_macip_cmd,
- "show bgp evpn route vni (1-16777215) mac WORD [ip WORD]",
+ "show bgp evpn route vni " CMD_VNI_RANGE " mac WORD [ip WORD]",
SHOW_STR BGP_STR EVPN_HELP_STR
"EVPN route information\n"
"VXLAN Network Identifier\n"
@@ -4085,7 +4085,7 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_macip,
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_multicast,
show_bgp_evpn_route_vni_multicast_cmd,
- "show bgp evpn route vni (1-16777215) multicast A.B.C.D",
+ "show bgp evpn route vni " CMD_VNI_RANGE " multicast A.B.C.D",
SHOW_STR BGP_STR EVPN_HELP_STR
"EVPN route information\n"
"VXLAN Network Identifier\n"
@@ -4108,7 +4108,7 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_import_rt, show_bgp_evpn_import_rt_cmd,
DEFUN_NOSH (bgp_evpn_vni,
bgp_evpn_vni_cmd,
- "vni (1-16777215)",
+ "vni " CMD_VNI_RANGE,
"VXLAN Network Identifier\n"
"VNI number\n")
{
@@ -4134,7 +4134,7 @@ DEFUN_NOSH (bgp_evpn_vni,
DEFUN (no_bgp_evpn_vni,
no_bgp_evpn_vni_cmd,
- "no vni (1-16777215)",
+ "no vni " CMD_VNI_RANGE,
NO_STR
"VXLAN Network Identifier\n"
"VNI number\n")
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 4542d0ec27..8ae74a008c 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -453,6 +453,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
char exist_buf[PATH_ADDPATH_STR_BUFFER];
uint32_t new_mm_seq;
uint32_t exist_mm_seq;
+ int nh_cmp;
*paths_eq = 0;
@@ -545,6 +546,28 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
exist_mm_seq);
return 0;
}
+
+ /*
+ * if sequence numbers are the same path with the lowest IP
+ * wins
+ */
+ nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
+ if (nh_cmp < 0) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to same MM seq %u and lower IP %s",
+ pfx_buf, new_buf, exist_buf, new_mm_seq,
+ inet_ntoa(new->attr->nexthop));
+ return 1;
+ }
+ if (nh_cmp > 0) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to same MM seq %u and higher IP %s",
+ pfx_buf, new_buf, exist_buf, new_mm_seq,
+ inet_ntoa(new->attr->nexthop));
+ return 0;
+ }
}
/* 1. Weight check. */
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 60a4e994c9..f7c4175383 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -3438,7 +3438,7 @@ DEFUN (no_match_evpn_route_type,
DEFUN (match_evpn_vni,
match_evpn_vni_cmd,
- "match evpn vni (1-16777215)",
+ "match evpn vni " CMD_VNI_RANGE,
MATCH_STR
EVPN_HELP_STR
"Match VNI\n"
@@ -3450,7 +3450,7 @@ DEFUN (match_evpn_vni,
DEFUN (no_match_evpn_vni,
no_match_evpn_vni_cmd,
- "no match evpn vni (1-16777215)",
+ "no match evpn vni " CMD_VNI_RANGE,
NO_STR
MATCH_STR
EVPN_HELP_STR
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 948cc8518c..c57cd38151 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -822,6 +822,87 @@ DEFUN_HIDDEN (no_bgp_multiple_instance,
return CMD_SUCCESS;
}
+DEFUN_HIDDEN (bgp_local_mac,
+ bgp_local_mac_cmd,
+ "bgp local-mac vni " CMD_VNI_RANGE " mac WORD seq (0-4294967295)",
+ BGP_STR
+ "Local MAC config\n"
+ "VxLAN Network Identifier\n"
+ "VNI number\n"
+ "local mac\n"
+ "mac address\n"
+ "mac-mobility sequence\n"
+ "seq number\n")
+{
+ int rv;
+ vni_t vni;
+ struct ethaddr mac;
+ struct ipaddr ip;
+ uint32_t seq;
+ struct bgp *bgp;
+
+ vni = strtoul(argv[3]->arg, NULL, 10);
+ if (!prefix_str2mac(argv[5]->arg, &mac)) {
+ vty_out(vty, "%% Malformed MAC address\n");
+ return CMD_WARNING;
+ }
+ memset(&ip, 0, sizeof(ip));
+ seq = strtoul(argv[7]->arg, NULL, 10);
+
+ bgp = bgp_get_default();
+ if (!bgp) {
+ vty_out(vty, "Default BGP instance is not there\n");
+ return CMD_WARNING;
+ }
+
+ rv = bgp_evpn_local_macip_add(bgp, vni, &mac, &ip, 0 /* flags */, seq);
+ if (rv < 0) {
+ vty_out(vty, "Internal error\n");
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN_HIDDEN (no_bgp_local_mac,
+ no_bgp_local_mac_cmd,
+ "no bgp local-mac vni " CMD_VNI_RANGE " mac WORD",
+ NO_STR
+ BGP_STR
+ "Local MAC config\n"
+ "VxLAN Network Identifier\n"
+ "VNI number\n"
+ "local mac\n"
+ "mac address\n")
+{
+ int rv;
+ vni_t vni;
+ struct ethaddr mac;
+ struct ipaddr ip;
+ struct bgp *bgp;
+
+ vni = strtoul(argv[4]->arg, NULL, 10);
+ if (!prefix_str2mac(argv[6]->arg, &mac)) {
+ vty_out(vty, "%% Malformed MAC address\n");
+ return CMD_WARNING;
+ }
+ memset(&ip, 0, sizeof(ip));
+
+ bgp = bgp_get_default();
+ if (!bgp) {
+ vty_out(vty, "Default BGP instance is not there\n");
+ return CMD_WARNING;
+ }
+
+ rv = bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
+ if (rv < 0) {
+ vty_out(vty, "Internal error\n");
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
#if (CONFDATE > 20190601)
CPP_NOTICE("bgpd: time to remove deprecated cli bgp config-type cisco")
CPP_NOTICE("This includes BGP_OPT_CISCO_CONFIG")
@@ -12593,6 +12674,10 @@ void bgp_vty_init(void)
install_element(CONFIG_NODE, &bgp_config_type_cmd);
install_element(CONFIG_NODE, &no_bgp_config_type_cmd);
+ /* "bgp local-mac" hidden commands. */
+ install_element(CONFIG_NODE, &bgp_local_mac_cmd);
+ install_element(CONFIG_NODE, &no_bgp_local_mac_cmd);
+
/* bgp route-map delay-timer commands. */
install_element(CONFIG_NODE, &bgp_set_route_map_delay_timer_cmd);
install_element(CONFIG_NODE, &no_bgp_set_route_map_delay_timer_cmd);
diff --git a/lib/command.h b/lib/command.h
index 873ecdda98..11514fd5e8 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -378,6 +378,7 @@ struct cmd_node {
#define WATCHFRR_STR "watchfrr information\n"
#define ZEBRA_STR "Zebra information\n"
+#define CMD_VNI_RANGE "(1-16777215)"
#define CONF_BACKUP_EXT ".sav"
/* Command warnings. */
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 35f719fa54..cd78551cb4 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -1458,7 +1458,7 @@ DEFUNSH_HIDDEN(VTYSH_BGPD, address_family_evpn2, address_family_evpn2_cmd,
}
#endif
-DEFUNSH(VTYSH_BGPD, bgp_evpn_vni, bgp_evpn_vni_cmd, "vni (1-16777215)",
+DEFUNSH(VTYSH_BGPD, bgp_evpn_vni, bgp_evpn_vni_cmd, "vni " CMD_VNI_RANGE,
"VXLAN Network Identifier\n"
"VNI number\n")
{
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 4fff376377..263cb3d22c 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -68,9 +68,6 @@ static void vty_show_ip_route_summary(struct vty *vty,
static void vty_show_ip_route_summary_prefix(struct vty *vty,
struct route_table *table);
-/* VNI range as per RFC 7432 */
-#define CMD_VNI_RANGE "(1-16777215)"
-
DEFUN (ip_multicast_mode,
ip_multicast_mode_cmd,
"ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 0bc1ea50bb..d372d3e832 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -148,8 +148,7 @@ static void zvni_mac_del_all(zebra_vni_t *zvni, int uninstall, int upd_client,
static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr);
static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
uint8_t flags, uint32_t seq);
-static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
- uint8_t flags);
+static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr);
static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
struct interface *br_if, vlanid_t vid);
static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac);
@@ -2305,6 +2304,7 @@ static int zvni_remote_neigh_update(zebra_vni_t *zvni,
UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
+ ZEBRA_NEIGH_SET_ACTIVE(n);
n->r_vtep_ip = zmac->fwd_info.r_vtep_ip;
}
@@ -2407,7 +2407,7 @@ static void zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
&wctx->r_vtep_ip))) {
if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
zvni_mac_send_del_to_client(wctx->zvni->vni,
- &mac->macaddr, mac->flags);
+ &mac->macaddr);
}
if (wctx->uninstall)
@@ -2494,18 +2494,10 @@ static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
/*
* Inform BGP about local MAC deletion.
*/
-static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
- uint8_t mac_flags)
+static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr)
{
- uint8_t flags = 0;
-
- if (CHECK_FLAG(mac_flags, ZEBRA_MAC_STICKY))
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
- if (CHECK_FLAG(mac_flags, ZEBRA_MAC_DEF_GW))
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
-
- return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
- 0, ZEBRA_MACIP_DEL);
+ return zvni_macip_send_msg_to_client(vni, macaddr, NULL, 0 /* flags */,
+ 0 /* seq */, ZEBRA_MACIP_DEL);
}
/*
@@ -4304,6 +4296,10 @@ static void process_remote_macip_add(vni_t vni,
}
}
+ /* Remove local MAC from BGP. */
+ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
+ zvni_mac_send_del_to_client(zvni->vni, macaddr);
+
/* Set "auto" and "remote" forwarding info. */
UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
@@ -4324,6 +4320,7 @@ static void process_remote_macip_add(vni_t vni,
/* Install the entry. */
zvni_mac_install(zvni, mac);
+
}
/* Update seq number. */
@@ -4522,6 +4519,13 @@ static void process_remote_macip_del(vni_t vni,
} else {
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
zvni_process_neigh_on_remote_mac_del(zvni, mac);
+ /*
+ * the remote sequence number in the auto mac entry
+ * needs to be reset to 0 as the mac entry may have
+ * been removed on all VTEPs (including
+ * the originating one)
+ */
+ mac->rem_seq = 0;
/* If all remote neighbors referencing a remote MAC
* go away, we need to uninstall the MAC.
@@ -5730,7 +5734,7 @@ int zebra_vxlan_check_del_local_mac(struct interface *ifp,
ifp->ifindex, vni);
/* Remove MAC from BGP. */
- zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
+ zvni_mac_send_del_to_client(zvni->vni, macaddr);
/*
* If there are no neigh associated with the mac delete the mac
@@ -5841,7 +5845,7 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
zvni_process_neigh_on_local_mac_del(zvni, mac);
/* Remove MAC from BGP. */
- zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
+ zvni_mac_send_del_to_client(zvni->vni, macaddr);
/*
* If there are no neigh associated with the mac delete the mac