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