mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-01-04 17:20:10 +00:00
lib, zebra, bgpd: Move route EVPN flag to nexthop
Multipath route may have mixed nexthops of EVPN and IP unicast. Move EVPN flag to nexthop to support such cases. Signed-off-by: Xiao Liang <shaw.leon@gmail.com>
This commit is contained in:
parent
db6d4c8375
commit
5609e70fb8
@ -1132,6 +1132,7 @@ static bool update_ipv4nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
|
||||
api_nh->type = NEXTHOP_TYPE_IPV4;
|
||||
else {
|
||||
api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
|
||||
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN);
|
||||
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
|
||||
api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
|
||||
}
|
||||
@ -1170,6 +1171,7 @@ static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
|
||||
api_nh->type = NEXTHOP_TYPE_IPV6;
|
||||
else {
|
||||
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
||||
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN);
|
||||
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
|
||||
api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
|
||||
}
|
||||
@ -1268,7 +1270,6 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
|
||||
mpls_label_t label;
|
||||
struct bgp_sid_info *sid_info;
|
||||
int nh_othervrf = 0;
|
||||
bool is_evpn;
|
||||
bool nh_updated = false;
|
||||
bool do_wt_ecmp;
|
||||
uint64_t cum_bw = 0;
|
||||
@ -1319,11 +1320,6 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
|
||||
|
||||
tag = info->attr->tag;
|
||||
|
||||
/* If the route's source is EVPN, flag as such. */
|
||||
is_evpn = is_route_parent_evpn(info);
|
||||
if (is_evpn)
|
||||
SET_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE);
|
||||
|
||||
if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED
|
||||
|| info->sub_type == BGP_ROUTE_AGGREGATE) {
|
||||
SET_FLAG(api.flags, ZEBRA_FLAG_IBGP);
|
||||
@ -1364,6 +1360,7 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
|
||||
|
||||
for (; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
|
||||
uint32_t nh_weight;
|
||||
bool is_evpn;
|
||||
|
||||
if (valid_nh_count >= multipath_num)
|
||||
break;
|
||||
@ -1430,6 +1427,8 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
|
||||
BGP_ORIGINAL_UPDATE(bgp_orig, mpinfo, bgp);
|
||||
|
||||
if (nh_family == AF_INET) {
|
||||
is_evpn = is_route_parent_evpn(mpinfo);
|
||||
|
||||
nh_updated = update_ipv4nh_for_route_install(
|
||||
nh_othervrf, bgp_orig,
|
||||
&mpinfo_cp->attr->nexthop, mpinfo_cp->attr,
|
||||
@ -1441,6 +1440,8 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
|
||||
nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp,
|
||||
&ifindex);
|
||||
|
||||
is_evpn = is_route_parent_evpn(mpinfo);
|
||||
|
||||
if (!nexthop)
|
||||
nh_updated = update_ipv4nh_for_route_install(
|
||||
nh_othervrf, bgp_orig,
|
||||
@ -1465,9 +1466,9 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
|
||||
|| mpinfo->peer->sort == BGP_PEER_CONFED))
|
||||
allow_recursion = true;
|
||||
|
||||
if (mpinfo->extra
|
||||
&& bgp_is_valid_label(&mpinfo->extra->label[0])
|
||||
&& !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
|
||||
if (mpinfo->extra &&
|
||||
bgp_is_valid_label(&mpinfo->extra->label[0]) &&
|
||||
!CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) {
|
||||
mpls_lse_decode(mpinfo->extra->label[0], &label, &ttl,
|
||||
&exp, &bos);
|
||||
|
||||
@ -1485,8 +1486,8 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
|
||||
|
||||
api_nh->weight = nh_weight;
|
||||
|
||||
if (mpinfo->extra && !sid_zero(&mpinfo->extra->sid[0].sid)
|
||||
&& !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
|
||||
if (mpinfo->extra && !sid_zero(&mpinfo->extra->sid[0].sid) &&
|
||||
!CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) {
|
||||
sid_info = &mpinfo->extra->sid[0];
|
||||
|
||||
memcpy(&api_nh->seg6_segs, &sid_info->sid,
|
||||
@ -1613,19 +1614,21 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
|
||||
label_buf[0] = '\0';
|
||||
eth_buf[0] = '\0';
|
||||
segs_buf[0] = '\0';
|
||||
if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)
|
||||
&& !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE))
|
||||
if (CHECK_FLAG(api_nh->flags,
|
||||
ZAPI_NEXTHOP_FLAG_LABEL) &&
|
||||
!CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN))
|
||||
snprintf(label_buf, sizeof(label_buf),
|
||||
"label %u", api_nh->labels[0]);
|
||||
if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6)
|
||||
&& !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
|
||||
if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6) &&
|
||||
!CHECK_FLAG(api_nh->flags,
|
||||
ZAPI_NEXTHOP_FLAG_EVPN)) {
|
||||
inet_ntop(AF_INET6, &api_nh->seg6_segs,
|
||||
sid_buf, sizeof(sid_buf));
|
||||
snprintf(segs_buf, sizeof(segs_buf), "segs %s",
|
||||
sid_buf);
|
||||
}
|
||||
if (CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)
|
||||
&& !is_zero_mac(&api_nh->rmac))
|
||||
if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN) &&
|
||||
!is_zero_mac(&api_nh->rmac))
|
||||
snprintf(eth_buf, sizeof(eth_buf), " RMAC %s",
|
||||
prefix_mac2str(&api_nh->rmac,
|
||||
buf1, sizeof(buf1)));
|
||||
@ -1730,10 +1733,6 @@ void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info,
|
||||
api.tableid = info->attr->rmap_table_id;
|
||||
}
|
||||
|
||||
/* If the route's source is EVPN, flag as such. */
|
||||
if (is_route_parent_evpn(info))
|
||||
SET_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE);
|
||||
|
||||
if (bgp_debug_zebra(p))
|
||||
zlog_debug("Tx route delete VRF %u %pFX", bgp->vrf_id,
|
||||
&api.prefix);
|
||||
|
||||
@ -94,6 +94,7 @@ struct nexthop {
|
||||
#define NEXTHOP_FLAG_RNH_FILTERED (1 << 5) /* rmap filtered, used by rnh */
|
||||
#define NEXTHOP_FLAG_HAS_BACKUP (1 << 6) /* Backup nexthop index is set */
|
||||
#define NEXTHOP_FLAG_SRTE (1 << 7) /* SR-TE color used for BGP traffic */
|
||||
#define NEXTHOP_FLAG_EVPN (1 << 8) /* nexthop is EVPN */
|
||||
|
||||
#define NEXTHOP_IS_ACTIVE(flags) \
|
||||
(CHECK_FLAG(flags, NEXTHOP_FLAG_ACTIVE) \
|
||||
|
||||
@ -1038,7 +1038,7 @@ int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
|
||||
stream_putl(s, api_nh->weight);
|
||||
|
||||
/* Router MAC for EVPN routes. */
|
||||
if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
|
||||
if (CHECK_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_EVPN))
|
||||
stream_put(s, &(api_nh->rmac),
|
||||
sizeof(struct ethaddr));
|
||||
|
||||
@ -1402,7 +1402,7 @@ int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
|
||||
STREAM_GETL(s, api_nh->weight);
|
||||
|
||||
/* Router MAC for EVPN routes. */
|
||||
if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
|
||||
if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN))
|
||||
STREAM_GET(&(api_nh->rmac), s,
|
||||
sizeof(struct ethaddr));
|
||||
|
||||
@ -1830,6 +1830,9 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
|
||||
if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK))
|
||||
SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
|
||||
|
||||
if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_EVPN))
|
||||
SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_EVPN);
|
||||
|
||||
if (nh->nh_label && (nh->nh_label->num_labels > 0)) {
|
||||
|
||||
/* Validate */
|
||||
|
||||
@ -452,6 +452,7 @@ struct zapi_nexthop {
|
||||
#define ZAPI_NEXTHOP_FLAG_HAS_BACKUP 0x08 /* Nexthop has a backup */
|
||||
#define ZAPI_NEXTHOP_FLAG_SEG6 0x10
|
||||
#define ZAPI_NEXTHOP_FLAG_SEG6LOCAL 0x20
|
||||
#define ZAPI_NEXTHOP_FLAG_EVPN 0x40
|
||||
|
||||
/*
|
||||
* ZAPI Nexthop Group. For use with protocol creation of nexthop groups.
|
||||
|
||||
@ -1606,13 +1606,14 @@ static struct nexthop *nexthop_from_zapi(const struct zapi_nexthop *api_nh,
|
||||
/* Special handling for IPv4 routes sourced from EVPN:
|
||||
* the nexthop and associated MAC need to be installed.
|
||||
*/
|
||||
if (CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE)) {
|
||||
if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) {
|
||||
memset(&vtep_ip, 0, sizeof(vtep_ip));
|
||||
vtep_ip.ipa_type = IPADDR_V4;
|
||||
memcpy(&(vtep_ip.ipaddr_v4), &(api_nh->gate.ipv4),
|
||||
sizeof(struct in_addr));
|
||||
zebra_rib_queue_evpn_route_add(
|
||||
api_nh->vrf_id, &api_nh->rmac, &vtep_ip, p);
|
||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN);
|
||||
}
|
||||
break;
|
||||
case NEXTHOP_TYPE_IPV6:
|
||||
@ -1639,13 +1640,14 @@ static struct nexthop *nexthop_from_zapi(const struct zapi_nexthop *api_nh,
|
||||
/* Special handling for IPv6 routes sourced from EVPN:
|
||||
* the nexthop and associated MAC need to be installed.
|
||||
*/
|
||||
if (CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE)) {
|
||||
if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) {
|
||||
memset(&vtep_ip, 0, sizeof(vtep_ip));
|
||||
vtep_ip.ipa_type = IPADDR_V6;
|
||||
memcpy(&vtep_ip.ipaddr_v6, &(api_nh->gate.ipv6),
|
||||
sizeof(struct in6_addr));
|
||||
zebra_rib_queue_evpn_route_add(
|
||||
api_nh->vrf_id, &api_nh->rmac, &vtep_ip, p);
|
||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN);
|
||||
}
|
||||
break;
|
||||
case NEXTHOP_TYPE_BLACKHOLE:
|
||||
|
||||
@ -2562,7 +2562,7 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
|
||||
}
|
||||
|
||||
/* Check for available evpn encapsulations. */
|
||||
if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE))
|
||||
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN))
|
||||
continue;
|
||||
|
||||
zl3vni = zl3vni_from_vrf(nexthop->vrf_id);
|
||||
|
||||
@ -208,7 +208,7 @@ static int netlink_route_info_add_nh(struct netlink_route_info *ri,
|
||||
if (!nhi.gateway && nhi.if_index == 0)
|
||||
return 0;
|
||||
|
||||
if (re && CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)) {
|
||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN)) {
|
||||
nhi.encap_info.encap_type = FPM_NH_ENCAP_VXLAN;
|
||||
|
||||
/* Extract VNI id for the nexthop SVI interface */
|
||||
|
||||
@ -3302,7 +3302,7 @@ static void _route_entry_dump_nh(const struct route_entry *re,
|
||||
if (nexthop->weight)
|
||||
snprintf(wgt_str, sizeof(wgt_str), "wgt %d,", nexthop->weight);
|
||||
|
||||
zlog_debug("%s: %s %s[%u] %svrf %s(%u) %s%s with flags %s%s%s%s%s%s%s%s",
|
||||
zlog_debug("%s: %s %s[%u] %svrf %s(%u) %s%s with flags %s%s%s%s%s%s%s%s%s",
|
||||
straddr, (nexthop->rparent ? " NH" : "NH"), nhname,
|
||||
nexthop->ifindex, label_str, vrf ? vrf->name : "Unknown",
|
||||
nexthop->vrf_id,
|
||||
@ -3327,7 +3327,9 @@ static void _route_entry_dump_nh(const struct route_entry *re,
|
||||
(CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)
|
||||
? "BACKUP " : ""),
|
||||
(CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_SRTE)
|
||||
? "SRTE " : ""));
|
||||
? "SRTE " : ""),
|
||||
(CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN)
|
||||
? "EVPN " : ""));
|
||||
|
||||
}
|
||||
|
||||
@ -3764,6 +3766,8 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||
}
|
||||
|
||||
if (same) {
|
||||
struct nexthop *tmp_nh;
|
||||
|
||||
if (fromkernel && CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)
|
||||
&& !allow_delete) {
|
||||
rib_install_kernel(rn, same, NULL);
|
||||
@ -3776,12 +3780,10 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||
* EVPN - the nexthop (and associated MAC) need to be
|
||||
* uninstalled if no more refs.
|
||||
*/
|
||||
if (CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE)) {
|
||||
struct nexthop *tmp_nh;
|
||||
|
||||
for (ALL_NEXTHOPS(re->nhe->nhg, tmp_nh)) {
|
||||
struct ipaddr vtep_ip;
|
||||
for (ALL_NEXTHOPS(re->nhe->nhg, tmp_nh)) {
|
||||
struct ipaddr vtep_ip;
|
||||
|
||||
if (CHECK_FLAG(tmp_nh->flags, NEXTHOP_FLAG_EVPN)) {
|
||||
memset(&vtep_ip, 0, sizeof(struct ipaddr));
|
||||
if (afi == AFI_IP) {
|
||||
vtep_ip.ipa_type = IPADDR_V4;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user