From e9ce224b8543c0e432c4eb29240ffc1300bbdf6e Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 28 Nov 2018 23:51:34 -0200 Subject: [PATCH] yang, ripngd: add 'frr-ripngd.yang' and associated stub callbacks 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 --- lib/yang.c | 1 + ripngd/ripng_cli.c | 39 ++ ripngd/ripng_cli.h | 24 ++ ripngd/ripng_main.c | 2 + ripngd/ripng_northbound.c | 621 +++++++++++++++++++++++++++++++ ripngd/ripngd.h | 8 + ripngd/subdir.am | 10 + yang/confd/confd.frr-ripngd.yang | 22 ++ yang/frr-ripngd.yang | 321 ++++++++++++++++ yang/subdir.am | 4 + 10 files changed, 1052 insertions(+) create mode 100644 ripngd/ripng_cli.c create mode 100644 ripngd/ripng_cli.h create mode 100644 ripngd/ripng_northbound.c create mode 100644 yang/confd/confd.frr-ripngd.yang create mode 100644 yang/frr-ripngd.yang diff --git a/lib/yang.c b/lib/yang.c index 462e693549..780b986103 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -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 index 0000000000..b033a39ac6 --- /dev/null +++ b/ripngd/ripng_cli.c @@ -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 + +#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 index 0000000000..a3f29b9859 --- /dev/null +++ b/ripngd/ripng_cli.h @@ -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_ */ diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c index 98df7ef12d..11d1266706 100644 --- a/ripngd/ripng_main.c +++ b/ripngd/ripng_main.c @@ -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 index 0000000000..84e4bf43e7 --- /dev/null +++ b/ripngd/ripng_northbound.c @@ -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 + +#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, + }, + } +}; diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h index 1095a33494..7d4f822da4 100644 --- a/ripngd/ripngd.h +++ b/ripngd/ripngd.h @@ -89,6 +89,10 @@ #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 */ diff --git a/ripngd/subdir.am b/ripngd/subdir.am index 8f834a1d29..25d72e5c5f 100644 --- a/ripngd/subdir.am +++ b/ripngd/subdir.am @@ -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 index 0000000000..5d876ff4d3 --- /dev/null +++ b/yang/confd/confd.frr-ripngd.yang @@ -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 index 0000000000..0cc5f18a5f --- /dev/null +++ b/yang/frr-ripngd.yang @@ -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: + FRR Development List: "; + 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."; + } +} diff --git a/yang/subdir.am b/yang/subdir.am index 07bd225780..6484e1181f 100644 --- a/yang/subdir.am +++ b/yang/subdir.am @@ -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 -- 2.39.5