mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-04 11:45:06 +00:00 
			
		
		
		
	Merge pull request #1938 from donaldsharp/vpn_peer_withdrawal
bgpd: Fix peer withdrawal and route leaking for vpn's and vrf's
This commit is contained in:
		
						commit
						80a80e1af0
					
				@ -2095,6 +2095,25 @@ struct bgp_process_queue {
 | 
			
		||||
	unsigned int queued;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * old_select = The old best path
 | 
			
		||||
 * new_select = the new best path
 | 
			
		||||
 *
 | 
			
		||||
 * if (!old_select && new_select)
 | 
			
		||||
 *     We are sending new information on.
 | 
			
		||||
 *
 | 
			
		||||
 * if (old_select && new_select) {
 | 
			
		||||
 *         if (new_select != old_select)
 | 
			
		||||
 *                 We have a new best path send a change
 | 
			
		||||
 *         else
 | 
			
		||||
 *                 We've received a update with new attributes that needs
 | 
			
		||||
 *                 to be passed on.
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * if (old_select && !new_select)
 | 
			
		||||
 *     We have no eligible route that we can announce or the rn
 | 
			
		||||
 *     is being removed.
 | 
			
		||||
 */
 | 
			
		||||
static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
 | 
			
		||||
				 afi_t afi, safi_t safi)
 | 
			
		||||
{
 | 
			
		||||
@ -2294,7 +2313,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
 | 
			
		||||
				|| old_select->sub_type == BGP_ROUTE_AGGREGATE
 | 
			
		||||
				|| old_select->sub_type == BGP_ROUTE_IMPORTED))
 | 
			
		||||
 | 
			
		||||
				bgp_zebra_withdraw(p, old_select, safi);
 | 
			
		||||
				bgp_zebra_withdraw(p, old_select, bgp, safi);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -3664,10 +3683,12 @@ static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
 | 
			
		||||
	struct bgp_node *rn = cnq->rn;
 | 
			
		||||
	struct peer *peer = wq->spec.data;
 | 
			
		||||
	struct bgp_info *ri;
 | 
			
		||||
	struct bgp *bgp;
 | 
			
		||||
	afi_t afi = bgp_node_table(rn)->afi;
 | 
			
		||||
	safi_t safi = bgp_node_table(rn)->safi;
 | 
			
		||||
 | 
			
		||||
	assert(rn && peer);
 | 
			
		||||
	bgp = peer->bgp;
 | 
			
		||||
 | 
			
		||||
	/* It is possible that we have multiple paths for a prefix from a peer
 | 
			
		||||
	 * if that peer is using AddPath.
 | 
			
		||||
@ -3686,8 +3707,18 @@ static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
 | 
			
		||||
			/* If this is an EVPN route, process for
 | 
			
		||||
			 * un-import. */
 | 
			
		||||
			if (safi == SAFI_EVPN)
 | 
			
		||||
				bgp_evpn_unimport_route(peer->bgp, afi, safi,
 | 
			
		||||
				bgp_evpn_unimport_route(bgp, afi, safi,
 | 
			
		||||
							&rn->p, ri);
 | 
			
		||||
			/* Handle withdraw for VRF route-leaking and L3VPN */
 | 
			
		||||
			if (SAFI_UNICAST == safi
 | 
			
		||||
			    && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
 | 
			
		||||
				bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT))
 | 
			
		||||
				vpn_leak_from_vrf_withdraw(bgp_get_default(),
 | 
			
		||||
							   bgp, ri);
 | 
			
		||||
			if (SAFI_MPLS_VPN == safi &&
 | 
			
		||||
			    bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
 | 
			
		||||
				vpn_leak_to_vrf_withdraw(bgp, ri);
 | 
			
		||||
 | 
			
		||||
			bgp_rib_remove(rn, ri, peer, afi, safi);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -3953,7 +3984,8 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void bgp_cleanup_table(struct bgp_table *table, safi_t safi)
 | 
			
		||||
static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
 | 
			
		||||
			      safi_t safi)
 | 
			
		||||
{
 | 
			
		||||
	struct bgp_node *rn;
 | 
			
		||||
	struct bgp_info *ri;
 | 
			
		||||
@ -3969,7 +4001,8 @@ static void bgp_cleanup_table(struct bgp_table *table, safi_t safi)
 | 
			
		||||
				|| ri->sub_type == BGP_ROUTE_IMPORTED)) {
 | 
			
		||||
 | 
			
		||||
				if (bgp_fibupd_safi(safi))
 | 
			
		||||
					bgp_zebra_withdraw(&rn->p, ri, safi);
 | 
			
		||||
					bgp_zebra_withdraw(&rn->p, ri,
 | 
			
		||||
							   bgp, safi);
 | 
			
		||||
				bgp_info_reap(rn, ri);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@ -3984,7 +4017,8 @@ void bgp_cleanup_routes(struct bgp *bgp)
 | 
			
		||||
	for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
 | 
			
		||||
		if (afi == AFI_L2VPN)
 | 
			
		||||
			continue;
 | 
			
		||||
		bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST);
 | 
			
		||||
		bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
 | 
			
		||||
				  SAFI_UNICAST);
 | 
			
		||||
		/*
 | 
			
		||||
		 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
 | 
			
		||||
		 */
 | 
			
		||||
