From 272e11bfc4be93a57867834edf950804680697dd Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Fri, 16 Apr 2021 12:17:11 -0400 Subject: [PATCH 1/8] zebra: give some evpn apis better names Use more useful names for a few evpn apis. Signed-off-by: Mark Stapp --- zebra/zebra_evpn.c | 13 +++++++------ zebra/zebra_evpn.h | 4 ++-- zebra/zebra_evpn_mac.c | 10 +++++----- zebra/zebra_evpn_mac.h | 10 +++++----- zebra/zebra_evpn_neigh.c | 9 +++++---- zebra/zebra_evpn_neigh.h | 9 +++++---- zebra/zebra_vxlan.c | 4 ++-- 7 files changed, 31 insertions(+), 28 deletions(-) diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index 816f46bac9..8e73e86139 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -1380,7 +1380,7 @@ zebra_evpn_process_sync_macip_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr, /************************** remote mac-ip handling **************************/ /* Process a remote MACIP add from BGP. */ -void process_remote_macip_add(vni_t vni, struct ethaddr *macaddr, +void zebra_evpn_rem_macip_add(vni_t vni, struct ethaddr *macaddr, uint16_t ipa_len, struct ipaddr *ipaddr, uint8_t flags, uint32_t seq, struct in_addr vtep_ip, esi_t *esi) @@ -1447,17 +1447,18 @@ void process_remote_macip_add(vni_t vni, struct ethaddr *macaddr, return; - if (process_mac_remote_macip_add(zevpn, zvrf, macaddr, ipa_len, ipaddr, - &mac, vtep_ip, flags, seq, esi) + if (zebra_evpn_mac_remote_macip_add(zevpn, zvrf, macaddr, ipa_len, + ipaddr, &mac, vtep_ip, flags, seq, + esi) != 0) return; - process_neigh_remote_macip_add(zevpn, zvrf, ipaddr, mac, vtep_ip, flags, - seq); + zebra_evpn_neigh_remote_macip_add(zevpn, zvrf, ipaddr, mac, vtep_ip, + flags, seq); } /* Process a remote MACIP delete from BGP. */ -void process_remote_macip_del(vni_t vni, struct ethaddr *macaddr, +void zebra_evpn_rem_macip_del(vni_t vni, struct ethaddr *macaddr, uint16_t ipa_len, struct ipaddr *ipaddr, struct in_addr vtep_ip) { diff --git a/zebra/zebra_evpn.h b/zebra/zebra_evpn.h index ee9e1406e4..f7837d09a8 100644 --- a/zebra/zebra_evpn.h +++ b/zebra/zebra_evpn.h @@ -204,11 +204,11 @@ int zebra_evpn_vtep_uninstall(zebra_evpn_t *zevpn, struct in_addr *vtep_ip); void zebra_evpn_handle_flooding_remote_vteps(struct hash_bucket *bucket, void *zvrf); void zebra_evpn_cleanup_all(struct hash_bucket *bucket, void *arg); -void process_remote_macip_add(vni_t vni, struct ethaddr *macaddr, +void zebra_evpn_rem_macip_add(vni_t vni, struct ethaddr *macaddr, uint16_t ipa_len, struct ipaddr *ipaddr, uint8_t flags, uint32_t seq, struct in_addr vtep_ip, esi_t *esi); -void process_remote_macip_del(vni_t vni, struct ethaddr *macaddr, +void zebra_evpn_rem_macip_del(vni_t vni, struct ethaddr *macaddr, uint16_t ipa_len, struct ipaddr *ipaddr, struct in_addr vtep_ip); void zebra_evpn_cfg_cleanup(struct hash_bucket *bucket, void *ctxt); diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index fe3167dc29..26694245f1 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -1958,11 +1958,11 @@ void zebra_evpn_print_dad_mac_hash_detail(struct hash_bucket *bucket, zebra_evpn_print_mac_hash_detail(bucket, ctxt); } -int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, - struct ethaddr *macaddr, uint16_t ipa_len, - struct ipaddr *ipaddr, zebra_mac_t **macp, - struct in_addr vtep_ip, uint8_t flags, - uint32_t seq, esi_t *esi) +int zebra_evpn_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, + struct ethaddr *macaddr, uint16_t ipa_len, + struct ipaddr *ipaddr, zebra_mac_t **macp, + struct in_addr vtep_ip, uint8_t flags, + uint32_t seq, esi_t *esi) { char buf1[INET6_ADDRSTRLEN]; bool sticky; diff --git a/zebra/zebra_evpn_mac.h b/zebra/zebra_evpn_mac.h index fb162f1a93..5d17e283ae 100644 --- a/zebra/zebra_evpn_mac.h +++ b/zebra/zebra_evpn_mac.h @@ -262,11 +262,11 @@ void zebra_evpn_rem_mac_del(zebra_evpn_t *zevi, zebra_mac_t *mac); void zebra_evpn_print_dad_mac_hash(struct hash_bucket *bucket, void *ctxt); void zebra_evpn_print_dad_mac_hash_detail(struct hash_bucket *bucket, void *ctxt); -int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, - struct ethaddr *macaddr, uint16_t ipa_len, - struct ipaddr *ipaddr, zebra_mac_t **macp, - struct in_addr vtep_ip, uint8_t flags, - uint32_t seq, esi_t *esi); +int zebra_evpn_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, + struct ethaddr *macaddr, uint16_t ipa_len, + struct ipaddr *ipaddr, zebra_mac_t **macp, + struct in_addr vtep_ip, uint8_t flags, + uint32_t seq, esi_t *esi); int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, struct interface *ifp, diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c index 4c7a1542fc..a78bac010c 100644 --- a/zebra/zebra_evpn_neigh.c +++ b/zebra/zebra_evpn_neigh.c @@ -2046,10 +2046,11 @@ void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket, zebra_evpn_print_neigh_hash_detail(bucket, ctxt); } -void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, - struct ipaddr *ipaddr, zebra_mac_t *mac, - struct in_addr vtep_ip, uint8_t flags, - uint32_t seq) +void zebra_evpn_neigh_remote_macip_add(zebra_evpn_t *zevpn, + struct zebra_vrf *zvrf, + struct ipaddr *ipaddr, zebra_mac_t *mac, + struct in_addr vtep_ip, uint8_t flags, + uint32_t seq) { zebra_neigh_t *n; int update_neigh = 0; diff --git a/zebra/zebra_evpn_neigh.h b/zebra/zebra_evpn_neigh.h index 05156c1255..fdfe6dc1d0 100644 --- a/zebra/zebra_evpn_neigh.h +++ b/zebra/zebra_evpn_neigh.h @@ -266,10 +266,11 @@ void zebra_evpn_print_neigh_hash_detail(struct hash_bucket *bucket, void *ctxt); void zebra_evpn_print_dad_neigh_hash(struct hash_bucket *bucket, void *ctxt); void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket, void *ctxt); -void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, - struct ipaddr *ipaddr, zebra_mac_t *mac, - struct in_addr vtep_ip, uint8_t flags, - uint32_t seq); +void zebra_evpn_neigh_remote_macip_add(zebra_evpn_t *zevpn, + struct zebra_vrf *zvrf, + struct ipaddr *ipaddr, zebra_mac_t *mac, + struct in_addr vtep_ip, uint8_t flags, + uint32_t seq); int zebra_evpn_neigh_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, struct ipaddr *ip, zebra_mac_t *mac); void zebra_evpn_neigh_remote_uninstall(zebra_evpn_t *zevpn, diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 2f3ea7475a..b434433e17 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -3844,7 +3844,7 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) ipaddr2str(&ip, buf1, sizeof(buf1)) : "", &vtep_ip, zebra_route_string(client->proto)); - process_remote_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip); + zebra_evpn_rem_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip); } stream_failure: @@ -3907,7 +3907,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) zebra_route_string(client->proto)); } - process_remote_macip_add(vni, &macaddr, ipa_len, &ip, + zebra_evpn_rem_macip_add(vni, &macaddr, ipa_len, &ip, flags, seq, vtep_ip, &esi); } From 0a0875df5b788de834d2e97cbad25bf0f9fd0b15 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Fri, 16 Apr 2021 15:28:14 -0400 Subject: [PATCH 2/8] lib: remove quagga from route_types.txt Remove the q-word. Signed-off-by: Mark Stapp --- lib/route_types.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/route_types.txt b/lib/route_types.txt index c48391545d..77639070c9 100644 --- a/lib/route_types.txt +++ b/lib/route_types.txt @@ -1,4 +1,4 @@ -# Canonical Zserv route types information registry for Quagga. +# Canonical Zserv route types information registry for FRR. # # Used to construct route_types.c and route_types.h # @@ -60,7 +60,7 @@ ZEBRA_ROUTE_PIM, pim, pimd, 'P', 0, 0, 0, "PIM", pimd ZEBRA_ROUTE_EIGRP, eigrp, eigrpd, 'E', 1, 0, 1, "EIGRP", eigrpd ZEBRA_ROUTE_NHRP, nhrp, nhrpd, 'N', 1, 1, 1, "NHRP", nhrpd # HSLS and OLSR both are AFI independent (so: 1, 1), however -# we want to disable for them for general Quagga distribution. +# we want to disable for them for general FRR distribution. # This at least makes it trivial for users of these protocols # to 'switch on' redist support (direct numeric entry remaining # possible). From 32367e7a3b948c7447c21169478fdd659b546270 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Mon, 19 Apr 2021 11:12:51 -0400 Subject: [PATCH 3/8] zebra: add workqueue support for EVPN updates Add workqueue subqueue for EVPN/VxLAN updates; migrate the evpn route and remote ES processing from their ZAPI handlers to the workqueue. Signed-off-by: Mark Stapp --- zebra/rib.h | 30 ++++- zebra/zebra_evpn_mh.c | 21 ++- zebra/zebra_evpn_mh.h | 5 +- zebra/zebra_evpn_neigh.c | 2 +- zebra/zebra_rib.c | 272 ++++++++++++++++++++++++++++++++------- 5 files changed, 265 insertions(+), 65 deletions(-) diff --git a/zebra/rib.h b/zebra/rib.h index b7ffb9ce8d..6902e0881b 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -177,15 +177,16 @@ struct route_entry { /* meta-queue structure: * sub-queue 0: nexthop group objects - * sub-queue 1: connected - * sub-queue 2: kernel - * sub-queue 3: static - * sub-queue 4: RIP, RIPng, OSPF, OSPF6, IS-IS, EIGRP, NHRP - * sub-queue 5: iBGP, eBGP - * sub-queue 6: any other origin (if any) typically those that + * sub-queue 1: EVPN/VxLAN objects + * sub-queue 2: connected + * sub-queue 3: kernel + * sub-queue 4: static + * sub-queue 5: RIP, RIPng, OSPF, OSPF6, IS-IS, EIGRP, NHRP + * sub-queue 6: iBGP, eBGP + * sub-queue 7: any other origin (if any) typically those that * don't generate routes */ -#define MQ_SIZE 7 +#define MQ_SIZE 8 struct meta_queue { struct list *subq[MQ_SIZE]; uint32_t size; /* sum of lengths of all subqueues */ @@ -446,6 +447,21 @@ extern int rib_queue_nhg_ctx_add(struct nhg_ctx *ctx); /* Enqueue incoming nhg from proto daemon for processing */ extern int rib_queue_nhe_add(struct nhg_hash_entry *nhe); +/* Enqueue evpn route for processing */ +int zebra_rib_queue_evpn_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac, + const struct ipaddr *vtep_ip, + const struct prefix *host_prefix); +int zebra_rib_queue_evpn_route_del(vrf_id_t vrf_id, + const struct ipaddr *vtep_ip, + const struct prefix *host_prefix); +/* Enqueue EVPN remote ES for processing */ +int zebra_rib_queue_evpn_rem_es_add(const esi_t *esi, + const struct in_addr *vtep_ip, + bool esr_rxed, uint8_t df_alg, + uint16_t df_pref); +int zebra_rib_queue_evpn_rem_es_del(const esi_t *esi, + const struct in_addr *vtep_ip); + extern void meta_queue_free(struct meta_queue *mq); extern int zebra_rib_labeled_unicast(struct route_entry *re); extern struct route_table *rib_table_ipv6; diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index d6ae92a03d..eb57338a8e 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -1747,7 +1747,7 @@ static int zebra_es_rb_cmp(const struct zebra_evpn_es *es1, RB_GENERATE(zebra_es_rb_head, zebra_evpn_es, rb_node, zebra_es_rb_cmp); /* Lookup ES */ -struct zebra_evpn_es *zebra_evpn_es_find(esi_t *esi) +struct zebra_evpn_es *zebra_evpn_es_find(const esi_t *esi) { struct zebra_evpn_es tmp; @@ -1758,7 +1758,7 @@ struct zebra_evpn_es *zebra_evpn_es_find(esi_t *esi) /* A new local es is created when a local-es-id and sysmac is configured * against an interface. */ -static struct zebra_evpn_es *zebra_evpn_es_new(esi_t *esi) +static struct zebra_evpn_es *zebra_evpn_es_new(const esi_t *esi) { struct zebra_evpn_es *es; @@ -2392,7 +2392,7 @@ static int zebra_evpn_type3_esi_update(struct zebra_if *zif, uint32_t lid, return zebra_evpn_local_es_update(zif, &esi); } -static int zebra_evpn_remote_es_del(esi_t *esi, struct in_addr vtep_ip) +int zebra_evpn_remote_es_del(const esi_t *esi, struct in_addr vtep_ip) { char buf[ESI_STR_LEN]; struct zebra_evpn_es *es; @@ -2432,9 +2432,8 @@ static void zebra_evpn_remote_es_flush(struct zebra_evpn_es **esp) zebra_evpn_es_remote_info_re_eval(esp); } -static int zebra_evpn_remote_es_add(esi_t *esi, struct in_addr vtep_ip, - bool esr_rxed, uint8_t df_alg, - uint16_t df_pref) +int zebra_evpn_remote_es_add(const esi_t *esi, struct in_addr vtep_ip, + bool esr_rxed, uint8_t df_alg, uint16_t df_pref) { char buf[ESI_STR_LEN]; struct zebra_evpn_es *es; @@ -2498,10 +2497,10 @@ void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS) : false; STREAM_GETC(s, df_alg); STREAM_GETW(s, df_pref); - zebra_evpn_remote_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_evpn_remote_es_del(&esi, vtep_ip); + zebra_rib_queue_evpn_rem_es_del(&esi, &vtep_ip); } stream_failure: @@ -3901,12 +3900,12 @@ void zebra_evpn_proc_remote_nh(ZAPI_HANDLER_ARGS) 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, + zebra_rib_queue_evpn_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, + zebra_rib_queue_evpn_route_del(vrf_id, &nh, (struct prefix *)&dummy_prefix); } } diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 8861e80cee..8bb9e02802 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -330,6 +330,9 @@ extern void zebra_evpn_es_show_detail(struct vty *vty, bool uj); extern void zebra_evpn_es_show_esi(struct vty *vty, bool uj, esi_t *esi); extern void zebra_evpn_update_all_es(zebra_evpn_t *zevpn); extern void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS); +int zebra_evpn_remote_es_add(const esi_t *esi, struct in_addr vtep_ip, + bool esr_rxed, uint8_t df_alg, uint16_t df_pref); +int zebra_evpn_remote_es_del(const esi_t *esi, struct in_addr vtep_ip); extern void zebra_evpn_es_evi_show(struct vty *vty, bool uj, int detail); extern void zebra_evpn_es_evi_show_vni(struct vty *vty, bool uj, vni_t vni, int detail); @@ -337,7 +340,7 @@ extern void zebra_evpn_es_mac_deref_entry(zebra_mac_t *mac); extern bool zebra_evpn_es_mac_ref_entry(zebra_mac_t *mac, struct zebra_evpn_es *es); extern bool zebra_evpn_es_mac_ref(zebra_mac_t *mac, esi_t *esi); -extern struct zebra_evpn_es *zebra_evpn_es_find(esi_t *esi); +extern struct zebra_evpn_es *zebra_evpn_es_find(const esi_t *esi); extern void zebra_evpn_interface_init(void); extern int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp); extern void zebra_evpn_acc_vl_show(struct vty *vty, bool uj); diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c index a78bac010c..e58144d0c9 100644 --- a/zebra/zebra_evpn_neigh.c +++ b/zebra/zebra_evpn_neigh.c @@ -2299,7 +2299,7 @@ int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, struct ipaddr *ip) } /* If it is a remote entry, the kernel has aged this out or someone has - * deleted it, it needs to be re-installed as Quagga is the owner. + * deleted it, it needs to be re-installed as FRR is the owner. */ if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) { zebra_evpn_rem_neigh_install(zevpn, n, false /*was_static*/); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 12cc0b4e8a..c02dc6aa68 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -56,13 +56,14 @@ #include "zebra/zebra_vxlan.h" #include "zebra/zapi_msg.h" #include "zebra/zebra_dplane.h" +#include "zebra/zebra_evpn_mh.h" DEFINE_MGROUP(ZEBRA, "zebra"); DEFINE_MTYPE(ZEBRA, RE, "Route Entry"); DEFINE_MTYPE_STATIC(ZEBRA, RIB_DEST, "RIB destination"); DEFINE_MTYPE_STATIC(ZEBRA, RIB_UPDATE_CTX, "Rib update context object"); -DEFINE_MTYPE_STATIC(ZEBRA, WQ_NHG_WRAPPER, "WQ nhg wrapper"); +DEFINE_MTYPE_STATIC(ZEBRA, WQ_WRAPPER, "WQ wrapper"); /* * Event, list, and mutex for delivery of dataplane results @@ -74,7 +75,7 @@ static struct dplane_ctx_q rib_dplane_q; DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason), (rn, reason)); -/* Should we allow non Quagga processes to delete our routes */ +/* Should we allow non FRR processes to delete our routes */ extern int allow_delete; /* Each route type's string and default distance value. */ @@ -83,41 +84,44 @@ static const struct { uint8_t distance; uint8_t meta_q_map; } route_info[ZEBRA_ROUTE_MAX] = { - [ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Uneeded for nhg's */, 0}, - [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 6}, - [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 2}, - [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, 1}, - [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 3}, - [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 4}, - [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 4}, - [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 4}, - [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 4}, - [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 4}, - [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 5}, - [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 6}, - [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 4}, - [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 4}, - [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 6}, - [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 6}, - [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 3}, - [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 6}, - [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 5}, - [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 5}, - [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 5}, - [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 5}, - [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 5}, - [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 4}, - [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 6}, - [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 6}, - [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 6}, - [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 4}, - [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 6}, - [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 6}, + [ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Unneeded for nhg's */, 0}, + [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 7}, + [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 3}, + [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, 2}, + [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 4}, + [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 5}, + [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 5}, + [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 5}, + [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 5}, + [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 5}, + [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 6}, + [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 7}, + [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 5}, + [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 5}, + [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 7}, + [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 7}, + [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 4}, + [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 7}, + [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 6}, + [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 6}, + [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 6}, + [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 6}, + [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 6}, + [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 5}, + [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 7}, + [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 7}, + [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 7}, + [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 5}, + [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 7}, + [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 7}, /* Any new route type added to zebra, should be mirrored here */ /* no entry/default: 150 */ }; +/* EVPN/VXLAN subqueue is number 1 */ +#define META_QUEUE_EVPN 1 + /* Wrapper struct for nhg workqueue items; a 'ctx' is an incoming update * from the OS, and an 'nhe' is a nhe update. */ @@ -132,6 +136,23 @@ struct wq_nhg_wrapper { #define WQ_NHG_WRAPPER_TYPE_CTX 0x01 #define WQ_NHG_WRAPPER_TYPE_NHG 0x02 +/* Wrapper structs for evpn/vxlan workqueue items. */ +struct wq_evpn_wrapper { + int type; + bool add_p; + vrf_id_t vrf_id; + bool esr_rxed; + uint8_t df_alg; + uint16_t df_pref; + esi_t esi; + struct ipaddr ip; + struct ethaddr mac; + struct prefix prefix; +}; + +#define WQ_EVPN_WRAPPER_TYPE_VRFROUTE 0x01 +#define WQ_EVPN_WRAPPER_TYPE_REM_ES 0x02 + /* %pRN is already a printer for route_nodes that just prints the prefix */ #ifdef _FRR_ATTRIBUTE_PRINTFRR #pragma FRR printfrr_ext "%pZN" (struct route_node *) @@ -2315,6 +2336,39 @@ done: dplane_ctx_fini(&ctx); } +/* + * Process a node from the EVPN/VXLAN subqueue. + */ +static void process_subq_evpn(struct listnode *lnode) +{ + struct wq_evpn_wrapper *w; + + /* In general, the list node points to a wrapper object + * holding the info necessary to make some update. + */ + w = listgetdata(lnode); + if (!w) + return; + + if (w->type == WQ_EVPN_WRAPPER_TYPE_VRFROUTE) { + if (w->add_p) + zebra_vxlan_evpn_vrf_route_add(w->vrf_id, &w->mac, + &w->ip, &w->prefix); + else + zebra_vxlan_evpn_vrf_route_del(w->vrf_id, &w->ip, + &w->prefix); + } else if (w->type == WQ_EVPN_WRAPPER_TYPE_REM_ES) { + if (w->add_p) + zebra_evpn_remote_es_add(&w->esi, w->ip.ipaddr_v4, + w->esr_rxed, w->df_alg, + w->df_pref); + else + zebra_evpn_remote_es_del(&w->esi, w->ip.ipaddr_v4); + } + + XFREE(MTYPE_WQ_WRAPPER, w); +} + /* * Process the nexthop-group workqueue subqueue */ @@ -2355,8 +2409,7 @@ static void process_subq_nhg(struct listnode *lnode) /* Process incoming nhg update, probably from a proto daemon */ newnhe = zebra_nhg_proto_add(nhe->id, nhe->type, nhe->zapi_instance, - nhe->zapi_session, - &nhe->nhg, 0); + nhe->zapi_session, &nhe->nhg, 0); /* Report error to daemon via ZAPI */ if (newnhe == NULL) @@ -2368,7 +2421,7 @@ static void process_subq_nhg(struct listnode *lnode) zebra_nhg_free(nhe); } - XFREE(MTYPE_WQ_NHG_WRAPPER, w); + XFREE(MTYPE_WQ_WRAPPER, w); } static void process_subq_route(struct listnode *lnode, uint8_t qindex) @@ -2411,9 +2464,9 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex) route_unlock_node(rnode); } -/* Take a list of route_node structs and return 1, if there was a record - * picked from it and processed by rib_process(). Don't process more, - * than one RN record; operate only in the specified sub-queue. +/* + * Examine the specified subqueue; process one entry and return 1 if + * there is a node, return 0 otherwise. */ static unsigned int process_subq(struct list *subq, uint8_t qindex) { @@ -2422,7 +2475,9 @@ static unsigned int process_subq(struct list *subq, uint8_t qindex) if (!lnode) return 0; - if (qindex == route_info[ZEBRA_ROUTE_NHG].meta_q_map) + if (qindex == META_QUEUE_EVPN) + process_subq_evpn(lnode); + else if (qindex == route_info[ZEBRA_ROUTE_NHG].meta_q_map) process_subq_nhg(lnode); else process_subq_route(lnode, qindex); @@ -2432,7 +2487,7 @@ static unsigned int process_subq(struct list *subq, uint8_t qindex) return 1; } -/* Dispatch the meta queue by picking, processing and unlocking the next RN from +/* Dispatch the meta queue by picking and processing the next node from * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and * data is pointed to the meta queue structure. */ @@ -2538,7 +2593,7 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data) if (!ctx) return -1; - w = XCALLOC(MTYPE_WQ_NHG_WRAPPER, sizeof(struct wq_nhg_wrapper)); + w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_nhg_wrapper)); w->type = WQ_NHG_WRAPPER_TYPE_CTX; w->u.ctx = ctx; @@ -2564,7 +2619,7 @@ static int rib_meta_queue_nhg_add(struct meta_queue *mq, void *data) if (!nhe) return -1; - w = XCALLOC(MTYPE_WQ_NHG_WRAPPER, sizeof(struct wq_nhg_wrapper)); + w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_nhg_wrapper)); w->type = WQ_NHG_WRAPPER_TYPE_NHG; w->u.nhe = nhe; @@ -2579,6 +2634,14 @@ static int rib_meta_queue_nhg_add(struct meta_queue *mq, void *data) return 0; } +static int rib_meta_queue_evpn_add(struct meta_queue *mq, void *data) +{ + listnode_add(mq->subq[META_QUEUE_EVPN], data); + mq->size++; + + return 0; +} + static int mq_add_handler(void *data, int (*mq_add_func)(struct meta_queue *mq, void *data)) { @@ -2640,6 +2703,123 @@ int rib_queue_nhe_add(struct nhg_hash_entry *nhe) return mq_add_handler(nhe, rib_meta_queue_nhg_add); } +/* + * Enqueue evpn route for processing + */ +int zebra_rib_queue_evpn_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac, + const struct ipaddr *vtep_ip, + const struct prefix *host_prefix) +{ + struct wq_evpn_wrapper *w; + + w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper)); + + w->type = WQ_EVPN_WRAPPER_TYPE_VRFROUTE; + w->add_p = true; + w->vrf_id = vrf_id; + w->mac = *rmac; + w->ip = *vtep_ip; + w->prefix = *host_prefix; + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__, + vrf_id, vtep_ip, host_prefix); + + return mq_add_handler(w, rib_meta_queue_evpn_add); +} + +int zebra_rib_queue_evpn_route_del(vrf_id_t vrf_id, + const struct ipaddr *vtep_ip, + const struct prefix *host_prefix) +{ + struct wq_evpn_wrapper *w; + + w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper)); + + w->type = WQ_EVPN_WRAPPER_TYPE_VRFROUTE; + w->add_p = false; + w->vrf_id = vrf_id; + w->ip = *vtep_ip; + w->prefix = *host_prefix; + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__, + vrf_id, vtep_ip, host_prefix); + + return mq_add_handler(w, rib_meta_queue_evpn_add); +} + +/* Enqueue EVPN remote ES for processing */ +int zebra_rib_queue_evpn_rem_es_add(const esi_t *esi, + const struct in_addr *vtep_ip, + bool esr_rxed, uint8_t df_alg, + uint16_t df_pref) +{ + 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_ES; + w->add_p = true; + w->esi = *esi; + w->ip.ipa_type = IPADDR_V4; + w->ip.ipaddr_v4 = *vtep_ip; + w->esr_rxed = esr_rxed; + w->df_alg = df_alg; + w->df_pref = df_pref; + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("%s: vtep %pI4, esi %s enqueued", __func__, vtep_ip, + esi_to_str(esi, buf, sizeof(buf))); + + return mq_add_handler(w, rib_meta_queue_evpn_add); +} + +int zebra_rib_queue_evpn_rem_es_del(const esi_t *esi, + const struct in_addr *vtep_ip) +{ + 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_ES; + w->add_p = false; + w->esi = *esi; + w->ip.ipa_type = IPADDR_V4; + w->ip.ipaddr_v4 = *vtep_ip; + + 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: vtep %pI4, esi %s enqueued", __func__, vtep_ip, + buf); + } + + 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) +{ + struct listnode *node; + struct wq_evpn_wrapper *w; + + /* Free the node wrapper object, and the struct it wraps */ + while ((node = listhead(l)) != NULL) { + w = node->data; + node->data = NULL; + + XFREE(MTYPE_WQ_WRAPPER, w); + + list_delete_node(l, node); + } +} + /* Clean up the nhg meta-queue list */ static void nhg_meta_queue_free(struct list *l) { @@ -2656,7 +2836,7 @@ static void nhg_meta_queue_free(struct list *l) else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG) zebra_nhg_free(w->u.nhe); - XFREE(MTYPE_WQ_NHG_WRAPPER, w); + XFREE(MTYPE_WQ_WRAPPER, w); list_delete_node(l, node); } @@ -2688,6 +2868,8 @@ void meta_queue_free(struct meta_queue *mq) /* Some subqueues may need cleanup - nhgs for example */ if (i == route_info[ZEBRA_ROUTE_NHG].meta_q_map) nhg_meta_queue_free(mq->subq[i]); + else if (i == META_QUEUE_EVPN) + evpn_meta_queue_free(mq->subq[i]); list_delete(&mq->subq[i]); } @@ -2763,7 +2945,7 @@ rib_dest_t *zebra_rib_create_dest(struct route_node *rn) * dest is created on-demand by rib_link() and is kept around at least * as long as there are ribs hanging off it (@see rib_gc_dest()). * - * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code): + * Refcounting (aka "locking" throughout the Zebra and FRR code): * * - route_nodes: refcounted by: * - dest attached to route_node: @@ -3518,7 +3700,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, &(tmp_nh->gate.ipv6), sizeof(struct in6_addr)); } - zebra_vxlan_evpn_vrf_route_del(re->vrf_id, + zebra_rib_queue_evpn_route_del(re->vrf_id, &vtep_ip, p); } } From 1a3bd37f7c29fca429d7ef79ace80cd6db1d5563 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Mon, 19 Apr 2021 14:26:57 -0400 Subject: [PATCH 4/8] zebra: use more const Use const in many more evpn apis, especially for macaddr, ipaddr arguments. Signed-off-by: Mark Stapp --- zebra/rt.h | 4 ++-- zebra/rt_netlink.c | 14 +++++++------- zebra/rt_netlink.h | 5 +++-- zebra/rtread_netlink.c | 6 +++--- zebra/rtread_sysctl.c | 4 ++-- zebra/zebra_evpn.c | 20 +++++++++++--------- zebra/zebra_evpn.h | 10 +++++----- zebra/zebra_evpn_mac.c | 41 +++++++++++++++++++++------------------- zebra/zebra_evpn_mac.h | 40 +++++++++++++++++++++------------------ zebra/zebra_evpn_mh.c | 2 +- zebra/zebra_evpn_mh.h | 4 ++-- zebra/zebra_evpn_neigh.c | 39 ++++++++++++++++++++------------------ zebra/zebra_evpn_neigh.h | 33 +++++++++++++++++--------------- 13 files changed, 119 insertions(+), 103 deletions(-) diff --git a/zebra/rt.h b/zebra/rt.h index f79ddbe958..929a44ade7 100644 --- a/zebra/rt.h +++ b/zebra/rt.h @@ -93,10 +93,10 @@ extern void macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp, struct interface *br_if); extern void macfdb_read_specific_mac(struct zebra_ns *zns, struct interface *br_if, - struct ethaddr *mac, vlanid_t vid); + const struct ethaddr *mac, vlanid_t vid); extern void neigh_read(struct zebra_ns *zns); extern void neigh_read_for_vlan(struct zebra_ns *zns, struct interface *ifp); -extern void neigh_read_specific_ip(struct ipaddr *ip, +extern void neigh_read_specific_ip(const struct ipaddr *ip, struct interface *vlan_if); extern void route_read(struct zebra_ns *zns); extern int kernel_upd_mac_nh(uint32_t nh_id, struct in_addr vtep_ip); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 38f8140db2..a64ec52dda 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -3466,10 +3466,9 @@ int netlink_macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp, /* Request for MAC FDB for a specific MAC address in VLAN from the kernel */ static int netlink_request_specific_mac_in_bridge(struct zebra_ns *zns, - int family, - int type, + int family, int type, struct interface *br_if, - struct ethaddr *mac, + const struct ethaddr *mac, vlanid_t vid) { struct { @@ -3506,7 +3505,7 @@ static int netlink_request_specific_mac_in_bridge(struct zebra_ns *zns, int netlink_macfdb_read_specific_mac(struct zebra_ns *zns, struct interface *br_if, - struct ethaddr *mac, vlanid_t vid) + const struct ethaddr *mac, vlanid_t vid) { int ret = 0; struct zebra_dplane_info dp_info; @@ -3946,7 +3945,8 @@ int netlink_neigh_read_for_vlan(struct zebra_ns *zns, struct interface *vlan_if) * read using netlink interface. */ static int netlink_request_specific_neigh_in_vlan(struct zebra_ns *zns, - int type, struct ipaddr *ip, + int type, + const struct ipaddr *ip, ifindex_t ifindex) { struct { @@ -3983,8 +3983,8 @@ static int netlink_request_specific_neigh_in_vlan(struct zebra_ns *zns, return netlink_request(&zns->netlink_cmd, &req); } -int netlink_neigh_read_specific_ip(struct ipaddr *ip, - struct interface *vlan_if) +int netlink_neigh_read_specific_ip(const struct ipaddr *ip, + struct interface *vlan_if) { int ret = 0; struct zebra_ns *zns; diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index 4e41ff984b..93c06e555b 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -99,8 +99,9 @@ extern int netlink_neigh_read_for_vlan(struct zebra_ns *zns, struct interface *vlan_if); extern int netlink_macfdb_read_specific_mac(struct zebra_ns *zns, struct interface *br_if, - struct ethaddr *mac, uint16_t vid); -extern int netlink_neigh_read_specific_ip(struct ipaddr *ip, + const struct ethaddr *mac, + uint16_t vid); +extern int netlink_neigh_read_specific_ip(const struct ipaddr *ip, struct interface *vlan_if); extern vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id); diff --git a/zebra/rtread_netlink.c b/zebra/rtread_netlink.c index fbca47351d..f70b006acd 100644 --- a/zebra/rtread_netlink.c +++ b/zebra/rtread_netlink.c @@ -46,9 +46,9 @@ void macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp, } void macfdb_read_specific_mac(struct zebra_ns *zns, struct interface *br_if, - struct ethaddr *mac, vlanid_t vid) + const struct ethaddr *mac, vlanid_t vid) { -netlink_macfdb_read_specific_mac(zns, br_if, mac, vid); + netlink_macfdb_read_specific_mac(zns, br_if, mac, vid); } void neigh_read(struct zebra_ns *zns) @@ -61,7 +61,7 @@ void neigh_read_for_vlan(struct zebra_ns *zns, struct interface *vlan_if) netlink_neigh_read_for_vlan(zns, vlan_if); } -void neigh_read_specific_ip(struct ipaddr *ip, struct interface *vlan_if) +void neigh_read_specific_ip(const struct ipaddr *ip, struct interface *vlan_if) { netlink_neigh_read_specific_ip(ip, vlan_if); } diff --git a/zebra/rtread_sysctl.c b/zebra/rtread_sysctl.c index 74c6825ba1..594f7c2dd9 100644 --- a/zebra/rtread_sysctl.c +++ b/zebra/rtread_sysctl.c @@ -88,7 +88,7 @@ void macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp, } void macfdb_read_specific_mac(struct zebra_ns *zns, struct interface *br_if, - struct ethaddr *mac, vlanid_t vid) + const struct ethaddr *mac, vlanid_t vid) { } @@ -100,7 +100,7 @@ void neigh_read_for_vlan(struct zebra_ns *zns, struct interface *vlan_if) { } -void neigh_read_specific_ip(struct ipaddr *ip, struct interface *vlan_if) +void neigh_read_specific_ip(const struct ipaddr *ip, struct interface *vlan_if) { } diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index 8e73e86139..2c9f1dca59 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -1330,10 +1330,12 @@ void zebra_evpn_cleanup_all(struct hash_bucket *bucket, void *arg) zebra_evpn_del(zevpn); } -static void -zebra_evpn_process_sync_macip_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr, - uint16_t ipa_len, struct ipaddr *ipaddr, - uint8_t flags, uint32_t seq, esi_t *esi) +static void zebra_evpn_process_sync_macip_add(zebra_evpn_t *zevpn, + const struct ethaddr *macaddr, + uint16_t ipa_len, + const struct ipaddr *ipaddr, + uint8_t flags, uint32_t seq, + const esi_t *esi) { struct sync_mac_ip_ctx ctx; char ipbuf[INET6_ADDRSTRLEN]; @@ -1380,10 +1382,10 @@ zebra_evpn_process_sync_macip_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr, /************************** remote mac-ip handling **************************/ /* Process a remote MACIP add from BGP. */ -void zebra_evpn_rem_macip_add(vni_t vni, struct ethaddr *macaddr, - uint16_t ipa_len, struct ipaddr *ipaddr, +void zebra_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr, + uint16_t ipa_len, const struct ipaddr *ipaddr, uint8_t flags, uint32_t seq, - struct in_addr vtep_ip, esi_t *esi) + struct in_addr vtep_ip, const esi_t *esi) { zebra_evpn_t *zevpn; zebra_vtep_t *zvtep; @@ -1458,8 +1460,8 @@ void zebra_evpn_rem_macip_add(vni_t vni, struct ethaddr *macaddr, } /* Process a remote MACIP delete from BGP. */ -void zebra_evpn_rem_macip_del(vni_t vni, struct ethaddr *macaddr, - uint16_t ipa_len, struct ipaddr *ipaddr, +void zebra_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr, + uint16_t ipa_len, const struct ipaddr *ipaddr, struct in_addr vtep_ip) { zebra_evpn_t *zevpn; diff --git a/zebra/zebra_evpn.h b/zebra/zebra_evpn.h index f7837d09a8..774627a15d 100644 --- a/zebra/zebra_evpn.h +++ b/zebra/zebra_evpn.h @@ -204,12 +204,12 @@ int zebra_evpn_vtep_uninstall(zebra_evpn_t *zevpn, struct in_addr *vtep_ip); void zebra_evpn_handle_flooding_remote_vteps(struct hash_bucket *bucket, void *zvrf); void zebra_evpn_cleanup_all(struct hash_bucket *bucket, void *arg); -void zebra_evpn_rem_macip_add(vni_t vni, struct ethaddr *macaddr, - uint16_t ipa_len, struct ipaddr *ipaddr, +void zebra_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr, + uint16_t ipa_len, const struct ipaddr *ipaddr, uint8_t flags, uint32_t seq, - struct in_addr vtep_ip, esi_t *esi); -void zebra_evpn_rem_macip_del(vni_t vni, struct ethaddr *macaddr, - uint16_t ipa_len, struct ipaddr *ipaddr, + struct in_addr vtep_ip, const esi_t *esi); +void zebra_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr, + uint16_t ipa_len, const struct ipaddr *ipaddr, struct in_addr vtep_ip); void zebra_evpn_cfg_cleanup(struct hash_bucket *bucket, void *ctxt); diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index 26694245f1..c503b56dbc 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -986,8 +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, struct ethaddr *macaddr, - struct ipaddr *ip, uint8_t flags, +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) { @@ -1095,7 +1095,8 @@ static void *zebra_evpn_mac_alloc(void *p) /* * Add MAC entry. */ -zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr) +zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevpn, + const struct ethaddr *macaddr) { zebra_mac_t tmp_mac; zebra_mac_t *mac = NULL; @@ -1254,7 +1255,8 @@ void zebra_evpn_mac_del_all(zebra_evpn_t *zevpn, int uninstall, int upd_client, /* * Look up MAC hash entry. */ -zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevpn, struct ethaddr *mac) +zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevpn, + const struct ethaddr *mac) { zebra_mac_t tmp; zebra_mac_t *pmac; @@ -1269,7 +1271,7 @@ zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevpn, struct ethaddr *mac) /* * Inform BGP about local MAC addition. */ -int zebra_evpn_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr, +int zebra_evpn_mac_send_add_to_client(vni_t vni, const struct ethaddr *macaddr, uint32_t mac_flags, uint32_t seq, struct zebra_evpn_es *es) { @@ -1303,7 +1305,7 @@ int zebra_evpn_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr, /* * Inform BGP about local MAC deletion. */ -int zebra_evpn_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr, +int zebra_evpn_mac_send_del_to_client(vni_t vni, const struct ethaddr *macaddr, uint32_t flags, bool force) { if (!force) { @@ -1563,7 +1565,7 @@ void zebra_evpn_sync_mac_del(zebra_mac_t *mac) static inline bool zebra_evpn_mac_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_mac_t *mac, uint32_t seq, uint16_t ipa_len, - struct ipaddr *ipaddr, + const struct ipaddr *ipaddr, bool sync) { char ipbuf[INET6_ADDRSTRLEN]; @@ -1627,11 +1629,10 @@ static inline bool zebra_evpn_mac_is_bgp_seq_ok(zebra_evpn_t *zevpn, return true; } -zebra_mac_t * -zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr, - uint16_t ipa_len, struct ipaddr *ipaddr, - uint8_t flags, uint32_t seq, esi_t *esi, - struct sync_mac_ip_ctx *ctx) +zebra_mac_t *zebra_evpn_proc_sync_mac_update( + zebra_evpn_t *zevpn, const struct ethaddr *macaddr, uint16_t ipa_len, + const struct ipaddr *ipaddr, uint8_t flags, uint32_t seq, + const esi_t *esi, struct sync_mac_ip_ctx *ctx) { zebra_mac_t *mac; bool inform_bgp = false; @@ -1959,10 +1960,12 @@ void zebra_evpn_print_dad_mac_hash_detail(struct hash_bucket *bucket, } int zebra_evpn_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, - struct ethaddr *macaddr, uint16_t ipa_len, - struct ipaddr *ipaddr, zebra_mac_t **macp, - struct in_addr vtep_ip, uint8_t flags, - uint32_t seq, esi_t *esi) + const struct ethaddr *macaddr, + uint16_t ipa_len, + const struct ipaddr *ipaddr, + zebra_mac_t **macp, struct in_addr vtep_ip, + uint8_t flags, uint32_t seq, + const esi_t *esi) { char buf1[INET6_ADDRSTRLEN]; bool sticky; @@ -2127,7 +2130,7 @@ int zebra_evpn_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, struct interface *ifp, - struct ethaddr *macaddr, vlanid_t vid, + const struct ethaddr *macaddr, vlanid_t vid, bool sticky, bool local_inactive, bool dp_static, zebra_mac_t *mac) { @@ -2447,8 +2450,8 @@ int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac, } int zebra_evpn_mac_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, - struct ipaddr *ip, zebra_mac_t **macp, - struct ethaddr *macaddr, vlanid_t vlan_id, + const struct ipaddr *ip, zebra_mac_t **macp, + const struct ethaddr *macaddr, vlanid_t vlan_id, bool def_gw) { zebra_mac_t *mac; diff --git a/zebra/zebra_evpn_mac.h b/zebra/zebra_evpn_mac.h index 5d17e283ae..e90082e50b 100644 --- a/zebra/zebra_evpn_mac.h +++ b/zebra/zebra_evpn_mac.h @@ -229,11 +229,14 @@ int zebra_evpn_rem_mac_uninstall(zebra_evpn_t *zevi, zebra_mac_t *mac, int zebra_evpn_rem_mac_install(zebra_evpn_t *zevi, zebra_mac_t *mac, bool was_static); void zebra_evpn_deref_ip2mac(zebra_evpn_t *zevi, zebra_mac_t *mac); -zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevi, struct ethaddr *mac); -zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevi, struct ethaddr *macaddr); +zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevi, + const struct ethaddr *mac); +zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevi, + const struct ethaddr *macaddr); int zebra_evpn_mac_del(zebra_evpn_t *zevi, zebra_mac_t *mac); -int zebra_evpn_macip_send_msg_to_client(uint32_t id, struct ethaddr *macaddr, - struct ipaddr *ip, uint8_t flags, +int zebra_evpn_macip_send_msg_to_client(uint32_t id, + const struct ethaddr *macaddr, + const struct ipaddr *ip, uint8_t flags, uint32_t seq, int state, struct zebra_evpn_es *es, uint16_t cmd); void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json); @@ -246,38 +249,39 @@ void zebra_evpn_mac_send_add_del_to_client(zebra_mac_t *mac, bool old_bgp_ready, void zebra_evpn_mac_del_all(zebra_evpn_t *zevi, int uninstall, int upd_client, uint32_t flags); -int zebra_evpn_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr, +int zebra_evpn_mac_send_add_to_client(vni_t vni, const struct ethaddr *macaddr, uint32_t mac_flags, uint32_t seq, struct zebra_evpn_es *es); -int zebra_evpn_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr, +int zebra_evpn_mac_send_del_to_client(vni_t vni, const struct ethaddr *macaddr, uint32_t flags, bool force); void zebra_evpn_send_mac_list_to_client(zebra_evpn_t *zevi); -zebra_mac_t * -zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevi, struct ethaddr *macaddr, - uint16_t ipa_len, struct ipaddr *ipaddr, - uint8_t flags, uint32_t seq, esi_t *esi, - struct sync_mac_ip_ctx *ctx); +zebra_mac_t *zebra_evpn_proc_sync_mac_update( + zebra_evpn_t *zevi, const struct ethaddr *macaddr, uint16_t ipa_len, + const struct ipaddr *ipaddr, uint8_t flags, uint32_t seq, + const esi_t *esi, struct sync_mac_ip_ctx *ctx); void zebra_evpn_sync_mac_del(zebra_mac_t *mac); void zebra_evpn_rem_mac_del(zebra_evpn_t *zevi, zebra_mac_t *mac); void zebra_evpn_print_dad_mac_hash(struct hash_bucket *bucket, void *ctxt); void zebra_evpn_print_dad_mac_hash_detail(struct hash_bucket *bucket, void *ctxt); int zebra_evpn_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, - struct ethaddr *macaddr, uint16_t ipa_len, - struct ipaddr *ipaddr, zebra_mac_t **macp, - struct in_addr vtep_ip, uint8_t flags, - uint32_t seq, esi_t *esi); + const struct ethaddr *macaddr, + uint16_t ipa_len, + const struct ipaddr *ipaddr, + zebra_mac_t **macp, struct in_addr vtep_ip, + uint8_t flags, uint32_t seq, + const esi_t *esi); int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, struct interface *ifp, - struct ethaddr *macaddr, vlanid_t vid, + const struct ethaddr *macaddr, vlanid_t vid, bool sticky, bool local_inactive, bool dp_static, zebra_mac_t *mac); int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac, bool clear_static); int zebra_evpn_mac_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, - struct ipaddr *ip, zebra_mac_t **macp, - struct ethaddr *macaddr, vlanid_t vlan_id, + const struct ipaddr *ip, zebra_mac_t **macp, + const struct ethaddr *macaddr, vlanid_t vlan_id, bool def_gw); void zebra_evpn_mac_svi_add(struct interface *ifp, zebra_evpn_t *zevpn); void zebra_evpn_mac_svi_del(struct interface *ifp, zebra_evpn_t *zevpn); diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index eb57338a8e..8ba62280f0 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -2541,7 +2541,7 @@ bool zebra_evpn_es_mac_ref_entry(zebra_mac_t *mac, struct zebra_evpn_es *es) return true; } -bool zebra_evpn_es_mac_ref(zebra_mac_t *mac, esi_t *esi) +bool zebra_evpn_es_mac_ref(zebra_mac_t *mac, const esi_t *esi) { struct zebra_evpn_es *es; diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 8bb9e02802..a828056f1f 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -338,8 +338,8 @@ extern void zebra_evpn_es_evi_show_vni(struct vty *vty, bool uj, vni_t vni, int detail); extern void zebra_evpn_es_mac_deref_entry(zebra_mac_t *mac); extern bool zebra_evpn_es_mac_ref_entry(zebra_mac_t *mac, - struct zebra_evpn_es *es); -extern bool zebra_evpn_es_mac_ref(zebra_mac_t *mac, esi_t *esi); + struct zebra_evpn_es *es); +extern bool zebra_evpn_es_mac_ref(zebra_mac_t *mac, const esi_t *esi); extern struct zebra_evpn_es *zebra_evpn_es_find(const esi_t *esi); extern void zebra_evpn_interface_init(void); extern int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp); diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c index e58144d0c9..839e8d9ebc 100644 --- a/zebra/zebra_evpn_neigh.c +++ b/zebra/zebra_evpn_neigh.c @@ -204,7 +204,7 @@ static void *zebra_evpn_neigh_alloc(void *p) } static void zebra_evpn_local_neigh_ref_mac(zebra_neigh_t *n, - struct ethaddr *macaddr, + const struct ethaddr *macaddr, zebra_mac_t *mac, bool send_mac_update) { @@ -284,8 +284,8 @@ static void zebra_evpn_sync_neigh_dp_install(zebra_neigh_t *n, /* * Inform BGP about local neighbor addition. */ -int zebra_evpn_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip, - struct ethaddr *macaddr, +int zebra_evpn_neigh_send_add_to_client(vni_t vni, const struct ipaddr *ip, + const struct ethaddr *macaddr, zebra_mac_t *zmac, uint32_t neigh_flags, uint32_t seq) { @@ -497,7 +497,7 @@ static void zebra_evpn_local_neigh_deref_mac(zebra_neigh_t *n, } bool zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_neigh_t *n, - struct ethaddr *macaddr, uint32_t seq, + const struct ethaddr *macaddr, uint32_t seq, bool sync) { uint32_t tmp_seq; @@ -543,8 +543,8 @@ bool zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_neigh_t *n, * Add neighbor entry. */ static zebra_neigh_t *zebra_evpn_neigh_add(zebra_evpn_t *zevpn, - struct ipaddr *ip, - struct ethaddr *mac, + const struct ipaddr *ip, + const struct ethaddr *mac, zebra_mac_t *zmac, uint32_t n_flags) { zebra_neigh_t tmp_n; @@ -615,8 +615,8 @@ void zebra_evpn_sync_neigh_del(zebra_neigh_t *n) zebra_neigh_t * zebra_evpn_proc_sync_neigh_update(zebra_evpn_t *zevpn, zebra_neigh_t *n, - uint16_t ipa_len, struct ipaddr *ipaddr, - uint8_t flags, uint32_t seq, esi_t *esi, + uint16_t ipa_len, const struct ipaddr *ipaddr, + uint8_t flags, uint32_t seq, const esi_t *esi, struct sync_mac_ip_ctx *ctx) { struct interface *ifp = NULL; @@ -895,7 +895,8 @@ void zebra_evpn_neigh_del_all(zebra_evpn_t *zevpn, int uninstall, /* * Look up neighbor hash entry. */ -zebra_neigh_t *zebra_evpn_neigh_lookup(zebra_evpn_t *zevpn, struct ipaddr *ip) +zebra_neigh_t *zebra_evpn_neigh_lookup(zebra_evpn_t *zevpn, + const struct ipaddr *ip) { zebra_neigh_t tmp; zebra_neigh_t *n; @@ -1254,9 +1255,9 @@ zebra_evpn_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf, zebra_neigh_t *nbr, } int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp, - struct ipaddr *ip, struct ethaddr *macaddr, - bool is_router, bool local_inactive, - bool dp_static) + const struct ipaddr *ip, + const struct ethaddr *macaddr, bool is_router, + bool local_inactive, bool dp_static) { struct zebra_vrf *zvrf; zebra_neigh_t *n = NULL; @@ -1596,7 +1597,8 @@ int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp, } int zebra_evpn_remote_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp, - struct ipaddr *ip, struct ethaddr *macaddr, + const struct ipaddr *ip, + const struct ethaddr *macaddr, uint16_t state) { zebra_neigh_t *n = NULL; @@ -2048,9 +2050,9 @@ void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket, void zebra_evpn_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, - struct ipaddr *ipaddr, zebra_mac_t *mac, - struct in_addr vtep_ip, uint8_t flags, - uint32_t seq) + const struct ipaddr *ipaddr, + zebra_mac_t *mac, struct in_addr vtep_ip, + uint8_t flags, uint32_t seq) { zebra_neigh_t *n; int update_neigh = 0; @@ -2241,7 +2243,8 @@ int zebra_evpn_neigh_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, void zebra_evpn_neigh_remote_uninstall(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, zebra_neigh_t *n, - zebra_mac_t *mac, struct ipaddr *ipaddr) + zebra_mac_t *mac, + const struct ipaddr *ipaddr) { if (zvrf->dad_freeze && CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE) && CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) @@ -2274,7 +2277,7 @@ void zebra_evpn_neigh_remote_uninstall(zebra_evpn_t *zevpn, } } -int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, struct ipaddr *ip) +int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, const struct ipaddr *ip) { zebra_neigh_t *n; zebra_mac_t *zmac; diff --git a/zebra/zebra_evpn_neigh.h b/zebra/zebra_evpn_neigh.h index fdfe6dc1d0..3735a833fd 100644 --- a/zebra/zebra_evpn_neigh.h +++ b/zebra/zebra_evpn_neigh.h @@ -217,26 +217,27 @@ int remote_neigh_count(zebra_mac_t *zmac); int zebra_evpn_rem_neigh_install(zebra_evpn_t *zevpn, zebra_neigh_t *n, bool was_static); void zebra_evpn_install_neigh_hash(struct hash_bucket *bucket, void *ctxt); -int zebra_evpn_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip, - struct ethaddr *macaddr, +int zebra_evpn_neigh_send_add_to_client(vni_t vni, const struct ipaddr *ip, + const struct ethaddr *macaddr, zebra_mac_t *zmac, uint32_t neigh_flags, uint32_t seq); int zebra_evpn_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, uint32_t flags, int state, bool force); bool zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_neigh_t *n, - struct ethaddr *macaddr, uint32_t seq, + const struct ethaddr *macaddr, uint32_t seq, bool sync); int zebra_evpn_neigh_del(zebra_evpn_t *zevpn, zebra_neigh_t *n); void zebra_evpn_sync_neigh_del(zebra_neigh_t *n); zebra_neigh_t * zebra_evpn_proc_sync_neigh_update(zebra_evpn_t *zevpn, zebra_neigh_t *n, - uint16_t ipa_len, struct ipaddr *ipaddr, - uint8_t flags, uint32_t seq, esi_t *esi, + uint16_t ipa_len, const struct ipaddr *ipaddr, + uint8_t flags, uint32_t seq, const esi_t *esi, struct sync_mac_ip_ctx *ctx); void zebra_evpn_neigh_del_all(zebra_evpn_t *zevpn, int uninstall, int upd_client, uint32_t flags); -zebra_neigh_t *zebra_evpn_neigh_lookup(zebra_evpn_t *zevpn, struct ipaddr *ip); +zebra_neigh_t *zebra_evpn_neigh_lookup(zebra_evpn_t *zevpn, + const struct ipaddr *ip); int zebra_evpn_rem_neigh_install(zebra_evpn_t *zevpn, zebra_neigh_t *n, bool was_static); @@ -251,11 +252,12 @@ void zebra_evpn_process_neigh_on_local_mac_change(zebra_evpn_t *zevpn, void zebra_evpn_process_neigh_on_remote_mac_del(zebra_evpn_t *zevpn, zebra_mac_t *zmac); int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp, - struct ipaddr *ip, struct ethaddr *macaddr, - bool is_router, bool local_inactive, - bool dp_static); + const struct ipaddr *ip, + const struct ethaddr *macaddr, bool is_router, + bool local_inactive, bool dp_static); int zebra_evpn_remote_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp, - struct ipaddr *ip, struct ethaddr *macaddr, + const struct ipaddr *ip, + const struct ethaddr *macaddr, uint16_t state); void zebra_evpn_send_neigh_to_client(zebra_evpn_t *zevpn); void zebra_evpn_clear_dup_neigh_hash(struct hash_bucket *bucket, void *ctxt); @@ -268,15 +270,16 @@ void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket, void *ctxt); void zebra_evpn_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, - struct ipaddr *ipaddr, zebra_mac_t *mac, - struct in_addr vtep_ip, uint8_t flags, - uint32_t seq); + const struct ipaddr *ipaddr, + zebra_mac_t *mac, struct in_addr vtep_ip, + uint8_t flags, uint32_t seq); int zebra_evpn_neigh_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, struct ipaddr *ip, zebra_mac_t *mac); void zebra_evpn_neigh_remote_uninstall(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, zebra_neigh_t *n, - zebra_mac_t *mac, struct ipaddr *ipaddr); -int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, struct ipaddr *ip); + zebra_mac_t *mac, + const struct ipaddr *ipaddr); +int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, const struct ipaddr *ip); #ifdef __cplusplus From 7f7e49d11a9f5d9f8d14387522a612d49f0a5e3f Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Mon, 19 Apr 2021 15:25:27 -0400 Subject: [PATCH 5/8] 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: From 7e5b0b2b360e2d1afa77ada284575286c4c707de Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Tue, 20 Apr 2021 09:14:46 -0400 Subject: [PATCH 6/8] zebra: process EVPN remote VTEP updates from the workqueue Move remote VTEP updates from immediate, inline processing in their ZAPI message handlers to the main workqueue. Signed-off-by: Mark Stapp --- zebra/rib.h | 6 + zebra/zapi_msg.c | 4 +- zebra/zebra_rib.c | 53 +++++++++ zebra/zebra_vxlan.c | 269 ++++++++++++++++++++++++++------------------ zebra/zebra_vxlan.h | 12 +- 5 files changed, 230 insertions(+), 114 deletions(-) diff --git a/zebra/rib.h b/zebra/rib.h index 669cc75248..31d9dfd265 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -470,6 +470,12 @@ int zebra_rib_queue_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr, uint8_t flags, uint32_t seq, struct in_addr vtep_ip, const esi_t *esi); +/* Enqueue VXLAN remote vtep update for processing */ +int zebra_rib_queue_evpn_rem_vtep_add(vrf_id_t vrf_id, vni_t vni, + struct in_addr vtep_ip, + int flood_control); +int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id, vni_t vni, + struct in_addr vtep_ip); extern void meta_queue_free(struct meta_queue *mq); extern int zebra_rib_labeled_unicast(struct route_entry *re); diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 4ef4bc6722..a53e388062 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -3653,8 +3653,8 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = { [ZEBRA_ADVERTISE_ALL_VNI] = zebra_vxlan_advertise_all_vni, [ZEBRA_REMOTE_ES_VTEP_ADD] = zebra_evpn_proc_remote_es, [ZEBRA_REMOTE_ES_VTEP_DEL] = zebra_evpn_proc_remote_es, - [ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add, - [ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del, + [ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add_zapi, + [ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del_zapi, [ZEBRA_REMOTE_MACIP_ADD] = zebra_vxlan_remote_macip_add, [ZEBRA_REMOTE_MACIP_DEL] = zebra_vxlan_remote_macip_del, [ZEBRA_DUPLICATE_ADDR_DETECTION] = zebra_vxlan_dup_addr_detection, diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 5f12c3012d..c51dd759a6 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -157,6 +157,7 @@ struct wq_evpn_wrapper { #define WQ_EVPN_WRAPPER_TYPE_VRFROUTE 0x01 #define WQ_EVPN_WRAPPER_TYPE_REM_ES 0x02 #define WQ_EVPN_WRAPPER_TYPE_REM_MACIP 0x03 +#define WQ_EVPN_WRAPPER_TYPE_REM_VTEP 0x04 /* %pRN is already a printer for route_nodes that just prints the prefix */ #ifdef _FRR_ATTRIBUTE_PRINTFRR @@ -2384,8 +2385,16 @@ static void process_subq_evpn(struct listnode *lnode) else zebra_evpn_rem_macip_del(w->vni, &w->macaddr, ipa_len, &w->ip, w->vtep_ip); + } else if (w->type == WQ_EVPN_WRAPPER_TYPE_REM_VTEP) { + if (w->add_p) + zebra_vxlan_remote_vtep_add(w->vrf_id, w->vni, + w->vtep_ip, w->flags); + else + zebra_vxlan_remote_vtep_del(w->vrf_id, w->vni, + w->vtep_ip); } + XFREE(MTYPE_WQ_WRAPPER, w); } @@ -2881,6 +2890,50 @@ int zebra_rib_queue_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr, return mq_add_handler(w, rib_meta_queue_evpn_add); } +/* + * Enqueue remote VTEP address for processing + */ +int zebra_rib_queue_evpn_rem_vtep_add(vrf_id_t vrf_id, vni_t vni, + struct in_addr vtep_ip, int flood_control) +{ + struct wq_evpn_wrapper *w; + + w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper)); + + w->type = WQ_EVPN_WRAPPER_TYPE_REM_VTEP; + w->add_p = true; + w->vrf_id = vrf_id; + w->vni = vni; + w->vtep_ip = vtep_ip; + w->flags = flood_control; + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__, vrf_id, + &vtep_ip); + + return mq_add_handler(w, rib_meta_queue_evpn_add); +} + +int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id, vni_t vni, + 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_VTEP; + w->add_p = false; + w->vrf_id = vrf_id; + w->vni = vni; + w->vtep_ip = vtep_ip; + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__, vrf_id, + &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 4b96831231..2b46929acb 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -4199,27 +4199,23 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, /* * Handle message from client to delete a remote VTEP for an EVPN. */ -void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS) +void zebra_vxlan_remote_vtep_del_zapi(ZAPI_HANDLER_ARGS) { struct stream *s; unsigned short l = 0; vni_t vni; struct in_addr vtep_ip; - zebra_evpn_t *zevpn; - zebra_vtep_t *zvtep; - struct interface *ifp; - struct zebra_if *zif; if (!is_evpn_enabled()) { zlog_debug( - "%s: EVPN is not enabled yet we have received a vtep del command", + "%s: EVPN is not enabled yet we have received a VTEP DEL msg", __func__); return; } if (!EVPN_ENABLED(zvrf)) { - zlog_debug("Recv MACIP DEL for non-EVPN VRF %u", - zvrf_id(zvrf)); + zlog_debug("Recv VTEP DEL zapi for non-EVPN VRF %u", + zvrf_id(zvrf)); return; } @@ -4239,76 +4235,182 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS) l += 4; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Recv VTEP_DEL %pI4 VNI %u from %s", + zlog_debug("Recv VTEP DEL %pI4 VNI %u from %s", &vtep_ip, vni, zebra_route_string(client->proto)); - /* Locate VNI hash entry - expected to exist. */ - zevpn = zebra_evpn_lookup(vni); - if (!zevpn) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "Failed to locate VNI hash upon remote VTEP DEL, VNI %u", - vni); - continue; - } - - ifp = zevpn->vxlan_if; - if (!ifp) { - zlog_debug( - "VNI %u hash %p doesn't have intf upon remote VTEP DEL", - zevpn->vni, zevpn); - continue; - } - zif = ifp->info; - - /* If down or not mapped to a bridge, we're done. */ - if (!if_is_operative(ifp) || !zif->brslave_info.br_if) - continue; - - /* If the remote VTEP does not exist, there's nothing more to - * do. - * Otherwise, uninstall any remote MACs pointing to this VTEP - * and - * then, the VTEP entry itself and remove it. - */ - zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip); - if (!zvtep) - continue; - - zebra_evpn_vtep_uninstall(zevpn, &vtep_ip); - zebra_evpn_vtep_del(zevpn, zvtep); + /* Enqueue for processing */ + zebra_rib_queue_evpn_rem_vtep_del(zvrf_id(zvrf), vni, vtep_ip); } stream_failure: return; } +/* + * Handle message from client to delete a remote VTEP for an EVPN. + */ +void zebra_vxlan_remote_vtep_del(vrf_id_t vrf_id, vni_t vni, + struct in_addr vtep_ip) +{ + zebra_evpn_t *zevpn; + zebra_vtep_t *zvtep; + struct interface *ifp; + struct zebra_if *zif; + struct zebra_vrf *zvrf; + + if (!is_evpn_enabled()) { + zlog_debug("%s: Can't process vtep del: EVPN is not enabled", + __func__); + return; + } + + zvrf = zebra_vrf_lookup_by_id(vrf_id); + if (!zvrf) + return; + + if (!EVPN_ENABLED(zvrf)) { + zlog_debug("Can't process VTEP DEL for non-EVPN VRF %u", + zvrf_id(zvrf)); + return; + } + + /* Locate VNI hash entry - expected to exist. */ + zevpn = zebra_evpn_lookup(vni); + if (!zevpn) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "Failed to locate VNI hash for remote VTEP DEL, VNI %u", + vni); + return; + } + + ifp = zevpn->vxlan_if; + if (!ifp) { + zlog_debug( + "VNI %u hash %p doesn't have intf upon remote VTEP DEL", + zevpn->vni, zevpn); + return; + } + zif = ifp->info; + + /* If down or not mapped to a bridge, we're done. */ + if (!if_is_operative(ifp) || !zif->brslave_info.br_if) + return; + + /* If the remote VTEP does not exist, there's nothing more to + * do. + * Otherwise, uninstall any remote MACs pointing to this VTEP + * and then, the VTEP entry itself and remove it. + */ + zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip); + if (!zvtep) + return; + + zebra_evpn_vtep_uninstall(zevpn, &vtep_ip); + zebra_evpn_vtep_del(zevpn, zvtep); +} + /* * Handle message from client to add a remote VTEP for an EVPN. */ -void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) +void zebra_vxlan_remote_vtep_add(vrf_id_t vrf_id, vni_t vni, + struct in_addr vtep_ip, int flood_control) +{ + zebra_evpn_t *zevpn; + struct interface *ifp; + struct zebra_if *zif; + zebra_vtep_t *zvtep; + struct zebra_vrf *zvrf; + + if (!is_evpn_enabled()) { + zlog_debug("%s: EVPN not enabled: can't process a VTEP ADD", + __func__); + return; + } + + zvrf = zebra_vrf_lookup_by_id(vrf_id); + if (!zvrf) + return; + + if (!EVPN_ENABLED(zvrf)) { + zlog_debug("Can't process VTEP ADD for non-EVPN VRF %u", + zvrf_id(zvrf)); + return; + } + + /* Locate VNI hash entry - expected to exist. */ + zevpn = zebra_evpn_lookup(vni); + if (!zevpn) { + flog_err( + EC_ZEBRA_VTEP_ADD_FAILED, + "Failed to locate EVPN hash upon remote VTEP ADD, VNI %u", + vni); + return; + } + + ifp = zevpn->vxlan_if; + if (!ifp) { + flog_err( + EC_ZEBRA_VTEP_ADD_FAILED, + "VNI %u hash %p doesn't have intf upon remote VTEP ADD", + zevpn->vni, zevpn); + return; + } + + zif = ifp->info; + + /* If down or not mapped to a bridge, we're done. */ + if (!if_is_operative(ifp) || !zif->brslave_info.br_if) + return; + + zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip); + if (zvtep) { + /* If the remote VTEP already exists check if + * the flood mode has changed + */ + if (zvtep->flood_control != flood_control) { + if (zvtep->flood_control == VXLAN_FLOOD_DISABLED) + /* old mode was head-end-replication but + * is no longer; get rid of the HER fdb + * entry installed before + */ + zebra_evpn_vtep_uninstall(zevpn, &vtep_ip); + zvtep->flood_control = flood_control; + zebra_evpn_vtep_install(zevpn, zvtep); + } + } else { + zvtep = zebra_evpn_vtep_add(zevpn, &vtep_ip, flood_control); + if (zvtep) + zebra_evpn_vtep_install(zevpn, zvtep); + else + flog_err(EC_ZEBRA_VTEP_ADD_FAILED, + "Failed to add remote VTEP, VNI %u zevpn %p", + vni, zevpn); + } +} + +/* + * Handle message from client to add a remote VTEP for an EVPN. + */ +void zebra_vxlan_remote_vtep_add_zapi(ZAPI_HANDLER_ARGS) { struct stream *s; unsigned short l = 0; vni_t vni; struct in_addr vtep_ip; - zebra_evpn_t *zevpn; - struct interface *ifp; - struct zebra_if *zif; int flood_control; - zebra_vtep_t *zvtep; if (!is_evpn_enabled()) { zlog_debug( - "%s: EVPN not enabled yet we received a vtep_add zapi call", + "%s: EVPN not enabled yet we received a VTEP ADD zapi msg", __func__); return; } if (!EVPN_ENABLED(zvrf)) { - zlog_debug("Recv MACIP ADD for non-EVPN VRF %u", - zvrf_id(zvrf)); + zlog_debug("Recv VTEP ADD zapi for non-EVPN VRF %u", + zvrf_id(zvrf)); return; } @@ -4323,62 +4425,13 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) l += IPV4_MAX_BYTELEN + 4; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Recv VTEP_ADD %pI4 VNI %u flood %d from %s", - &vtep_ip, vni, flood_control, - zebra_route_string(client->proto)); + zlog_debug("Recv VTEP ADD %pI4 VNI %u flood %d from %s", + &vtep_ip, vni, flood_control, + zebra_route_string(client->proto)); - /* Locate VNI hash entry - expected to exist. */ - zevpn = zebra_evpn_lookup(vni); - if (!zevpn) { - flog_err( - EC_ZEBRA_VTEP_ADD_FAILED, - "Failed to locate EVPN hash upon remote VTEP ADD, VNI %u", - vni); - continue; - } - - ifp = zevpn->vxlan_if; - if (!ifp) { - flog_err( - EC_ZEBRA_VTEP_ADD_FAILED, - "VNI %u hash %p doesn't have intf upon remote VTEP ADD", - zevpn->vni, zevpn); - continue; - } - - zif = ifp->info; - - /* If down or not mapped to a bridge, we're done. */ - if (!if_is_operative(ifp) || !zif->brslave_info.br_if) - continue; - - zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip); - if (zvtep) { - /* If the remote VTEP already exists check if - * the flood mode has changed - */ - if (zvtep->flood_control != flood_control) { - if (zvtep->flood_control - == VXLAN_FLOOD_DISABLED) - /* old mode was head-end-replication but - * is no longer; get rid of the HER fdb - * entry installed before - */ - zebra_evpn_vtep_uninstall(zevpn, - &vtep_ip); - zvtep->flood_control = flood_control; - zebra_evpn_vtep_install(zevpn, zvtep); - } - } else { - zvtep = zebra_evpn_vtep_add(zevpn, &vtep_ip, - flood_control); - if (zvtep) - zebra_evpn_vtep_install(zevpn, zvtep); - else - flog_err(EC_ZEBRA_VTEP_ADD_FAILED, - "Failed to add remote VTEP, VNI %u zevpn %p", - vni, zevpn); - } + /* Enqueue for processing */ + zebra_rib_queue_evpn_rem_vtep_add(zvrf_id(zvrf), vni, vtep_ip, + flood_control); } stream_failure: @@ -4393,7 +4446,7 @@ stream_failure: * 3. vrr interface (MACVLAN) associated to a SVI * We advertise macip routes for an interface if it is associated to VxLan vlan */ -int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, +int zebra_vxlan_add_del_gw_macip(struct interface *ifp, const struct prefix *p, int add) { struct ipaddr ip; diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 24de8ff04e..915e987b6b 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -72,8 +72,12 @@ is_vxlan_flooding_head_end(void) /* ZAPI message handlers */ extern void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS); extern void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS); -extern void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS); -extern void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS); +extern void zebra_vxlan_remote_vtep_add_zapi(ZAPI_HANDLER_ARGS); +extern void zebra_vxlan_remote_vtep_del_zapi(ZAPI_HANDLER_ARGS); +void zebra_vxlan_remote_vtep_add(vrf_id_t vrf_id, vni_t vni, + struct in_addr vtep_ip, int flood_control); +extern void zebra_vxlan_remote_vtep_del(vrf_id_t vrf_id, vni_t vni, + struct in_addr vtep_ip); extern void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS); extern void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS); extern void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS); @@ -157,8 +161,8 @@ extern void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json); extern void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json); extern void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf, json_object *json_vrfs); -extern int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, - int add); +extern int zebra_vxlan_add_del_gw_macip(struct interface *ifp, + const struct prefix *p, int add); extern int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if); extern int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if); From b747851a5d4ec314a8a6cac52d86ff3f463ee1d2 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Thu, 22 Apr 2021 14:32:57 -0400 Subject: [PATCH 7/8] tests: skip tests after errors in bgp-evpn-vxlan In bgp-evpn-vxlan, skip test cases if there's been a failure; a couple of cases were missing this. Signed-off-by: Mark Stapp --- .../topotests/bgp_evpn_vxlan_topo1/test_bgp_evpn_vxlan.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/topotests/bgp_evpn_vxlan_topo1/test_bgp_evpn_vxlan.py b/tests/topotests/bgp_evpn_vxlan_topo1/test_bgp_evpn_vxlan.py index 086bad6481..fd5bb38b98 100755 --- a/tests/topotests/bgp_evpn_vxlan_topo1/test_bgp_evpn_vxlan.py +++ b/tests/topotests/bgp_evpn_vxlan_topo1/test_bgp_evpn_vxlan.py @@ -365,6 +365,10 @@ def test_ip_pe1_learn(): "run the IP learn test for PE1" tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + host1 = tgen.gears["host1"] pe1 = tgen.gears["PE1"] pe2 = tgen.gears["PE2"] @@ -380,6 +384,10 @@ def test_ip_pe2_learn(): "run the IP learn test for PE2" tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + host2 = tgen.gears["host2"] pe1 = tgen.gears["PE1"] pe2 = tgen.gears["PE2"] From 80ff3f05ea3eef4e72ef6d2520cfc4bfae82a4cb Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Thu, 22 Apr 2021 14:59:29 -0400 Subject: [PATCH 8/8] zebra: replace ipaddr2str in dplane module Replace a couple of ipaddr2str calls with pIA in the dplane module. Signed-off-by: Mark Stapp --- zebra/zebra_dplane.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 04411fa0d2..1217ed915a 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -3640,14 +3640,10 @@ enum zebra_dplane_result dplane_neigh_ip_update(enum dplane_op_e op, uint16_t state = 0; uint32_t update_flags; - if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) { - char buf1[PREFIX_STRLEN], buf2[PREFIX_STRLEN]; + if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) + zlog_debug("%s: init link ctx %s: ifp %s, link_ip %pIA ip %pIA", + __func__, dplane_op2str(op), ifp->name, link_ip, ip); - ipaddr2str(link_ip, buf1, sizeof(buf1)); - ipaddr2str(ip, buf2, sizeof(buf2)); - zlog_debug("init link ctx %s: ifp %s, ip %s link %s", - dplane_op2str(op), ifp->name, buf1, buf2); - } if (ndm_state == ZEBRA_NEIGH_STATE_REACHABLE) state = DPLANE_NUD_REACHABLE; else if (ndm_state == ZEBRA_NEIGH_STATE_FAILED)