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 #include "eigrpd/eigrp_vty_clippy.c"
60 static void eigrp_vty_display_prefix_entry(struct vty
*vty
, struct eigrp
*eigrp
,
61 struct eigrp_prefix_descriptor
*pe
,
65 struct eigrp_route_descriptor
*te
;
66 struct listnode
*node
;
68 for (ALL_LIST_ELEMENTS_RO(pe
->entries
, node
, te
)) {
70 || (((te
->flags
& EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG
)
71 == EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG
)
72 || ((te
->flags
& EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG
)
73 == EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG
))) {
74 show_ip_eigrp_route_descriptor(vty
, eigrp
, te
, &first
);
80 static struct eigrp
*eigrp_vty_get_eigrp(struct vty
*vty
, const char *vrf_name
)
85 vrf
= vrf_lookup_by_name(vrf_name
);
87 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
90 vty_out(vty
, "VRF %s specified does not exist",
91 vrf_name
? vrf_name
: VRF_DEFAULT_NAME
);
95 return eigrp_lookup(vrf
->vrf_id
);
98 static void eigrp_topology_helper(struct vty
*vty
, struct eigrp
*eigrp
,
101 struct eigrp_prefix_descriptor
*tn
;
102 struct route_node
*rn
;
104 show_ip_eigrp_topology_header(vty
, eigrp
);
106 for (rn
= route_top(eigrp
->topology_table
); rn
; rn
= route_next(rn
)) {
111 eigrp_vty_display_prefix_entry(vty
, eigrp
, tn
,
116 DEFPY (show_ip_eigrp_topology_all
,
117 show_ip_eigrp_topology_all_cmd
,
118 "show ip eigrp [vrf NAME] topology [all-links$all]",
121 "IP-EIGRP show commands\n"
123 "IP-EIGRP topology\n"
124 "Show all links in topology table\n")
128 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
131 RB_FOREACH (v
, vrf_name_head
, &vrfs_by_name
) {
132 eigrp
= eigrp_lookup(v
->vrf_id
);
136 vty_out(vty
, "VRF %s:\n", v
->name
);
138 eigrp_topology_helper(vty
, eigrp
, all
);
141 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
143 vty_out(vty
, " EIGRP Routing Process not enabled\n");
147 eigrp_topology_helper(vty
, eigrp
, all
);
153 DEFPY (show_ip_eigrp_topology
,
154 show_ip_eigrp_topology_cmd
,
155 "show ip eigrp [vrf NAME] topology <A.B.C.D$address|A.B.C.D/M$prefix>",
158 "IP-EIGRP show commands\n"
160 "IP-EIGRP topology\n"
161 "For a specific address\n"
162 "For a specific prefix\n")
165 struct eigrp_prefix_descriptor
*tn
;
166 struct route_node
*rn
;
169 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
170 vty_out(vty
, "Specifying vrf `all` for a particular address/prefix makes no sense\n");
174 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
176 vty_out(vty
, " EIGRP Routing Process not enabled\n");
180 show_ip_eigrp_topology_header(vty
, eigrp
);
183 prefix_str
= address_str
;
185 if (str2prefix(prefix_str
, &cmp
) < 0) {
186 vty_out(vty
, "%% Malformed address\n");
190 rn
= route_node_match(eigrp
->topology_table
, &cmp
);
192 vty_out(vty
, "%% Network not in table\n");
197 vty_out(vty
, "%% Network not in table\n");
198 route_unlock_node(rn
);
203 eigrp_vty_display_prefix_entry(vty
, eigrp
, tn
, argc
== 5);
205 route_unlock_node(rn
);
209 static void eigrp_interface_helper(struct vty
*vty
, struct eigrp
*eigrp
,
210 const char *ifname
, const char *detail
)
212 struct eigrp_interface
*ei
;
213 struct listnode
*node
;
216 show_ip_eigrp_interface_header(vty
, eigrp
);
218 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
219 if (!ifname
|| strcmp(ei
->ifp
->name
, ifname
) == 0) {
220 show_ip_eigrp_interface_sub(vty
, eigrp
, ei
);
222 show_ip_eigrp_interface_detail(vty
, eigrp
, ei
);
227 DEFPY (show_ip_eigrp_interfaces
,
228 show_ip_eigrp_interfaces_cmd
,
229 "show ip eigrp [vrf NAME] interfaces [IFNAME] [detail]$detail",
232 "IP-EIGRP show commands\n"
234 "IP-EIGRP interfaces\n"
235 "Interface name to look at\n"
236 "Detailed information\n")
240 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
243 RB_FOREACH (v
, vrf_name_head
, &vrfs_by_name
) {
244 eigrp
= eigrp_lookup(v
->vrf_id
);
248 vty_out(vty
, "VRF %s:\n", v
->name
);
250 eigrp_interface_helper(vty
, eigrp
, ifname
, detail
);
253 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
255 vty_out(vty
, "EIGRP Routing Process not enabled\n");
259 eigrp_interface_helper(vty
, eigrp
, ifname
, detail
);
266 static void eigrp_neighbors_helper(struct vty
*vty
, struct eigrp
*eigrp
,
267 const char *ifname
, const char *detail
)
269 struct eigrp_interface
*ei
;
270 struct listnode
*node
, *node2
, *nnode2
;
271 struct eigrp_neighbor
*nbr
;
273 show_ip_eigrp_neighbor_header(vty
, eigrp
);
275 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
276 if (!ifname
|| strcmp(ei
->ifp
->name
, ifname
) == 0) {
277 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
278 if (detail
|| (nbr
->state
== EIGRP_NEIGHBOR_UP
))
279 show_ip_eigrp_neighbor_sub(vty
, nbr
,
286 DEFPY (show_ip_eigrp_neighbors
,
287 show_ip_eigrp_neighbors_cmd
,
288 "show ip eigrp [vrf NAME] neighbors [IFNAME] [detail]$detail",
291 "IP-EIGRP show commands\n"
293 "IP-EIGRP neighbors\n"
294 "Interface to show on\n"
295 "Detailed Information\n")
299 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
302 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
303 eigrp
= eigrp_lookup(vrf
->vrf_id
);
307 vty_out(vty
, "VRF %s:\n", vrf
->name
);
309 eigrp_neighbors_helper(vty
, eigrp
, ifname
, detail
);
312 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
314 vty_out(vty
, " EIGRP Routing Process not enabled\n");
318 eigrp_neighbors_helper(vty
, eigrp
, ifname
, detail
);
325 * Execute hard restart for all neighbors
327 DEFPY (clear_ip_eigrp_neighbors
,
328 clear_ip_eigrp_neighbors_cmd
,
329 "clear ip eigrp [vrf NAME] neighbors",
334 "Clear IP-EIGRP neighbors\n")
337 struct eigrp_interface
*ei
;
338 struct listnode
*node
, *node2
, *nnode2
;
339 struct eigrp_neighbor
*nbr
;
341 /* Check if eigrp process is enabled */
342 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
344 vty_out(vty
, " EIGRP Routing Process not enabled\n");
348 /* iterate over all eigrp interfaces */
349 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
350 /* send Goodbye Hello */
351 eigrp_hello_send(ei
, EIGRP_HELLO_GRACEFUL_SHUTDOWN
, NULL
);
353 /* iterate over all neighbors on eigrp interface */
354 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
355 if (nbr
->state
!= EIGRP_NEIGHBOR_DOWN
) {
357 "Neighbor %pI4 (%s) is down: manually cleared",
359 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
361 vty_time_print(vty
, 0);
363 "Neighbor %pI4 (%s) is down: manually cleared\n",
365 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
368 /* set neighbor to DOWN */
369 nbr
->state
= EIGRP_NEIGHBOR_DOWN
;
370 /* delete neighbor */
371 eigrp_nbr_delete(nbr
);
380 * Execute hard restart for all neighbors on interface
382 DEFPY (clear_ip_eigrp_neighbors_int
,
383 clear_ip_eigrp_neighbors_int_cmd
,
384 "clear ip eigrp [vrf NAME] neighbors IFNAME",
389 "Clear IP-EIGRP neighbors\n"
390 "Interface's name\n")
393 struct eigrp_interface
*ei
;
394 struct listnode
*node2
, *nnode2
;
395 struct eigrp_neighbor
*nbr
;
397 /* Check if eigrp process is enabled */
398 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
400 vty_out(vty
, " EIGRP Routing Process not enabled\n");
404 /* lookup interface by specified name */
405 ei
= eigrp_if_lookup_by_name(eigrp
, ifname
);
407 vty_out(vty
, " Interface (%s) doesn't exist\n", ifname
);
411 /* send Goodbye Hello */
412 eigrp_hello_send(ei
, EIGRP_HELLO_GRACEFUL_SHUTDOWN
, NULL
);
414 /* iterate over all neighbors on eigrp interface */
415 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
416 if (nbr
->state
!= EIGRP_NEIGHBOR_DOWN
) {
418 "Neighbor %pI4 (%s) is down: manually cleared",
420 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
422 vty_time_print(vty
, 0);
424 "Neighbor %pI4 (%s) is down: manually cleared\n",
426 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
429 /* set neighbor to DOWN */
430 nbr
->state
= EIGRP_NEIGHBOR_DOWN
;
431 /* delete neighbor */
432 eigrp_nbr_delete(nbr
);
440 * Execute hard restart for neighbor specified by IP
442 DEFPY (clear_ip_eigrp_neighbors_IP
,
443 clear_ip_eigrp_neighbors_IP_cmd
,
444 "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr",
449 "Clear IP-EIGRP neighbors\n"
450 "IP-EIGRP neighbor address\n")
453 struct eigrp_neighbor
*nbr
;
455 /* Check if eigrp process is enabled */
456 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
458 vty_out(vty
, " EIGRP Routing Process not enabled\n");
462 /* lookup neighbor in whole process */
463 nbr
= eigrp_nbr_lookup_by_addr_process(eigrp
, nbr_addr
);
465 /* if neighbor doesn't exists, notify user and exit */
467 vty_out(vty
, "Neighbor with entered address doesn't exists.\n");
471 /* execute hard reset on neighbor */
472 eigrp_nbr_hard_restart(nbr
, vty
);
478 * Execute graceful restart for all neighbors
480 DEFPY (clear_ip_eigrp_neighbors_soft
,
481 clear_ip_eigrp_neighbors_soft_cmd
,
482 "clear ip eigrp [vrf NAME] neighbors soft",
487 "Clear IP-EIGRP neighbors\n"
488 "Resync with peers without adjacency reset\n")
492 /* Check if eigrp process is enabled */
493 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
495 vty_out(vty
, " EIGRP Routing Process not enabled\n");
499 /* execute graceful restart on all neighbors */
500 eigrp_update_send_process_GR(eigrp
, EIGRP_GR_MANUAL
, vty
);
506 * Execute graceful restart for all neighbors on interface
508 DEFPY (clear_ip_eigrp_neighbors_int_soft
,
509 clear_ip_eigrp_neighbors_int_soft_cmd
,
510 "clear ip eigrp [vrf NAME] neighbors IFNAME soft",
515 "Clear IP-EIGRP neighbors\n"
517 "Resync with peer without adjacency reset\n")
520 struct eigrp_interface
*ei
;
522 /* Check if eigrp process is enabled */
523 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
525 vty_out(vty
, " EIGRP Routing Process not enabled\n");
529 /* lookup interface by specified name */
530 ei
= eigrp_if_lookup_by_name(eigrp
, ifname
);
532 vty_out(vty
, " Interface (%s) doesn't exist\n", argv
[4]->arg
);
536 /* execute graceful restart for all neighbors on interface */
537 eigrp_update_send_interface_GR(ei
, EIGRP_GR_MANUAL
, vty
);
542 * Execute graceful restart for neighbor specified by IP
544 DEFPY (clear_ip_eigrp_neighbors_IP_soft
,
545 clear_ip_eigrp_neighbors_IP_soft_cmd
,
546 "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr soft",
551 "Clear IP-EIGRP neighbors\n"
552 "IP-EIGRP neighbor address\n"
553 "Resync with peer without adjacency reset\n")
556 struct eigrp_neighbor
*nbr
;
559 /* Check if eigrp process is enabled */
560 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
562 vty_out(vty
, " EIGRP Routing Process not enabled\n");
566 /* lookup neighbor in whole process */
567 nbr
= eigrp_nbr_lookup_by_addr_process(eigrp
, nbr_addr
);
569 /* if neighbor doesn't exists, notify user and exit */
571 vty_out(vty
, "Neighbor with entered address doesn't exists.\n");
575 /* execute graceful restart on neighbor */
576 eigrp_update_send_GR(nbr
, EIGRP_GR_MANUAL
, vty
);
581 void eigrp_vty_show_init(void)
583 install_element(VIEW_NODE
, &show_ip_eigrp_interfaces_cmd
);
585 install_element(VIEW_NODE
, &show_ip_eigrp_neighbors_cmd
);
587 install_element(VIEW_NODE
, &show_ip_eigrp_topology_cmd
);
588 install_element(VIEW_NODE
, &show_ip_eigrp_topology_all_cmd
);
591 /* Install EIGRP related vty commands. */
592 void eigrp_vty_init(void)
594 /* commands for manual hard restart */
595 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_cmd
);
596 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_int_cmd
);
597 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_IP_cmd
);
598 /* commands for manual graceful restart */
599 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_soft_cmd
);
600 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_int_soft_cmd
);
601 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_IP_soft_cmd
);