From 8c9226c216f9bf3ee0ca28f8db52ef9d0956f411 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 9 May 2018 01:34:58 -0300 Subject: [PATCH] ripd: retrofit the 'router rip' command to the new northbound model * Implement the northbound callbacks associated to the '/frr-ripd:ripd/instance' YANG path (the code is mostly a copy and paste from the original "router rip" DEFUNs); * Move rip_create_socket() out of rip_create() since creating a socket is an error-prone operation and thus needs to be performed separately during the NB_EV_PREPARE phase; * On rip_create(), fetch the defaults from the frr-ripd YANG model; * Convert the "[no] router rip" CLI commands to be dumb wrappers around the northbound callbacks; * On config_write_rip(), write logic to call all 'cli_show' northbound callbacks defined under the '/frr-ripd:ripd/instance' YANG path. Signed-off-by: Renato Westphal --- ripd/rip_cli.c | 53 +++++++++++++++++++++++++++++ ripd/rip_cli.h | 3 ++ ripd/rip_northbound.c | 29 ++++++++++++++-- ripd/ripd.c | 77 +++++++++++++++---------------------------- ripd/ripd.h | 3 ++ 5 files changed, 112 insertions(+), 53 deletions(-) diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index 0923af5798..684fbd300a 100644 --- a/ripd/rip_cli.c +++ b/ripd/rip_cli.c @@ -34,6 +34,59 @@ #include "ripd/rip_cli_clippy.c" #endif +/* + * XPath: /frr-ripd:ripd/instance + */ +DEFPY_NOSH (router_rip, + router_rip_cmd, + "router rip", + "Enable a routing process\n" + "Routing Information Protocol (RIP)\n") +{ + int ret; + + struct cli_config_change changes[] = { + { + .xpath = "/frr-ripd:ripd/instance", + .operation = NB_OP_CREATE, + .value = NULL, + }, + }; + + ret = nb_cli_cfg_change(vty, NULL, changes, array_size(changes)); + if (ret == CMD_SUCCESS) + VTY_PUSH_XPATH(RIP_NODE, changes[0].xpath); + + return ret; +} + +DEFPY (no_router_rip, + no_router_rip_cmd, + "no router rip", + NO_STR + "Enable a routing process\n" + "Routing Information Protocol (RIP)\n") +{ + struct cli_config_change changes[] = { + { + .xpath = "/frr-ripd:ripd/instance", + .operation = NB_OP_DELETE, + .value = NULL, + }, + }; + + return nb_cli_cfg_change(vty, NULL, changes, array_size(changes)); +} + +void cli_show_router_rip(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, "!\n"); + vty_out(vty, "router rip\n"); +} + void rip_cli_init(void) { + install_element(CONFIG_NODE, &router_rip_cmd); + install_element(CONFIG_NODE, &no_router_rip_cmd); } diff --git a/ripd/rip_cli.h b/ripd/rip_cli.h index 2af54e3597..b8997e8805 100644 --- a/ripd/rip_cli.h +++ b/ripd/rip_cli.h @@ -21,4 +21,7 @@ #ifndef _FRR_RIP_CLI_H_ #define _FRR_RIP_CLI_H_ +extern void cli_show_router_rip(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); + #endif /* _FRR_RIP_CLI_H_ */ diff --git a/ripd/rip_northbound.c b/ripd/rip_northbound.c index c2a73bfa89..e780bc5e11 100644 --- a/ripd/rip_northbound.c +++ b/ripd/rip_northbound.c @@ -39,14 +39,38 @@ static int ripd_instance_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { - /* TODO: implement me. */ + int socket; + + switch (event) { + case NB_EV_VALIDATE: + break; + case NB_EV_PREPARE: + socket = rip_create_socket(); + if (socket < 0) + return NB_ERR_RESOURCE; + resource->fd = socket; + break; + case NB_EV_ABORT: + socket = resource->fd; + close(socket); + break; + case NB_EV_APPLY: + socket = resource->fd; + rip_create(socket); + break; + } + return NB_OK; } static int ripd_instance_delete(enum nb_event event, const struct lyd_node *dnode) { - /* TODO: implement me. */ + if (event != NB_EV_APPLY) + return NB_OK; + + rip_clean(); + return NB_OK; } @@ -693,6 +717,7 @@ const struct frr_yang_module_info frr_ripd_info = { .xpath = "/frr-ripd:ripd/instance", .cbs.create = ripd_instance_create, .cbs.delete = ripd_instance_delete, + .cbs.cli_show = cli_show_router_rip, }, { .xpath = "/frr-ripd:ripd/instance/allow-ecmp", diff --git a/ripd/ripd.c b/ripd/ripd.c index dd0d17ee47..9cb1ae8cfb 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -41,6 +41,7 @@ #include "keychain.h" #include "privs.h" #include "lib_errors.h" +#include "northbound_cli.h" #include "ripd/ripd.h" #include "ripd/rip_debug.h" @@ -1322,7 +1323,7 @@ static void rip_response_process(struct rip_packet *packet, int size, } /* Make socket for RIP protocol. */ -static int rip_create_socket(void) +int rip_create_socket(void) { int ret; int sock; @@ -2663,17 +2664,26 @@ void rip_redistribute_withdraw(int type) } /* Create new RIP instance and set it to global variable. */ -static int rip_create(void) +int rip_create(int socket) { rip = XCALLOC(MTYPE_RIP, sizeof(struct rip)); /* Set initial value. */ - rip->version_send = RI_RIP_VERSION_2; - rip->version_recv = RI_RIP_VERSION_1_AND_2; - rip->update_time = RIP_UPDATE_TIMER_DEFAULT; - rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT; - rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT; - rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT; + rip->ecmp = yang_get_default_bool("%s/allow-ecmp", RIP_INSTANCE); + rip->default_metric = + yang_get_default_uint8("%s/default-metric", RIP_INSTANCE); + rip->distance = + yang_get_default_uint8("%s/distance/default", RIP_INSTANCE); + rip->garbage_time = yang_get_default_uint32("%s/timers/flush-interval", + RIP_INSTANCE); + rip->timeout_time = yang_get_default_uint32( + "%s/timers/holddown-interval", RIP_INSTANCE); + rip->update_time = yang_get_default_uint32("%s/timers/update-interval", + RIP_INSTANCE); + rip->version_send = + yang_get_default_enum("%s/version/send", RIP_INSTANCE); + rip->version_recv = + yang_get_default_enum("%s/version/receive", RIP_INSTANCE); /* Initialize RIP routig table. */ rip->table = route_table_init(); @@ -2683,10 +2693,8 @@ static int rip_create(void) /* Make output stream. */ rip->obuf = stream_new(1500); - /* Make socket. */ - rip->sock = rip_create_socket(); - if (rip->sock < 0) - return rip->sock; + /* Set socket. */ + rip->sock = socket; /* Create read and timer thread. */ rip_event(RIP_READ, rip->sock); @@ -2791,40 +2799,6 @@ void rip_event(enum rip_event event, int sock) } } -DEFUN_NOSH (router_rip, - router_rip_cmd, - "router rip", - "Enable a routing process\n" - "Routing Information Protocol (RIP)\n") -{ - int ret; - - /* If rip is not enabled before. */ - if (!rip) { - ret = rip_create(); - if (ret < 0) { - zlog_info("Can't create RIP"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - VTY_PUSH_CONTEXT(RIP_NODE, rip); - - return CMD_SUCCESS; -} - -DEFUN (no_router_rip, - no_router_rip_cmd, - "no router rip", - NO_STR - "Enable a routing process\n" - "Routing Information Protocol (RIP)\n") -{ - if (rip) - rip_clean(); - return CMD_SUCCESS; -} - DEFUN (rip_version, rip_version_cmd, "version (1-2)", @@ -3641,12 +3615,15 @@ static int config_write_rip(struct vty *vty) int write = 0; struct route_node *rn; struct rip_distance *rdistance; + struct lyd_node *dnode; - if (rip) { - /* Router RIP statement. */ - vty_out(vty, "router rip\n"); + dnode = yang_dnode_get(running_config->dnode, + "/frr-ripd:ripd/instance"); + if (dnode) { write++; + nb_cli_show_dnode_cmds(vty, dnode, false); + /* RIP version statement. Default is RIP version 2. */ if (rip->version_send != RI_RIP_VERSION_2 || rip->version_recv != RI_RIP_VERSION_1_AND_2) @@ -3989,8 +3966,6 @@ void rip_init(void) /* Install rip commands. */ install_element(VIEW_NODE, &show_ip_rip_cmd); install_element(VIEW_NODE, &show_ip_rip_status_cmd); - install_element(CONFIG_NODE, &router_rip_cmd); - install_element(CONFIG_NODE, &no_router_rip_cmd); install_default(RIP_NODE); install_element(RIP_NODE, &rip_version_cmd); diff --git a/ripd/ripd.h b/ripd/ripd.h index 78a204eb70..8e34939f2e 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -383,11 +383,14 @@ extern void rip_zclient_stop(void); extern void rip_zclient_reset(void); extern void rip_offset_init(void); extern int if_check_address(struct in_addr addr); +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_create_socket(void); + extern int rip_redistribute_check(int); extern void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p, struct nexthop *nh, unsigned int metric, -- 2.39.5