3 * Copyright (C) 2013-2016
15 * This file is part of GNU Zebra.
17 * GNU Zebra is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2, or (at your option) any
22 * GNU Zebra is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * General Public License for more details.
27 * You should have received a copy of the GNU General Public License along
28 * with this program; see the file COPYING; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
45 #include "distribute.h"
47 #include "eigrpd/eigrp_structs.h"
48 #include "eigrpd/eigrpd.h"
49 #include "eigrpd/eigrp_interface.h"
50 #include "eigrpd/eigrp_neighbor.h"
51 #include "eigrpd/eigrp_packet.h"
52 #include "eigrpd/eigrp_zebra.h"
53 #include "eigrpd/eigrp_vty.h"
54 #include "eigrpd/eigrp_network.h"
55 #include "eigrpd/eigrp_dump.h"
56 #include "eigrpd/eigrp_const.h"
58 #ifndef VTYSH_EXTRACT_PL
59 #include "eigrpd/eigrp_vty_clippy.c"
62 static void eigrp_vty_display_prefix_entry(struct vty
*vty
,
64 struct eigrp_prefix_entry
*pe
,
68 struct eigrp_nexthop_entry
*te
;
69 struct listnode
*node
;
71 for (ALL_LIST_ELEMENTS_RO(pe
->entries
, node
, te
)) {
74 & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG
)
75 == EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG
)
77 & EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG
)
78 == EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG
))) {
79 show_ip_eigrp_nexthop_entry(vty
, eigrp
, te
,
86 static struct eigrp
*eigrp_vty_get_eigrp(struct vty
*vty
, const char *vrf_name
)
91 vrf
= vrf_lookup_by_name(vrf_name
);
93 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
96 vty_out(vty
, "VRF %s specified does not exist",
97 vrf_name
? vrf_name
: VRF_DEFAULT_NAME
);
101 return eigrp_lookup(vrf
->vrf_id
);
104 static void eigrp_topology_helper(struct vty
*vty
, struct eigrp
*eigrp
,
107 struct eigrp_prefix_entry
*tn
;
108 struct route_node
*rn
;
110 show_ip_eigrp_topology_header(vty
, eigrp
);
112 for (rn
= route_top(eigrp
->topology_table
); rn
; rn
= route_next(rn
)) {
117 eigrp_vty_display_prefix_entry(vty
, eigrp
, tn
,
122 DEFPY (show_ip_eigrp_topology_all
,
123 show_ip_eigrp_topology_all_cmd
,
124 "show ip eigrp [vrf NAME] topology [all-links$all]",
127 "IP-EIGRP show commands\n"
129 "IP-EIGRP topology\n"
130 "Show all links in topology table\n")
134 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
137 RB_FOREACH (v
, vrf_name_head
, &vrfs_by_name
) {
138 eigrp
= eigrp_lookup(v
->vrf_id
);
142 vty_out(vty
, "VRF %s:\n", v
->name
);
144 eigrp_topology_helper(vty
, eigrp
, all
);
147 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
149 vty_out(vty
, " EIGRP Routing Process not enabled\n");
153 eigrp_topology_helper(vty
, eigrp
, all
);
159 DEFPY (show_ip_eigrp_topology
,
160 show_ip_eigrp_topology_cmd
,
161 "show ip eigrp [vrf NAME] topology <A.B.C.D$address|A.B.C.D/M$prefix>",
164 "IP-EIGRP show commands\n"
166 "IP-EIGRP topology\n"
167 "For a specific address\n"
168 "For a specific prefix\n")
171 struct eigrp_prefix_entry
*tn
;
172 struct route_node
*rn
;
175 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
176 vty_out(vty
, "Specifying vrf `all` for a particular address/prefix makes no sense\n");
180 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
182 vty_out(vty
, " EIGRP Routing Process not enabled\n");
186 show_ip_eigrp_topology_header(vty
, eigrp
);
189 prefix_str
= address_str
;
191 if (str2prefix(prefix_str
, &cmp
) < 0) {
192 vty_out(vty
, "%% Malformed address\n");
196 rn
= route_node_match(eigrp
->topology_table
, &cmp
);
198 vty_out(vty
, "%% Network not in table\n");
203 vty_out(vty
, "%% Network not in table\n");
204 route_unlock_node(rn
);
209 eigrp_vty_display_prefix_entry(vty
, eigrp
, tn
, argc
== 5);
211 route_unlock_node(rn
);
215 static void eigrp_interface_helper(struct vty
*vty
, struct eigrp
*eigrp
,
216 const char *ifname
, const char *detail
)
218 struct eigrp_interface
*ei
;
219 struct listnode
*node
;
222 show_ip_eigrp_interface_header(vty
, eigrp
);
224 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
225 if (!ifname
|| strcmp(ei
->ifp
->name
, ifname
) == 0) {
226 show_ip_eigrp_interface_sub(vty
, eigrp
, ei
);
228 show_ip_eigrp_interface_detail(vty
, eigrp
, ei
);
233 DEFPY (show_ip_eigrp_interfaces
,
234 show_ip_eigrp_interfaces_cmd
,
235 "show ip eigrp [vrf NAME] interfaces [IFNAME] [detail]$detail",
238 "IP-EIGRP show commands\n"
240 "IP-EIGRP interfaces\n"
241 "Interface name to look at\n"
242 "Detailed information\n")
246 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
249 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
250 eigrp
= eigrp_lookup(vrf
->vrf_id
);
254 vty_out(vty
, "VRF %s:\n", vrf
->name
);
256 eigrp_interface_helper(vty
, eigrp
, ifname
, detail
);
259 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
261 vty_out(vty
, "EIGRP Routing Process not enabled\n");
265 eigrp_interface_helper(vty
, eigrp
, ifname
, detail
);
272 static void eigrp_neighbors_helper(struct vty
*vty
, struct eigrp
*eigrp
,
273 const char *ifname
, const char *detail
)
275 struct eigrp_interface
*ei
;
276 struct listnode
*node
, *node2
, *nnode2
;
277 struct eigrp_neighbor
*nbr
;
279 show_ip_eigrp_neighbor_header(vty
, eigrp
);
281 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
282 if (!ifname
|| strcmp(ei
->ifp
->name
, ifname
) == 0) {
283 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
284 if (detail
|| (nbr
->state
== EIGRP_NEIGHBOR_UP
))
285 show_ip_eigrp_neighbor_sub(vty
, nbr
,
292 DEFPY (show_ip_eigrp_neighbors
,
293 show_ip_eigrp_neighbors_cmd
,
294 "show ip eigrp [vrf NAME] neighbors [IFNAME] [detail]$detail",
297 "IP-EIGRP show commands\n"
299 "IP-EIGRP neighbors\n"
300 "Interface to show on\n"
301 "Detailed Information\n")
305 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
308 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
309 eigrp
= eigrp_lookup(vrf
->vrf_id
);
313 vty_out(vty
, "VRF %s:\n", vrf
->name
);
315 eigrp_neighbors_helper(vty
, eigrp
, ifname
, detail
);
318 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
320 vty_out(vty
, " EIGRP Routing Process not enabled\n");
324 eigrp_neighbors_helper(vty
, eigrp
, ifname
, detail
);
331 * Execute hard restart for all neighbors
333 DEFPY (clear_ip_eigrp_neighbors
,
334 clear_ip_eigrp_neighbors_cmd
,
335 "clear ip eigrp [vrf NAME] neighbors",
340 "Clear IP-EIGRP neighbors\n")
343 struct eigrp_interface
*ei
;
344 struct listnode
*node
, *node2
, *nnode2
;
345 struct eigrp_neighbor
*nbr
;
347 /* Check if eigrp process is enabled */
348 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
350 vty_out(vty
, " EIGRP Routing Process not enabled\n");
354 /* iterate over all eigrp interfaces */
355 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
356 /* send Goodbye Hello */
357 eigrp_hello_send(ei
, EIGRP_HELLO_GRACEFUL_SHUTDOWN
, NULL
);
359 /* iterate over all neighbors on eigrp interface */
360 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
361 if (nbr
->state
!= EIGRP_NEIGHBOR_DOWN
) {
363 "Neighbor %s (%s) is down: manually cleared",
365 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
367 vty_time_print(vty
, 0);
369 "Neighbor %s (%s) is down: manually cleared\n",
371 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
374 /* set neighbor to DOWN */
375 nbr
->state
= EIGRP_NEIGHBOR_DOWN
;
376 /* delete neighbor */
377 eigrp_nbr_delete(nbr
);
386 * Execute hard restart for all neighbors on interface
388 DEFPY (clear_ip_eigrp_neighbors_int
,
389 clear_ip_eigrp_neighbors_int_cmd
,
390 "clear ip eigrp [vrf NAME] neighbors IFNAME",
395 "Clear IP-EIGRP neighbors\n"
396 "Interface's name\n")
399 struct eigrp_interface
*ei
;
400 struct listnode
*node2
, *nnode2
;
401 struct eigrp_neighbor
*nbr
;
403 /* Check if eigrp process is enabled */
404 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
406 vty_out(vty
, " EIGRP Routing Process not enabled\n");
410 /* lookup interface by specified name */
411 ei
= eigrp_if_lookup_by_name(eigrp
, ifname
);
413 vty_out(vty
, " Interface (%s) doesn't exist\n", ifname
);
417 /* send Goodbye Hello */
418 eigrp_hello_send(ei
, EIGRP_HELLO_GRACEFUL_SHUTDOWN
, NULL
);
420 /* iterate over all neighbors on eigrp interface */
421 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
422 if (nbr
->state
!= EIGRP_NEIGHBOR_DOWN
) {
423 zlog_debug("Neighbor %s (%s) is down: manually cleared",
425 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
427 vty_time_print(vty
, 0);
429 "Neighbor %s (%s) is down: manually cleared\n",
431 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
434 /* set neighbor to DOWN */
435 nbr
->state
= EIGRP_NEIGHBOR_DOWN
;
436 /* delete neighbor */
437 eigrp_nbr_delete(nbr
);
445 * Execute hard restart for neighbor specified by IP
447 DEFPY (clear_ip_eigrp_neighbors_IP
,
448 clear_ip_eigrp_neighbors_IP_cmd
,
449 "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr",
454 "Clear IP-EIGRP neighbors\n"
455 "IP-EIGRP neighbor address\n")
458 struct eigrp_neighbor
*nbr
;
460 /* Check if eigrp process is enabled */
461 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
463 vty_out(vty
, " EIGRP Routing Process not enabled\n");
467 /* lookup neighbor in whole process */
468 nbr
= eigrp_nbr_lookup_by_addr_process(eigrp
, nbr_addr
);
470 /* if neighbor doesn't exists, notify user and exit */
472 vty_out(vty
, "Neighbor with entered address doesn't exists.\n");
476 /* execute hard reset on neighbor */
477 eigrp_nbr_hard_restart(nbr
, vty
);
483 * Execute graceful restart for all neighbors
485 DEFPY (clear_ip_eigrp_neighbors_soft
,
486 clear_ip_eigrp_neighbors_soft_cmd
,
487 "clear ip eigrp [vrf NAME] neighbors soft",
492 "Clear IP-EIGRP neighbors\n"
493 "Resync with peers without adjacency reset\n")
497 /* Check if eigrp process is enabled */
498 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
500 vty_out(vty
, " EIGRP Routing Process not enabled\n");
504 /* execute graceful restart on all neighbors */
505 eigrp_update_send_process_GR(eigrp
, EIGRP_GR_MANUAL
, vty
);
511 * Execute graceful restart for all neighbors on interface
513 DEFPY (clear_ip_eigrp_neighbors_int_soft
,
514 clear_ip_eigrp_neighbors_int_soft_cmd
,
515 "clear ip eigrp [vrf NAME] neighbors IFNAME soft",
520 "Clear IP-EIGRP neighbors\n"
522 "Resync with peer without adjacency reset\n")
525 struct eigrp_interface
*ei
;
527 /* Check if eigrp process is enabled */
528 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
530 vty_out(vty
, " EIGRP Routing Process not enabled\n");
534 /* lookup interface by specified name */
535 ei
= eigrp_if_lookup_by_name(eigrp
, ifname
);
537 vty_out(vty
, " Interface (%s) doesn't exist\n", argv
[4]->arg
);
541 /* execute graceful restart for all neighbors on interface */
542 eigrp_update_send_interface_GR(ei
, EIGRP_GR_MANUAL
, vty
);
547 * Execute graceful restart for neighbor specified by IP
549 DEFPY (clear_ip_eigrp_neighbors_IP_soft
,
550 clear_ip_eigrp_neighbors_IP_soft_cmd
,
551 "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr soft",
556 "Clear IP-EIGRP neighbors\n"
557 "IP-EIGRP neighbor address\n"
558 "Resync with peer without adjacency reset\n")
561 struct eigrp_neighbor
*nbr
;
564 /* Check if eigrp process is enabled */
565 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
567 vty_out(vty
, " EIGRP Routing Process not enabled\n");
571 /* lookup neighbor in whole process */
572 nbr
= eigrp_nbr_lookup_by_addr_process(eigrp
, nbr_addr
);
574 /* if neighbor doesn't exists, notify user and exit */
576 vty_out(vty
, "Neighbor with entered address doesn't exists.\n");
580 /* execute graceful restart on neighbor */
581 eigrp_update_send_GR(nbr
, EIGRP_GR_MANUAL
, vty
);
586 void eigrp_vty_show_init(void)
588 install_element(VIEW_NODE
, &show_ip_eigrp_interfaces_cmd
);
590 install_element(VIEW_NODE
, &show_ip_eigrp_neighbors_cmd
);
592 install_element(VIEW_NODE
, &show_ip_eigrp_topology_cmd
);
593 install_element(VIEW_NODE
, &show_ip_eigrp_topology_all_cmd
);
596 /* Install EIGRP related vty commands. */
597 void eigrp_vty_init(void)
599 /* commands for manual hard restart */
600 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_cmd
);
601 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_int_cmd
);
602 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_IP_cmd
);
603 /* commands for manual graceful restart */
604 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_soft_cmd
);
605 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_int_soft_cmd
);
606 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_IP_soft_cmd
);