]> git.proxmox.com Git - mirror_frr.git/commitdiff
eigrpd: migrate old CLI to northbound
authorRafael Zalamena <rzalamena@opensourcerouting.org>
Tue, 30 Jul 2019 15:44:13 +0000 (12:44 -0300)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Sat, 3 Aug 2019 17:52:45 +0000 (14:52 -0300)
Move all configuration commands to the new CLI code (`eigrp_cli.c`),
implement the northbound and do all the necessary wiring to get it
working.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
eigrpd/eigrp_cli.c [new file with mode: 0644]
eigrpd/eigrp_main.c
eigrpd/eigrp_northbound.c [new file with mode: 0644]
eigrpd/eigrp_vty.c
eigrpd/eigrp_vty.h
eigrpd/eigrpd.h
eigrpd/subdir.am
yang/subdir.am

diff --git a/eigrpd/eigrp_cli.c b/eigrpd/eigrp_cli.c
new file mode 100644 (file)
index 0000000..ba657a7
--- /dev/null
@@ -0,0 +1,920 @@
+/*
+ * EIGRP daemon CLI implementation.
+ *
+ * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
+ *                    Rafael Zalamena
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+#include <zebra.h>
+
+#include "lib/command.h"
+#include "lib/log.h"
+#include "lib/northbound_cli.h"
+
+#include "eigrp_structs.h"
+#include "eigrpd.h"
+#include "eigrp_zebra.h"
+
+#ifndef VTYSH_EXTRACT_PL
+#include "eigrpd/eigrp_cli_clippy.c"
+#endif /* VTYSH_EXTRACT_PL */
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance
+ */
+DEFPY_NOSH(
+       router_eigrp,
+       router_eigrp_cmd,
+       "router eigrp (1-65535)$as",
+       ROUTER_STR
+       EIGRP_STR
+       AS_STR)
+{
+       char xpath[XPATH_MAXLEN];
+       int rv;
+
+       snprintf(xpath, sizeof(xpath),
+                "/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='']",
+                as_str);
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       rv = nb_cli_apply_changes(vty, NULL);
+       if (rv == CMD_SUCCESS)
+               VTY_PUSH_XPATH(EIGRP_NODE, xpath);
+
+       return rv;
+}
+
+DEFPY_NOSH(
+       no_router_eigrp,
+       no_router_eigrp_cmd,
+       "no router eigrp (1-65535)$as",
+       NO_STR
+       ROUTER_STR
+       EIGRP_STR
+       AS_STR)
+{
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath),
+                "/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='']",
+                as_str);
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_header(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults)
+{
+       const char *asn = yang_dnode_get_string(dnode, "./asn");
+
+       vty_out(vty, "router eigrp %s\n", asn);
+}
+
+void eigrp_cli_show_end_header(struct vty *vty, struct lyd_node *dnode)
+{
+       vty_out(vty, "!\n");
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/router-id
+ */
+DEFPY(
+       eigrp_router_id,
+       eigrp_router_id_cmd,
+       "eigrp router-id A.B.C.D$addr",
+       EIGRP_STR
+       "Router ID for this EIGRP process\n"
+       "EIGRP Router-ID in IP address format\n")
+{
+       nb_cli_enqueue_change(vty, "./router-id", NB_OP_MODIFY, addr_str);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_router_id,
+       no_eigrp_router_id_cmd,
+       "no eigrp router-id [A.B.C.D]",
+       NO_STR
+       EIGRP_STR
+       "Router ID for this EIGRP process\n"
+       "EIGRP Router-ID in IP address format\n")
+{
+       nb_cli_enqueue_change(vty, "./router-id", NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_router_id(struct vty *vty, struct lyd_node *dnode,
+                             bool show_defaults)
+{
+       const char *router_id = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " eigrp router-id %s\n", router_id);
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/passive-interface
+ */
+DEFPY(
+       eigrp_passive_interface,
+       eigrp_passive_interface_cmd,
+       "[no] passive-interface IFNAME",
+       NO_STR
+       "Suppress routing updates on an interface\n"
+       "Interface to suppress on\n")
+{
+       if (no)
+               nb_cli_enqueue_change(vty, "./passive-interface",
+                                     NB_OP_DESTROY, ifname);
+       else
+               nb_cli_enqueue_change(vty, "./passive-interface",
+                                     NB_OP_CREATE, ifname);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_passive_interface(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults)
+{
+       const char *ifname = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " passive-interface %s\n", ifname);
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/active-time
+ */
+DEFPY(
+       eigrp_timers_active,
+       eigrp_timers_active_cmd,
+       "timers active-time <(1-65535)$timer|disabled$disabled>",
+       "Adjust routing timers\n"
+       "Time limit for active state\n"
+       "Active state time limit in seconds\n"
+       "Disable time limit for active state\n")
+{
+       if (disabled)
+               nb_cli_enqueue_change(vty, "./active-time", NB_OP_MODIFY, "0");
+       else
+               nb_cli_enqueue_change(vty, "./active-time",
+                                     NB_OP_MODIFY, timer_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_timers_active,
+       no_eigrp_timers_active_cmd,
+       "no timers active-time [<(1-65535)|disabled>]",
+       NO_STR
+       "Adjust routing timers\n"
+       "Time limit for active state\n"
+       "Active state time limit in seconds\n"
+       "Disable time limit for active state\n")
+{
+       nb_cli_enqueue_change(vty, "./active-time", NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_active_time(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults)
+{
+       const char *timer = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " timers active-time %s\n", timer);
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/variance
+ */
+DEFPY(
+       eigrp_variance,
+       eigrp_variance_cmd,
+       "variance (1-128)$variance",
+       "Control load balancing variance\n"
+       "Metric variance multiplier\n")
+{
+       nb_cli_enqueue_change(vty, "./variance", NB_OP_MODIFY, variance_str);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_variance,
+       no_eigrp_variance_cmd,
+       "no variance [(1-128)]",
+       NO_STR
+       "Control load balancing variance\n"
+       "Metric variance multiplier\n")
+{
+       nb_cli_enqueue_change(vty, "./variance", NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_variance(struct vty *vty, struct lyd_node *dnode,
+                            bool show_defaults)
+{
+       const char *variance = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " variance %s\n", variance);
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/maximum-paths
+ */
+DEFPY(
+       eigrp_maximum_paths,
+       eigrp_maximum_paths_cmd,
+       "maximum-paths (1-32)$maximum_paths",
+       "Forward packets over multiple paths\n"
+       "Number of paths\n")
+{
+       nb_cli_enqueue_change(vty, "./maximum-paths", NB_OP_MODIFY,
+                             maximum_paths_str);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_maximum_paths,
+       no_eigrp_maximum_paths_cmd,
+       "no maximum-paths [(1-32)]",
+       NO_STR
+       "Forward packets over multiple paths\n"
+       "Number of paths\n")
+{
+       nb_cli_enqueue_change(vty, "./maximum-paths", NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_maximum_paths(struct vty *vty, struct lyd_node *dnode,
+                                 bool show_defaults)
+{
+       const char *maximum_paths = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " maximum-paths %s\n", maximum_paths);
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K1
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K2
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K3
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K4
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K5
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K6
+ */
+DEFPY(
+       eigrp_metric_weights,
+       eigrp_metric_weights_cmd,
+       "metric weights (0-255)$k1 (0-255)$k2 (0-255)$k3 (0-255)$k4 (0-255)$k5 [(0-255)$k6]",
+       "Modify metrics and parameters for advertisement\n"
+       "Modify metric coefficients\n"
+       "K1\n"
+       "K2\n"
+       "K3\n"
+       "K4\n"
+       "K5\n"
+       "K6\n")
+{
+       nb_cli_enqueue_change(vty, "./metric-weights/K1", NB_OP_MODIFY, k1_str);
+       nb_cli_enqueue_change(vty, "./metric-weights/K2", NB_OP_MODIFY, k2_str);
+       nb_cli_enqueue_change(vty, "./metric-weights/K3", NB_OP_MODIFY, k3_str);
+       nb_cli_enqueue_change(vty, "./metric-weights/K4", NB_OP_MODIFY, k4_str);
+       nb_cli_enqueue_change(vty, "./metric-weights/K5", NB_OP_MODIFY, k5_str);
+       if (k6)
+               nb_cli_enqueue_change(vty, "./metric-weights/K6",
+                                     NB_OP_MODIFY, k6_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_metric_weights,
+       no_eigrp_metric_weights_cmd,
+       "no metric weights [(0-255) (0-255) (0-255) (0-255) (0-255) (0-255)]",
+       NO_STR
+       "Modify metrics and parameters for advertisement\n"
+       "Modify metric coefficients\n"
+       "K1\n"
+       "K2\n"
+       "K3\n"
+       "K4\n"
+       "K5\n"
+       "K6\n")
+{
+       nb_cli_enqueue_change(vty, "./metric-weights/K1", NB_OP_DESTROY, NULL);
+       nb_cli_enqueue_change(vty, "./metric-weights/K2", NB_OP_DESTROY, NULL);
+       nb_cli_enqueue_change(vty, "./metric-weights/K3", NB_OP_DESTROY, NULL);
+       nb_cli_enqueue_change(vty, "./metric-weights/K4", NB_OP_DESTROY, NULL);
+       nb_cli_enqueue_change(vty, "./metric-weights/K5", NB_OP_DESTROY, NULL);
+       nb_cli_enqueue_change(vty, "./metric-weights/K6", NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_metrics(struct vty *vty, struct lyd_node *dnode,
+                           bool show_defaults)
+{
+       const char *k1, *k2, *k3, *k4, *k5, *k6;
+
+       k1 = yang_dnode_exists(dnode, "./K1") ?
+               yang_dnode_get_string(dnode, "./K1") : "0";
+       k2 = yang_dnode_exists(dnode, "./K2") ?
+               yang_dnode_get_string(dnode, "./K2") : "0";
+       k3 = yang_dnode_exists(dnode, "./K3") ?
+               yang_dnode_get_string(dnode, "./K3") : "0";
+       k4 = yang_dnode_exists(dnode, "./K4") ?
+               yang_dnode_get_string(dnode, "./K4") : "0";
+       k5 = yang_dnode_exists(dnode, "./K5") ?
+               yang_dnode_get_string(dnode, "./K5") : "0";
+       k6 = yang_dnode_exists(dnode, "./K6") ?
+               yang_dnode_get_string(dnode, "./K6") : "0";
+
+       vty_out(vty, " metric weights %s %s %s %s %s",
+               k1, k2, k3, k4, k5);
+       if (k6)
+               vty_out(vty, " %s", k6);
+       vty_out(vty, "\n");
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/network
+ */
+DEFPY(
+       eigrp_network,
+       eigrp_network_cmd,
+       "[no] network A.B.C.D/M$prefix",
+       NO_STR
+       "Enable routing on an IP network\n"
+       "EIGRP network prefix\n")
+{
+       if (no)
+               nb_cli_enqueue_change(vty, "./network", NB_OP_DESTROY,
+                                     prefix_str);
+       else
+               nb_cli_enqueue_change(vty, "./network", NB_OP_CREATE,
+                                     prefix_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_network(struct vty *vty, struct lyd_node *dnode,
+                           bool show_defaults)
+{
+       const char *prefix = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " network %s\n", prefix);
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/neighbor
+ */
+DEFPY(
+       eigrp_neighbor,
+       eigrp_neighbor_cmd,
+       "[no] neighbor A.B.C.D$addr",
+       NO_STR
+       "Specify a neighbor router\n"
+       "Neighbor address\n")
+{
+       if (no)
+               nb_cli_enqueue_change(vty, "./neighbor", NB_OP_DESTROY,
+                                     addr_str);
+       else
+               nb_cli_enqueue_change(vty, "./neighbor", NB_OP_CREATE,
+                                     addr_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_neighbor(struct vty *vty, struct lyd_node *dnode,
+                           bool show_defaults)
+{
+       const char *prefix = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " neighbor %s\n", prefix);
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/route-map
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/bandwidth
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/delay
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/reliability
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/load
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/mtu
+ */
+DEFPY(
+       eigrp_redistribute_source_metric,
+       eigrp_redistribute_source_metric_cmd,
+       "[no] redistribute " FRR_REDIST_STR_EIGRPD
+       "$proto [metric (1-4294967295)$bw (0-4294967295)$delay (0-255)$rlbt (1-255)$load (1-65535)$mtu]",
+       NO_STR
+       REDIST_STR
+       FRR_REDIST_HELP_STR_EIGRPD
+       "Metric for redistributed routes\n"
+       "Bandwidth metric in Kbits per second\n"
+       "EIGRP delay metric, in 10 microsecond units\n"
+       "EIGRP reliability metric where 255 is 100% reliable2 ?\n"
+       "EIGRP Effective bandwidth metric (Loading) where 255 is 100% loaded\n"
+       "EIGRP MTU of the path\n")
+{
+       char xpath[XPATH_MAXLEN], xpath_metric[XPATH_MAXLEN + 64];
+
+       snprintf(xpath, sizeof(xpath), "./redistribute[protocol='%s']", proto);
+
+       if (no) {
+               nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+               return nb_cli_apply_changes(vty, NULL);
+       }
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       if (bw == 0 || delay == 0 || rlbt == 0 || load == 0 || mtu == 0)
+               return nb_cli_apply_changes(vty, NULL);
+
+       snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/bandwidth",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, bw_str);
+       snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/delay", xpath);
+       nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, delay_str);
+       snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/reliability",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, rlbt_str);
+       snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/load", xpath);
+       nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, load_str);
+       snprintf(xpath_metric, sizeof(xpath_metric), "%s/metrics/mtu", xpath);
+       nb_cli_enqueue_change(vty, xpath_metric, NB_OP_MODIFY, mtu_str);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_redistribute(struct vty *vty, struct lyd_node *dnode,
+                                bool show_defaults)
+{
+       const char *proto = yang_dnode_get_string(dnode, "./protocol");
+       const char *bw, *delay, *load, *mtu, *rlbt;
+
+       bw = yang_dnode_exists(dnode, "./metrics/bandwidth") ?
+               yang_dnode_get_string(dnode, "./metrics/bandwidth") : NULL;
+       delay = yang_dnode_exists(dnode, "./metrics/delay") ?
+               yang_dnode_get_string(dnode, "./metrics/delay") : NULL;
+       rlbt = yang_dnode_exists(dnode, "./metrics/reliability") ?
+               yang_dnode_get_string(dnode, "./metrics/reliability") : NULL;
+       load = yang_dnode_exists(dnode, "./metrics/load") ?
+               yang_dnode_get_string(dnode, "./metrics/load") : NULL;
+       mtu = yang_dnode_exists(dnode, "./metrics/mtu") ?
+               yang_dnode_get_string(dnode, "./metrics/mtu") : NULL;
+
+       vty_out(vty, " redistribute %s", proto);
+       if (bw || rlbt || delay || load || mtu)
+               vty_out(vty, " metric %s %s %s %s %s", bw, delay, rlbt, load,
+                       mtu);
+       vty_out(vty, "\n");
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/delay
+ */
+DEFPY(
+       eigrp_if_delay,
+       eigrp_if_delay_cmd,
+       "delay (1-16777215)$delay",
+       "Specify interface throughput delay\n"
+       "Throughput delay (tens of microseconds)\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/delay",
+                             NB_OP_MODIFY, delay_str);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_if_delay,
+       no_eigrp_if_delay_cmd,
+       "no delay [(1-16777215)]",
+       NO_STR
+       "Specify interface throughput delay\n"
+       "Throughput delay (tens of microseconds)\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/delay",
+                             NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_delay(struct vty *vty, struct lyd_node *dnode,
+                         bool show_defaults)
+{
+       const char *delay = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " delay %s\n", delay);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/bandwidth
+ */
+DEFPY(
+       eigrp_if_bandwidth,
+       eigrp_if_bandwidth_cmd,
+       "eigrp bandwidth (1-10000000)$bw",
+       EIGRP_STR
+       "Set bandwidth informational parameter\n"
+       "Bandwidth in kilobits\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/bandwidth",
+                             NB_OP_MODIFY, bw_str);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_if_bandwidth,
+       no_eigrp_if_bandwidth_cmd,
+       "no eigrp bandwidth [(1-10000000)]",
+       NO_STR
+       EIGRP_STR
+       "Set bandwidth informational parameter\n"
+       "Bandwidth in kilobits\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/bandwidth",
+                             NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_bandwidth(struct vty *vty, struct lyd_node *dnode,
+                             bool show_defaults)
+{
+       const char *bandwidth = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " eigrp bandwidth %s\n", bandwidth);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hello-interval
+ */
+DEFPY(
+       eigrp_if_ip_hellointerval,
+       eigrp_if_ip_hellointerval_cmd,
+       "ip hello-interval eigrp (1-65535)$hello",
+       "Interface Internet Protocol config commands\n"
+       "Configures EIGRP hello interval\n"
+       EIGRP_STR
+       "Seconds between hello transmissions\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hello-interval",
+                             NB_OP_MODIFY, hello_str);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_if_ip_hellointerval,
+       no_eigrp_if_ip_hellointerval_cmd,
+       "no ip hello-interval eigrp [(1-65535)]",
+       NO_STR
+       "Interface Internet Protocol config commands\n"
+       "Configures EIGRP hello interval\n"
+       EIGRP_STR
+       "Seconds between hello transmissions\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hello-interval",
+                             NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+
+void eigrp_cli_show_hello_interval(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       const char *hello = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " ip hello-interval eigrp %s\n", hello);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hold-time
+ */
+DEFPY(
+       eigrp_if_ip_holdinterval,
+       eigrp_if_ip_holdinterval_cmd,
+       "ip hold-time eigrp (1-65535)$hold",
+       "Interface Internet Protocol config commands\n"
+       "Configures EIGRP IPv4 hold time\n"
+       EIGRP_STR
+       "Seconds before neighbor is considered down\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hold-time",
+                             NB_OP_MODIFY, hold_str);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_if_ip_holdinterval,
+       no_eigrp_if_ip_holdinterval_cmd,
+       "no ip hold-time eigrp [(1-65535)]",
+       NO_STR
+       "Interface Internet Protocol config commands\n"
+       "Configures EIGRP IPv4 hold time\n"
+       EIGRP_STR
+       "Seconds before neighbor is considered down\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-eigrpd:eigrp/hold-time",
+                             NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_hold_time(struct vty *vty, struct lyd_node *dnode,
+                             bool show_defaults)
+{
+       const char *holdtime = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " ip hold-time eigrp %s\n", holdtime);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/split-horizon
+ */
+/* NOT implemented. */
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/summarize-addresses
+ */
+DEFPY(
+       eigrp_ip_summary_address,
+       eigrp_ip_summary_address_cmd,
+       "ip summary-address eigrp (1-65535)$as A.B.C.D/M$prefix",
+       "Interface Internet Protocol config commands\n"
+       "Perform address summarization\n"
+       EIGRP_STR
+       AS_STR
+       "Summary <network>/<length>, e.g. 192.168.0.0/16\n")
+{
+       char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64];
+
+       snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']",
+                as_str);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_auth, sizeof(xpath_auth), "%s/summarize-address", xpath);
+       nb_cli_enqueue_change(vty, xpath_auth, NB_OP_CREATE, prefix_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_ip_summary_address,
+       no_eigrp_ip_summary_address_cmd,
+       "no ip summary-address eigrp (1-65535)$as A.B.C.D/M$prefix",
+       NO_STR
+       "Interface Internet Protocol config commands\n"
+       "Perform address summarization\n"
+       EIGRP_STR
+       AS_STR
+       "Summary <network>/<length>, e.g. 192.168.0.0/16\n")
+{
+       char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64];
+
+       snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']",
+                as_str);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_auth, sizeof(xpath_auth), "%s/summarize-address", xpath);
+       nb_cli_enqueue_change(vty, xpath_auth, NB_OP_DESTROY, prefix_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_summarize_address(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults)
+{
+       const struct eigrp_interface *eif = nb_running_get_entry(dnode, NULL,
+                                                                true);
+       const char *summarize_address = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " ip summary-address eigrp %d %s\n",
+               eif->eigrp->AS, summarize_address);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication
+ */
+DEFPY(
+       eigrp_authentication_mode,
+       eigrp_authentication_mode_cmd,
+       "ip authentication mode eigrp (1-65535)$as <md5|hmac-sha-256>$crypt",
+       "Interface Internet Protocol config commands\n"
+       "Authentication subcommands\n"
+       "Mode\n"
+       EIGRP_STR
+       AS_STR
+       "Keyed message digest\n"
+       "HMAC SHA256 algorithm \n")
+{
+       char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64];
+
+       snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']",
+                as_str);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_auth, sizeof(xpath_auth), "%s/authentication", xpath);
+       nb_cli_enqueue_change(vty, xpath_auth, NB_OP_MODIFY, crypt);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_authentication_mode,
+       no_eigrp_authentication_mode_cmd,
+       "no ip authentication mode eigrp (1-65535)$as [<md5|hmac-sha-256>]",
+       NO_STR
+       "Interface Internet Protocol config commands\n"
+       "Authentication subcommands\n"
+       "Mode\n"
+       EIGRP_STR
+       AS_STR
+       "Keyed message digest\n"
+       "HMAC SHA256 algorithm \n")
+{
+       char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64];
+
+       snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']",
+                as_str);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_auth, sizeof(xpath_auth), "%s/authentication", xpath);
+       nb_cli_enqueue_change(vty, xpath_auth, NB_OP_MODIFY, "none");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_authentication(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       const struct eigrp_interface *eif = nb_running_get_entry(dnode, NULL,
+                                                                true);
+       const char *crypt = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " ip authentication mode eigrp %d %s\n",
+               eif->eigrp->AS, crypt);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/keychain
+ */
+DEFPY(
+       eigrp_authentication_keychain,
+       eigrp_authentication_keychain_cmd,
+       "ip authentication key-chain eigrp (1-65535)$as WORD$name",
+       "Interface Internet Protocol config commands\n"
+       "Authentication subcommands\n"
+       "Key-chain\n"
+       EIGRP_STR
+       AS_STR
+       "Name of key-chain\n")
+{
+       char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64];
+
+       snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']",
+                as_str);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_auth, sizeof(xpath_auth), "%s/keychain", xpath);
+       nb_cli_enqueue_change(vty, xpath_auth, NB_OP_MODIFY, name);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(
+       no_eigrp_authentication_keychain,
+       no_eigrp_authentication_keychain_cmd,
+       "no ip authentication key-chain eigrp (1-65535)$as [WORD]",
+       NO_STR
+       "Interface Internet Protocol config commands\n"
+       "Authentication subcommands\n"
+       "Key-chain\n"
+       EIGRP_STR
+       AS_STR
+       "Name of key-chain\n")
+{
+       char xpath[XPATH_MAXLEN], xpath_auth[XPATH_MAXLEN + 64];
+
+       snprintf(xpath, sizeof(xpath), "./frr-eigrpd:eigrp/instance[asn='%s']",
+                as_str);
+       snprintf(xpath_auth, sizeof(xpath_auth), "%s/keychain", xpath);
+       nb_cli_enqueue_change(vty, xpath_auth, NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void eigrp_cli_show_keychain(struct vty *vty, struct lyd_node *dnode,
+                            bool show_defaults)
+{
+       const struct eigrp_interface *eif = nb_running_get_entry(dnode, NULL,
+                                                                true);
+       const char *keychain = yang_dnode_get_string(dnode, NULL);
+
+       vty_out(vty, " ip authentication key-chain eigrp %d %s\n",
+               eif->eigrp->AS, keychain);
+}
+
+
+/*
+ * CLI installation procedures.
+ */
+static struct cmd_node eigrp_node = {EIGRP_NODE, "%s(config-router)# ", 1};
+
+static int eigrp_config_write(struct vty *vty)
+{
+       struct lyd_node *dnode;
+       int written = 0;
+
+       dnode = yang_dnode_get(running_config->dnode, "/frr-eigrpd:eigrpd");
+       if (dnode) {
+               nb_cli_show_dnode_cmds(vty, dnode, false);
+               written = 1;
+       }
+
+       return written;
+}
+
+static struct cmd_node eigrp_interface_node = {INTERFACE_NODE,
+                                              "%s(config-if)# ", 1};
+
+
+static int eigrp_write_interface(struct vty *vty)
+{
+       struct lyd_node *dnode;
+       struct interface *ifp;
+       struct vrf *vrf;
+       int written = 0;
+
+       RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
+               FOR_ALL_INTERFACES(vrf, ifp) {
+                       dnode = yang_dnode_get(
+                               running_config->dnode,
+                               "/frr-interface:lib/interface[name='%s'][vrf='%s']",
+                               ifp->name, vrf->name);
+                       if (dnode == NULL)
+                               continue;
+
+                       written = 1;
+                       nb_cli_show_dnode_cmds(vty, dnode, false);
+               }
+       }
+
+       return written;
+}
+
+void
+eigrp_cli_init(void)
+{
+       install_element(CONFIG_NODE, &router_eigrp_cmd);
+       install_element(CONFIG_NODE, &no_router_eigrp_cmd);
+
+       install_node(&eigrp_node, eigrp_config_write);
+       install_default(EIGRP_NODE);
+
+       install_element(EIGRP_NODE, &eigrp_router_id_cmd);
+       install_element(EIGRP_NODE, &no_eigrp_router_id_cmd);
+       install_element(EIGRP_NODE, &eigrp_passive_interface_cmd);
+       install_element(EIGRP_NODE, &eigrp_timers_active_cmd);
+       install_element(EIGRP_NODE, &no_eigrp_timers_active_cmd);
+       install_element(EIGRP_NODE, &eigrp_variance_cmd);
+       install_element(EIGRP_NODE, &no_eigrp_variance_cmd);
+       install_element(EIGRP_NODE, &eigrp_maximum_paths_cmd);
+       install_element(EIGRP_NODE, &no_eigrp_maximum_paths_cmd);
+       install_element(EIGRP_NODE, &eigrp_metric_weights_cmd);
+       install_element(EIGRP_NODE, &no_eigrp_metric_weights_cmd);
+       install_element(EIGRP_NODE, &eigrp_network_cmd);
+       install_element(EIGRP_NODE, &eigrp_neighbor_cmd);
+       install_element(EIGRP_NODE, &eigrp_redistribute_source_metric_cmd);
+
+       install_node(&eigrp_interface_node, eigrp_write_interface);
+       if_cmd_init();
+
+       install_element(INTERFACE_NODE, &eigrp_if_delay_cmd);
+       install_element(INTERFACE_NODE, &no_eigrp_if_delay_cmd);
+       install_element(INTERFACE_NODE, &eigrp_if_bandwidth_cmd);
+       install_element(INTERFACE_NODE, &no_eigrp_if_bandwidth_cmd);
+       install_element(INTERFACE_NODE, &eigrp_if_ip_hellointerval_cmd);
+       install_element(INTERFACE_NODE, &no_eigrp_if_ip_hellointerval_cmd);
+       install_element(INTERFACE_NODE, &eigrp_if_ip_holdinterval_cmd);
+       install_element(INTERFACE_NODE, &no_eigrp_if_ip_holdinterval_cmd);
+       install_element(INTERFACE_NODE, &eigrp_ip_summary_address_cmd);
+       install_element(INTERFACE_NODE, &no_eigrp_ip_summary_address_cmd);
+       install_element(INTERFACE_NODE, &eigrp_authentication_mode_cmd);
+       install_element(INTERFACE_NODE, &no_eigrp_authentication_mode_cmd);
+       install_element(INTERFACE_NODE, &eigrp_authentication_keychain_cmd);
+       install_element(INTERFACE_NODE, &no_eigrp_authentication_keychain_cmd);
+}
index 3db59a838b2bb35ac77440df52fb2ca919847710..12dbdca82895688d7b3a0b56452a83bd3651c5f3 100644 (file)
@@ -131,6 +131,7 @@ struct quagga_signal_t eigrp_signals[] = {
 };
 
 static const struct frr_yang_module_info *eigrpd_yang_modules[] = {
+       &frr_eigrpd_info,
        &frr_interface_info,
 };
 
@@ -187,7 +188,7 @@ int main(int argc, char **argv, char **envp)
        eigrp_vty_init();
        keychain_init();
        eigrp_vty_show_init();
-       eigrp_vty_if_init();
+       eigrp_cli_init();
 
 #ifdef HAVE_SNMP
        eigrp_snmp_init();
diff --git a/eigrpd/eigrp_northbound.c b/eigrpd/eigrp_northbound.c
new file mode 100644 (file)
index 0000000..5f0c918
--- /dev/null
@@ -0,0 +1,1584 @@
+/*
+ * EIGRP daemon northbound implementation.
+ *
+ * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
+ *                    Rafael Zalamena
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+#include <zebra.h>
+
+#include "lib/keychain.h"
+#include "lib/log.h"
+#include "lib/northbound.h"
+#include "lib/table.h"
+#include "lib/vrf.h"
+#include "lib/zclient.h"
+
+#include "eigrp_structs.h"
+#include "eigrpd.h"
+#include "eigrp_interface.h"
+#include "eigrp_network.h"
+#include "eigrp_zebra.h"
+
+/* Helper functions. */
+static void redistribute_get_metrics(const struct lyd_node *dnode,
+                                    struct eigrp_metrics *em)
+{
+       memset(em, 0, sizeof(*em));
+
+       if (yang_dnode_exists(dnode, "./bandwidth"))
+               em->bandwidth = yang_dnode_get_uint32(dnode, "./bandwidth");
+       if (yang_dnode_exists(dnode, "./delay"))
+               em->delay = yang_dnode_get_uint32(dnode, "./delay");
+#if 0 /* TODO: How does MTU work? */
+       if (yang_dnode_exists(dnode, "./mtu"))
+               em->mtu[0] = yang_dnode_get_uint32(dnode, "./mtu");
+#endif
+       if (yang_dnode_exists(dnode, "./load"))
+               em->load = yang_dnode_get_uint32(dnode, "./load");
+       if (yang_dnode_exists(dnode, "./reliability"))
+               em->reliability = yang_dnode_get_uint32(dnode, "./reliability");
+}
+
+static struct eigrp_interface *eigrp_interface_lookup(const struct eigrp *eigrp,
+                                                     const char *ifname)
+{
+       struct eigrp_interface *eif;
+       struct listnode *ln;
+
+       for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, ln, eif)) {
+               if (strcmp(ifname, eif->ifp->name))
+                       continue;
+
+               return eif;
+       }
+
+       return NULL;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance
+ */
+static int eigrpd_instance_create(enum nb_event event,
+                                 const struct lyd_node *dnode,
+                                 union nb_resource *resource)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               /* NOTHING */
+               break;
+       case NB_EV_PREPARE:
+               eigrp = eigrp_get(yang_dnode_get_string(dnode, "./asn"));
+               resource->ptr = eigrp;
+               break;
+       case NB_EV_ABORT:
+               eigrp_finish_final(resource->ptr);
+               break;
+       case NB_EV_APPLY:
+               nb_running_set_entry(dnode, resource->ptr);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int eigrpd_instance_destroy(enum nb_event event,
+                                  const struct lyd_node *dnode)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_unset_entry(dnode);
+               eigrp_finish_final(eigrp);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/router-id
+ */
+static int eigrpd_instance_router_id_modify(enum nb_event event,
+                                           const struct lyd_node *dnode,
+                                           union nb_resource *resource)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               yang_dnode_get_ipv4(&eigrp->router_id_static, dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int eigrpd_instance_router_id_destroy(enum nb_event event,
+                                            const struct lyd_node *dnode)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->router_id_static.s_addr = 0;
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/passive-interface
+ */
+static int
+eigrpd_instance_passive_interface_create(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct eigrp_interface *eif;
+       struct eigrp *eigrp;
+       const char *ifname;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               eigrp = nb_running_get_entry(dnode, NULL, false);
+               if (eigrp == NULL) {
+                       /*
+                        * XXX: we can't verify if the interface exists
+                        * and is active until EIGRP is up.
+                        */
+                       break;
+               }
+
+               ifname = yang_dnode_get_string(dnode, NULL);
+               eif = eigrp_interface_lookup(eigrp, ifname);
+               if (eif == NULL)
+                       return NB_ERR_INCONSISTENCY;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               ifname = yang_dnode_get_string(dnode, NULL);
+               eif = eigrp_interface_lookup(eigrp, ifname);
+               if (eif == NULL)
+                       return NB_ERR_INCONSISTENCY;
+
+               eif->params.passive_interface = EIGRP_IF_PASSIVE;
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int
+eigrpd_instance_passive_interface_destroy(enum nb_event event,
+                                         const struct lyd_node *dnode)
+{
+       struct eigrp_interface *eif;
+       struct eigrp *eigrp;
+       const char *ifname;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               ifname = yang_dnode_get_string(dnode, NULL);
+               eif = eigrp_interface_lookup(eigrp, ifname);
+               if (eif == NULL)
+                       break;
+
+               eif->params.passive_interface = EIGRP_IF_ACTIVE;
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/active-time
+ */
+static int eigrpd_instance_active_time_modify(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       switch (event) {
+       case NB_EV_VALIDATE:
+               /* TODO: Not implemented. */
+               return NB_ERR_INCONSISTENCY;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* NOTHING */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/variance
+ */
+static int eigrpd_instance_variance_modify(enum nb_event event,
+                                          const struct lyd_node *dnode,
+                                          union nb_resource *resource)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->variance = yang_dnode_get_uint8(dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int eigrpd_instance_variance_destroy(enum nb_event event,
+                                           const struct lyd_node *dnode)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->variance = EIGRP_VARIANCE_DEFAULT;
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/maximum-paths
+ */
+static int eigrpd_instance_maximum_paths_modify(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->max_paths = yang_dnode_get_uint8(dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int eigrpd_instance_maximum_paths_destroy(enum nb_event event,
+                                                const struct lyd_node *dnode)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->max_paths = EIGRP_MAX_PATHS_DEFAULT;
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K1
+ */
+static int
+eigrpd_instance_metric_weights_K1_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[0] = yang_dnode_get_uint8(dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int
+eigrpd_instance_metric_weights_K1_destroy(enum nb_event event,
+                                         const struct lyd_node *dnode)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[0] = EIGRP_K1_DEFAULT;
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K2
+ */
+static int
+eigrpd_instance_metric_weights_K2_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[1] = yang_dnode_get_uint8(dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int
+eigrpd_instance_metric_weights_K2_destroy(enum nb_event event,
+                                         const struct lyd_node *dnode)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[1] = EIGRP_K2_DEFAULT;
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K3
+ */
+static int
+eigrpd_instance_metric_weights_K3_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[2] = yang_dnode_get_uint8(dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int
+eigrpd_instance_metric_weights_K3_destroy(enum nb_event event,
+                                         const struct lyd_node *dnode)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[2] = EIGRP_K3_DEFAULT;
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K4
+ */
+static int
+eigrpd_instance_metric_weights_K4_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[3] = yang_dnode_get_uint8(dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int
+eigrpd_instance_metric_weights_K4_destroy(enum nb_event event,
+                                         const struct lyd_node *dnode)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[3] = EIGRP_K4_DEFAULT;
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K5
+ */
+static int
+eigrpd_instance_metric_weights_K5_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[4] = yang_dnode_get_uint8(dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int
+eigrpd_instance_metric_weights_K5_destroy(enum nb_event event,
+                                         const struct lyd_node *dnode)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[4] = EIGRP_K5_DEFAULT;
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K6
+ */
+static int
+eigrpd_instance_metric_weights_K6_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[5] = yang_dnode_get_uint8(dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int
+eigrpd_instance_metric_weights_K6_destroy(enum nb_event event,
+                                         const struct lyd_node *dnode)
+{
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp->k_values[5] = EIGRP_K6_DEFAULT;
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/network
+ */
+static int eigrpd_instance_network_create(enum nb_event event,
+                                         const struct lyd_node *dnode,
+                                         union nb_resource *resource)
+{
+       struct route_node *rnode;
+       struct prefix prefix;
+       struct eigrp *eigrp;
+       int exists;
+
+       yang_dnode_get_ipv4p(&prefix, dnode, NULL);
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               eigrp = nb_running_get_entry(dnode, NULL, false);
+               /* If entry doesn't exist it means the list is empty. */
+               if (eigrp == NULL)
+                       break;
+
+               rnode = route_node_get(eigrp->networks, &prefix);
+               exists = (rnode->info != NULL);
+               route_unlock_node(rnode);
+               if (exists)
+                       return NB_ERR_INCONSISTENCY;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               if (eigrp_network_set(eigrp, &prefix) == 0)
+                       return NB_ERR_INCONSISTENCY;
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int eigrpd_instance_network_destroy(enum nb_event event,
+                                          const struct lyd_node *dnode)
+{
+       struct route_node *rnode;
+       struct prefix prefix;
+       struct eigrp *eigrp;
+       int exists = 0;
+
+       yang_dnode_get_ipv4p(&prefix, dnode, NULL);
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               eigrp = nb_running_get_entry(dnode, NULL, false);
+               /* If entry doesn't exist it means the list is empty. */
+               if (eigrp == NULL)
+                       break;
+
+               rnode = route_node_get(eigrp->networks, &prefix);
+               exists = (rnode->info != NULL);
+               route_unlock_node(rnode);
+               if (exists == 0)
+                       return NB_ERR_INCONSISTENCY;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               eigrp_network_unset(eigrp, &prefix);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/neighbor
+ */
+static int eigrpd_instance_neighbor_create(enum nb_event event,
+                                          const struct lyd_node *dnode,
+                                          union nb_resource *resource)
+{
+       switch (event) {
+       case NB_EV_VALIDATE:
+               /* TODO: Not implemented. */
+               return NB_ERR_INCONSISTENCY;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* NOTHING */
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int eigrpd_instance_neighbor_destroy(enum nb_event event,
+                                           const struct lyd_node *dnode)
+{
+       switch (event) {
+       case NB_EV_VALIDATE:
+               /* TODO: Not implemented. */
+               return NB_ERR_INCONSISTENCY;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* NOTHING */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute
+ */
+static int eigrpd_instance_redistribute_create(enum nb_event event,
+                                              const struct lyd_node *dnode,
+                                              union nb_resource *resource)
+{
+       struct eigrp_metrics metrics;
+       struct eigrp *eigrp;
+       uint32_t proto;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               proto = yang_dnode_get_enum(dnode, "./protocol");
+               if (vrf_bitmap_check(zclient->redist[AFI_IP][proto],
+                                    VRF_DEFAULT))
+                       return NB_ERR_INCONSISTENCY;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               proto = yang_dnode_get_enum(dnode, "./protocol");
+               redistribute_get_metrics(dnode, &metrics);
+               eigrp_redistribute_set(eigrp, proto, metrics);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int eigrpd_instance_redistribute_destroy(enum nb_event event,
+                                               const struct lyd_node *dnode)
+{
+       struct eigrp *eigrp;
+       uint32_t proto;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               proto = yang_dnode_get_enum(dnode, "./protocol");
+               eigrp_redistribute_unset(eigrp, proto);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/route-map
+ */
+static int
+eigrpd_instance_redistribute_route_map_modify(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       switch (event) {
+       case NB_EV_VALIDATE:
+               /* TODO: Not implemented. */
+               return NB_ERR_INCONSISTENCY;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* NOTHING */
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int
+eigrpd_instance_redistribute_route_map_destroy(enum nb_event event,
+                                              const struct lyd_node *dnode)
+{
+       switch (event) {
+       case NB_EV_VALIDATE:
+               /* TODO: Not implemented. */
+               return NB_ERR_INCONSISTENCY;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* NOTHING */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/bandwidth
+ */
+static int eigrpd_instance_redistribute_metrics_bandwidth_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       struct eigrp_metrics metrics;
+       struct eigrp *eigrp;
+       uint32_t proto;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               proto = yang_dnode_get_enum(dnode, "../../protocol");
+               redistribute_get_metrics(dnode, &metrics);
+               eigrp_redistribute_set(eigrp, proto, metrics);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int eigrpd_instance_redistribute_metrics_bandwidth_destroy(
+       enum nb_event event, const struct lyd_node *dnode)
+{
+       struct eigrp_metrics metrics;
+       struct eigrp *eigrp;
+       uint32_t proto;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eigrp = nb_running_get_entry(dnode, NULL, true);
+               proto = yang_dnode_get_enum(dnode, "../../protocol");
+               redistribute_get_metrics(dnode, &metrics);
+               eigrp_redistribute_set(eigrp, proto, metrics);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/delay
+ */
+static int
+eigrpd_instance_redistribute_metrics_delay_modify(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
+                                                                    dnode,
+                                                                    resource);
+}
+
+static int
+eigrpd_instance_redistribute_metrics_delay_destroy(enum nb_event event,
+                                                  const struct lyd_node *dnode)
+{
+       return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
+                                                                     dnode);
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/reliability
+ */
+static int eigrpd_instance_redistribute_metrics_reliability_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
+                                                                    dnode,
+                                                                    resource);
+}
+
+static int eigrpd_instance_redistribute_metrics_reliability_destroy(
+       enum nb_event event, const struct lyd_node *dnode)
+{
+       return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
+                                                                     dnode);
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/load
+ */
+static int
+eigrpd_instance_redistribute_metrics_load_modify(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
+                                                                    dnode,
+                                                                    resource);
+}
+
+static int
+eigrpd_instance_redistribute_metrics_load_destroy(enum nb_event event,
+                                                 const struct lyd_node *dnode)
+{
+       return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
+                                                                     dnode);
+}
+
+/*
+ * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/mtu
+ */
+static int
+eigrpd_instance_redistribute_metrics_mtu_modify(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
+                                                                    dnode,
+                                                                    resource);
+}
+
+static int
+eigrpd_instance_redistribute_metrics_mtu_destroy(enum nb_event event,
+                                                const struct lyd_node *dnode)
+{
+       return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
+                                                                     dnode);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/delay
+ */
+static int lib_interface_eigrp_delay_modify(enum nb_event event,
+                                           const struct lyd_node *dnode,
+                                           union nb_resource *resource)
+{
+       struct eigrp_interface *ei;
+       struct interface *ifp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               ifp = nb_running_get_entry(dnode, NULL, false);
+               if (ifp == NULL) {
+                       /*
+                        * XXX: we can't verify if the interface exists
+                        * and is active until EIGRP is up.
+                        */
+                       break;
+               }
+
+               ei = ifp->info;
+               if (ei == NULL)
+                       return NB_ERR_INCONSISTENCY;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               ifp = nb_running_get_entry(dnode, NULL, true);
+               ei = ifp->info;
+               if (ei == NULL)
+                       return NB_ERR_INCONSISTENCY;
+
+               ei->params.delay = yang_dnode_get_uint32(dnode, NULL);
+               eigrp_if_reset(ifp);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/bandwidth
+ */
+static int lib_interface_eigrp_bandwidth_modify(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       struct interface *ifp;
+       struct eigrp_interface *ei;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               ifp = nb_running_get_entry(dnode, NULL, false);
+               if (ifp == NULL) {
+                       /*
+                        * XXX: we can't verify if the interface exists
+                        * and is active until EIGRP is up.
+                        */
+                       break;
+               }
+
+               ei = ifp->info;
+               if (ei == NULL)
+                       return NB_ERR_INCONSISTENCY;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               ifp = nb_running_get_entry(dnode, NULL, true);
+               ei = ifp->info;
+               if (ei == NULL)
+                       return NB_ERR_INCONSISTENCY;
+
+               ei->params.bandwidth = yang_dnode_get_uint32(dnode, NULL);
+               eigrp_if_reset(ifp);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hello-interval
+ */
+static int
+lib_interface_eigrp_hello_interval_modify(enum nb_event event,
+                                         const struct lyd_node *dnode,
+                                         union nb_resource *resource)
+{
+       struct interface *ifp;
+       struct eigrp_interface *ei;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               ifp = nb_running_get_entry(dnode, NULL, false);
+               if (ifp == NULL) {
+                       /*
+                        * XXX: we can't verify if the interface exists
+                        * and is active until EIGRP is up.
+                        */
+                       break;
+               }
+
+               ei = ifp->info;
+               if (ei == NULL)
+                       return NB_ERR_INCONSISTENCY;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               ifp = nb_running_get_entry(dnode, NULL, true);
+               ei = ifp->info;
+               if (ei == NULL)
+                       return NB_ERR_INCONSISTENCY;
+
+               ei->params.v_hello = yang_dnode_get_uint16(dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hold-time
+ */
+static int lib_interface_eigrp_hold_time_modify(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       struct interface *ifp;
+       struct eigrp_interface *ei;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               ifp = nb_running_get_entry(dnode, NULL, false);
+               if (ifp == NULL) {
+                       /*
+                        * XXX: we can't verify if the interface exists
+                        * and is active until EIGRP is up.
+                        */
+                       break;
+               }
+
+               ei = ifp->info;
+               if (ei == NULL)
+                       return NB_ERR_INCONSISTENCY;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               ifp = nb_running_get_entry(dnode, NULL, true);
+               ei = ifp->info;
+               if (ei == NULL)
+                       return NB_ERR_INCONSISTENCY;
+
+               ei->params.v_wait = yang_dnode_get_uint16(dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/split-horizon
+ */
+static int
+lib_interface_eigrp_split_horizon_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       switch (event) {
+       case NB_EV_VALIDATE:
+               /* TODO: Not implemented. */
+               return NB_ERR_INCONSISTENCY;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* NOTHING */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance
+ */
+static int lib_interface_eigrp_instance_create(enum nb_event event,
+                                              const struct lyd_node *dnode,
+                                              union nb_resource *resource)
+{
+       struct eigrp_interface *eif;
+       struct interface *ifp;
+       struct eigrp *eigrp;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               ifp = nb_running_get_entry(dnode, NULL, false);
+               if (ifp == NULL) {
+                       /*
+                        * XXX: we can't verify if the interface exists
+                        * and is active until EIGRP is up.
+                        */
+                       break;
+               }
+
+               eigrp = eigrp_get(yang_dnode_get_string(dnode, "./asn"));
+               eif = eigrp_interface_lookup(eigrp, ifp->name);
+               if (eif == NULL)
+                       return NB_ERR_INCONSISTENCY;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               ifp = nb_running_get_entry(dnode, NULL, true);
+               eigrp = eigrp_get(yang_dnode_get_string(dnode, "./asn"));
+               eif = eigrp_interface_lookup(eigrp, ifp->name);
+               if (eif == NULL)
+                       return NB_ERR_INCONSISTENCY;
+
+               nb_running_set_entry(dnode, eif);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int lib_interface_eigrp_instance_destroy(enum nb_event event,
+                                               const struct lyd_node *dnode)
+{
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               nb_running_unset_entry(dnode);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/summarize-addresses
+ */
+static int lib_interface_eigrp_instance_summarize_addresses_create(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       switch (event) {
+       case NB_EV_VALIDATE:
+               /* TODO: Not implemented. */
+               return NB_ERR_INCONSISTENCY;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* NOTHING */
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int lib_interface_eigrp_instance_summarize_addresses_destroy(
+       enum nb_event event, const struct lyd_node *dnode)
+{
+       switch (event) {
+       case NB_EV_VALIDATE:
+               /* TODO: Not implemented. */
+               return NB_ERR_INCONSISTENCY;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* NOTHING */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication
+ */
+static int
+lib_interface_eigrp_instance_authentication_modify(enum nb_event event,
+                                                  const struct lyd_node *dnode,
+                                                  union nb_resource *resource)
+{
+       struct eigrp_interface *eif;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eif = nb_running_get_entry(dnode, NULL, true);
+               eif->params.auth_type = yang_dnode_get_enum(dnode, NULL);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/keychain
+ */
+static int
+lib_interface_eigrp_instance_keychain_modify(enum nb_event event,
+                                            const struct lyd_node *dnode,
+                                            union nb_resource *resource)
+{
+       struct eigrp_interface *eif;
+       struct keychain *keychain;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               keychain = keychain_lookup(yang_dnode_get_string(dnode, NULL));
+               if (keychain == NULL)
+                       return NB_ERR_INCONSISTENCY;
+               break;
+       case NB_EV_PREPARE:
+               resource->ptr = strdup(yang_dnode_get_string(dnode, NULL));
+               if (resource->ptr == NULL)
+                       return NB_ERR_RESOURCE;
+               break;
+       case NB_EV_ABORT:
+               free(resource->ptr);
+               resource->ptr = NULL;
+               break;
+       case NB_EV_APPLY:
+               eif = nb_running_get_entry(dnode, NULL, true);
+               if (eif->params.auth_keychain)
+                       free(eif->params.auth_keychain);
+
+               eif->params.auth_keychain = resource->ptr;
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int
+lib_interface_eigrp_instance_keychain_destroy(enum nb_event event,
+                                             const struct lyd_node *dnode)
+{
+       struct eigrp_interface *eif;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               /* NOTHING */
+               break;
+       case NB_EV_APPLY:
+               eif = nb_running_get_entry(dnode, NULL, true);
+               if (eif->params.auth_keychain)
+                       free(eif->params.auth_keychain);
+
+               eif->params.auth_keychain = NULL;
+               break;
+       }
+
+       return NB_OK;
+}
+
+/* clang-format off */
+const struct frr_yang_module_info frr_eigrpd_info = {
+       .name = "frr-eigrpd",
+       .nodes = {
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance",
+                       .cbs = {
+                               .create = eigrpd_instance_create,
+                               .destroy = eigrpd_instance_destroy,
+                               .cli_show = eigrp_cli_show_header,
+                               .cli_show_end = eigrp_cli_show_end_header,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/router-id",
+                       .cbs = {
+                               .modify = eigrpd_instance_router_id_modify,
+                               .destroy = eigrpd_instance_router_id_destroy,
+                               .cli_show = eigrp_cli_show_router_id,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/passive-interface",
+                       .cbs = {
+                               .create = eigrpd_instance_passive_interface_create,
+                               .destroy = eigrpd_instance_passive_interface_destroy,
+                               .cli_show = eigrp_cli_show_passive_interface,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/active-time",
+                       .cbs = {
+                               .modify = eigrpd_instance_active_time_modify,
+                               .cli_show = eigrp_cli_show_active_time,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/variance",
+                       .cbs = {
+                               .modify = eigrpd_instance_variance_modify,
+                               .destroy = eigrpd_instance_variance_destroy,
+                               .cli_show = eigrp_cli_show_variance,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/maximum-paths",
+                       .cbs = {
+                               .modify = eigrpd_instance_maximum_paths_modify,
+                               .destroy = eigrpd_instance_maximum_paths_destroy,
+                               .cli_show = eigrp_cli_show_maximum_paths,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights",
+                       .cbs = {
+                               .cli_show = eigrp_cli_show_metrics,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K1",
+                       .cbs = {
+                               .modify = eigrpd_instance_metric_weights_K1_modify,
+                               .destroy = eigrpd_instance_metric_weights_K1_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K2",
+                       .cbs = {
+                               .modify = eigrpd_instance_metric_weights_K2_modify,
+                               .destroy = eigrpd_instance_metric_weights_K2_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K3",
+                       .cbs = {
+                               .modify = eigrpd_instance_metric_weights_K3_modify,
+                               .destroy = eigrpd_instance_metric_weights_K3_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K4",
+                       .cbs = {
+                               .modify = eigrpd_instance_metric_weights_K4_modify,
+                               .destroy = eigrpd_instance_metric_weights_K4_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K5",
+                       .cbs = {
+                               .modify = eigrpd_instance_metric_weights_K5_modify,
+                               .destroy = eigrpd_instance_metric_weights_K5_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K6",
+                       .cbs = {
+                               .modify = eigrpd_instance_metric_weights_K6_modify,
+                               .destroy = eigrpd_instance_metric_weights_K6_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/network",
+                       .cbs = {
+                               .create = eigrpd_instance_network_create,
+                               .destroy = eigrpd_instance_network_destroy,
+                               .cli_show = eigrp_cli_show_network,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/neighbor",
+                       .cbs = {
+                               .create = eigrpd_instance_neighbor_create,
+                               .destroy = eigrpd_instance_neighbor_destroy,
+                               .cli_show = eigrp_cli_show_neighbor,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/redistribute",
+                       .cbs = {
+                               .create = eigrpd_instance_redistribute_create,
+                               .destroy = eigrpd_instance_redistribute_destroy,
+                               .cli_show = eigrp_cli_show_redistribute,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/route-map",
+                       .cbs = {
+                               .modify = eigrpd_instance_redistribute_route_map_modify,
+                               .destroy = eigrpd_instance_redistribute_route_map_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/bandwidth",
+                       .cbs = {
+                               .modify = eigrpd_instance_redistribute_metrics_bandwidth_modify,
+                               .destroy = eigrpd_instance_redistribute_metrics_bandwidth_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/delay",
+                       .cbs = {
+                               .modify = eigrpd_instance_redistribute_metrics_delay_modify,
+                               .destroy = eigrpd_instance_redistribute_metrics_delay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/reliability",
+                       .cbs = {
+                               .modify = eigrpd_instance_redistribute_metrics_reliability_modify,
+                               .destroy = eigrpd_instance_redistribute_metrics_reliability_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/load",
+                       .cbs = {
+                               .modify = eigrpd_instance_redistribute_metrics_load_modify,
+                               .destroy = eigrpd_instance_redistribute_metrics_load_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/mtu",
+                       .cbs = {
+                               .modify = eigrpd_instance_redistribute_metrics_mtu_modify,
+                               .destroy = eigrpd_instance_redistribute_metrics_mtu_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/delay",
+                       .cbs = {
+                               .modify = lib_interface_eigrp_delay_modify,
+                               .cli_show = eigrp_cli_show_delay,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/bandwidth",
+                       .cbs = {
+                               .modify = lib_interface_eigrp_bandwidth_modify,
+                               .cli_show = eigrp_cli_show_bandwidth,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/hello-interval",
+                       .cbs = {
+                               .modify = lib_interface_eigrp_hello_interval_modify,
+                               .cli_show = eigrp_cli_show_hello_interval,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/hold-time",
+                       .cbs = {
+                               .modify = lib_interface_eigrp_hold_time_modify,
+                               .cli_show = eigrp_cli_show_hold_time,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/split-horizon",
+                       .cbs = {
+                               .modify = lib_interface_eigrp_split_horizon_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance",
+                       .cbs = {
+                               .create = lib_interface_eigrp_instance_create,
+                               .destroy = lib_interface_eigrp_instance_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance/summarize-addresses",
+                       .cbs = {
+                               .create = lib_interface_eigrp_instance_summarize_addresses_create,
+                               .destroy = lib_interface_eigrp_instance_summarize_addresses_destroy,
+                               .cli_show = eigrp_cli_show_summarize_address,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication",
+                       .cbs = {
+                               .modify = lib_interface_eigrp_instance_authentication_modify,
+                               .cli_show = eigrp_cli_show_authentication,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance/keychain",
+                       .cbs = {
+                               .modify = lib_interface_eigrp_instance_keychain_modify,
+                               .destroy = lib_interface_eigrp_instance_keychain_destroy,
+                               .cli_show = eigrp_cli_show_keychain,
+                       }
+               },
+               {
+                       .xpath = NULL,
+               },
+       }
+};
index d51faaac598cda318ec52d1148f475d8479ea5e1..207622e659a6d4ee663cc35f673a358637f8665d 100644 (file)
 #include "eigrpd/eigrp_vty_clippy.c"
 #endif
 
-static int config_write_network(struct vty *vty, struct eigrp *eigrp)
-{
-       struct route_node *rn;
-       int i;
-
-       /* `network area' print. */
-       for (rn = route_top(eigrp->networks); rn; rn = route_next(rn))
-               if (rn->info) {
-                       /* Network print. */
-                       vty_out(vty, " network %s/%d \n",
-                               inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen);
-               }
-
-       if (eigrp->max_paths != EIGRP_MAX_PATHS_DEFAULT)
-               vty_out(vty, " maximum-paths %d\n", eigrp->max_paths);
-
-       if (eigrp->variance != EIGRP_VARIANCE_DEFAULT)
-               vty_out(vty, " variance %d\n", eigrp->variance);
-
-       for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
-               if (i != zclient->redist_default
-                   && vrf_bitmap_check(zclient->redist[AFI_IP][i],
-                                       VRF_DEFAULT))
-                       vty_out(vty, " redistribute %s\n",
-                               zebra_route_string(i));
-
-       /*Separate EIGRP configuration from the rest of the config*/
-       vty_out(vty, "!\n");
-
-       return 0;
-}
-
-static int config_write_interfaces(struct vty *vty, struct eigrp *eigrp)
-{
-       struct eigrp_interface *ei;
-       struct listnode *node;
-
-       for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
-               vty_frame(vty, "interface %s\n", ei->ifp->name);
-
-               if (ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) {
-                       vty_out(vty, " ip authentication mode eigrp %d md5\n",
-                               eigrp->AS);
-               }
-
-               if (ei->params.auth_type == EIGRP_AUTH_TYPE_SHA256) {
-                       vty_out(vty,
-                               " ip authentication mode eigrp %d hmac-sha-256\n",
-                               eigrp->AS);
-               }
-
-               if (ei->params.auth_keychain) {
-                       vty_out(vty,
-                               " ip authentication key-chain eigrp %d %s\n",
-                               eigrp->AS, ei->params.auth_keychain);
-               }
-
-               if (ei->params.v_hello != EIGRP_HELLO_INTERVAL_DEFAULT) {
-                       vty_out(vty, " ip hello-interval eigrp %d\n",
-                               ei->params.v_hello);
-               }
-
-               if (ei->params.v_wait != EIGRP_HOLD_INTERVAL_DEFAULT) {
-                       vty_out(vty, " ip hold-time eigrp %d\n",
-                               ei->params.v_wait);
-               }
-
-               /*Separate this EIGRP interface configuration from the others*/
-               vty_endframe(vty, "!\n");
-       }
-
-       return 0;
-}
-
-static int eigrp_write_interface(struct vty *vty)
-{
-       struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
-       struct interface *ifp;
-       struct eigrp_interface *ei;
-
-       FOR_ALL_INTERFACES (vrf, ifp) {
-               ei = ifp->info;
-               if (!ei)
-                       continue;
-
-               vty_frame(vty, "interface %s\n", ifp->name);
-
-               if (ifp->desc)
-                       vty_out(vty, " description %s\n", ifp->desc);
-
-               if (ei->params.bandwidth != EIGRP_BANDWIDTH_DEFAULT)
-                       vty_out(vty, " bandwidth %u\n", ei->params.bandwidth);
-               if (ei->params.delay != EIGRP_DELAY_DEFAULT)
-                       vty_out(vty, " delay %u\n", ei->params.delay);
-               if (ei->params.v_hello != EIGRP_HELLO_INTERVAL_DEFAULT)
-                       vty_out(vty, " ip hello-interval eigrp %u\n",
-                               ei->params.v_hello);
-               if (ei->params.v_wait != EIGRP_HOLD_INTERVAL_DEFAULT)
-                       vty_out(vty, " ip hold-time eigrp %u\n",
-                               ei->params.v_wait);
-
-               vty_endframe(vty, "!\n");
-       }
-
-       return 0;
-}
-
-/**
- * Writes distribute lists to config
- */
-static int config_write_eigrp_distribute(struct vty *vty, struct eigrp *eigrp)
-{
-       int write = 0;
-
-       /* Distribute configuration. */
-       write += config_write_distribute(vty, eigrp->distribute_ctx);
-
-       return write;
-}
-
-/**
- * Writes 'router eigrp' section to config
- */
-static int config_write_eigrp_router(struct vty *vty, struct eigrp *eigrp)
-{
-       int write = 0;
-
-       /* `router eigrp' print. */
-       vty_out(vty, "router eigrp %d\n", eigrp->AS);
-
-       write++;
-
-       /* Router ID print. */
-       if (eigrp->router_id_static.s_addr != 0) {
-               vty_out(vty, " eigrp router-id %s\n",
-                       inet_ntoa(eigrp->router_id_static));
-       }
-
-       /* Network area print. */
-       config_write_network(vty, eigrp);
-
-       /* Distribute-list and default-information print. */
-       config_write_eigrp_distribute(vty, eigrp);
-
-       /*Separate EIGRP configuration from the rest of the config*/
-       vty_out(vty, "!\n");
-
-       return write;
-}
-
-DEFUN_NOSH (router_eigrp,
-            router_eigrp_cmd,
-            "router eigrp (1-65535)",
-            "Enable a routing process\n"
-            "Start EIGRP configuration\n"
-            "AS Number to use\n")
-{
-       struct eigrp *eigrp = eigrp_get(argv[2]->arg);
-       VTY_PUSH_CONTEXT(EIGRP_NODE, eigrp);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_router_eigrp,
-       no_router_eigrp_cmd,
-       "no router eigrp (1-65535)",
-       NO_STR
-       "Routing process\n"
-       "EIGRP configuration\n"
-       "AS number to use\n")
-{
-       vty->node = CONFIG_NODE;
-
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       if (eigrp->AS != atoi(argv[3]->arg)) {
-               vty_out(vty, "%% Attempting to deconfigure non-existent AS\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       eigrp_finish_final(eigrp);
-
-       return CMD_SUCCESS;
-}
-
-DEFPY (eigrp_router_id,
-       eigrp_router_id_cmd,
-       "eigrp router-id A.B.C.D$addr",
-       "EIGRP specific commands\n"
-       "Router ID for this EIGRP process\n"
-       "EIGRP Router-ID in IP address format\n")
-{
-       VTY_DECLVAR_CONTEXT(eigrp, eigrp);
-
-       eigrp->router_id_static = addr;
-
-       return CMD_SUCCESS;
-}
-
-DEFPY (no_eigrp_router_id,
-       no_eigrp_router_id_cmd,
-       "no eigrp router-id [A.B.C.D$addr]",
-       NO_STR
-       "EIGRP specific commands\n"
-       "Router ID for this EIGRP process\n"
-       "EIGRP Router-ID in IP address format\n")
-{
-       VTY_DECLVAR_CONTEXT(eigrp, eigrp);
-
-       eigrp->router_id_static.s_addr = 0;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (eigrp_passive_interface,
-       eigrp_passive_interface_cmd,
-       "passive-interface IFNAME",
-       "Suppress routing updates on an interface\n"
-       "Interface to suppress on\n")
-{
-       VTY_DECLVAR_CONTEXT(eigrp, eigrp);
-       struct eigrp_interface *ei;
-       struct listnode *node;
-       char *ifname = argv[1]->arg;
-
-       for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
-               if (strcmp(ifname, ei->ifp->name) == 0) {
-                       ei->params.passive_interface = EIGRP_IF_PASSIVE;
-                       return CMD_SUCCESS;
-               }
-       }
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_passive_interface,
-       no_eigrp_passive_interface_cmd,
-       "no passive-interface IFNAME",
-       NO_STR
-       "Suppress routing updates on an interface\n"
-       "Interface to suppress on\n")
-{
-       VTY_DECLVAR_CONTEXT(eigrp, eigrp);
-       struct eigrp_interface *ei;
-       struct listnode *node;
-       char *ifname = argv[2]->arg;
-
-       for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
-               if (strcmp(ifname, ei->ifp->name) == 0) {
-                       ei->params.passive_interface = EIGRP_IF_ACTIVE;
-                       return CMD_SUCCESS;
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (eigrp_timers_active,
-       eigrp_timers_active_cmd,
-       "timers active-time <(1-65535)|disabled>",
-       "Adjust routing timers\n"
-       "Time limit for active state\n"
-       "Active state time limit in seconds\n"
-       "Disable time limit for active state\n")
-{
-       // struct eigrp *eigrp = vty->index;
-       /*TODO: */
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_timers_active,
-       no_eigrp_timers_active_cmd,
-       "no timers active-time <(1-65535)|disabled>",
-       NO_STR
-       "Adjust routing timers\n"
-       "Time limit for active state\n"
-       "Active state time limit in seconds\n"
-       "Disable time limit for active state\n")
-{
-       // struct eigrp *eigrp = vty->index;
-       /*TODO: */
-
-       return CMD_SUCCESS;
-}
-
-
-DEFUN (eigrp_metric_weights,
-       eigrp_metric_weights_cmd,
-       "metric weights (0-255) (0-255) (0-255) (0-255) (0-255) ",
-       "Modify metrics and parameters for advertisement\n"
-       "Modify metric coefficients\n"
-       "K1\n"
-       "K2\n"
-       "K3\n"
-       "K4\n"
-       "K5\n")
-{
-       // struct eigrp *eigrp = vty->index;
-       /*TODO: */
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_metric_weights,
-       no_eigrp_metric_weights_cmd,
-       "no metric weights (0-255) (0-255) (0-255) (0-255) (0-255)",
-       NO_STR
-       "Modify metrics and parameters for advertisement\n"
-       "Modify metric coefficients\n"
-       "K1\n"
-       "K2\n"
-       "K3\n"
-       "K4\n"
-       "K5\n")
-{
-       // struct eigrp *eigrp = vty->index;
-       /*TODO: */
-
-       return CMD_SUCCESS;
-}
-
-
-DEFUN (eigrp_network,
-       eigrp_network_cmd,
-       "network A.B.C.D/M",
-       "Enable routing on an IP network\n"
-       "EIGRP network prefix\n")
-{
-       VTY_DECLVAR_CONTEXT(eigrp, eigrp);
-       struct prefix p;
-       int ret;
-
-       (void)str2prefix(argv[1]->arg, &p);
-
-       ret = eigrp_network_set(eigrp, &p);
-
-       if (ret == 0) {
-               vty_out(vty, "There is already same network statement.\n");
-               return CMD_WARNING;
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_network,
-       no_eigrp_network_cmd,
-       "no network A.B.C.D/M",
-       NO_STR
-       "Disable routing on an IP network\n"
-       "EIGRP network prefix\n")
-{
-       VTY_DECLVAR_CONTEXT(eigrp, eigrp);
-       struct prefix p;
-       int ret;
-
-       (void)str2prefix(argv[2]->arg, &p);
-
-       ret = eigrp_network_unset(eigrp, &p);
-
-       if (ret == 0) {
-               vty_out(vty, "Can't find specified network configuration.\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (eigrp_neighbor,
-       eigrp_neighbor_cmd,
-       "neighbor A.B.C.D",
-       "Specify a neighbor router\n"
-       "Neighbor address\n")
-{
-       // struct eigrp *eigrp = vty->index;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_neighbor,
-       no_eigrp_neighbor_cmd,
-       "no neighbor A.B.C.D",
-       NO_STR
-       "Specify a neighbor router\n"
-       "Neighbor address\n")
-{
-       // struct eigrp *eigrp = vty->index;
-
-       return CMD_SUCCESS;
-}
-
 static void eigrp_vty_display_prefix_entry(struct vty *vty,
                                           struct eigrp *eigrp,
                                           struct eigrp_prefix_entry *pe,
@@ -650,585 +254,6 @@ DEFUN (show_ip_eigrp_neighbors,
        return CMD_SUCCESS;
 }
 
-DEFUN (eigrp_if_delay,
-       eigrp_if_delay_cmd,
-       "delay (1-16777215)",
-       "Specify interface throughput delay\n"
-       "Throughput delay (tens of microseconds)\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct eigrp_interface *ei = ifp->info;
-       struct eigrp *eigrp;
-       uint32_t delay;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-
-               return CMD_SUCCESS;
-       }
-
-       if (!ei) {
-               vty_out(vty, " EIGRP not configured on this interface\n");
-               return CMD_SUCCESS;
-       }
-       delay = atoi(argv[1]->arg);
-
-       ei->params.delay = delay;
-       eigrp_if_reset(ifp);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_if_delay,
-       no_eigrp_if_delay_cmd,
-       "no delay (1-16777215)",
-       NO_STR
-       "Specify interface throughput delay\n"
-       "Throughput delay (tens of microseconds)\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct eigrp_interface *ei = ifp->info;
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-
-               return CMD_SUCCESS;
-       }
-       if (!ei) {
-               vty_out(vty, " EIGRP not configured on this interface\n");
-               return CMD_SUCCESS;
-       }
-
-       ei->params.delay = EIGRP_DELAY_DEFAULT;
-       eigrp_if_reset(ifp);
-
-       return CMD_SUCCESS;
-}
-
-DEFPY (eigrp_if_bandwidth,
-       eigrp_if_bandwidth_cmd,
-       "eigrp bandwidth (1-10000000)$bw",
-       "EIGRP specific commands\n"
-       "Set bandwidth informational parameter\n"
-       "Bandwidth in kilobits\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct eigrp_interface *ei = ifp->info;
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       if (!ei) {
-               vty_out(vty, " EIGRP not configured on this interface\n");
-               return CMD_SUCCESS;
-       }
-
-       ei->params.bandwidth = bw;
-       eigrp_if_reset(ifp);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_if_bandwidth,
-       no_eigrp_if_bandwidth_cmd,
-       "no eigrp bandwidth [(1-10000000)]",
-       NO_STR
-       "EIGRP specific commands\n"
-       "Set bandwidth informational parameter\n"
-       "Bandwidth in kilobits\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct eigrp_interface *ei = ifp->info;
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       if (!ei) {
-               vty_out(vty, " EIGRP not configured on this interface\n");
-               return CMD_SUCCESS;
-       }
-
-       ei->params.bandwidth = EIGRP_BANDWIDTH_DEFAULT;
-       eigrp_if_reset(ifp);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (eigrp_if_ip_hellointerval,
-       eigrp_if_ip_hellointerval_cmd,
-       "ip hello-interval eigrp (1-65535)",
-       "Interface Internet Protocol config commands\n"
-       "Configures EIGRP hello interval\n"
-       "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
-       "Seconds between hello transmissions\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct eigrp_interface *ei = ifp->info;
-       uint32_t hello;
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       if (!ei) {
-               vty_out(vty, " EIGRP not configured on this interface\n");
-               return CMD_SUCCESS;
-       }
-
-       hello = atoi(argv[3]->arg);
-
-       ei->params.v_hello = hello;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_if_ip_hellointerval,
-       no_eigrp_if_ip_hellointerval_cmd,
-       "no ip hello-interval eigrp [(1-65535)]",
-       NO_STR
-       "Interface Internet Protocol config commands\n"
-       "Configures EIGRP hello interval\n"
-       "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
-       "Seconds between hello transmissions\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct eigrp_interface *ei = ifp->info;
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       if (!ei) {
-               vty_out(vty, " EIGRP not configured on this interface\n");
-               return CMD_SUCCESS;
-       }
-
-       ei->params.v_hello = EIGRP_HELLO_INTERVAL_DEFAULT;
-
-       THREAD_TIMER_OFF(ei->t_hello);
-       thread_add_timer(master, eigrp_hello_timer, ei, 1, &ei->t_hello);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (eigrp_if_ip_holdinterval,
-       eigrp_if_ip_holdinterval_cmd,
-       "ip hold-time eigrp (1-65535)",
-       "Interface Internet Protocol config commands\n"
-       "Configures EIGRP IPv4 hold time\n"
-       "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
-       "Seconds before neighbor is considered down\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct eigrp_interface *ei = ifp->info;
-       uint32_t hold;
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       if (!ei) {
-               vty_out(vty, " EIGRP not configured on this interface\n");
-               return CMD_SUCCESS;
-       }
-
-       hold = atoi(argv[3]->arg);
-
-       ei->params.v_wait = hold;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (eigrp_ip_summary_address,
-       eigrp_ip_summary_address_cmd,
-       "ip summary-address eigrp (1-65535) A.B.C.D/M",
-       "Interface Internet Protocol config commands\n"
-       "Perform address summarization\n"
-       "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
-       "AS number\n"
-       "Summary <network>/<length>, e.g. 192.168.0.0/16\n")
-{
-       // VTY_DECLVAR_CONTEXT(interface, ifp);
-       // uint32_t AS;
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       // AS = atoi (argv[3]->arg);
-
-       /*TODO: */
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_ip_summary_address,
-       no_eigrp_ip_summary_address_cmd,
-       "no ip summary-address eigrp (1-65535) A.B.C.D/M",
-       NO_STR
-       "Interface Internet Protocol config commands\n"
-       "Perform address summarization\n"
-       "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
-       "AS number\n"
-       "Summary <network>/<length>, e.g. 192.168.0.0/16\n")
-{
-       // VTY_DECLVAR_CONTEXT(interface, ifp);
-       // uint32_t AS;
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       // AS = atoi (argv[4]->arg);
-
-       /*TODO: */
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_if_ip_holdinterval,
-       no_eigrp_if_ip_holdinterval_cmd,
-       "no ip hold-time eigrp",
-       NO_STR
-       "Interface Internet Protocol config commands\n"
-       "Configures EIGRP hello interval\n"
-       "Enhanced Interior Gateway Routing Protocol (EIGRP)\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct eigrp_interface *ei = ifp->info;
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       if (!ei) {
-               vty_out(vty, " EIGRP not configured on this interface\n");
-               return CMD_SUCCESS;
-       }
-
-       ei->params.v_wait = EIGRP_HOLD_INTERVAL_DEFAULT;
-
-       return CMD_SUCCESS;
-}
-
-static int str2auth_type(const char *str, struct eigrp_interface *ei)
-{
-       /* Sanity check. */
-       if (str == NULL)
-               return CMD_WARNING_CONFIG_FAILED;
-
-       if (strncmp(str, "md5", 3) == 0) {
-               ei->params.auth_type = EIGRP_AUTH_TYPE_MD5;
-               return CMD_SUCCESS;
-       } else if (strncmp(str, "hmac-sha-256", 12) == 0) {
-               ei->params.auth_type = EIGRP_AUTH_TYPE_SHA256;
-               return CMD_SUCCESS;
-       }
-
-       return CMD_WARNING_CONFIG_FAILED;
-}
-
-DEFUN (eigrp_authentication_mode,
-       eigrp_authentication_mode_cmd,
-       "ip authentication mode eigrp (1-65535) <md5|hmac-sha-256>",
-       "Interface Internet Protocol config commands\n"
-       "Authentication subcommands\n"
-       "Mode\n"
-       "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
-       "Autonomous system number\n"
-       "Keyed message digest\n"
-       "HMAC SHA256 algorithm \n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct eigrp_interface *ei = ifp->info;
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       if (!ei) {
-               vty_out(vty, " EIGRP not configured on this interface\n");
-               return CMD_SUCCESS;
-       }
-
-       //  if(strncmp(argv[2], "md5",3))
-       //    IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_MD5;
-       //  else if(strncmp(argv[2], "hmac-sha-256",12))
-       //    IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_SHA256;
-
-       return str2auth_type(argv[5]->arg, ei);
-}
-
-DEFUN (no_eigrp_authentication_mode,
-       no_eigrp_authentication_mode_cmd,
-       "no ip authentication mode eigrp (1-65535) <md5|hmac-sha-256>",
-       "Disable\n"
-       "Interface Internet Protocol config commands\n"
-       "Authentication subcommands\n"
-       "Mode\n"
-       "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
-       "Autonomous system number\n"
-       "Keyed message digest\n"
-       "HMAC SHA256 algorithm \n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct eigrp_interface *ei = ifp->info;
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, " EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       if (!ei) {
-               vty_out(vty, " EIGRP not configured on this interface\n");
-               return CMD_SUCCESS;
-       }
-
-       ei->params.auth_type = EIGRP_AUTH_TYPE_NONE;
-
-       return CMD_SUCCESS;
-}
-
-DEFPY (eigrp_authentication_keychain,
-       eigrp_authentication_keychain_cmd,
-       "[no] ip authentication key-chain eigrp (1-65535)$as WORD$name",
-       NO_STR
-       "Interface Internet Protocol config commands\n"
-       "Authentication subcommands\n"
-       "Key-chain\n"
-       "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
-       "Autonomous system number\n"
-       "Name of key-chain\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct eigrp_interface *ei = ifp->info;
-       struct eigrp *eigrp;
-       struct keychain *keychain;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, "EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       if (!ei) {
-               vty_out(vty, " EIGRP not configured on this interface\n");
-               return CMD_SUCCESS;
-       }
-
-       if (no) {
-               if ((ei->params.auth_keychain != NULL)
-                   && (strcmp(ei->params.auth_keychain, name) == 0)) {
-                       free(ei->params.auth_keychain);
-                       ei->params.auth_keychain = NULL;
-               } else
-                       vty_out(vty,
-                               "Key chain with specified name not configured on interface\n");
-               return CMD_SUCCESS;
-       }
-
-       keychain = keychain_lookup(name);
-       if (keychain != NULL) {
-               if (ei->params.auth_keychain) {
-                       free(ei->params.auth_keychain);
-                       ei->params.auth_keychain = strdup(keychain->name);
-               } else
-                       ei->params.auth_keychain = strdup(keychain->name);
-       } else {
-               vty_out(vty,
-                       "Key chain with specified name not found\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (eigrp_redistribute_source_metric,
-       eigrp_redistribute_source_metric_cmd,
-       "redistribute " FRR_REDIST_STR_EIGRPD
-       " [metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)]",
-       REDIST_STR
-       FRR_REDIST_HELP_STR_EIGRPD
-       "Metric for redistributed routes\n"
-       "Bandwidth metric in Kbits per second\n"
-       "EIGRP delay metric, in 10 microsecond units\n"
-       "EIGRP reliability metric where 255 is 100% reliable2 ?\n"
-       "EIGRP Effective bandwidth metric (Loading) where 255 is 100% loaded\n"
-       "EIGRP MTU of the path\n")
-{
-       VTY_DECLVAR_CONTEXT(eigrp, eigrp);
-       struct eigrp_metrics metrics_from_command = {0};
-       int source;
-       int idx = 0;
-
-       /* Get distribute source. */
-       argv_find(argv, argc, "redistribute", &idx);
-       source = proto_redistnum(AFI_IP, argv[idx + 1]->text);
-       if (source < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Get metrics values */
-
-       return eigrp_redistribute_set(eigrp, source, metrics_from_command);
-}
-
-DEFUN (no_eigrp_redistribute_source_metric,
-       no_eigrp_redistribute_source_metric_cmd,
-       "no redistribute " FRR_REDIST_STR_EIGRPD
-       " [metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)]",
-       "Disable\n"
-       REDIST_STR
-       FRR_REDIST_HELP_STR_EIGRPD
-       "Metric for redistributed routes\n"
-       "Bandwidth metric in Kbits per second\n"
-       "EIGRP delay metric, in 10 microsecond units\n"
-       "EIGRP reliability metric where 255 is 100% reliable2 ?\n"
-       "EIGRP Effective bandwidth metric (Loading) where 255 is 100% loaded\n"
-       "EIGRP MTU of the path\n")
-{
-       VTY_DECLVAR_CONTEXT(eigrp, eigrp);
-       int source;
-       int idx = 0;
-
-       /* Get distribute source. */
-       argv_find(argv, argc, "redistribute", &idx);
-       source = proto_redistnum(AFI_IP, argv[idx + 1]->text);
-       if (source < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Get metrics values */
-
-       return eigrp_redistribute_unset(eigrp, source);
-}
-
-DEFUN (eigrp_variance,
-       eigrp_variance_cmd,
-       "variance (1-128)",
-       "Control load balancing variance\n"
-       "Metric variance multiplier\n")
-{
-       struct eigrp *eigrp;
-       uint8_t variance;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, "EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-       variance = atoi(argv[1]->arg);
-
-       eigrp->variance = variance;
-
-       /*TODO: */
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_variance,
-       no_eigrp_variance_cmd,
-       "no variance (1-128)",
-       "Disable\n"
-       "Control load balancing variance\n"
-       "Metric variance multiplier\n")
-{
-       struct eigrp *eigrp;
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, "EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       eigrp->variance = EIGRP_VARIANCE_DEFAULT;
-
-       /*TODO: */
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (eigrp_maximum_paths,
-       eigrp_maximum_paths_cmd,
-       "maximum-paths (1-32)",
-       "Forward packets over multiple paths\n"
-       "Number of paths\n")
-{
-       struct eigrp *eigrp;
-       uint8_t max;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, "EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       max = atoi(argv[1]->arg);
-
-       eigrp->max_paths = max;
-
-       /*TODO: */
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_eigrp_maximum_paths,
-       no_eigrp_maximum_paths_cmd,
-       "no maximum-paths (1-32)",
-       NO_STR
-       "Forward packets over multiple paths\n"
-       "Number of paths\n")
-{
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp == NULL) {
-               vty_out(vty, "EIGRP Routing Process not enabled\n");
-               return CMD_SUCCESS;
-       }
-
-       eigrp->max_paths = EIGRP_MAX_PATHS_DEFAULT;
-
-       /*TODO: */
-
-       return CMD_SUCCESS;
-}
-
 /*
  * Execute hard restart for all neighbors
  */
@@ -1492,40 +517,6 @@ DEFUN (clear_ip_eigrp_neighbors_IP_soft,
        return CMD_SUCCESS;
 }
 
-static struct cmd_node eigrp_node = {EIGRP_NODE, "%s(config-router)# ", 1};
-
-/* Save EIGRP configuration */
-static int eigrp_config_write(struct vty *vty)
-{
-       struct eigrp *eigrp;
-
-       eigrp = eigrp_lookup();
-       if (eigrp != NULL) {
-               /* Writes 'router eigrp' section to config */
-               config_write_eigrp_router(vty, eigrp);
-
-               /* Interface config print */
-               config_write_interfaces(vty, eigrp);
-               //
-               //      /* static neighbor print. */
-               //      config_write_eigrp_nbr_nbma (vty, eigrp);
-               //
-               //      /* Virtual-Link print. */
-               //      config_write_virtual_link (vty, eigrp);
-               //
-               //      /* Default metric configuration.  */
-               //      config_write_eigrp_default_metric (vty, eigrp);
-               //
-               //      /* Distribute-list and default-information print. */
-               //      config_write_eigrp_distribute (vty, eigrp);
-               //
-               //      /* Distance configuration. */
-               //      config_write_eigrp_distance (vty, eigrp)
-       }
-
-       return 0;
-}
-
 void eigrp_vty_show_init(void)
 {
        install_element(VIEW_NODE, &show_ip_eigrp_interfaces_cmd);
@@ -1536,69 +527,9 @@ void eigrp_vty_show_init(void)
        install_element(VIEW_NODE, &show_ip_eigrp_topology_all_cmd);
 }
 
-/* eigrpd's interface node. */
-static struct cmd_node eigrp_interface_node = {INTERFACE_NODE,
-                                              "%s(config-if)# ", 1};
-
-void eigrp_vty_if_init(void)
-{
-       install_node(&eigrp_interface_node, eigrp_write_interface);
-       if_cmd_init();
-
-       /* Delay and bandwidth configuration commands*/
-       install_element(INTERFACE_NODE, &eigrp_if_delay_cmd);
-       install_element(INTERFACE_NODE, &no_eigrp_if_delay_cmd);
-       install_element(INTERFACE_NODE, &eigrp_if_bandwidth_cmd);
-       install_element(INTERFACE_NODE, &no_eigrp_if_bandwidth_cmd);
-
-       /*Hello-interval and hold-time interval configuration commands*/
-       install_element(INTERFACE_NODE, &eigrp_if_ip_holdinterval_cmd);
-       install_element(INTERFACE_NODE, &no_eigrp_if_ip_holdinterval_cmd);
-       install_element(INTERFACE_NODE, &eigrp_if_ip_hellointerval_cmd);
-       install_element(INTERFACE_NODE, &no_eigrp_if_ip_hellointerval_cmd);
-
-       /* "Authentication configuration commands */
-       install_element(INTERFACE_NODE, &eigrp_authentication_mode_cmd);
-       install_element(INTERFACE_NODE, &no_eigrp_authentication_mode_cmd);
-       install_element(INTERFACE_NODE, &eigrp_authentication_keychain_cmd);
-
-       /*EIGRP Summarization commands*/
-       install_element(INTERFACE_NODE, &eigrp_ip_summary_address_cmd);
-       install_element(INTERFACE_NODE, &no_eigrp_ip_summary_address_cmd);
-}
-
-static void eigrp_vty_zebra_init(void)
-{
-       install_element(EIGRP_NODE, &eigrp_redistribute_source_metric_cmd);
-       install_element(EIGRP_NODE, &no_eigrp_redistribute_source_metric_cmd);
-}
-
 /* Install EIGRP related vty commands. */
 void eigrp_vty_init(void)
 {
-       install_node(&eigrp_node, eigrp_config_write);
-
-       install_default(EIGRP_NODE);
-
-       install_element(CONFIG_NODE, &router_eigrp_cmd);
-       install_element(CONFIG_NODE, &no_router_eigrp_cmd);
-       install_element(EIGRP_NODE, &eigrp_network_cmd);
-       install_element(EIGRP_NODE, &no_eigrp_network_cmd);
-       install_element(EIGRP_NODE, &eigrp_variance_cmd);
-       install_element(EIGRP_NODE, &no_eigrp_variance_cmd);
-       install_element(EIGRP_NODE, &eigrp_router_id_cmd);
-       install_element(EIGRP_NODE, &no_eigrp_router_id_cmd);
-       install_element(EIGRP_NODE, &eigrp_passive_interface_cmd);
-       install_element(EIGRP_NODE, &no_eigrp_passive_interface_cmd);
-       install_element(EIGRP_NODE, &eigrp_timers_active_cmd);
-       install_element(EIGRP_NODE, &no_eigrp_timers_active_cmd);
-       install_element(EIGRP_NODE, &eigrp_metric_weights_cmd);
-       install_element(EIGRP_NODE, &no_eigrp_metric_weights_cmd);
-       install_element(EIGRP_NODE, &eigrp_maximum_paths_cmd);
-       install_element(EIGRP_NODE, &no_eigrp_maximum_paths_cmd);
-       install_element(EIGRP_NODE, &eigrp_neighbor_cmd);
-       install_element(EIGRP_NODE, &no_eigrp_neighbor_cmd);
-
        /* commands for manual hard restart */
        install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_cmd);
        install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_int_cmd);
@@ -1607,6 +538,4 @@ void eigrp_vty_init(void)
        install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_soft_cmd);
        install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_int_soft_cmd);
        install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_IP_soft_cmd);
-
-       eigrp_vty_zebra_init();
 }
index 3fbadf6dfbe200f1f12b080dae454702c47e5468..ebbf503857deba628c272dd63342a0bcd4b2af60 100644 (file)
@@ -35,6 +35,5 @@
 /* Prototypes. */
 extern void eigrp_vty_init(void);
 extern void eigrp_vty_show_init(void);
-extern void eigrp_vty_if_init(void);
 
 #endif /* _Quagga_EIGRP_VTY_H_ */
index de7c881ac01556f5ff71487987397aa57aef2989..3ef3a9c0ccef410431cd354baba15c365544ca45 100644 (file)
@@ -52,4 +52,51 @@ extern struct eigrp *eigrp_get(const char *);
 extern struct eigrp *eigrp_lookup(void);
 extern void eigrp_router_id_update(struct eigrp *);
 
+/* eigrp_cli.c */
+extern void eigrp_cli_show_header(struct vty *vty, struct lyd_node *dnode,
+                                 bool show_defaults);
+extern void eigrp_cli_show_end_header(struct vty *vty, struct lyd_node *dnode);
+extern void eigrp_cli_show_router_id(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults);
+extern void eigrp_cli_show_passive_interface(struct vty *vty,
+                                            struct lyd_node *dnode,
+                                            bool show_defaults);
+extern void eigrp_cli_show_active_time(struct vty *vty, struct lyd_node *dnode,
+                                      bool show_defaults);
+extern void eigrp_cli_show_variance(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+extern void eigrp_cli_show_maximum_paths(struct vty *vty,
+                                        struct lyd_node *dnode,
+                                        bool show_defaults);
+extern void eigrp_cli_show_metrics(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults);
+extern void eigrp_cli_show_network(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults);
+extern void eigrp_cli_show_neighbor(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+extern void eigrp_cli_show_redistribute(struct vty *vty,
+                                       struct lyd_node *dnode,
+                                       bool show_defaults);
+extern void eigrp_cli_show_delay(struct vty *vty, struct lyd_node *dnode,
+                                bool show_defaults);
+extern void eigrp_cli_show_bandwidth(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults);
+extern void eigrp_cli_show_hello_interval(struct vty *vty,
+                                         struct lyd_node *dnode,
+                                         bool show_defaults);
+extern void eigrp_cli_show_hold_time(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults);
+extern void eigrp_cli_show_summarize_address(struct vty *vty,
+                                            struct lyd_node *dnode,
+                                            bool show_defaults);
+extern void eigrp_cli_show_authentication(struct vty *vty,
+                                         struct lyd_node *dnode,
+                                         bool show_defaults);
+extern void eigrp_cli_show_keychain(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+extern void eigrp_cli_init(void);
+
+/* eigrp_northbound.c */
+extern const struct frr_yang_module_info frr_eigrpd_info;
+
 #endif /* _ZEBRA_EIGRPD_H */
index 4503030fdfe854762802a85bb54fd2d9c8d8e779..cc4676658630f50dad8f9c5d1d3255df32230fdc 100644 (file)
@@ -7,6 +7,7 @@ noinst_LIBRARIES += eigrpd/libeigrp.a
 sbin_PROGRAMS += eigrpd/eigrpd
 dist_examples_DATA += eigrpd/eigrpd.conf.sample
 vtysh_scan += \
+       $(top_srcdir)/eigrpd/eigrp_cli.c \
        $(top_srcdir)/eigrpd/eigrp_dump.c \
        $(top_srcdir)/eigrpd/eigrp_vty.c \
        # end
@@ -15,6 +16,7 @@ man8 += $(MANBUILD)/eigrpd.8
 endif
 
 eigrpd_libeigrp_a_SOURCES = \
+       eigrpd/eigrp_cli.c \
        eigrpd/eigrp_dump.c \
        eigrpd/eigrp_errors.c \
        eigrpd/eigrp_filter.c \
@@ -24,6 +26,7 @@ eigrpd_libeigrp_a_SOURCES = \
        eigrpd/eigrp_memory.c \
        eigrpd/eigrp_neighbor.c \
        eigrpd/eigrp_network.c \
+       eigrpd/eigrp_northbound.c \
        eigrpd/eigrp_packet.c \
        eigrpd/eigrp_query.c \
        eigrpd/eigrp_reply.c \
@@ -47,6 +50,9 @@ eigrpdheader_HEADERS = \
 eigrpd/eigrp_vty_clippy.c: $(CLIPPY_DEPS)
 eigrpd/eigrp_vty.$(OBJEXT): eigrpd/eigrp_vty_clippy.c
 
+eigrpd/eigrp_cli_clippy.c: $(CLIPPY_DEPS)
+eigrpd/eigrp_cli.$(OBJEXT): eigrpd/eigrp_cli_clippy.c
+
 noinst_HEADERS += \
        eigrpd/eigrp_const.h \
        eigrpd/eigrp_errors.h \
@@ -64,5 +70,9 @@ noinst_HEADERS += \
        eigrpd/eigrp_zebra.h \
        # end
 
+nodist_eigrpd_eigrpd_SOURCES = \
+       yang/frr-eigrpd.yang.c \
+       # end
+
 eigrpd_eigrpd_SOURCES = eigrpd/eigrp_main.c
 eigrpd_eigrpd_LDADD = eigrpd/libeigrp.a lib/libfrr.la $(LIBCAP)
index 4b3baeea9dcfa3ef467fcd44924e131f489bed0e..18d2bf160cb1855492dbb3e657ff89e6dfc2e2e1 100644 (file)
@@ -28,6 +28,10 @@ if BFDD
 dist_yangmodels_DATA += yang/frr-bfdd.yang
 endif
 
+if EIGRPD
+dist_yangmodels_DATA += yang/frr-eigrpd.yang
+endif
+
 if RIPD
 dist_yangmodels_DATA += yang/frr-ripd.yang
 endif