summaryrefslogtreecommitdiff
path: root/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_attr.h4
-rw-r--r--bgpd/bgp_evpn.c23
-rw-r--r--bgpd/bgp_evpn.h1
-rw-r--r--bgpd/bgp_nht.c11
-rw-r--r--bgpd/bgp_route.c28
5 files changed, 58 insertions, 9 deletions
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 42002bd378..375a2272e1 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -69,6 +69,10 @@
#define BGP_PREFIX_SID_IPV6_LENGTH 19
#define BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH 6
+#define BGP_ATTR_NH_AFI(afi, attr) \
+ ((afi != AFI_L2VPN) ? afi : \
+ ((attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4) ? AFI_IP : AFI_IP6))
+
/* PMSI tunnel types (RFC 6514) */
struct bgp_attr_encap_subtlv {
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 07d3f7b31e..36ea9a991a 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -6026,3 +6026,26 @@ int bgp_evpn_get_type5_prefixlen(struct prefix *pfx)
return evp->prefix.prefix_addr.ip_prefix_length;
}
+
+/*
+ * Should we register nexthop for this EVPN prefix for nexthop tracking?
+ */
+bool bgp_evpn_is_prefix_nht_supported(struct prefix *pfx)
+{
+ struct prefix_evpn *evp = (struct prefix_evpn *)pfx;
+
+ /*
+ * EVPN RT-5 should not be marked as valid and imported to vrfs if the
+ * BGP nexthop is not reachable. To check for the nexthop reachability,
+ * Add nexthop for EVPN RT-5 for nexthop tracking.
+ *
+ * Ideally, a BGP route should be marked as valid only if the
+ * nexthop is reachable. Thus, other EVPN route types also should be
+ * added here after testing is performed for them.
+ */
+ if (pfx && pfx->family == AF_EVPN &&
+ evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)
+ return true;
+
+ return false;
+}
diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h
index 6d1e8cd31b..798c3e59bc 100644
--- a/bgpd/bgp_evpn.h
+++ b/bgpd/bgp_evpn.h
@@ -191,5 +191,6 @@ extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp);
extern void bgp_evpn_cleanup(struct bgp *bgp);
extern void bgp_evpn_init(struct bgp *bgp);
extern int bgp_evpn_get_type5_prefixlen(struct prefix *pfx);
+extern bool bgp_evpn_is_prefix_nht_supported(struct prefix *pfx);
#endif /* _QUAGGA_BGP_EVPN_H */
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 6be08efb21..0969c8e77e 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -43,6 +43,7 @@
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_zebra.h"
#include "bgpd/bgp_flowspec_util.h"
+#include "bgpd/bgp_evpn.h"
extern struct zclient *zclient;
@@ -773,6 +774,16 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|| CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
SET_FLAG(path->flags, BGP_PATH_IGP_CHANGED);
+ if (safi == SAFI_EVPN &&
+ bgp_evpn_is_prefix_nht_supported(&rn->p)) {
+ if (CHECK_FLAG(path->flags, BGP_PATH_VALID))
+ bgp_evpn_import_route(bgp_path, afi, safi,
+ &rn->p, path);
+ else
+ bgp_evpn_unimport_route(bgp_path, afi, safi,
+ &rn->p, path);
+ }
+
bgp_process(bgp_path, rn, afi, safi);
}
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 261fe77800..a40cd737a8 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -3038,6 +3038,7 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
int connected = 0;
int do_loop_check = 1;
int has_valid_label = 0;
+ afi_t nh_afi;
#if ENABLE_BGP_VNC
int vnc_implicit_withdraw = 0;
#endif
@@ -3433,8 +3434,10 @@ int bgp_update(struct peer *peer, 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)) {
+ 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 (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
&& !CHECK_FLAG(peer->flags,
PEER_FLAG_DISABLE_CONNECTED_CHECK)
@@ -3449,8 +3452,10 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
if (pi->extra && pi->extra->bgp_orig)
bgp_nexthop = pi->extra->bgp_orig;
- if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, pi,
- NULL, connected)
+ nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
+
+ if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
+ pi, NULL, connected)
|| CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
else {
@@ -3498,7 +3503,8 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
* updating
* the attributes for the route in the VNI(s).
*/
- if (safi == SAFI_EVPN && !same_attr)
+ if (safi == SAFI_EVPN && !same_attr &&
+ CHECK_FLAG(pi->flags, BGP_PATH_VALID))
bgp_evpn_import_route(bgp, afi, safi, p, pi);
/* Process change. */
@@ -3571,8 +3577,9 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
evpn == NULL ? NULL : &evpn->gw_ip);
}
/* Nexthop reachability check. */
- if ((afi == AFI_IP || afi == AFI_IP6)
- && (safi == SAFI_UNICAST || safi == SAFI_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 (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
&& !CHECK_FLAG(peer->flags,
PEER_FLAG_DISABLE_CONNECTED_CHECK)
@@ -3581,7 +3588,10 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
else
connected = 0;
- if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, connected)
+ nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
+
+ if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, new, NULL,
+ connected)
|| CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
else {
@@ -3632,7 +3642,7 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
return -1;
/* If this is an EVPN route, process for import. */
- if (safi == SAFI_EVPN)
+ if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
bgp_evpn_import_route(bgp, afi, safi, p, new);
hook_call(bgp_process, bgp, afi, safi, rn, peer, false);