From: Anuradha Karuppiah Date: Mon, 14 Sep 2020 13:35:45 +0000 (-0700) Subject: lib/zebra: zapi for installing EVPN nexthops from bgp X-Git-Tag: frr-8.0.1~341^2~5 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=7bfa7d0233d6ba4c33aead8a576e21b03951aa64;p=mirror_frr.git lib/zebra: zapi for installing EVPN nexthops from bgp EVPN nexthops are installed as remote neighs by zebra. This was earlier done only via VRF IPvX uni routes imported from EVPN routes. With EVPN-MH these VRF routes now reference a L3NHG which is setup based on the EAD and doesn't include the RMAC. To workaround that BGP now consolidates and maintains EVPN nexthops which are then sent to zebra. zebra sets up these nexthops as L3-VNI nh entries using a dummy type-1 route as reference. Ticket: CM-31398 Signed-off-by: Anuradha Karuppiah --- 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);