bgpd: track mpls vpn nexthops

There is no nexthop reachability information for
received MPLS VPN prefixes.
This information is necessary when BGP also acts
as LSR device, and is needed to create an MPLS entry
between two BGP speakers: the next-hop to pick-up
in the MPLS entry has to be connected.

The nexthop reachability information is available
for other non MPLS VPN prefixes, and is handled
by the bgp nexthop cache (bnc) contexts.
Extend the usage of the BNC contexts for L3VPN
prefixes.

Note that the MPLS VPN routes had to be redistributed
as before, to avoid breaking existing deployments
that use FRR as route reflectors. Because of this, the
nexthop reachability status has been maintained to OK
for MPLS VPN prefixes.

Note also that the label allocation per nexthop tracking
was wrongly using the MPLS VPN safi to get a valid BNC
context, when choosing which label to return in the
'vpn_leak_from_vrf_get_per_nexthop_label()' function.
Fix this by using SAFI_UNICAST instead.

Fixes: 577be36a41 ("bgpd: add support for l3vpn per-nexthop label")
Link: https://github.com/FRRouting/frr/pull/13380
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2023-04-21 14:28:28 +02:00
parent 658c5ebe38
commit cd0e9bfbc4
2 changed files with 27 additions and 18 deletions

View File

@ -467,6 +467,9 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
pi->sub_type == BGP_ROUTE_IMPORTED && pi->extra &&
pi->extra->num_labels && !bnc->is_evpn_gwip_nexthop)
return bgp_isvalid_nexthop_for_mpls(bnc, pi);
else if (safi == SAFI_MPLS_VPN)
/* avoid not redistributing mpls vpn routes */
return 1;
else
return (bgp_isvalid_nexthop(bnc));
}
@ -1190,6 +1193,9 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)
bnc_is_valid_nexthop =
bgp_isvalid_nexthop_for_mpls(bnc, path) ? true
: false;
} else if (safi == SAFI_MPLS_VPN) {
/* avoid not redistributing mpls vpn routes */
bnc_is_valid_nexthop = true;
} else {
if (bgp_update_martian_nexthop(
bnc->bgp, afi, safi, path->type,

View File

@ -4621,10 +4621,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
/* Nexthop reachability check - for unicast and
* labeled-unicast.. */
if (((afi == AFI_IP || afi == AFI_IP6)
&& (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
|| (safi == SAFI_EVPN &&
bgp_evpn_is_prefix_nht_supported(p))) {
if (((afi == AFI_IP || afi == AFI_IP6) &&
(safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST ||
safi == SAFI_MPLS_VPN)) ||
(safi == SAFI_EVPN &&
bgp_evpn_is_prefix_nht_supported(p))) {
if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
&& peer->ttl == BGP_DEFAULT_TTL
&& !CHECK_FLAG(peer->flags,
@ -4645,10 +4646,14 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
safi, pi, NULL, connected,
bgp_nht_param_prefix) ||
CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) {
if (accept_own)
bgp_path_info_set_flag(
dest, pi, BGP_PATH_ACCEPT_OWN);
bgp_path_info_set_flag(dest, pi,
BGP_PATH_VALID);
else {
} else {
if (BGP_DEBUG(nht, NHT)) {
zlog_debug("%s(%pI4): NH unresolved",
__func__,
@ -4658,10 +4663,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
BGP_PATH_VALID);
}
} else {
if (accept_own)
bgp_path_info_set_flag(dest, pi,
BGP_PATH_ACCEPT_OWN);
bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
}
@ -4791,9 +4792,10 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
}
/* Nexthop reachability check. */
if (((afi == AFI_IP || afi == AFI_IP6)
&& (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
|| (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
if (((afi == AFI_IP || afi == AFI_IP6) &&
(safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST ||
safi == SAFI_MPLS_VPN)) ||
(safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
&& peer->ttl == BGP_DEFAULT_TTL
&& !CHECK_FLAG(peer->flags,
@ -4808,18 +4810,19 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
connected, bgp_nht_param_prefix) ||
CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) {
if (accept_own)
bgp_path_info_set_flag(dest, new,
BGP_PATH_ACCEPT_OWN);
bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
else {
} else {
if (BGP_DEBUG(nht, NHT))
zlog_debug("%s(%pI4): NH unresolved", __func__,
&attr_new->nexthop);
bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
}
} else {
if (accept_own)
bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
}