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 0078f8ab0b4e..6d5cc032764d 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2879,7 +2879,7 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, { const struct prefix *p; struct peer *onlypeer; - struct attr attr; + struct attr attr = {0}, *pattr = &attr; afi_t afi; safi_t safi; struct bgp *bgp; @@ -2900,7 +2900,7 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, PEER_STATUS_ORF_WAIT_REFRESH)) return; - memset(&attr, 0, sizeof(attr)); + memset(pattr, 0, sizeof(*pattr)); /* It's initialized in bgp_announce_check() */ /* Announcement to the subgroup. If the route is filtered withdraw it. @@ -2911,32 +2911,34 @@ 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)) { - struct attr *adv_attr = - bgp_attr_intern(&attr); - - bgp_adj_out_set_subgroup(dest, subgrp, - adv_attr, - selected); - } else + 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 */ - else { + else bgp_adj_out_unset_subgroup(dest, subgrp, 1, 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..7902d40bd988 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 @@ -668,7 +670,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp, { struct bgp_dest *dest; struct bgp_path_info *ri; - struct attr attr; + struct attr attr = {0}, *pattr = &attr; struct peer *peer; afi_t afi; safi_t safi; @@ -712,24 +714,25 @@ void subgroup_announce_table(struct update_subgroup *subgrp, continue; if (subgroup_announce_check(dest, ri, subgrp, dest_p, - &attr, NULL)) { + pattr, NULL)) { /* Check if route can be advertised */ if (advertise) { if (!bgp_check_withdrawal(bgp, dest)) { - struct attr *adv_attr = - bgp_attr_intern(&attr); - - bgp_adj_out_set_subgroup( - dest, subgrp, adv_attr, - ri); - } else + if (!bgp_adj_out_set_subgroup( + dest, subgrp, pattr, + ri)) + bgp_attr_flush(pattr); + } else { bgp_adj_out_unset_subgroup( dest, subgrp, 1, bgp_addpath_id_for_peer( peer, afi, safi_rib, &ri->tx_addpath)); - } + bgp_attr_flush(pattr); + } + } else + bgp_attr_flush(pattr); } else { /* If default originate is enabled for * the peer, do not send explicit @@ -748,6 +751,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp, bgp_addpath_id_for_peer( peer, afi, safi_rib, &ri->tx_addpath)); + bgp_attr_flush(pattr); } } } @@ -811,7 +815,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 +956,18 @@ 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); }