summaryrefslogtreecommitdiff
path: root/eigrpd/eigrp_cli.c
diff options
context:
space:
mode:
authorRafael Zalamena <rzalamena@opensourcerouting.org>2019-07-30 12:44:13 -0300
committerRafael Zalamena <rzalamena@opensourcerouting.org>2019-08-03 14:52:45 -0300
commitf25c244b7502f2fa61f143b514eef8f6b9e24355 (patch)
tree958c2e80d4f37fd8b7de604ed9d3d70e3cae1c25 /eigrpd/eigrp_cli.c
parent9008789aa429abac9738c4b361f0c5ebf37f2550 (diff)
eigrpd: migrate old CLI to northbound
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>
Diffstat (limited to 'eigrpd/eigrp_cli.c')
-rw-r--r--eigrpd/eigrp_cli.c920
1 files changed, 920 insertions, 0 deletions
diff --git a/eigrpd/eigrp_cli.c b/eigrpd/eigrp_cli.c
new file mode 100644
index 0000000000..ba657a7d5d
--- /dev/null
+++ b/eigrpd/eigrp_cli.c
@@ -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);
+}