]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: ignore NEXT_HOP for MP_REACH_NLRI
authorTrey Aspelund <taspelund@nvidia.com>
Tue, 26 Jul 2022 22:04:14 +0000 (22:04 +0000)
committerTrey Aspelund <taspelund@nvidia.com>
Thu, 4 Aug 2022 20:36:49 +0000 (20:36 +0000)
RFC 4760 states we SHOULD ignore the NEXT_HOP attribute for BGP Update
messages carrying only MP_REACH_NLRI attributes. Thus we should use the
Network Address of Next Hop field of the MP_REACH_NLRI as the nexthop.

Instead of always looking for BGP_ATTR_NEXT_HOP, this commit ensures:
1) we set mp_nexthop_len to BGP_ATTR_NHLEN_IPV4 for v4 bgp_static routes
2) we check mp_nexthop_len when choosing the nexthop to use for nht
3) we check mp_nexthop_len when choosing the nexthop to send to zebra
4) we check mp_nexthop_len when picking the nexthop to shown by vtysh

Reported-by: Binon Gorbutt <binon@aervivo.com>
Signed-off-by: Trey Aspelund <taspelund@nvidia.com>
bgpd/bgp_evpn.c
bgpd/bgp_nht.c
bgpd/bgp_route.c
bgpd/bgp_zebra.c

index 395111e1d28d00e9e0bc5afb24ae69007f671ebd..0642c966eb1078087f86df8f5fac64c65899bd49 100644 (file)
@@ -2448,8 +2448,10 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
        if (attr.evpn_overlay.type != OVERLAY_INDEX_GATEWAY_IP) {
                if (afi == AFI_IP6)
                        evpn_convert_nexthop_to_ipv6(&attr);
-               else
+               else {
+                       attr.nexthop = attr.mp_nexthop_global_in;
                        attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
+               }
        } else {
 
                /*
index e03e83db2c3363a8b6ff943147af931664e3d83d..344608fda1cc54245630cddc8b0ce7de0d558127 100644 (file)
@@ -199,8 +199,8 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
                   to derive
                   address-family from the next-hop. */
                if (!is_bgp_static_route)
-                       afi = BGP_ATTR_NEXTHOP_AFI_IP6(pi->attr) ? AFI_IP6
-                                                                : AFI_IP;
+                       afi = BGP_ATTR_MP_NEXTHOP_LEN_IP6(pi->attr) ? AFI_IP6
+                                                                   : AFI_IP;
 
                /* Validation for the ipv4 mapped ipv6 nexthop. */
                if (IS_MAPPED_IPV6(&pi->attr->mp_nexthop_global)) {
@@ -847,7 +847,11 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
                                p->u.prefix4 = ipv4;
                                p->prefixlen = IPV4_MAX_BITLEN;
                        } else {
-                               p->u.prefix4 = pi->attr->nexthop;
+                               if (p_orig->family == AF_EVPN)
+                                       p->u.prefix4 =
+                                               pi->attr->mp_nexthop_global_in;
+                               else
+                                       p->u.prefix4 = pi->attr->nexthop;
                                p->prefixlen = IPV4_MAX_BITLEN;
                        }
                }
index 99fbce4ec5085673abd16551e7bdc86bc34322aa..2e7dbaaf66d6d1eae67731d1babe65b6f19042c5 100644 (file)
@@ -5881,6 +5881,9 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p,
        attr.med = bgp_static->igpmetric;
        attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
 
+       if (afi == AFI_IP)
+               attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
+
        if (bgp_static->atomic)
                attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
 
@@ -8391,6 +8394,7 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
        case NEXTHOP_TYPE_IPV4:
        case NEXTHOP_TYPE_IPV4_IFINDEX:
                attr.nexthop = nexthop->ipv4;
+               attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
                break;
        case NEXTHOP_TYPE_IPV6:
        case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -8401,6 +8405,7 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
                switch (p->family) {
                case AF_INET:
                        attr.nexthop.s_addr = INADDR_ANY;
+                       attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
                        break;
                case AF_INET6:
                        memset(&attr.mp_nexthop_global, 0,
@@ -8951,7 +8956,8 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
                        json_nexthop_global = json_object_new_object();
 
                        json_object_string_addf(json_nexthop_global, "ip",
-                                               "%pI4", &attr->nexthop);
+                                               "%pI4",
+                                               &attr->mp_nexthop_global_in);
 
                        if (path->peer->hostname)
                                json_object_string_add(json_nexthop_global,
@@ -8964,10 +8970,12 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
                                                     "used");
                } else {
                        if (nexthop_hostname)
-                               len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
+                               len = vty_out(vty, "%pI4(%s)%s",
+                                             &attr->mp_nexthop_global_in,
                                              nexthop_hostname, vrf_id_str);
                        else
-                               len = vty_out(vty, "%pI4%s", &attr->nexthop,
+                               len = vty_out(vty, "%pI4%s",
+                                             &attr->mp_nexthop_global_in,
                                              vrf_id_str);
 
                        len = wide ? (41 - len) : (16 - len);
@@ -9013,7 +9021,7 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
                                        vty_out(vty, "%*s", len, " ");
                        }
                }
