summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c59
-rw-r--r--bgpd/bgp_nht.c8
-rw-r--r--bgpd/bgp_zebra.c41
3 files changed, 92 insertions, 16 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index ae365fa13e..d00a882c1a 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -53,6 +53,7 @@
#include "bgpd/bgp_addpath.h"
#include "bgpd/bgp_mac.h"
#include "bgpd/bgp_vty.h"
+#include "bgpd/bgp_nht.h"
/*
* Definitions and external declarations.
@@ -2402,6 +2403,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
bool new_pi = false;
bool use_l3nhg = false;
bool is_l3nhg_active = false;
+ char buf1[INET6_ADDRSTRLEN];
memset(pp, 0, sizeof(struct prefix));
ip_prefix_from_evpn_prefix(evp, pp);
@@ -2432,10 +2434,36 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
* make sure to set the flag for next hop attribute.
*/
attr = *parent_pi->attr;
- if (afi == AFI_IP6)
- evpn_convert_nexthop_to_ipv6(&attr);
- else
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
+ if (attr.evpn_overlay.type != OVERLAY_INDEX_GATEWAY_IP) {
+ if (afi == AFI_IP6)
+ evpn_convert_nexthop_to_ipv6(&attr);
+ else
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
+ } else {
+
+ /*
+ * If gateway IP overlay index is specified in the NLRI of
+ * EVPN RT-5, this gateway IP should be used as the nexthop
+ * for the prefix in the VRF
+ */
+ if (bgp_debug_zebra(NULL)) {
+ zlog_debug(
+ "Install gateway IP %s as nexthop for prefix %pFX in vrf %s",
+ inet_ntop(pp->family, &attr.evpn_overlay.gw_ip,
+ buf1, sizeof(buf1)), pp,
+ vrf_id_to_name(bgp_vrf->vrf_id));
+ }
+
+ if (afi == AFI_IP6) {
+ memcpy(&attr.mp_nexthop_global,
+ &attr.evpn_overlay.gw_ip.ipv6,
+ sizeof(struct in6_addr));
+ attr.mp_nexthop_len = IPV6_MAX_BYTELEN;
+ } else {
+ attr.nexthop = attr.evpn_overlay.gw_ip.ipv4;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
+ }
+ }
bgp_evpn_es_vrf_use_nhg(bgp_vrf, &parent_pi->attr->esi, &use_l3nhg,
&is_l3nhg_active, NULL);
@@ -2481,8 +2509,27 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
pi->attr = attr_new;
pi->uptime = bgp_clock();
}
- /* as it is an importation, change nexthop */
- bgp_path_info_set_flag(dest, pi, BGP_PATH_ANNC_NH_SELF);
+
+ /* Gateway IP nexthop should be resolved */
+ if (attr.evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
+ if (bgp_find_or_add_nexthop(bgp_vrf, bgp_vrf, afi, safi, pi,
+ NULL, 0))
+ bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
+ else {
+ if (BGP_DEBUG(nht, NHT)) {
+ inet_ntop(pp->family,
+ &attr.evpn_overlay.gw_ip,
+ buf1, sizeof(buf1));
+ zlog_debug("%s: gateway IP NH unresolved",
+ buf1);
+ }
+ bgp_path_info_unset_flag(dest, pi, BGP_PATH_VALID);
+ }
+ } else {
+
+ /* as it is an importation, change nexthop */
+ bgp_path_info_set_flag(dest, pi, BGP_PATH_ANNC_NH_SELF);
+ }
/* Link path to evpn nexthop */
bgp_evpn_path_nh_add(bgp_vrf, pi);
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 4b4a3716e6..638c72ae67 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -942,6 +942,9 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
* In case of unicast routes that were imported from vpn
* and that have labels, they are valid only if there are
* nexthops with labels
+ *
+ * If the nexthop is EVPN gateway-IP,
+ * do not check for a valid label.
*/
bool bnc_is_valid_nexthop = false;
@@ -950,8 +953,9 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
if (safi == SAFI_UNICAST &&
path->sub_type == BGP_ROUTE_IMPORTED &&
path->extra &&
- path->extra->num_labels) {
-
+ path->extra->num_labels &&
+ path->attr->evpn_overlay.type !=
+ OVERLAY_INDEX_GATEWAY_IP) {
bnc_is_valid_nexthop =
bgp_isvalid_labeled_nexthop(bnc) ? true : false;
} else {
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index c2c114d2c9..b32f319655 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1058,9 +1058,19 @@ static bool update_ipv4nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
* connected routes leaked into a VRF.
*/
if (is_evpn) {
- api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
- SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
- api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
+
+ /*
+ * If the nexthop is EVPN overlay index gateway IP,
+ * treat the nexthop as NEXTHOP_TYPE_IPV4
+ * Else, mark the nexthop as onlink.
+ */
+ if (attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP)
+ api_nh->type = NEXTHOP_TYPE_IPV4;
+ else {
+ api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
+ 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) {
api_nh->type = NEXTHOP_TYPE_IFINDEX;
@@ -1085,9 +1095,19 @@ static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
api_nh->vrf_id = nh_bgp->vrf_id;
if (is_evpn) {
- api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
- SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
- api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
+
+ /*
+ * If the nexthop is EVPN overlay index gateway IP,
+ * treat the nexthop as NEXTHOP_TYPE_IPV4
+ * Else, mark the nexthop as onlink.
+ */
+ if (attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP)
+ api_nh->type = NEXTHOP_TYPE_IPV6;
+ else {
+ api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
+ SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
+ api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
+ }
} else if (nh_othervrf) {
if (IN6_IS_ADDR_UNSPECIFIED(nexthop)) {
api_nh->type = NEXTHOP_TYPE_IFINDEX;
@@ -1392,8 +1412,13 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
api_nh->label_num = 1;
api_nh->labels[0] = label;
}
- memcpy(&api_nh->rmac, &(mpinfo->attr->rmac),
- sizeof(struct ethaddr));
+
+ if (is_evpn
+ && mpinfo->attr->evpn_overlay.type
+ != OVERLAY_INDEX_GATEWAY_IP)
+ memcpy(&api_nh->rmac, &(mpinfo->attr->rmac),
+ sizeof(struct ethaddr));
+
api_nh->weight = nh_weight;
if (mpinfo->extra