]> git.puffer.fish Git - matthieu/frr.git/commitdiff
yang, ripngd: add 'frr-ripngd.yang' and associated stub callbacks
authorRenato Westphal <renato@opensourcerouting.org>
Thu, 29 Nov 2018 01:51:34 +0000 (23:51 -0200)
committerRenato Westphal <renato@opensourcerouting.org>
Mon, 3 Dec 2018 15:47:58 +0000 (13:47 -0200)
Introduce frr-ripngd.yang, which defines a model for managing the
FRR ripngd daemon.

Update the 'frr_yang_module_info' array of ripngd with the new
'frr-ripngd' module.

Add two new files (ripng_cli.[ch]) which should contain all ripngd
commands converted to the new northbound model. Centralizing all
commands in a single place will facilitate the process of moving
the CLI to a separate program in the future.

Add automatically generated stub callbacks in
ripng_northbound.c. These callbacks will be implemented gradually
in the following commits.

Add the confd.frr-ripngd.yang YANG module with annotations specific
to the ConfD daemon.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
lib/yang.c
ripngd/ripng_cli.c [new file with mode: 0644]
ripngd/ripng_cli.h [new file with mode: 0644]
ripngd/ripng_main.c
ripngd/ripng_northbound.c [new file with mode: 0644]
ripngd/ripngd.h
ripngd/subdir.am
yang/confd/confd.frr-ripngd.yang [new file with mode: 0644]
yang/frr-ripngd.yang [new file with mode: 0644]
yang/subdir.am

