diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index 4f394bf19e..1d94d02bd7 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 dd810fb70e..34cbd646fb 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 bbac1a0a00..4373484a29 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 25c279a773..fdb19a3c14 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 31697264a0..fd8762904f 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);