diff options
Diffstat (limited to 'bgpd')
| -rw-r--r-- | bgpd/bgp_route.c | 28 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 34 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 24 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 9 | 
4 files changed, 54 insertions, 41 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 8b94892b39..672c43b37c 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4923,6 +4923,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,  	bool force_evpn_import = false;  	safi_t orig_safi = safi;  	struct bgp_labels bgp_labels = {}; +	struct bgp_route_evpn *p_evpn = evpn;  	uint8_t i;  	if (frrtrace_enabled(frr_bgp, process_update)) { @@ -4964,11 +4965,9 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,  		 * will not be interned. In which case, it is ok to update the  		 * attr->evpn_overlay, so that, this can be stored in adj_in.  		 */ -		if (evpn) { -			if (afi == AFI_L2VPN) -				bgp_attr_set_evpn_overlay(attr, evpn); -			else -				evpn_overlay_free(evpn); +		if (evpn && afi == AFI_L2VPN) { +			bgp_attr_set_evpn_overlay(attr, evpn); +			p_evpn = NULL;  		}  		bgp_adj_in_set(dest, peer, attr, addpath_id, &bgp_labels);  	} @@ -5141,11 +5140,9 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,  	 * attr->evpn_overlay with evpn directly. Instead memcpy  	 * evpn to new_atr.evpn_overlay before it is interned.  	 */ -	if (soft_reconfig && evpn) { -		if (afi == AFI_L2VPN) -			bgp_attr_set_evpn_overlay(&new_attr, evpn); -		else -			evpn_overlay_free(evpn); +	if (soft_reconfig && evpn && afi == AFI_L2VPN) { +		bgp_attr_set_evpn_overlay(&new_attr, evpn); +		p_evpn = NULL;  	}  	/* Apply incoming route-map. @@ -5314,7 +5311,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,  			bgp_dest_unlock_node(dest);  			bgp_attr_unintern(&attr_new); - +			if (p_evpn) +				evpn_overlay_free(p_evpn);  			return;  		} @@ -5479,6 +5477,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,  			ret = bgp_damp_update(pi, dest, afi, safi);  			if (ret == BGP_DAMP_SUPPRESSED) {  				bgp_dest_unlock_node(dest); +				if (p_evpn) +					evpn_overlay_free(p_evpn);  				return;  			}  		} @@ -5565,6 +5565,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,  					   type, sub_type, NULL);  		}  #endif +		if (p_evpn) +			evpn_overlay_free(p_evpn);  		return;  	} // End of implicit withdraw @@ -5659,6 +5661,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,  	}  #endif +	if (p_evpn) +		evpn_overlay_free(p_evpn);  	return;  /* This BGP update is filtered.  Log the reason then update BGP @@ -5722,6 +5726,8 @@ filtered:  	}  #endif +	if (p_evpn) +		evpn_overlay_free(p_evpn);  	return;  } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 33b220d3ec..2b3e11929b 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1499,13 +1499,12 @@ DEFUN_NOSH (router_bgp,  	int idx_asn = 2;  	int idx_view_vrf = 3;  	int idx_vrf = 4; -	int is_new_bgp = 0;  	int idx_asnotation = 3;  	int idx_asnotation_kind = 4;  	enum asnotation_mode asnotation = ASNOTATION_UNDEFINED;  	int ret;  	as_t as; -	struct bgp *bgp; +	struct bgp *bgp = NULL;  	const char *name = NULL;  	enum bgp_instance_type inst_type; @@ -1567,35 +1566,40 @@ DEFUN_NOSH (router_bgp,  				asnotation = ASNOTATION_PLAIN;  		} -		if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) -			is_new_bgp = (bgp_lookup(as, name) == NULL); - -		ret = bgp_get_vty(&bgp, &as, name, inst_type, -				  argv[idx_asn]->arg, asnotation); +		ret = bgp_lookup_by_as_name_type(&bgp, &as, argv[idx_asn]->arg, asnotation, name, +						 inst_type, true); +		if (bgp && ret == BGP_INSTANCE_EXISTS) +			ret = CMD_SUCCESS; +		else if (bgp == NULL && ret == CMD_SUCCESS) +			/* SUCCESS and bgp is NULL */ +			ret = bgp_get_vty(&bgp, &as, name, inst_type, argv[idx_asn]->arg, +					  asnotation);  		switch (ret) {  		case BGP_ERR_AS_MISMATCH:  			vty_out(vty, "BGP is already running; AS is %s\n", -				bgp->as_pretty); +				bgp ? bgp->as_pretty : "unknown");  			return CMD_WARNING_CONFIG_FAILED;  		case BGP_ERR_INSTANCE_MISMATCH:  			vty_out(vty,  				"BGP instance name and AS number mismatch\n"); -			vty_out(vty, -				"BGP instance is already running; AS is %s\n", -				bgp->as_pretty); +			vty_out(vty, "BGP instance is already running; AS is %s\n", +				bgp ? bgp->as_pretty : "unknown");  			return CMD_WARNING_CONFIG_FAILED;  		} +		if (!bgp) { +			vty_out(vty, "BGP instance not found\n"); +			return CMD_WARNING_CONFIG_FAILED; +		}  		/*  		 * If we just instantiated the default instance, complete  		 * any pending VRF-VPN leaking that was configured via  		 * earlier "router bgp X vrf FOO" blocks.  		 */ -		if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT) +		if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)  			vpn_leak_postchange_all(); -		if (inst_type == BGP_INSTANCE_TYPE_VRF || -		    IS_BGP_INSTANCE_HIDDEN(bgp)) { +		if (inst_type == BGP_INSTANCE_TYPE_VRF || IS_BGP_INSTANCE_HIDDEN(bgp)) {  			bgp_vpn_leak_export(bgp);  			UNSET_FLAG(bgp->flags, BGP_FLAG_INSTANCE_HIDDEN);  			UNSET_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS); @@ -10559,7 +10563,7 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,  		SET_FLAG(bgp_default->flags, BGP_FLAG_INSTANCE_HIDDEN);  	} -	vrf_bgp = bgp_lookup_by_name(import_name); +	vrf_bgp = bgp_lookup_by_name_filter(import_name, false);  	if (!vrf_bgp) {  		if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) {  			vrf_bgp = bgp_default; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index c2254ae791..d5463f3d0c 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3634,13 +3634,13 @@ struct bgp *bgp_lookup(as_t as, const char *name)  }  /* Lookup BGP structure by view name. */ -struct bgp *bgp_lookup_by_name(const char *name) +struct bgp *bgp_lookup_by_name_filter(const char *name, bool filter_auto)  {  	struct bgp *bgp;  	struct listnode *node, *nnode;  	for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { -		if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) +		if (filter_auto && CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))  			continue;  		if ((bgp->name == NULL && name == NULL)  		    || (bgp->name && name && strcmp(bgp->name, name) == 0)) @@ -3649,6 +3649,11 @@ struct bgp *bgp_lookup_by_name(const char *name)  	return NULL;  } +struct bgp *bgp_lookup_by_name(const char *name) +{ +	return bgp_lookup_by_name_filter(name, true); +} +  /* Lookup BGP instance based on VRF id. */  /* Note: Only to be used for incoming messages from Zebra. */  struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id) @@ -3734,10 +3739,9 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id,  		return bgp_check_main_socket(create, bgp);  } -int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, -			       const char *as_pretty, +int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *as_pretty,  			       enum asnotation_mode asnotation, const char *name, -			       enum bgp_instance_type inst_type) +			       enum bgp_instance_type inst_type, bool force_config)  {  	struct bgp *bgp;  	struct peer *peer = NULL; @@ -3746,7 +3750,7 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as,  	/* Multiple instance check. */  	if (name) -		bgp = bgp_lookup_by_name(name); +		bgp = bgp_lookup_by_name_filter(name, !force_config);  	else  		bgp = bgp_get_default(); @@ -3756,7 +3760,7 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as,  		/* Handle AS number change */  		if (bgp->as != *as) {  			if (hidden || CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) { -				if (hidden) { +				if (force_config == false && hidden) {  					bgp_create(as, name, inst_type,  						   as_pretty, asnotation, bgp,  						   hidden); @@ -3764,7 +3768,8 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as,  						   BGP_FLAG_INSTANCE_HIDDEN);  				} else {  					bgp->as = *as; -					UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); +					if (force_config == false) +						UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO);  				}  				/* Set all peer's local AS with this ASN */ @@ -3801,8 +3806,7 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,  	struct vrf *vrf = NULL;  	int ret = 0; -	ret = bgp_lookup_by_as_name_type(bgp_val, as, as_pretty, asnotation, -					 name, inst_type); +	ret = bgp_lookup_by_as_name_type(bgp_val, as, as_pretty, asnotation, name, inst_type, false);  	if (ret || *bgp_val)  		return ret; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index c72072852d..96a78e6662 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -2285,6 +2285,7 @@ extern void bgp_zclient_reset(void);  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_name_filter(const char *name, bool filter_auto);  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); @@ -2859,11 +2860,9 @@ extern struct peer *peer_new(struct bgp *bgp);  extern struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,  					const char *ip_str, bool use_json); -extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, -				      const char *as_pretty, -				      enum asnotation_mode asnotation, -				      const char *name, -				      enum bgp_instance_type inst_type); +extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *as_pretty, +				      enum asnotation_mode asnotation, const char *name, +				      enum bgp_instance_type inst_type, bool force_config);  /* Hooks */  DECLARE_HOOK(bgp_vrf_status_changed, (struct bgp *bgp, struct interface *ifp),  | 
