mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 17:24:26 +00:00
bgpd: Use source route's path attributes for type-5 routes
When an IPv4 or IPv6 unicast route is injected into EVPN as a type-5 route (upon user configuration), ensure that the source route (best path)'s path attributes are used to build the EVPN type-5 route. This will result in correct AS_PATH and ORIGIN attributes for the type-5 route so that it doesn't appear that all type-5 routes are locally sourced. This is necessary to ensure that external paths (IPv4 or IPv6 from EBGP peer) are preferred over internal EVPN paths, if both exist. Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com> Ticket: CM-19051 Reviewed By: CCR-7009 Testing Done: Verify failed scenario
This commit is contained in:
parent
aa9db9e6e2
commit
2f69f6d368
@ -1070,7 +1070,8 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_def,
|
||||
|
||||
/* update evpn type-5 route entry */
|
||||
static int update_evpn_type5_route(struct bgp *bgp_vrf,
|
||||
struct prefix_evpn *evp)
|
||||
struct prefix_evpn *evp,
|
||||
struct attr* src_attr)
|
||||
{
|
||||
afi_t afi = AFI_L2VPN;
|
||||
safi_t safi = SAFI_EVPN;
|
||||
@ -1083,9 +1084,16 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf,
|
||||
if (!bgp_def)
|
||||
return -1;
|
||||
|
||||
/* build path attribute for this route */
|
||||
memset(&attr, 0, sizeof(struct attr));
|
||||
bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
|
||||
/* Build path attribute for this route - use the source attr, if
|
||||
* present, else treat as locally originated.
|
||||
*/
|
||||
if (src_attr)
|
||||
bgp_attr_dup(&attr, src_attr);
|
||||
else {
|
||||
memset(&attr, 0, sizeof(struct attr));
|
||||
bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
|
||||
}
|
||||
/* Set nexthop to ourselves and fill in the Router MAC. */
|
||||
attr.nexthop = bgp_vrf->originator_ip;
|
||||
attr.mp_nexthop_global_in = bgp_vrf->originator_ip;
|
||||
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
|
||||
@ -3222,8 +3230,14 @@ void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf,
|
||||
|
||||
}
|
||||
|
||||
/* advertise ip prefix as type-5 route*/
|
||||
/*
|
||||
* Advertise IP prefix as type-5 route. The afi/safi and src_attr passed
|
||||
* to this function correspond to those of the source IP prefix (best
|
||||
* path in the case of the attr. In the case of a local prefix (when we
|
||||
* are advertising local subnets), the src_attr will be NULL.
|
||||
*/
|
||||
void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,
|
||||
struct attr *src_attr,
|
||||
afi_t afi, safi_t safi)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -3238,29 +3252,39 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,
|
||||
return;
|
||||
|
||||
build_type5_prefix_from_ip_prefix(&evp, p);
|
||||
ret = update_evpn_type5_route(bgp_vrf, &evp);
|
||||
if (ret) {
|
||||
ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
|
||||
if (ret)
|
||||
zlog_err(
|
||||
"%u failed to create type-5 route for prefix %s in vrf %s",
|
||||
"%u: Failed to create type-5 route for prefix %s",
|
||||
bgp_vrf->vrf_id,
|
||||
prefix2str(p, buf, sizeof(buf)),
|
||||
vrf_id_to_name(bgp_vrf->vrf_id));
|
||||
}
|
||||
prefix2str(p, buf, sizeof(buf)));
|
||||
}
|
||||
|
||||
/* advertise all type-5 routes for an address family */
|
||||
/* Inject all prefixes of a particular address-family (currently, IPv4 or
|
||||
* IPv6 unicast) into EVPN as type-5 routes. This is invoked when the
|
||||
* advertisement is enabled.
|
||||
*/
|
||||
void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf,
|
||||
afi_t afi, safi_t safi)
|
||||
{
|
||||
struct bgp_table *table = NULL;
|
||||
struct bgp_node *rn = NULL;
|
||||
struct bgp_info *ri;
|
||||
|
||||
table = bgp_vrf->rib[afi][safi];
|
||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
||||
|
||||
if (!rn->info)
|
||||
continue;
|
||||
bgp_evpn_advertise_type5_route(bgp_vrf, &rn->p, afi, safi);
|
||||
/* Need to identify the "selected" route entry to use its
|
||||
* attribute.
|
||||
* TODO: Support for AddPath for EVPN.
|
||||
*/
|
||||
for (ri = rn->info; ri; ri = ri->next) {
|
||||
if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
|
||||
bgp_evpn_advertise_type5_route(bgp_vrf, &rn->p,
|
||||
ri->attr,
|
||||
afi, safi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@ static inline vni_t label2vni(mpls_label_t *label)
|
||||
|
||||
extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,
|
||||
struct prefix *p,
|
||||
struct attr *src_attr,
|
||||
afi_t afi, safi_t safi);
|
||||
extern void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf,
|
||||
struct prefix *p,
|
||||
|
@ -2226,7 +2226,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
|
||||
/* advertise/withdraw type-5 routes */
|
||||
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
|
||||
if (new_select)
|
||||
bgp_evpn_advertise_type5_route(bgp, &rn->p, afi, safi);
|
||||
bgp_evpn_advertise_type5_route(bgp, &rn->p,
|
||||
new_select->attr,
|
||||
afi, safi);
|
||||
else if (old_select)
|
||||
bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi);
|
||||
}
|
||||
|
@ -1872,10 +1872,12 @@ static void bgp_zebra_process_local_ip_prefix(int cmd,
|
||||
|
||||
if (p.family == AF_INET)
|
||||
return bgp_evpn_advertise_type5_route(bgp_vrf, &p,
|
||||
NULL,
|
||||
AFI_IP,
|
||||
SAFI_UNICAST);
|
||||
else
|
||||
return bgp_evpn_advertise_type5_route(bgp_vrf, &p,
|
||||
NULL,
|
||||
AFI_IP6,
|
||||
SAFI_UNICAST);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user