From f2ee6d5cd9653fecc7ab2a1e029a3a43f72b4c99 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 29 Oct 2020 21:41:12 +0200 Subject: [PATCH] bgpd: Handle route-maps properly for `default-originate route-map` command The problem is that only prefixes were handled and any other `match` commands were ignored. Let's do not forget them as well. Signed-off-by: Donatas Abraitis --- bgpd/bgp_route.c | 2 +- bgpd/bgp_route.h | 2 +- bgpd/bgp_updgrp_adv.c | 51 ++++++++++++++++++++++++++++--------------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 52e90f5c6a..090d64026d 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1687,7 +1687,7 @@ void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp) } -static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr) +void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr) { if (family == AF_INET) { attr->nexthop.s_addr = INADDR_ANY; diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 43744044b4..e4c6f9a0e2 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -757,5 +757,5 @@ extern int bgp_distance_set(uint8_t distance, const char *ip_str, extern int bgp_distance_unset(uint8_t distance, const char *ip_str, const char *access_list_str, afi_t afi, safi_t safi, char *errmsg, size_t errmsg_len); - +extern void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr); #endif /* _QUAGGA_BGP_ROUTE_H */ diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index ac77ccd8a4..3cfb73d8a8 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -731,7 +731,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) struct bgp *bgp; struct attr attr; struct attr *new_attr = &attr; - struct aspath *aspath; struct prefix p; struct peer *from; struct bgp_dest *dest; @@ -756,7 +755,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) from = bgp->peer_self; bgp_attr_default_set(&attr, BGP_ORIGIN_IGP); - aspath = attr.aspath; attr.local_pref = bgp->default_local_pref; @@ -772,12 +770,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) } if (peer->default_rmap[afi][safi].name) { - struct attr attr_tmp = attr; - struct bgp_path_info bpi_rmap = {0}; - - bpi_rmap.peer = bgp->peer_self; - bpi_rmap.attr = &attr_tmp; - SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT); /* Iterate over the RIB to see if we can announce @@ -789,20 +781,45 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) if (!bgp_dest_has_bgp_path_info_data(dest)) continue; - ret = route_map_apply(peer->default_rmap[afi][safi].map, - bgp_dest_get_prefix(dest), - RMAP_BGP, &bpi_rmap); + for (pi = bgp_dest_get_bgp_path_info(dest); pi; + pi = pi->next) { + struct attr tmp_attr; + struct bgp_path_info tmp_pi; + struct bgp_path_info_extra tmp_pie; + + tmp_attr = *pi->attr; + + prep_for_rmap_apply(&tmp_pi, &tmp_pie, dest, pi, + pi->peer, &tmp_attr); - if (ret != RMAP_DENYMATCH) + ret = route_map_apply( + peer->default_rmap[afi][safi].map, + bgp_dest_get_prefix(dest), RMAP_BGP, + &tmp_pi); + + if (ret == RMAP_DENYMATCH) { + bgp_attr_flush(&tmp_attr); + continue; + } else { + new_attr = bgp_attr_intern(&tmp_attr); + new_attr->aspath = attr.aspath; + + subgroup_announce_reset_nhop( + (peer_cap_enhe(peer, afi, safi) + ? AF_INET6 + : AF_INET), + new_attr); + + break; + } + } + if (ret == RMAP_PERMITMATCH) break; } bgp->peer_self->rmap_type = 0; - new_attr = bgp_attr_intern(&attr_tmp); - if (ret == RMAP_DENYMATCH) { - bgp_attr_flush(&attr_tmp); + if (ret == RMAP_DENYMATCH) withdraw = 1; - } } /* Check if the default route is in local BGP RIB which is @@ -881,8 +898,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) subgroup_default_update_packet(subgrp, new_attr, from); } } - - aspath_unintern(&aspath); } /* -- 2.39.5