]> git.proxmox.com Git - mirror_frr.git/commitdiff
staticd: add command to show monitored routes
authorRafael Zalamena <rzalamena@opensourcerouting.org>
Wed, 24 Mar 2021 12:40:46 +0000 (09:40 -0300)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Fri, 13 Jan 2023 18:32:12 +0000 (15:32 -0300)
Add command to visualize all monitored routes and their state.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
staticd/static_bfd.c
staticd/static_routes.h
staticd/static_vty.c

index dda0487139dad962f1273764e448a9708ecf292d..a955d155e9e987c31b524eec9b469d287a0a3fb5 100644 (file)
@@ -217,3 +217,171 @@ void static_bfd_initialize(struct zclient *zc, struct thread_master *tm)
        /* Initialize BFD integration library. */
        bfd_protocol_integration_init(zc, tm);
 }
+
+/*
+ * Display functions
+ */
+static void static_bfd_show_nexthop_json(struct vty *vty,
+                                        struct json_object *jo,
+                                        const struct static_nexthop *sn)
+{
+       const struct prefix *dst_p, *src_p;
+       struct json_object *jo_nh;
+
+       jo_nh = json_object_new_object();
+
+       srcdest_rnode_prefixes(sn->rn, &dst_p, &src_p);
+       if (src_p)
+               json_object_string_addf(jo_nh, "from", "%pFX", src_p);
+
+       json_object_string_addf(jo_nh, "prefix", "%pFX", dst_p);
+       json_object_string_add(jo_nh, "vrf", sn->nh_vrfname);
+
+       json_object_boolean_add(jo_nh, "installed", !sn->path_down);
+
+       json_object_array_add(jo, jo_nh);
+}
+
+static void static_bfd_show_path_json(struct vty *vty, struct json_object *jo,
+                                     struct route_table *rt)
+{
+       struct route_node *rn;
+
+       for (rn = route_top(rt); rn; rn = srcdest_route_next(rn)) {
+               struct static_route_info *si = static_route_info_from_rnode(rn);
+               struct static_path *sp;
+
+               if (si == NULL)
+                       continue;
+
+               frr_each (static_path_list, &si->path_list, sp) {
+                       struct static_nexthop *sn;
+
+                       frr_each (static_nexthop_list, &sp->nexthop_list, sn) {
+                               /* Skip non configured BFD sessions. */
+                               if (sn->bsp == NULL)
+                                       continue;
+
+                               static_bfd_show_nexthop_json(vty, jo, sn);
+                       }
+               }
+       }
+}
+
+static void static_bfd_show_json(struct vty *vty)
+{
+       struct json_object *jo, *jo_path, *jo_afi_safi;
+       struct vrf *vrf;
+
+       jo = json_object_new_object();
+       jo_path = json_object_new_object();
+
+       json_object_object_add(jo, "path-list", jo_path);
+       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+               const struct static_vrf *svrf = vrf->info;
+               struct route_table *rt;
+
+               jo_afi_safi = json_object_new_array();
+               json_object_object_add(jo_path, "ipv4-unicast", jo_afi_safi);
+               rt = svrf->stable[AFI_IP][SAFI_UNICAST];
+               if (rt)
+                       static_bfd_show_path_json(vty, jo_afi_safi, rt);
+
+               jo_afi_safi = json_object_new_array();
+               json_object_object_add(jo_path, "ipv4-multicast", jo_afi_safi);
+               rt = svrf->stable[AFI_IP][SAFI_MULTICAST];
+               if (rt)
+                       static_bfd_show_path_json(vty, jo_afi_safi, rt);
+
+               jo_afi_safi = json_object_new_array();
+               json_object_object_add(jo_path, "ipv6-unicast", jo_afi_safi);
+               rt = svrf->stable[AFI_IP6][SAFI_UNICAST];
+               if (rt)
+                       static_bfd_show_path_json(vty, jo_afi_safi, rt);
+       }
+
+       vty_out(vty, "%s\n", json_object_to_json_string_ext(jo, 0));
+       json_object_free(jo);
+}
+
+static void static_bfd_show_nexthop(struct vty *vty,
+                                   const struct static_nexthop *sn)
+{
+       vty_out(vty, "        %pRN", sn->rn);
+
+       if (sn->bsp == NULL) {
+               vty_out(vty, "\n");
+               return;
+       }
+
+       if (sn->type == STATIC_IPV4_GATEWAY ||
+           sn->type == STATIC_IPV4_GATEWAY_IFNAME)
+               vty_out(vty, " peer %pI4", &sn->addr.ipv4);
+       else if (sn->type == STATIC_IPV6_GATEWAY ||
+                sn->type == STATIC_IPV6_GATEWAY_IFNAME)
+               vty_out(vty, " peer %pI6", &sn->addr.ipv6);
+       else
+               vty_out(vty, " peer unknown");
+
+       vty_out(vty, " (status: %s)\n",
+               sn->path_down ? "uninstalled" : "installed");
+}
+
+static void static_bfd_show_path(struct vty *vty, struct route_table *rt)
+{
+       struct route_node *rn;
+
+       for (rn = route_top(rt); rn; rn = srcdest_route_next(rn)) {
+               struct static_route_info *si = static_route_info_from_rnode(rn);
+               struct static_path *sp;
+
+               if (si == NULL)
+                       continue;
+
+               frr_each (static_path_list, &si->path_list, sp) {
+                       struct static_nexthop *sn;
+
+                       frr_each (static_nexthop_list, &sp->nexthop_list, sn) {
+                               /* Skip non configured BFD sessions. */
+                               if (sn->bsp == NULL)
+                                       continue;
+
+                               static_bfd_show_nexthop(vty, sn);
+                       }
+               }
+       }
+}
+
+void static_bfd_show(struct vty *vty, bool json)
+{
+       struct vrf *vrf;
+
+       if (json) {
+               static_bfd_show_json(vty);
+               return;
+       }
+
+       vty_out(vty, "Showing BFD monitored static routes:\n");
+       vty_out(vty, "\n  Next hops:\n");
+       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+               const struct static_vrf *svrf = vrf->info;
+               struct route_table *rt;
+
+               vty_out(vty, "    VRF %s IPv4 Unicast:\n", vrf->name);
+               rt = svrf->stable[AFI_IP][SAFI_UNICAST];
+               if (rt)
+                       static_bfd_show_path(vty, rt);
+
+               vty_out(vty, "\n    VRF %s IPv4 Multicast:\n", vrf->name);
+               rt = svrf->stable[AFI_IP][SAFI_MULTICAST];
+               if (rt)
+                       static_bfd_show_path(vty, rt);
+
+               vty_out(vty, "\n    VRF %s IPv6 Unicast:\n", vrf->name);
+               rt = svrf->stable[AFI_IP6][SAFI_UNICAST];
+               if (rt)
+                       static_bfd_show_path(vty, rt);
+       }
+
+       vty_out(vty, "\n");
+}
index 7082e8959d255ae7c802fa2ad7f8a4d6f27297b2..2332cfd2bf819fb3209ab7cf0967d29ab3e30960 100644 (file)
@@ -244,6 +244,8 @@ extern void static_next_hop_bfd_multi_hop(struct static_nexthop *sn, bool mhop);
 /** Call this function after zebra client initialization. */
 extern void static_bfd_initialize(struct zclient *zc, struct thread_master *tm);
 
