mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-29 18:56:41 +00:00
Merge pull request #9475 from iqras23/change1
bgpd: VRF-Lite fix nexthop type
This commit is contained in:
commit
0f64a435db
@ -691,6 +691,8 @@ unsigned int attrhash_key_make(const void *p)
|
|||||||
key = jhash(attr->mp_nexthop_local.s6_addr, IPV6_MAX_BYTELEN, key);
|
key = jhash(attr->mp_nexthop_local.s6_addr, IPV6_MAX_BYTELEN, key);
|
||||||
MIX3(attr->nh_ifindex, attr->nh_lla_ifindex, attr->distance);
|
MIX3(attr->nh_ifindex, attr->nh_lla_ifindex, attr->distance);
|
||||||
MIX(attr->rmap_table_id);
|
MIX(attr->rmap_table_id);
|
||||||
|
MIX(attr->nh_type);
|
||||||
|
MIX(attr->bh_type);
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
@ -747,7 +749,9 @@ bool attrhash_cmp(const void *p1, const void *p2)
|
|||||||
&& attr1->distance == attr2->distance
|
&& attr1->distance == attr2->distance
|
||||||
&& srv6_l3vpn_same(attr1->srv6_l3vpn, attr2->srv6_l3vpn)
|
&& srv6_l3vpn_same(attr1->srv6_l3vpn, attr2->srv6_l3vpn)
|
||||||
&& srv6_vpn_same(attr1->srv6_vpn, attr2->srv6_vpn)
|
&& 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,6 +307,12 @@ struct attr {
|
|||||||
/* EVPN DF preference and algorithm for DF election on local ESs */
|
/* EVPN DF preference and algorithm for DF election on local ESs */
|
||||||
uint16_t df_pref;
|
uint16_t df_pref;
|
||||||
uint8_t df_alg;
|
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 */
|
/* rmap_change_flags definition */
|
||||||
|
@ -8066,8 +8066,9 @@ DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
|
|||||||
void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
|
void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
|
||||||
const union g_addr *nexthop, ifindex_t ifindex,
|
const union g_addr *nexthop, ifindex_t ifindex,
|
||||||
enum nexthop_types_t nhtype, uint8_t distance,
|
enum nexthop_types_t nhtype, uint8_t distance,
|
||||||
uint32_t metric, uint8_t type,
|
enum blackhole_type bhtype, uint32_t metric,
|
||||||
unsigned short instance, route_tag_t tag)
|
uint8_t type, unsigned short instance,
|
||||||
|
route_tag_t tag)
|
||||||
{
|
{
|
||||||
struct bgp_path_info *new;
|
struct bgp_path_info *new;
|
||||||
struct bgp_path_info *bpi;
|
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;
|
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
attr.bh_type = bhtype;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
attr.nh_type = nhtype;
|
||||||
attr.nh_ifindex = ifindex;
|
attr.nh_ifindex = ifindex;
|
||||||
|
|
||||||
attr.med = metric;
|
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,
|
extern void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
|
||||||
const union g_addr *nexthop, ifindex_t ifindex,
|
const union g_addr *nexthop, ifindex_t ifindex,
|
||||||
enum nexthop_types_t nhtype, uint8_t distance,
|
enum nexthop_types_t nhtype, uint8_t distance,
|
||||||
uint32_t metric, uint8_t type,
|
enum blackhole_type bhtype, uint32_t metric,
|
||||||
unsigned short instance, route_tag_t tag);
|
uint8_t type, unsigned short instance,
|
||||||
|
route_tag_t tag);
|
||||||
extern void bgp_redistribute_delete(struct bgp *, struct prefix *, uint8_t,
|
extern void bgp_redistribute_delete(struct bgp *, struct prefix *, uint8_t,
|
||||||
unsigned short);
|
unsigned short);
|
||||||
extern void bgp_redistribute_withdraw(struct bgp *, afi_t, int, 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)
|
static int zebra_read_route(ZAPI_CALLBACK_ARGS)
|
||||||
{
|
{
|
||||||
enum nexthop_types_t nhtype;
|
enum nexthop_types_t nhtype;
|
||||||
|
enum blackhole_type bhtype = BLACKHOLE_UNSPEC;
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
union g_addr nexthop;
|
union g_addr nexthop = {};
|
||||||
ifindex_t ifindex;
|
ifindex_t ifindex;
|
||||||
int add, i;
|
int add, i;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
@ -494,10 +495,16 @@ static int zebra_read_route(ZAPI_CALLBACK_ARGS)
|
|||||||
&& IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
|
&& IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nexthop = api.nexthops[0].gate;
|
|
||||||
ifindex = api.nexthops[0].ifindex;
|
ifindex = api.nexthops[0].ifindex;
|
||||||
nhtype = api.nexthops[0].type;
|
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);
|
add = (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD);
|
||||||
if (add) {
|
if (add) {
|
||||||
/*
|
/*
|
||||||
@ -517,8 +524,8 @@ static int zebra_read_route(ZAPI_CALLBACK_ARGS)
|
|||||||
|
|
||||||
/* Now perform the add/update. */
|
/* Now perform the add/update. */
|
||||||
bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex,
|
bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex,
|
||||||
nhtype, api.distance, api.metric, api.type,
|
nhtype, bhtype, api.distance, api.metric,
|
||||||
api.instance, api.tag);
|
api.type, api.instance, api.tag);
|
||||||
} else {
|
} else {
|
||||||
bgp_redistribute_delete(bgp, &api.prefix, api.type,
|
bgp_redistribute_delete(bgp, &api.prefix, api.type,
|
||||||
api.instance);
|
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
|
* a VRF (which are programmed as onlink on l3-vni SVI) as well as
|
||||||
* connected routes leaked into a VRF.
|
* 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,
|
* If the nexthop is EVPN overlay index gateway IP,
|
||||||
* treat the nexthop as NEXTHOP_TYPE_IPV4
|
* 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);
|
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
|
||||||
api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
|
api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
|
||||||
}
|
}
|
||||||
} else if (nh_othervrf &&
|
} else if (nh_othervrf && api_nh->gate.ipv4.s_addr == INADDR_ANY) {
|
||||||
api_nh->gate.ipv4.s_addr == INADDR_ANY) {
|
|
||||||
api_nh->type = NEXTHOP_TYPE_IFINDEX;
|
api_nh->type = NEXTHOP_TYPE_IFINDEX;
|
||||||
api_nh->ifindex = attr->nh_ifindex;
|
api_nh->ifindex = attr->nh_ifindex;
|
||||||
} else
|
} else
|
||||||
@ -1113,8 +1121,10 @@ static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
|
|||||||
attr = pi->attr;
|
attr = pi->attr;
|
||||||
api_nh->vrf_id = nh_bgp->vrf_id;
|
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,
|
* If the nexthop is EVPN overlay index gateway IP,
|
||||||
* treat the nexthop as NEXTHOP_TYPE_IPV4
|
* 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;
|
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;
|
api_nh->gate.ipv6 = *nexthop;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -519,12 +519,13 @@ struct nexthop *nexthop_from_ipv6_ifindex(const struct in6_addr *ipv6,
|
|||||||
return nexthop;
|
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;
|
struct nexthop *nexthop;
|
||||||
|
|
||||||
nexthop = nexthop_new();
|
nexthop = nexthop_new();
|
||||||
nexthop->vrf_id = VRF_DEFAULT;
|
nexthop->vrf_id = nh_vrf_id;
|
||||||
nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
|
nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
|
||||||
nexthop->bh_type = bh_type;
|
nexthop->bh_type = bh_type;
|
||||||
|
|
||||||
|
@ -182,7 +182,8 @@ struct nexthop *nexthop_from_ipv6(const struct in6_addr *ipv6,
|
|||||||
vrf_id_t vrf_id);
|
vrf_id_t vrf_id);
|
||||||
struct nexthop *nexthop_from_ipv6_ifindex(const struct in6_addr *ipv6,
|
struct nexthop *nexthop_from_ipv6_ifindex(const struct in6_addr *ipv6,
|
||||||
ifindex_t ifindex, vrf_id_t vrf_id);
|
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.
|
* Hash a nexthop. Suitable for use with hash tables.
|
||||||
|
@ -112,15 +112,15 @@ static void test_run_first(void)
|
|||||||
nexthop_free(nh2);
|
nexthop_free(nh2);
|
||||||
|
|
||||||
/* Blackhole */
|
/* Blackhole */
|
||||||
nh1 = nexthop_from_blackhole(BLACKHOLE_REJECT);
|
nh1 = nexthop_from_blackhole(BLACKHOLE_REJECT, 0);
|
||||||
nh2 = nexthop_from_blackhole(BLACKHOLE_REJECT);
|
nh2 = nexthop_from_blackhole(BLACKHOLE_REJECT, 0);
|
||||||
|
|
||||||
ret = nexthop_cmp_basic(nh1, nh2);
|
ret = nexthop_cmp_basic(nh1, nh2);
|
||||||
assert(ret == 0);
|
assert(ret == 0);
|
||||||
|
|
||||||
nexthop_free(nh2);
|
nexthop_free(nh2);
|
||||||
|
|
||||||
nh2 = nexthop_from_blackhole(BLACKHOLE_NULL);
|
nh2 = nexthop_from_blackhole(BLACKHOLE_NULL, 0);
|
||||||
|
|
||||||
ret = nexthop_cmp_basic(nh1, nh2);
|
ret = nexthop_cmp_basic(nh1, nh2);
|
||||||
assert(ret != 0);
|
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",
|
zlog_debug("%s: nh blackhole %d",
|
||||||
__func__, api_nh->bh_type);
|
__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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,9 +357,11 @@ static void show_nexthop_detail_helper(struct vty *vty,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((re->vrf_id != nexthop->vrf_id)
|
if (re->vrf_id != nexthop->vrf_id) {
|
||||||
&& (nexthop->type != NEXTHOP_TYPE_BLACKHOLE))
|
struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
|
||||||
vty_out(vty, "(vrf %s)", vrf_id_to_name(nexthop->vrf_id));
|
|
||||||
|
vty_out(vty, "(vrf %s)", VRF_LOGNAME(vrf));
|
||||||
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
|
||||||
vty_out(vty, " (duplicate nexthop removed)");
|
vty_out(vty, " (duplicate nexthop removed)");
|
||||||
@ -607,8 +609,7 @@ static void show_route_nexthop_helper(struct vty *vty,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((re == NULL || (nexthop->vrf_id != re->vrf_id))
|
if ((re == NULL || (nexthop->vrf_id != re->vrf_id)))
|
||||||
&& (nexthop->type != NEXTHOP_TYPE_BLACKHOLE))
|
|
||||||
vty_out(vty, " (vrf %s)", vrf_id_to_name(nexthop->vrf_id));
|
vty_out(vty, " (vrf %s)", vrf_id_to_name(nexthop->vrf_id));
|
||||||
|
|
||||||
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
||||||
@ -780,8 +781,7 @@ static void show_nexthop_json_helper(json_object *json_nexthop,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((nexthop->vrf_id != re->vrf_id)
|
if (nexthop->vrf_id != re->vrf_id)
|
||||||
&& (nexthop->type != NEXTHOP_TYPE_BLACKHOLE))
|
|
||||||
json_object_string_add(json_nexthop, "vrf",
|
json_object_string_add(json_nexthop, "vrf",
|
||||||
vrf_id_to_name(nexthop->vrf_id));
|
vrf_id_to_name(nexthop->vrf_id));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user