]> git.proxmox.com Git - mirror_frr.git/blob - eigrpd/eigrp_dump.c
Merge pull request #6753 from mjstapp/fix_zebra_backup_sa
[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, R - Reply\n r - reply Status, s - sia Status\n\n");
238 }
239
240 void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn)
241 {
242 struct list *successors = eigrp_topology_get_successor(tn);
243 char buffer[PREFIX_STRLEN];
244
245 vty_out(vty, "%-3c", (tn->state > 0) ? 'A' : 'P');
246
247 vty_out(vty, "%s, ",
248 prefix2str(tn->destination, buffer, PREFIX_STRLEN));
249 vty_out(vty, "%u successors, ", (successors) ? successors->count : 0);
250 vty_out(vty, "FD is %u, serno: %" PRIu64 " \n", tn->fdistance,
251 tn->serno);
252
253 if (successors)
254 list_delete(&successors);
255 }
256
257 void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp,
258 struct eigrp_nexthop_entry *te, bool *first)
259 {
260 if (te->reported_distance == EIGRP_MAX_METRIC)
261 return;
262
263 if (*first) {
264 show_ip_eigrp_prefix_entry(vty, te->prefix);
265 *first = false;
266 }
267
268 if (te->adv_router == eigrp->neighbor_self)
269 vty_out(vty, "%-7s%s, %s\n", " ", "via Connected",
270 IF_NAME(te->ei));
271 else {
272 vty_out(vty, "%-7s%s%s (%u/%u), %s\n", " ", "via ",
273 inet_ntoa(te->adv_router->src), te->distance,
274 te->reported_distance, IF_NAME(te->ei));
275 }
276 }
277
278
279 DEFUN_NOSH (show_debugging_eigrp,
280 show_debugging_eigrp_cmd,
281 "show debugging [eigrp]",
282 SHOW_STR
283 DEBUG_STR
284 EIGRP_STR)
285 {
286 int i;
287
288 vty_out(vty, "EIGRP debugging status:\n");
289
290 /* Show debug status for events. */
291 if (IS_DEBUG_EIGRP(event, EVENT))
292 vty_out(vty, " EIGRP event debugging is on\n");
293
294 /* Show debug status for EIGRP Packets. */
295 for (i = 0; i < 11; i++) {
296 if (i == 8)
297 continue;
298
299 if (IS_DEBUG_EIGRP_PACKET(i, SEND)
300 && IS_DEBUG_EIGRP_PACKET(i, RECV)) {
301 vty_out(vty, " EIGRP packet %s%s debugging is on\n",
302 lookup_msg(eigrp_packet_type_str, i + 1, NULL),
303 IS_DEBUG_EIGRP_PACKET(i, PACKET_DETAIL)
304 ? " detail"
305 : "");
306 } else {
307 if (IS_DEBUG_EIGRP_PACKET(i, SEND))
308 vty_out(vty,
309 " EIGRP packet %s send%s debugging is on\n",
310 lookup_msg(eigrp_packet_type_str, i + 1,
311 NULL),
312 IS_DEBUG_EIGRP_PACKET(i, PACKET_DETAIL)
313 ? " detail"
314 : "");
315 if (IS_DEBUG_EIGRP_PACKET(i, RECV))
316 vty_out(vty,
317 " EIGRP packet %s receive%s debugging is on\n",
318 lookup_msg(eigrp_packet_type_str, i + 1,
319 NULL),
320 IS_DEBUG_EIGRP_PACKET(i, PACKET_DETAIL)
321 ? " detail"
322 : "");
323 }
324 }
325
326 return CMD_SUCCESS;
327 }
328
329
330 /*
331 [no] debug eigrp packet (hello|dd|ls-request|ls-update|ls-ack|all)
332 [send|recv [detail]]
333 */
334
335 DEFUN (debug_eigrp_transmit,
336 debug_eigrp_transmit_cmd,
337 "debug eigrp transmit <send|recv|all> [detail]",
338 DEBUG_STR
339 EIGRP_STR
340 "EIGRP transmission events\n"
341 "packet sent\n"
342 "packet received\n"
343 "all packets\n"
344 "Detailed Information\n")
345 {
346 int flag = 0;
347 int idx = 2;
348
349 /* send or recv. */
350 if (argv_find(argv, argc, "send", &idx))
351 flag = EIGRP_DEBUG_SEND;
352 else if (argv_find(argv, argc, "recv", &idx))
353 flag = EIGRP_DEBUG_RECV;
354 else if (argv_find(argv, argc, "all", &idx))
355 flag = EIGRP_DEBUG_SEND_RECV;
356
357 /* detail option */
358 if (argv_find(argv, argc, "detail", &idx))
359 flag = EIGRP_DEBUG_PACKET_DETAIL;
360
361 if (vty->node == CONFIG_NODE)
362 DEBUG_TRANSMIT_ON(0, flag);
363 else
364 TERM_DEBUG_TRANSMIT_ON(0, flag);
365
366 return CMD_SUCCESS;
367 }
368
369 DEFUN (no_debug_eigrp_transmit,
370 no_debug_eigrp_transmit_cmd,
371 "no debug eigrp transmit <send|recv|all> [detail]",
372 NO_STR
373 UNDEBUG_STR
374 EIGRP_STR
375 "EIGRP transmission events\n"
376 "packet sent\n"
377 "packet received\n"
378 "all packets\n"
379 "Detailed Information\n")
380 {
381 int flag = 0;
382 int idx = 3;
383
384 /* send or recv. */
385 if (argv_find(argv, argc, "send", &idx))
386 flag = EIGRP_DEBUG_SEND;
387 else if (argv_find(argv, argc, "recv", &idx))
388 flag = EIGRP_DEBUG_RECV;
389 else if (argv_find(argv, argc, "all", &idx))
390 flag = EIGRP_DEBUG_SEND_RECV;
391
392 /* detail option */
393 if (argv_find(argv, argc, "detail", &idx))
394 flag = EIGRP_DEBUG_PACKET_DETAIL;
395
396 if (vty->node == CONFIG_NODE)
397 DEBUG_TRANSMIT_OFF(0, flag);
398 else
399 TERM_DEBUG_TRANSMIT_OFF(0, flag);
400
401 return CMD_SUCCESS;
402 }
403
404 DEFUN (debug_eigrp_packets,
405 debug_eigrp_packets_all_cmd,
406 "debug eigrp packets <siaquery|siareply|ack|hello|probe|query|reply|request|retry|stub|terse|update|all> [send|receive] [detail]",
407 DEBUG_STR
408 EIGRP_STR
409 "EIGRP packets\n"
410 "EIGRP SIA-Query packets\n"
411 "EIGRP SIA-Reply packets\n"
412 "EIGRP ack packets\n"
413 "EIGRP hello packets\n"
414 "EIGRP probe packets\n"
415 "EIGRP query packets\n"
416 "EIGRP reply packets\n"
417 "EIGRP request packets\n"
418 "EIGRP retransmissions\n"
419 "EIGRP stub packets\n"
420 "Display all EIGRP packets except Hellos\n"
421 "EIGRP update packets\n"
422 "Display all EIGRP packets\n"
423 "Send Packets\n"
424 "Receive Packets\n"
425 "Detail Information\n")
426 {
427 int type = 0;
428 int flag = 0;
429 int i;
430 int idx = 0;
431
432 /* Check packet type. */
433 if (argv_find(argv, argc, "hello", &idx))
434 type = EIGRP_DEBUG_HELLO;
435 if (argv_find(argv, argc, "update", &idx))
436 type = EIGRP_DEBUG_UPDATE;
437 if (argv_find(argv, argc, "query", &idx))
438 type = EIGRP_DEBUG_QUERY;
439 if (argv_find(argv, argc, "ack", &idx))
440 type = EIGRP_DEBUG_ACK;
441 if (argv_find(argv, argc, "probe", &idx))
442 type = EIGRP_DEBUG_PROBE;
443 if (argv_find(argv, argc, "stub", &idx))
444 type = EIGRP_DEBUG_STUB;
445 if (argv_find(argv, argc, "reply", &idx))
446 type = EIGRP_DEBUG_REPLY;
447 if (argv_find(argv, argc, "request", &idx))
448 type = EIGRP_DEBUG_REQUEST;
449 if (argv_find(argv, argc, "siaquery", &idx))
450 type = EIGRP_DEBUG_SIAQUERY;
451 if (argv_find(argv, argc, "siareply", &idx))
452 type = EIGRP_DEBUG_SIAREPLY;
453 if (argv_find(argv, argc, "all", &idx))
454 type = EIGRP_DEBUG_PACKETS_ALL;
455
456
457 /* All packet types, both send and recv. */
458 flag = EIGRP_DEBUG_SEND_RECV;
459
460 /* send or recv. */
461 if (argv_find(argv, argc, "s", &idx))
462 flag = EIGRP_DEBUG_SEND;
463 else if (argv_find(argv, argc, "r", &idx))
464 flag = EIGRP_DEBUG_RECV;
465
466 /* detail. */
467 if (argv_find(argv, argc, "detail", &idx))
468 flag |= EIGRP_DEBUG_PACKET_DETAIL;
469
470 for (i = 0; i < 11; i++)
471 if (type & (0x01 << i)) {
472 if (vty->node == CONFIG_NODE)
473 DEBUG_PACKET_ON(i, flag);
474 else
475 TERM_DEBUG_PACKET_ON(i, flag);
476 }
477
478 return CMD_SUCCESS;
479 }
480
481 DEFUN (no_debug_eigrp_packets,
482 no_debug_eigrp_packets_all_cmd,
483 "no debug eigrp packets <siaquery|siareply|ack|hello|probe|query|reply|request|retry|stub|terse|update|all> [send|receive] [detail]",
484 NO_STR
485 UNDEBUG_STR
486 EIGRP_STR
487 "EIGRP packets\n"
488 "EIGRP SIA-Query packets\n"
489 "EIGRP SIA-Reply packets\n"
490 "EIGRP ack packets\n"
491 "EIGRP hello packets\n"
492 "EIGRP probe packets\n"
493 "EIGRP query packets\n"
494 "EIGRP reply packets\n"
495 "EIGRP request packets\n"
496 "EIGRP retransmissions\n"
497 "EIGRP stub packets\n"
498 "Display all EIGRP packets except Hellos\n"
499 "EIGRP update packets\n"
500 "Display all EIGRP packets\n"
501 "Send Packets\n"
502 "Receive Packets\n"
503 "Detailed Information\n")
504 {
505 int type = 0;
506 int flag = 0;
507 int i;
508 int idx = 0;
509
510 /* Check packet type. */
511 if (argv_find(argv, argc, "hello", &idx))
512 type = EIGRP_DEBUG_HELLO;
513 if (argv_find(argv, argc, "update", &idx))
514 type = EIGRP_DEBUG_UPDATE;
515 if (argv_find(argv, argc, "query", &idx))
516 type = EIGRP_DEBUG_QUERY;
517 if (argv_find(argv, argc, "ack", &idx))
518 type = EIGRP_DEBUG_ACK;
519 if (argv_find(argv, argc, "probe", &idx))
520 type = EIGRP_DEBUG_PROBE;
521 if (argv_find(argv, argc, "stub", &idx))
522 type = EIGRP_DEBUG_STUB;
523 if (argv_find(argv, argc, "reply", &idx))
524 type = EIGRP_DEBUG_REPLY;
525 if (argv_find(argv, argc, "request", &idx))
526 type = EIGRP_DEBUG_REQUEST;
527 if (argv_find(argv, argc, "siaquery", &idx))
528 type = EIGRP_DEBUG_SIAQUERY;
529 if (argv_find(argv, argc, "siareply", &idx))
530 type = EIGRP_DEBUG_SIAREPLY;
531
532 /* Default, both send and recv. */
533 flag = EIGRP_DEBUG_SEND_RECV;
534
535 /* send or recv. */
536 if (argv_find(argv, argc, "send", &idx))
537 flag = EIGRP_DEBUG_SEND;
538 else if (argv_find(argv, argc, "reply", &idx))
539 flag = EIGRP_DEBUG_RECV;
540
541 /* detail. */
542 if (argv_find(argv, argc, "detail", &idx))
543 flag |= EIGRP_DEBUG_PACKET_DETAIL;
544
545 for (i = 0; i < 11; i++)
546 if (type & (0x01 << i)) {
547 if (vty->node == CONFIG_NODE)
548 DEBUG_PACKET_OFF(i, flag);
549 else
550 TERM_DEBUG_PACKET_OFF(i, flag);
551 }
552
553 return CMD_SUCCESS;
554 }
555
556 /* Debug node. */
557 static int config_write_debug(struct vty *vty);
558 static struct cmd_node eigrp_debug_node = {
559 .name = "debug",
560 .node = DEBUG_NODE,
561 .prompt = "",
562 .config_write = config_write_debug,
563 };
564
565 /* Initialize debug commands. */
566 void eigrp_debug_init(void)
567 {
568 install_node(&eigrp_debug_node);
569
570 install_element(ENABLE_NODE, &show_debugging_eigrp_cmd);
571 install_element(ENABLE_NODE, &debug_eigrp_packets_all_cmd);
572 install_element(ENABLE_NODE, &no_debug_eigrp_packets_all_cmd);
573 install_element(ENABLE_NODE, &debug_eigrp_transmit_cmd);
574 install_element(ENABLE_NODE, &no_debug_eigrp_transmit_cmd);
575
576 install_element(CONFIG_NODE, &show_debugging_eigrp_cmd);
577 install_element(CONFIG_NODE, &debug_eigrp_packets_all_cmd);
578 install_element(CONFIG_NODE, &no_debug_eigrp_packets_all_cmd);
579 install_element(CONFIG_NODE, &debug_eigrp_transmit_cmd);
580 install_element(CONFIG_NODE, &no_debug_eigrp_transmit_cmd);
581 }