index 462e693549ea832b17db3d579a62840aa7558040..780b986103023db819796d3af5475c4c94464d9e 100644 (file)
@@ -74,6 +74,7 @@ static const char *yang_module_imp_clb(const char *mod_name,
 static const char * const frr_native_modules[] = {
        "frr-interface",
        "frr-ripd",
+       "frr-ripngd",
 };
 
 /* Generate the yang_modules tree. */
diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c
new file mode 100644 (file)
index 0000000..b033a39
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ * Copyright (C) 2018 NetDEF, Inc.
+ *                    Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "if.h"
+#include "vrf.h"
+#include "log.h"
+#include "prefix.h"
+#include "command.h"
+#include "northbound_cli.h"
+#include "libfrr.h"
+
+#include "ripngd/ripngd.h"
+#include "ripngd/ripng_cli.h"
+#ifndef VTYSH_EXTRACT_PL
+#include "ripngd/ripng_cli_clippy.c"
+#endif
+
+void ripng_cli_init(void)
+{
+}
diff --git a/ripngd/ripng_cli.h b/ripngd/ripng_cli.h
new file mode 100644 (file)
index 0000000..a3f29b9
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ * Copyright (C) 2018 NetDEF, Inc.
+ *                    Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _FRR_RIPNG_CLI_H_
+#define _FRR_RIPNG_CLI_H_
+
+#endif /* _FRR_RIPNG_CLI_H_ */
index 98df7ef12d89111708b456b7a8fa8d2905d55e3c..11d12667068103b0e9c441dec93e367096251177 100644 (file)
@@ -120,6 +120,7 @@ struct quagga_signal_t ripng_signals[] = {
 
 static const struct frr_yang_module_info *ripngd_yang_modules[] = {
        &frr_interface_info,
+       &frr_ripngd_info,
 };
 
 FRR_DAEMON_INFO(ripngd, RIPNG, .vty_port = RIPNG_VTY_PORT,
@@ -177,6 +178,7 @@ int main(int argc, char **argv)
 
        /* RIPngd inits. */
        ripng_init();
+       ripng_cli_init();
        zebra_init(master);
        ripng_peer_init();
 
diff --git a/ripngd/ripng_northbound.c b/ripngd/ripng_northbound.c
new file mode 100644 (file)
index 0000000..84e4bf4
--- /dev/null
@@ -0,0 +1,621 @@
+/*
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ * Copyright (C) 2018 NetDEF, Inc.
+ *                    Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "if.h"
+#include "vrf.h"
+#include "log.h"
+#include "prefix.h"
+#include "table.h"
+#include "command.h"
+#include "routemap.h"
+#include "northbound.h"
+#include "libfrr.h"
+
+#include "ripngd/ripngd.h"
+#include "ripngd/ripng_cli.h"
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance
+ */
+static int ripngd_instance_create(enum nb_event event,
+                                 const struct lyd_node *dnode,
+                                 union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static int ripngd_instance_delete(enum nb_event event,
+                                 const struct lyd_node *dnode)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/allow-ecmp
+ */
+static int ripngd_instance_allow_ecmp_modify(enum nb_event event,
+                                            const struct lyd_node *dnode,
+                                            union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/default-information-originate
+ */
+static int ripngd_instance_default_information_originate_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/default-metric
+ */
+static int ripngd_instance_default_metric_modify(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/network
+ */
+static int ripngd_instance_network_create(enum nb_event event,
+                                         const struct lyd_node *dnode,
+                                         union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static int ripngd_instance_network_delete(enum nb_event event,
+                                         const struct lyd_node *dnode)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/interface
+ */
+static int ripngd_instance_interface_create(enum nb_event event,
+                                           const struct lyd_node *dnode,
+                                           union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static int ripngd_instance_interface_delete(enum nb_event event,
+                                           const struct lyd_node *dnode)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/offset-list
+ */
+static int ripngd_instance_offset_list_create(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static int ripngd_instance_offset_list_delete(enum nb_event event,
+                                             const struct lyd_node *dnode)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/offset-list/access-list
+ */
+static int
+ripngd_instance_offset_list_access_list_modify(enum nb_event event,
+                                              const struct lyd_node *dnode,
+                                              union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/offset-list/metric
+ */
+static int
+ripngd_instance_offset_list_metric_modify(enum nb_event event,
+                                         const struct lyd_node *dnode,
+                                         union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/passive-interface
+ */
+static int
+ripngd_instance_passive_interface_create(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static int
+ripngd_instance_passive_interface_delete(enum nb_event event,
+                                        const struct lyd_node *dnode)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/redistribute
+ */
+static int ripngd_instance_redistribute_create(enum nb_event event,
+                                              const struct lyd_node *dnode,
+                                              union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static int ripngd_instance_redistribute_delete(enum nb_event event,
+                                              const struct lyd_node *dnode)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map
+ */
+static int
+ripngd_instance_redistribute_route_map_modify(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static int
+ripngd_instance_redistribute_route_map_delete(enum nb_event event,
+                                             const struct lyd_node *dnode)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/redistribute/metric
+ */
+static int
+ripngd_instance_redistribute_metric_modify(enum nb_event event,
+                                          const struct lyd_node *dnode,
+                                          union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static int
+ripngd_instance_redistribute_metric_delete(enum nb_event event,
+                                          const struct lyd_node *dnode)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/static-route
+ */
+static int ripngd_instance_static_route_create(enum nb_event event,
+                                              const struct lyd_node *dnode,
+                                              union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static int ripngd_instance_static_route_delete(enum nb_event event,
+                                              const struct lyd_node *dnode)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/aggregate-address
+ */
+static int
+ripngd_instance_aggregate_address_create(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static int
+ripngd_instance_aggregate_address_delete(enum nb_event event,
+                                        const struct lyd_node *dnode)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval
+ */
+static int
+ripngd_instance_timers_flush_interval_modify(enum nb_event event,
+                                            const struct lyd_node *dnode,
+                                            union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/timers/holddown-interval
+ */
+static int
+ripngd_instance_timers_holddown_interval_modify(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/timers/update-interval
+ */
+static int
+ripngd_instance_timers_update_interval_modify(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor
+ */
+static const void *
+ripngd_state_neighbors_neighbor_get_next(const void *parent_list_entry,
+                                        const void *list_entry)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+static int ripngd_state_neighbors_neighbor_get_keys(const void *list_entry,
+                                                   struct yang_list_keys *keys)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static const void *
+ripngd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry,
+                                            const struct yang_list_keys *keys)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/address
+ */
+static struct yang_data *
+ripngd_state_neighbors_neighbor_address_get_elem(const char *xpath,
+                                                const void *list_entry)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/last-update
+ */
+static struct yang_data *
+ripngd_state_neighbors_neighbor_last_update_get_elem(const char *xpath,
+                                                    const void *list_entry)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/bad-packets-rcvd
+ */
+static struct yang_data *
+ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
+       const char *xpath, const void *list_entry)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/bad-routes-rcvd
+ */
+static struct yang_data *
+ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath,
+                                                        const void *list_entry)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/routes/route
+ */
+static const void *
+ripngd_state_routes_route_get_next(const void *parent_list_entry,
+                                  const void *list_entry)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+static int ripngd_state_routes_route_get_keys(const void *list_entry,
+                                             struct yang_list_keys *keys)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+static const void *
+ripngd_state_routes_route_lookup_entry(const void *parent_list_entry,
+                                      const struct yang_list_keys *keys)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/routes/route/prefix
+ */
+static struct yang_data *
+ripngd_state_routes_route_prefix_get_elem(const char *xpath,
+                                         const void *list_entry)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/routes/route/next-hop
+ */
+static struct yang_data *
+ripngd_state_routes_route_next_hop_get_elem(const char *xpath,
+                                           const void *list_entry)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/routes/route/interface
+ */
+static struct yang_data *
+ripngd_state_routes_route_interface_get_elem(const char *xpath,
+                                            const void *list_entry)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/routes/route/metric
+ */
+static struct yang_data *
+ripngd_state_routes_route_metric_get_elem(const char *xpath,
+                                         const void *list_entry)
+{
+       /* TODO: implement me. */
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:clear-ripng-route
+ */
+static int clear_ripng_route_rpc(const char *xpath, const struct list *input,
+                                struct list *output)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
+ */
+static int
+lib_interface_ripng_split_horizon_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       /* TODO: implement me. */
+       return NB_OK;
+}
+
+/* clang-format off */
+const struct frr_yang_module_info frr_ripngd_info = {
+       .name = "frr-ripngd",
+       .nodes = {
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance",
+                       .cbs.create = ripngd_instance_create,
+                       .cbs.delete = ripngd_instance_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/allow-ecmp",
+                       .cbs.modify = ripngd_instance_allow_ecmp_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/default-information-originate",
+                       .cbs.modify = ripngd_instance_default_information_originate_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/default-metric",
+                       .cbs.modify = ripngd_instance_default_metric_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/network",
+                       .cbs.create = ripngd_instance_network_create,
+                       .cbs.delete = ripngd_instance_network_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/interface",
+                       .cbs.create = ripngd_instance_interface_create,
+                       .cbs.delete = ripngd_instance_interface_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/offset-list",
+                       .cbs.create = ripngd_instance_offset_list_create,
+                       .cbs.delete = ripngd_instance_offset_list_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/offset-list/access-list",
+                       .cbs.modify = ripngd_instance_offset_list_access_list_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/offset-list/metric",
+                       .cbs.modify = ripngd_instance_offset_list_metric_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/passive-interface",
+                       .cbs.create = ripngd_instance_passive_interface_create,
+                       .cbs.delete = ripngd_instance_passive_interface_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/redistribute",
+                       .cbs.create = ripngd_instance_redistribute_create,
+                       .cbs.delete = ripngd_instance_redistribute_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/redistribute/route-map",
+                       .cbs.modify = ripngd_instance_redistribute_route_map_modify,
+                       .cbs.delete = ripngd_instance_redistribute_route_map_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/redistribute/metric",
+                       .cbs.modify = ripngd_instance_redistribute_metric_modify,
+                       .cbs.delete = ripngd_instance_redistribute_metric_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/static-route",
+                       .cbs.create = ripngd_instance_static_route_create,
+                       .cbs.delete = ripngd_instance_static_route_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/aggregate-address",
+                       .cbs.create = ripngd_instance_aggregate_address_create,
+                       .cbs.delete = ripngd_instance_aggregate_address_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/timers/flush-interval",
+                       .cbs.modify = ripngd_instance_timers_flush_interval_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/timers/holddown-interval",
+                       .cbs.modify = ripngd_instance_timers_holddown_interval_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/timers/update-interval",
+                       .cbs.modify = ripngd_instance_timers_update_interval_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor",
+                       .cbs.get_next = ripngd_state_neighbors_neighbor_get_next,
+                       .cbs.get_keys = ripngd_state_neighbors_neighbor_get_keys,
+                       .cbs.lookup_entry = ripngd_state_neighbors_neighbor_lookup_entry,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/address",
+                       .cbs.get_elem = ripngd_state_neighbors_neighbor_address_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/last-update",
+                       .cbs.get_elem = ripngd_state_neighbors_neighbor_last_update_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/bad-packets-rcvd",
+                       .cbs.get_elem = ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/bad-routes-rcvd",
+                       .cbs.get_elem = ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/routes/route",
+                       .cbs.get_next = ripngd_state_routes_route_get_next,
+                       .cbs.get_keys = ripngd_state_routes_route_get_keys,
+                       .cbs.lookup_entry = ripngd_state_routes_route_lookup_entry,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/routes/route/prefix",
+                       .cbs.get_elem = ripngd_state_routes_route_prefix_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/routes/route/next-hop",
+                       .cbs.get_elem = ripngd_state_routes_route_next_hop_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/routes/route/interface",
+                       .cbs.get_elem = ripngd_state_routes_route_interface_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/routes/route/metric",
+                       .cbs.get_elem = ripngd_state_routes_route_metric_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:clear-ripng-route",
+                       .cbs.rpc = clear_ripng_route_rpc,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-ripngd:ripng/split-horizon",
+                       .cbs.modify = lib_interface_ripng_split_horizon_modify,
+               },
+               {
+                       .xpath = NULL,
+               },
+       }
+};
index 1095a33494e71d49946be5581df0f11fa37f8480..7d4f822da4a9a818f11a04e843a9af449012a376 100644 (file)
 #define IFMINMTU    576
 #endif /* IFMINMTU */
 
+/* YANG paths */
+#define RIPNG_INSTANCE "/frr-ripngd:ripngd/instance"
+#define RIPNG_IFACE    "/frr-interface:lib/interface/frr-ripngd:ripng"
+
 /* RIPng structure. */
 struct ripng {
        /* RIPng socket. */
@@ -412,4 +416,8 @@ extern struct ripng_info *ripng_ecmp_add(struct ripng_info *);
 extern struct ripng_info *ripng_ecmp_replace(struct ripng_info *);
 extern struct ripng_info *ripng_ecmp_delete(struct ripng_info *);
 
+/* Northbound. */
+extern void ripng_cli_init(void);
+extern const struct frr_yang_module_info frr_ripngd_info;
+
 #endif /* _ZEBRA_RIPNG_RIPNGD_H */
index 8f834a1d297d5200fd4b711a90b7264d6fbf5bc2..25d72e5c5fc09a404aa81dc900a3432640e91857 100644 (file)
@@ -6,6 +6,7 @@ if RIPNGD
 noinst_LIBRARIES += ripngd/libripng.a
 sbin_PROGRAMS += ripngd/ripngd
 vtysh_scan += \
+       $(top_srcdir)/ripngd/ripng_cli.c \
        $(top_srcdir)/ripngd/ripng_debug.c \
        $(top_srcdir)/ripngd/ripng_interface.c \
        $(top_srcdir)/ripngd/ripng_offset.c \
@@ -16,11 +17,13 @@ man8 += $(MANBUILD)/ripngd.8
 endif
 
 ripngd_libripng_a_SOURCES = \
+       ripngd/ripng_cli.c \
        ripngd/ripng_debug.c \
        ripngd/ripng_interface.c \
        ripngd/ripng_memory.c \
        ripngd/ripng_nexthop.c \
        ripngd/ripng_offset.c \
+       ripngd/ripng_northbound.c \
        ripngd/ripng_peer.c \
        ripngd/ripng_route.c \
        ripngd/ripng_routemap.c \
@@ -28,7 +31,11 @@ ripngd_libripng_a_SOURCES = \
        ripngd/ripngd.c \
        # end
 
+ripngd/ripng_cli_clippy.c: $(CLIPPY_DEPS)
+ripngd/ripng_cli.$(OBJEXT): ripngd/ripng_cli_clippy.c
+
 noinst_HEADERS += \
+       ripngd/ripng_cli.h \
        ripngd/ripng_debug.h \
        ripngd/ripng_memory.h \
        ripngd/ripng_nexthop.h \
@@ -40,5 +47,8 @@ ripngd_ripngd_LDADD = ripngd/libripng.a lib/libfrr.la @LIBCAP@
 ripngd_ripngd_SOURCES = \
        ripngd/ripng_main.c \
        # end
+nodist_ripngd_ripngd_SOURCES = \
+       yang/frr-ripngd.yang.c \
+       # end
 
 dist_examples_DATA += ripngd/ripngd.conf.sample
diff --git a/yang/confd/confd.frr-ripngd.yang b/yang/confd/confd.frr-ripngd.yang
new file mode 100644 (file)
index 0000000..5d876ff
--- /dev/null
@@ -0,0 +1,22 @@
+module confd.frr-ripngd {
+  namespace "urn:dummy";
+  prefix "dummy";
+
+  import tailf-common {
+    prefix tailf;
+  }
+  import frr-ripngd {
+    prefix frr-ripngd;
+  }
+
+  tailf:annotate-module "frr-ripngd" {
+    tailf:annotate-statement "container[name='ripngd']" {
+      tailf:annotate-statement "container[name='state']" {
+        tailf:callpoint "state";
+      }
+    }
+    tailf:annotate-statement "rpc[name='clear-ripng-route']" {
+      tailf:actionpoint "actionpoint";
+    }
+  }
+}
diff --git a/yang/frr-ripngd.yang b/yang/frr-ripngd.yang
new file mode 100644 (file)
index 0000000..0cc5f18
--- /dev/null
@@ -0,0 +1,321 @@
+module frr-ripngd {
+  yang-version 1.1;
+  namespace "http://frrouting.org/yang/ripngd";
+  prefix frr-ripngd;
+
+  import ietf-inet-types {
+    prefix inet;
+  }
+  import ietf-yang-types {
+    prefix yang;
+  }
+  import frr-interface {
+    prefix frr-interface;
+  }
+  import frr-route-types {
+    prefix frr-route-types;
+  }
+
+  organization
+    "Free Range Routing";
+  contact
+    "FRR Users List:       <mailto:frog@lists.frrouting.org>
+     FRR Development List: <mailto:dev@lists.frrouting.org>";
+  description
+    "This module defines a model for managing FRR ripngd daemon.";
+
+  revision 2018-11-27 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 2080: RIPng for IPv6.";
+  }
+
+  container ripngd {
+    /*
+     * Global configuration data
+     */
+    container instance {
+      presence "Present if the RIPng protocol is enabled.";
+      description
+        "RIPng routing instance.";
+
+      leaf allow-ecmp {
+        type boolean;
+        default "false";
+        description
+          "Allow equal-cost multi-path.";
+      }
+      leaf default-information-originate {
+        type boolean;
+        default "false";
+        description
+          "Control distribution of default route.";
+      }
+      leaf default-metric {
+        type uint8 {
+          range "1..16";
+        }
+        default "1";
+        description
+          "Default metric of redistributed routes.";
+      }
+      leaf-list network {
+        type inet:ipv6-prefix;
+        description
+          "Enable RIPng on the specified IPv6 network.";
+      }
+      leaf-list interface {
+        type string {
+          length "1..16";
+        }
+        description
+          "Enable RIPng on the specified interface.";
+      }
+      list offset-list {
+        key "interface direction";
+        description
+          "Offset-list to modify route metric.";
+        leaf interface {
+          type string;
+          description
+            "Interface to match. Use '*' to match all interfaces.";
+        }
+        leaf direction {
+          type enumeration {
+            enum in {
+              value 0;
+              description
+                "Incoming updates.";
+            }
+            enum out {
+              value 1;
+              description
+                "Outgoing updates.";
+            }
+          }
+          description
+            "Incoming or outgoing updates.";
+        }
+        leaf access-list {
+          type string;
+          mandatory true;
+          description
+            "Access-list name.";
+        }
+        leaf metric {
+          type uint8 {
+            range "0..16";
+          }
+          mandatory true;
+          description
+            "Route metric.";
+        }
+      }
+      leaf-list passive-interface {
+        type string {
+          length "1..16";
+        }
+        description
+          "A list of interfaces where the sending of RIPng packets
+           is disabled.";
+      }
+      list redistribute {
+        key "protocol";
+        description
+          "Redistributes routes learned from other routing protocols.";
+        leaf protocol {
+          type frr-route-types:frr-route-types-v6;
+          description
+            "Routing protocol.";
+          must '. != "ripng"';
+        }
+        leaf route-map {
+          type string {
+            length "1..max";
+          }
+          description
+            "Applies the conditions of the specified route-map to
+             routes that are redistributed into the RIPng routing
+             instance.";
+        }
+        leaf metric {
+          type uint8 {
+            range "0..16";
+          }
+          description
+            "Metric used for the redistributed route. If a metric is
+             not specified, the metric configured with the
+             default-metric attribute in RIPng router configuration is
+             used. If the default-metric attribute has not been
+             configured, the default metric for redistributed routes
+             is 0.";
+        }
+      }
+      leaf-list static-route {
+        type inet:ipv6-prefix;
+        description
+          "RIPng static routes.";
+      }
+      leaf-list aggregate-address {
+        type inet:ipv6-prefix;
+        description
+          "RIPng aggregate route announcement.";
+      }
+      container timers {
+        description
+          "Settings of basic timers";
+        leaf flush-interval {
+          type uint16 {
+            range "1..65535";
+          }
+          units "seconds";
+          default "120";
+          description
+            "Interval before a route is flushed from the routing
+             table.";
+        }
+        leaf holddown-interval {
+          type uint16 {
+            range "1..65535";
+          }
+          units "seconds";
+          default "180";
+          description
+            "Interval before better routes are released.";
+        }
+        leaf update-interval {
+          type uint16 {
+            range "1..65535";
+          }
+          units "seconds";
+          default "30";
+          description
+            "Interval at which RIPng updates are sent.";
+        }
+      }
+    }
+
+    /*
+     * Operational data.
+     */
+    container state {
+      config false;
+      description
+        "Operational data.";
+
+      container neighbors {
+        description
+          "Neighbor information.";
+        list neighbor {
+          key "address";
+          description
+            "A RIPng neighbor.";
+          leaf address {
+            type inet:ipv6-address;
+            description
+              "IPv6 address that a RIPng neighbor is using as its
+               source address.";
+          }
+          leaf last-update {
+            type yang:date-and-time;
+            description
+              "The time when the most recent RIPng update was
+               received from this neighbor.";
+          }
+          leaf bad-packets-rcvd {
+            type yang:counter32;
+            description
+              "The number of RIPng invalid packets received from
+               this neighbor which were subsequently discarded
+               for any reason (e.g. a version 0 packet, or an
+               unknown command type).";
+          }
+          leaf bad-routes-rcvd {
+            type yang:counter32;
+            description
+              "The number of routes received from this neighbor,
+               in valid RIPng packets, which were ignored for any
+               reason (e.g. unknown address family, or invalid
+               metric).";
+          }
+        }
+      }
+      container routes {
+        description
+          "Route information.";
+        list route {
+          key "prefix";
+          description
+            "A RIPng IPv6 route.";
+          leaf prefix {
+            type inet:ipv6-prefix;
+            description
+              "IPv6 address and prefix length, in the format
+               specified in RFC6991.";
+          }
+          leaf next-hop {
+            type inet:ipv6-address;
+            description
+              "Next hop IPv6 address.";
+          }
+          leaf interface {
+            type string;
+            description
+              "The interface that the route uses.";
+          }
+          leaf metric {
+            type uint8 {
+              range "0..16";
+            }
+            description
+              "Route metric.";
+          }
+        }
+      }
+    }
+  }
+
+  /*
+   * Per-interface configuration data
+   */
+  augment "/frr-interface:lib/frr-interface:interface" {
+    container ripng {
+      description
+        "RIPng interface parameters.";
+      leaf split-horizon {
+        type enumeration {
+          enum "disabled" {
+            value 0;
+            description
+              "Disables split-horizon processing.";
+          }
+          enum "simple" {
+            value 1;
+            description
+              "Enables simple split-horizon processing.";
+          }
+          enum "poison-reverse" {
+            value 2;
+            description
+              "Enables split-horizon processing with poison
+               reverse.";
+          }
+        }
+        default "simple";
+        description
+          "Controls RIPng split-horizon processing on the specified
+           interface.";
+      }
+    }
+  }
+
+  /*
+   * RPCs
+   */
+  rpc clear-ripng-route {
+    description
+      "Clears RIPng routes from the IPv6 routing table and routes
+       redistributed into the RIPng protocol.";
+  }
+}
index 07bd225780526ed459211442d4203a73f3f0a287..6484e1181f04cb9c42ef8b869c6772b5f205b43a 100644 (file)
@@ -27,3 +27,7 @@ dist_yangmodels_DATA += yang/frr-route-types.yang
 if RIPD
 dist_yangmodels_DATA += yang/frr-ripd.yang
 endif
+
+if RIPNGD
+dist_yangmodels_DATA += yang/frr-ripngd.yang
+endif