]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ripd: retrofit the 'router rip' command to the new northbound model
authorRenato Westphal <renato@opensourcerouting.org>
Wed, 9 May 2018 04:34:58 +0000 (01:34 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Sat, 27 Oct 2018 18:16:12 +0000 (16:16 -0200)
* 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 <renato@opensourcerouting.org>
ripd/rip_cli.c
ripd/rip_cli.h
ripd/rip_northbound.c
ripd/ripd.c
ripd/ripd.h

index 0923af57986997da1814b763eb27293a95d94c73..684fbd300aa6ad1d46ec8093f46a47b63182b994 100644 (file)
 #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);
 }
index 2af54e359739b25b60bbda2fdf0c91a5f6491733..b8997e8805127bf7e840185b70eec35d38bc2a45 100644 (file)
@@ -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_ */
index c2a73bfa89c09b1e293c4556caa2c3f3c72ee00a..e780bc5e116e6623a105f268e37fac5b5f8492be 100644 (file)
@@ -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",
index dd0d17ee47c0cf8dd94769ef592c7990dcf24526..9cb1ae8cfbc7cf749e2f980bc1e2841c5940d06f 100644 (file)
@@ -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);
index 78a204eb702036a0f81bc28e7312afa2482658f2..8e34939f2e5055b5e344ac6ce10f3575f921787b 100644 (file)
@@ -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,