diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c index 04a2cfc5e363..dbf58eb7fc94 100644 --- a/bgpd/bgp_conditional_adv.c +++ b/bgpd/bgp_conditional_adv.c @@ -137,8 +137,9 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi, if (update_type == UPDATE_TYPE_ADVERTISE && subgroup_announce_check(dest, pi, subgrp, dest_p, &attr, &advmap_attr)) { - bgp_adj_out_set_subgroup(dest, subgrp, &attr, - pi); + if (!bgp_adj_out_set_subgroup(dest, subgrp, + &attr, pi)) + bgp_attr_flush(&attr); } else { /* If default originate is enabled for * the peer, do not send explicit diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index e15a3b375408..c1ac7b8b31a1 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2811,9 +2811,9 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, { const struct prefix *p; struct peer *onlypeer; - struct attr attr; afi_t afi; safi_t safi; + struct attr attr = { 0 }, *pattr = &attr; struct bgp *bgp; bool advertise; @@ -2843,22 +2843,30 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, advertise = bgp_check_advertise(bgp, dest); if (selected) { - if (subgroup_announce_check(dest, selected, subgrp, p, &attr, + if (subgroup_announce_check(dest, selected, subgrp, p, pattr, NULL)) { /* Route is selected, if the route is already installed * in FIB, then it is advertised */ if (advertise) { - if (!bgp_check_withdrawal(bgp, dest)) - bgp_adj_out_set_subgroup( - dest, subgrp, &attr, selected); - else + if (!bgp_check_withdrawal(bgp, dest)) { + if (!bgp_adj_out_set_subgroup(dest, + subgrp, + pattr, + selected)) + bgp_attr_flush(pattr); + } else { bgp_adj_out_unset_subgroup( dest, subgrp, 1, addpath_tx_id); - } - } else + bgp_attr_flush(pattr); + } + } else + bgp_attr_flush(pattr); + } else { bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id); + bgp_attr_flush(pattr); + } } /* If selected is NULL we must withdraw the path using addpath_tx_id */ diff --git a/bgpd/bgp_updgrp.h b/bgpd/bgp_updgrp.h index 56289d399d3b..57da41050523 100644 --- a/bgpd/bgp_updgrp.h +++ b/bgpd/bgp_updgrp.h @@ -454,7 +454,7 @@ extern struct bgp_adj_out *bgp_adj_out_alloc(struct update_subgroup *subgrp, extern void bgp_adj_out_remove_subgroup(struct bgp_dest *dest, struct bgp_adj_out *adj, struct update_subgroup *subgrp); -extern void bgp_adj_out_set_subgroup(struct bgp_dest *dest, +extern bool bgp_adj_out_set_subgroup(struct bgp_dest *dest, struct update_subgroup *subgrp, struct attr *attr, struct bgp_path_info *path); diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index d7cb51c66749..00a6f43bff85 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -449,7 +449,7 @@ bgp_advertise_clean_subgroup(struct update_subgroup *subgrp, return next; } -void bgp_adj_out_set_subgroup(struct bgp_dest *dest, +bool bgp_adj_out_set_subgroup(struct bgp_dest *dest, struct update_subgroup *subgrp, struct attr *attr, struct bgp_path_info *path) { @@ -469,7 +469,7 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, bgp = SUBGRP_INST(subgrp); if (DISABLE_BGP_ANNOUNCE) - return; + return false; /* Look for adjacency information. */ adj = adj_lookup( @@ -485,7 +485,7 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, bgp_addpath_id_for_peer(peer, afi, safi, &path->tx_addpath)); if (!adj) - return; + return false; subgrp->pscount++; } @@ -524,7 +524,7 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, * will never be able to coalesce the 3rd peer down */ subgrp->version = MAX(subgrp->version, dest->version); - return; + return false; } if (adj->adv) @@ -571,6 +571,8 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, bgp_adv_fifo_add_tail(&subgrp->sync->update, adv); subgrp->version = MAX(subgrp->version, dest->version); + + return true; } /* The only time 'withdraw' will be false is if we are sending @@ -799,7 +801,7 @@ void subgroup_announce_route(struct update_subgroup *subgrp) void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) { struct bgp *bgp; - struct attr attr; + struct attr attr = { 0 }; struct attr *new_attr = &attr; struct aspath *aspath; struct prefix p; @@ -933,18 +935,19 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) if (dest) { for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { - if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) - if (subgroup_announce_check( - dest, pi, subgrp, - bgp_dest_get_prefix(dest), - &attr, NULL)) { - struct attr *default_attr = - bgp_attr_intern(&attr); - - bgp_adj_out_set_subgroup( - dest, subgrp, - default_attr, pi); - } + if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) + continue; + + if (subgroup_announce_check(dest, pi, subgrp, + bgp_dest_get_prefix( + dest), + &attr, NULL)) { + if (!bgp_adj_out_set_subgroup(dest, + subgrp, + &attr, pi)) + bgp_attr_flush(&attr); + } else + bgp_attr_flush(&attr); } bgp_dest_unlock_node(dest); }