diff options
| author | paulzlabn <paulz@labn.net> | 2018-03-21 18:27:22 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-03-21 18:27:22 -0700 |
| commit | 80a80e1af0781052846d2bc66c4d29f15f618689 (patch) | |
| tree | dad9cf6ce8599093d7a489ccb47210ba101aecca | |
| parent | c6323200a7ea111fadfc9035841f8165f319c3ca (diff) | |
| parent | 568e10ca581e0519eb613f0fcd08dff794e27cd3 (diff) | |
Merge pull request #1938 from donaldsharp/vpn_peer_withdrawal
bgpd: Fix peer withdrawal and route leaking for vpn's and vrf's
| -rw-r--r-- | bgpd/bgp_route.c | 51 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 11 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.h | 3 |
3 files changed, 51 insertions, 14 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 35732d1bf5..41dff0a7e2 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -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; diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 486ea3937a..bc6ee73da8 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -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); diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index da5160bc16..c30f63039b 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -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); |
