]> git.proxmox.com Git - mirror_frr.git/blob - eigrpd/eigrp_vty.c
Merge pull request #6377 from ton31337/fix/bgpd_statistics
[mirror_frr.git] / eigrpd / eigrp_vty.c
1 /*
2 * EIGRP VTY Interface.
3 * Copyright (C) 2013-2016
4 * Authors:
5 * Donnie Savage
6 * Jan Janovic
7 * Matej Perina
8 * Peter Orsag
9 * Peter Paluch
10 * Frantisek Gazo
11 * Tomas Hvorkovy
12 * Martin Kontsek
13 * Lukas Koribsky
14 *
15 * This file is part of GNU Zebra.
16 *
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
20 * later version.
21 *
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.
26 *
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
30 */
31
32 #include <zebra.h>
33
34 #include "memory.h"
35 #include "thread.h"
36 #include "prefix.h"
37 #include "table.h"
38 #include "vty.h"
39 #include "command.h"
40 #include "plist.h"
41 #include "log.h"
42 #include "zclient.h"
43 #include "keychain.h"
44 #include "linklist.h"
45 #include "distribute.h"
46
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"
57
58 #ifndef VTYSH_EXTRACT_PL
59 #include "eigrpd/eigrp_vty_clippy.c"
60 #endif
61
62 static void eigrp_vty_display_prefix_entry(struct vty *vty,
63 struct eigrp *eigrp,
64 struct eigrp_prefix_entry *pe,
65 bool all)
66 {
67 bool first = true;
68 struct eigrp_nexthop_entry *te;
69 struct listnode *node;
70
71 for (ALL_LIST_ELEMENTS_RO(pe->entries, node, te)) {
72 if (all
73 || (((te->flags
74 & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)
75 == EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)
76 || ((te->flags
77 & EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG)
78 == EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG))) {
79 show_ip_eigrp_nexthop_entry(vty, eigrp, te,
80 &first);
81 first = false;
82 }
83 }
84 }
85
86 static struct eigrp *eigrp_vty_get_eigrp(struct vty *vty, const char *vrf_name)
87 {
88 struct vrf *vrf;
89
90 if (vrf_name)
91 vrf = vrf_lookup_by_name(vrf_name);
92 else
93 vrf = vrf_lookup_by_id(VRF_DEFAULT);
94
95 if (!vrf) {
96 vty_out(vty, "VRF %s specified does not exist",
97 vrf_name ? vrf_name : VRF_DEFAULT_NAME);
98 return NULL;
99 }
100
101 return eigrp_lookup(vrf->vrf_id);
102 }
103
104 DEFPY (show_ip_eigrp_topology_all,
105 show_ip_eigrp_topology_all_cmd,
106 "show ip eigrp [vrf NAME] topology [all-links$all]",
107 SHOW_STR
108 IP_STR
109 "IP-EIGRP show commands\n"
110 VRF_CMD_HELP_STR
111 "IP-EIGRP topology\n"
112 "Show all links in topology table\n")
113 {
114 struct eigrp *eigrp;
115 struct eigrp_prefix_entry *tn;
116 struct route_node *rn;
117
118 eigrp = eigrp_vty_get_eigrp(vty, vrf);
119 if (eigrp == NULL) {
120 vty_out(vty, " EIGRP Routing Process not enabled\n");
121 return CMD_SUCCESS;
122 }
123
124 show_ip_eigrp_topology_header(vty, eigrp);
125
126 for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
127 if (!rn->info)
128 continue;
129
130 tn = rn->info;
131 eigrp_vty_display_prefix_entry(vty, eigrp, tn,
132 all ? true : false);
133 }
134
135 return CMD_SUCCESS;
136
137 }
138
139 DEFPY (show_ip_eigrp_topology,
140 show_ip_eigrp_topology_cmd,
141 "show ip eigrp [vrf NAME] topology <A.B.C.D$address|A.B.C.D/M$prefix>",
142 SHOW_STR
143 IP_STR
144 "IP-EIGRP show commands\n"
145 VRF_CMD_HELP_STR
146 "IP-EIGRP topology\n"
147 "For a specific address\n"
148 "For a specific prefix\n")
149 {
150 struct eigrp *eigrp;
151 struct eigrp_prefix_entry *tn;
152 struct route_node *rn;
153 struct prefix cmp;
154
155 eigrp = eigrp_vty_get_eigrp(vty, vrf);
156 if (eigrp == NULL) {
157 vty_out(vty, " EIGRP Routing Process not enabled\n");
158 return CMD_SUCCESS;
159 }
160
161 show_ip_eigrp_topology_header(vty, eigrp);
162
163 if (address_str)
164 prefix_str = address_str;
165
166 if (str2prefix(prefix_str, &cmp) < 0) {
167 vty_out(vty, "%% Malformed address\n");
168 return CMD_WARNING;
169 }
170
171 rn = route_node_match(eigrp->topology_table, &cmp);
172 if (!rn) {
173 vty_out(vty, "%% Network not in table\n");
174 return CMD_WARNING;
175 }
176
177 if (!rn->info) {
178 vty_out(vty, "%% Network not in table\n");
179 route_unlock_node(rn);
180 return CMD_WARNING;
181 }
182
183 tn = rn->info;
184 eigrp_vty_display_prefix_entry(vty, eigrp, tn, argc == 5);
185
186 route_unlock_node(rn);
187 return CMD_SUCCESS;
188 }
189
190 DEFPY (show_ip_eigrp_interfaces,
191 show_ip_eigrp_interfaces_cmd,
192 "show ip eigrp [vrf NAME] interfaces [IFNAME] [detail]$detail",
193 SHOW_STR
194 IP_STR
195 "IP-EIGRP show commands\n"
196 VRF_CMD_HELP_STR
197 "IP-EIGRP interfaces\n"
198 "Interface name to look at\n"
199 "Detailed information\n")
200 {
201 struct eigrp_interface *ei;
202 struct eigrp *eigrp;
203 struct listnode *node;
204
205 eigrp = eigrp_vty_get_eigrp(vty, vrf);
206 if (eigrp == NULL) {
207 vty_out(vty, "EIGRP Routing Process not enabled\n");
208 return CMD_SUCCESS;
209 }
210
211 if (!ifname)
212 show_ip_eigrp_interface_header(vty, eigrp);
213
214 for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
215 if (!ifname || strcmp(ei->ifp->name, ifname) == 0) {
216 show_ip_eigrp_interface_sub(vty, eigrp, ei);
217 if (detail)
218 show_ip_eigrp_interface_detail(vty, eigrp, ei);
219 }
220 }
221
222 return CMD_SUCCESS;
223 }
224
225 DEFPY (show_ip_eigrp_neighbors,
226 show_ip_eigrp_neighbors_cmd,
227 "show ip eigrp [vrf NAME] neighbors [IFNAME] [detail]$detail",
228 SHOW_STR
229 IP_STR
230 "IP-EIGRP show commands\n"
231 VRF_CMD_HELP_STR
232 "IP-EIGRP neighbors\n"
233 "Interface to show on\n"
234 "Detailed Information\n")
235 {
236 struct eigrp *eigrp;
237 struct eigrp_interface *ei;
238 struct listnode *node, *node2, *nnode2;
239 struct eigrp_neighbor *nbr;
240
241 eigrp = eigrp_vty_get_eigrp(vty, vrf);
242 if (eigrp == NULL) {
243 vty_out(vty, " EIGRP Routing Process not enabled\n");
244 return CMD_SUCCESS;
245 }
246
247 show_ip_eigrp_neighbor_header(vty, eigrp);
248
249 for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
250 if (!ifname || strcmp(ei->ifp->name, ifname) == 0) {
251 for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
252 if (detail || (nbr->state == EIGRP_NEIGHBOR_UP))
253 show_ip_eigrp_neighbor_sub(vty, nbr,
254 !!detail);
255 }
256 }
257 }
258
259 return CMD_SUCCESS;
260 }
261
262 /*
263 * Execute hard restart for all neighbors
264 */
265 DEFPY (clear_ip_eigrp_neighbors,
266 clear_ip_eigrp_neighbors_cmd,
267 "clear ip eigrp [vrf NAME] neighbors",
268 CLEAR_STR
269 IP_STR
270 "Clear IP-EIGRP\n"
271 VRF_CMD_HELP_STR
272 "Clear IP-EIGRP neighbors\n")
273 {
274 struct eigrp *eigrp;
275 struct eigrp_interface *ei;
276 struct listnode *node, *node2, *nnode2;
277 struct eigrp_neighbor *nbr;
278
279 /* Check if eigrp process is enabled */
280 eigrp = eigrp_vty_get_eigrp(vty, vrf);
281 if (eigrp == NULL) {
282 vty_out(vty, " EIGRP Routing Process not enabled\n");
283 return CMD_SUCCESS;
284 }
285
286 /* iterate over all eigrp interfaces */
287 for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
288 /* send Goodbye Hello */
289 eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL);
290
291 /* iterate over all neighbors on eigrp interface */
292 for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
293 if (nbr->state != EIGRP_NEIGHBOR_DOWN) {
294 zlog_debug(
295 "Neighbor %s (%s) is down: manually cleared",
296 inet_ntoa(nbr->src),
297 ifindex2ifname(nbr->ei->ifp->ifindex,
298 eigrp->vrf_id));
299 vty_time_print(vty, 0);
300 vty_out(vty,
301 "Neighbor %s (%s) is down: manually cleared\n",
302 inet_ntoa(nbr->src),
303 ifindex2ifname(nbr->ei->ifp->ifindex,
304 eigrp->vrf_id));
305
306 /* set neighbor to DOWN */
307 nbr->state = EIGRP_NEIGHBOR_DOWN;
308 /* delete neighbor */
309 eigrp_nbr_delete(nbr);
310 }
311 }
312 }
313
314 return CMD_SUCCESS;
315 }
316
317 /*
318 * Execute hard restart for all neighbors on interface
319 */
320 DEFPY (clear_ip_eigrp_neighbors_int,
321 clear_ip_eigrp_neighbors_int_cmd,
322 "clear ip eigrp [vrf NAME] neighbors IFNAME",
323 CLEAR_STR
324 IP_STR
325 "Clear IP-EIGRP\n"
326 VRF_CMD_HELP_STR
327 "Clear IP-EIGRP neighbors\n"
328 "Interface's name\n")
329 {
330 struct eigrp *eigrp;
331 struct eigrp_interface *ei;
332 struct listnode *node2, *nnode2;
333 struct eigrp_neighbor *nbr;
334
335 /* Check if eigrp process is enabled */
336 eigrp = eigrp_vty_get_eigrp(vty, vrf);
337 if (eigrp == NULL) {
338 vty_out(vty, " EIGRP Routing Process not enabled\n");
339 return CMD_SUCCESS;
340 }
341
342 /* lookup interface by specified name */
343 ei = eigrp_if_lookup_by_name(eigrp, ifname);
344 if (ei == NULL) {
345 vty_out(vty, " Interface (%s) doesn't exist\n", ifname);
346 return CMD_WARNING;
347 }
348
349 /* send Goodbye Hello */
350 eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL);
351
352 /* iterate over all neighbors on eigrp interface */
353 for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
354 if (nbr->state != EIGRP_NEIGHBOR_DOWN) {
355 zlog_debug("Neighbor %s (%s) is down: manually cleared",
356 inet_ntoa(nbr->src),
357 ifindex2ifname(nbr->ei->ifp->ifindex,
358 eigrp->vrf_id));
359 vty_time_print(vty, 0);
360 vty_out(vty,
361 "Neighbor %s (%s) is down: manually cleared\n",
362 inet_ntoa(nbr->src),
363 ifindex2ifname(nbr->ei->ifp->ifindex,
364 eigrp->vrf_id));
365
366 /* set neighbor to DOWN */
367 nbr->state = EIGRP_NEIGHBOR_DOWN;
368 /* delete neighbor */
369 eigrp_nbr_delete(nbr);
370 }
371 }
372
373 return CMD_SUCCESS;
374 }
375
376 /*
377 * Execute hard restart for neighbor specified by IP
378 */
379 DEFPY (clear_ip_eigrp_neighbors_IP,
380 clear_ip_eigrp_neighbors_IP_cmd,
381 "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr",
382 CLEAR_STR
383 IP_STR
384 "Clear IP-EIGRP\n"
385 VRF_CMD_HELP_STR
386 "Clear IP-EIGRP neighbors\n"
387 "IP-EIGRP neighbor address\n")
388 {
389 struct eigrp *eigrp;
390 struct eigrp_neighbor *nbr;
391
392 /* Check if eigrp process is enabled */
393 eigrp = eigrp_vty_get_eigrp(vty, vrf);
394 if (eigrp == NULL) {
395 vty_out(vty, " EIGRP Routing Process not enabled\n");
396 return CMD_SUCCESS;
397 }
398
399 /* lookup neighbor in whole process */
400 nbr = eigrp_nbr_lookup_by_addr_process(eigrp, nbr_addr);
401
402 /* if neighbor doesn't exists, notify user and exit */
403 if (nbr == NULL) {
404 vty_out(vty, "Neighbor with entered address doesn't exists.\n");
405 return CMD_WARNING;
406 }
407
408 /* execute hard reset on neighbor */
409 eigrp_nbr_hard_restart(nbr, vty);
410
411 return CMD_SUCCESS;
412 }
413
414 /*
415 * Execute graceful restart for all neighbors
416 */
417 DEFPY (clear_ip_eigrp_neighbors_soft,
418 clear_ip_eigrp_neighbors_soft_cmd,
419 "clear ip eigrp [vrf NAME] neighbors soft",
420 CLEAR_STR
421 IP_STR
422 "Clear IP-EIGRP\n"
423 VRF_CMD_HELP_STR
424 "Clear IP-EIGRP neighbors\n"
425 "Resync with peers without adjacency reset\n")
426 {
427 struct eigrp *eigrp;
428
429 /* Check if eigrp process is enabled */
430 eigrp = eigrp_vty_get_eigrp(vty, vrf);
431 if (eigrp == NULL) {
432 vty_out(vty, " EIGRP Routing Process not enabled\n");
433 return CMD_SUCCESS;
434 }
435
436 /* execute graceful restart on all neighbors */
437 eigrp_update_send_process_GR(eigrp, EIGRP_GR_MANUAL, vty);
438
439 return CMD_SUCCESS;
440 }
441
442 /*
443 * Execute graceful restart for all neighbors on interface
444 */
445 DEFPY (clear_ip_eigrp_neighbors_int_soft,
446 clear_ip_eigrp_neighbors_int_soft_cmd,
447 "clear ip eigrp [vrf NAME] neighbors IFNAME soft",
448 CLEAR_STR
449 IP_STR
450 "Clear IP-EIGRP\n"
451 VRF_CMD_HELP_STR
452 "Clear IP-EIGRP neighbors\n"
453 "Interface's name\n"
454 "Resync with peer without adjacency reset\n")
455 {
456 struct eigrp *eigrp;
457 struct eigrp_interface *ei;
458
459 /* Check if eigrp process is enabled */
460 eigrp = eigrp_vty_get_eigrp(vty, vrf);
461 if (eigrp == NULL) {
462 vty_out(vty, " EIGRP Routing Process not enabled\n");
463 return CMD_SUCCESS;
464 }
465
466 /* lookup interface by specified name */
467 ei = eigrp_if_lookup_by_name(eigrp, ifname);
468 if (ei == NULL) {
469 vty_out(vty, " Interface (%s) doesn't exist\n", argv[4]->arg);
470 return CMD_WARNING;
471 }
472
473 /* execute graceful restart for all neighbors on interface */
474 eigrp_update_send_interface_GR(ei, EIGRP_GR_MANUAL, vty);
475 return CMD_SUCCESS;
476 }
477
478 /*
479 * Execute graceful restart for neighbor specified by IP
480 */
481 DEFPY (clear_ip_eigrp_neighbors_IP_soft,
482 clear_ip_eigrp_neighbors_IP_soft_cmd,
483 "clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr soft",
484 CLEAR_STR
485 IP_STR
486 "Clear IP-EIGRP\n"
487 VRF_CMD_HELP_STR
488 "Clear IP-EIGRP neighbors\n"
489 "IP-EIGRP neighbor address\n"
490 "Resync with peer without adjacency reset\n")
491 {
492 struct eigrp *eigrp;
493 struct eigrp_neighbor *nbr;
494
495
496 /* Check if eigrp process is enabled */
497 eigrp = eigrp_vty_get_eigrp(vty, vrf);
498 if (eigrp == NULL) {
499 vty_out(vty, " EIGRP Routing Process not enabled\n");
500 return CMD_SUCCESS;
501 }
502
503 /* lookup neighbor in whole process */
504 nbr = eigrp_nbr_lookup_by_addr_process(eigrp, nbr_addr);
505
506 /* if neighbor doesn't exists, notify user and exit */
507 if (nbr == NULL) {
508 vty_out(vty, "Neighbor with entered address doesn't exists.\n");
509 return CMD_WARNING;
510 }
511
512 /* execute graceful restart on neighbor */
513 eigrp_update_send_GR(nbr, EIGRP_GR_MANUAL, vty);
514
515 return CMD_SUCCESS;
516 }
517
518 void eigrp_vty_show_init(void)
519 {
520 install_element(VIEW_NODE, &show_ip_eigrp_interfaces_cmd);
521
522 install_element(VIEW_NODE, &show_ip_eigrp_neighbors_cmd);
523
524 install_element(VIEW_NODE, &show_ip_eigrp_topology_cmd);
525 install_element(VIEW_NODE, &show_ip_eigrp_topology_all_cmd);
526 }
527
528 /* Install EIGRP related vty commands. */
529 void eigrp_vty_init(void)
530 {
531 /* commands for manual hard restart */
532 install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_cmd);
533 install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_int_cmd);
534 install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_IP_cmd);
535 /* commands for manual graceful restart */
536 install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_soft_cmd);
537 install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_int_soft_cmd);
538 install_element(ENABLE_NODE, &clear_ip_eigrp_neighbors_IP_soft_cmd);
539 }