From f25c244b7502f2fa61f143b514eef8f6b9e24355 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Tue, 30 Jul 2019 12:44:13 -0300 Subject: [PATCH] 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 --- eigrpd/eigrp_cli.c | 920 +++++++++++++++++++++ eigrpd/eigrp_main.c | 3 +- eigrpd/eigrp_northbound.c | 1584 +++++++++++++++++++++++++++++++++++++ eigrpd/eigrp_vty.c | 1071 ------------------------- eigrpd/eigrp_vty.h | 1 - eigrpd/eigrpd.h | 47 ++ eigrpd/subdir.am | 10 + yang/subdir.am | 4 + 8 files changed, 2567 insertions(+), 1073 deletions(-) create mode 100644 eigrpd/eigrp_cli.c create mode 100644 eigrpd/eigrp_northbound.c 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 + +#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 /, 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 /, 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 $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 []", + 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); +} diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c index 3db59a838b..12dbdca828 100644 --- a/eigrpd/eigrp_main.c +++ b/eigrpd/eigrp_main.c @@ -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 index 0000000000..5f0c91809e --- /dev/null +++ b/eigrpd/eigrp_northbound.c @@ -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 + +#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, + }, + } +}; diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index d51faaac59..207622e659 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -59,402 +59,6 @@ #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 /, 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 /, 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) ", - "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) ", - "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(); } diff --git a/eigrpd/eigrp_vty.h b/eigrpd/eigrp_vty.h index 3fbadf6dfb..ebbf503857 100644 --- a/eigrpd/eigrp_vty.h +++ b/eigrpd/eigrp_vty.h @@ -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_ */ diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h index de7c881ac0..3ef3a9c0cc 100644 --- a/eigrpd/eigrpd.h +++ b/eigrpd/eigrpd.h @@ -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 */ diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index 4503030fdf..cc46766586 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -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) diff --git a/yang/subdir.am b/yang/subdir.am index 4b3baeea9d..18d2bf160c 100644 --- a/yang/subdir.am +++ b/yang/subdir.am @@ -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