From: Trey Aspelund Date: Tue, 26 Jul 2022 22:04:14 +0000 (+0000) Subject: bgpd: ignore NEXT_HOP for MP_REACH_NLRI X-Git-Tag: base_8.4~155^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=7226bc40d606e30251024032995ff21c391ad19f;p=matthieu%2Ffrr.git bgpd: ignore NEXT_HOP for MP_REACH_NLRI 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 Signed-off-by: Trey Aspelund --- diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 395111e1d2..0642c966eb 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -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 { /* diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index e03e83db2c..344608fda1 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -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; } } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 99fbce4ec5..2e7dbaaf66 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -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"); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 2f2784c3cc..9c9b88e125 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -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;