struct peer_af *paf;
const struct prefix *dest_p;
struct update_subgroup *subgrp;
- struct attr dummy_attr = {0}, attr = {0};
+ struct attr advmap_attr = {0}, attr = {0};
struct bgp_path_info_extra path_extra = {0};
route_map_result_t ret;
assert(dest_p);
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
- dummy_attr = *pi->attr;
+ advmap_attr = *pi->attr;
/* Fill temp path_info */
prep_for_rmap_apply(&path, &path_extra, dest, pi,
- pi->peer, &dummy_attr);
+ pi->peer, &advmap_attr);
- RESET_FLAG(dummy_attr.rmap_change_flags);
+ RESET_FLAG(advmap_attr.rmap_change_flags);
ret = route_map_apply(rmap, dest_p, &path);
- bgp_attr_flush(&dummy_attr);
-
- if (ret != RMAP_PERMITMATCH)
+ if (ret != RMAP_PERMITMATCH ||
+ !bgp_check_selected(pi, peer, addpath_capable, afi,
+ safi)) {
+ bgp_attr_flush(&advmap_attr);
continue;
+ }
- if (bgp_check_selected(pi, peer, addpath_capable, afi,
- safi)) {
- /* Skip route-map checks in
- * subgroup_announce_check while executing from
- * the conditional advertise scanner process.
- * otherwise when route-map is also configured
- * on same peer, routes in advertise-map may not
- * be advertised as expected.
+ /* Skip route-map checks in
+ * subgroup_announce_check while executing from
+ * the conditional advertise scanner process.
+ * otherwise when route-map is also configured
+ * on same peer, routes in advertise-map may not
+ * be advertised as expected.
+ */
+ if (update_type == ADVERTISE &&
+ subgroup_announce_check(dest, pi, subgrp, dest_p,
+ &attr, &advmap_attr)) {
+ bgp_adj_out_set_subgroup(dest, subgrp, &attr,
+ pi);
+ } 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 ((update_type == ADVERTISE)
- && subgroup_announce_check(dest, pi, subgrp,
- dest_p, &attr,
- true))
- bgp_adj_out_set_subgroup(dest, subgrp,
- &attr, pi);
- 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(dest_p))
- break;
-
- bgp_adj_out_unset_subgroup(
- dest, subgrp, 1,
- bgp_addpath_id_for_peer(
- peer, afi, safi,
- &pi->tx_addpath));
- }
+ if (CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_DEFAULT_ORIGINATE) &&
+ is_default_prefix(dest_p))
+ break;
+
+ bgp_adj_out_unset_subgroup(
+ dest, subgrp, 1,
+ bgp_addpath_id_for_peer(
+ peer, afi, safi,
+ &pi->tx_addpath));
}
+ bgp_attr_flush(&advmap_attr);
}
}
UNSET_FLAG(subgrp->sflags, SUBGRP_STATUS_TABLE_REPARSING);
bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
struct update_subgroup *subgrp,
const struct prefix *p, struct attr *attr,
- bool skip_rmap_check)
+ struct attr *post_attr)
{
struct bgp_filter *filter;
struct peer *from;
}
}
- /* For modify attribute, copy it to temporary structure. */
- *attr = *piattr;
+ /* For modify attribute, copy it to temporary structure.
+ * post_attr comes from BGP conditional advertisements, where
+ * attributes are already processed by advertise-map route-map,
+ * and this needs to be saved instead of overwriting from the
+ * path attributes.
+ */
+ if (post_attr)
+ *attr = *post_attr;
+ else
+ *attr = *piattr;
/* If local-preference is not set. */
if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
bgp_peer_as_override(bgp, afi, safi, peer, attr);
/* Route map & unsuppress-map apply. */
- if (!skip_rmap_check
- && (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
+ if (!post_attr &&
+ (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
struct bgp_path_info rmap_path = {0};
struct bgp_path_info_extra dummy_rmap_path_extra = {0};
struct attr dummy_attr = {0};
if (selected) {
if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
- false)) {
+ NULL)) {
/* Route is selected, if the route is already installed
* in FIB, then it is advertised
*/