ripd: retrofit all RIP interface commands to the new northbound model

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
Renato Westphal 2018-05-09 01:35:03 -03:00
parent c1b7e58eda
commit 94b117b2fb
5 changed files with 634 additions and 564 deletions

View File

@ -778,6 +778,455 @@ void cli_show_rip_version(struct vty *vty, struct lyd_node *dnode,
} }
} }
/*
* 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));
}
void rip_cli_init(void) void rip_cli_init(void)
{ {
install_element(CONFIG_NODE, &router_rip_cmd); install_element(CONFIG_NODE, &router_rip_cmd);
@ -805,4 +1254,19 @@ void rip_cli_init(void)
install_element(RIP_NODE, &no_rip_timers_cmd); install_element(RIP_NODE, &no_rip_timers_cmd);
install_element(RIP_NODE, &rip_version_cmd); install_element(RIP_NODE, &rip_version_cmd);
install_element(RIP_NODE, &no_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);
} }

View File

@ -61,5 +61,26 @@ extern void cli_show_rip_timers(struct vty *vty, struct lyd_node *dnode,
bool show_defaults); bool show_defaults);
extern void cli_show_rip_version(struct vty *vty, struct lyd_node *dnode, extern void cli_show_rip_version(struct vty *vty, struct lyd_node *dnode,
bool show_defaults); bool show_defaults);
extern void cli_show_ip_rip_split_horizon(struct vty *vty,
struct lyd_node *dnode,
bool show_defaults);
extern void cli_show_ip_rip_v2_broadcast(struct vty *vty,
struct lyd_node *dnode,
bool show_defaults);
extern void cli_show_ip_rip_receive_version(struct vty *vty,
struct lyd_node *dnode,
bool show_defaults);
extern void cli_show_ip_rip_send_version(struct vty *vty,
struct lyd_node *dnode,
bool show_defaults);
extern void cli_show_ip_rip_authentication_scheme(struct vty *vty,
struct lyd_node *dnode,
bool show_defaults);
extern void cli_show_ip_rip_authentication_string(struct vty *vty,
struct lyd_node *dnode,
bool show_defaults);
extern void cli_show_ip_rip_authentication_key_chain(struct vty *vty,
struct lyd_node *dnode,
bool show_defaults);
#endif /* _FRR_RIP_CLI_H_ */ #endif /* _FRR_RIP_CLI_H_ */

View File

