summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/log.c4
-rw-r--r--lib/zclient.h2
-rw-r--r--zebra/zapi_msg.c2
-rw-r--r--zebra/zebra_evpn_mh.c41
-rw-r--r--zebra/zebra_evpn_mh.h1
-rw-r--r--zebra/zebra_vxlan.c5
6 files changed, 54 insertions, 1 deletions
diff --git a/lib/log.c b/lib/log.c
index b86d3022b..e078d8e2a 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -462,7 +462,9 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_NHG_DEL),
DESC_ENTRY(ZEBRA_NHG_NOTIFY_OWNER),
DESC_ENTRY(ZEBRA_ROUTE_NOTIFY_REQUEST),
- DESC_ENTRY(ZEBRA_CLIENT_CLOSE_NOTIFY)};
+ DESC_ENTRY(ZEBRA_CLIENT_CLOSE_NOTIFY),
+ DESC_ENTRY(ZEBRA_EVPN_REMOTE_NH_ADD),
+ DESC_ENTRY(ZEBRA_EVPN_REMOTE_NH_DEL)};
#undef DESC_ENTRY
static const struct zebra_desc_table unknown = {0, "unknown", '?'};
diff --git a/lib/zclient.h b/lib/zclient.h
index 43197534a..5b2298c42 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -213,6 +213,8 @@ typedef enum {
ZEBRA_NHG_ADD,
ZEBRA_NHG_DEL,
ZEBRA_NHG_NOTIFY_OWNER,
+ ZEBRA_EVPN_REMOTE_NH_ADD,
+ ZEBRA_EVPN_REMOTE_NH_DEL,
ZEBRA_ERROR,
ZEBRA_CLIENT_CAPABILITIES,
ZEBRA_OPAQUE_MESSAGE,
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 63ba6cd8d..b48291441 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -3350,6 +3350,8 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_NHG_ADD] = zread_nhg_add,
[ZEBRA_NHG_DEL] = zread_nhg_del,
[ZEBRA_ROUTE_NOTIFY_REQUEST] = zread_route_notify_request,
+ [ZEBRA_EVPN_REMOTE_NH_ADD] = zebra_evpn_proc_remote_nh,
+ [ZEBRA_EVPN_REMOTE_NH_DEL] = zebra_evpn_proc_remote_nh,
};
/*
diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c
index 1c258a04f..cabba707a 100644
--- a/zebra/zebra_evpn_mh.c
+++ b/zebra/zebra_evpn_mh.c
@@ -3867,6 +3867,47 @@ static void zebra_evpn_mh_startup_delay_timer_start(const char *rc)
}
}
+/*****************************************************************************
+ * Nexthop management: nexthops associated with Type-2 routes that have
+ * an ES as destination are consolidated by BGP into a per-VRF nh->rmac
+ * mapping which is the installed as a remote neigh/fdb entry with a
+ * dummy (type-1) prefix referencing it.
+ * This handling is needed because Type-2 routes with ES as dest use NHG
+ * that are setup using EAD routes (i.e. such NHGs do not include the
+ * RMAC info).
+ ****************************************************************************/
+void zebra_evpn_proc_remote_nh(ZAPI_HANDLER_ARGS)
+{
+ struct stream *s;
+ vrf_id_t vrf_id;
+ struct ipaddr nh;
+ struct ethaddr rmac;
+ struct prefix_evpn dummy_prefix;
+
+ s = msg;
+ vrf_id = stream_getl(s);
+ stream_get(&nh, s, sizeof(nh));
+
+ memset(&dummy_prefix, 0, sizeof(dummy_prefix));
+ dummy_prefix.family = AF_EVPN;
+ dummy_prefix.prefixlen = (sizeof(struct evpn_addr) * 8);
+ dummy_prefix.prefix.route_type = 1; /* XXX - fixup to type-1 def */
+
+ if (hdr->command == ZEBRA_EVPN_REMOTE_NH_ADD) {
+ stream_get(&rmac, s, sizeof(rmac));
+ if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+ zlog_debug("evpn remote nh %d %pIA rmac %pEA add",
+ vrf_id, &nh, &rmac);
+ zebra_vxlan_evpn_vrf_route_add(vrf_id, &rmac, &nh,
+ (struct prefix *)&dummy_prefix);
+ } else {
+ if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+ zlog_debug("evpn remote nh %d %pIA del", vrf_id, &nh);
+ zebra_vxlan_evpn_vrf_route_del(vrf_id, &nh,
+ (struct prefix *)&dummy_prefix);
+ }
+}
+
/*****************************************************************************/
void zebra_evpn_mh_config_write(struct vty *vty)
{
diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h
index 2361a70bf..8861e80ce 100644
--- a/zebra/zebra_evpn_mh.h
+++ b/zebra/zebra_evpn_mh.h
@@ -382,5 +382,6 @@ extern void zebra_evpn_acc_bd_svi_set(struct zebra_if *vlan_zif,
extern void zebra_evpn_acc_bd_svi_mac_add(struct interface *vlan_if);
extern void zebra_evpn_es_bypass_update(struct zebra_evpn_es *es,
struct interface *ifp, bool bypass);
+extern void zebra_evpn_proc_remote_nh(ZAPI_HANDLER_ARGS);
#endif /* _ZEBRA_EVPN_MH_H */
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index bc2eac7a0..4cd3b60a0 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -149,6 +149,11 @@ static int host_rb_entry_compare(const struct host_rb_entry *hle1,
} else if (hle1->p.family == AF_INET6) {
return memcmp(&hle1->p.u.prefix6, &hle2->p.u.prefix6,
IPV6_MAX_BYTELEN);
+ } else if (hle1->p.family == AF_EVPN) {
+ /* a single dummy prefix of route_type BGP_EVPN_AD_ROUTE is
+ * used for all nexthops associated with a non-zero ESI
+ */
+ return 0;
} else {
zlog_debug("%s: Unexpected family type: %d", __func__,
hle1->p.family);