diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c index 24d822a745dc..edb9bc8bb76d 100644 --- a/bgpd/bgp_conditional_adv.c +++ b/bgpd/bgp_conditional_adv.c @@ -135,8 +135,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 f063fa96997d..15d469f7a1e8 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2877,9 +2877,13 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, { const struct prefix *p; struct peer *onlypeer; +<<<<<<< HEAD struct attr attr; afi_t afi; safi_t safi; +======= + struct attr attr = { 0 }, *pattr = &attr; +>>>>>>> addff17a5 (bgpd: Ensure community data is freed in some cases.) struct bgp *bgp; bool advertise; @@ -2909,12 +2913,13 @@ 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) { +<<<<<<< HEAD if (!bgp_check_withdrawal(bgp, dest)) { struct attr *adv_attr = bgp_attr_intern(&attr); @@ -2923,12 +2928,26 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, adv_attr, selected); } else +======= + if (!bgp_check_withdrawal(bgp, dest, safi)) { + if (!bgp_adj_out_set_subgroup(dest, + subgrp, + pattr, + selected)) + bgp_attr_flush(pattr); + } else { +>>>>>>> addff17a5 (bgpd: Ensure community data is freed in some cases.) 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 e27c1e7b6708..b7b6aa07e9f0 100644 --- a/bgpd/bgp_updgrp.h +++ b/bgpd/bgp_updgrp.h @@ -458,7 +458,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 dcde4263da52..baf86908b1d5 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -454,7 +454,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) { @@ -474,7 +474,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( @@ -490,7 +490,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++; } @@ -529,7 +529,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) @@ -576,6 +576,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 @@ -811,7 +813,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; @@ -952,18 +954,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); }