1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2013-2016
30 #include "distribute.h"
32 #include "eigrpd/eigrp_structs.h"
33 #include "eigrpd/eigrpd.h"
34 #include "eigrpd/eigrp_interface.h"
35 #include "eigrpd/eigrp_neighbor.h"
36 #include "eigrpd/eigrp_packet.h"
37 #include "eigrpd/eigrp_zebra.h"
38 #include "eigrpd/eigrp_vty.h"
39 #include "eigrpd/eigrp_network.h"
40 #include "eigrpd/eigrp_dump.h"
41 #include "eigrpd/eigrp_const.h"
43 #include "eigrpd/eigrp_vty_clippy.c"
45 static void eigrp_vty_display_prefix_entry(struct vty
*vty
, struct eigrp
*eigrp
,
46 struct eigrp_prefix_descriptor
*pe
,
50 struct eigrp_route_descriptor
*te
;
51 struct listnode
*node
;
53 for (ALL_LIST_ELEMENTS_RO(pe
->entries
, node
, te
)) {
55 || (((te
->flags
& EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG
)
56 == EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG
)
57 || ((te
->flags
& EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG
)
58 == EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG
))) {
59 show_ip_eigrp_route_descriptor(vty
, eigrp
, te
, &first
);
65 static struct eigrp
*eigrp_vty_get_eigrp(struct vty
*vty
, const char *vrf_name
)
70 vrf
= vrf_lookup_by_name(vrf_name
);
72 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
75 vty_out(vty
, "VRF %s specified does not exist",
76 vrf_name
? vrf_name
: VRF_DEFAULT_NAME
);
80 return eigrp_lookup(vrf
->vrf_id
);
83 static void eigrp_topology_helper(struct vty
*vty
, struct eigrp
*eigrp
,
86 struct eigrp_prefix_descriptor
*tn
;
87 struct route_node
*rn
;
89 show_ip_eigrp_topology_header(vty
, eigrp
);
91 for (rn
= route_top(eigrp
->topology_table
); rn
; rn
= route_next(rn
)) {
96 eigrp_vty_display_prefix_entry(vty
, eigrp
, tn
,
101 DEFPY (show_ip_eigrp_topology_all
,
102 show_ip_eigrp_topology_all_cmd
,
103 "show ip eigrp [vrf NAME] topology [all-links$all]",
106 "IP-EIGRP show commands\n"
108 "IP-EIGRP topology\n"
109 "Show all links in topology table\n")
113 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
116 RB_FOREACH (v
, vrf_name_head
, &vrfs_by_name
) {
117 eigrp
= eigrp_lookup(v
->vrf_id
);
121 vty_out(vty
, "VRF %s:\n", v
->name
);
123 eigrp_topology_helper(vty
, eigrp
, all
);
126 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
128 vty_out(vty
, " EIGRP Routing Process not enabled\n");
132 eigrp_topology_helper(vty
, eigrp
, all
);
138 DEFPY (show_ip_eigrp_topology
,
139 show_ip_eigrp_topology_cmd
,
140 "show ip eigrp [vrf NAME] topology <A.B.C.D$address|A.B.C.D/M$prefix>",
143 "IP-EIGRP show commands\n"
145 "IP-EIGRP topology\n"
146 "For a specific address\n"
147 "For a specific prefix\n")
150 struct eigrp_prefix_descriptor
*tn
;
151 struct route_node
*rn
;
154 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
155 vty_out(vty
, "Specifying vrf `all` for a particular address/prefix makes no sense\n");
159 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
161 vty_out(vty
, " EIGRP Routing Process not enabled\n");
165 show_ip_eigrp_topology_header(vty
, eigrp
);
168 prefix_str
= address_str
;
170 if (str2prefix(prefix_str
, &cmp
) < 0) {
171 vty_out(vty
, "%% Malformed address\n");
175 rn
= route_node_match(eigrp
->topology_table
, &cmp
);
177 vty_out(vty
, "%% Network not in table\n");
182 vty_out(vty
, "%% Network not in table\n");
183 route_unlock_node(rn
);
188 eigrp_vty_display_prefix_entry(vty
, eigrp
, tn
, argc
== 5);
190 route_unlock_node(rn
);
194 static void eigrp_interface_helper(struct vty
*vty
, struct eigrp
*eigrp
,
195 const char *ifname
, const char *detail
)
197 struct eigrp_interface
*ei
;
198 struct listnode
*node
;
201 show_ip_eigrp_interface_header(vty
, eigrp
);
203 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
204 if (!ifname
|| strcmp(ei
->ifp
->name
, ifname
) == 0) {
205 show_ip_eigrp_interface_sub(vty
, eigrp
, ei
);
207 show_ip_eigrp_interface_detail(vty
, eigrp
, ei
);
212 DEFPY (show_ip_eigrp_interfaces
,
213 show_ip_eigrp_interfaces_cmd
,
214 "show ip eigrp [vrf NAME] interfaces [IFNAME] [detail]$detail",
217 "IP-EIGRP show commands\n"
219 "IP-EIGRP interfaces\n"
220 "Interface name to look at\n"
221 "Detailed information\n")
225 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
228 RB_FOREACH (v
, vrf_name_head
, &vrfs_by_name
) {
229 eigrp
= eigrp_lookup(v
->vrf_id
);
233 vty_out(vty
, "VRF %s:\n", v
->name
);
235 eigrp_interface_helper(vty
, eigrp
, ifname
, detail
);
238 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
240 vty_out(vty
, "EIGRP Routing Process not enabled\n");
244 eigrp_interface_helper(vty
, eigrp
, ifname
, detail
);
251 static void eigrp_neighbors_helper(struct vty
*vty
, struct eigrp
*eigrp
,
252 const char *ifname
, const char *detail
)
254 struct eigrp_interface
*ei
;
255 struct listnode
*node
, *node2
, *nnode2
;
256 struct eigrp_neighbor
*nbr
;
258 show_ip_eigrp_neighbor_header(vty
, eigrp
);
260 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
261 if (!ifname
|| strcmp(ei
->ifp
->name
, ifname
) == 0) {
262 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
263 if (detail
|| (nbr
->state
== EIGRP_NEIGHBOR_UP
))
264 show_ip_eigrp_neighbor_sub(vty
, nbr
,
271 DEFPY (show_ip_eigrp_neighbors
,
272 show_ip_eigrp_neighbors_cmd
,
273 "show ip eigrp [vrf NAME] neighbors [IFNAME] [detail]$detail",
276 "IP-EIGRP show commands\n"
278 "IP-EIGRP neighbors\n"
279 "Interface to show on\n"
280 "Detailed Information\n")
284 if (vrf
&& strncmp(vrf
, "all", sizeof("all")) == 0) {
287 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
288 eigrp
= eigrp_lookup(vrf
->vrf_id
);
292 vty_out(vty
, "VRF %s:\n", vrf
->name
);
294 eigrp_neighbors_helper(vty
, eigrp
, ifname
, detail
);
297 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
299 vty_out(vty
, " EIGRP Routing Process not enabled\n");
303 eigrp_neighbors_helper(vty
, eigrp
, ifname
, detail
);
310 * Execute hard restart for all neighbors
312 DEFPY (clear_ip_eigrp_neighbors
,
313 clear_ip_eigrp_neighbors_cmd
,
314 "clear ip eigrp [vrf NAME] neighbors",
319 "Clear IP-EIGRP neighbors\n")
322 struct eigrp_interface
*ei
;
323 struct listnode
*node
, *node2
, *nnode2
;
324 struct eigrp_neighbor
*nbr
;
326 /* Check if eigrp process is enabled */
327 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
329 vty_out(vty
, " EIGRP Routing Process not enabled\n");
333 /* iterate over all eigrp interfaces */
334 for (ALL_LIST_ELEMENTS_RO(eigrp
->eiflist
, node
, ei
)) {
335 /* send Goodbye Hello */
336 eigrp_hello_send(ei
, EIGRP_HELLO_GRACEFUL_SHUTDOWN
, NULL
);
338 /* iterate over all neighbors on eigrp interface */
339 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
340 if (nbr
->state
!= EIGRP_NEIGHBOR_DOWN
) {
342 "Neighbor %pI4 (%s) is down: manually cleared",
344 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
346 vty_time_print(vty
, 0);
348 "Neighbor %pI4 (%s) is down: manually cleared\n",
350 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
353 /* set neighbor to DOWN */
354 nbr
->state
= EIGRP_NEIGHBOR_DOWN
;
355 /* delete neighbor */
356 eigrp_nbr_delete(nbr
);
365 * Execute hard restart for all neighbors on interface
367 DEFPY (clear_ip_eigrp_neighbors_int
,
368 clear_ip_eigrp_neighbors_int_cmd
,
369 "clear ip eigrp [vrf NAME] neighbors IFNAME",
374 "Clear IP-EIGRP neighbors\n"
375 "Interface's name\n")
378 struct eigrp_interface
*ei
;
379 struct listnode
*node2
, *nnode2
;
380 struct eigrp_neighbor
*nbr
;
382 /* Check if eigrp process is enabled */
383 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
385 vty_out(vty
, " EIGRP Routing Process not enabled\n");
389 /* lookup interface by specified name */
390 ei
= eigrp_if_lookup_by_name(eigrp
, ifname
);
392 vty_out(vty
, " Interface (%s) doesn't exist\n", ifname
);
396 /* send Goodbye Hello */
397 eigrp_hello_send(ei
, EIGRP_HELLO_GRACEFUL_SHUTDOWN
, NULL
);
399 /* iterate over all neighbors on eigrp interface */
400 for (ALL_LIST_ELEMENTS(ei
->nbrs
, node2
, nnode2
, nbr
)) {
401 if (nbr
->state
!= EIGRP_NEIGHBOR_DOWN
) {
403 "Neighbor %pI4 (%s) is down: manually cleared",
405 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
407 vty_time_print(vty
, 0);
409 "Neighbor %pI4 (%s) is down: manually cleared\n",
411 ifindex2ifname(nbr
->ei
->ifp
->ifindex
,
414 /* set neighbor to DOWN */
415 nbr
->state
= EIGRP_NEIGHBOR_DOWN
;
416 /* delete neighbor */
417 eigrp_nbr_delete(nbr
);
425 * Execute hard restart for neighbor specified by IP
427 DEFPY (clear_ip_eigrp_neighbors_IP
,
428 clear_ip_eigrp_neighbors_IP_cmd
,
429 "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr",
434 "Clear IP-EIGRP neighbors\n"
435 "IP-EIGRP neighbor address\n")
438 struct eigrp_neighbor
*nbr
;
440 /* Check if eigrp process is enabled */
441 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
443 vty_out(vty
, " EIGRP Routing Process not enabled\n");
447 /* lookup neighbor in whole process */
448 nbr
= eigrp_nbr_lookup_by_addr_process(eigrp
, nbr_addr
);
450 /* if neighbor doesn't exists, notify user and exit */
452 vty_out(vty
, "Neighbor with entered address doesn't exists.\n");
456 /* execute hard reset on neighbor */
457 eigrp_nbr_hard_restart(nbr
, vty
);
463 * Execute graceful restart for all neighbors
465 DEFPY (clear_ip_eigrp_neighbors_soft
,
466 clear_ip_eigrp_neighbors_soft_cmd
,
467 "clear ip eigrp [vrf NAME] neighbors soft",
472 "Clear IP-EIGRP neighbors\n"
473 "Resync with peers without adjacency reset\n")
477 /* Check if eigrp process is enabled */
478 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
480 vty_out(vty
, " EIGRP Routing Process not enabled\n");
484 /* execute graceful restart on all neighbors */
485 eigrp_update_send_process_GR(eigrp
, EIGRP_GR_MANUAL
, vty
);
491 * Execute graceful restart for all neighbors on interface
493 DEFPY (clear_ip_eigrp_neighbors_int_soft
,
494 clear_ip_eigrp_neighbors_int_soft_cmd
,
495 "clear ip eigrp [vrf NAME] neighbors IFNAME soft",
500 "Clear IP-EIGRP neighbors\n"
502 "Resync with peer without adjacency reset\n")
505 struct eigrp_interface
*ei
;
507 /* Check if eigrp process is enabled */
508 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
510 vty_out(vty
, " EIGRP Routing Process not enabled\n");
514 /* lookup interface by specified name */
515 ei
= eigrp_if_lookup_by_name(eigrp
, ifname
);
517 vty_out(vty
, " Interface (%s) doesn't exist\n", argv
[4]->arg
);
521 /* execute graceful restart for all neighbors on interface */
522 eigrp_update_send_interface_GR(ei
, EIGRP_GR_MANUAL
, vty
);
527 * Execute graceful restart for neighbor specified by IP
529 DEFPY (clear_ip_eigrp_neighbors_IP_soft
,
530 clear_ip_eigrp_neighbors_IP_soft_cmd
,
531 "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr soft",
536 "Clear IP-EIGRP neighbors\n"
537 "IP-EIGRP neighbor address\n"
538 "Resync with peer without adjacency reset\n")
541 struct eigrp_neighbor
*nbr
;
544 /* Check if eigrp process is enabled */
545 eigrp
= eigrp_vty_get_eigrp(vty
, vrf
);
547 vty_out(vty
, " EIGRP Routing Process not enabled\n");
551 /* lookup neighbor in whole process */
552 nbr
= eigrp_nbr_lookup_by_addr_process(eigrp
, nbr_addr
);
554 /* if neighbor doesn't exists, notify user and exit */
556 vty_out(vty
, "Neighbor with entered address doesn't exists.\n");
560 /* execute graceful restart on neighbor */
561 eigrp_update_send_GR(nbr
, EIGRP_GR_MANUAL
, vty
);
566 void eigrp_vty_show_init(void)
568 install_element(VIEW_NODE
, &show_ip_eigrp_interfaces_cmd
);
570 install_element(VIEW_NODE
, &show_ip_eigrp_neighbors_cmd
);
572 install_element(VIEW_NODE
, &show_ip_eigrp_topology_cmd
);
573 install_element(VIEW_NODE
, &show_ip_eigrp_topology_all_cmd
);
576 /* Install EIGRP related vty commands. */
577 void eigrp_vty_init(void)
579 /* commands for manual hard restart */
580 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_cmd
);
581 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_int_cmd
);
582 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_IP_cmd
);
583 /* commands for manual graceful restart */
584 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_soft_cmd
);
585 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_int_soft_cmd
);
586 install_element(ENABLE_NODE
, &clear_ip_eigrp_neighbors_IP_soft_cmd
);