From 7f7e49d11a9f5d9f8d14387522a612d49f0a5e3f Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Mon, 19 Apr 2021 15:25:27 -0400 Subject: [PATCH] zebra: use workqueue for vxlan remote macip updates Enqueue incoming vxlan remote macip updates on the main workqueue, instead of performing the updates immediately, in-line. Signed-off-by: Mark Stapp --- zebra/rib.h | 9 +++++ zebra/zebra_evpn_mac.c | 3 +- zebra/zebra_evpn_mh.c | 4 +- zebra/zebra_rib.c | 88 +++++++++++++++++++++++++++++++++++++++--- zebra/zebra_vxlan.c | 17 +++----- 5 files changed, 102 insertions(+), 19 deletions(-) diff --git a/zebra/rib.h b/zebra/rib.h index 6902e0881b..669cc75248 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -461,6 +461,15 @@ int zebra_rib_queue_evpn_rem_es_add(const esi_t *esi, uint16_t df_pref); int zebra_rib_queue_evpn_rem_es_del(const esi_t *esi, const struct in_addr *vtep_ip); +/* Enqueue EVPN remote macip update for processing */ +int zebra_rib_queue_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr, + const struct ipaddr *ip, + struct in_addr vtep_ip); +int zebra_rib_queue_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr, + const struct ipaddr *ipaddr, + uint8_t flags, uint32_t seq, + struct in_addr vtep_ip, + const esi_t *esi); extern void meta_queue_free(struct meta_queue *mq); extern int zebra_rib_labeled_unicast(struct route_entry *re); diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index c503b56dbc..cf2aa67269 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -986,7 +986,8 @@ void zebra_evpn_print_mac_hash_detail(struct hash_bucket *bucket, void *ctxt) /* * Inform BGP about local MACIP. */ -int zebra_evpn_macip_send_msg_to_client(vni_t vni, const struct ethaddr *macaddr, +int zebra_evpn_macip_send_msg_to_client(vni_t vni, + const struct ethaddr *macaddr, const struct ipaddr *ip, uint8_t flags, uint32_t seq, int state, struct zebra_evpn_es *es, uint16_t cmd) diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 8ba62280f0..05947faf4f 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -2497,8 +2497,8 @@ void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS) : false; STREAM_GETC(s, df_alg); STREAM_GETW(s, df_pref); - zebra_rib_queue_evpn_rem_es_add(&esi, &vtep_ip, esr_rxed, df_alg, - df_pref); + zebra_rib_queue_evpn_rem_es_add(&esi, &vtep_ip, esr_rxed, + df_alg, df_pref); } else { zebra_rib_queue_evpn_rem_es_del(&esi, &vtep_ip); } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index c02dc6aa68..5f12c3012d 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -144,14 +144,19 @@ struct wq_evpn_wrapper { bool esr_rxed; uint8_t df_alg; uint16_t df_pref; + uint32_t flags; + uint32_t seq; esi_t esi; + vni_t vni; struct ipaddr ip; - struct ethaddr mac; + struct ethaddr macaddr; struct prefix prefix; + struct in_addr vtep_ip; }; -#define WQ_EVPN_WRAPPER_TYPE_VRFROUTE 0x01 -#define WQ_EVPN_WRAPPER_TYPE_REM_ES 0x02 +#define WQ_EVPN_WRAPPER_TYPE_VRFROUTE 0x01 +#define WQ_EVPN_WRAPPER_TYPE_REM_ES 0x02 +#define WQ_EVPN_WRAPPER_TYPE_REM_MACIP 0x03 /* %pRN is already a printer for route_nodes that just prints the prefix */ #ifdef _FRR_ATTRIBUTE_PRINTFRR @@ -2352,7 +2357,7 @@ static void process_subq_evpn(struct listnode *lnode) if (w->type == WQ_EVPN_WRAPPER_TYPE_VRFROUTE) { if (w->add_p) - zebra_vxlan_evpn_vrf_route_add(w->vrf_id, &w->mac, + zebra_vxlan_evpn_vrf_route_add(w->vrf_id, &w->macaddr, &w->ip, &w->prefix); else zebra_vxlan_evpn_vrf_route_del(w->vrf_id, &w->ip, @@ -2364,6 +2369,21 @@ static void process_subq_evpn(struct listnode *lnode) w->df_pref); else zebra_evpn_remote_es_del(&w->esi, w->ip.ipaddr_v4); + } else if (w->type == WQ_EVPN_WRAPPER_TYPE_REM_MACIP) { + uint16_t ipa_len = 0; + + if (w->ip.ipa_type == IPADDR_V4) + ipa_len = IPV4_MAX_BYTELEN; + else if (w->ip.ipa_type == IPADDR_V6) + ipa_len = IPV6_MAX_BYTELEN; + + if (w->add_p) + zebra_evpn_rem_macip_add(w->vni, &w->macaddr, ipa_len, + &w->ip, w->flags, w->seq, + w->vtep_ip, &w->esi); + else + zebra_evpn_rem_macip_del(w->vni, &w->macaddr, ipa_len, + &w->ip, w->vtep_ip); } XFREE(MTYPE_WQ_WRAPPER, w); @@ -2717,7 +2737,7 @@ int zebra_rib_queue_evpn_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac, w->type = WQ_EVPN_WRAPPER_TYPE_VRFROUTE; w->add_p = true; w->vrf_id = vrf_id; - w->mac = *rmac; + w->macaddr = *rmac; w->ip = *vtep_ip; w->prefix = *host_prefix; @@ -2803,6 +2823,64 @@ int zebra_rib_queue_evpn_rem_es_del(const esi_t *esi, return mq_add_handler(w, rib_meta_queue_evpn_add); } +/* + * Enqueue EVPN remote macip update for processing + */ +int zebra_rib_queue_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr, + const struct ipaddr *ipaddr, + uint8_t flags, uint32_t seq, + struct in_addr vtep_ip, const esi_t *esi) +{ + struct wq_evpn_wrapper *w; + char buf[ESI_STR_LEN]; + + w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper)); + + w->type = WQ_EVPN_WRAPPER_TYPE_REM_MACIP; + w->add_p = true; + w->vni = vni; + w->macaddr = *macaddr; + w->ip = *ipaddr; + w->flags = flags; + w->seq = seq; + w->vtep_ip = vtep_ip; + w->esi = *esi; + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) { + if (memcmp(esi, zero_esi, sizeof(esi_t)) != 0) + esi_to_str(esi, buf, sizeof(buf)); + else + strlcpy(buf, "-", sizeof(buf)); + + zlog_debug("%s: mac %pEA, vtep %pI4, esi %s enqueued", __func__, + macaddr, &vtep_ip, buf); + } + + return mq_add_handler(w, rib_meta_queue_evpn_add); +} + +int zebra_rib_queue_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr, + const struct ipaddr *ip, + struct in_addr vtep_ip) +{ + struct wq_evpn_wrapper *w; + + w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper)); + + w->type = WQ_EVPN_WRAPPER_TYPE_REM_MACIP; + w->add_p = false; + w->vni = vni; + w->macaddr = *macaddr; + w->ip = *ip; + w->vtep_ip = vtep_ip; + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("%s: mac %pEA, vtep %pI4 enqueued", __func__, + macaddr, &vtep_ip); + + return mq_add_handler(w, rib_meta_queue_evpn_add); +} + /* Clean up the EVPN meta-queue list */ static void evpn_meta_queue_free(struct list *l) { diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index b434433e17..4b96831231 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -3820,10 +3820,6 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) uint16_t l = 0, ipa_len; char buf1[INET6_ADDRSTRLEN]; - memset(&macaddr, 0, sizeof(struct ethaddr)); - memset(&ip, 0, sizeof(struct ipaddr)); - memset(&vtep_ip, 0, sizeof(struct in_addr)); - s = msg; while (l < hdr->length) { @@ -3844,7 +3840,8 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) ipaddr2str(&ip, buf1, sizeof(buf1)) : "", &vtep_ip, zebra_route_string(client->proto)); - zebra_evpn_rem_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip); + /* Enqueue to workqueue for processing */ + zebra_rib_queue_evpn_rem_macip_del(vni, &macaddr, &ip, vtep_ip); } stream_failure: @@ -3870,10 +3867,6 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) esi_t esi; char esi_buf[ESI_STR_LEN]; - memset(&macaddr, 0, sizeof(struct ethaddr)); - memset(&ip, 0, sizeof(struct ipaddr)); - memset(&vtep_ip, 0, sizeof(struct in_addr)); - if (!EVPN_ENABLED(zvrf)) { zlog_debug("EVPN not enabled, ignoring remote MACIP ADD"); return; @@ -3882,6 +3875,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) s = msg; while (l < hdr->length) { + int res_length = zebra_vxlan_remote_macip_helper( true, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip, &flags, &seq, &esi); @@ -3907,8 +3901,9 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) zebra_route_string(client->proto)); } - zebra_evpn_rem_macip_add(vni, &macaddr, ipa_len, &ip, - flags, seq, vtep_ip, &esi); + /* Enqueue to workqueue for processing */ + zebra_rib_queue_evpn_rem_macip_add(vni, &macaddr, &ip, flags, + seq, vtep_ip, &esi); } stream_failure: -- 2.39.5