}
}
+/*
+ * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon
+ */
+DEFPY (ip_rip_split_horizon,
+ ip_rip_split_horizon_cmd,
+ "[no] ip rip split-horizon [poisoned-reverse$poisoned_reverse]",
+ NO_STR
+ IP_STR
+ "Routing Information Protocol\n"
+ "Perform split horizon\n"
+ "With poisoned-reverse\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/split-horizon",
+ .operation = NB_OP_MODIFY,
+ },
+ };
+
+ if (no)
+ changes[0].value = "disabled";
+ else if (poisoned_reverse)
+ changes[0].value = "poison-reverse";
+ else
+ changes[0].value = "simple";
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+void cli_show_ip_rip_split_horizon(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ int value;
+
+ value = yang_dnode_get_enum(dnode, NULL);
+ switch (value) {
+ case RIP_NO_SPLIT_HORIZON:
+ vty_out(vty, " no ip rip split-horizon\n");
+ break;
+ case RIP_SPLIT_HORIZON:
+ vty_out(vty, " ip rip split-horizon\n");
+ break;
+ case RIP_SPLIT_HORIZON_POISONED_REVERSE:
+ vty_out(vty, " ip rip split-horizon poisoned-reverse\n");
+ break;
+ }
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast
+ */
+DEFPY (ip_rip_v2_broadcast,
+ ip_rip_v2_broadcast_cmd,
+ "[no] ip rip v2-broadcast",
+ NO_STR
+ IP_STR
+ "Routing Information Protocol\n"
+ "Send ip broadcast v2 update\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/v2-broadcast",
+ .operation = NB_OP_MODIFY,
+ .value = no ? "false" : "true",
+ },
+ };
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+void cli_show_ip_rip_v2_broadcast(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ if (!yang_dnode_get_bool(dnode, NULL))
+ vty_out(vty, " no");
+
+ vty_out(vty, " ip rip v2-broadcast\n");
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive
+ */
+DEFPY (ip_rip_receive_version,
+ ip_rip_receive_version_cmd,
+ "ip rip receive version <{1$v1|2$v2}|none>",
+ IP_STR
+ "Routing Information Protocol\n"
+ "Advertisement reception\n"
+ "Version control\n"
+ "RIP version 1\n"
+ "RIP version 2\n"
+ "None\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/version-receive",
+ .operation = NB_OP_MODIFY,
+ },
+ };
+
+ if (v1 && v2)
+ changes[0].value = "both";
+ else if (v1)
+ changes[0].value = "1";
+ else if (v2)
+ changes[0].value = "2";
+ else
+ changes[0].value = "none";
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+DEFPY (no_ip_rip_receive_version,
+ no_ip_rip_receive_version_cmd,
+ "no ip rip receive version [<{1|2}|none>]",
+ NO_STR
+ IP_STR
+ "Routing Information Protocol\n"
+ "Advertisement reception\n"
+ "Version control\n"
+ "RIP version 1\n"
+ "RIP version 2\n"
+ "None\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/version-receive",
+ .operation = NB_OP_MODIFY,
+ .value = NULL,
+ },
+ };
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+void cli_show_ip_rip_receive_version(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ switch (yang_dnode_get_enum(dnode, NULL)) {
+ case RI_RIP_UNSPEC:
+ vty_out(vty, " no ip rip receive version\n");
+ break;
+ case RI_RIP_VERSION_1:
+ vty_out(vty, " ip rip receive version 1\n");
+ break;
+ case RI_RIP_VERSION_2:
+ vty_out(vty, " ip rip receive version 2\n");
+ break;
+ case RI_RIP_VERSION_1_AND_2:
+ vty_out(vty, " ip rip receive version 1 2\n");
+ break;
+ case RI_RIP_VERSION_NONE:
+ vty_out(vty, " ip rip receive version none\n");
+ break;
+ }
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send
+ */
+DEFPY (ip_rip_send_version,
+ ip_rip_send_version_cmd,
+ "ip rip send version <{1$v1|2$v2}|none>",
+ IP_STR
+ "Routing Information Protocol\n"
+ "Advertisement transmission\n"
+ "Version control\n"
+ "RIP version 1\n"
+ "RIP version 2\n"
+ "None\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/version-send",
+ .operation = NB_OP_MODIFY,
+ },
+ };
+
+ if (v1 && v2)
+ changes[0].value = "both";
+ else if (v1)
+ changes[0].value = "1";
+ else if (v2)
+ changes[0].value = "2";
+ else
+ changes[0].value = "none";
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+DEFPY (no_ip_rip_send_version,
+ no_ip_rip_send_version_cmd,
+ "no ip rip send version [<{1|2}|none>]",
+ NO_STR
+ IP_STR
+ "Routing Information Protocol\n"
+ "Advertisement transmission\n"
+ "Version control\n"
+ "RIP version 1\n"
+ "RIP version 2\n"
+ "None\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/version-send",
+ .operation = NB_OP_MODIFY,
+ .value = NULL,
+ },
+ };
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+void cli_show_ip_rip_send_version(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ switch (yang_dnode_get_enum(dnode, NULL)) {
+ case RI_RIP_UNSPEC:
+ vty_out(vty, " no ip rip send version\n");
+ break;
+ case RI_RIP_VERSION_1:
+ vty_out(vty, " ip rip send version 1\n");
+ break;
+ case RI_RIP_VERSION_2:
+ vty_out(vty, " ip rip send version 2\n");
+ break;
+ case RI_RIP_VERSION_1_AND_2:
+ vty_out(vty, " ip rip send version 1 2\n");
+ break;
+ case RI_RIP_VERSION_NONE:
+ vty_out(vty, " ip rip send version none\n");
+ break;
+ }
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme
+ */
+DEFPY (ip_rip_authentication_mode,
+ ip_rip_authentication_mode_cmd,
+ "ip rip authentication mode <md5$mode [auth-length <rfc|old-ripd>$auth_length]|text$mode>",
+ IP_STR
+ "Routing Information Protocol\n"
+ "Authentication control\n"
+ "Authentication mode\n"
+ "Keyed message digest\n"
+ "MD5 authentication data length\n"
+ "RFC compatible\n"
+ "Old ripd compatible\n"
+ "Clear text authentication\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/authentication-scheme/mode",
+ .operation = NB_OP_MODIFY,
+ .value = strmatch(mode, "md5") ? "md5" : "plain-text",
+ },
+ {
+ .xpath = "./frr-ripd:rip/authentication-scheme/md5-auth-length",
+ .operation = NB_OP_MODIFY,
+ },
+ };
+
+ if (auth_length) {
+ if (strmatch(auth_length, "rfc"))
+ changes[1].value = "16";
+ else
+ changes[1].value = "20";
+ }
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+DEFPY (no_ip_rip_authentication_mode,
+ no_ip_rip_authentication_mode_cmd,
+ "no ip rip authentication mode [<md5 [auth-length <rfc|old-ripd>]|text>]",
+ NO_STR
+ IP_STR
+ "Routing Information Protocol\n"
+ "Authentication control\n"
+ "Authentication mode\n"
+ "Keyed message digest\n"
+ "MD5 authentication data length\n"
+ "RFC compatible\n"
+ "Old ripd compatible\n"
+ "Clear text authentication\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/authentication-scheme/mode",
+ .operation = NB_OP_MODIFY,
+ },
+ {
+ .xpath = "./frr-ripd:rip/authentication-scheme/md5-auth-length",
+ .operation = NB_OP_MODIFY,
+ },
+ };
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+void cli_show_ip_rip_authentication_scheme(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults)
+{
+ switch (yang_dnode_get_enum(dnode, "./mode")) {
+ case RIP_NO_AUTH:
+ vty_out(vty, " no ip rip authentication mode\n");
+ break;
+ case RIP_AUTH_SIMPLE_PASSWORD:
+ vty_out(vty, " ip rip authentication mode text\n");
+ break;
+ 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")
+ == RIP_AUTH_MD5_SIZE)
+ vty_out(vty, " auth-length rfc");
+ else
+ vty_out(vty, " auth-length old-ripd");
+ }
+ vty_out(vty, "\n");
+ break;
+ }
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password
+ */
+DEFPY (ip_rip_authentication_string,
+ ip_rip_authentication_string_cmd,
+ "ip rip authentication string LINE$password",
+ IP_STR
+ "Routing Information Protocol\n"
+ "Authentication control\n"
+ "Authentication string\n"
+ "Authentication string\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/authentication-password",
+ .operation = NB_OP_MODIFY,
+ .value = password,
+ },
+ };
+
+ if (strlen(password) > 16) {
+ vty_out(vty,
+ "%% RIPv2 authentication string must be shorter than 16\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH,
+ "/frr-ripd:rip/authentication-key-chain")) {
+ vty_out(vty, "%% key-chain configuration exists\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+DEFPY (no_ip_rip_authentication_string,
+ no_ip_rip_authentication_string_cmd,
+ "no ip rip authentication string [LINE]",
+ NO_STR
+ IP_STR
+ "Routing Information Protocol\n"
+ "Authentication control\n"
+ "Authentication string\n"
+ "Authentication string\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/authentication-password",
+ .operation = NB_OP_DELETE,
+ },
+ };
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+void cli_show_ip_rip_authentication_string(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults)
+{
+ vty_out(vty, " ip rip authentication string %s\n",
+ yang_dnode_get_string(dnode, NULL));
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain
+ */
+DEFPY (ip_rip_authentication_key_chain,
+ ip_rip_authentication_key_chain_cmd,
+ "ip rip authentication key-chain LINE$keychain",
+ IP_STR
+ "Routing Information Protocol\n"
+ "Authentication control\n"
+ "Authentication key-chain\n"
+ "name of key-chain\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/authentication-key-chain",
+ .operation = NB_OP_MODIFY,
+ .value = keychain,
+ },
+ };
+
+ if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH,
+ "/frr-ripd:rip/authentication-password")) {
+ vty_out(vty, "%% authentication string configuration exists\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+DEFPY (no_ip_rip_authentication_key_chain,
+ no_ip_rip_authentication_key_chain_cmd,
+ "no ip rip authentication key-chain [LINE]",
+ NO_STR
+ IP_STR
+ "Routing Information Protocol\n"
+ "Authentication control\n"
+ "Authentication key-chain\n"
+ "name of key-chain\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./frr-ripd:rip/authentication-key-chain",
+ .operation = NB_OP_DELETE,
+ },
+ };
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+void cli_show_ip_rip_authentication_key_chain(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults)
+{
+ vty_out(vty, " ip rip authentication key-chain %s\n",
+ yang_dnode_get_string(dnode, NULL));
+}
+
+/*
+ * XPath: /frr-ripd:clear-rip-route
+ */
+DEFPY (clear_ip_rip,
+ clear_ip_rip_cmd,
+ "clear ip rip",
+ CLEAR_STR
+ IP_STR
+ "Clear IP RIP database\n")
+{
+ return nb_cli_rpc("/frr-ripd:clear-rip-route", NULL, NULL);
+}
+
void rip_cli_init(void)
{
install_element(CONFIG_NODE, &router_rip_cmd);
install_element(RIP_NODE, &no_rip_timers_cmd);
install_element(RIP_NODE, &rip_version_cmd);
install_element(RIP_NODE, &no_rip_version_cmd);
+
+ install_element(INTERFACE_NODE, &ip_rip_split_horizon_cmd);
+ install_element(INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
+ install_element(INTERFACE_NODE, &ip_rip_receive_version_cmd);
+ install_element(INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
+ install_element(INTERFACE_NODE, &ip_rip_send_version_cmd);
+ install_element(INTERFACE_NODE, &no_ip_rip_send_version_cmd);
+ install_element(INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
+ install_element(INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
+ install_element(INTERFACE_NODE, &ip_rip_authentication_string_cmd);
+ install_element(INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
+ install_element(INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
+ install_element(INTERFACE_NODE,
+ &no_ip_rip_authentication_key_chain_cmd);
+
+ install_element(ENABLE_NODE, &clear_ip_rip_cmd);
}