diff options
Diffstat (limited to 'zebra/zebra_vty.c')
| -rw-r--r-- | zebra/zebra_vty.c | 184 |
1 files changed, 108 insertions, 76 deletions
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index c6b3eb48a0..04f2e91e69 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -60,6 +60,7 @@ #include "zebra/zebra_nb.h" #include "zebra/kernel_netlink.h" #include "zebra/table_manager.h" +#include "zebra/zebra_script.h" extern int allow_delete; @@ -75,7 +76,7 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, const struct prefix *longer_prefix_p, bool supernets_only, int type, unsigned short ospf_instance_id, uint32_t tableid, - struct route_show_ctx *ctx); + bool show_ng, struct route_show_ctx *ctx); static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, int mcast, bool use_fib, bool show_ng); static void vty_show_ip_route_summary(struct vty *vty, @@ -157,7 +158,8 @@ DEFUN (show_ip_rpf, }; return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST, - false, uj, 0, NULL, false, 0, 0, 0, &ctx); + false, uj, 0, NULL, false, 0, 0, 0, false, + &ctx); } DEFUN (show_ip_rpf_addr, @@ -449,6 +451,8 @@ static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re, bzo.community); json_object_string_add(json, "largeCommunities", bzo.lcommunity); + json_object_string_add(json, "selectionReason", + bzo.selection_reason); } else { vty_out(vty, " AS-Path : %s\n", bzo.aspath); @@ -459,6 +463,9 @@ static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re, if (bzo.lcommunity[0] != '\0') vty_out(vty, " Large-Communities: %s\n", bzo.lcommunity); + + vty_out(vty, " Selection reason : %s\n", + bzo.selection_reason); } } default: @@ -534,8 +541,14 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, vty_out(vty, " Last update %s ago\n", buf); - if (show_ng) + if (show_ng) { vty_out(vty, " Nexthop Group ID: %u\n", re->nhe_id); + if (re->nhe_installed_id != 0 + && re->nhe_id != re->nhe_installed_id) + vty_out(vty, + " Installed Nexthop Group ID: %u\n", + re->nhe_installed_id); + } for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) { /* Use helper to format each nexthop */ @@ -703,10 +716,8 @@ static void show_nexthop_json_helper(json_object *json_nexthop, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - json_object_string_add( - json_nexthop, "ip", - inet_ntop(AF_INET, &nexthop->gate.ipv4, - buf, sizeof(buf))); + json_object_string_addf(json_nexthop, "ip", "%pI4", + &nexthop->gate.ipv4); json_object_string_add(json_nexthop, "afi", "ipv4"); @@ -723,10 +734,8 @@ static void show_nexthop_json_helper(json_object *json_nexthop, break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: - json_object_string_add( - json_nexthop, "ip", - inet_ntop(AF_INET6, &nexthop->gate.ipv6, - buf, sizeof(buf))); + json_object_string_addf(json_nexthop, "ip", "%pI6", + &nexthop->gate.ipv6); json_object_string_add(json_nexthop, "afi", "ipv6"); @@ -776,6 +785,13 @@ static void show_nexthop_json_helper(json_object *json_nexthop, break; } + /* This nexthop is a resolver for the parent nexthop. + * Set resolver flag for better clarity and delimiter + * in flat list of nexthops in json. + */ + if (nexthop->rparent) + json_object_boolean_true_add(json_nexthop, "resolver"); + if (nexthop->vrf_id != re->vrf_id) json_object_string_add(json_nexthop, "vrf", vrf_id_to_name(nexthop->vrf_id)); @@ -880,7 +896,7 @@ static void show_nexthop_json_helper(json_object *json_nexthop, static void vty_show_ip_route(struct vty *vty, struct route_node *rn, struct route_entry *re, json_object *json, - bool is_fib) + bool is_fib, bool show_ng) { const struct nexthop *nexthop; int len = 0; @@ -968,6 +984,11 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, &(re->nhe->nhg))); json_object_int_add(json_route, "nexthopGroupId", re->nhe_id); + if (re->nhe_installed_id != 0) + json_object_int_add(json_route, + "installedNexthopGroupId", + re->nhe_installed_id); + json_object_string_add(json_route, "uptime", up_str); for (ALL_NEXTHOPS_PTR(nhg, nexthop)) { @@ -1041,6 +1062,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, len += vty_out(vty, " [%u/%u]", re->distance, re->metric); + if (show_ng) + len += vty_out(vty, " (%u)", re->nhe_id); + /* Nexthop information. */ for (ALL_NEXTHOPS_PTR(nhg, nexthop)) { if (first_p) { @@ -1113,16 +1137,12 @@ static void vty_show_ip_route_detail_json(struct vty *vty, */ if (use_fib && re != dest->selected_fib) continue; - vty_show_ip_route(vty, rn, re, json_prefix, use_fib); + vty_show_ip_route(vty, rn, re, json_prefix, use_fib, false); } prefix2str(&rn->p, buf, sizeof(buf)); json_object_object_add(json, buf, json_prefix); - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY - | JSON_C_TO_STRING_NOSLASHESCAPE)); - json_object_free(json); + vty_json(vty, json); } static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, @@ -1131,7 +1151,8 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, const struct prefix *longer_prefix_p, bool supernets_only, int type, unsigned short ospf_instance_id, bool use_json, - uint32_t tableid, struct route_show_ctx *ctx) + uint32_t tableid, bool show_ng, + struct route_show_ctx *ctx) { struct route_node *rn; struct route_entry *re; @@ -1222,7 +1243,8 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, first = 0; } - vty_show_ip_route(vty, rn, re, json_prefix, use_fib); + vty_show_ip_route(vty, rn, re, json_prefix, use_fib, + show_ng); } if (json_prefix) { @@ -1232,14 +1254,8 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, } } - if (use_json) { - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json, - JSON_C_TO_STRING_PRETTY - | JSON_C_TO_STRING_NOSLASHESCAPE)); - json_object_free(json); - } + if (use_json) + vty_json(vty, json); } static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf, @@ -1247,7 +1263,7 @@ static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf, route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, - unsigned short ospf_instance_id, + unsigned short ospf_instance_id, bool show_ng, struct route_show_ctx *ctx) { struct zebra_router_table *zrt; @@ -1266,7 +1282,7 @@ static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf, do_show_ip_route(vty, zvrf_name(zvrf), afi, SAFI_UNICAST, use_fib, use_json, tag, longer_prefix_p, supernets_only, type, ospf_instance_id, - zrt->tableid, ctx); + zrt->tableid, show_ng, ctx); } } @@ -1276,7 +1292,7 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, const struct prefix *longer_prefix_p, bool supernets_only, int type, unsigned short ospf_instance_id, uint32_t tableid, - struct route_show_ctx *ctx) + bool show_ng, struct route_show_ctx *ctx) { struct route_table *table; struct zebra_vrf *zvrf = NULL; @@ -1309,7 +1325,7 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, do_show_route_helper(vty, zvrf, table, afi, use_fib, tag, longer_prefix_p, supernets_only, type, - ospf_instance_id, use_json, tableid, ctx); + ospf_instance_id, use_json, tableid, show_ng, ctx); return CMD_SUCCESS; } @@ -1332,12 +1348,6 @@ DEFPY (show_ip_nht, afi_t afi = ipv4 ? AFI_IP : AFI_IP6; vrf_id_t vrf_id = VRF_DEFAULT; struct prefix prefix, *p = NULL; - enum rnh_type rtype; - - if (strcmp(type, "nht") == 0) - rtype = RNH_NEXTHOP_TYPE; - else - rtype = RNH_IMPORT_CHECK_TYPE; if (vrf_all) { struct vrf *vrf; @@ -1347,7 +1357,7 @@ DEFPY (show_ip_nht, if ((zvrf = vrf->info) != NULL) { vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf)); zebra_print_rnh_table(zvrf_id(zvrf), afi, vty, - rtype, NULL); + NULL); } return CMD_SUCCESS; } @@ -1361,7 +1371,7 @@ DEFPY (show_ip_nht, return CMD_WARNING; } - zebra_print_rnh_table(vrf_id, afi, vty, rtype, p); + zebra_print_rnh_table(vrf_id, afi, vty, p); return CMD_SUCCESS; } @@ -1380,9 +1390,9 @@ DEFUN (ip_nht_default_route, if (zvrf->zebra_rnh_ip_default_route) return CMD_SUCCESS; - zvrf->zebra_rnh_ip_default_route = 1; + zvrf->zebra_rnh_ip_default_route = true; - zebra_evaluate_rnh(zvrf, AFI_IP, 0, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST); return CMD_SUCCESS; } @@ -1719,8 +1729,8 @@ DEFUN (no_ip_nht_default_route, if (!zvrf->zebra_rnh_ip_default_route) return CMD_SUCCESS; - zvrf->zebra_rnh_ip_default_route = 0; - zebra_evaluate_rnh(zvrf, AFI_IP, 0, RNH_NEXTHOP_TYPE, NULL); + zvrf->zebra_rnh_ip_default_route = false; + zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST); return CMD_SUCCESS; } @@ -1739,8 +1749,8 @@ DEFUN (ipv6_nht_default_route, if (zvrf->zebra_rnh_ipv6_default_route) return CMD_SUCCESS; - zvrf->zebra_rnh_ipv6_default_route = 1; - zebra_evaluate_rnh(zvrf, AFI_IP6, 0, RNH_NEXTHOP_TYPE, NULL); + zvrf->zebra_rnh_ipv6_default_route = true; + zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST); return CMD_SUCCESS; } @@ -1760,8 +1770,8 @@ DEFUN (no_ipv6_nht_default_route, if (!zvrf->zebra_rnh_ipv6_default_route) return CMD_SUCCESS; - zvrf->zebra_rnh_ipv6_default_route = 0; - zebra_evaluate_rnh(zvrf, AFI_IP6, 0, RNH_NEXTHOP_TYPE, NULL); + zvrf->zebra_rnh_ipv6_default_route = false; + zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST); return CMD_SUCCESS; } @@ -1799,7 +1809,7 @@ DEFPY (show_route, }]\ [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\ >\ - [json$json]", + [<json$json|nexthop-group$ng>]", SHOW_STR IP_STR "IP forwarding table\n" @@ -1828,7 +1838,8 @@ DEFPY (show_route, "IPv6 prefix\n" "Show route matching the specified Network/Mask pair only\n" FRR_IP6_REDIST_HELP_STR_ZEBRA - JSON_STR) + JSON_STR + "Nexthop Group Information\n") { afi_t afi = ipv4 ? AFI_IP : AFI_IP6; struct vrf *vrf; @@ -1864,18 +1875,18 @@ DEFPY (show_route, continue; if (table_all) - do_show_ip_route_all(vty, zvrf, afi, !!fib, - !!json, tag, - prefix_str ? prefix : NULL, - !!supernets_only, type, - ospf_instance_id, &ctx); + do_show_ip_route_all( + vty, zvrf, afi, !!fib, !!json, tag, + prefix_str ? prefix : NULL, + !!supernets_only, type, + ospf_instance_id, !!ng, &ctx); else - do_show_ip_route(vty, zvrf_name(zvrf), afi, - SAFI_UNICAST, !!fib, !!json, - tag, - prefix_str ? prefix : NULL, - !!supernets_only, type, - ospf_instance_id, table, &ctx); + do_show_ip_route( + vty, zvrf_name(zvrf), afi, SAFI_UNICAST, + !!fib, !!json, tag, + prefix_str ? prefix : NULL, + !!supernets_only, type, + ospf_instance_id, table, !!ng, &ctx); } } else { vrf_id_t vrf_id = VRF_DEFAULT; @@ -1894,13 +1905,13 @@ DEFPY (show_route, do_show_ip_route_all(vty, zvrf, afi, !!fib, !!json, tag, prefix_str ? prefix : NULL, !!supernets_only, type, - ospf_instance_id, &ctx); + ospf_instance_id, !!ng, &ctx); else do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib, !!json, tag, prefix_str ? prefix : NULL, !!supernets_only, type, - ospf_instance_id, table, &ctx); + ospf_instance_id, table, !!ng, &ctx); } return CMD_SUCCESS; @@ -2477,10 +2488,7 @@ static void vty_show_ip_route_summary(struct vty *vty, json_object_int_add(json_route_summary, "routesTotalFib", fib_cnt[ZEBRA_ROUTE_TOTAL]); - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json_route_summary, JSON_C_TO_STRING_PRETTY)); - json_object_free(json_route_summary); + vty_json(vty, json_route_summary); } else { vty_out(vty, "------\n"); vty_out(vty, "%-20s %-20d %-20d \n", "Totals", @@ -2628,10 +2636,7 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty, json_object_int_add(json_route_summary, "prefixRoutesTotalFib", fib_cnt[ZEBRA_ROUTE_TOTAL]); - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json_route_summary, JSON_C_TO_STRING_PRETTY)); - json_object_free(json_route_summary); + vty_json(vty, json_route_summary); } else { vty_out(vty, "------\n"); vty_out(vty, "%-20s %-20d %-20d \n", "Totals", @@ -2672,7 +2677,7 @@ DEFUN (show_ipv6_mroute, vty_out(vty, SHOW_ROUTE_V6_HEADER); first = 0; } - vty_show_ip_route(vty, rn, re, NULL, false); + vty_show_ip_route(vty, rn, re, NULL, false, false); } return CMD_SUCCESS; } @@ -2704,7 +2709,8 @@ DEFUN (show_ipv6_mroute_vrf_all, vty_out(vty, SHOW_ROUTE_V6_HEADER); first = 0; } - vty_show_ip_route(vty, rn, re, NULL, false); + vty_show_ip_route(vty, rn, re, NULL, false, + false); } } return CMD_SUCCESS; @@ -3003,9 +3009,7 @@ DEFUN (show_vrf_vni, if (uj) { json_object_object_add(json, "vrfs", json_vrfs); - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); + vty_json(vty, json); } return CMD_SUCCESS; @@ -4317,6 +4321,30 @@ DEFUN(ip_table_range, ip_table_range_cmd, return table_manager_range(vty, true, zvrf, argv[3]->arg, argv[4]->arg); } +#ifdef HAVE_SCRIPTING + +DEFUN(zebra_on_rib_process_script, zebra_on_rib_process_script_cmd, + "zebra on-rib-process script SCRIPT", + ZEBRA_STR + "on_rib_process_dplane_results hook call\n" + "Set a script\n" + "Script name (same as filename in /etc/frr/scripts/, without .lua)\n") +{ + + if (frrscript_names_set_script_name(ZEBRA_ON_RIB_PROCESS_HOOK_CALL, + argv[3]->arg) + == 0) { + vty_out(vty, "Successfully added script %s for hook call %s\n", + argv[3]->arg, ZEBRA_ON_RIB_PROCESS_HOOK_CALL); + } else { + vty_out(vty, "Failed to add script %s for hook call %s\n", + argv[3]->arg, ZEBRA_ON_RIB_PROCESS_HOOK_CALL); + } + return CMD_SUCCESS; +} + +#endif /* HAVE_SCRIPTING */ + /* IP node for static routes. */ static int zebra_ip_config(struct vty *vty); static struct cmd_node ip_node = { @@ -4473,5 +4501,9 @@ void zebra_vty_init(void) install_element(CONFIG_NODE, &no_zebra_kernel_netlink_batch_tx_buf_cmd); #endif /* HAVE_NETLINK */ +#ifdef HAVE_SCRIPTING + install_element(CONFIG_NODE, &zebra_on_rib_process_script_cmd); +#endif /* HAVE_SCRIPTING */ + install_element(VIEW_NODE, &zebra_show_routing_tables_summary_cmd); } |
