diff options
-rw-r--r-- | lib/log.c | 4 | ||||
-rw-r--r-- | lib/zclient.h | 2 | ||||
-rw-r--r-- | zebra/zapi_msg.c | 2 | ||||
-rw-r--r-- | zebra/zebra_evpn_mh.c | 41 | ||||
-rw-r--r-- | zebra/zebra_evpn_mh.h | 1 | ||||
-rw-r--r-- | zebra/zebra_vxlan.c | 5 |
6 files changed, 54 insertions, 1 deletions
@@ -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); |