/* * 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" #include "eigrp_cli.h" #ifndef VTYSH_EXTRACT_PL #include "eigrpd/eigrp_cli_clippy.c" #endif /* VTYSH_EXTRACT_PL */ /* * XPath: /frr-eigrpd:eigrpd/instance */ DEFPY_YANG_NOSH( router_eigrp, router_eigrp_cmd, "router eigrp (1-65535)$as [vrf NAME]", ROUTER_STR EIGRP_STR AS_STR VRF_CMD_HELP_STR) { char xpath[XPATH_MAXLEN]; int rv; snprintf(xpath, sizeof(xpath), "/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='%s']", as_str, vrf ? vrf : VRF_DEFAULT_NAME); 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_YANG( no_router_eigrp, no_router_eigrp_cmd, "no router eigrp (1-65535)$as [vrf NAME]", NO_STR ROUTER_STR EIGRP_STR AS_STR VRF_CMD_HELP_STR) { char xpath[XPATH_MAXLEN]; snprintf(xpath, sizeof(xpath), "/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='%s']", as_str, vrf ? vrf : VRF_DEFAULT_NAME); 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"); const char *vrf = yang_dnode_get_string(dnode, "./vrf"); vty_out(vty, "router eigrp %s", asn); if (strcmp(vrf, VRF_DEFAULT_NAME)) vty_out(vty, " vrf %s", vrf); vty_out(vty, "\n"); } 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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_YANG( 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-addresses", xpath); nb_cli_enqueue_change(vty, xpath_auth, NB_OP_CREATE, prefix_str); return nb_cli_apply_changes(vty, NULL); } DEFPY_YANG( 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-addresses", 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 lyd_node *instance = yang_dnode_get_parent(dnode, "instance"); uint16_t asn = yang_dnode_get_uint16(instance, "./asn"); const char *summarize_address = yang_dnode_get_string(dnode, NULL); vty_out(vty, " ip summary-address eigrp %d %s\n", asn, summarize_address); } /* * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication */ DEFPY_YANG( 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_YANG( 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 lyd_node *instance = yang_dnode_get_parent(dnode, "instance"); uint16_t asn = yang_dnode_get_uint16(instance, "./asn"); const char *crypt = yang_dnode_get_string(dnode, NULL); vty_out(vty, " ip authentication mode eigrp %d %s\n", asn, crypt); } /* * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/keychain */ DEFPY_YANG( 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_YANG( 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 lyd_node *instance = yang_dnode_get_parent(dnode, "instance"); uint16_t asn = yang_dnode_get_uint16(instance, "./asn"); const char *keychain = yang_dnode_get_string(dnode, NULL); vty_out(vty, " ip authentication key-chain eigrp %d %s\n", asn, keychain); } /* * CLI installation procedures. */ static int eigrp_config_write(struct vty *vty); static struct cmd_node eigrp_node = { .name = "eigrp", .node = EIGRP_NODE, .parent_node = CONFIG_NODE, .prompt = "%s(config-router)# ", .config_write = eigrp_config_write, }; 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 int eigrp_write_interface(struct vty *vty); static struct cmd_node eigrp_interface_node = { .name = "interface", .node = INTERFACE_NODE, .parent_node = CONFIG_NODE, .prompt = "%s(config-if)# ", .config_write = eigrp_write_interface, }; 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); 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); 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); }