+extern void static_bfd_show(struct vty *vty, bool isjson);
+
 #ifdef __cplusplus
 }
 #endif
index 0d4a91f347e052c4e65397f83fc821a14cb41aea..d62ea092b3ecc475f3cac20bb1584b0aca70cced 100644 (file)
@@ -1471,6 +1471,18 @@ DEFPY_YANG(debug_staticd, debug_staticd_cmd,
        return CMD_SUCCESS;
 }
 
+DEFPY(staticd_show_bfd_routes, staticd_show_bfd_routes_cmd,
+      "show bfd static route [json]$isjson",
+      SHOW_STR
+      BFD_INTEGRATION_STR
+      STATICD_STR
+      ROUTE_STR
+      JSON_STR)
+{
+       static_bfd_show(vty, !!isjson);
+       return CMD_SUCCESS;
+}
+
 DEFUN_NOSH (show_debugging_static,
            show_debugging_static_cmd,
            "show debugging [static]",
@@ -1517,4 +1529,6 @@ void static_vty_init(void)
        install_element(ENABLE_NODE, &show_debugging_static_cmd);
        install_element(ENABLE_NODE, &debug_staticd_cmd);
        install_element(CONFIG_NODE, &debug_staticd_cmd);
+
+       install_element(ENABLE_NODE, &staticd_show_bfd_routes_cmd);
 }