summaryrefslogtreecommitdiff
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/if_netlink.c32
-rw-r--r--zebra/kernel_socket.c12
-rw-r--r--zebra/redistribute.c6
-rw-r--r--zebra/rib.h45
-rw-r--r--zebra/rt.h4
-rw-r--r--zebra/rt_netlink.c14
-rw-r--r--zebra/rt_netlink.h5
-rw-r--r--zebra/rtread_netlink.c6
-rw-r--r--zebra/rtread_sysctl.c4
-rw-r--r--zebra/subdir.am12
-rw-r--r--zebra/zapi_msg.c20
-rw-r--r--zebra/zebra_dplane.c10
-rw-r--r--zebra/zebra_evpn.c29
-rw-r--r--zebra/zebra_evpn.h10
-rw-r--r--zebra/zebra_evpn_mac.c44
-rw-r--r--zebra/zebra_evpn_mac.h42
-rw-r--r--zebra/zebra_evpn_mh.c23
-rw-r--r--zebra/zebra_evpn_mh.h9
-rw-r--r--zebra/zebra_evpn_neigh.c44
-rw-r--r--zebra/zebra_evpn_neigh.h36
-rw-r--r--zebra/zebra_mpls.c34
-rw-r--r--zebra/zebra_mpls.h6
-rw-r--r--zebra/zebra_nhg.c9
-rw-r--r--zebra/zebra_rib.c403
-rw-r--r--zebra/zebra_rnh.c3
-rw-r--r--zebra/zebra_rnh.h3
-rw-r--r--zebra/zebra_vrf.h1
-rw-r--r--zebra/zebra_vxlan.c282
-rw-r--r--zebra/zebra_vxlan.h12
-rw-r--r--zebra/zserv.c2
30 files changed, 820 insertions, 342 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index c2b4dcc52f..a51e0b82cb 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -706,6 +706,9 @@ static int netlink_bridge_vxlan_update(struct interface *ifp,
struct bridge_vlan_info *vinfo;
vlanid_t access_vlan;
+ if (!af_spec)
+ return 0;
+
/* There is a 1-to-1 mapping of VLAN to VxLAN - hence
* only 1 access VLAN is accepted.
*/
@@ -742,23 +745,26 @@ static void netlink_bridge_vlan_update(struct interface *ifp,
/* create a new bitmap space for re-eval */
bf_init(zif->vlan_bitmap, IF_VLAN_BITMAP_MAX);
- for (i = RTA_DATA(af_spec), rem = RTA_PAYLOAD(af_spec);
- RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
+ if (af_spec) {
+ for (i = RTA_DATA(af_spec), rem = RTA_PAYLOAD(af_spec);
+ RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
- if (i->rta_type != IFLA_BRIDGE_VLAN_INFO)
- continue;
+ if (i->rta_type != IFLA_BRIDGE_VLAN_INFO)
+ continue;
- vinfo = RTA_DATA(i);
+ vinfo = RTA_DATA(i);
- if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
- vid_range_start = vinfo->vid;
- continue;
- }
+ if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
+ vid_range_start = vinfo->vid;
+ continue;
+ }
- if (!(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END))
- vid_range_start = vinfo->vid;
+ if (!(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END))
+ vid_range_start = vinfo->vid;
- zebra_vlan_bitmap_compute(ifp, vid_range_start, vinfo->vid);
+ zebra_vlan_bitmap_compute(ifp, vid_range_start,
+ vinfo->vid);
+ }
}
zebra_vlan_mbr_re_eval(ifp, old_vlan_bitmap);
@@ -794,8 +800,6 @@ static int netlink_bridge_interface(struct nlmsghdr *h, int len, ns_id_t ns_id,
/* We are only interested in the access VLAN i.e., AF_SPEC */
af_spec = tb[IFLA_AF_SPEC];
- if (!af_spec)
- return 0;
if (IS_ZEBRA_IF_VXLAN(ifp))
return netlink_bridge_vxlan_update(ifp, af_spec);
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 252bf04782..5c060ac6f8 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -849,8 +849,8 @@ int ifam_read(struct ifa_msghdr *ifam)
bool dest_same = false;
char ifname[INTERFACE_NAMSIZ];
short ifnlen = 0;
- char isalias = 0;
- int flags = 0;
+ bool isalias = false;
+ uint32_t flags = 0;
ifname[0] = ifname[INTERFACE_NAMSIZ - 1] = '\0';
@@ -865,7 +865,13 @@ int ifam_read(struct ifa_msghdr *ifam)
}
if (ifnlen && strncmp(ifp->name, ifname, INTERFACE_NAMSIZ))
- isalias = 1;
+ isalias = true;
+
+ /*
+ * Mark the alias prefixes as secondary
+ */
+ if (isalias)
+ SET_FLAG(flags, ZEBRA_IFA_SECONDARY);
/* N.B. The info in ifa_msghdr does not tell us whether the RTA_BRD
field contains a broadcast address or a peer address, so we are
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 89f46f9c97..26f6d404e9 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -153,10 +153,16 @@ static bool zebra_redistribute_check(const struct route_entry *re,
struct zserv *client,
const struct prefix *p, int afi)
{
+ struct zebra_vrf *zvrf;
+
/* Process only if there is valid re */
if (!re)
return false;
+ zvrf = vrf_info_lookup(re->vrf_id);
+ if (re->vrf_id == VRF_DEFAULT && zvrf->table_id != re->table)
+ return false;
+
/* If default route and redistributed */
if (is_default_prefix(p)
&& vrf_bitmap_check(client->redist_default[afi], re->vrf_id))
diff --git a/zebra/rib.h b/zebra/rib.h
index b7ffb9ce8d..31d9dfd265 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,36 @@ 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);
+/* 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);
+/* 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);
extern struct route_table *rib_table_ipv6;
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/subdir.am b/zebra/subdir.am
index 70d8c4005d..731f0c9ad1 100644
--- a/zebra/subdir.am
+++ b/zebra/subdir.am
@@ -196,14 +196,14 @@ zebra_zebra_irdp_la_SOURCES = \
zebra/irdp_main.c \
zebra/irdp_packet.c \
# end
-zebra_zebra_irdp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
+zebra_zebra_irdp_la_LDFLAGS = $(MODULE_LDFLAGS)
zebra_zebra_snmp_la_SOURCES = zebra/zebra_snmp.c
zebra_zebra_snmp_la_CFLAGS = $(AM_CFLAGS) $(SNMP_CFLAGS) -std=gnu11
-zebra_zebra_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
+zebra_zebra_snmp_la_LDFLAGS = $(MODULE_LDFLAGS)
zebra_zebra_snmp_la_LIBADD = lib/libfrrsnmp.la
-zebra_zebra_fpm_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
+zebra_zebra_fpm_la_LDFLAGS = $(MODULE_LDFLAGS)
zebra_zebra_fpm_la_LIBADD =
zebra_zebra_fpm_la_SOURCES = zebra/zebra_fpm.c
zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_netlink.c
@@ -220,7 +220,7 @@ endif
# Sample dataplane plugin
if DEV_BUILD
zebra_dplane_sample_plugin_la_SOURCES = zebra/sample_plugin.c
-zebra_dplane_sample_plugin_la_LDFLAGS = -module -shared -avoid-version -export-dynamic
+zebra_dplane_sample_plugin_la_LDFLAGS = $(MODULE_LDFLAGS)
endif
nodist_zebra_zebra_SOURCES = \
@@ -229,13 +229,13 @@ nodist_zebra_zebra_SOURCES = \
# end
zebra_zebra_cumulus_mlag_la_SOURCES = zebra/zebra_mlag_private.c
-zebra_zebra_cumulus_mlag_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
+zebra_zebra_cumulus_mlag_la_LDFLAGS = $(MODULE_LDFLAGS)
if LINUX
module_LTLIBRARIES += zebra/dplane_fpm_nl.la
zebra_dplane_fpm_nl_la_SOURCES = zebra/dplane_fpm_nl.c
-zebra_dplane_fpm_nl_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
+zebra_dplane_fpm_nl_la_LDFLAGS = $(MODULE_LDFLAGS)
zebra_dplane_fpm_nl_la_LIBADD =
vtysh_scan += zebra/dplane_fpm_nl.c
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index d760432eb1..27fb5d7c22 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -682,6 +682,8 @@ static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client,
stream_put_in_addr(s, &addr);
if (re) {
+ struct nexthop_group *nhg;
+
stream_putc(s, re->distance);
stream_putl(s, re->metric);
num = 0;
@@ -689,15 +691,11 @@ static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client,
nump = stream_get_endp(s);
/* reserve room for nexthop_num */
stream_putc(s, 0);
- /*
- * Only non-recursive routes are elegible to resolve the
- * nexthop we are looking up. Therefore, we will just iterate
- * over the top chain of nexthops.
- */
- for (nexthop = re->nhe->nhg.nexthop; nexthop;
- nexthop = nexthop->next)
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ nhg = rib_get_fib_nhg(re);
+ for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
+ if (rnh_nexthop_valid(re, nexthop))
num += zserv_encode_nexthop(s, nexthop);
+ }
/* store nexthop_num */
stream_putc_at(s, nump, num);
@@ -3109,6 +3107,8 @@ static void zread_vrf_label(ZAPI_HANDLER_ARGS)
}
zvrf->label[afi] = nlabel;
+ zvrf->label_proto[afi] = client->proto;
+
stream_failure:
return;
}
@@ -3659,8 +3659,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_dplane.c b/zebra/zebra_dplane.c
index 8e88a73512..2a30fc6eef 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -3656,14 +3656,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)
diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c
index 816f46bac9..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 process_remote_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;
@@ -1447,18 +1449,19 @@ 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,
- 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 ee9e1406e4..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 process_remote_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 process_remote_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 fe3167dc29..cf2aa67269 100644
--- a/zebra/zebra_evpn_mac.c
+++ b/zebra/zebra_evpn_mac.c
@@ -986,8 +986,9 @@ 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 +1096,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 +1256,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 +1272,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 +1306,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 +1566,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 +1630,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;
@@ -1958,11 +1960,13 @@ 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,
+ 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 +2131,7 @@ int process_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 +2451,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 fb162f1a93..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 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,
+ 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 d6ae92a03d..05947faf4f 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:
@@ -2542,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;
@@ -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..a828056f1f 100644
--- a/zebra/zebra_evpn_mh.h
+++ b/zebra/zebra_evpn_mh.h
@@ -330,14 +330,17 @@ 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);
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);
+ 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);
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 4c7a1542fc..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;
@@ -2046,10 +2048,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,
+ 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;
@@ -2240,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)
@@ -2273,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;
@@ -2298,7 +2302,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_evpn_neigh.h b/zebra/zebra_evpn_neigh.h
index 05156c1255..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);
@@ -266,16 +268,18 @@ 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,
+ 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
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index a2d1513ce4..66d2d6b4ba 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -3932,6 +3932,40 @@ void zebra_mpls_cleanup_tables(struct zebra_vrf *zvrf)
}
/*
+ * When a vrf label is assigned and the client goes away
+ * we should cleanup the vrf labels associated with
+ * that zclient.
+ */
+void zebra_mpls_client_cleanup_vrf_label(uint8_t proto)
+{
+ struct vrf *vrf;
+ struct zebra_vrf *def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
+
+ if (def_zvrf == NULL)
+ return;
+
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
+ struct zebra_vrf *zvrf = vrf->info;
+ afi_t afi;
+
+ if (!zvrf)
+ continue;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+ if (zvrf->label_proto[afi] == proto
+ && zvrf->label[afi] != MPLS_LABEL_NONE)
+ lsp_uninstall(def_zvrf, zvrf->label[afi]);
+
+ /*
+ * Cleanup data structures by fiat
+ */
+ zvrf->label_proto[afi] = 0;
+ zvrf->label[afi] = MPLS_LABEL_NONE;
+ }
+ }
+}
+
+/*
* Called upon process exiting, need to delete LSP forwarding
* entries from the kernel.
* NOTE: Currently supported only for default VRF.
diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
index 7059d393ed..5195b2f14f 100644
--- a/zebra/zebra_mpls.h
+++ b/zebra/zebra_mpls.h
@@ -416,6 +416,12 @@ void zebra_mpls_init(void);
*/
void zebra_mpls_vty_init(void);
+/*
+ * When cleaning up a client connection ensure that there are no
+ * vrf labels that need cleaning up too
+ */
+void zebra_mpls_client_cleanup_vrf_label(uint8_t proto);
+
/* Inline functions. */
/*
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index af86263a16..46d5164127 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -453,8 +453,13 @@ static void *zebra_nhg_hash_alloc(void *arg)
/* Mark duplicate nexthops in a group at creation time. */
nexthop_group_mark_duplicates(&(nhe->nhg));
- /* Add the ifp now if it's not a group or recursive and has ifindex */
- if (nhe->nhg.nexthop && nhe->nhg.nexthop->ifindex) {
+ /*
+ * Add the ifp now if it's not a group or recursive and has ifindex.
+ *
+ * A proto-owned ID is always a group.
+ */
+ if (!PROTO_OWNED(nhe) && nhe->nhg.nexthop && !nhe->nhg.nexthop->next
+ && !nhe->nhg.nexthop->resolved && nhe->nhg.nexthop->ifindex) {
struct interface *ifp = NULL;
ifp = if_lookup_by_index(nhe->nhg.nexthop->ifindex,
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 12cc0b4e8a..c51dd759a6 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,29 @@ 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;
+ uint32_t flags;
+ uint32_t seq;
+ esi_t esi;
+ vni_t vni;
+ struct ipaddr ip;
+ 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_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
#pragma FRR printfrr_ext "%pZN" (struct route_node *)
@@ -2316,6 +2343,62 @@ done:
}
/*
+ * 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->macaddr,
+ &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);
+ } 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);
+ } 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);
+}
+
+/*
* Process the nexthop-group workqueue subqueue
*/
static void process_subq_nhg(struct listnode *lnode)
@@ -2355,8 +2438,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 +2450,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 +2493,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 +2504,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 +2516,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 +2622,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 +2648,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 +2663,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 +2732,225 @@ 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->macaddr = *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);
+}
+
+/*
+ * 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);
+}
+
+/*
+ * 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)
+{
+ 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 +2967,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 +2999,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 +3076,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 +3831,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);
}
}
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 41d55c2e6c..017a4aae7f 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -598,8 +598,7 @@ static const int RNH_INVALID_NH_FLAGS = (NEXTHOP_FLAG_RECURSIVE |
NEXTHOP_FLAG_DUPLICATE |
NEXTHOP_FLAG_RNH_FILTERED);
-static bool rnh_nexthop_valid(const struct route_entry *re,
- const struct nexthop *nh)
+bool rnh_nexthop_valid(const struct route_entry *re, const struct nexthop *nh)
{
return (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)
&& CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE)
diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h
index 4897a6af30..24ee6d0bd9 100644
--- a/zebra/zebra_rnh.h
+++ b/zebra/zebra_rnh.h
@@ -64,6 +64,9 @@ extern void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty,
extern int rnh_resolve_via_default(struct zebra_vrf *zvrf, int family);
+extern bool rnh_nexthop_valid(const struct route_entry *re,
+ const struct nexthop *nh);
+
/* UI control to avoid notifications if backup nexthop status changes */
void rnh_set_hide_backups(bool hide_p);
bool rnh_get_hide_backups(void);
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index 57dd0c20ad..f32f09850b 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -105,6 +105,7 @@ struct zebra_vrf {
/* MPLS Label to handle L3VPN <-> vrf popping */
mpls_label_t label[AFI_MAX];
+ uint8_t label_proto[AFI_MAX];
/* MPLS static LSP config table */
struct hash *slsp_table;
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 2f3ea7475a..1660792221 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -366,8 +366,6 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
buf1, sizeof(buf1)));
json_object_int_add(json, "refCount",
rb_host_count(&zrmac->host_rb));
- json_object_int_add(json, "localSequence", zrmac->loc_seq);
- json_object_int_add(json, "remoteSequence", zrmac->rem_seq);
RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb)
json_object_array_add(
json_hosts,
@@ -3820,10 +3818,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 +3838,8 @@ 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);
+ /* Enqueue to workqueue for processing */
+ zebra_rib_queue_evpn_rem_macip_del(vni, &macaddr, &ip, vtep_ip);
}
stream_failure:
@@ -3870,10 +3865,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 +3873,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 +3899,9 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
zebra_route_string(client->proto));
}
- process_remote_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:
@@ -4204,27 +4197,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;
}
@@ -4244,76 +4233,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;
- }
+ /* Enqueue for processing */
+ zebra_rib_queue_evpn_rem_vtep_del(zvrf_id(zvrf), vni, vtep_ip);
+ }
- ifp = zevpn->vxlan_if;
- if (!ifp) {
+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(
- "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
- zevpn->vni, zevpn);
- continue;
- }
- zif = ifp->info;
+ "Failed to locate VNI hash for remote VTEP DEL, VNI %u",
+ vni);
+ return;
+ }
- /* If down or not mapped to a bridge, we're done. */
- if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
- continue;
+ 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 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;
+ /* 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);
+ 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(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;
}
-stream_failure:
- 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_HANDLER_ARGS)
+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;
}
@@ -4328,62 +4423,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));
-
- /* 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;
+ zlog_debug("Recv VTEP ADD %pI4 VNI %u flood %d from %s",
+ &vtep_ip, vni, flood_control,
+ zebra_route_string(client->proto));
- 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:
@@ -4398,7 +4444,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);
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 1d94fcae6b..e4a48093f7 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -595,6 +595,8 @@ static void zserv_client_free(struct zserv *client)
close(client->sock);
if (DYNAMIC_CLIENT_GR_DISABLED(client)) {
+ zebra_mpls_client_cleanup_vrf_label(client->proto);
+
nroutes = rib_score_proto(client->proto,
client->instance);
zlog_notice(