-       } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+       } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
                if (json_paths) {
                        json_nexthop_global = json_object_new_object();
 
@@ -9046,7 +9054,7 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
        }
 
        /* IPv6 Next Hop */
-       else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+       else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
                if (json_paths) {
                        json_nexthop_global = json_object_new_object();
                        json_object_string_addf(json_nexthop_global, "ip",
@@ -9321,9 +9329,9 @@ void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
        /* Print attribute */
        if (attr) {
                if (use_json) {
-                       if (p->family == AF_INET
-                           && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
-                               || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+                       if (p->family == AF_INET &&
+                           (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
+                            !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
                                if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
                                        json_object_string_addf(
                                                json_net, "nextHop", "%pI4",
@@ -9332,13 +9340,13 @@ void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
                                        json_object_string_addf(
                                                json_net, "nextHop", "%pI4",
                                                &attr->nexthop);
-                       } else if (p->family == AF_INET6
-                                  || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+                       } else if (p->family == AF_INET6 ||
+                                  BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
                                json_object_string_addf(
                                        json_net, "nextHopGlobal", "%pI6",
                                        &attr->mp_nexthop_global);
-                       } else if (p->family == AF_EVPN
-                                  && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+                       } else if (p->family == AF_EVPN &&
+                                  !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
                                json_object_string_addf(
                                        json_net, "nextHop", "%pI4",
                                        &attr->mp_nexthop_global_in);
@@ -9364,10 +9372,10 @@ void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
                        json_object_string_add(json_net, "bgpOriginCode",
                                               bgp_origin_str[attr->origin]);
                } else {
-                       if (p->family == AF_INET
-                           && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
-                               || safi == SAFI_EVPN
-                               || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+                       if (p->family == AF_INET &&
+                           (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
+                            safi == SAFI_EVPN ||
+                            !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
                                if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
                                    || safi == SAFI_EVPN)
                                        vty_out(vty, "%-16pI4",
@@ -9376,8 +9384,8 @@ void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
                                        vty_out(vty, "%-41pI4", &attr->nexthop);
                                else
                                        vty_out(vty, "%-16pI4", &attr->nexthop);
-                       } else if (p->family == AF_INET6
-                                  || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+                       } else if (p->family == AF_INET6 ||
+                                  BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
                                char buf[BUFSIZ];
 
                                len = vty_out(
@@ -9456,10 +9464,10 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p,
 
        /* Print attribute */
        attr = path->attr;
-       if (((p->family == AF_INET)
-            && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
-           || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
-           || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+       if (((p->family == AF_INET) &&
+            ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
+           (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
+           (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
                if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
                    || safi == SAFI_EVPN) {
                        if (json)
@@ -9476,10 +9484,10 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p,
                        else
                                vty_out(vty, "%-16pI4", &attr->nexthop);
                }
-       } else if (((p->family == AF_INET6)
-                   && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
-                  || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
-                  || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+       } else if (((p->family == AF_INET6) &&
+                   ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
+                  (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
+                  (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
                char buf_a[512];
 
                if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
@@ -10102,10 +10110,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
        /* Display the nexthop */
        const struct prefix *bn_p = bgp_dest_get_prefix(bn);
 
-       if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
-            || bn_p->family == AF_EVPN)
-           && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
-               || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+       if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET ||
+            bn_p->family == AF_EVPN) &&
+           (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
+            !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
                if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
                    || safi == SAFI_EVPN) {
                        if (json_paths) {
@@ -10210,9 +10218,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
        /* This path was originated locally */
        if (path->peer == bgp->peer_self) {
 
-               if (safi == SAFI_EVPN
-                   || (bn_p->family == AF_INET
-                       && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+               if (safi == SAFI_EVPN || (bn_p->family == AF_INET &&
+                                         !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
                        if (json_paths)
                                json_object_string_add(json_peer, "peerId",
                                                       "0.0.0.0");
index 2f2784c3cc7c1eb0dcdfe4f0bb01d485418206e2..9c9b88e1255420d7ca144496ab5b1d51472d7ac3 100644 (file)
@@ -1363,12 +1363,12 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
                nh_weight = 0;
 
                /* Get nexthop address-family */
-               if (p->family == AF_INET
-                   && !BGP_ATTR_NEXTHOP_AFI_IP6(mpinfo_cp->attr))
+               if (p->family == AF_INET &&
+                   !BGP_ATTR_MP_NEXTHOP_LEN_IP6(mpinfo_cp->attr))
                        nh_family = AF_INET;
-               else if (p->family == AF_INET6
-                        || (p->family == AF_INET
-                            && BGP_ATTR_NEXTHOP_AFI_IP6(mpinfo_cp->attr)))
+               else if (p->family == AF_INET6 ||
+                        (p->family == AF_INET &&
+                         BGP_ATTR_MP_NEXTHOP_LEN_IP6(mpinfo_cp->attr)))
                        nh_family = AF_INET6;
                else
                        continue;