mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02: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 a new issue