mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 14:29:47 +00:00
bgpd: VRF-Lite fix nexthop type
Description: Change is intended for fixing the following issues related to vrf route leaking: Routes with special nexthops i.e. blackhole/sink routes when imported, are not programmed into the FIB and corresponding nexthop is set as 'inactive', nexthop interface as 'unknown'. While importing/leaking routes between VRFs, in case of special nexthop(ipv4/ipv6) once bgp announces route(s) to zebra, nexthop type is incorrectly set as NEXTHOP_TYPE_IPV6_IFINDEX/NEXTHOP_TYPE_IFINDEX i.e. directly connected even though we are not able to resolve through an interface. This leads to nexthop_active_check marking nexthop !NEXTHOP_FLAG_ACTIVE. Unable to find the active nexthop(s), route is not programmed into the FIB. Whenever BGP leaks routes, set the correct nexthop type, so that route gets resolved and correctly programmed into the FIB, in the imported vrf. Co-authored-by: Kantesh Mundaragi <kmundaragi@vmware.com> Signed-off-by: Iqra Siddiqui <imujeebsiddi@vmware.com>
This commit is contained in:
parent
d9377cb626
commit
0789eb69e5
@ -691,6 +691,8 @@ unsigned int attrhash_key_make(const void *p)
|
||||
key = jhash(attr->mp_nexthop_local.s6_addr, IPV6_MAX_BYTELEN, key);
|
||||
MIX3(attr->nh_ifindex, attr->nh_lla_ifindex, attr->distance);
|
||||
MIX(attr->rmap_table_id);
|
||||
MIX(attr->nh_type);
|
||||
MIX(attr->bh_type);
|
||||
|
||||
return key;
|
||||
}
|
||||
@ -747,7 +749,9 @@ bool attrhash_cmp(const void *p1, const void *p2)
|
||||
&& attr1->distance == attr2->distance
|
||||
&& srv6_l3vpn_same(attr1->srv6_l3vpn, attr2->srv6_l3vpn)
|
||||
&& srv6_vpn_same(attr1->srv6_vpn, attr2->srv6_vpn)
|
||||
&& attr1->srte_color == attr2->srte_color)
|
||||
&& attr1->srte_color == attr2->srte_color
|
||||
&& attr1->nh_type == attr2->nh_type
|
||||
&& attr1->bh_type == attr2->bh_type)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -307,6 +307,12 @@ struct attr {
|
||||
/* EVPN DF preference and algorithm for DF election on local ESs */
|
||||
uint16_t df_pref;
|
||||
uint8_t df_alg;
|
||||
|
||||
/* Nexthop type */
|
||||
enum nexthop_types_t nh_type;
|
||||
|
||||
/* If NEXTHOP_TYPE_BLACKHOLE, then blackhole type */
|
||||
enum blackhole_type bh_type;
|
||||
};
|
||||
|
||||
/* rmap_change_flags definition */
|
||||
|
@ -8066,8 +8066,9 @@ DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
|
||||
void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
|
||||
const union g_addr *nexthop, ifindex_t ifindex,
|
||||
enum nexthop_types_t nhtype, uint8_t distance,
|
||||
uint32_t metric, uint8_t type,
|
||||
unsigned short instance, route_tag_t tag)
|
||||
enum blackhole_type bhtype, uint32_t metric,
|
||||
uint8_t type, unsigned short instance,
|
||||
route_tag_t tag)
|
||||
{
|
||||
struct bgp_path_info *new;
|
||||
struct bgp_path_info *bpi;
|
||||
@ -8109,8 +8110,10 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
|
||||
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
|
||||
break;
|
||||
}
|
||||
attr.bh_type = bhtype;
|
||||
break;
|
||||
}
|
||||
attr.nh_type = nhtype;
|
||||
attr.nh_ifindex = ifindex;
|
||||
|
||||
attr.med = metric;
|
||||
|
@ -642,8 +642,9 @@ extern bool bgp_maximum_prefix_overflow(struct peer *, afi_t, safi_t, int);
|
||||
extern void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
|
||||
const union g_addr *nexthop, ifindex_t ifindex,
|
||||
enum nexthop_types_t nhtype, uint8_t distance,
|
||||
uint32_t metric, uint8_t type,
|
||||
unsigned short instance, route_tag_t tag);
|
||||
enum blackhole_type bhtype, uint32_t metric,
|
||||
uint8_t type, unsigned short instance,
|
||||
route_tag_t tag);
|
||||
extern void bgp_redistribute_delete(struct bgp *, struct prefix *, uint8_t,
|
||||
unsigned short);
|
||||
extern void bgp_redistribute_withdraw(struct bgp *, afi_t, int, unsigned short);
|
||||
|
@ -472,8 +472,9 @@ static int bgp_interface_vrf_update(ZAPI_CALLBACK_ARGS)
|
||||
static int zebra_read_route(ZAPI_CALLBACK_ARGS)
|
||||
{
|
||||
enum nexthop_types_t nhtype;
|
||||
enum blackhole_type bhtype = BLACKHOLE_UNSPEC;
|
||||
struct zapi_route api;
|
||||
union g_addr nexthop;
|
||||
union g_addr nexthop = {};
|
||||
ifindex_t ifindex;
|
||||
int add, i;
|
||||
struct bgp *bgp;
|
||||
@ -494,10 +495,16 @@ static int zebra_read_route(ZAPI_CALLBACK_ARGS)
|
||||
&& IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
|
||||
return 0;
|
||||
|
||||
nexthop = api.nexthops[0].gate;
|
||||
ifindex = api.nexthops[0].ifindex;
|
||||
nhtype = api.nexthops[0].type;
|
||||
|
||||
/* api_nh structure has union of gate and bh_type */
|
||||
if (nhtype == NEXTHOP_TYPE_BLACKHOLE) {
|
||||
/* bh_type is only applicable if NEXTHOP_TYPE_BLACKHOLE*/
|
||||
bhtype = api.nexthops[0].bh_type;
|
||||
} else
|
||||
nexthop = api.nexthops[0].gate;
|
||||
|
||||
add = (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD);
|
||||
if (add) {
|
||||
/*
|
||||
@ -517,8 +524,8 @@ static int zebra_read_route(ZAPI_CALLBACK_ARGS)
|
||||
|
||||
/* Now perform the add/update. */
|
||||
bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex,
|
||||
nhtype, api.distance, api.metric, api.type,
|
||||
api.instance, api.tag);
|
||||
nhtype, bhtype, api.distance, api.metric,
|
||||
api.type, api.instance, api.tag);
|
||||
} else {
|
||||
bgp_redistribute_delete(bgp, &api.prefix, api.type,
|
||||
api.instance);
|
||||
@ -1076,8 +1083,10 @@ static bool update_ipv4nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
|
||||
* a VRF (which are programmed as onlink on l3-vni SVI) as well as
|
||||
* connected routes leaked into a VRF.
|
||||
*/
|
||||
if (is_evpn) {
|
||||
|
||||
if (attr->nh_type == NEXTHOP_TYPE_BLACKHOLE) {
|
||||
api_nh->type = attr->nh_type;
|
||||
api_nh->bh_type = attr->bh_type;
|
||||
} else if (is_evpn) {
|
||||
/*
|
||||
* If the nexthop is EVPN overlay index gateway IP,
|
||||
* treat the nexthop as NEXTHOP_TYPE_IPV4
|
||||
@ -1090,8 +1099,7 @@ static bool update_ipv4nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
|
||||
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
|
||||
api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
|
||||
}
|
||||
} else if (nh_othervrf &&
|
||||
api_nh->gate.ipv4.s_addr == INADDR_ANY) {
|
||||
} else if (nh_othervrf && api_nh->gate.ipv4.s_addr == INADDR_ANY) {
|
||||
api_nh->type = NEXTHOP_TYPE_IFINDEX;
|
||||
api_nh->ifindex = attr->nh_ifindex;
|
||||
} else
|
||||
@ -1113,8 +1121,10 @@ static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
|
||||
attr = pi->attr;
|
||||
api_nh->vrf_id = nh_bgp->vrf_id;
|
||||
|
||||
if (is_evpn) {
|
||||
|
||||
if (attr->nh_type == NEXTHOP_TYPE_BLACKHOLE) {
|
||||
api_nh->type = attr->nh_type;
|
||||
api_nh->bh_type = attr->bh_type;
|
||||
} else if (is_evpn) {
|
||||
/*
|
||||
* If the nexthop is EVPN overlay index gateway IP,
|
||||
* treat the nexthop as NEXTHOP_TYPE_IPV4
|
||||
@ -1169,7 +1179,8 @@ static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
|
||||
api_nh->ifindex = 0;
|
||||
}
|
||||
}
|
||||
if (nexthop)
|
||||
/* api_nh structure has union of gate and bh_type */
|
||||
if (nexthop && api_nh->type != NEXTHOP_TYPE_BLACKHOLE)
|
||||
api_nh->gate.ipv6 = *nexthop;
|
||||
|
||||
return true;
|
||||
|
@ -519,12 +519,13 @@ struct nexthop *nexthop_from_ipv6_ifindex(const struct in6_addr *ipv6,
|
||||
return nexthop;
|
||||
}
|
||||
|
||||
struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type)
|
||||
struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type,
|
||||
vrf_id_t nh_vrf_id)
|
||||
{
|
||||
struct nexthop *nexthop;
|
||||
|
||||
nexthop = nexthop_new();
|
||||
nexthop->vrf_id = VRF_DEFAULT;
|
||||
nexthop->vrf_id = nh_vrf_id;
|
||||
nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
|
||||
nexthop->bh_type = bh_type;
|
||||
|
||||
|
@ -182,7 +182,8 @@ struct nexthop *nexthop_from_ipv6(const struct in6_addr *ipv6,
|
||||
vrf_id_t vrf_id);
|
||||
struct nexthop *nexthop_from_ipv6_ifindex(const struct in6_addr *ipv6,
|
||||
ifindex_t ifindex, vrf_id_t vrf_id);
|
||||
struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type);
|
||||
struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type,
|
||||
vrf_id_t nh_vrf_id);
|
||||
|
||||
/*
|
||||
* Hash a nexthop. Suitable for use with hash tables.
|
||||
|
@ -112,15 +112,15 @@ static void test_run_first(void)
|
||||
nexthop_free(nh2);
|
||||
|
||||
/* Blackhole */
|
||||
nh1 = nexthop_from_blackhole(BLACKHOLE_REJECT);
|
||||
nh2 = nexthop_from_blackhole(BLACKHOLE_REJECT);
|
||||
nh1 = nexthop_from_blackhole(BLACKHOLE_REJECT, 0);
|
||||
nh2 = nexthop_from_blackhole(BLACKHOLE_REJECT, 0);
|
||||
|
||||
ret = nexthop_cmp_basic(nh1, nh2);
|
||||
assert(ret == 0);
|
||||
|
||||
nexthop_free(nh2);
|
||||
|
||||
nh2 = nexthop_from_blackhole(BLACKHOLE_NULL);
|
||||
nh2 = nexthop_from_blackhole(BLACKHOLE_NULL, 0);
|
||||
|
||||
ret = nexthop_cmp_basic(nh1, nh2);
|
||||
assert(ret != 0);
|
||||
|
@ -1611,7 +1611,8 @@ static struct nexthop *nexthop_from_zapi(const struct zapi_nexthop *api_nh,
|
||||
zlog_debug("%s: nh blackhole %d",
|
||||
__func__, api_nh->bh_type);
|
||||
|
||||
nexthop = nexthop_from_blackhole(api_nh->bh_type);
|
||||
nexthop =
|
||||
nexthop_from_blackhole(api_nh->bh_type, api_nh->vrf_id);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -357,9 +357,11 @@ static void show_nexthop_detail_helper(struct vty *vty,
|
||||
break;
|
||||
}
|
||||
|
||||
if ((re->vrf_id != nexthop->vrf_id)
|
||||
&& (nexthop->type != NEXTHOP_TYPE_BLACKHOLE))
|
||||
vty_out(vty, "(vrf %s)", vrf_id_to_name(nexthop->vrf_id));
|
||||
if (re->vrf_id != nexthop->vrf_id) {
|
||||
struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
|
||||
|
||||
vty_out(vty, "(vrf %s)", VRF_LOGNAME(vrf));
|
||||
}
|
||||
|
||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
|
||||
vty_out(vty, " (duplicate nexthop removed)");
|
||||
@ -607,8 +609,7 @@ static void show_route_nexthop_helper(struct vty *vty,
|
||||
break;
|
||||
}
|
||||
|
||||
if ((re == NULL || (nexthop->vrf_id != re->vrf_id))
|
||||
&& (nexthop->type != NEXTHOP_TYPE_BLACKHOLE))
|
||||
if ((re == NULL || (nexthop->vrf_id != re->vrf_id)))
|
||||
vty_out(vty, " (vrf %s)", vrf_id_to_name(nexthop->vrf_id));
|
||||
|
||||
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
||||
@ -780,8 +781,7 @@ static void show_nexthop_json_helper(json_object *json_nexthop,
|
||||
break;
|
||||
}
|
||||
|
||||
if ((nexthop->vrf_id != re->vrf_id)
|
||||
&& (nexthop->type != NEXTHOP_TYPE_BLACKHOLE))
|
||||
if (nexthop->vrf_id != re->vrf_id)
|
||||
json_object_string_add(json_nexthop, "vrf",
|
||||
vrf_id_to_name(nexthop->vrf_id));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user