diff options
| author | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2019-07-30 12:44:13 -0300 | 
|---|---|---|
| committer | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2019-08-03 14:52:45 -0300 | 
| commit | f25c244b7502f2fa61f143b514eef8f6b9e24355 (patch) | |
| tree | 958c2e80d4f37fd8b7de604ed9d3d70e3cae1c25 /eigrpd/eigrp_cli.c | |
| parent | 9008789aa429abac9738c4b361f0c5ebf37f2550 (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.c | 920 | 
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); +}  | 
