summaryrefslogtreecommitdiff
path: root/zebra/zebra_vty.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_vty.c')
-rw-r--r--zebra/zebra_vty.c184
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);
}