]> git.proxmox.com Git - mirror_frr.git/blob - eigrpd/eigrp_dump.c
*: move CLI node names to cmd_node->name
[mirror_frr.git] / eigrpd / eigrp_dump.c
1 /*
2 * EIGRP Dump Functions and Debugging.
3 * Copyright (C) 2013-2014
4 * Authors:
5 * Donnie Savage
6 * Jan Janovic
7 * Matej Perina
8 * Peter Orsag
9 * Peter Paluch
10 *
11 * This file is part of GNU Zebra.
12 *
13 * GNU Zebra is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2, or (at your option) any
16 * later version.
17 *
18 * GNU Zebra is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; see the file COPYING; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 */
27
28 #include <zebra.h>
29
30 #include "linklist.h"
31 #include "thread.h"
32 #include "prefix.h"
33 #include "command.h"
34 #include "stream.h"
35 #include "log.h"
36 #include "sockopt.h"
37 #include "table.h"
38 #include "keychain.h"
39
40 #include "eigrpd/eigrp_structs.h"
41 #include "eigrpd/eigrpd.h"
42 #include "eigrpd/eigrp_interface.h"
43 #include "eigrpd/eigrp_neighbor.h"
44 #include "eigrpd/eigrp_packet.h"
45 #include "eigrpd/eigrp_zebra.h"
46 #include "eigrpd/eigrp_vty.h"
47 #include "eigrpd/eigrp_network.h"
48 #include "eigrpd/eigrp_dump.h"
49 #include "eigrpd/eigrp_topology.h"
50
51 /* Enable debug option variables -- valid only session. */
52 unsigned long term_debug_eigrp = 0;
53 unsigned long term_debug_eigrp_nei = 0;
54 unsigned long term_debug_eigrp_packet[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
55 unsigned long term_debug_eigrp_zebra = 6;
56 unsigned long term_debug_eigrp_transmit = 0;
57
58 /* Configuration debug option variables. */
59 unsigned long conf_debug_eigrp = 0;
60 unsigned long conf_debug_eigrp_nei = 0;
61 unsigned long conf_debug_eigrp_packet[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
62 unsigned long conf_debug_eigrp_zebra = 0;
63 unsigned long conf_debug_eigrp_transmit = 0;
64
65
66 static int config_write_debug(struct vty *vty)
67 {
68 int write = 0;
69 int i;
70
71 const char *type_str[] = {"update", "request", "query", "reply",
72 "hello", "", "probe", "ack",
73 "", "SIA query", "SIA reply", "stub",
74 "all"};
75 const char *detail_str[] = {
76 "", " send", " recv", "",
77 " detail", " send detail", " recv detail", " detail"};
78
79
80 /* debug eigrp event. */
81
82 /* debug eigrp packet */
83 for (i = 0; i < 10; i++) {
84 if (conf_debug_eigrp_packet[i] == 0
85 && term_debug_eigrp_packet[i] == 0)
86 continue;
87
88 vty_out(vty, "debug eigrp packet %s%s\n", type_str[i],
89 detail_str[conf_debug_eigrp_packet[i]]);
90 write = 1;
91 }
92
93 return write;
94 }
95
96 static int eigrp_neighbor_packet_queue_sum(struct eigrp_interface *ei)
97 {
98 struct eigrp_neighbor *nbr;
99 struct listnode *node, *nnode;
100 int sum;
101 sum = 0;
102
103 for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) {
104 sum += nbr->retrans_queue->count;
105 }
106
107 return sum;
108 }
109
110 /*
111 * Expects header to be in host order
112 */
113 void eigrp_ip_header_dump(struct ip *iph)
114 {
115 /* IP Header dump. */
116 zlog_debug("ip_v %u", iph->ip_v);
117 zlog_debug("ip_hl %u", iph->ip_hl);
118 zlog_debug("ip_tos %u", iph->ip_tos);
119 zlog_debug("ip_len %u", iph->ip_len);
120 zlog_debug("ip_id %u", (uint32_t)iph->ip_id);
121 zlog_debug("ip_off %u", (uint32_t)iph->ip_off);
122 zlog_debug("ip_ttl %u", iph->ip_ttl);
123 zlog_debug("ip_p %u", iph->ip_p);
124 zlog_debug("ip_sum 0x%x", (uint32_t)iph->ip_sum);
125 zlog_debug("ip_src %s", inet_ntoa(iph->ip_src));
126 zlog_debug("ip_dst %s", inet_ntoa(iph->ip_dst));
127 }
128
129 /*
130 * Expects header to be in host order
131 */
132 void eigrp_header_dump(struct eigrp_header *eigrph)
133 {
134 /* EIGRP Header dump. */
135 zlog_debug("eigrp_version %u", eigrph->version);
136 zlog_debug("eigrp_opcode %u", eigrph->opcode);
137 zlog_debug("eigrp_checksum 0x%x", ntohs(eigrph->checksum));
138 zlog_debug("eigrp_flags 0x%x", ntohl(eigrph->flags));
139 zlog_debug("eigrp_sequence %u", ntohl(eigrph->sequence));
140 zlog_debug("eigrp_ack %u", ntohl(eigrph->ack));
141 zlog_debug("eigrp_vrid %u", ntohs(eigrph->vrid));
142 zlog_debug("eigrp_AS %u", ntohs(eigrph->ASNumber));
143 }
144
145 const char *eigrp_if_name_string(struct eigrp_interface *ei)
146 {
147 if (!ei)
148 return "inactive";
149
150 return ei->ifp->name;
151 }
152
153 void show_ip_eigrp_interface_header(struct vty *vty, struct eigrp *eigrp)
154 {
155
156 vty_out(vty,
157 "\nEIGRP interfaces for AS(%d)\n\n %-10s %-10s %-10s %-6s %-12s %-7s %-14s %-12s %-8s %-8s %-8s\n %-39s %-12s %-7s %-14s %-12s %-8s\n",
158 eigrp->AS, "Interface", "Bandwidth", "Delay", "Peers",
159 "Xmit Queue", "Mean", "Pacing Time", "Multicast", "Pending",
160 "Hello", "Holdtime", "", "Un/Reliable", "SRTT", "Un/Reliable",
161 "Flow Timer", "Routes");
162 }
163
164 void show_ip_eigrp_interface_sub(struct vty *vty, struct eigrp *eigrp,
165 struct eigrp_interface *ei)
166 {
167 vty_out(vty, "%-11s ", IF_NAME(ei));
168 vty_out(vty, "%-11u", ei->params.bandwidth);
169 vty_out(vty, "%-11u", ei->params.delay);
170 vty_out(vty, "%-7u", ei->nbrs->count);
171 vty_out(vty, "%u %c %-10u", 0, '/',
172 eigrp_neighbor_packet_queue_sum(ei));
173 vty_out(vty, "%-7u %-14u %-12u %-8u", 0, 0, 0, 0);
174 vty_out(vty, "%-8u %-8u \n", ei->params.v_hello, ei->params.v_wait);
175 }
176
177 void show_ip_eigrp_interface_detail(struct vty *vty, struct eigrp *eigrp,
178 struct eigrp_interface *ei)
179 {
180 vty_out(vty, "%-2s %s %d %-3s \n", "", "Hello interval is ", 0, " sec");
181 vty_out(vty, "%-2s %s %s \n", "", "Next xmit serial", "<none>");
182 vty_out(vty, "%-2s %s %d %s %d %s %d %s %d \n", "",
183 "Un/reliable mcasts: ", 0, "/", 0, "Un/reliable ucasts: ", 0,
184 "/", 0);
185 vty_out(vty, "%-2s %s %d %s %d %s %d \n", "", "Mcast exceptions: ", 0,
186 " CR packets: ", 0, " ACKs suppressed: ", 0);
187 vty_out(vty, "%-2s %s %d %s %d \n", "", "Retransmissions sent: ", 0,
188 "Out-of-sequence rcvd: ", 0);
189 vty_out(vty, "%-2s %s %s %s \n", "", "Authentication mode is ", "not",
190 "set");
191 vty_out(vty, "%-2s %s \n", "", "Use multicast");
192 }
193
194 void show_ip_eigrp_neighbor_header(struct vty *vty, struct eigrp *eigrp)
195 {
196 vty_out(vty,
197 "\nEIGRP neighbors for AS(%d)\n\n%-3s %-17s %-20s %-6s %-8s %-6s %-5s %-5s %-5s\n %-41s %-6s %-8s %-6s %-4s %-6s %-5s \n",
198 eigrp->AS, "H", "Address", "Interface", "Hold", "Uptime",
199 "SRTT", "RTO", "Q", "Seq", "", "(sec)", "", "(ms)", "", "Cnt",
200 "Num");
201 }
202
203 void show_ip_eigrp_neighbor_sub(struct vty *vty, struct eigrp_neighbor *nbr,
204 int detail)
205 {
206
207 vty_out(vty, "%-3u %-17s %-21s", 0, eigrp_neigh_ip_string(nbr),
208 IF_NAME(nbr->ei));
209 if (nbr->t_holddown)
210 vty_out(vty, "%-7lu",
211 thread_timer_remain_second(nbr->t_holddown));
212 else
213 vty_out(vty, "- ");
214 vty_out(vty, "%-8u %-6u %-5u", 0, 0, EIGRP_PACKET_RETRANS_TIME);
215 vty_out(vty, "%-7lu", nbr->retrans_queue->count);
216 vty_out(vty, "%u\n", nbr->recv_sequence_number);
217
218
219 if (detail) {
220 vty_out(vty, " Version %u.%u/%u.%u", nbr->os_rel_major,
221 nbr->os_rel_minor, nbr->tlv_rel_major,
222 nbr->tlv_rel_minor);
223 vty_out(vty, ", Retrans: %lu, Retries: %lu",
224 nbr->retrans_queue->count, 0UL);
225 vty_out(vty, ", %s\n", eigrp_nbr_state_str(nbr));
226 }
227 }
228
229 /*
230 * Print standard header for show EIGRP topology output
231 */
232 void show_ip_eigrp_topology_header(struct vty *vty, struct eigrp *eigrp)
233 {
234 vty_out(vty, "\nEIGRP Topology Table for AS(%d)/ID(%s)\n\n", eigrp->AS,
235 inet_ntoa(eigrp->router_id));
236 vty_out(vty,
237 "Codes: P - Passive, A - Active, U - Update, Q - Query, "
238 "R - Reply\n r - reply Status, s - sia Status\n\n");
239 }
240
241 void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn)
242 {
243 struct list *successors = eigrp_topology_get_successor(tn);
244 char buffer[PREFIX_STRLEN];
245
246 vty_out(vty, "%-3c", (tn->state > 0) ? 'A' : 'P');
247
248 vty_out(vty, "%s, ",
249 prefix2str(tn->destination, buffer, PREFIX_STRLEN));
250 vty_out(vty, "%u successors, ", (successors) ? successors->count : 0);
251 vty_out(vty, "FD is %u, serno: %" PRIu64 " \n", tn->fdistance,
252 tn->serno);
253
254 if (successors)
255 list_delete(&successors);
256 }
257
258 void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp,
259 struct eigrp_nexthop_entry *te, bool *first)
260 {
261 if (te->reported_distance == EIGRP_MAX_METRIC)
262 return;
263
264 if (*first) {
265 show_ip_eigrp_prefix_entry(vty, te->prefix);
266 *first = false;
267 }
268
269 if (te->adv_router == eigrp->neighbor_self)
270 vty_out(vty, "%-7s%s, %s\n", " ", "via Connected",
271 IF_NAME(te->ei));
272 else {
273 vty_out(vty, "%-7s%s%s (%u/%u), %s\n", " ", "via ",
274 inet_ntoa(te->adv_router->src), te->distance,
275 te->reported_distance, IF_NAME(te->ei));
276 }
277 }
278
279
280 DEFUN_NOSH (show_debugging_eigrp,
281 show_debugging_eigrp_cmd,
282 "show debugging [eigrp]",
283 SHOW_STR
284 DEBUG_STR
285 EIGRP_STR)
286 {
287 int i;
288
289 vty_out(vty, "EIGRP debugging status:\n");
290
291 /* Show debug status for events. */
292 if (IS_DEBUG_EIGRP(event, EVENT))
293 vty_out(vty, " EIGRP event debugging is on\n");
294
295 /* Show debug status for EIGRP Packets. */
296 for (i = 0; i < 11; i++) {
297 if (i == 8)
298 continue;
299
300 if (IS_DEBUG_EIGRP_PACKET(i, SEND)
301 && IS_DEBUG_EIGRP_PACKET(i, RECV)) {
302 vty_out(vty, " EIGRP packet %s%s debugging is on\n",
303 lookup_msg(eigrp_packet_type_str, i + 1, NULL),
304 IS_DEBUG_EIGRP_PACKET(i, PACKET_DETAIL)
305 ? " detail"
306 : "");
307 } else {
308 if (IS_DEBUG_EIGRP_PACKET(i, SEND))
309 vty_out(vty,
310 " EIGRP packet %s send%s debugging is on\n",
311 lookup_msg(eigrp_packet_type_str, i + 1,
312 NULL),
313 IS_DEBUG_EIGRP_PACKET(i, PACKET_DETAIL)
314 ? " detail"
315 : "");
316 if (IS_DEBUG_EIGRP_PACKET(i, RECV))
317 vty_out(vty,
318 " EIGRP packet %s receive%s debugging is on\n",
319 lookup_msg(eigrp_packet_type_str, i + 1,
320 NULL),
321 IS_DEBUG_EIGRP_PACKET(i, PACKET_DETAIL)
322 ? " detail"
323 : "");
324 }
325 }
326
327 return CMD_SUCCESS;
328 }
329
330
331 /*
332 [no] debug eigrp packet (hello|dd|ls-request|ls-update|ls-ack|all)
333 [send|recv [detail]]
334 */
335
336 DEFUN (debug_eigrp_transmit,
337 debug_eigrp_transmit_cmd,
338 "debug eigrp transmit <send|recv|all> [detail]",
339 DEBUG_STR
340 EIGRP_STR
341 "EIGRP transmission events\n"
342 "packet sent\n"
343 "packet received\n"
344 "all packets\n"
345 "Detailed Information\n")
346 {
347 int flag = 0;
348 int idx = 2;
349
350 /* send or recv. */
351 if (argv_find(argv, argc, "send", &idx))
352 flag = EIGRP_DEBUG_SEND;
353 else if (argv_find(argv, argc, "recv", &idx))
354 flag = EIGRP_DEBUG_RECV;
355 else if (argv_find(argv, argc, "all", &idx))
356 flag = EIGRP_DEBUG_SEND_RECV;
357
358 /* detail option */
359 if (argv_find(argv, argc, "detail", &idx))
360 flag = EIGRP_DEBUG_PACKET_DETAIL;
361
362 if (vty->node == CONFIG_NODE)
363 DEBUG_TRANSMIT_ON(0, flag);
364 else
365 TERM_DEBUG_TRANSMIT_ON(0, flag);
366
367 return CMD_SUCCESS;
368 }
369
370 DEFUN (no_debug_eigrp_transmit,
371 no_debug_eigrp_transmit_cmd,
372 "no debug eigrp transmit <send|recv|all> [detail]",
373 NO_STR
374 UNDEBUG_STR
375 EIGRP_STR
376 "EIGRP transmission events\n"
377 "packet sent\n"
378 "packet received\n"
379 "all packets\n"
380 "Detailed Information\n")
381 {
382 int flag = 0;
383 int idx = 3;
384
385 /* send or recv. */
386 if (argv_find(argv, argc, "send", &idx))
387 flag = EIGRP_DEBUG_SEND;
388 else if (argv_find(argv, argc, "recv", &idx))
389 flag = EIGRP_DEBUG_RECV;
390 else if (argv_find(argv, argc, "all", &idx))
391 flag = EIGRP_DEBUG_SEND_RECV;
392
393 /* detail option */
394 if (argv_find(argv, argc, "detail", &idx))
395 flag = EIGRP_DEBUG_PACKET_DETAIL;
396
397 if (vty->node == CONFIG_NODE)
398 DEBUG_TRANSMIT_OFF(0, flag);
399 else
400 TERM_DEBUG_TRANSMIT_OFF(0, flag);
401
402 return CMD_SUCCESS;
403 }
404
405 DEFUN (debug_eigrp_packets,
406 debug_eigrp_packets_all_cmd,
407 "debug eigrp packets <siaquery|siareply|ack|hello|probe|query|reply|request|retry|stub|terse|update|all> [send|receive] [detail]",
408 DEBUG_STR
409 EIGRP_STR
410 "EIGRP packets\n"
411 "EIGRP SIA-Query packets\n"
412 "EIGRP SIA-Reply packets\n"
413 "EIGRP ack packets\n"
414 "EIGRP hello packets\n"
415 "EIGRP probe packets\n"
416 "EIGRP query packets\n"
417 "EIGRP reply packets\n"
418 "EIGRP request packets\n"
419 "EIGRP retransmissions\n"
420 "EIGRP stub packets\n"
421 "Display all EIGRP packets except Hellos\n"
422 "EIGRP update packets\n"
423 "Display all EIGRP packets\n"
424 "Send Packets\n"
425 "Receive Packets\n"
426 "Detail Information\n")
427 {
428 int type = 0;
429 int flag = 0;
430 int i;
431 int idx = 0;
432
433 /* Check packet type. */
434 if (argv_find(argv, argc, "hello", &idx))
435 type = EIGRP_DEBUG_HELLO;
436 if (argv_find(argv, argc, "update", &idx))
437 type = EIGRP_DEBUG_UPDATE;
438 if (argv_find(argv, argc, "query", &idx))
439 type = EIGRP_DEBUG_QUERY;
440 if (argv_find(argv, argc, "ack", &idx))
441 type = EIGRP_DEBUG_ACK;
442 if (argv_find(argv, argc, "probe", &idx))
443 type = EIGRP_DEBUG_PROBE;
444 if (argv_find(argv, argc, "stub", &idx))
445 type = EIGRP_DEBUG_STUB;
446 if (argv_find(argv, argc, "reply", &idx))
447 type = EIGRP_DEBUG_REPLY;
448 if (argv_find(argv, argc, "request", &idx))
449 type = EIGRP_DEBUG_REQUEST;
450 if (argv_find(argv, argc, "siaquery", &idx))
451 type = EIGRP_DEBUG_SIAQUERY;
452 if (argv_find(argv, argc, "siareply", &idx))
453 type = EIGRP_DEBUG_SIAREPLY;
454 if (argv_find(argv, argc, "all", &idx))
455 type = EIGRP_DEBUG_PACKETS_ALL;
456
457
458 /* All packet types, both send and recv. */
459 flag = EIGRP_DEBUG_SEND_RECV;
460
461 /* send or recv. */
462 if (argv_find(argv, argc, "s", &idx))
463 flag = EIGRP_DEBUG_SEND;
464 else if (argv_find(argv, argc, "r", &idx))
465 flag = EIGRP_DEBUG_RECV;
466
467 /* detail. */
468 if (argv_find(argv, argc, "detail", &idx))
469 flag |= EIGRP_DEBUG_PACKET_DETAIL;
470
471 for (i = 0; i < 11; i++)
472 if (type & (0x01 << i)) {
473 if (vty->node == CONFIG_NODE)
474 DEBUG_PACKET_ON(i, flag);
475 else
476 TERM_DEBUG_PACKET_ON(i, flag);
477 }
478
479 return CMD_SUCCESS;
480 }
481
482 DEFUN (no_debug_eigrp_packets,
483 no_debug_eigrp_packets_all_cmd,
484 "no debug eigrp packets <siaquery|siareply|ack|hello|probe|query|reply|request|retry|stub|terse|update|all> [send|receive] [detail]",
485 NO_STR
486 UNDEBUG_STR
487 EIGRP_STR
488 "EIGRP packets\n"
489 "EIGRP SIA-Query packets\n"
490 "EIGRP SIA-Reply packets\n"
491 "EIGRP ack packets\n"
492 "EIGRP hello packets\n"
493 "EIGRP probe packets\n"
494 "EIGRP query packets\n"
495 "EIGRP reply packets\n"
496 "EIGRP request packets\n"
497 "EIGRP retransmissions\n"
498 "EIGRP stub packets\n"
499 "Display all EIGRP packets except Hellos\n"
500 "EIGRP update packets\n"
501 "Display all EIGRP packets\n"
502 "Send Packets\n"
503 "Receive Packets\n"
504 "Detailed Information\n")
505 {
506 int type = 0;
507 int flag = 0;
508 int i;
509 int idx = 0;
510
511 /* Check packet type. */
512 if (argv_find(argv, argc, "hello", &idx))
513 type = EIGRP_DEBUG_HELLO;
514 if (argv_find(argv, argc, "update", &idx))
515 type = EIGRP_DEBUG_UPDATE;
516 if (argv_find(argv, argc, "query", &idx))
517 type = EIGRP_DEBUG_QUERY;
518 if (argv_find(argv, argc, "ack", &idx))
519 type = EIGRP_DEBUG_ACK;
520 if (argv_find(argv, argc, "probe", &idx))
521 type = EIGRP_DEBUG_PROBE;
522 if (argv_find(argv, argc, "stub", &idx))
523 type = EIGRP_DEBUG_STUB;
524 if (argv_find(argv, argc, "reply", &idx))
525 type = EIGRP_DEBUG_REPLY;
526 if (argv_find(argv, argc, "request", &idx))
527 type = EIGRP_DEBUG_REQUEST;
528 if (argv_find(argv, argc, "siaquery", &idx))
529 type = EIGRP_DEBUG_SIAQUERY;
530 if (argv_find(argv, argc, "siareply", &idx))
531 type = EIGRP_DEBUG_SIAREPLY;
532
533 /* Default, both send and recv. */
534 flag = EIGRP_DEBUG_SEND_RECV;
535
536 /* send or recv. */
537 if (argv_find(argv, argc, "send", &idx))
538 flag = EIGRP_DEBUG_SEND;
539 else if (argv_find(argv, argc, "reply", &idx))
540 flag = EIGRP_DEBUG_RECV;
541
542 /* detail. */
543 if (argv_find(argv, argc, "detail", &idx))
544 flag |= EIGRP_DEBUG_PACKET_DETAIL;
545
546 for (i = 0; i < 11; i++)
547 if (type & (0x01 << i)) {
548 if (vty->node == CONFIG_NODE)
549 DEBUG_PACKET_OFF(i, flag);
550 else
551 TERM_DEBUG_PACKET_OFF(i, flag);
552 }
553
554 return CMD_SUCCESS;
555 }
556
557 /* Debug node. */
558 static int config_write_debug(struct vty *vty);
559 static struct cmd_node eigrp_debug_node = {
560 .name = "debug",
561 .node = DEBUG_NODE,
562 .prompt = "",
563 .config_write = config_write_debug,
564 };
565
566 /* Initialize debug commands. */
567 void eigrp_debug_init(void)
568 {
569 install_node(&eigrp_debug_node);
570
571 install_element(ENABLE_NODE, &show_debugging_eigrp_cmd);
572 install_element(ENABLE_NODE, &debug_eigrp_packets_all_cmd);
573 install_element(ENABLE_NODE, &no_debug_eigrp_packets_all_cmd);
574 install_element(ENABLE_NODE, &debug_eigrp_transmit_cmd);
575 install_element(ENABLE_NODE, &no_debug_eigrp_transmit_cmd);
576
577 install_element(CONFIG_NODE, &show_debugging_eigrp_cmd);
578 install_element(CONFIG_NODE, &debug_eigrp_packets_all_cmd);
579 install_element(CONFIG_NODE, &no_debug_eigrp_packets_all_cmd);
580 install_element(CONFIG_NODE, &debug_eigrp_transmit_cmd);
581 install_element(CONFIG_NODE, &no_debug_eigrp_transmit_cmd);
582 }