mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-12 09:52:27 +00:00
bgpd: Allow EVPN advertise route-map to modify attributes
Ensure that the EVPN advertise route-map is applied on a copy of the original path_info and associated attribute, so that if the route-map has SET clauses, they can operate properly. This closely follows the model already in use in other route-map application code. Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com> Reviewed-by: Don Slice <dslice@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
d69a76ac1a
commit
e34291b86a
@ -4576,16 +4576,34 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
|
|||||||
/* apply the route-map */
|
/* apply the route-map */
|
||||||
if (bgp_vrf->adv_cmd_rmap[afi][safi].map) {
|
if (bgp_vrf->adv_cmd_rmap[afi][safi].map) {
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
struct bgp_path_info tmp_pi;
|
||||||
|
struct bgp_path_info_extra tmp_pie;
|
||||||
|
struct attr tmp_attr;
|
||||||
|
|
||||||
|
tmp_attr = *pi->attr;
|
||||||
|
|
||||||
|
/* Fill temp path_info */
|
||||||
|
prep_for_rmap_apply(
|
||||||
|
&tmp_pi, &tmp_pie, rn, pi,
|
||||||
|
pi->peer, &tmp_attr);
|
||||||
|
|
||||||
|
RESET_FLAG(tmp_attr.rmap_change_flags);
|
||||||
|
|
||||||
ret = route_map_apply(
|
ret = route_map_apply(
|
||||||
bgp_vrf->adv_cmd_rmap[afi][safi]
|
bgp_vrf->adv_cmd_rmap[afi][safi]
|
||||||
.map,
|
.map,
|
||||||
&rn->p, RMAP_BGP, pi);
|
&rn->p, RMAP_BGP, &tmp_pi);
|
||||||
if (ret == RMAP_DENYMATCH)
|
if (ret == RMAP_DENYMATCH) {
|
||||||
|
bgp_attr_flush(&tmp_attr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bgp_evpn_advertise_type5_route(
|
bgp_evpn_advertise_type5_route(
|
||||||
bgp_vrf, &rn->p, pi->attr, afi, safi);
|
bgp_vrf, &rn->p, &tmp_attr,
|
||||||
|
afi, safi);
|
||||||
|
} else
|
||||||
|
bgp_evpn_advertise_type5_route(
|
||||||
|
bgp_vrf, &rn->p, pi->attr,
|
||||||
|
afi, safi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1875,16 +1875,9 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
|
|||||||
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};
|
||||||
|
|
||||||
memset(&rmap_path, 0, sizeof(struct bgp_path_info));
|
/* Fill temp path_info */
|
||||||
rmap_path.peer = peer;
|
prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra,
|
||||||
rmap_path.attr = attr;
|
rn, pi, peer, attr);
|
||||||
rmap_path.net = rn;
|
|
||||||
|
|
||||||
if (pi->extra) {
|
|
||||||
memcpy(&dummy_rmap_path_extra, pi->extra,
|
|
||||||
sizeof(struct bgp_path_info_extra));
|
|
||||||
rmap_path.extra = &dummy_rmap_path_extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* don't confuse inbound and outbound setting */
|
/* don't confuse inbound and outbound setting */
|
||||||
RESET_FLAG(attr->rmap_change_flags);
|
RESET_FLAG(attr->rmap_change_flags);
|
||||||
@ -2693,16 +2686,30 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
|
|||||||
/* apply the route-map */
|
/* apply the route-map */
|
||||||
if (bgp->adv_cmd_rmap[afi][safi].map) {
|
if (bgp->adv_cmd_rmap[afi][safi].map) {
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
struct bgp_path_info rmap_path;
|
||||||
|
struct bgp_path_info_extra rmap_path_extra;
|
||||||
|
struct attr dummy_attr;
|
||||||
|
|
||||||
|
dummy_attr = *new_select->attr;
|
||||||
|
|
||||||
|
/* Fill temp path_info */
|
||||||
|
prep_for_rmap_apply(
|
||||||
|
&rmap_path, &rmap_path_extra,
|
||||||
|
rn, new_select, new_select->peer,
|
||||||
|
&dummy_attr);
|
||||||
|
|
||||||
|
RESET_FLAG(dummy_attr.rmap_change_flags);
|
||||||
|
|
||||||
ret = route_map_apply(
|
ret = route_map_apply(
|
||||||
bgp->adv_cmd_rmap[afi][safi].map,
|
bgp->adv_cmd_rmap[afi][safi].map,
|
||||||
&rn->p, RMAP_BGP, new_select);
|
&rn->p, RMAP_BGP, &rmap_path);
|
||||||
if (ret == RMAP_DENYMATCH)
|
if (ret == RMAP_DENYMATCH) {
|
||||||
|
bgp_attr_flush(&dummy_attr);
|
||||||
bgp_evpn_withdraw_type5_route(
|
bgp_evpn_withdraw_type5_route(
|
||||||
bgp, &rn->p, afi, safi);
|
bgp, &rn->p, afi, safi);
|
||||||
else
|
} else
|
||||||
bgp_evpn_advertise_type5_route(
|
bgp_evpn_advertise_type5_route(
|
||||||
bgp, &rn->p, new_select->attr,
|
bgp, &rn->p, &dummy_attr,
|
||||||
afi, safi);
|
afi, safi);
|
||||||
} else {
|
} else {
|
||||||
bgp_evpn_advertise_type5_route(bgp,
|
bgp_evpn_advertise_type5_route(bgp,
|
||||||
|
@ -467,6 +467,23 @@ static inline bool is_pi_family_matching(struct bgp_path_info *pi,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void prep_for_rmap_apply(struct bgp_path_info *dst_pi,
|
||||||
|
struct bgp_path_info_extra *dst_pie,
|
||||||
|
struct bgp_node *rn,
|
||||||
|
struct bgp_path_info *src_pi,
|
||||||
|
struct peer *peer, struct attr *attr)
|
||||||
|
{
|
||||||
|
memset(dst_pi, 0, sizeof(struct bgp_path_info));
|
||||||
|
dst_pi->peer = peer;
|
||||||
|
dst_pi->attr = attr;
|
||||||
|
dst_pi->net = rn;
|
||||||
|
if (src_pi->extra) {
|
||||||
|
memcpy(dst_pie, src_pi->extra,
|
||||||
|
sizeof(struct bgp_path_info_extra));
|
||||||
|
dst_pi->extra = dst_pie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* called before bgp_process() */
|
/* called before bgp_process() */
|
||||||
DECLARE_HOOK(bgp_process,
|
DECLARE_HOOK(bgp_process,
|
||||||
(struct bgp *bgp, afi_t afi, safi_t safi,
|
(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
|
Loading…
Reference in New Issue
Block a user