summaryrefslogtreecommitdiffstats
path: root/ripd/rip_cli.c
diff options
context:
space:
mode:
Diffstat (limited to 'ripd/rip_cli.c')
-rw-r--r--ripd/rip_cli.c394
1 files changed, 297 insertions, 97 deletions
diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c
index 097c708..4d4349b 100644
--- a/ripd/rip_cli.c
+++ b/ripd/rip_cli.c
@@ -8,6 +8,7 @@
#include <zebra.h>
#include "if.h"
+#include "if_rmap.h"
#include "vrf.h"
#include "log.h"
#include "prefix.h"
@@ -73,7 +74,7 @@ void cli_show_router_rip(struct vty *vty, const struct lyd_node *dnode,
{
const char *vrf_name;
- vrf_name = yang_dnode_get_string(dnode, "./vrf");
+ vrf_name = yang_dnode_get_string(dnode, "vrf");
vty_out(vty, "!\n");
vty_out(vty, "router rip");
@@ -82,6 +83,11 @@ void cli_show_router_rip(struct vty *vty, const struct lyd_node *dnode,
vty_out(vty, "\n");
}
+void cli_show_end_router_rip(struct vty *vty, const struct lyd_node *dnode)
+{
+ vty_out(vty, "exit\n");
+}
+
/*
* XPath: /frr-ripd:ripd/instance/allow-ecmp
*/
@@ -255,11 +261,11 @@ void cli_show_rip_distance_source(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults)
{
vty_out(vty, " distance %s %s",
- yang_dnode_get_string(dnode, "./distance"),
- yang_dnode_get_string(dnode, "./prefix"));
- if (yang_dnode_exists(dnode, "./access-list"))
+ yang_dnode_get_string(dnode, "distance"),
+ yang_dnode_get_string(dnode, "prefix"));
+ if (yang_dnode_exists(dnode, "access-list"))
vty_out(vty, " %s",
- yang_dnode_get_string(dnode, "./access-list"));
+ yang_dnode_get_string(dnode, "access-list"));
vty_out(vty, "\n");
}
@@ -273,8 +279,13 @@ DEFPY_YANG (rip_neighbor,
"Specify a neighbor router\n"
"Neighbor address\n")
{
- nb_cli_enqueue_change(vty, "./explicit-neighbor",
- no ? NB_OP_DESTROY : NB_OP_CREATE, neighbor_str);
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath), "./explicit-neighbor[.='%s']",
+ neighbor_str);
+
+ nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+ NULL);
return nb_cli_apply_changes(vty, NULL);
}
@@ -295,8 +306,12 @@ DEFPY_YANG (rip_network_prefix,
"Enable routing on an IP network\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
{
- nb_cli_enqueue_change(vty, "./network",
- no ? NB_OP_DESTROY : NB_OP_CREATE, network_str);
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath), "./network[.='%s']", network_str);
+
+ nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+ NULL);
return nb_cli_apply_changes(vty, NULL);
}
@@ -317,8 +332,12 @@ DEFPY_YANG (rip_network_if,
"Enable routing on an IP network\n"
"Interface name\n")
{
- nb_cli_enqueue_change(vty, "./interface",
- no ? NB_OP_DESTROY : NB_OP_CREATE, network);
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath), "./interface[.='%s']", network);
+
+ nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+ NULL);
return nb_cli_apply_changes(vty, NULL);
}
@@ -362,12 +381,12 @@ void cli_show_rip_offset_list(struct vty *vty, const struct lyd_node *dnode,
{
const char *interface;
- interface = yang_dnode_get_string(dnode, "./interface");
+ interface = yang_dnode_get_string(dnode, "interface");
vty_out(vty, " offset-list %s %s %s",
- yang_dnode_get_string(dnode, "./access-list"),
- yang_dnode_get_string(dnode, "./direction"),
- yang_dnode_get_string(dnode, "./metric"));
+ yang_dnode_get_string(dnode, "access-list"),
+ yang_dnode_get_string(dnode, "direction"),
+ yang_dnode_get_string(dnode, "metric"));
if (!strmatch(interface, "*"))
vty_out(vty, " %s", interface);
vty_out(vty, "\n");
@@ -412,17 +431,21 @@ DEFPY_YANG (rip_passive_interface,
bool passive_default =
yang_dnode_get_bool(vty->candidate_config->dnode, "%s%s",
VTY_CURR_XPATH, "/passive-default");
+ char xpath[XPATH_MAXLEN];
+ enum nb_operation op;
if (passive_default) {
- nb_cli_enqueue_change(vty, "./non-passive-interface",
- no ? NB_OP_CREATE : NB_OP_DESTROY,
- ifname);
+ snprintf(xpath, sizeof(xpath),
+ "./non-passive-interface[.='%s']", ifname);
+ op = no ? NB_OP_CREATE : NB_OP_DESTROY;
} else {
- nb_cli_enqueue_change(vty, "./passive-interface",
- no ? NB_OP_DESTROY : NB_OP_CREATE,
- ifname);
+ snprintf(xpath, sizeof(xpath), "./passive-interface[.='%s']",
+ ifname);
+ op = no ? NB_OP_DESTROY : NB_OP_CREATE;
}
+ nb_cli_enqueue_change(vty, xpath, op, NULL);
+
return nb_cli_apply_changes(vty, NULL);
}
@@ -475,13 +498,13 @@ void cli_show_rip_redistribute(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults)
{
vty_out(vty, " redistribute %s",
- yang_dnode_get_string(dnode, "./protocol"));
- if (yang_dnode_exists(dnode, "./metric"))
+ yang_dnode_get_string(dnode, "protocol"));
+ if (yang_dnode_exists(dnode, "metric"))
vty_out(vty, " metric %s",
- yang_dnode_get_string(dnode, "./metric"));
- if (yang_dnode_exists(dnode, "./route-map"))
+ yang_dnode_get_string(dnode, "metric"));
+ if (yang_dnode_exists(dnode, "route-map"))
vty_out(vty, " route-map %s",
- yang_dnode_get_string(dnode, "./route-map"));
+ yang_dnode_get_string(dnode, "route-map"));
vty_out(vty, "\n");
}
@@ -495,8 +518,12 @@ DEFPY_YANG (rip_route,
"RIP static route configuration\n"
"IP prefix <network>/<length>\n")
{
- nb_cli_enqueue_change(vty, "./static-route",
- no ? NB_OP_DESTROY : NB_OP_CREATE, route_str);
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath), "./static-route[.='%s']", route_str);
+
+ nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+ NULL);
return nb_cli_apply_changes(vty, NULL);
}
@@ -550,9 +577,9 @@ void cli_show_rip_timers(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults)
{
vty_out(vty, " timers basic %s %s %s\n",
- yang_dnode_get_string(dnode, "./update-interval"),
- yang_dnode_get_string(dnode, "./holddown-interval"),
- yang_dnode_get_string(dnode, "./flush-interval"));
+ yang_dnode_get_string(dnode, "update-interval"),
+ yang_dnode_get_string(dnode, "holddown-interval"),
+ yang_dnode_get_string(dnode, "flush-interval"));
}
/*
@@ -591,7 +618,7 @@ void cli_show_rip_version(struct vty *vty, const struct lyd_node *dnode,
* We have only one "version" command and three possible combinations of
* send/receive values.
*/
- switch (yang_dnode_get_enum(dnode, "./receive")) {
+ switch (yang_dnode_get_enum(dnode, "receive")) {
case RI_RIP_VERSION_1:
vty_out(vty, " version 1\n");
break;
@@ -912,7 +939,7 @@ void cli_show_ip_rip_authentication_scheme(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults)
{
- switch (yang_dnode_get_enum(dnode, "./mode")) {
+ switch (yang_dnode_get_enum(dnode, "mode")) {
case RIP_NO_AUTH:
vty_out(vty, " no ip rip authentication mode\n");
break;
@@ -922,8 +949,8 @@ void cli_show_ip_rip_authentication_scheme(struct vty *vty,
case RIP_AUTH_MD5:
vty_out(vty, " ip rip authentication mode md5");
if (show_defaults
- || !yang_dnode_is_default(dnode, "./md5-auth-length")) {
- if (yang_dnode_get_enum(dnode, "./md5-auth-length")
+ || !yang_dnode_is_default(dnode, "md5-auth-length")) {
+ if (yang_dnode_get_enum(dnode, "md5-auth-length")
== RIP_AUTH_MD5_SIZE)
vty_out(vty, " auth-length rfc");
else
@@ -1098,85 +1125,134 @@ void cli_show_ip_rip_bfd_profile(struct vty *vty, const struct lyd_node *dnode,
yang_dnode_get_string(dnode, NULL));
}
-/*
- * XPath: /frr-ripd:clear-rip-route
- */
-DEFPY_YANG (clear_ip_rip,
- clear_ip_rip_cmd,
- "clear ip rip [vrf WORD]",
- CLEAR_STR
- IP_STR
- "Clear IP RIP database\n"
- VRF_CMD_HELP_STR)
+DEFPY_YANG(
+ rip_distribute_list, rip_distribute_list_cmd,
+ "distribute-list ACCESSLIST4_NAME$name <in|out>$dir [WORD$ifname]",
+ "Filter networks in routing updates\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
{
- struct list *input;
- int ret;
-
- input = list_new();
- if (vrf) {
- struct yang_data *yang_vrf;
-
- yang_vrf = yang_data_new("/frr-ripd:clear-rip-route/input/vrf",
- vrf);
- listnode_add(input, yang_vrf);
- }
-
- ret = nb_cli_rpc(vty, "/frr-ripd:clear-rip-route", input, NULL);
-
- list_delete(&input);
+ char xpath[XPATH_MAXLEN];
- return ret;
+ snprintf(xpath, sizeof(xpath),
+ "./distribute-list[interface='%s']/%s/access-list",
+ ifname ? ifname : "", dir);
+ /* nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); */
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, name);
+ return nb_cli_apply_changes(vty, NULL);
}
-DEFUN (rip_distribute_list,
- rip_distribute_list_cmd,
- "distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
- "Filter networks in routing updates\n"
- "Specify a prefix\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
+DEFPY_YANG(
+ rip_distribute_list_prefix, rip_distribute_list_prefix_cmd,
+ "distribute-list prefix PREFIXLIST4_NAME$name <in|out>$dir [WORD$ifname]",
+ "Filter networks in routing updates\n"
+ "Specify a prefix list\n"
+ "Prefix-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
{
- const char *ifname = NULL;
- int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
-
- if (argv[argc - 1]->type == VARIABLE_TKN)
- ifname = argv[argc - 1]->arg;
+ char xpath[XPATH_MAXLEN];
- return distribute_list_parser(prefix, true, argv[2 + prefix]->text,
- argv[1 + prefix]->arg, ifname);
+ snprintf(xpath, sizeof(xpath),
+ "./distribute-list[interface='%s']/%s/prefix-list",
+ ifname ? ifname : "", dir);
+ /* nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); */
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, name);
+ return nb_cli_apply_changes(vty, NULL);
}
-DEFUN (rip_no_distribute_list,
- rip_no_distribute_list_cmd,
- "no distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
- NO_STR
- "Filter networks in routing updates\n"
- "Specify a prefix\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
+DEFPY_YANG(no_rip_distribute_list,
+ no_rip_distribute_list_cmd,
+ "no distribute-list [ACCESSLIST4_NAME$name] <in|out>$dir [WORD$ifname]",
+ NO_STR
+ "Filter networks in routing updates\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
{
- const char *ifname = NULL;
- int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
+ const struct lyd_node *value_node;
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath),
+ "./distribute-list[interface='%s']/%s/access-list",
+ ifname ? ifname : "", dir);
+ /*
+ * See if the user has specified specific list so check it exists.
+ *
+ * NOTE: Other FRR CLI commands do not do this sort of verification and
+ * there may be an official decision not to.
+ */
+ if (name) {
+ value_node = yang_dnode_getf(vty->candidate_config->dnode, "%s/%s",
+ VTY_CURR_XPATH, xpath);
+ if (!value_node || strcmp(name, lyd_get_value(value_node))) {
+ vty_out(vty, "distribute list doesn't exist\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+}
- if (argv[argc - 1]->type == VARIABLE_TKN)
- ifname = argv[argc - 1]->arg;
+DEFPY_YANG(no_rip_distribute_list_prefix,
+ no_rip_distribute_list_prefix_cmd,
+ "no distribute-list prefix [PREFIXLIST4_NAME$name] <in|out>$dir [WORD$ifname]",
+ NO_STR
+ "Filter networks in routing updates\n"
+ "Specify a prefix list\n"
+ "Prefix-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
+{
+ const struct lyd_node *value_node;
+ char xpath[XPATH_MAXLEN];
- return distribute_list_no_parser(vty, prefix, true,
- argv[3 + prefix]->text,
- argv[2 + prefix]->arg, ifname);
+ snprintf(xpath, sizeof(xpath),
+ "./distribute-list[interface='%s']/%s/prefix-list",
+ ifname ? ifname : "", dir);
+ /*
+ * See if the user has specified specific list so check it exists.
+ *
+ * NOTE: Other FRR CLI commands do not do this sort of verification and
+ * there may be an official decision not to.
+ */
+ if (name) {
+ value_node = yang_dnode_getf(vty->candidate_config->dnode, "%s/%s",
+ VTY_CURR_XPATH, xpath);
+ if (!value_node || strcmp(name, lyd_get_value(value_node))) {
+ vty_out(vty, "distribute list doesn't exist\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
}
+/* RIP node structure. */
+static struct cmd_node rip_node = {
+ .name = "rip",
+ .node = RIP_NODE,
+ .parent_node = CONFIG_NODE,
+ .prompt = "%s(config-router)# ",
+ // .config_write = config_write_rip,
+};
+
void rip_cli_init(void)
{
+ install_node(&rip_node);
+
install_element(CONFIG_NODE, &router_rip_cmd);
install_element(CONFIG_NODE, &no_router_rip_cmd);
install_element(RIP_NODE, &rip_distribute_list_cmd);
- install_element(RIP_NODE, &rip_no_distribute_list_cmd);
+ install_element(RIP_NODE, &rip_distribute_list_prefix_cmd);
+ install_element(RIP_NODE, &no_rip_distribute_list_cmd);
+ install_element(RIP_NODE, &no_rip_distribute_list_prefix_cmd);
install_element(RIP_NODE, &rip_allow_ecmp_cmd);
install_element(RIP_NODE, &no_rip_allow_ecmp_cmd);
@@ -1200,6 +1276,7 @@ void rip_cli_init(void)
install_element(RIP_NODE, &no_rip_version_cmd);
install_element(RIP_NODE, &rip_bfd_default_profile_cmd);
install_element(RIP_NODE, &no_rip_bfd_default_profile_cmd);
+ install_default(RIP_NODE);
install_element(INTERFACE_NODE, &ip_rip_split_horizon_cmd);
install_element(INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
@@ -1218,5 +1295,128 @@ void rip_cli_init(void)
install_element(INTERFACE_NODE, &ip_rip_bfd_profile_cmd);
install_element(INTERFACE_NODE, &no_ip_rip_bfd_profile_cmd);
- install_element(ENABLE_NODE, &clear_ip_rip_cmd);
-}
+ if_rmap_init(RIP_NODE);
+}
+/* clang-format off */
+const struct frr_yang_module_info frr_ripd_cli_info = {
+ .name = "frr-ripd",
+ .ignore_cfg_cbs = true,
+ .nodes = {
+ {
+ .xpath = "/frr-ripd:ripd/instance",
+ .cbs.cli_show = cli_show_router_rip,
+ .cbs.cli_show_end = cli_show_end_router_rip,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/allow-ecmp",
+ .cbs.cli_show = cli_show_rip_allow_ecmp,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/default-information-originate",
+ .cbs.cli_show = cli_show_rip_default_information_originate,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/default-metric",
+ .cbs.cli_show = cli_show_rip_default_metric,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/distance/default",
+ .cbs.cli_show = cli_show_rip_distance,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/distance/source",
+ .cbs.cli_show = cli_show_rip_distance_source,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/explicit-neighbor",
+ .cbs.cli_show = cli_show_rip_neighbor,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/network",
+ .cbs.cli_show = cli_show_rip_network_prefix,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/interface",
+ .cbs.cli_show = cli_show_rip_network_interface,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/offset-list",
+ .cbs.cli_show = cli_show_rip_offset_list,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/passive-default",
+ .cbs.cli_show = cli_show_rip_passive_default,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/passive-interface",
+ .cbs.cli_show = cli_show_rip_passive_interface,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/non-passive-interface",
+ .cbs.cli_show = cli_show_rip_non_passive_interface,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/redistribute",
+ .cbs.cli_show = cli_show_rip_redistribute,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/if-route-maps/if-route-map",
+ .cbs.cli_show = cli_show_if_route_map,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/static-route",
+ .cbs.cli_show = cli_show_rip_route,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/timers",
+ .cbs.cli_show = cli_show_rip_timers,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/version",
+ .cbs.cli_show = cli_show_rip_version,
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/default-bfd-profile",
+ .cbs.cli_show = cli_show_ripd_instance_default_bfd_profile,
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-ripd:rip/split-horizon",
+ .cbs.cli_show = cli_show_ip_rip_split_horizon,
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-ripd:rip/v2-broadcast",
+ .cbs.cli_show = cli_show_ip_rip_v2_broadcast,
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-receive",
+ .cbs.cli_show = cli_show_ip_rip_receive_version,
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-send",
+ .cbs.cli_show = cli_show_ip_rip_send_version,
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme",
+ .cbs.cli_show = cli_show_ip_rip_authentication_scheme,
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-password",
+ .cbs.cli_show = cli_show_ip_rip_authentication_string,
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain",
+ .cbs.cli_show = cli_show_ip_rip_authentication_key_chain,
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-ripd:rip/bfd-monitoring/enable",
+ .cbs.cli_show = cli_show_ip_rip_bfd_enable,
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-ripd:rip/bfd-monitoring/profile",
+ .cbs.cli_show = cli_show_ip_rip_bfd_profile,
+ },
+ {
+ .xpath = NULL,
+ },
+ }
+};