mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-14 09:55:40 +00:00
bgpd: Allow setting attributes over route-maps for conditional advertisements
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
This commit is contained in:
parent
5cb526136a
commit
cb290e57c7
@ -82,7 +82,7 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi,
|
|||||||
struct peer_af *paf;
|
struct peer_af *paf;
|
||||||
const struct prefix *dest_p;
|
const struct prefix *dest_p;
|
||||||
struct update_subgroup *subgrp;
|
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};
|
struct bgp_path_info_extra path_extra = {0};
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
@ -110,55 +110,53 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi,
|
|||||||
assert(dest_p);
|
assert(dest_p);
|
||||||
|
|
||||||
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
|
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 */
|
/* Fill temp path_info */
|
||||||
prep_for_rmap_apply(&path, &path_extra, dest, pi,
|
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);
|
ret = route_map_apply(rmap, dest_p, &path);
|
||||||
bgp_attr_flush(&dummy_attr);
|
if (ret != RMAP_PERMITMATCH ||
|
||||||
|
!bgp_check_selected(pi, peer, addpath_capable, afi,
|
||||||
if (ret != RMAP_PERMITMATCH)
|
safi)) {
|
||||||
|
bgp_attr_flush(&advmap_attr);
|
||||||
continue;
|
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.
|
|
||||||
*/
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 (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);
|
UNSET_FLAG(subgrp->sflags, SUBGRP_STATUS_TABLE_REPARSING);
|
||||||
|
@ -1836,7 +1836,7 @@ void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
|
|||||||
bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
|
bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
|
||||||
struct update_subgroup *subgrp,
|
struct update_subgroup *subgrp,
|
||||||
const struct prefix *p, struct attr *attr,
|
const struct prefix *p, struct attr *attr,
|
||||||
bool skip_rmap_check)
|
struct attr *post_attr)
|
||||||
{
|
{
|
||||||
struct bgp_filter *filter;
|
struct bgp_filter *filter;
|
||||||
struct peer *from;
|
struct peer *from;
|
||||||
@ -2067,8 +2067,16 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For modify attribute, copy it to temporary structure. */
|
/* For modify attribute, copy it to temporary structure.
|
||||||
*attr = *piattr;
|
* 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 local-preference is not set. */
|
||||||
if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
|
if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
|
||||||
@ -2162,8 +2170,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
|
|||||||
bgp_peer_as_override(bgp, afi, safi, peer, attr);
|
bgp_peer_as_override(bgp, afi, safi, peer, attr);
|
||||||
|
|
||||||
/* Route map & unsuppress-map apply. */
|
/* Route map & unsuppress-map apply. */
|
||||||
if (!skip_rmap_check
|
if (!post_attr &&
|
||||||
&& (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
|
(ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
|
||||||
struct bgp_path_info rmap_path = {0};
|
struct bgp_path_info rmap_path = {0};
|
||||||
struct bgp_path_info_extra dummy_rmap_path_extra = {0};
|
struct bgp_path_info_extra dummy_rmap_path_extra = {0};
|
||||||
struct attr dummy_attr = {0};
|
struct attr dummy_attr = {0};
|
||||||
@ -2696,7 +2704,7 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp,
|
|||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
|
if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
|
||||||
false)) {
|
NULL)) {
|
||||||
/* Route is selected, if the route is already installed
|
/* Route is selected, if the route is already installed
|
||||||
* in FIB, then it is advertised
|
* in FIB, then it is advertised
|
||||||
*/
|
*/
|
||||||
|
@ -785,7 +785,7 @@ extern bool subgroup_announce_check(struct bgp_dest *dest,
|
|||||||
struct bgp_path_info *pi,
|
struct bgp_path_info *pi,
|
||||||
struct update_subgroup *subgrp,
|
struct update_subgroup *subgrp,
|
||||||
const struct prefix *p, struct attr *attr,
|
const struct prefix *p, struct attr *attr,
|
||||||
bool skip_rmap_check);
|
struct attr *post_attr);
|
||||||
|
|
||||||
extern void bgp_peer_clear_node_queue_drain_immediate(struct peer *peer);
|
extern void bgp_peer_clear_node_queue_drain_immediate(struct peer *peer);
|
||||||
extern void bgp_process_queues_drain_immediate(void);
|
extern void bgp_process_queues_drain_immediate(void);
|
||||||
|
@ -691,7 +691,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp,
|
|||||||
safi)) {
|
safi)) {
|
||||||
if (subgroup_announce_check(dest, ri, subgrp,
|
if (subgroup_announce_check(dest, ri, subgrp,
|
||||||
dest_p, &attr,
|
dest_p, &attr,
|
||||||
false)) {
|
NULL)) {
|
||||||
/* Check if route can be advertised */
|
/* Check if route can be advertised */
|
||||||
if (advertise) {
|
if (advertise) {
|
||||||
if (!bgp_check_withdrawal(bgp,
|
if (!bgp_check_withdrawal(bgp,
|
||||||
@ -910,7 +910,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
|
|||||||
if (subgroup_announce_check(
|
if (subgroup_announce_check(
|
||||||
dest, pi, subgrp,
|
dest, pi, subgrp,
|
||||||
bgp_dest_get_prefix(dest),
|
bgp_dest_get_prefix(dest),
|
||||||
&attr, false))
|
&attr, NULL))
|
||||||
bgp_adj_out_set_subgroup(
|
bgp_adj_out_set_subgroup(
|
||||||
dest, subgrp, &attr,
|
dest, subgrp, &attr,
|
||||||
pi);
|
pi);
|
||||||
|
@ -19,6 +19,7 @@ route-map ADV-MAP-1 permit 20
|
|||||||
!
|
!
|
||||||
route-map ADV-MAP-2 permit 10
|
route-map ADV-MAP-2 permit 10
|
||||||
match ip address prefix-list IP2
|
match ip address prefix-list IP2
|
||||||
|
set metric 911
|
||||||
!
|
!
|
||||||
route-map EXIST-MAP permit 10
|
route-map EXIST-MAP permit 10
|
||||||
match community DEFAULT-ROUTE
|
match community DEFAULT-ROUTE
|
||||||
|
@ -334,7 +334,7 @@ def test_bgp_conditional_advertisement():
|
|||||||
"192.0.2.1/32": None,
|
"192.0.2.1/32": None,
|
||||||
"192.0.2.5/32": None,
|
"192.0.2.5/32": None,
|
||||||
"10.139.224.0/20": None,
|
"10.139.224.0/20": None,
|
||||||
"203.0.113.1/32": [{"protocol": "bgp"}],
|
"203.0.113.1/32": [{"protocol": "bgp", "metric": 911}],
|
||||||
}
|
}
|
||||||
return topotest.json_cmp(output, expected)
|
return topotest.json_cmp(output, expected)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user