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
, struct eigrp
*eigrp
,
63 struct eigrp_prefix_descriptor
*pe
,
67 struct eigrp_route_descriptor
*te
;
68 struct listnode
*node
;
70 for (ALL_LIST_ELEMENTS_RO(pe
->entries
, node
, te
)) {
72 || (((te
->flags
& EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG
)
73 == EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG
)
74 || ((te
->flags
& EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG
)
75 == EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG
))) {
76 show_ip_eigrp_route_descriptor(vty
, eigrp
, te
, &first
);
82 static struct eigrp
*eigrp_vty_get_eigrp(struct vty
*vty
, const char *vrf_name
)
87 vrf
= vrf_lookup_by_name(vrf_name
);
89 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
92 vty_out(vty
, "VRF %s specified does not exist",
93 vrf_name
? vrf_name
: VRF_DEFAULT_NAME
);
97 return eigrp_lookup(vrf
->vrf_id
);
100 static void eigrp_topology_helper(struct vty
*vty
, struct eigrp
*eigrp
,
103 struct eigrp_prefix_descriptor
*tn
;
104 struct route_node
*rn
;
106 show_ip_eigrp_topology_header(vty
, eigrp
);
108 for (rn
= route_top(eigrp
->topology_table
); rn
; rn
= route_next(rn
)) {
113 eigrp_vty_display_prefix_entry(vty
, eigrp
, tn
,
118 DEFPY (show_ip_eigrp_topology_all
,
119 show_ip_eigrp_topology_all_cmd
,
120 "show ip eigrp [vrf NAME] topology [all-links$all]",
123 "IP-EIGRP show commands\n"
125 "IP-EIGRP topology\n"
126 "Show all links in topology table\n")
130 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
133 RB_FOREACH (v
, vrf_name_head
, &vrfs_by_name
) {
134 eigrp
= eigrp_lookup(v
->vrf_id
);
138 vty_out(vty
, "VRF %s:\n", v
->name
);
140 eigrp_topology_helper(vty
, eigrp
, all
);
143 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
145 vty_out(vty
, " EIGRP Routing Process not enabled\n");
149 eigrp_topology_helper(vty
, eigrp
, all
);
155 DEFPY (show_ip_eigrp_topology
,
156 show_ip_eigrp_topology_cmd
,
157 "show ip eigrp [vrf NAME] topology <A.B.C.D$address|A.B.C.D/M$prefix>",
160 "IP-EIGRP show commands\n"
162 "IP-EIGRP topology\n"
163 "For a specific address\n"
164 "For a specific prefix\n")
167 struct eigrp_prefix_descriptor
*tn
;
168 struct route_node
*rn
;
171 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
172 vty_out(vty
, "Specifying vrf `all` for a particular address/prefix makes no sense\n");
176 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
178 vty_out(vty
, " EIGRP Routing Process not enabled\n");
182 show_ip_eigrp_topology_header(vty
, eigrp
);
185 prefix_str
= address_str
;
187 if (str2prefix(prefix_str
, &cmp
) < 0) {
188 vty_out(vty
, "%% Malformed address\n");
192 rn
= route_node_match(eigrp
->topology_table
, &cmp
);
194 vty_out(vty
, "%% Network not in table\n");
199 vty_out(vty
, "%% Network not in table\n");
200 route_unlock_node(rn
);
205 eigrp_vty_display_prefix_entry(vty
, eigrp
, tn
, argc
== 5);
207 route_unlock_node(rn
);
211 static void eigrp_interface_helper(struct vty
*vty
, struct eigrp
*eigrp
,
212 const char *ifname
, const char *detail
)
214 struct eigrp_interface
*ei
;
215 struct listnode
*node
;
218 show_ip_eigrp_interface_header(vty
, eigrp
);
220 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
221 if (!ifname
|| strcmp(ei
->ifp
->name
, ifname
) == 0) {
222 show_ip_eigrp_interface_sub(vty
, eigrp
, ei
);
224 show_ip_eigrp_interface_detail(vty
, eigrp
, ei
);
229 DEFPY (show_ip_eigrp_interfaces
,
230 show_ip_eigrp_interfaces_cmd
,
231 "show ip eigrp [vrf NAME] interfaces [IFNAME] [detail]$detail",
234 "IP-EIGRP show commands\n"
236 "IP-EIGRP interfaces\n"
237 "Interface name to look at\n"
238 "Detailed information\n")
242 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
245 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
246 eigrp
= eigrp_lookup(vrf
->vrf_id
);
250 vty_out(vty
, "VRF %s:\n", vrf
->name
);
252 eigrp_interface_helper(vty
, eigrp
, ifname
, detail
);
255 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
257 vty_out(vty
, "EIGRP Routing Process not enabled\n");
261 eigrp_interface_helper(vty
, eigrp
, ifname
, detail
);
268 static void eigrp_neighbors_helper(struct vty
*vty
, struct eigrp
*eigrp
,
269 const char *ifname
, const char *detail
)
271 struct eigrp_interface
*ei
;
272 struct listnode
*node
, *node2
, *nnode2
;
273 struct eigrp_neighbor
*nbr
;
275 show_ip_eigrp_neighbor_header(vty
, eigrp
);
277 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
278 if (!ifname
|| strcmp(ei
->ifp
->name
, ifname
) == 0) {
279 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
280 if (detail
|| (nbr
->state
== EIGRP_NEIGHBOR_UP
))
281 show_ip_eigrp_neighbor_sub(vty
, nbr
,
288 DEFPY (show_ip_eigrp_neighbors
,
289 show_ip_eigrp_neighbors_cmd
,
290 "show ip eigrp [vrf NAME] neighbors [IFNAME] [detail]$detail",
293 "IP-EIGRP show commands\n"
295 "IP-EIGRP neighbors\n"
296 "Interface to show on\n"
297 "Detailed Information\n")
301 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
304 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
305 eigrp
= eigrp_lookup(vrf
->vrf_id
);
309 vty_out(vty
, "VRF %s:\n", vrf
->name
);
311 eigrp_neighbors_helper(vty
, eigrp
, ifname
, detail
);
314 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
316 vty_out(vty
, " EIGRP Routing Process not enabled\n");
320 eigrp_neighbors_helper(vty
, eigrp
, ifname
, detail
);
327 * Execute hard restart for all neighbors
329 DEFPY (clear_ip_eigrp_neighbors
,
330 clear_ip_eigrp_neighbors_cmd
,
331 "clear ip eigrp [vrf NAME] neighbors",
336 "Clear IP-EIGRP neighbors\n")
339 struct eigrp_interface
*ei
;
340 struct listnode
*node
, *node2
, *nnode2
;
341 struct eigrp_neighbor
*nbr
;
343 /* Check if eigrp process is enabled */
344 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
346 vty_out(vty
, " EIGRP Routing Process not enabled\n");
350 /* iterate over all eigrp interfaces */
351 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
352 /* send Goodbye Hello */
353 eigrp_hello_send(ei
, EIGRP_HELLO_GRACEFUL_SHUTDOWN
, NULL
);
355 /* iterate over all neighbors on eigrp interface */
356 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
357 if (nbr
->state
!= EIGRP_NEIGHBOR_DOWN
) {
359 "Neighbor %pI4 (%s) is down: manually cleared",
361 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
363 vty_time_print(vty
, 0);
365 "Neighbor %pI4 (%s) is down: manually cleared\n",
367 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
370 /* set neighbor to DOWN */
371 nbr
->state
= EIGRP_NEIGHBOR_DOWN
;
372 /* delete neighbor */
373 eigrp_nbr_delete(nbr
);
382 * Execute hard restart for all neighbors on interface
384 DEFPY (clear_ip_eigrp_neighbors_int
,
385 clear_ip_eigrp_neighbors_int_cmd
,
386 "clear ip eigrp [vrf NAME] neighbors IFNAME",
391 "Clear IP-EIGRP neighbors\n"
392 "Interface's name\n")
395 struct eigrp_interface
*ei
;
396 struct listnode
*node2
, *nnode2
;
397 struct eigrp_neighbor
*nbr
;
399 /* Check if eigrp process is enabled */
400 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
402 vty_out(vty
, " EIGRP Routing Process not enabled\n");
406 /* lookup interface by specified name */
407 ei
= eigrp_if_lookup_by_name(eigrp
, ifname
);
409 vty_out(vty
, " Interface (%s) doesn't exist\n", ifname
);
413 /* send Goodbye Hello */
414 eigrp_hello_send(ei
, EIGRP_HELLO_GRACEFUL_SHUTDOWN
, NULL
);
416 /* iterate over all neighbors on eigrp interface */
417 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
418 if (nbr
->state
!= EIGRP_NEIGHBOR_DOWN
) {
420 "Neighbor %pI4 (%s) is down: manually cleared",
422 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
424 vty_time_print(vty
, 0);
426 "Neighbor %pI4 (%s) is down: manually cleared\n",
428 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
431 /* set neighbor to DOWN */
432 nbr
->state
= EIGRP_NEIGHBOR_DOWN
;
433 /* delete neighbor */
434 eigrp_nbr_delete(nbr
);
442 * Execute hard restart for neighbor specified by IP
444 DEFPY (clear_ip_eigrp_neighbors_IP
,
445 clear_ip_eigrp_neighbors_IP_cmd
,
446 "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr",
451 "Clear IP-EIGRP neighbors\n"
452 "IP-EIGRP neighbor address\n")
455 struct eigrp_neighbor
*nbr
;
457 /* Check if eigrp process is enabled */
458 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
460 vty_out(vty
, " EIGRP Routing Process not enabled\n");
464 /* lookup neighbor in whole process */
465 nbr
= eigrp_nbr_lookup_by_addr_process(eigrp
, nbr_addr
);
467 /* if neighbor doesn't exists, notify user and exit */
469 vty_out(vty
, "Neighbor with entered address doesn't exists.\n");
473 /* execute hard reset on neighbor */
474 eigrp_nbr_hard_restart(nbr
, vty
);
480 * Execute graceful restart for all neighbors
482 DEFPY (clear_ip_eigrp_neighbors_soft
,
483 clear_ip_eigrp_neighbors_soft_cmd
,
484 "clear ip eigrp [vrf NAME] neighbors soft",
489 "Clear IP-EIGRP neighbors\n"
490 "Resync with peers without adjacency reset\n")
494 /* Check if eigrp process is enabled */
495 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
497 vty_out(vty
, " EIGRP Routing Process not enabled\n");
501 /* execute graceful restart on all neighbors */
502 eigrp_update_send_process_GR(eigrp
, EIGRP_GR_MANUAL
, vty
);
508 * Execute graceful restart for all neighbors on interface
510 DEFPY (clear_ip_eigrp_neighbors_int_soft
,
511 clear_ip_eigrp_neighbors_int_soft_cmd
,
512 "clear ip eigrp [vrf NAME] neighbors IFNAME soft",
517 "Clear IP-EIGRP neighbors\n"
519 "Resync with peer without adjacency reset\n")
522 struct eigrp_interface
*ei
;
524 /* Check if eigrp process is enabled */
525 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
527 vty_out(vty
, " EIGRP Routing Process not enabled\n");
531 /* lookup interface by specified name */
532 ei
= eigrp_if_lookup_by_name(eigrp
, ifname
);
534 vty_out(vty
, " Interface (%s) doesn't exist\n", argv
[4]->arg
);
538 /* execute graceful restart for all neighbors on interface */
539 eigrp_update_send_interface_GR(ei
, EIGRP_GR_MANUAL
, vty
);
544 * Execute graceful restart for neighbor specified by IP
546 DEFPY (clear_ip_eigrp_neighbors_IP_soft
,
547 clear_ip_eigrp_neighbors_IP_soft_cmd
,
548 "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr soft",
553 "Clear IP-EIGRP neighbors\n"
554 "IP-EIGRP neighbor address\n"
555 "Resync with peer without adjacency reset\n")
558 struct eigrp_neighbor
*nbr
;
561 /* Check if eigrp process is enabled */
562 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
564 vty_out(vty
, " EIGRP Routing Process not enabled\n");
568 /* lookup neighbor in whole process */
569 nbr
= eigrp_nbr_lookup_by_addr_process(eigrp
, nbr_addr
);
571 /* if neighbor doesn't exists, notify user and exit */
573 vty_out(vty
, "Neighbor with entered address doesn't exists.\n");
577 /* execute graceful restart on neighbor */
578 eigrp_update_send_GR(nbr
, EIGRP_GR_MANUAL
, vty
);
583 void eigrp_vty_show_init(void)
585 install_element(VIEW_NODE
, &show_ip_eigrp_interfaces_cmd
);
587 install_element(VIEW_NODE
, &show_ip_eigrp_neighbors_cmd
);
589 install_element(VIEW_NODE
, &show_ip_eigrp_topology_cmd
);
590 install_element(VIEW_NODE
, &show_ip_eigrp_topology_all_cmd
);
593 /* Install EIGRP related vty commands. */
594 void eigrp_vty_init(void)
596 /* commands for manual hard restart */
597 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_cmd
);
598 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_int_cmd
);
599 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_IP_cmd
);
600 /* commands for manual graceful restart */
601 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_soft_cmd
);
602 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_int_soft_cmd
);
603 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_IP_soft_cmd
);