diff options
| author | Tuetuopay <tuetuopay@me.com> | 2019-03-06 19:09:25 +0100 | 
|---|---|---|
| committer | Tuetuopay <tuetuopay@me.com> | 2019-03-19 11:56:14 +0100 | 
| commit | e2f3a930c54c13c3174d6641fe4e6ee159966bd1 (patch) | |
| tree | bdfc8e5bff81c5ba50c6b83cf37a6e434553bf65 | |
| parent | 0ff3b1118b3fe59859c2f6c9286f1756ba5f775d (diff) | |
bgpd: Allow non-default instance to be EVPN one
This makes the instance bearing the advertise-all-vni config option
register to zebra as the EVPN one, forwarding it the option.
Signed-off-by: Tuetuopay <tuetuopay@me.com>
Sponsored-by: Scaleway
| -rw-r--r-- | bgpd/bgp_evpn.h | 2 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_vty.c | 11 | ||||
| -rw-r--r-- | bgpd/bgp_main.c | 7 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 14 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 37 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 5 | 
6 files changed, 65 insertions, 11 deletions
diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index fbf30083e1..bcc524d5aa 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -31,7 +31,7 @@ static inline int is_evpn_enabled(void)  {  	struct bgp *bgp = NULL; -	bgp = bgp_get_default(); +	bgp = bgp_get_evpn();  	return bgp ? bgp->advertise_all_vni : 0;  } diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 8437c4024e..9ac1af046a 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -2757,6 +2757,7 @@ static void evpn_unset_advertise_subnet(struct bgp *bgp, struct bgpevpn *vpn)  static void evpn_set_advertise_all_vni(struct bgp *bgp)  {  	bgp->advertise_all_vni = 1; +	bgp_set_evpn(bgp);  	bgp_zebra_advertise_all_vni(bgp, bgp->advertise_all_vni);  } @@ -2767,6 +2768,7 @@ static void evpn_set_advertise_all_vni(struct bgp *bgp)  static void evpn_unset_advertise_all_vni(struct bgp *bgp)  {  	bgp->advertise_all_vni = 0; +	bgp_set_evpn(bgp_get_default());  	bgp_zebra_advertise_all_vni(bgp, bgp->advertise_all_vni);  	bgp_evpn_cleanup_on_disable(bgp);  } @@ -2954,9 +2956,18 @@ DEFUN (bgp_evpn_advertise_all_vni,         "Advertise All local VNIs\n")  {  	struct bgp *bgp = VTY_GET_CONTEXT(bgp); +	struct bgp *bgp_evpn = NULL;  	if (!bgp)  		return CMD_WARNING; + +	bgp_evpn = bgp_get_evpn(); +	if (bgp_evpn && bgp_evpn != bgp) { +		vty_out(vty, "%% Please unconfigure EVPN in VRF %s\n", +			bgp_evpn->name); +		return CMD_WARNING_CONFIG_FAILED; +	} +  	evpn_set_advertise_all_vni(bgp);  	return CMD_SUCCESS;  } diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 47e7c1686f..697889cc6b 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -171,7 +171,7 @@ void sigusr1(void)  */  static __attribute__((__noreturn__)) void bgp_exit(int status)  { -	struct bgp *bgp, *bgp_default; +	struct bgp *bgp, *bgp_default, *bgp_evpn;  	struct listnode *node, *nnode;  	/* it only makes sense for this to be called on a clean exit */ @@ -184,13 +184,16 @@ static __attribute__((__noreturn__)) void bgp_exit(int status)  	bgp_close();  	bgp_default = bgp_get_default(); +	bgp_evpn = bgp_get_evpn();  	/* reverse bgp_master_init */  	for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { -		if (bgp_default == bgp) +		if (bgp_default == bgp || bgp_evpn == bgp)  			continue;  		bgp_delete(bgp);  	} +	if (bgp_evpn && bgp_evpn != bgp_default) +		bgp_delete(bgp_evpn);  	if (bgp_default)  		bgp_delete(bgp_default); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 5f0b20e029..398735d7a4 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1632,7 +1632,7 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,  			return CMD_WARNING;  #if ENABLE_BGP_VNC -		if (bgp->vrf_id == VRF_DEFAULT +		if (bgp->advertise_all_vni  		    && type == ZEBRA_ROUTE_VNC_DIRECT) {  			vnc_export_bgp_enable(  				bgp, afi); /* only enables if mode bits cfg'd */ @@ -1794,7 +1794,7 @@ int bgp_redistribute_unset(struct bgp *bgp, afi_t afi, int type,   * status. red lookup fails if there is no zebra connection.   */  #if ENABLE_BGP_VNC -	if (bgp->vrf_id == VRF_DEFAULT && type == ZEBRA_ROUTE_VNC_DIRECT) { +	if (bgp->advertise_all_vni && type == ZEBRA_ROUTE_VNC_DIRECT) {  		vnc_export_bgp_disable(bgp, afi);  	}  #endif @@ -1861,9 +1861,8 @@ void bgp_zebra_instance_register(struct bgp *bgp)  	/* Register for router-id, interfaces, redistributed routes. */  	zclient_send_reg_requests(zclient, bgp->vrf_id); -	/* For default instance, register to learn about VNIs, if appropriate. -	 */ -	if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && is_evpn_enabled()) +	/* For EVPN instance, register to learn about VNIs, if appropriate. */ +	if (bgp->advertise_all_vni)  		bgp_zebra_advertise_all_vni(bgp, 1);  	bgp_nht_register_nexthops(bgp); @@ -1881,9 +1880,8 @@ void bgp_zebra_instance_deregister(struct bgp *bgp)  	if (BGP_DEBUG(zebra, ZEBRA))  		zlog_debug("Deregistering VRF %u", bgp->vrf_id); -	/* For default instance, unregister learning about VNIs, if appropriate. -	 */ -	if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && is_evpn_enabled()) +	/* For EVPN instance, unregister learning about VNIs, if appropriate. */ +	if (bgp->advertise_all_vni)  		bgp_zebra_advertise_all_vni(bgp, 0);  	/* Deregister for router-id, interfaces, redistributed routes. */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index d99b402e28..8fcf417b3a 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2872,6 +2872,12 @@ static struct bgp *bgp_create(as_t *as, const char *name,  				   name, *as);  	} +	/* Default the EVPN VRF to the default one */ +	if (inst_type == BGP_INSTANCE_TYPE_DEFAULT && !bgp_master.bgp_evpn) { +		bgp_lock(bgp); +		bm->bgp_evpn = bgp; +	} +  	bgp_lock(bgp);  	bgp->heuristic_coalesce = true;  	bgp->inst_type = inst_type; @@ -3070,6 +3076,29 @@ struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id)  	return (vrf->info) ? (struct bgp *)vrf->info : NULL;  } +/* Sets the BGP instance where EVPN is enabled */ +void bgp_set_evpn(struct bgp *bgp) +{ +	if (bm->bgp_evpn == bgp) +		return; + +	/* First, release the reference count we hold on the instance */ +	if (bm->bgp_evpn) +		bgp_unlock(bm->bgp_evpn); + +	bm->bgp_evpn = bgp; + +	/* Increase the reference count on this new VRF */ +	if (bm->bgp_evpn) +		bgp_lock(bm->bgp_evpn); +} + +/* Returns the BGP instance where EVPN is enabled, if any */ +struct bgp *bgp_get_evpn(void) +{ +	return bm->bgp_evpn; +} +  /* handle socket creation or deletion, if necessary   * this is called for all new BGP instances   */ @@ -3354,6 +3383,14 @@ int bgp_delete(struct bgp *bgp)  	if (vrf)  		bgp_vrf_unlink(bgp, vrf); +	/* Update EVPN VRF pointer */ +	if (bm->bgp_evpn == bgp) { +		if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) +			bgp_set_evpn(NULL); +		else +			bgp_set_evpn(bgp_get_default()); +	} +  	thread_master_free_unused(bm->master);  	bgp_unlock(bgp); /* initial reference */ diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index c7d137c76c..f9c269e3e6 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -150,6 +150,9 @@ struct bgp_master {  	/* dynamic mpls label allocation pool */  	struct labelpool labelpool; +	/* BGP-EVPN VRF ID. Defaults to default VRF (if any) */ +	struct bgp* bgp_evpn; +  	bool terminating;	/* global flag that sigint terminate seen */  	QOBJ_FIELDS  }; @@ -1506,6 +1509,8 @@ extern struct bgp *bgp_get_default(void);  extern struct bgp *bgp_lookup(as_t, const char *);  extern struct bgp *bgp_lookup_by_name(const char *);  extern struct bgp *bgp_lookup_by_vrf_id(vrf_id_t); +extern struct bgp *bgp_get_evpn(void); +extern void bgp_set_evpn(struct bgp *bgp);  extern struct peer *peer_lookup(struct bgp *, union sockunion *);  extern struct peer *peer_lookup_by_conf_if(struct bgp *, const char *);  extern struct peer *peer_lookup_by_hostname(struct bgp *, const char *);  | 