@ -3994,7 +4028,7 @@ void bgp_cleanup_routes(struct bgp *bgp)
 | 
			
		||||
			for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
 | 
			
		||||
			     rn = bgp_route_next(rn)) {
 | 
			
		||||
				if (rn->info) {
 | 
			
		||||
					bgp_cleanup_table(
 | 
			
		||||
					bgp_cleanup_table(bgp,
 | 
			
		||||
						(struct bgp_table *)(rn->info),
 | 
			
		||||
						safi);
 | 
			
		||||
					bgp_table_finish((struct bgp_table **)&(
 | 
			
		||||
@ -4007,7 +4041,7 @@ void bgp_cleanup_routes(struct bgp *bgp)
 | 
			
		||||
			for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
 | 
			
		||||
			     rn = bgp_route_next(rn)) {
 | 
			
		||||
				if (rn->info) {
 | 
			
		||||
					bgp_cleanup_table(
 | 
			
		||||
					bgp_cleanup_table(bgp,
 | 
			
		||||
						(struct bgp_table *)(rn->info),
 | 
			
		||||
						safi);
 | 
			
		||||
					bgp_table_finish((struct bgp_table **)&(
 | 
			
		||||
@ -4021,7 +4055,8 @@ void bgp_cleanup_routes(struct bgp *bgp)
 | 
			
		||||
	for (rn = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); rn;
 | 
			
		||||
	     rn = bgp_route_next(rn)) {
 | 
			
		||||
		if (rn->info) {
 | 
			
		||||
			bgp_cleanup_table((struct bgp_table *)(rn->info),
 | 
			
		||||
			bgp_cleanup_table(bgp,
 | 
			
		||||
					  (struct bgp_table *)(rn->info),
 | 
			
		||||
					  SAFI_EVPN);
 | 
			
		||||
			bgp_table_finish((struct bgp_table **)&(rn->info));
 | 
			
		||||
			rn->info = NULL;
 | 
			
		||||
 | 
			
		||||
@ -1303,7 +1303,8 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
 | 
			
		||||
						   safi);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info, safi_t safi)
 | 
			
		||||
void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info,
 | 
			
		||||
			struct bgp *bgp, safi_t safi)
 | 
			
		||||
{
 | 
			
		||||
	struct zapi_route api;
 | 
			
		||||
	struct peer *peer;
 | 
			
		||||
@ -1329,12 +1330,12 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info, safi_t safi)
 | 
			
		||||
	/* Don't try to install if we're not connected to Zebra or Zebra doesn't
 | 
			
		||||
	 * know of this instance.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!bgp_install_info_to_zebra(peer->bgp))
 | 
			
		||||
	if (!bgp_install_info_to_zebra(bgp))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	memset(&api, 0, sizeof(api));
 | 
			
		||||
	memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr));
 | 
			
		||||
	api.vrf_id = peer->bgp->vrf_id;
 | 
			
		||||
	api.vrf_id = bgp->vrf_id;
 | 
			
		||||
	api.type = ZEBRA_ROUTE_BGP;
 | 
			
		||||
	api.safi = safi;
 | 
			
		||||
	api.prefix = *p;
 | 
			
		||||
@ -1353,14 +1354,14 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info, safi_t safi)
 | 
			
		||||
 | 
			
		||||
	if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
 | 
			
		||||
	    || CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
 | 
			
		||||
	    || bgp_flag_check(peer->bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
 | 
			
		||||
	    || bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
 | 
			
		||||
		SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
 | 
			
		||||
 | 
			
		||||
	if (bgp_debug_zebra(p)) {
 | 
			
		||||
		char buf[PREFIX_STRLEN];
 | 
			
		||||
 | 
			
		||||
		prefix2str(&api.prefix, buf, sizeof(buf));
 | 
			
		||||
		zlog_debug("Tx route delete VRF %u %s", peer->bgp->vrf_id, buf);
 | 
			
		||||
		zlog_debug("Tx route delete VRF %u %s", bgp->vrf_id, buf);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,8 @@ extern void bgp_config_write_redistribute(struct vty *, struct bgp *, afi_t,
 | 
			
		||||
extern void bgp_zebra_announce(struct bgp_node *, struct prefix *,
 | 
			
		||||
			       struct bgp_info *, struct bgp *, afi_t, safi_t);
 | 
			
		||||
extern void bgp_zebra_announce_table(struct bgp *, afi_t, safi_t);
 | 
			
		||||
extern void bgp_zebra_withdraw(struct prefix *, struct bgp_info *, safi_t);
 | 
			
		||||
extern void bgp_zebra_withdraw(struct prefix *, struct bgp_info *,
 | 
			
		||||
			       struct bgp *, safi_t);
 | 
			
		||||
 | 
			
		||||
extern void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer);
 | 
			
		||||
extern void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user