summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2018-05-09 06:34:59 +0200
committerRenato Westphal <renato@opensourcerouting.org>2018-10-27 20:16:12 +0200
commitf0ab22fb70ef94ce4f3109d36744d730003e9876 (patch)
tree9340b90badfbb1d02e91dc99b02dfd44e1a905ca
parentripd: retrofit the 'distance source' commands to the new northbound model (diff)
downloadfrr-f0ab22fb70ef94ce4f3109d36744d730003e9876.tar.xz
frr-f0ab22fb70ef94ce4f3109d36744d730003e9876.zip
ripd: retrofit the 'neighbor' command to the new northbound model
Make rip_neighbor_add() and rip_neighbor_delete() return northbound error codes since their return values are used as the return value of some northbound callbacks. These functions shouldn't fail in normal conditions because the northbound layer guarantees it will never call the 'create' or 'delete' callback more than once for the same object. Hence any failure in those functions would indicate an internal inconsistency that needs to be investigated (by returning NB_ERR the northbound will log a detailed error message indicating the xpath of the object, the event and the callback where the error happened). Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
-rw-r--r--ripd/rip_cli.c28
-rw-r--r--ripd/rip_cli.h2
-rw-r--r--ripd/rip_interface.c62
-rw-r--r--ripd/rip_northbound.c25
-rw-r--r--ripd/ripd.h2
5 files changed, 60 insertions, 59 deletions
diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c
index 4f394bf19..1d94d02bd 100644
--- a/ripd/rip_cli.c
+++ b/ripd/rip_cli.c
@@ -304,6 +304,33 @@ void cli_show_rip_distance_source(struct vty *vty, struct lyd_node *dnode,
vty_out(vty, "\n");
}
+/*
+ * XPath: /frr-ripd:ripd/instance/explicit-neighbor
+ */
+DEFPY (rip_neighbor,
+ rip_neighbor_cmd,
+ "[no] neighbor A.B.C.D",
+ NO_STR
+ "Specify a neighbor router\n"
+ "Neighbor address\n")
+{
+ struct cli_config_change changes[] = {
+ {
+ .xpath = "./explicit-neighbor",
+ .operation = no ? NB_OP_DELETE : NB_OP_CREATE,
+ .value = neighbor_str,
+ },
+ };
+
+ return nb_cli_cfg_change(vty, NULL, changes, array_size(changes));
+}
+
+void cli_show_rip_neighbor(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ vty_out(vty, " neighbor %s\n", yang_dnode_get_string(dnode, NULL));
+}
+
void rip_cli_init(void)
{
install_element(CONFIG_NODE, &router_rip_cmd);
@@ -317,4 +344,5 @@ void rip_cli_init(void)
install_element(RIP_NODE, &no_rip_distance_cmd);
install_element(RIP_NODE, &rip_distance_source_cmd);
install_element(RIP_NODE, &no_rip_distance_source_cmd);
+ install_element(RIP_NODE, &rip_neighbor_cmd);
}
diff --git a/ripd/rip_cli.h b/ripd/rip_cli.h
index dd810fb70..34cbd646f 100644
--- a/ripd/rip_cli.h
+++ b/ripd/rip_cli.h
@@ -35,5 +35,7 @@ extern void cli_show_rip_distance(struct vty *vty, struct lyd_node *dnode,
extern void cli_show_rip_distance_source(struct vty *vty,
struct lyd_node *dnode,
bool show_defaults);
+extern void cli_show_rip_neighbor(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
#endif /* _FRR_RIP_CLI_H_ */
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index bbac1a0a0..4373484a2 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -35,6 +35,7 @@
#include "sockopt.h"
#include "privs.h"
#include "lib_errors.h"
+#include "northbound_cli.h"
#include "zebra/connected.h"
@@ -1011,29 +1012,29 @@ int rip_neighbor_lookup(struct sockaddr_in *from)
}
/* Add new RIP neighbor to the neighbor tree. */
-static int rip_neighbor_add(struct prefix_ipv4 *p)
+int rip_neighbor_add(struct prefix_ipv4 *p)
{
struct route_node *node;
node = route_node_get(rip->neighbor, (struct prefix *)p);
if (node->info)
- return -1;
+ return NB_ERR_INCONSISTENCY;
node->info = rip->neighbor;
- return 0;
+ return NB_OK;
}
/* Delete RIP neighbor from the neighbor tree. */
-static int rip_neighbor_delete(struct prefix_ipv4 *p)
+int rip_neighbor_delete(struct prefix_ipv4 *p)
{
struct route_node *node;
/* Lock for look up. */
node = route_node_lookup(rip->neighbor, (struct prefix *)p);
if (!node)
- return -1;
+ return NB_ERR_INCONSISTENCY;
node->info = NULL;
@@ -1043,7 +1044,7 @@ static int rip_neighbor_delete(struct prefix_ipv4 *p)
/* Unlock real neighbor information lock. */
route_unlock_node(node);
- return 0;
+ return NB_OK;
}
/* Clear all network and neighbor configuration. */
@@ -1208,53 +1209,6 @@ DEFUN (no_rip_network,
return CMD_SUCCESS;
}
-/* RIP neighbor configuration set. */
-DEFUN (rip_neighbor,
- rip_neighbor_cmd,
- "neighbor A.B.C.D",
- "Specify a neighbor router\n"
- "Neighbor address\n")
-{
- int idx_ipv4 = 1;
- int ret;
- struct prefix_ipv4 p;
-
- ret = str2prefix_ipv4(argv[idx_ipv4]->arg, &p);
-
- if (ret <= 0) {
- vty_out(vty, "Please specify address by A.B.C.D\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- rip_neighbor_add(&p);
-
- return CMD_SUCCESS;
-}
-
-/* RIP neighbor configuration unset. */
-DEFUN (no_rip_neighbor,
- no_rip_neighbor_cmd,
- "no neighbor A.B.C.D",
- NO_STR
- "Specify a neighbor router\n"
- "Neighbor address\n")
-{
- int idx_ipv4 = 2;
- int ret;
- struct prefix_ipv4 p;
-
- ret = str2prefix_ipv4(argv[idx_ipv4]->arg, &p);
-
- if (ret <= 0) {
- vty_out(vty, "Please specify address by A.B.C.D\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- rip_neighbor_delete(&p);
-
- return CMD_SUCCESS;
-}
-
DEFUN (ip_rip_receive_version,
ip_rip_receive_version_cmd,
"ip rip receive version <(1-2)|none>",
@@ -1896,8 +1850,6 @@ void rip_if_init(void)
/* Install commands. */
install_element(RIP_NODE, &rip_network_cmd);
install_element(RIP_NODE, &no_rip_network_cmd);
- install_element(RIP_NODE, &rip_neighbor_cmd);
- install_element(RIP_NODE, &no_rip_neighbor_cmd);
install_element(RIP_NODE, &rip_passive_interface_cmd);
install_element(RIP_NODE, &no_rip_passive_interface_cmd);
diff --git a/ripd/rip_northbound.c b/ripd/rip_northbound.c
index 25c279a77..fdb19a3c1 100644
--- a/ripd/rip_northbound.c
+++ b/ripd/rip_northbound.c
@@ -276,15 +276,31 @@ static int ripd_instance_explicit_neighbor_create(enum nb_event event,
const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
- return NB_OK;
+ struct prefix_ipv4 p;
+
+ if (event != NB_EV_APPLY)
+ return NB_OK;
+
+ p.family = AF_INET;
+ p.prefixlen = IPV4_MAX_BITLEN;
+ yang_dnode_get_ipv4(&p.prefix, dnode, NULL);
+
+ return rip_neighbor_add(&p);
}
static int ripd_instance_explicit_neighbor_delete(enum nb_event event,
const struct lyd_node *dnode)
{
- /* TODO: implement me. */
- return NB_OK;
+ struct prefix_ipv4 p;
+
+ if (event != NB_EV_APPLY)
+ return NB_OK;
+
+ p.family = AF_INET;
+ p.prefixlen = IPV4_MAX_BITLEN;
+ yang_dnode_get_ipv4(&p.prefix, dnode, NULL);
+
+ return rip_neighbor_delete(&p);
}
/*
@@ -858,6 +874,7 @@ const struct frr_yang_module_info frr_ripd_info = {
.xpath = "/frr-ripd:ripd/instance/explicit-neighbor",
.cbs.create = ripd_instance_explicit_neighbor_create,
.cbs.delete = ripd_instance_explicit_neighbor_delete,
+ .cbs.cli_show = cli_show_rip_neighbor,
},
{
.xpath = "/frr-ripd:ripd/instance/network",
diff --git a/ripd/ripd.h b/ripd/ripd.h
index 31697264a..fd8762904 100644
--- a/ripd/ripd.h
+++ b/ripd/ripd.h
@@ -389,6 +389,8 @@ extern int rip_create(int socket);
extern int rip_request_send(struct sockaddr_in *, struct interface *, uint8_t,
struct connected *);
extern int rip_neighbor_lookup(struct sockaddr_in *);
+extern int rip_neighbor_add(struct prefix_ipv4 *p);
+extern int rip_neighbor_delete(struct prefix_ipv4 *p);
extern void rip_ecmp_disable(void);