From 886c9e027b41b3a02c7df6939bc7824cbed92f43 Mon Sep 17 00:00:00 2001 From: Karthikeya Venkat Muppalla Date: Mon, 7 Oct 2024 03:36:33 -0700 Subject: [PATCH] bgpd: [SOO] show bgp ip unicast detail per src nhg Enhance the commands "show bgp ipv4/ipv6 unicast" detail and non detail outputs when 'bgp nhg-per-origin' is configured. Testing: switch# sh bgp ipv4 unicast BGP table version is 218, local router ID is 6.0.0.6, vrf id 0 Default local pref 100, local AS 65011 Status codes: s suppressed, d damped, h history, u unsorted, * valid, > best, = multipath, + multipath nhg i internal, r RIB-failure, S Stale, R Removed Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self Origin codes: i - IGP, e - EGP, ? - incomplete RPKI validation codes: V valid, I invalid, N Not found Network Next Hop Metric LocPrf Weight Path *> 6.0.0.7/32 220.10.0.65(spine11) 0 65201 65012 ? *+ 220.10.0.81(spine11) 0 65201 65012 ? *+ 220.10.0.97(spine11) 0 65201 65012 ? *+ 220.11.0.65(spine12) 0 65201 65012 ? *+ 220.11.0.81(spine12) 0 65201 65012 ? *+ 220.11.0.97(spine12) 0 65201 65012 ? *> 77.0.0.0/32 220.10.0.65(spine11) 0 65201 65012 ? *+ 220.10.0.81(spine11) 0 65201 65012 ? *+ 220.10.0.97(spine11) 0 65201 65012 ? *+ 220.11.0.65(spine12) 0 65201 65012 ? *+ 220.11.0.81(spine12) 0 65201 65012 ? *+ 220.11.0.97(spine12) mlx-3700-68# show bgp ipv4 unicast 77.0.0.0/32 BGP routing table entry for 77.0.0.0/32, version 150 SoO:6.0.0.7, multipath soo nhg:70328887 Paths: (6 available, best #1, table default) Advertised to non peer-group peers: spine11(220.10.0.65) spine11(220.10.0.81) spine11(220.10.0.97) spine12(220.11.0.65) spine12(220.11.0.81) spine12(220.11.0.97) 65201 65012 220.11.0.65 (spine12) from spine12(220.11.0.65) (6.0.0.11) Origin incomplete, valid, external, multipath soo nhg, bestpath-from-AS 65201, best (Older Path) Extended Community: SoO:6.0.0.7:1234 Last update: Mon Oct 7 09:48:36 2024 65201 65012 220.10.0.65 (spine11) from spine11(220.10.0.65) (6.0.0.10) Origin incomplete, valid, external, multipath soo nhg Extended Community: SoO:6.0.0.7:1234 Last update: Mon Oct 7 09:48:36 2024 65201 65012 220.10.0.81 (spine11) from spine11(220.10.0.81) (6.0.0.10) Origin incomplete, valid, external, multipath soo nhg Extended Community: SoO:6.0.0.7:1234 Last update: Mon Oct 7 09:48:36 2024 65201 65012 220.10.0.97 (spine11) from spine11(220.10.0.97) (6.0.0.10) Origin incomplete, valid, external, multipath soo nhg Extended Community: SoO:6.0.0.7:1234 Last update: Mon Oct 7 09:48:36 2024 65201 65012 220.11.0.81 (spine12) from spine12(220.11.0.81) (6.0.0.11) Origin incomplete, valid, external, multipath soo nhg Extended Community: SoO:6.0.0.7:1234 Last update: Mon Oct 7 09:48:36 2024 65201 65012 220.11.0.97 (spine12) from spine12(220.11.0.97) (6.0.0.11) Origin incomplete, valid, external, multipath soo nhg Extended Community: SoO:6.0.0.7:1234 Last update: Mon Oct 7 09:48:36 2024 mlx-3700-68# Ticket: #3951671 Signed-off-by: Karthikeya Venkat Muppalla --- bgpd/bgp_per_src_nhg.c | 63 ++++++++++++++++++++++++++++++++++++++++-- bgpd/bgp_per_src_nhg.h | 2 ++ bgpd/bgp_route.c | 48 +++++++++++++++++++++++++++----- bgpd/bgp_route.h | 6 ++-- bgpd/bgp_vty.c | 2 +- 5 files changed, 108 insertions(+), 13 deletions(-) diff --git a/bgpd/bgp_per_src_nhg.c b/bgpd/bgp_per_src_nhg.c index c3eaddecd3b7..054ba1526ddd 100644 --- a/bgpd/bgp_per_src_nhg.c +++ b/bgpd/bgp_per_src_nhg.c @@ -91,7 +91,8 @@ void bgp_process_route_with_soo_attr(struct bgp *bgp, struct bgp_dest *dest, struct in_addr *ipaddr, bool is_add, bool soo_attr_del); static struct bgp_dest_soo_hash_entry * -bgp_dest_soo_find(struct bgp_per_src_nhg_hash_entry *nhe, struct prefix *p); +bgp_dest_soo_find(struct bgp_per_src_nhg_hash_entry *nhe, + const struct prefix *p); /*temp code, will be deleted after timer wheel test*/ void bgp_soo_route_select_nh_eval(struct event *event); @@ -772,7 +773,8 @@ static void *bgp_dest_soo_alloc(void *p) } static struct bgp_dest_soo_hash_entry * -bgp_dest_soo_find(struct bgp_per_src_nhg_hash_entry *nhe, struct prefix *p) +bgp_dest_soo_find(struct bgp_per_src_nhg_hash_entry *nhe, + const struct prefix *p) { struct bgp_dest_soo_hash_entry tmp; struct bgp_dest_soo_hash_entry *dest_he; @@ -1627,4 +1629,61 @@ void bgp_process_mpath_route_soo_attr(struct bgp *bgp, afi_t afi, } } +static bool is_nhg_per_origin_configured(struct bgp *bgp) +{ + afi_t afi; + safi_t safi; + bool nhg_per_origin = false; + FOREACH_AFI_SAFI (afi, safi) { + if (CHECK_FLAG(bgp->per_src_nhg_flags[afi][safi], + BGP_FLAG_NHG_PER_ORIGIN)) { + nhg_per_origin = true; + } + } + + return nhg_per_origin; +} + +bool is_path_using_soo_nhg(const struct prefix *p, struct bgp_path_info *path, + uint32_t *soo_nhg, struct in_addr *soo) +{ + bool using_soo_nhg = false; + if (is_nhg_per_origin_configured(path->peer->bgp) && + route_has_soo_attr(path)) { + struct in_addr in; + bool is_soo_route = bgp_is_soo_route(path->net, path, &in); + struct bgp_per_src_nhg_hash_entry *nhe = NULL; + struct ipaddr ip; + + memset(&ip, 0, sizeof(struct ipaddr)); + SET_IPADDR_V4(&ip); + memcpy(&ip.ipaddr_v4, &in, sizeof(ip.ipaddr_v4)); + nhe = bgp_per_src_nhg_find(path->peer->bgp, &ip); + + if (nhe) { + if (is_soo_route) { + if (bf_test_index( + nhe->bgp_selected_soo_route_pi_bitmap, + path->peer->bit_index)) { + using_soo_nhg = true; + *soo_nhg = nhe->nhg_id; + memcpy(soo, &in, + sizeof(struct in_addr)); + } + } else { + struct bgp_dest_soo_hash_entry *dest_he; + dest_he = bgp_dest_soo_find(nhe, p); + if (CHECK_FLAG( + dest_he->flags, + DEST_PRESENT_IN_NHGID_USE_LIST)) { + using_soo_nhg = true; + *soo_nhg = nhe->nhg_id; + memcpy(soo, &in, + sizeof(struct in_addr)); + } + } + } + } + return using_soo_nhg; +} diff --git a/bgpd/bgp_per_src_nhg.h b/bgpd/bgp_per_src_nhg.h index 5994ebd06286..8b242de03a90 100644 --- a/bgpd/bgp_per_src_nhg.h +++ b/bgpd/bgp_per_src_nhg.h @@ -174,4 +174,6 @@ void bgp_process_route_transition_between_nhid(struct bgp *bgp, struct bgp_dest void bgp_process_mpath_route_soo_attr(struct bgp *bgp, afi_t afi, struct bgp_dest *dest, struct bgp_path_info *new_best, bool is_add); +bool is_path_using_soo_nhg(const struct prefix *p, struct bgp_path_info *path, + uint32_t *soo_nhg, struct in_addr *soo); #endif /* _BGP_PER_SRC_NHG_H */ diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 2a590975aa58..177dab4149f0 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -9784,6 +9784,8 @@ static void route_vty_short_status_out(struct vty *vty, json_object *json_path) { enum rpki_states rpki_state = RPKI_NOT_BEING_USED; + uint32_t soo_nhg = 0; + struct in_addr soo_ip; if (json_path) { @@ -9868,9 +9870,13 @@ static void route_vty_short_status_out(struct vty *vty, vty_out(vty, "d"); else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) vty_out(vty, ">"); - else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)) - vty_out(vty, "="); - else + else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)) { + if (is_path_using_soo_nhg(p, path, &soo_nhg, &soo_ip)) { + vty_out(vty, "+"); + } else { + vty_out(vty, "="); + } + } else vty_out(vty, " "); /* Internal route. */ @@ -11004,6 +11010,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, char time_buf[64]; struct bgp_path_info *bpi_ultimate = bgp_get_imported_bpi_ultimate(path); + uint32_t soo_nhg = 0; + struct in_addr soo_ip; if (json_paths) { json_path = json_object_new_object(); @@ -11596,8 +11604,13 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, (CHECK_FLAG(path->flags, BGP_PATH_SELECTED) && bgp_path_info_mpath_count(path) > 1)) { if (json_paths) json_object_boolean_true_add(json_path, "multipath"); - else - vty_out(vty, ", multipath"); + else { + if (is_path_using_soo_nhg(p, path, &soo_nhg, &soo_ip)) { + vty_out(vty, ", multipath soo nhg"); + } else { + vty_out(vty, ", multipath"); + } + } } // Mark the bestpath(s) @@ -12719,6 +12732,9 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, uint32_t ttl = 0; uint32_t bos = 0; uint32_t exp = 0; + uint32_t soo_nhg = 0; + struct in_addr soo; + bool path_using_soo_nhg = false; mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos); @@ -12745,10 +12761,16 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, bgp_evpn_route2json((struct prefix_evpn *)p, json); } } else { + for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { + if (is_path_using_soo_nhg(p, pi, &soo_nhg, &soo)) { + path_using_soo_nhg = true; + break; + } + } + if (!json) { vty_out(vty, - "BGP routing table entry for %s%s%pFX, version %" PRIu64 - "\n", + "BGP routing table entry for %s%s%pFX, version %" PRIu64, (((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) && prd) @@ -12758,6 +12780,18 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, : ""), safi == SAFI_MPLS_VPN && prd ? ":" : "", p, dest->version); + if (path_using_soo_nhg) { + struct ipaddr ip; + memset(&ip, 0, sizeof(ip)); + SET_IPADDR_V4(&ip); + memcpy(&ip.ipaddr_v4, &soo, + sizeof(ip.ipaddr_v4)); + vty_out(vty, + " SoO:%pIA, multipath soo nhg:%d\n", + &ip, soo_nhg); + } else { + vty_out(vty, "\n"); + } } else { if (incremental_print) { diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 3e12a26759e6..74cd2c290d17 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -57,9 +57,9 @@ enum bgp_show_adj_route_type { }; -#define BGP_SHOW_SCODE_HEADER \ - "Status codes: s suppressed, d damped, " \ - "h history, u unsorted, * valid, > best, = multipath,\n" \ +#define BGP_SHOW_SCODE_HEADER \ + "Status codes: s suppressed, d damped, " \ + "h history, u unsorted, * valid, > best, = multipath, + multipath nhg,\n" \ " i internal, r RIB-failure, S Stale, R Removed\n" #define BGP_SHOW_OCODE_HEADER \ "Origin codes: i - IGP, e - EGP, ? - incomplete\n" diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 0fcefc4dc34d..8ae43e9149f1 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -20434,7 +20434,7 @@ static void show_bgp_soo_entry(struct bgp_per_src_nhg_hash_entry *soo_entry, vty_out(vty, " %s", pfxprint); if (CHECK_FLAG(bgp_dest_soo_entry->flags, DEST_PRESENT_IN_NHGID_USE_LIST)) { - vty_out(vty, "uses SoO NHG"); + vty_out(vty, " uses SoO NHG"); } vty_print_bitfield(vty, " Selected path info bitmap",