@ -207,7 +207,6 @@ static void rip_request_interface(struct interface *ifp)
/* Fetch RIP interface information. */ /* Fetch RIP interface information. */
ri = ifp->info; ri = ifp->info;
/* If there is no version configuration in the interface, /* If there is no version configuration in the interface,
use rip's version setting. */ use rip's version setting. */
{ {
@ -498,22 +497,21 @@ void rip_interfaces_clean(void)
static void rip_interface_reset(struct rip_interface *ri) static void rip_interface_reset(struct rip_interface *ri)
{ {
/* Default authentication type is simple password for Cisco ri->auth_type = yang_get_default_enum("%s/authentication-scheme/mode",
compatibility. */ RIP_IFACE);
ri->auth_type = RIP_NO_AUTH; ri->md5_auth_len = yang_get_default_enum(
ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE; "%s/authentication-scheme/md5-auth-length", RIP_IFACE);
/* Set default split-horizon behavior. If the interface is Frame /* Set default split-horizon behavior. If the interface is Frame
Relay or SMDS is enabled, the default value for split-horizon is Relay or SMDS is enabled, the default value for split-horizon is
off. But currently Zebra does detect Frame Relay or SMDS off. But currently Zebra does detect Frame Relay or SMDS
interface. So all interface is set to split horizon. */ interface. So all interface is set to split horizon. */
ri->split_horizon_default = RIP_SPLIT_HORIZON; ri->split_horizon =
ri->split_horizon = ri->split_horizon_default; yang_get_default_enum("%s/split-horizon", RIP_IFACE);
ri->ri_send = RI_RIP_UNSPEC; ri->ri_send = yang_get_default_enum("%s/version-send", RIP_IFACE);
ri->ri_receive = RI_RIP_UNSPEC; ri->ri_receive = yang_get_default_enum("%s/version-receive", RIP_IFACE);
ri->v2_broadcast = yang_get_default_bool("%s/v2-broadcast", RIP_IFACE);
ri->v2_broadcast = 0;
if (ri->auth_str) if (ri->auth_str)
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str); XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
@ -521,7 +519,6 @@ static void rip_interface_reset(struct rip_interface *ri)
if (ri->key_chain) if (ri->key_chain)
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain); XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
ri->list[RIP_FILTER_IN] = NULL; ri->list[RIP_FILTER_IN] = NULL;
ri->list[RIP_FILTER_OUT] = NULL; ri->list[RIP_FILTER_OUT] = NULL;
@ -1163,526 +1160,28 @@ void rip_passive_nondefault_clean(void)
rip_passive_interface_apply_all(); rip_passive_interface_apply_all();
} }
DEFUN (ip_rip_receive_version,
ip_rip_receive_version_cmd,
"ip rip receive version <(1-2)|none>",
IP_STR
"Routing Information Protocol\n"
"Advertisement reception\n"
"Version control\n"
"RIP version\n"
"None\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_type = 4;
struct rip_interface *ri;
ri = ifp->info;
switch (argv[idx_type]->arg[0]) {
case '1':
ri->ri_receive = RI_RIP_VERSION_1;
return CMD_SUCCESS;
case '2':
ri->ri_receive = RI_RIP_VERSION_2;
return CMD_SUCCESS;
case 'n':
ri->ri_receive = RI_RIP_VERSION_NONE;
return CMD_SUCCESS;
default:
break;
}
return CMD_WARNING_CONFIG_FAILED;
}
DEFUN (ip_rip_receive_version_1,
ip_rip_receive_version_1_cmd,
"ip rip receive version <1 2|2 1>",
IP_STR
"Routing Information Protocol\n"
"Advertisement reception\n"
"Version control\n"
"RIP version 1\n"
"RIP version 2\n"
"RIP version 2\n"
"RIP version 1\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
/* Version 1 and 2. */
ri->ri_receive = RI_RIP_VERSION_1_AND_2;
return CMD_SUCCESS;
}
DEFUN (no_ip_rip_receive_version,
no_ip_rip_receive_version_cmd,
"no ip rip receive version [(1-2)]",
NO_STR
IP_STR
"Routing Information Protocol\n"
"Advertisement reception\n"
"Version control\n"
"RIP version\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
ri->ri_receive = RI_RIP_UNSPEC;
return CMD_SUCCESS;
}
DEFUN (ip_rip_send_version,
ip_rip_send_version_cmd,
"ip rip send version (1-2)",
IP_STR
"Routing Information Protocol\n"
"Advertisement transmission\n"
"Version control\n"
"RIP version\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_type = 4;
struct rip_interface *ri;
ri = ifp->info;
/* Version 1. */
if (atoi(argv[idx_type]->arg) == 1) {
ri->ri_send = RI_RIP_VERSION_1;
return CMD_SUCCESS;
}
if (atoi(argv[idx_type]->arg) == 2) {
ri->ri_send = RI_RIP_VERSION_2;
return CMD_SUCCESS;
}
return CMD_WARNING_CONFIG_FAILED;
}
DEFUN (ip_rip_send_version_1,
ip_rip_send_version_1_cmd,
"ip rip send version <1 2|2 1>",
IP_STR
"Routing Information Protocol\n"
"Advertisement transmission\n"
"Version control\n"
"RIP version 1\n"
"RIP version 2\n"
"RIP version 2\n"
"RIP version 1\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
/* Version 1 and 2. */
ri->ri_send = RI_RIP_VERSION_1_AND_2;
return CMD_SUCCESS;
}
DEFUN (no_ip_rip_send_version,
no_ip_rip_send_version_cmd,
"no ip rip send version [(1-2)]",
NO_STR
IP_STR
"Routing Information Protocol\n"
"Advertisement transmission\n"
"Version control\n"
"RIP version\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
ri->ri_send = RI_RIP_UNSPEC;
return CMD_SUCCESS;
}
DEFUN (ip_rip_v2_broadcast,
ip_rip_v2_broadcast_cmd,
"ip rip v2-broadcast",
IP_STR
"Routing Information Protocol\n"
"Send ip broadcast v2 update\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
ri->v2_broadcast = 1;
return CMD_SUCCESS;
}
DEFUN (no_ip_rip_v2_broadcast,
no_ip_rip_v2_broadcast_cmd,
"no ip rip v2-broadcast",
NO_STR
IP_STR
"Routing Information Protocol\n"
"Send ip broadcast v2 update\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
ri->v2_broadcast = 0;
return CMD_SUCCESS;
}
DEFUN (ip_rip_authentication_mode,
ip_rip_authentication_mode_cmd,
"ip rip authentication mode <md5|text> [auth-length <rfc|old-ripd>]",
IP_STR
"Routing Information Protocol\n"
"Authentication control\n"
"Authentication mode\n"
"Keyed message digest\n"
"Clear text authentication\n"
"MD5 authentication data length\n"
"RFC compatible\n"
"Old ripd compatible\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
char *cryptmode = argv[4]->text;
char *authlen = (argc > 5) ? argv[6]->text : NULL;
struct rip_interface *ri;
int auth_type;
ri = ifp->info;
if (strmatch("md5", cryptmode))
auth_type = RIP_AUTH_MD5;
else {
assert(strmatch("text", cryptmode));
auth_type = RIP_AUTH_SIMPLE_PASSWORD;
}
ri->auth_type = auth_type;
if (argc > 5) {
if (auth_type != RIP_AUTH_MD5) {
vty_out(vty,
"auth length argument only valid for md5\n");
return CMD_WARNING_CONFIG_FAILED;
}
if (strmatch("rfc", authlen))
ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
else {
assert(strmatch("old-ripd", authlen));
ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
}
}
return CMD_SUCCESS;
}
DEFUN (no_ip_rip_authentication_mode,
no_ip_rip_authentication_mode_cmd,
"no ip rip authentication mode [<md5|text> [auth-length <rfc|old-ripd>]]",
NO_STR
IP_STR
"Routing Information Protocol\n"
"Authentication control\n"
"Authentication mode\n"
"Keyed message digest\n"
"Clear text authentication\n"
"MD5 authentication data length\n"
"RFC compatible\n"
"Old ripd compatible\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
ri->auth_type = RIP_NO_AUTH;
ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
return CMD_SUCCESS;
}
DEFUN (ip_rip_authentication_string,
ip_rip_authentication_string_cmd,
"ip rip authentication string LINE",
IP_STR
"Routing Information Protocol\n"
"Authentication control\n"
"Authentication string\n"
"Authentication string\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_line = 4;
struct rip_interface *ri;
ri = ifp->info;
if (strlen(argv[idx_line]->arg) > 16) {
vty_out(vty,
"%% RIPv2 authentication string must be shorter than 16\n");
return CMD_WARNING_CONFIG_FAILED;
}
if (ri->key_chain) {
vty_out(vty, "%% key-chain configuration exists\n");
return CMD_WARNING_CONFIG_FAILED;
}
if (ri->auth_str)
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
ri->auth_str = XSTRDUP(MTYPE_RIP_INTERFACE_STRING, argv[idx_line]->arg);
return CMD_SUCCESS;
}
DEFUN (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")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
if (ri->auth_str)
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
return CMD_SUCCESS;
}
DEFUN (ip_rip_authentication_key_chain,
ip_rip_authentication_key_chain_cmd,
"ip rip authentication key-chain LINE",
IP_STR
"Routing Information Protocol\n"
"Authentication control\n"
"Authentication key-chain\n"
"name of key-chain\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_line = 4;
struct rip_interface *ri;
ri = ifp->info;
if (ri->auth_str) {
vty_out(vty, "%% authentication string configuration exists\n");
return CMD_WARNING_CONFIG_FAILED;
}
if (ri->key_chain)
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
ri->key_chain =
XSTRDUP(MTYPE_RIP_INTERFACE_STRING, argv[idx_line]->arg);
return CMD_SUCCESS;
}
DEFUN (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")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
if (ri->key_chain)
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
return CMD_SUCCESS;
}
/* CHANGED: ip rip split-horizon
Cisco and Zebra's command is
ip split-horizon
*/
DEFUN (ip_rip_split_horizon,
ip_rip_split_horizon_cmd,
"ip rip split-horizon",
IP_STR
"Routing Information Protocol\n"
"Perform split horizon\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
ri->split_horizon = RIP_SPLIT_HORIZON;
return CMD_SUCCESS;
}
DEFUN (ip_rip_split_horizon_poisoned_reverse,
ip_rip_split_horizon_poisoned_reverse_cmd,
"ip rip split-horizon poisoned-reverse",
IP_STR
"Routing Information Protocol\n"
"Perform split horizon\n"
"With poisoned-reverse\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
return CMD_SUCCESS;
}
/* CHANGED: no ip rip split-horizon
Cisco and Zebra's command is
no ip split-horizon
*/
DEFUN (no_ip_rip_split_horizon,
no_ip_rip_split_horizon_cmd,
"no ip rip split-horizon",
NO_STR
IP_STR
"Routing Information Protocol\n"
"Perform split horizon\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
ri->split_horizon = RIP_NO_SPLIT_HORIZON;
return CMD_SUCCESS;
}
DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
no_ip_rip_split_horizon_poisoned_reverse_cmd,
"no ip rip split-horizon poisoned-reverse",
NO_STR
IP_STR
"Routing Information Protocol\n"
"Perform split horizon\n"
"With poisoned-reverse\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
ri = ifp->info;
switch (ri->split_horizon) {
case RIP_SPLIT_HORIZON_POISONED_REVERSE:
ri->split_horizon = RIP_SPLIT_HORIZON;
default:
break;
}
return CMD_SUCCESS;
}
/* Write rip configuration of each interface. */ /* Write rip configuration of each interface. */
static int rip_interface_config_write(struct vty *vty) static int rip_interface_config_write(struct vty *vty)
{ {
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
struct interface *ifp; struct interface *ifp;
int write = 0;
FOR_ALL_INTERFACES (vrf, ifp) { FOR_ALL_INTERFACES (vrf, ifp) {
struct rip_interface *ri; struct lyd_node *dnode;
ri = ifp->info; dnode = yang_dnode_get(
running_config->dnode,
/* Do not display the interface if there is no "/frr-interface:lib/interface[name='%s'][vrf='%s']",
* configuration about it. ifp->name, vrf->name);
**/ if (dnode == NULL)
if ((!ifp->desc)
&& (ri->split_horizon == ri->split_horizon_default)
&& (ri->ri_send == RI_RIP_UNSPEC)
&& (ri->ri_receive == RI_RIP_UNSPEC)
&& (ri->auth_type != RIP_AUTH_MD5) && (!ri->v2_broadcast)
&& (ri->md5_auth_len != RIP_AUTH_MD5_SIZE)
&& (!ri->auth_str) && (!ri->key_chain))
continue; continue;
vty_frame(vty, "interface %s\n", ifp->name); write = 1;
nb_cli_show_dnode_cmds(vty, dnode, false);
if (ifp->desc)
vty_out(vty, " description %s\n", ifp->desc);
/* Split horizon. */
if (ri->split_horizon != ri->split_horizon_default) {
switch (ri->split_horizon) {
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;
case RIP_NO_SPLIT_HORIZON:
default:
vty_out(vty, " no ip rip split-horizon\n");
break;
}
} }
/* RIP version setting. */ return write;
if (ri->ri_send != RI_RIP_UNSPEC)
vty_out(vty, " ip rip send version %s\n",
lookup_msg(ri_version_msg, ri->ri_send, NULL));
if (ri->ri_receive != RI_RIP_UNSPEC)
vty_out(vty, " ip rip receive version %s \n",
lookup_msg(ri_version_msg, ri->ri_receive,
NULL));
if (ri->v2_broadcast)
vty_out(vty, " ip rip v2-broadcast\n");
/* RIP authentication. */
if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
vty_out(vty, " ip rip authentication mode text\n");
if (ri->auth_type == RIP_AUTH_MD5) {
vty_out(vty, " ip rip authentication mode md5");
if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
vty_out(vty, " auth-length old-ripd");
else
vty_out(vty, " auth-length rfc");
vty_out(vty, "\n");
}
if (ri->auth_str)
vty_out(vty, " ip rip authentication string %s\n",
ri->auth_str);
if (ri->key_chain)
vty_out(vty, " ip rip authentication key-chain %s\n",
ri->key_chain);
vty_endframe(vty, "!\n");
}
return 0;
} }
int rip_show_network_config(struct vty *vty) int rip_show_network_config(struct vty *vty)
@ -1748,33 +1247,4 @@ void rip_if_init(void)
/* Install interface node. */ /* Install interface node. */
install_node(&interface_node, rip_interface_config_write); install_node(&interface_node, rip_interface_config_write);
if_cmd_init(); if_cmd_init();
/* Install commands. */
install_element(INTERFACE_NODE, &ip_rip_send_version_cmd);
install_element(INTERFACE_NODE, &ip_rip_send_version_1_cmd);
install_element(INTERFACE_NODE, &no_ip_rip_send_version_cmd);
install_element(INTERFACE_NODE, &ip_rip_receive_version_cmd);
install_element(INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
install_element(INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
install_element(INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
install_element(INTERFACE_NODE, &no_ip_rip_v2_broadcast_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_key_chain_cmd);
install_element(INTERFACE_NODE,
&no_ip_rip_authentication_key_chain_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_split_horizon_cmd);
install_element(INTERFACE_NODE,
&ip_rip_split_horizon_poisoned_reverse_cmd);
install_element(INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
install_element(INTERFACE_NODE,
&no_ip_rip_split_horizon_poisoned_reverse_cmd);
} }

View File

@ -785,7 +785,16 @@ static int lib_interface_rip_split_horizon_modify(enum nb_event event,
const struct lyd_node *dnode, const struct lyd_node *dnode,
union nb_resource *resource) union nb_resource *resource)
{ {
/* TODO: implement me. */ struct interface *ifp;
struct rip_interface *ri;
if (event != NB_EV_APPLY)
return NB_OK;
ifp = yang_dnode_get_entry(dnode);
ri = ifp->info;
ri->split_horizon = yang_dnode_get_enum(dnode, NULL);
return NB_OK; return NB_OK;
} }
@ -796,7 +805,16 @@ static int lib_interface_rip_v2_broadcast_modify(enum nb_event event,
const struct lyd_node *dnode, const struct lyd_node *dnode,
union nb_resource *resource) union nb_resource *resource)
{ {
/* TODO: implement me. */ struct interface *ifp;
struct rip_interface *ri;
if (event != NB_EV_APPLY)
return NB_OK;
ifp = yang_dnode_get_entry(dnode);
ri = ifp->info;
ri->v2_broadcast = yang_dnode_get_bool(dnode, NULL);
return NB_OK; return NB_OK;
} }
@ -808,7 +826,16 @@ lib_interface_rip_version_receive_modify(enum nb_event event,
const struct lyd_node *dnode, const struct lyd_node *dnode,
union nb_resource *resource) union nb_resource *resource)
{ {
/* TODO: implement me. */ struct interface *ifp;
struct rip_interface *ri;
if (event != NB_EV_APPLY)
return NB_OK;
ifp = yang_dnode_get_entry(dnode);
ri = ifp->info;
ri->ri_receive = yang_dnode_get_enum(dnode, NULL);
return NB_OK; return NB_OK;
} }
@ -819,7 +846,16 @@ static int lib_interface_rip_version_send_modify(enum nb_event event,
const struct lyd_node *dnode, const struct lyd_node *dnode,
union nb_resource *resource) union nb_resource *resource)
{ {
/* TODO: implement me. */ struct interface *ifp;
struct rip_interface *ri;
if (event != NB_EV_APPLY)
return NB_OK;
ifp = yang_dnode_get_entry(dnode);
ri = ifp->info;
ri->ri_send = yang_dnode_get_enum(dnode, NULL);
return NB_OK; return NB_OK;
} }
@ -830,7 +866,16 @@ static int lib_interface_rip_authentication_scheme_mode_modify(
enum nb_event event, const struct lyd_node *dnode, enum nb_event event, const struct lyd_node *dnode,
union nb_resource *resource) union nb_resource *resource)
{ {
/* TODO: implement me. */ struct interface *ifp;
struct rip_interface *ri;
if (event != NB_EV_APPLY)
return NB_OK;
ifp = yang_dnode_get_entry(dnode);
ri = ifp->info;
ri->auth_type = yang_dnode_get_enum(dnode, NULL);
return NB_OK; return NB_OK;
} }
@ -842,14 +887,33 @@ static int lib_interface_rip_authentication_scheme_md5_auth_length_modify(
enum nb_event event, const struct lyd_node *dnode, enum nb_event event, const struct lyd_node *dnode,
union nb_resource *resource) union nb_resource *resource)
{ {
/* TODO: implement me. */ struct interface *ifp;
struct rip_interface *ri;
if (event != NB_EV_APPLY)
return NB_OK;
ifp = yang_dnode_get_entry(dnode);
ri = ifp->info;
ri->md5_auth_len = yang_dnode_get_enum(dnode, NULL);
return NB_OK; return NB_OK;
} }
static int lib_interface_rip_authentication_scheme_md5_auth_length_delete( static int lib_interface_rip_authentication_scheme_md5_auth_length_delete(
enum nb_event event, const struct lyd_node *dnode) enum nb_event event, const struct lyd_node *dnode)
{ {
/* TODO: implement me. */ struct interface *ifp;
struct rip_interface *ri;
if (event != NB_EV_APPLY)
return NB_OK;
ifp = yang_dnode_get_entry(dnode);
ri = ifp->info;
ri->md5_auth_len = yang_get_default_enum(
"%s/authentication-scheme/md5-auth-length", RIP_IFACE);
return NB_OK; return NB_OK;
} }
@ -861,7 +925,19 @@ lib_interface_rip_authentication_password_modify(enum nb_event event,
const struct lyd_node *dnode, const struct lyd_node *dnode,
union nb_resource *resource) union nb_resource *resource)
{ {
/* TODO: implement me. */ struct interface *ifp;
struct rip_interface *ri;
if (event != NB_EV_APPLY)
return NB_OK;
ifp = yang_dnode_get_entry(dnode);
ri = ifp->info;
if (ri->auth_str)
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
ri->auth_str = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
yang_dnode_get_string(dnode, NULL));
return NB_OK; return NB_OK;
} }
@ -869,7 +945,16 @@ static int
lib_interface_rip_authentication_password_delete(enum nb_event event, lib_interface_rip_authentication_password_delete(enum nb_event event,
const struct lyd_node *dnode) const struct lyd_node *dnode)
{ {
/* TODO: implement me. */ struct interface *ifp;
struct rip_interface *ri;
if (event != NB_EV_APPLY)
return NB_OK;
ifp = yang_dnode_get_entry(dnode);
ri = ifp->info;
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
return NB_OK; return NB_OK;
} }
@ -881,7 +966,19 @@ lib_interface_rip_authentication_key_chain_modify(enum nb_event event,
const struct lyd_node *dnode, const struct lyd_node *dnode,
union nb_resource *resource) union nb_resource *resource)
{ {
/* TODO: implement me. */ struct interface *ifp;
struct rip_interface *ri;
if (event != NB_EV_APPLY)
return NB_OK;
ifp = yang_dnode_get_entry(dnode);
ri = ifp->info;
if (ri->key_chain)
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
ri->key_chain = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
yang_dnode_get_string(dnode, NULL));
return NB_OK; return NB_OK;
} }
@ -889,7 +986,16 @@ static int
lib_interface_rip_authentication_key_chain_delete(enum nb_event event, lib_interface_rip_authentication_key_chain_delete(enum nb_event event,
const struct lyd_node *dnode) const struct lyd_node *dnode)
{ {
/* TODO: implement me. */ struct interface *ifp;
struct rip_interface *ri;
if (event != NB_EV_APPLY)
return NB_OK;
ifp = yang_dnode_get_entry(dnode);
ri = ifp->info;
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
return NB_OK; return NB_OK;
} }
@ -1189,18 +1295,26 @@ const struct frr_yang_module_info frr_ripd_info = {
{ {
.xpath = "/frr-interface:lib/interface/frr-ripd:rip/split-horizon", .xpath = "/frr-interface:lib/interface/frr-ripd:rip/split-horizon",
.cbs.modify = lib_interface_rip_split_horizon_modify, .cbs.modify = lib_interface_rip_split_horizon_modify,
.cbs.cli_show = cli_show_ip_rip_split_horizon,
}, },
{ {
.xpath = "/frr-interface:lib/interface/frr-ripd:rip/v2-broadcast", .xpath = "/frr-interface:lib/interface/frr-ripd:rip/v2-broadcast",
.cbs.modify = lib_interface_rip_v2_broadcast_modify, .cbs.modify = lib_interface_rip_v2_broadcast_modify,
.cbs.cli_show = cli_show_ip_rip_v2_broadcast,
}, },
{ {
.xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-receive", .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-receive",
.cbs.modify = lib_interface_rip_version_receive_modify, .cbs.modify = lib_interface_rip_version_receive_modify,
.cbs.cli_show = cli_show_ip_rip_receive_version,
}, },
{ {
.xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-send", .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-send",
.cbs.modify = lib_interface_rip_version_send_modify, .cbs.modify = lib_interface_rip_version_send_modify,
.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-scheme/mode", .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode",
@ -1215,11 +1329,13 @@ const struct frr_yang_module_info frr_ripd_info = {
.xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-password", .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-password",
.cbs.modify = lib_interface_rip_authentication_password_modify, .cbs.modify = lib_interface_rip_authentication_password_modify,
.cbs.delete = lib_interface_rip_authentication_password_delete, .cbs.delete = lib_interface_rip_authentication_password_delete,
.cbs.cli_show = cli_show_ip_rip_authentication_string,
}, },
{ {
.xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain", .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain",
.cbs.modify = lib_interface_rip_authentication_key_chain_modify, .cbs.modify = lib_interface_rip_authentication_key_chain_modify,
.cbs.delete = lib_interface_rip_authentication_key_chain_delete, .cbs.delete = lib_interface_rip_authentication_key_chain_delete,
.cbs.cli_show = cli_show_ip_rip_authentication_key_chain,
}, },
{ {
.xpath = "/frr-ripd:ripd/state/neighbors/neighbor", .xpath = "/frr-ripd:ripd/state/neighbors/neighbor",

View File

@ -245,7 +245,7 @@ struct rip_interface {
int ri_receive; int ri_receive;
/* RIPv2 broadcast mode */ /* RIPv2 broadcast mode */
int v2_broadcast; bool v2_broadcast;
/* RIPv2 authentication type. */ /* RIPv2 authentication type. */
int auth_type; int auth_type;
@ -257,11 +257,10 @@ struct rip_interface {
char *key_chain; char *key_chain;
/* value to use for md5->auth_len */ /* value to use for md5->auth_len */
uint8_t md5_auth_len; int md5_auth_len;
/* Split horizon flag. */ /* Split horizon flag. */
split_horizon_policy_t split_horizon; split_horizon_policy_t split_horizon;
split_horizon_policy_t split_horizon_default;
/* For filter type slot. */ /* For filter type slot. */
#define RIP_FILTER_IN 0 #define RIP_FILTER_IN 0