mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-11-01 12:47:16 +00:00
bgpd: Configuring default-originate withdraws default route
Issue: Configuring default-originate when static default route is previously advertised results in withdrawal of the route. Fix : Delete the adj-out entry for the previously advertised static default route without sending explicit withdraw message. Signed-off-by: kssoman <somanks@gmail.com>
This commit is contained in:
parent
63ffd0ea20
commit
f55c9a4653
@ -533,6 +533,14 @@ void bgp_adj_out_unset_subgroup(struct bgp_node *rn,
|
||||
if (adj->adv)
|
||||
bgp_advertise_clean_subgroup(subgrp, adj);
|
||||
|
||||
/* If default originate is enabled and the route is default
|
||||
* route, do not send withdraw. This will prevent deletion of
|
||||
* the default route at the peer.
|
||||
*/
|
||||
if (CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)
|
||||
&& is_default_prefix(&rn->p))
|
||||
return;
|
||||
|
||||
if (adj->attr && withdraw) {
|
||||
/* We need advertisement structure. */
|
||||
adj->adv = bgp_advertise_new();
|
||||
@ -636,12 +644,25 @@ void subgroup_announce_table(struct update_subgroup *subgrp,
|
||||
rn_p, &attr))
|
||||
bgp_adj_out_set_subgroup(rn, subgrp,
|
||||
&attr, ri);
|
||||
else
|
||||
else {
|
||||
/* If default originate is enabled for
|
||||
* the peer, do not send explicit
|
||||
* withdraw. This will prevent deletion
|
||||
* of default route advertised through
|
||||
* default originate
|
||||
*/
|
||||
if (CHECK_FLAG(
|
||||
peer->af_flags[afi][safi],
|
||||
PEER_FLAG_DEFAULT_ORIGINATE)
|
||||
&& is_default_prefix(&rn->p))
|
||||
break;
|
||||
|
||||
bgp_adj_out_unset_subgroup(
|
||||
rn, subgrp, 1,
|
||||
bgp_addpath_id_for_peer(
|
||||
peer, afi, safi,
|
||||
&ri->tx_addpath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -709,7 +730,9 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
|
||||
struct prefix p;
|
||||
struct peer *from;
|
||||
struct bgp_node *rn;
|
||||
struct bgp_path_info *pi;
|
||||
struct peer *peer;
|
||||
struct bgp_adj_out *adj;
|
||||
route_map_result_t ret = RMAP_DENYMATCH;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
@ -732,10 +755,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
|
||||
|
||||
attr.local_pref = bgp->default_local_pref;
|
||||
|
||||
memset(&p, 0, sizeof(p));
|
||||
p.family = afi2family(afi);
|
||||
p.prefixlen = 0;
|
||||
|
||||
if ((afi == AFI_IP6) || peer_cap_enhe(peer, afi, safi)) {
|
||||
/* IPv6 global nexthop must be included. */
|
||||
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
|
||||
@ -778,21 +797,40 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the default route is in local BGP RIB which is
|
||||
* installed through redistribute or network command
|
||||
*/
|
||||
memset(&p, 0, sizeof(p));
|
||||
p.family = afi2family(afi);
|
||||
p.prefixlen = 0;
|
||||
rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi, &p, NULL);
|
||||
|
||||
if (withdraw) {
|
||||
/* Withdraw the default route advertised using default
|
||||
* originate
|
||||
*/
|
||||
if (CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE))
|
||||
subgroup_default_withdraw_packet(subgrp);
|
||||
UNSET_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE);
|
||||
|
||||
/* If default route is present in the local RIB, advertise the
|
||||
* route
|
||||
*/
|
||||
if (rn != NULL) {
|
||||
for (pi = bgp_node_get_bgp_path_info(rn); pi;
|
||||
pi = pi->next) {
|
||||
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
|
||||
if (subgroup_announce_check(
|
||||
rn, pi, subgrp, &rn->p,
|
||||
&attr))
|
||||
bgp_adj_out_set_subgroup(
|
||||
rn, subgrp, &attr, pi);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!CHECK_FLAG(subgrp->sflags,
|
||||
SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
|
||||
|
||||
if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN))
|
||||
bgp_attr_add_gshut_community(new_attr);
|
||||
|
||||
SET_FLAG(subgrp->sflags,
|
||||
SUBGRP_STATUS_DEFAULT_ORIGINATE);
|
||||
subgroup_default_update_packet(subgrp, new_attr, from);
|
||||
|
||||
/* The 'neighbor x.x.x.x default-originate' default will
|
||||
* act as an
|
||||
* implicit withdraw for any previous UPDATEs sent for
|
||||
@ -800,15 +838,37 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
|
||||
* clear adj_out for the 0.0.0.0/0 prefix in the BGP
|
||||
* table.
|
||||
*/
|
||||
memset(&p, 0, sizeof(p));
|
||||
p.family = afi2family(afi);
|
||||
p.prefixlen = 0;
|
||||
if (rn != NULL) {
|
||||
/* Remove the adjacency for the previously
|
||||
* advertised default route
|
||||
*/
|
||||
adj = adj_lookup(
|
||||
rn, subgrp,
|
||||
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
|
||||
if (adj != NULL) {
|
||||
/* Clean up previous advertisement. */
|
||||
if (adj->adv)
|
||||
bgp_advertise_clean_subgroup(
|
||||
subgrp, adj);
|
||||
|
||||
rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
|
||||
&p, NULL);
|
||||
bgp_adj_out_unset_subgroup(
|
||||
rn, subgrp, 0,
|
||||
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
|
||||
/* Remove from adjacency. */
|
||||
RB_REMOVE(bgp_adj_out_rb, &rn->adj_out,
|
||||
adj);
|
||||
|
||||
/* Free allocated information. */
|
||||
adj_free(adj);
|
||||
|
||||
bgp_unlock_node(rn);
|
||||
}
|
||||
}
|
||||
|
||||
/* Advertise the default route */
|
||||
if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN))
|
||||
bgp_attr_add_gshut_community(new_attr);
|
||||
|
||||
SET_FLAG(subgrp->sflags,
|
||||
SUBGRP_STATUS_DEFAULT_ORIGINATE);
|
||||
subgroup_default_update_packet(subgrp, new_attr, from);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user