summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Stapp <mjs@voltanet.io>2021-04-19 15:25:27 -0400
committerMark Stapp <mjs.ietf@gmail.com>2021-07-19 10:36:12 -0400
commit7f7e49d11a9f5d9f8d14387522a612d49f0a5e3f (patch)
tree53fe87339424cf84647484081e5ca8a87bcb6a72
parent1a3bd37f7c29fca429d7ef79ace80cd6db1d5563 (diff)
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 <mjs@voltanet.io>
-rw-r--r--zebra/rib.h9
-rw-r--r--zebra/zebra_evpn_mac.c3
-rw-r--r--zebra/zebra_evpn_mh.c4
-rw-r--r--zebra/zebra_rib.c88
-rw-r--r--zebra/zebra_vxlan.c17
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: