diff options
| author | Sharath Ramamurthy <sramamurthy@nvidia.com> | 2021-07-27 13:40:48 +0530 | 
|---|---|---|
| committer | Stephen Worley <sworley@nvidia.com> | 2023-02-13 18:12:04 -0500 | 
| commit | 0adeb5fdf46fe23a85924d04f2f02ee0be3cce6a (patch) | |
| tree | aa5d70622d9f3a621a1669dce5d5ca0c188c1bc1 | |
| parent | b95ce8fadbceea40639224d59bfcc0a2679f5604 (diff) | |
zebra: vxlan interface refactoring changes
This change refactors the zebra_vxlan_if related functionality
to a new zebra_vxlan_if.c file. zebra_vxlan_if_up/down,
zebra_vxlan_if_add/update/del is moved zebra_vxlan_if.c
Signed-off-by: Sharath Ramamurthy <sramamurthy@nvidia.com>
| -rw-r--r-- | zebra/subdir.am | 1 | ||||
| -rw-r--r-- | zebra/zebra_evpn.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_evpn_mac.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_evpn_mh.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_evpn_neigh.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_l2.c | 5 | ||||
| -rw-r--r-- | zebra/zebra_nb_state.c | 1 | ||||
| -rw-r--r-- | zebra/zebra_vxlan.c | 505 | ||||
| -rw-r--r-- | zebra/zebra_vxlan_if.c | 554 | ||||
| -rw-r--r-- | zebra/zebra_vxlan_if.h | 55 | ||||
| -rw-r--r-- | zebra/zebra_vxlan_private.h | 2 | 
11 files changed, 621 insertions, 510 deletions
diff --git a/zebra/subdir.am b/zebra/subdir.am index 5c4a87b934..104980218d 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -105,6 +105,7 @@ zebra_zebra_SOURCES = \  	zebra/zebra_vrf.c \  	zebra/zebra_vty.c \  	zebra/zebra_vxlan.c \ +	zebra/zebra_vxlan_if.c \  	zebra/zebra_evpn_mh.c \  	zebra/zebra_neigh.c \  	zebra/zserv.c \ diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index 0bf6039693..6f2765284b 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -47,10 +47,10 @@  #include "zebra/zebra_ns.h"  #include "zebra/zebra_vrf.h"  #include "zebra/zebra_vxlan.h" +#include "zebra/zebra_vxlan_private.h"  #include "zebra/zebra_evpn.h"  #include "zebra/zebra_evpn_mac.h"  #include "zebra/zebra_evpn_neigh.h" -#include "zebra/zebra_vxlan_private.h"  #include "zebra/zebra_evpn_mh.h"  #include "zebra/zebra_evpn_vxlan.h"  #include "zebra/zebra_router.h" diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index 4babbe97cd..801403c11c 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -36,6 +36,8 @@  #include "zebra/zebra_router.h"  #include "zebra/zebra_errors.h"  #include "zebra/zebra_vrf.h" +#include "zebra/zebra_vxlan.h" +#include "zebra/zebra_vxlan_if.h"  #include "zebra/zebra_evpn.h"  #include "zebra/zebra_evpn_mh.h"  #include "zebra/zebra_evpn_mac.h" diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 9d672ab51d..a2a0952165 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -44,9 +44,9 @@  #include "zebra/zebra_ns.h"  #include "zebra/zebra_vrf.h"  #include "zebra/zebra_vxlan.h" +#include "zebra/zebra_vxlan_private.h"  #include "zebra/zebra_evpn.h"  #include "zebra/zebra_evpn_mac.h" -#include "zebra/zebra_vxlan_private.h"  #include "zebra/zebra_router.h"  #include "zebra/zebra_evpn_mh.h"  #include "zebra/zebra_nhg.h" diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c index 684720bb4d..4c7f393fa1 100644 --- a/zebra/zebra_evpn_neigh.c +++ b/zebra/zebra_evpn_neigh.c @@ -36,6 +36,8 @@  #include "zebra/rt.h"  #include "zebra/zebra_errors.h"  #include "zebra/zebra_vrf.h" +#include "zebra/zebra_vxlan.h" +#include "zebra/zebra_vxlan_if.h"  #include "zebra/zebra_evpn.h"  #include "zebra/zebra_evpn_mh.h"  #include "zebra/zebra_evpn_neigh.h" diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c index 550b819428..e1de9a147a 100644 --- a/zebra/zebra_l2.c +++ b/zebra/zebra_l2.c @@ -43,6 +43,7 @@  #include "zebra/interface.h"  #include "zebra/zebra_l2.h"  #include "zebra/zebra_vxlan.h" +#include "zebra/zebra_vxlan_if.h"  #include "zebra/zebra_evpn_mh.h"  /* definitions */ @@ -349,8 +350,6 @@ void zebra_l2_vxlanif_add_update(struct interface *ifp,  	if (add) {  		memcpy(&zif->l2info.vxl, vxlan_info, sizeof(*vxlan_info)); -		zebra_evpn_vl_vxl_ref(zif->l2info.vxl.vni_info.vni.access_vlan, -				      zif->l2info.vxl.vni_info.vni.vni, zif);  		zebra_vxlan_if_add(ifp);  		return;  	} @@ -415,8 +414,6 @@ void zebra_l2_vxlanif_del(struct interface *ifp)  	zif = ifp->info;  	assert(zif); -	zebra_evpn_vl_vxl_deref(zif->l2info.vxl.vni_info.vni.access_vlan, -				zif->l2info.vxl.vni_info.vni.vni, zif);  	zebra_vxlan_if_del(ifp);  } diff --git a/zebra/zebra_nb_state.c b/zebra/zebra_nb_state.c index 0c0bd56383..45b9d440a6 100644 --- a/zebra/zebra_nb_state.c +++ b/zebra/zebra_nb_state.c @@ -26,6 +26,7 @@  #include "zebra/debug.h"  #include "printfrr.h"  #include "zebra/zebra_vxlan.h" +#include "zebra/zebra_vxlan_if.h"  /*   * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/up-count diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 79f696c97d..28ffafec5a 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -907,7 +907,7 @@ struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)  	return tmp_if;  } -static int zebra_evpn_vxlan_del(struct zebra_evpn *zevpn) +int zebra_evpn_vxlan_del(struct zebra_evpn *zevpn)  {  	zevpn_vxlan_if_set(zevpn, zevpn->vxlan_if, false /* set */); @@ -4797,509 +4797,6 @@ void zebra_vxlan_macvlan_up(struct interface *ifp)  	}  } -/* - * Handle VxLAN interface down - */ -int zebra_vxlan_if_down(struct interface *ifp) -{ -	vni_t vni; -	struct zebra_if *zif = NULL; -	struct zebra_l3vni *zl3vni = NULL; -	struct zebra_evpn *zevpn; -	struct zebra_vxlan_vni *vnip; - -	/* Check if EVPN is enabled. */ -	if (!is_evpn_enabled()) -		return 0; - -	zif = ifp->info; -	assert(zif); -	vnip = zebra_vxlan_if_vni_find(zif, 0); -	vni = vnip->vni; - -	zl3vni = zl3vni_lookup(vni); -	if (zl3vni) { -		/* process-if-down for l3-vni */ -		if (IS_ZEBRA_DEBUG_VXLAN) -			zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp->name, -				   ifp->ifindex, vni); - -		zebra_vxlan_process_l3vni_oper_down(zl3vni); -	} else { -		/* process if-down for l2-vni */ -		if (IS_ZEBRA_DEBUG_VXLAN) -			zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp->name, -				   ifp->ifindex, vni); - -		/* Locate hash entry; it is expected to exist. */ -		zevpn = zebra_evpn_lookup(vni); -		if (!zevpn) { -			zlog_debug( -				"Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u", -				ifp->name, ifp->ifindex, vni); -			return -1; -		} - -		assert(zevpn->vxlan_if == ifp); - -		/* remove from l3-vni list */ -		zl3vni = zl3vni_from_vrf(zevpn->vrf_id); -		if (zl3vni) -			listnode_delete(zl3vni->l2vnis, zevpn); - -		/* Delete this VNI from BGP. */ -		zebra_evpn_send_del_to_client(zevpn); - -		/* Free up all neighbors and MACs, if any. */ -		zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH); -		zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC); - -		/* Free up all remote VTEPs, if any. */ -		zebra_evpn_vtep_del_all(zevpn, 1); -	} -	return 0; -} - -/* - * Handle VxLAN interface up - update BGP if required. - */ -int zebra_vxlan_if_up(struct interface *ifp) -{ -	vni_t vni; -	struct zebra_if *zif = NULL; -	struct zebra_evpn *zevpn = NULL; -	struct zebra_l3vni *zl3vni = NULL; -	struct zebra_vxlan_vni *vnip; - -	/* Check if EVPN is enabled. */ -	if (!is_evpn_enabled()) -		return 0; - -	zif = ifp->info; -	assert(zif); -	vnip = zebra_vxlan_if_vni_find(zif, 0); -	vni = vnip->vni; - -	zl3vni = zl3vni_lookup(vni); -	if (zl3vni) { -		/* we need to associate with SVI, if any, we can associate with -		 * svi-if only after association with vxlan-intf is complete -		 */ -		zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni); -		zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni); - -		if (IS_ZEBRA_DEBUG_VXLAN) -			zlog_debug("Intf %s(%u) L3-VNI %u is UP svi_if %s mac_vlan_if %s" -				, ifp->name, ifp->ifindex, vni, -				zl3vni->svi_if ? zl3vni->svi_if->name : "NIL", -				zl3vni->mac_vlan_if ? -				zl3vni->mac_vlan_if->name : "NIL"); - -		if (is_l3vni_oper_up(zl3vni)) -			zebra_vxlan_process_l3vni_oper_up(zl3vni); -	} else { -		/* Handle L2-VNI add */ -		struct interface *vlan_if = NULL; - -		if (IS_ZEBRA_DEBUG_VXLAN) -			zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp->name, -				   ifp->ifindex, vni); - -		/* Locate hash entry; it is expected to exist. */ -		zevpn = zebra_evpn_lookup(vni); -		if (!zevpn) { -			zlog_debug( -				"Failed to locate EVPN hash at UP, IF %s(%u) VNI %u", -				ifp->name, ifp->ifindex, vni); -			return -1; -		} - -		assert(zevpn->vxlan_if == ifp); -		vlan_if = zvni_map_to_svi(vnip->access_vlan, -					  zif->brslave_info.br_if); -		if (vlan_if) { -			zevpn->svi_if = vlan_if; -			zevpn->vrf_id = vlan_if->vrf->vrf_id; -			zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id); -			if (zl3vni) -				listnode_add_sort_nodup(zl3vni->l2vnis, zevpn); -		} - -		/* If part of a bridge, inform BGP about this VNI. */ -		/* Also, read and populate local MACs and neighbors. */ -		if (zif->brslave_info.br_if) { -			zebra_evpn_send_add_to_client(zevpn); -			zebra_evpn_read_mac_neigh(zevpn, ifp); -		} -	} - -	return 0; -} - -/* - * Handle VxLAN interface delete. Locate and remove entry in hash table - * and update BGP, if required. - */ -int zebra_vxlan_if_del(struct interface *ifp) -{ -	vni_t vni; -	struct zebra_if *zif = NULL; -	struct zebra_evpn *zevpn = NULL; -	struct zebra_l3vni *zl3vni = NULL; -	struct zebra_vxlan_vni *vnip; - -	/* Check if EVPN is enabled. */ -	if (!is_evpn_enabled()) -		return 0; - -	zif = ifp->info; -	assert(zif); -	vnip = zebra_vxlan_if_vni_find(zif, 0); -	vni = vnip->vni; - -	zl3vni = zl3vni_lookup(vni); -	if (zl3vni) { - -		if (IS_ZEBRA_DEBUG_VXLAN) -			zlog_debug("Del L3-VNI %u intf %s(%u)", vni, ifp->name, -				   ifp->ifindex); - -		/* process oper-down for l3-vni */ -		zebra_vxlan_process_l3vni_oper_down(zl3vni); - -		/* remove the association with vxlan_if */ -		memset(&zl3vni->local_vtep_ip, 0, sizeof(struct in_addr)); -		zl3vni->vxlan_if = NULL; -	} else { - -		/* process if-del for l2-vni*/ -		if (IS_ZEBRA_DEBUG_VXLAN) -			zlog_debug("Del L2-VNI %u intf %s(%u)", vni, ifp->name, -				   ifp->ifindex); - -		/* Locate hash entry; it is expected to exist. */ -		zevpn = zebra_evpn_lookup(vni); -		if (!zevpn) { -			zlog_debug( -				"Failed to locate VNI hash at del, IF %s(%u) VNI %u", -				ifp->name, ifp->ifindex, vni); -			return 0; -		} - -		/* remove from l3-vni list */ -		zl3vni = zl3vni_from_vrf(zevpn->vrf_id); -		if (zl3vni) -			listnode_delete(zl3vni->l2vnis, zevpn); -		/* Delete VNI from BGP. */ -		zebra_evpn_send_del_to_client(zevpn); - -		/* Free up all neighbors and MAC, if any. */ -		zebra_evpn_neigh_del_all(zevpn, 0, 0, DEL_ALL_NEIGH); -		zebra_evpn_mac_del_all(zevpn, 0, 0, DEL_ALL_MAC); - -		/* Free up all remote VTEPs, if any. */ -		zebra_evpn_vtep_del_all(zevpn, 0); - -		/* Delete the hash entry. */ -		if (zebra_evpn_vxlan_del(zevpn)) { -			flog_err(EC_ZEBRA_VNI_DEL_FAILED, -				 "Failed to del EVPN hash %p, IF %s(%u) VNI %u", -				 zevpn, ifp->name, ifp->ifindex, zevpn->vni); -			return -1; -		} -	} -	return 0; -} - -/* - * Handle VxLAN interface update - change to tunnel IP, master or VLAN. - */ -int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags) -{ -	vni_t vni; -	struct zebra_if *zif = NULL; -	struct zebra_l2info_vxlan *vxl = NULL; -	struct zebra_evpn *zevpn = NULL; -	struct zebra_l3vni *zl3vni = NULL; -	struct interface *vlan_if = NULL; -	struct zebra_vxlan_vni *vnip; - -	/* Check if EVPN is enabled. */ -	if (!is_evpn_enabled()) -		return 0; - -	zif = ifp->info; -	assert(zif); -	vnip = zebra_vxlan_if_vni_find(zif, 0); -	vni = vnip->vni; - -	zl3vni = zl3vni_lookup(vni); -	if (zl3vni) { - -		if (IS_ZEBRA_DEBUG_VXLAN) -			zlog_debug( -				"Update L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x", -				vni, ifp->name, ifp->ifindex, vnip->access_vlan, -				&vxl->vtep_ip, zif->brslave_info.bridge_ifindex, -				chgflags); - -		/* Removed from bridge? Cleanup and return */ -		if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE) -		    && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) { -			zebra_vxlan_process_l3vni_oper_down(zl3vni); -			return 0; -		} - -		if ((chgflags & ZEBRA_VXLIF_MASTER_MAC_CHANGE) -		    && if_is_operative(ifp) && is_l3vni_oper_up(zl3vni)) { -			zebra_vxlan_process_l3vni_oper_down(zl3vni); -			zebra_vxlan_process_l3vni_oper_up(zl3vni); -			return 0; -		} - -		/* access-vlan change - process oper down, associate with new -		 * svi_if and then process oper up again -		 */ -		if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) { -			if (if_is_operative(ifp)) { -				zebra_vxlan_process_l3vni_oper_down(zl3vni); -				zl3vni->svi_if = NULL; -				zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni); -				zl3vni->mac_vlan_if = -					zl3vni_map_to_mac_vlan_if(zl3vni); -				zl3vni->local_vtep_ip = vxl->vtep_ip; -				if (is_l3vni_oper_up(zl3vni)) -					zebra_vxlan_process_l3vni_oper_up( -						zl3vni); -			} -		} - -		/* -		 * local-ip change - process oper down, associate with new -		 * local-ip and then process oper up again -		 */ -		if (chgflags & ZEBRA_VXLIF_LOCAL_IP_CHANGE) { -			if (if_is_operative(ifp)) { -				zebra_vxlan_process_l3vni_oper_down(zl3vni); -				zl3vni->local_vtep_ip = vxl->vtep_ip; -				if (is_l3vni_oper_up(zl3vni)) -					zebra_vxlan_process_l3vni_oper_up( -						zl3vni); -			} -		} - -		/* Update local tunnel IP. */ -		zl3vni->local_vtep_ip = vxl->vtep_ip; - -		/* if we have a valid new master, process l3-vni oper up */ -		if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) { -			if (if_is_operative(ifp) && is_l3vni_oper_up(zl3vni)) -				zebra_vxlan_process_l3vni_oper_up(zl3vni); -		} -	} else { - -		/* Update VNI hash. */ -		zevpn = zebra_evpn_lookup(vni); -		if (!zevpn) { -			zlog_debug( -				"Failed to find EVPN hash on update, IF %s(%u) VNI %u", -				ifp->name, ifp->ifindex, vni); -			return -1; -		} - -		if (IS_ZEBRA_DEBUG_VXLAN) -			zlog_debug( -				"Update L2-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x", -				vni, ifp->name, ifp->ifindex, vnip->access_vlan, -				&vxl->vtep_ip, zif->brslave_info.bridge_ifindex, -				chgflags); - -		/* Removed from bridge? Cleanup and return */ -		if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE) -		    && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) { -			/* Delete from client, remove all remote VTEPs */ -			/* Also, free up all MACs and neighbors. */ -			zevpn->svi_if = NULL; -			zebra_evpn_send_del_to_client(zevpn); -			zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH); -			zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC); -			zebra_evpn_vtep_del_all(zevpn, 1); -			return 0; -		} - -		/* Handle other changes. */ -		if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) { -			/* Remove all existing local neigh and MACs for this VNI -			 * (including from BGP) -			 */ -			zebra_evpn_neigh_del_all(zevpn, 0, 1, DEL_LOCAL_MAC); -			zebra_evpn_mac_del_all(zevpn, 0, 1, DEL_LOCAL_MAC); -		} - -		if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr -		    || zevpn->mcast_grp.s_addr != vnip->mcast_grp.s_addr) { -			zebra_vxlan_sg_deref(zevpn->local_vtep_ip, -				zevpn->mcast_grp); -			zebra_vxlan_sg_ref(vxl->vtep_ip, vnip->mcast_grp); -			zevpn->local_vtep_ip = vxl->vtep_ip; -			zevpn->mcast_grp = vnip->mcast_grp; -			/* on local vtep-ip check if ES orig-ip -			 * needs to be updated -			 */ -			zebra_evpn_es_set_base_evpn(zevpn); -		} -		zevpn_vxlan_if_set(zevpn, ifp, true /* set */); -		vlan_if = zvni_map_to_svi(vnip->access_vlan, -					  zif->brslave_info.br_if); -		if (vlan_if) { -			zevpn->svi_if = vlan_if; -			zevpn->vrf_id = vlan_if->vrf->vrf_id; -			zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id); -			if (zl3vni) -				listnode_add_sort_nodup(zl3vni->l2vnis, zevpn); -		} - -		/* Take further actions needed. -		 * Note that if we are here, there is a change of interest. -		 */ -		/* If down or not mapped to a bridge, we're done. */ -		if (!if_is_operative(ifp) || !zif->brslave_info.br_if) -			return 0; - -		/* Inform BGP, if there is a change of interest. */ -		if (chgflags & -		    (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE | -		     ZEBRA_VXLIF_MCAST_GRP_CHANGE | ZEBRA_VXLIF_VLAN_CHANGE)) -			zebra_evpn_send_add_to_client(zevpn); - -		/* If there is a valid new master or a VLAN mapping change, -		 * read and populate local MACs and neighbors. -		 * Also, reinstall any remote MACs and neighbors -		 * for this VNI (based on new VLAN). -		 */ -		if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) -			zebra_evpn_read_mac_neigh(zevpn, ifp); -		else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) { -			struct mac_walk_ctx m_wctx; -			struct neigh_walk_ctx n_wctx; - -			zebra_evpn_read_mac_neigh(zevpn, ifp); - -			memset(&m_wctx, 0, sizeof(m_wctx)); -			m_wctx.zevpn = zevpn; -			hash_iterate(zevpn->mac_table, -				     zebra_evpn_install_mac_hash, &m_wctx); - -			memset(&n_wctx, 0, sizeof(n_wctx)); -			n_wctx.zevpn = zevpn; -			hash_iterate(zevpn->neigh_table, -				     zebra_evpn_install_neigh_hash, &n_wctx); -		} -	} - -	return 0; -} - -/* - * Handle VxLAN interface add. - */ -int zebra_vxlan_if_add(struct interface *ifp) -{ -	vni_t vni; -	struct zebra_if *zif = NULL; -	struct zebra_l2info_vxlan *vxl = NULL; -	struct zebra_evpn *zevpn = NULL; -	struct zebra_l3vni *zl3vni = NULL; -	struct zebra_vxlan_vni *vnip; - -	/* Check if EVPN is enabled. */ -	if (!is_evpn_enabled()) -		return 0; - -	zif = ifp->info; -	assert(zif); -	vnip = zebra_vxlan_if_vni_find(zif, 0); -	vni = vnip->vni; - -	zl3vni = zl3vni_lookup(vni); -	if (zl3vni) { - -		/* process if-add for l3-vni*/ -		if (IS_ZEBRA_DEBUG_VXLAN) -			zlog_debug( -				"Add L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u", -				vni, ifp->name, ifp->ifindex, vnip->access_vlan, -				&vxl->vtep_ip, -				zif->brslave_info.bridge_ifindex); - -		/* associate with vxlan_if */ -		zl3vni->local_vtep_ip = vxl->vtep_ip; -		zl3vni->vxlan_if = ifp; - -		/* Associate with SVI, if any. We can associate with svi-if only -		 * after association with vxlan_if is complete */ -		zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni); - -		zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni); - -		if (is_l3vni_oper_up(zl3vni)) -			zebra_vxlan_process_l3vni_oper_up(zl3vni); -	} else { - -		/* process if-add for l2-vni */ -		struct interface *vlan_if = NULL; - -		/* Create or update EVPN hash. */ -		zevpn = zebra_evpn_lookup(vni); -		if (!zevpn) -			zevpn = zebra_evpn_add(vni); - -		if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr -		    || zevpn->mcast_grp.s_addr != vnip->mcast_grp.s_addr) { -			zebra_vxlan_sg_deref(zevpn->local_vtep_ip, -				zevpn->mcast_grp); -			zebra_vxlan_sg_ref(vxl->vtep_ip, vnip->mcast_grp); -			zevpn->local_vtep_ip = vxl->vtep_ip; -			zevpn->mcast_grp = vnip->mcast_grp; -			/* on local vtep-ip check if ES orig-ip -			 * needs to be updated -			 */ -			zebra_evpn_es_set_base_evpn(zevpn); -		} -		zevpn_vxlan_if_set(zevpn, ifp, true /* set */); -		vlan_if = zvni_map_to_svi(vnip->access_vlan, -					  zif->brslave_info.br_if); -		if (vlan_if) { -			zevpn->svi_if = vlan_if; -			zevpn->vrf_id = vlan_if->vrf->vrf_id; -			zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id); -			if (zl3vni) -				listnode_add_sort_nodup(zl3vni->l2vnis, zevpn); -		} - -		if (IS_ZEBRA_DEBUG_VXLAN) -			zlog_debug( -				"Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %pI4 mcast_grp %pI4 master %u", -				vni, -				vlan_if ? vlan_if->vrf->name : VRF_DEFAULT_NAME, -				ifp->name, ifp->ifindex, vnip->access_vlan, -				&vxl->vtep_ip, &vnip->mcast_grp, -				zif->brslave_info.bridge_ifindex); - -		/* If down or not mapped to a bridge, we're done. */ -		if (!if_is_operative(ifp) || !zif->brslave_info.br_if) -			return 0; - -		/* Inform BGP */ -		zebra_evpn_send_add_to_client(zevpn); - -		/* Read and populate local MACs and neighbors */ -		zebra_evpn_read_mac_neigh(zevpn, ifp); -	} - -	return 0; -} -  int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,  				    char *err, int err_str_sz, int filter,  				    int add) diff --git a/zebra/zebra_vxlan_if.c b/zebra/zebra_vxlan_if.c new file mode 100644 index 0000000000..eb01547fcc --- /dev/null +++ b/zebra/zebra_vxlan_if.c @@ -0,0 +1,554 @@ +/* + * Zebra EVPN for VxLAN interface handling + * + * Copyright (C) 2020 Cumulus Networks, Inc. + * Vivek Venkatraman, Stephen Worley, Sharath Ramamurthy + * + * This file is part of FRR. + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + */ + +#include <zebra.h> + +#include "hash.h" +#include "if.h" +#include "jhash.h" +#include "linklist.h" +#include "log.h" +#include "memory.h" +#include "prefix.h" +#include "stream.h" +#include "table.h" +#include "vlan.h" +#include "vxlan.h" +#ifdef GNU_LINUX +#include <linux/neighbour.h> +#endif + +#include "zebra/zebra_router.h" +#include "zebra/debug.h" +#include "zebra/interface.h" +#include "zebra/rib.h" +#include "zebra/rt.h" +#include "zebra/rt_netlink.h" +#include "zebra/zebra_errors.h" +#include "zebra/zebra_l2.h" +#include "zebra/zebra_ns.h" +#include "zebra/zebra_vrf.h" +#include "zebra/zebra_vxlan.h" +#include "zebra/zebra_vxlan_if.h" +#include "zebra/zebra_evpn.h" +#include "zebra/zebra_evpn_mac.h" +#include "zebra/zebra_evpn_neigh.h" +#include "zebra/zebra_vxlan_private.h" +#include "zebra/zebra_evpn_mh.h" +#include "zebra/zebra_evpn_vxlan.h" +#include "zebra/zebra_router.h" + +/* + * Handle VxLAN interface down + */ +int zebra_vxlan_if_down(struct interface *ifp) +{ +	vni_t vni; +	struct zebra_if *zif = NULL; +	struct zebra_l3vni *zl3vni = NULL; +	struct zebra_evpn *zevpn; +	struct zebra_vxlan_vni *vnip; + +	/* Check if EVPN is enabled. */ +	if (!is_evpn_enabled()) +		return 0; + +	zif = ifp->info; +	assert(zif); +	vnip = zebra_vxlan_if_vni_find(zif, 0); +	vni = vnip->vni; + +	zl3vni = zl3vni_lookup(vni); +	if (zl3vni) { +		/* process-if-down for l3-vni */ +		if (IS_ZEBRA_DEBUG_VXLAN) +			zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp->name, +				   ifp->ifindex, vni); + +		zebra_vxlan_process_l3vni_oper_down(zl3vni); +	} else { +		/* process if-down for l2-vni */ +		if (IS_ZEBRA_DEBUG_VXLAN) +			zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp->name, +				   ifp->ifindex, vni); + +		/* Locate hash entry; it is expected to exist. */ +		zevpn = zebra_evpn_lookup(vni); +		if (!zevpn) { +			zlog_debug( +				"Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u", +				ifp->name, ifp->ifindex, vni); +			return -1; +		} + +		assert(zevpn->vxlan_if == ifp); + +		/* remove from l3-vni list */ +		zl3vni = zl3vni_from_vrf(zevpn->vrf_id); +		if (zl3vni) +			listnode_delete(zl3vni->l2vnis, zevpn); + +		/* Delete this VNI from BGP. */ +		zebra_evpn_send_del_to_client(zevpn); + +		/* Free up all neighbors and MACs, if any. */ +		zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH); +		zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC); + +		/* Free up all remote VTEPs, if any. */ +		zebra_evpn_vtep_del_all(zevpn, 1); +	} +	return 0; +} + +/* + * Handle VxLAN interface up - update BGP if required. + */ +int zebra_vxlan_if_up(struct interface *ifp) +{ +	vni_t vni; +	struct zebra_if *zif = NULL; +	struct zebra_evpn *zevpn = NULL; +	struct zebra_l3vni *zl3vni = NULL; +	struct zebra_vxlan_vni *vnip; + +	/* Check if EVPN is enabled. */ +	if (!is_evpn_enabled()) +		return 0; + +	zif = ifp->info; +	assert(zif); +	vnip = zebra_vxlan_if_vni_find(zif, 0); +	vni = vnip->vni; + +	zl3vni = zl3vni_lookup(vni); +	if (zl3vni) { +		/* we need to associate with SVI, if any, we can associate with +		 * svi-if only after association with vxlan-intf is complete +		 */ +		zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni); +		zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni); + +		if (IS_ZEBRA_DEBUG_VXLAN) +			zlog_debug( +				"Intf %s(%u) L3-VNI %u is UP svi_if %s mac_vlan_if %s", +				ifp->name, ifp->ifindex, vni, +				zl3vni->svi_if ? zl3vni->svi_if->name : "NIL", +				zl3vni->mac_vlan_if ? zl3vni->mac_vlan_if->name +						    : "NIL"); + +		if (is_l3vni_oper_up(zl3vni)) +			zebra_vxlan_process_l3vni_oper_up(zl3vni); +	} else { +		/* Handle L2-VNI add */ +		struct interface *vlan_if = NULL; + +		if (IS_ZEBRA_DEBUG_VXLAN) +			zlog_debug("Intf %s(%u) L2-VNI %u is UP", ifp->name, +				   ifp->ifindex, vni); + +		/* Locate hash entry; it is expected to exist. */ +		zevpn = zebra_evpn_lookup(vni); +		if (!zevpn) { +			zlog_debug( +				"Failed to locate EVPN hash at UP, IF %s(%u) VNI %u", +				ifp->name, ifp->ifindex, vni); +			return -1; +		} + +		assert(zevpn->vxlan_if == ifp); +		vlan_if = zvni_map_to_svi(vnip->access_vlan, +					  zif->brslave_info.br_if); +		if (vlan_if) { +			zevpn->svi_if = vlan_if; +			zevpn->vrf_id = vlan_if->vrf->vrf_id; +			zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id); +			if (zl3vni) +				listnode_add_sort_nodup(zl3vni->l2vnis, zevpn); +		} + +		/* If part of a bridge, inform BGP about this VNI. */ +		/* Also, read and populate local MACs and neighbors. */ +		if (zif->brslave_info.br_if) { +			zebra_evpn_send_add_to_client(zevpn); +			zebra_evpn_read_mac_neigh(zevpn, ifp); +		} +	} + +	return 0; +} + +/* + * Handle VxLAN interface delete. Locate and remove entry in hash table + * and update BGP, if required. + */ +int zebra_vxlan_if_del(struct interface *ifp) +{ +	vni_t vni; +	struct zebra_if *zif = NULL; +	struct zebra_evpn *zevpn = NULL; +	struct zebra_l3vni *zl3vni = NULL; +	struct zebra_vxlan_vni *vnip; + +	/* Check if EVPN is enabled. */ +	if (!is_evpn_enabled()) +		return 0; + +	zif = ifp->info; +	assert(zif); +	vnip = zebra_vxlan_if_vni_find(zif, 0); +	vni = vnip->vni; + +	zl3vni = zl3vni_lookup(vni); +	if (zl3vni) { + +		if (IS_ZEBRA_DEBUG_VXLAN) +			zlog_debug("Del L3-VNI %u intf %s(%u)", vni, ifp->name, +				   ifp->ifindex); + +		/* process oper-down for l3-vni */ +		zebra_vxlan_process_l3vni_oper_down(zl3vni); + +		/* remove the association with vxlan_if */ +		memset(&zl3vni->local_vtep_ip, 0, sizeof(struct in_addr)); +		zl3vni->vxlan_if = NULL; +	} else { + +		/* process if-del for l2-vni*/ +		if (IS_ZEBRA_DEBUG_VXLAN) +			zlog_debug("Del L2-VNI %u intf %s(%u)", vni, ifp->name, +				   ifp->ifindex); + +		/* Locate hash entry; it is expected to exist. */ +		zevpn = zebra_evpn_lookup(vni); +		if (!zevpn) { +			zlog_debug( +				"Failed to locate VNI hash at del, IF %s(%u) VNI %u", +				ifp->name, ifp->ifindex, vni); +			return 0; +		} + +		/* remove from l3-vni list */ +		zl3vni = zl3vni_from_vrf(zevpn->vrf_id); +		if (zl3vni) +			listnode_delete(zl3vni->l2vnis, zevpn); +		/* Delete VNI from BGP. */ +		zebra_evpn_send_del_to_client(zevpn); + +		/* Free up all neighbors and MAC, if any. */ +		zebra_evpn_neigh_del_all(zevpn, 0, 0, DEL_ALL_NEIGH); +		zebra_evpn_mac_del_all(zevpn, 0, 0, DEL_ALL_MAC); + +		/* Free up all remote VTEPs, if any. */ +		zebra_evpn_vtep_del_all(zevpn, 0); + +		/* Delete the hash entry. */ +		if (zebra_evpn_vxlan_del(zevpn)) { +			flog_err(EC_ZEBRA_VNI_DEL_FAILED, +				 "Failed to del EVPN hash %p, IF %s(%u) VNI %u", +				 zevpn, ifp->name, ifp->ifindex, zevpn->vni); +			return -1; +		} +	} +	return 0; +} + +/* + * Handle VxLAN interface update - change to tunnel IP, master or VLAN. + */ +int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags) +{ +	vni_t vni; +	struct zebra_if *zif = NULL; +	struct zebra_l2info_vxlan *vxl = NULL; +	struct zebra_evpn *zevpn = NULL; +	struct zebra_l3vni *zl3vni = NULL; +	struct interface *vlan_if = NULL; +	struct zebra_vxlan_vni *vnip; + +	/* Check if EVPN is enabled. */ +	if (!is_evpn_enabled()) +		return 0; + +	zif = ifp->info; +	assert(zif); +	vnip = zebra_vxlan_if_vni_find(zif, 0); +	vni = vnip->vni; + +	zl3vni = zl3vni_lookup(vni); +	if (zl3vni) { + +		if (IS_ZEBRA_DEBUG_VXLAN) +			zlog_debug( +				"Update L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x", +				vni, ifp->name, ifp->ifindex, vnip->access_vlan, +				&vxl->vtep_ip, zif->brslave_info.bridge_ifindex, +				chgflags); + +		/* Removed from bridge? Cleanup and return */ +		if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE) +		    && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) { +			zebra_vxlan_process_l3vni_oper_down(zl3vni); +			return 0; +		} + +		if ((chgflags & ZEBRA_VXLIF_MASTER_MAC_CHANGE) +		    && if_is_operative(ifp) && is_l3vni_oper_up(zl3vni)) { +			zebra_vxlan_process_l3vni_oper_down(zl3vni); +			zebra_vxlan_process_l3vni_oper_up(zl3vni); +			return 0; +		} + +		/* access-vlan change - process oper down, associate with new +		 * svi_if and then process oper up again +		 */ +		if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) { +			if (if_is_operative(ifp)) { +				zebra_vxlan_process_l3vni_oper_down(zl3vni); +				zl3vni->svi_if = NULL; +				zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni); +				zl3vni->mac_vlan_if = +					zl3vni_map_to_mac_vlan_if(zl3vni); +				zl3vni->local_vtep_ip = vxl->vtep_ip; +				if (is_l3vni_oper_up(zl3vni)) +					zebra_vxlan_process_l3vni_oper_up( +						zl3vni); +			} +		} + +		/* +		 * local-ip change - process oper down, associate with new +		 * local-ip and then process oper up again +		 */ +		if (chgflags & ZEBRA_VXLIF_LOCAL_IP_CHANGE) { +			if (if_is_operative(ifp)) { +				zebra_vxlan_process_l3vni_oper_down(zl3vni); +				zl3vni->local_vtep_ip = vxl->vtep_ip; +				if (is_l3vni_oper_up(zl3vni)) +					zebra_vxlan_process_l3vni_oper_up( +						zl3vni); +			} +		} + +		/* Update local tunnel IP. */ +		zl3vni->local_vtep_ip = vxl->vtep_ip; + +		/* if we have a valid new master, process l3-vni oper up */ +		if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) { +			if (if_is_operative(ifp) && is_l3vni_oper_up(zl3vni)) +				zebra_vxlan_process_l3vni_oper_up(zl3vni); +		} +	} else { + +		/* Update VNI hash. */ +		zevpn = zebra_evpn_lookup(vni); +		if (!zevpn) { +			zlog_debug( +				"Failed to find EVPN hash on update, IF %s(%u) VNI %u", +				ifp->name, ifp->ifindex, vni); +			return -1; +		} + +		if (IS_ZEBRA_DEBUG_VXLAN) +			zlog_debug( +				"Update L2-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x", +				vni, ifp->name, ifp->ifindex, vnip->access_vlan, +				&vxl->vtep_ip, zif->brslave_info.bridge_ifindex, +				chgflags); + +		/* Removed from bridge? Cleanup and return */ +		if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE) +		    && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) { +			/* Delete from client, remove all remote VTEPs */ +			/* Also, free up all MACs and neighbors. */ +			zevpn->svi_if = NULL; +			zebra_evpn_send_del_to_client(zevpn); +			zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH); +			zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC); +			zebra_evpn_vtep_del_all(zevpn, 1); +			return 0; +		} + +		/* Handle other changes. */ +		if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) { +			/* Remove all existing local neigh and MACs for this VNI +			 * (including from BGP) +			 */ +			zebra_evpn_neigh_del_all(zevpn, 0, 1, DEL_LOCAL_MAC); +			zebra_evpn_mac_del_all(zevpn, 0, 1, DEL_LOCAL_MAC); +		} + +		if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr +		    || zevpn->mcast_grp.s_addr != vnip->mcast_grp.s_addr) { +			zebra_vxlan_sg_deref(zevpn->local_vtep_ip, +				zevpn->mcast_grp); +			zebra_vxlan_sg_ref(vxl->vtep_ip, vnip->mcast_grp); +			zevpn->local_vtep_ip = vxl->vtep_ip; +			zevpn->mcast_grp = vnip->mcast_grp; +			/* on local vtep-ip check if ES orig-ip +			 * needs to be updated +			 */ +			zebra_evpn_es_set_base_evpn(zevpn); +		} +		zevpn_vxlan_if_set(zevpn, ifp, true /* set */); +		vlan_if = zvni_map_to_svi(vnip->access_vlan, +					  zif->brslave_info.br_if); +		if (vlan_if) +			zevpn->svi_if = vlan_if; + +		/* Take further actions needed. +		 * Note that if we are here, there is a change of interest. +		 */ +		/* If down or not mapped to a bridge, we're done. */ +		if (!if_is_operative(ifp) || !zif->brslave_info.br_if) +			return 0; + +		/* Inform BGP, if there is a change of interest. */ +		if (chgflags & +		    (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE | +		     ZEBRA_VXLIF_MCAST_GRP_CHANGE | ZEBRA_VXLIF_VLAN_CHANGE)) +			zebra_evpn_send_add_to_client(zevpn); + +		/* If there is a valid new master or a VLAN mapping change, +		 * read and populate local MACs and neighbors. +		 * Also, reinstall any remote MACs and neighbors +		 * for this VNI (based on new VLAN). +		 */ +		if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) +			zebra_evpn_read_mac_neigh(zevpn, ifp); +		else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) { +			struct mac_walk_ctx m_wctx; +			struct neigh_walk_ctx n_wctx; + +			zebra_evpn_read_mac_neigh(zevpn, ifp); + +			memset(&m_wctx, 0, sizeof(m_wctx)); +			m_wctx.zevpn = zevpn; +			hash_iterate(zevpn->mac_table, +				     zebra_evpn_install_mac_hash, &m_wctx); + +			memset(&n_wctx, 0, sizeof(n_wctx)); +			n_wctx.zevpn = zevpn; +			hash_iterate(zevpn->neigh_table, +				     zebra_evpn_install_neigh_hash, &n_wctx); +		} +	} + +	return 0; +} + +/* + * Handle VxLAN interface add. + */ +int zebra_vxlan_if_add(struct interface *ifp) +{ +	vni_t vni; +	struct zebra_if *zif = NULL; +	struct zebra_l2info_vxlan *vxl = NULL; +	struct zebra_evpn *zevpn = NULL; +	struct zebra_l3vni *zl3vni = NULL; +	struct zebra_vxlan_vni *vnip; + +	/* Check if EVPN is enabled. */ +	if (!is_evpn_enabled()) +		return 0; + +	zif = ifp->info; +	assert(zif); +	vnip = zebra_vxlan_if_vni_find(zif, 0); +	vni = vnip->vni; + +	zl3vni = zl3vni_lookup(vni); +	if (zl3vni) { + +		/* process if-add for l3-vni*/ +		if (IS_ZEBRA_DEBUG_VXLAN) +			zlog_debug( +				"Add L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u", +				vni, ifp->name, ifp->ifindex, vnip->access_vlan, +				&vxl->vtep_ip, +				zif->brslave_info.bridge_ifindex); + +		/* associate with vxlan_if */ +		zl3vni->local_vtep_ip = vxl->vtep_ip; +		zl3vni->vxlan_if = ifp; + +		/* Associate with SVI, if any. We can associate with svi-if only +		 * after association with vxlan_if is complete */ +		zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni); + +		zl3vni->mac_vlan_if = zl3vni_map_to_mac_vlan_if(zl3vni); + +		if (is_l3vni_oper_up(zl3vni)) +			zebra_vxlan_process_l3vni_oper_up(zl3vni); +	} else { + +		/* process if-add for l2-vni */ +		struct interface *vlan_if = NULL; + +		/* Create or update EVPN hash. */ +		zevpn = zebra_evpn_lookup(vni); +		if (!zevpn) +			zevpn = zebra_evpn_add(vni); + +		if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr +		    || zevpn->mcast_grp.s_addr != vnip->mcast_grp.s_addr) { +			zebra_vxlan_sg_deref(zevpn->local_vtep_ip, +				zevpn->mcast_grp); +			zebra_vxlan_sg_ref(vxl->vtep_ip, vnip->mcast_grp); +			zevpn->local_vtep_ip = vxl->vtep_ip; +			zevpn->mcast_grp = vnip->mcast_grp; +			/* on local vtep-ip check if ES orig-ip +			 * needs to be updated +			 */ +			zebra_evpn_es_set_base_evpn(zevpn); +		} +		zevpn_vxlan_if_set(zevpn, ifp, true /* set */); +		vlan_if = zvni_map_to_svi(vnip->access_vlan, +					  zif->brslave_info.br_if); +		if (vlan_if) { +			zevpn->svi_if = vlan_if; +			zevpn->vrf_id = vlan_if->vrf->vrf_id; +			zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id); +			if (zl3vni) +				listnode_add_sort_nodup(zl3vni->l2vnis, zevpn); +		} + +		if (IS_ZEBRA_DEBUG_VXLAN) +			zlog_debug( +				"Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %pI4 mcast_grp %pI4 master %u", +				vni, +				vlan_if ? vlan_if->vrf->name : VRF_DEFAULT_NAME, +				ifp->name, ifp->ifindex, vnip->access_vlan, +				&vxl->vtep_ip, &vnip->mcast_grp, +				zif->brslave_info.bridge_ifindex); + +		/* If down or not mapped to a bridge, we're done. */ +		if (!if_is_operative(ifp) || !zif->brslave_info.br_if) +			return 0; + +		/* Inform BGP */ +		zebra_evpn_send_add_to_client(zevpn); + +		/* Read and populate local MACs and neighbors */ +		zebra_evpn_read_mac_neigh(zevpn, ifp); +	} + +	return 0; +} diff --git a/zebra/zebra_vxlan_if.h b/zebra/zebra_vxlan_if.h new file mode 100644 index 0000000000..721e2b87ad --- /dev/null +++ b/zebra/zebra_vxlan_if.h @@ -0,0 +1,55 @@ +/* + * Zebra VxLAN (EVPN) Data structures and definitions + * These are public definitions referenced by other files. + * Copyright (C) 2021 Cumulus Networks, Inc. + * Sharath Ramamurthy + * + * This file is part of FRR. + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FRR; see the file COPYING.  If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _ZEBRA_VXLAN_IF_H +#define _ZEBRA_VXLAN_IF_H + +#include <zebra.h> +#include <zebra/zebra_router.h> + +#include "linklist.h" +#include "if.h" +#include "vlan.h" +#include "vxlan.h" + +#include "lib/json.h" +#include "zebra/zebra_vrf.h" +#include "zebra/zserv.h" +#include "zebra/zebra_dplane.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern int zebra_vxlan_if_down(struct interface *ifp); +extern int zebra_vxlan_if_up(struct interface *ifp); +extern int zebra_vxlan_if_del(struct interface *ifp); +extern int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags); +extern int zebra_vxlan_if_add(struct interface *ifp); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZEBRA_VXLAN_IF_H */ diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h index 9161348b16..6da45b214e 100644 --- a/zebra/zebra_vxlan_private.h +++ b/zebra/zebra_vxlan_private.h @@ -29,6 +29,7 @@  #include "if.h"  #include "linklist.h"  #include "zebra_vxlan.h" +#include "zebra_vxlan_if.h"  #include "zebra_evpn.h"  #include "zebra_evpn_mac.h" @@ -266,5 +267,6 @@ extern void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip,  				 struct in_addr mcast_grp);  extern void zebra_vxlan_process_l3vni_oper_up(struct zebra_l3vni *zl3vni);  extern void zebra_vxlan_process_l3vni_oper_down(struct zebra_l3vni *zl3vni); +extern int zebra_evpn_vxlan_del(struct zebra_evpn *zevpn);  #endif /* _ZEBRA_VXLAN_PRIVATE_H */  | 
