bgpd: fix default-originate route-map processing

When processing a route-map for default-originate, we actually want to
match by attributes in routes from the RIB, but set attributes in the
newly originated route. Currently, it's not the case. Instead, we
construct a dummy path combining attributes from both routes, and we end
up with multiple problems:
- match by as-path doesn't work
- communities from the matched RIB route are copied to the newly
  originated route
- we corrupt the RIB routes

To fix the issue, we should use the new route-map API that allows using
separate match/set objects.

Fixes #9584.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
This commit is contained in:
Igor Ryzhov 2021-09-08 21:06:44 +03:00
parent c212584717
commit bf844bac67

View File

@ -812,6 +812,10 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
} }
if (peer->default_rmap[afi][safi].name) { if (peer->default_rmap[afi][safi].name) {
struct bgp_path_info tmp_pi = {0};
tmp_pi.peer = bgp->peer_self;
SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT); SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
/* Iterate over the RIB to see if we can announce /* Iterate over the RIB to see if we can announce
@ -825,24 +829,16 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
for (pi = bgp_dest_get_bgp_path_info(dest); pi; for (pi = bgp_dest_get_bgp_path_info(dest); pi;
pi = pi->next) { pi = pi->next) {
struct attr tmp_attr; struct attr tmp_attr = attr;
struct bgp_path_info tmp_pi;
struct bgp_path_info_extra tmp_pie;
tmp_attr = *pi->attr; tmp_pi.attr = &tmp_attr;
tmp_attr.aspath = attr.aspath;
prep_for_rmap_apply(&tmp_pi, &tmp_pie, dest, pi, ret = route_map_apply_ext(
pi->peer, &tmp_attr);
ret = route_map_apply(
peer->default_rmap[afi][safi].map, peer->default_rmap[afi][safi].map,
bgp_dest_get_prefix(dest), &tmp_pi); bgp_dest_get_prefix(dest), pi, &tmp_pi);
if (ret == RMAP_DENYMATCH) { if (ret == RMAP_DENYMATCH) {
/* The aspath belongs to 'attr' */ bgp_attr_undup(&tmp_attr, &attr);
tmp_attr.aspath = NULL;
bgp_attr_flush(&tmp_attr);
continue; continue;
} else { } else {
new_attr = bgp_attr_intern(&tmp_attr); new_attr = bgp_attr_intern(&tmp_attr);