]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_debug.c
bgpd: Parse PMSI Tunnel Attribute and display
[mirror_frr.git] / bgpd / bgp_debug.c
CommitLineData
718e3744 1/* BGP-4, BGP-4+ packet debug routine
896014f4
DL
2 * Copyright (C) 1996, 97, 99 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
718e3744 20
21#include <zebra.h>
22
5e4fa164 23#include <lib/version.h>
718e3744 24#include "prefix.h"
25#include "linklist.h"
26#include "stream.h"
27#include "command.h"
718e3744 28#include "log.h"
29#include "sockunion.h"
16286195 30#include "memory.h"
3f9c7369 31#include "queue.h"
039f3a34 32#include "filter.h"
718e3744 33
34#include "bgpd/bgpd.h"
35#include "bgpd/bgp_aspath.h"
36#include "bgpd/bgp_route.h"
37#include "bgpd/bgp_attr.h"
38#include "bgpd/bgp_debug.h"
39#include "bgpd/bgp_community.h"
3f9c7369 40#include "bgpd/bgp_updgrp.h"
906ad49b 41#include "bgpd/bgp_mplsvpn.h"
a4638609 42#include "bgpd/bgp_ecommunity.h"
b16031a2 43#include "bgpd/bgp_label.h"
44#include "bgpd/bgp_evpn.h"
718e3744 45
0b2aa3a0 46unsigned long conf_bgp_debug_as4;
16286195 47unsigned long conf_bgp_debug_neighbor_events;
718e3744 48unsigned long conf_bgp_debug_events;
49unsigned long conf_bgp_debug_packet;
50unsigned long conf_bgp_debug_filter;
51unsigned long conf_bgp_debug_keepalive;
52unsigned long conf_bgp_debug_update;
9fbdd100 53unsigned long conf_bgp_debug_bestpath;
a39275d7 54unsigned long conf_bgp_debug_zebra;
cebb7440 55unsigned long conf_bgp_debug_allow_martians;
fb018d25 56unsigned long conf_bgp_debug_nht;
3f9c7369 57unsigned long conf_bgp_debug_update_groups;
718e3744 58
0b2aa3a0 59unsigned long term_bgp_debug_as4;
16286195 60unsigned long term_bgp_debug_neighbor_events;
718e3744 61unsigned long term_bgp_debug_events;
62unsigned long term_bgp_debug_packet;
63unsigned long term_bgp_debug_filter;
64unsigned long term_bgp_debug_keepalive;
65unsigned long term_bgp_debug_update;
9fbdd100 66unsigned long term_bgp_debug_bestpath;
a39275d7 67unsigned long term_bgp_debug_zebra;
cebb7440 68unsigned long term_bgp_debug_allow_martians;
fb018d25 69unsigned long term_bgp_debug_nht;
3f9c7369 70unsigned long term_bgp_debug_update_groups;
718e3744 71
16286195
DS
72struct list *bgp_debug_neighbor_events_peers = NULL;
73struct list *bgp_debug_keepalive_peers = NULL;
74struct list *bgp_debug_update_out_peers = NULL;
75struct list *bgp_debug_update_in_peers = NULL;
76struct list *bgp_debug_update_prefixes = NULL;
9fbdd100 77struct list *bgp_debug_bestpath_prefixes = NULL;
16286195
DS
78struct list *bgp_debug_zebra_prefixes = NULL;
79
718e3744 80/* messages for BGP-4 status */
d62a17ae 81const struct message bgp_status_msg[] = {{Idle, "Idle"},
82 {Connect, "Connect"},
83 {Active, "Active"},
84 {OpenSent, "OpenSent"},
85 {OpenConfirm, "OpenConfirm"},
86 {Established, "Established"},
87 {Clearing, "Clearing"},
88 {Deleted, "Deleted"},
89 {0}};
718e3744 90
91/* BGP message type string. */
d62a17ae 92const char *bgp_type_str[] = {NULL, "OPEN", "UPDATE",
93 "NOTIFICATION", "KEEPALIVE", "ROUTE-REFRESH",
94 "CAPABILITY"};
718e3744 95
96/* message for BGP-4 Notify */
d62a17ae 97static const struct message bgp_notify_msg[] = {
98 {BGP_NOTIFY_HEADER_ERR, "Message Header Error"},
99 {BGP_NOTIFY_OPEN_ERR, "OPEN Message Error"},
100 {BGP_NOTIFY_UPDATE_ERR, "UPDATE Message Error"},
101 {BGP_NOTIFY_HOLD_ERR, "Hold Timer Expired"},
102 {BGP_NOTIFY_FSM_ERR, "Neighbor Events Error"},
103 {BGP_NOTIFY_CEASE, "Cease"},
104 {BGP_NOTIFY_CAPABILITY_ERR, "CAPABILITY Message Error"},
105 {0}};
106
107static const struct message bgp_notify_head_msg[] = {
108 {BGP_NOTIFY_HEADER_NOT_SYNC, "/Connection Not Synchronized"},
109 {BGP_NOTIFY_HEADER_BAD_MESLEN, "/Bad Message Length"},
110 {BGP_NOTIFY_HEADER_BAD_MESTYPE, "/Bad Message Type"},
111 {0}};
112
113static const struct message bgp_notify_open_msg[] = {
114 {BGP_NOTIFY_SUBCODE_UNSPECIFIC, "/Unspecific"},
115 {BGP_NOTIFY_OPEN_UNSUP_VERSION, "/Unsupported Version Number"},
116 {BGP_NOTIFY_OPEN_BAD_PEER_AS, "/Bad Peer AS"},
117 {BGP_NOTIFY_OPEN_BAD_BGP_IDENT, "/Bad BGP Identifier"},
118 {BGP_NOTIFY_OPEN_UNSUP_PARAM, "/Unsupported Optional Parameter"},
119 {BGP_NOTIFY_OPEN_AUTH_FAILURE, "/Authentication Failure"},
120 {BGP_NOTIFY_OPEN_UNACEP_HOLDTIME, "/Unacceptable Hold Time"},
121 {BGP_NOTIFY_OPEN_UNSUP_CAPBL, "/Unsupported Capability"},
122 {0}};
123
124static const struct message bgp_notify_update_msg[] = {
125 {BGP_NOTIFY_SUBCODE_UNSPECIFIC, "/Unspecific"},
126 {BGP_NOTIFY_UPDATE_MAL_ATTR, "/Malformed Attribute List"},
127 {BGP_NOTIFY_UPDATE_UNREC_ATTR, "/Unrecognized Well-known Attribute"},
128 {BGP_NOTIFY_UPDATE_MISS_ATTR, "/Missing Well-known Attribute"},
129 {BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, "/Attribute Flags Error"},
130 {BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, "/Attribute Length Error"},
131 {BGP_NOTIFY_UPDATE_INVAL_ORIGIN, "/Invalid ORIGIN Attribute"},
132 {BGP_NOTIFY_UPDATE_AS_ROUTE_LOOP, "/AS Routing Loop"},
133 {BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP, "/Invalid NEXT_HOP Attribute"},
134 {BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, "/Optional Attribute Error"},
135 {BGP_NOTIFY_UPDATE_INVAL_NETWORK, "/Invalid Network Field"},
136 {BGP_NOTIFY_UPDATE_MAL_AS_PATH, "/Malformed AS_PATH"},
137 {0}};
138
139static const struct message bgp_notify_cease_msg[] = {
140 {BGP_NOTIFY_SUBCODE_UNSPECIFIC, "/Unspecific"},
141 {BGP_NOTIFY_CEASE_MAX_PREFIX, "/Maximum Number of Prefixes Reached"},
142 {BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, "/Administratively Shutdown"},
143 {BGP_NOTIFY_CEASE_PEER_UNCONFIG, "/Peer Unconfigured"},
144 {BGP_NOTIFY_CEASE_ADMIN_RESET, "/Administratively Reset"},
145 {BGP_NOTIFY_CEASE_CONNECT_REJECT, "/Connection Rejected"},
146 {BGP_NOTIFY_CEASE_CONFIG_CHANGE, "/Other Configuration Change"},
147 {BGP_NOTIFY_CEASE_COLLISION_RESOLUTION,
148 "/Connection collision resolution"},
149 {BGP_NOTIFY_CEASE_OUT_OF_RESOURCE, "/Out of Resource"},
150 {0}};
151
152static const struct message bgp_notify_capability_msg[] = {
153 {BGP_NOTIFY_SUBCODE_UNSPECIFIC, "/Unspecific"},
154 {BGP_NOTIFY_CAPABILITY_INVALID_ACTION, "/Invalid Action Value"},
155 {BGP_NOTIFY_CAPABILITY_INVALID_LENGTH, "/Invalid Capability Length"},
156 {BGP_NOTIFY_CAPABILITY_MALFORMED_CODE, "/Malformed Capability Value"},
157 {0}};
718e3744 158
159/* Origin strings. */
d62a17ae 160const char *bgp_origin_str[] = {"i", "e", "?"};
161const char *bgp_origin_long_str[] = {"IGP", "EGP", "incomplete"};
7fd077aa 162const char *pmsi_tnltype_str[] = {"No info", "RSVP-TE P2MP", "mLDP P2MP",
163 "PIM-SSM", "PIM-SM", "PIM-BIDIR",
164 "Ingress Replication", "mLDP MP2MP"};
718e3744 165
16286195
DS
166
167/* Given a string return a pointer the corresponding peer structure */
d62a17ae 168static struct peer *bgp_find_peer(struct vty *vty, const char *peer_str)
16286195 169{
d62a17ae 170 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
171 int ret;
172 union sockunion su;
173 struct peer *peer;
174
175 if (!bgp) {
176 return NULL;
177 }
178 ret = str2sockunion(peer_str, &su);
179
180 /* 'swpX' string */
181 if (ret < 0) {
182 peer = peer_lookup_by_conf_if(bgp, peer_str);
183
184 if (!peer)
185 peer = peer_lookup_by_hostname(bgp, peer_str);
186
187 return peer;
188 } else
189 return peer_lookup(bgp, &su);
16286195
DS
190}
191
d62a17ae 192static void bgp_debug_list_free(struct list *list)
16286195 193{
d62a17ae 194 struct bgp_debug_filter *filter;
195 struct listnode *node, *nnode;
16286195 196
d62a17ae 197 if (list)
198 for (ALL_LIST_ELEMENTS(list, node, nnode, filter)) {
199 listnode_delete(list, filter);
16286195 200
d62a17ae 201 if (filter->p)
202 prefix_free(filter->p);
16286195 203
d62a17ae 204 if (filter->host)
205 XFREE(MTYPE_BGP_DEBUG_STR, filter->host);
16286195 206
d62a17ae 207 XFREE(MTYPE_BGP_DEBUG_FILTER, filter);
208 }
16286195
DS
209}
210
211/* Print the desc along with a list of peers/prefixes this debug is
212 * enabled for */
d62a17ae 213static void bgp_debug_list_print(struct vty *vty, const char *desc,
214 struct list *list)
215{
216 struct bgp_debug_filter *filter;
217 struct listnode *node, *nnode;
218 char buf[INET6_ADDRSTRLEN];
219
220 vty_out(vty, "%s", desc);
221
222 if (list && !list_isempty(list)) {
223 vty_out(vty, " for");
224 for (ALL_LIST_ELEMENTS(list, node, nnode, filter)) {
225 if (filter->host)
226 vty_out(vty, " %s", filter->host);
227
228 if (filter->p)
229 vty_out(vty, " %s/%d",
230 inet_ntop(filter->p->family,
231 &filter->p->u.prefix, buf,
232 INET6_ADDRSTRLEN),
233 filter->p->prefixlen);
234 }
235 }
236
237 vty_out(vty, "\n");
16286195
DS
238}
239
91ba2c8b
DS
240/* Print the command to enable the debug for each peer/prefix this debug is
241 * enabled for
242 */
d62a17ae 243static int bgp_debug_list_conf_print(struct vty *vty, const char *desc,
244 struct list *list)
245{
246 struct bgp_debug_filter *filter;
247 struct listnode *node, *nnode;
248 char buf[INET6_ADDRSTRLEN];
249 int write = 0;
250
251 if (list && !list_isempty(list)) {
252 for (ALL_LIST_ELEMENTS(list, node, nnode, filter)) {
253 if (filter->host) {
254 vty_out(vty, "%s %s\n", desc, filter->host);
255 write++;
256 }
257
258
259 if (filter->p) {
260 vty_out(vty, "%s %s/%d\n", desc,
261 inet_ntop(filter->p->family,
262 &filter->p->u.prefix, buf,
263 INET6_ADDRSTRLEN),
264 filter->p->prefixlen);
265 write++;
266 }
267 }
268 }
269
270 if (!write) {
271 vty_out(vty, "%s\n", desc);
272 write++;
273 }
274
275 return write;
91ba2c8b
DS
276}
277
d62a17ae 278static void bgp_debug_list_add_entry(struct list *list, const char *host,
279 const struct prefix *p)
16286195 280{
d62a17ae 281 struct bgp_debug_filter *filter;
282
283 filter = XCALLOC(MTYPE_BGP_DEBUG_FILTER,
284 sizeof(struct bgp_debug_filter));
285
286 if (host) {
287 filter->host = XSTRDUP(MTYPE_BGP_DEBUG_STR, host);
288 filter->p = NULL;
289 } else if (p) {
290 filter->host = NULL;
291 filter->p = prefix_new();
292 prefix_copy(filter->p, p);
293 }
294
295 listnode_add(list, filter);
16286195
DS
296}
297
d62a17ae 298static int bgp_debug_list_remove_entry(struct list *list, const char *host,
299 struct prefix *p)
300{
301 struct bgp_debug_filter *filter;
302 struct listnode *node, *nnode;
303
304 for (ALL_LIST_ELEMENTS(list, node, nnode, filter)) {
305 if (host && strcmp(filter->host, host) == 0) {
306 listnode_delete(list, filter);
307 XFREE(MTYPE_BGP_DEBUG_STR, filter->host);
308 XFREE(MTYPE_BGP_DEBUG_FILTER, filter);
309 return 1;
310 } else if (p && filter->p->prefixlen == p->prefixlen
311 && prefix_match(filter->p, p)) {
312 listnode_delete(list, filter);
313 prefix_free(filter->p);
314 XFREE(MTYPE_BGP_DEBUG_FILTER, filter);
315 return 1;
316 }
317 }
318
319 return 0;
16286195
DS
320}
321
d62a17ae 322static int bgp_debug_list_has_entry(struct list *list, const char *host,
323 const struct prefix *p)
324{
325 struct bgp_debug_filter *filter;
326 struct listnode *node, *nnode;
327
328 for (ALL_LIST_ELEMENTS(list, node, nnode, filter)) {
329 if (host) {
330 if (strcmp(filter->host, host) == 0) {
331 return 1;
332 }
333 } else if (p) {
334 if (filter->p->prefixlen == p->prefixlen
335 && prefix_match(filter->p, p)) {
336 return 1;
337 }
338 }
339 }
340
341 return 0;
16286195
DS
342}
343
d62a17ae 344int bgp_debug_peer_updout_enabled(char *host)
3f9c7369 345{
d62a17ae 346 return (bgp_debug_list_has_entry(bgp_debug_update_out_peers, host,
347 NULL));
3f9c7369
DS
348}
349
718e3744 350/* Dump attribute. */
d62a17ae 351int bgp_dump_attr(struct attr *attr, char *buf, size_t size)
718e3744 352{
d62a17ae 353 char addrbuf[BUFSIZ];
718e3744 354
d62a17ae 355 if (!attr)
356 return 0;
357
358 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)))
359 snprintf(buf, size, "nexthop %s", inet_ntoa(attr->nexthop));
360
361 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN)))
362 snprintf(buf + strlen(buf), size - strlen(buf), ", origin %s",
363 bgp_origin_str[attr->origin]);
364
365 /* Add MP case. */
366 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
367 || attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
368 snprintf(buf + strlen(buf), size - strlen(buf),
369 ", mp_nexthop %s",
370 inet_ntop(AF_INET6, &attr->mp_nexthop_global, addrbuf,
371 BUFSIZ));
372
373 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
374 snprintf(buf + strlen(buf), size - strlen(buf), "(%s)",
375 inet_ntop(AF_INET6, &attr->mp_nexthop_local, addrbuf,
376 BUFSIZ));
377
378 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4)
379 snprintf(buf, size, "nexthop %s", inet_ntoa(attr->nexthop));
380
381 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
382 snprintf(buf + strlen(buf), size - strlen(buf),
383 ", localpref %u", attr->local_pref);
384
385 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)))
386 snprintf(buf + strlen(buf), size - strlen(buf), ", metric %u",
387 attr->med);
388
389 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)))
390 snprintf(buf + strlen(buf), size - strlen(buf),
a4d82a8a
PZ
391 ", community %s",
392 community_str(attr->community, false));
d62a17ae 393
394 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
395 snprintf(buf + strlen(buf), size - strlen(buf),
396 ", extcommunity %s", ecommunity_str(attr->ecommunity));
397
398 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
399 snprintf(buf + strlen(buf), size - strlen(buf),
400 ", atomic-aggregate");
401
402 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)))
403 snprintf(buf + strlen(buf), size - strlen(buf),
404 ", aggregated by %u %s", attr->aggregator_as,
405 inet_ntoa(attr->aggregator_addr));
406
407 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))
408 snprintf(buf + strlen(buf), size - strlen(buf),
409 ", originator %s", inet_ntoa(attr->originator_id));
410
411 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
412 int i;
413
414 snprintf(buf + strlen(buf), size - strlen(buf),
415 ", clusterlist");
416 for (i = 0; i < attr->cluster->length / 4; i++)
417 snprintf(buf + strlen(buf), size - strlen(buf), " %s",
418 inet_ntoa(attr->cluster->list[i]));
419 }
420
7fd077aa 421 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)))
422 snprintf(buf + strlen(buf), size - strlen(buf), ", pmsi tnltype %u",
423 attr->pmsi_tnl_type);
424
d62a17ae 425 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)))
426 snprintf(buf + strlen(buf), size - strlen(buf), ", path %s",
427 aspath_print(attr->aspath));
428
429 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID))) {
430 if (attr->label_index != BGP_INVALID_LABEL_INDEX)
431 snprintf(buf + strlen(buf), size - strlen(buf),
432 ", label-index %u", attr->label_index);
433 }
434
435 if (strlen(buf) > 1)
436 return 1;
437 else
438 return 0;
3a8c7ba1 439}
718e3744 440
d62a17ae 441const char *bgp_notify_code_str(char code)
3a8c7ba1 442{
d62a17ae 443 return lookup_msg(bgp_notify_msg, code, "Unrecognized Error Code");
444}
718e3744 445
d62a17ae 446const char *bgp_notify_subcode_str(char code, char subcode)
447{
448
449 switch (code) {
450 case BGP_NOTIFY_HEADER_ERR:
451 return lookup_msg(bgp_notify_head_msg, subcode,
452 "Unrecognized Error Subcode");
453 case BGP_NOTIFY_OPEN_ERR:
454 return lookup_msg(bgp_notify_open_msg, subcode,
455 "Unrecognized Error Subcode");
456 case BGP_NOTIFY_UPDATE_ERR:
457 return lookup_msg(bgp_notify_update_msg, subcode,
458 "Unrecognized Error Subcode");
459 case BGP_NOTIFY_HOLD_ERR:
460 break;
461 case BGP_NOTIFY_FSM_ERR:
462 break;
463 case BGP_NOTIFY_CEASE:
464 return lookup_msg(bgp_notify_cease_msg, subcode,
465 "Unrecognized Error Subcode");
466 case BGP_NOTIFY_CAPABILITY_ERR:
467 return lookup_msg(bgp_notify_capability_msg, subcode,
468 "Unrecognized Error Subcode");
469 }
470 return "";
3a8c7ba1
DW
471}
472
38de8d02 473/* extract notify admin reason if correctly present */
d62a17ae 474const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data,
475 size_t datalen)
38de8d02 476{
d62a17ae 477 if (!data || datalen < 1)
478 return NULL;
38de8d02 479
d62a17ae 480 u_char len = data[0];
481 if (len > 128 || len > datalen - 1)
482 return NULL;
38de8d02 483
d62a17ae 484 return zlog_sanitize(buf, bufsz, data + 1, len);
38de8d02
DL
485}
486
3a8c7ba1 487/* dump notify packet */
d62a17ae 488void bgp_notify_print(struct peer *peer, struct bgp_notify *bgp_notify,
489 const char *direct)
490{
491 const char *subcode_str;
492 const char *code_str;
493 const char *msg_str = NULL;
494 char msg_buf[1024];
495
496 if (BGP_DEBUG(neighbor_events, NEIGHBOR_EVENTS)
497 || bgp_flag_check(peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
498 code_str = bgp_notify_code_str(bgp_notify->code);
499 subcode_str = bgp_notify_subcode_str(bgp_notify->code,
500 bgp_notify->subcode);
501
502 if (bgp_notify->code == BGP_NOTIFY_CEASE
503 && (bgp_notify->subcode == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
504 || bgp_notify->subcode
505 == BGP_NOTIFY_CEASE_ADMIN_RESET)) {
506 msg_str = bgp_notify_admin_message(
507 msg_buf, sizeof(msg_buf), bgp_notify->raw_data,
508 bgp_notify->length);
509 }
510
511 if (msg_str) {
512 zlog_info(
513 "%%NOTIFICATION: %s neighbor %s %d/%d (%s%s) \"%s\"",
514 strcmp(direct, "received") == 0
515 ? "received from"
516 : "sent to",
517 peer->host, bgp_notify->code,
518 bgp_notify->subcode, code_str, subcode_str,
519 msg_str);
520 } else {
521 msg_str = bgp_notify->data ? bgp_notify->data : "";
522 zlog_info(
523 "%%NOTIFICATION: %s neighbor %s %d/%d (%s%s) %d bytes %s",
524 strcmp(direct, "received") == 0
525 ? "received from"
526 : "sent to",
527 peer->host, bgp_notify->code,
528 bgp_notify->subcode, code_str, subcode_str,
529 bgp_notify->length, msg_str);
530 }
531 }
718e3744 532}
6b0655a2 533
d62a17ae 534static void bgp_debug_clear_updgrp_update_dbg(struct bgp *bgp)
3f9c7369 535{
d62a17ae 536 if (!bgp)
537 bgp = bgp_get_default();
538 update_group_walk(bgp, update_group_clear_update_dbg, NULL);
3f9c7369
DS
539}
540
541
718e3744 542/* Debug option setting interface. */
543unsigned long bgp_debug_option = 0;
544
d62a17ae 545int debug(unsigned int option)
718e3744 546{
d62a17ae 547 return bgp_debug_option & option;
718e3744 548}
549
0b2aa3a0
PJ
550DEFUN (debug_bgp_as4,
551 debug_bgp_as4_cmd,
552 "debug bgp as4",
553 DEBUG_STR
554 BGP_STR
555 "BGP AS4 actions\n")
556{
d62a17ae 557 if (vty->node == CONFIG_NODE)
558 DEBUG_ON(as4, AS4);
559 else {
560 TERM_DEBUG_ON(as4, AS4);
561 vty_out(vty, "BGP as4 debugging is on\n");
562 }
563 return CMD_SUCCESS;
0b2aa3a0
PJ
564}
565
566DEFUN (no_debug_bgp_as4,
567 no_debug_bgp_as4_cmd,
568 "no debug bgp as4",
569 NO_STR
570 DEBUG_STR
571 BGP_STR
572 "BGP AS4 actions\n")
573{
d62a17ae 574 if (vty->node == CONFIG_NODE)
575 DEBUG_OFF(as4, AS4);
576 else {
577 TERM_DEBUG_OFF(as4, AS4);
578 vty_out(vty, "BGP as4 debugging is off\n");
579 }
580 return CMD_SUCCESS;
0b2aa3a0
PJ
581}
582
0b2aa3a0
PJ
583DEFUN (debug_bgp_as4_segment,
584 debug_bgp_as4_segment_cmd,
585 "debug bgp as4 segment",
586 DEBUG_STR
587 BGP_STR
6e22b901 588 "BGP AS4 actions\n"
0b2aa3a0
PJ
589 "BGP AS4 aspath segment handling\n")
590{
d62a17ae 591 if (vty->node == CONFIG_NODE)
592 DEBUG_ON(as4, AS4_SEGMENT);
593 else {
594 TERM_DEBUG_ON(as4, AS4_SEGMENT);
595 vty_out(vty, "BGP as4 segment debugging is on\n");
596 }
597 return CMD_SUCCESS;
0b2aa3a0
PJ
598}
599
600DEFUN (no_debug_bgp_as4_segment,
601 no_debug_bgp_as4_segment_cmd,
602 "no debug bgp as4 segment",
603 NO_STR
604 DEBUG_STR
605 BGP_STR
6e22b901 606 "BGP AS4 actions\n"
0b2aa3a0
PJ
607 "BGP AS4 aspath segment handling\n")
608{
d62a17ae 609 if (vty->node == CONFIG_NODE)
610 DEBUG_OFF(as4, AS4_SEGMENT);
611 else {
612 TERM_DEBUG_OFF(as4, AS4_SEGMENT);
613 vty_out(vty, "BGP as4 segment debugging is off\n");
614 }
615 return CMD_SUCCESS;
0b2aa3a0
PJ
616}
617
16286195
DS
618/* debug bgp neighbor_events */
619DEFUN (debug_bgp_neighbor_events,
620 debug_bgp_neighbor_events_cmd,
621 "debug bgp neighbor-events",
718e3744 622 DEBUG_STR
623 BGP_STR
16286195 624 "BGP Neighbor Events\n")
718e3744 625{
d62a17ae 626 bgp_debug_list_free(bgp_debug_neighbor_events_peers);
627
628 if (vty->node == CONFIG_NODE)
629 DEBUG_ON(neighbor_events, NEIGHBOR_EVENTS);
630 else {
631 TERM_DEBUG_ON(neighbor_events, NEIGHBOR_EVENTS);
632 vty_out(vty, "BGP neighbor-events debugging is on\n");
633 }
634 return CMD_SUCCESS;
718e3744 635}
636
16286195
DS
637DEFUN (debug_bgp_neighbor_events_peer,
638 debug_bgp_neighbor_events_peer_cmd,
6147e2c6 639 "debug bgp neighbor-events <A.B.C.D|X:X::X:X|WORD>",
718e3744 640 DEBUG_STR
641 BGP_STR
16286195
DS
642 "BGP Neighbor Events\n"
643 "BGP neighbor IP address to debug\n"
644 "BGP IPv6 neighbor to debug\n"
645 "BGP neighbor on interface to debug\n")
718e3744 646{
d62a17ae 647 int idx_peer = 3;
648 const char *host = argv[idx_peer]->arg;
649
650 if (!bgp_debug_neighbor_events_peers)
651 bgp_debug_neighbor_events_peers = list_new();
652
653 if (bgp_debug_list_has_entry(bgp_debug_neighbor_events_peers, host,
654 NULL)) {
655 vty_out(vty,
656 "BGP neighbor-events debugging is already enabled for %s\n",
657 host);
658 return CMD_SUCCESS;
659 }
660
661 bgp_debug_list_add_entry(bgp_debug_neighbor_events_peers, host, NULL);
662
663 if (vty->node == CONFIG_NODE)
664 DEBUG_ON(neighbor_events, NEIGHBOR_EVENTS);
665 else {
666 TERM_DEBUG_ON(neighbor_events, NEIGHBOR_EVENTS);
667 vty_out(vty, "BGP neighbor-events debugging is on for %s\n",
668 host);
669 }
670 return CMD_SUCCESS;
718e3744 671}
672
16286195
DS
673DEFUN (no_debug_bgp_neighbor_events,
674 no_debug_bgp_neighbor_events_cmd,
675 "no debug bgp neighbor-events",
676 NO_STR
718e3744 677 DEBUG_STR
678 BGP_STR
16286195 679 "Neighbor Events\n")
718e3744 680{
d62a17ae 681 bgp_debug_list_free(bgp_debug_neighbor_events_peers);
682
683 if (vty->node == CONFIG_NODE)
684 DEBUG_OFF(neighbor_events, NEIGHBOR_EVENTS);
685 else {
686 TERM_DEBUG_OFF(neighbor_events, NEIGHBOR_EVENTS);
687 vty_out(vty, "BGP neighbor-events debugging is off\n");
688 }
689 return CMD_SUCCESS;
718e3744 690}
691
16286195
DS
692DEFUN (no_debug_bgp_neighbor_events_peer,
693 no_debug_bgp_neighbor_events_peer_cmd,
6147e2c6 694 "no debug bgp neighbor-events <A.B.C.D|X:X::X:X|WORD>",
718e3744 695 NO_STR
696 DEBUG_STR
697 BGP_STR
16286195
DS
698 "Neighbor Events\n"
699 "BGP neighbor IP address to debug\n"
700 "BGP IPv6 neighbor to debug\n"
701 "BGP neighbor on interface to debug\n")
718e3744 702{
d62a17ae 703 int idx_peer = 4;
704 int found_peer = 0;
705 const char *host = argv[idx_peer]->arg;
706
707 if (bgp_debug_neighbor_events_peers
708 && !list_isempty(bgp_debug_neighbor_events_peers)) {
709 found_peer = bgp_debug_list_remove_entry(
710 bgp_debug_neighbor_events_peers, host, NULL);
711
712 if (list_isempty(bgp_debug_neighbor_events_peers)) {
713 if (vty->node == CONFIG_NODE)
714 DEBUG_OFF(neighbor_events, NEIGHBOR_EVENTS);
715 else
716 TERM_DEBUG_OFF(neighbor_events,
717 NEIGHBOR_EVENTS);
718 }
719 }
720
721 if (found_peer)
722 vty_out(vty, "BGP neighbor-events debugging is off for %s\n",
723 host);
724 else
725 vty_out(vty,
726 "BGP neighbor-events debugging was not enabled for %s\n",
727 host);
728
729 return CMD_SUCCESS;
718e3744 730}
731
16286195 732/* debug bgp nht */
fb018d25
DS
733DEFUN (debug_bgp_nht,
734 debug_bgp_nht_cmd,
735 "debug bgp nht",
736 DEBUG_STR
737 BGP_STR
738 "BGP nexthop tracking events\n")
739{
d62a17ae 740 if (vty->node == CONFIG_NODE)
741 DEBUG_ON(nht, NHT);
742 else {
743 TERM_DEBUG_ON(nht, NHT);
744 vty_out(vty, "BGP nexthop tracking debugging is on\n");
745 }
746 return CMD_SUCCESS;
fb018d25
DS
747}
748
749DEFUN (no_debug_bgp_nht,
750 no_debug_bgp_nht_cmd,
751 "no debug bgp nht",
752 NO_STR
753 DEBUG_STR
754 BGP_STR
755 "BGP nexthop tracking events\n")
756{
d62a17ae 757 if (vty->node == CONFIG_NODE)
758 DEBUG_OFF(nht, NHT);
759 else {
760 TERM_DEBUG_OFF(nht, NHT);
761 vty_out(vty, "BGP nexthop tracking debugging is off\n");
762 }
763 return CMD_SUCCESS;
fb018d25
DS
764}
765
16286195
DS
766/* debug bgp keepalives */
767DEFUN (debug_bgp_keepalive,
768 debug_bgp_keepalive_cmd,
769 "debug bgp keepalives",
718e3744 770 DEBUG_STR
771 BGP_STR
16286195 772 "BGP keepalives\n")
718e3744 773{
d62a17ae 774 bgp_debug_list_free(bgp_debug_keepalive_peers);
775
776 if (vty->node == CONFIG_NODE)
777 DEBUG_ON(keepalive, KEEPALIVE);
778 else {
779 TERM_DEBUG_ON(keepalive, KEEPALIVE);
780 vty_out(vty, "BGP keepalives debugging is on\n");
781 }
782 return CMD_SUCCESS;
718e3744 783}
784
16286195
DS
785DEFUN (debug_bgp_keepalive_peer,
786 debug_bgp_keepalive_peer_cmd,
6147e2c6 787 "debug bgp keepalives <A.B.C.D|X:X::X:X|WORD>",
718e3744 788 DEBUG_STR
789 BGP_STR
16286195
DS
790 "BGP Neighbor Events\n"
791 "BGP neighbor IP address to debug\n"
792 "BGP IPv6 neighbor to debug\n"
793 "BGP neighbor on interface to debug\n")
718e3744 794{
d62a17ae 795 int idx_peer = 3;
796 const char *host = argv[idx_peer]->arg;
797
798 if (!bgp_debug_keepalive_peers)
799 bgp_debug_keepalive_peers = list_new();
800
801 if (bgp_debug_list_has_entry(bgp_debug_keepalive_peers, host, NULL)) {
802 vty_out(vty,
803 "BGP keepalive debugging is already enabled for %s\n",
804 host);
805 return CMD_SUCCESS;
806 }
807
808 bgp_debug_list_add_entry(bgp_debug_keepalive_peers, host, NULL);
809
810 if (vty->node == CONFIG_NODE)
811 DEBUG_ON(keepalive, KEEPALIVE);
812 else {
813 TERM_DEBUG_ON(keepalive, KEEPALIVE);
814 vty_out(vty, "BGP keepalives debugging is on for %s\n", host);
815 }
816 return CMD_SUCCESS;
718e3744 817}
818
819DEFUN (no_debug_bgp_keepalive,
820 no_debug_bgp_keepalive_cmd,
821 "no debug bgp keepalives",
822 NO_STR
823 DEBUG_STR
824 BGP_STR
825 "BGP keepalives\n")
826{
d62a17ae 827 bgp_debug_list_free(bgp_debug_keepalive_peers);
828
829 if (vty->node == CONFIG_NODE)
830 DEBUG_OFF(keepalive, KEEPALIVE);
831 else {
832 TERM_DEBUG_OFF(keepalive, KEEPALIVE);
833 vty_out(vty, "BGP keepalives debugging is off\n");
834 }
835 return CMD_SUCCESS;
718e3744 836}
837
16286195
DS
838DEFUN (no_debug_bgp_keepalive_peer,
839 no_debug_bgp_keepalive_peer_cmd,
6147e2c6 840 "no debug bgp keepalives <A.B.C.D|X:X::X:X|WORD>",
16286195
DS
841 NO_STR
842 DEBUG_STR
718e3744 843 BGP_STR
16286195
DS
844 "BGP keepalives\n"
845 "BGP neighbor IP address to debug\n"
846 "BGP IPv6 neighbor to debug\n"
847 "BGP neighbor on interface to debug\n")
848{
d62a17ae 849 int idx_peer = 4;
850 int found_peer = 0;
851 const char *host = argv[idx_peer]->arg;
852
853 if (bgp_debug_keepalive_peers
854 && !list_isempty(bgp_debug_keepalive_peers)) {
855 found_peer = bgp_debug_list_remove_entry(
856 bgp_debug_keepalive_peers, host, NULL);
857
858 if (list_isempty(bgp_debug_keepalive_peers)) {
859 if (vty->node == CONFIG_NODE)
860 DEBUG_OFF(keepalive, KEEPALIVE);
861 else
862 TERM_DEBUG_OFF(keepalive, KEEPALIVE);
863 }
864 }
865
866 if (found_peer)
867 vty_out(vty, "BGP keepalives debugging is off for %s\n", host);
868 else
869 vty_out(vty,
870 "BGP keepalives debugging was not enabled for %s\n",
871 host);
872
873 return CMD_SUCCESS;
16286195
DS
874}
875
9fbdd100 876/* debug bgp bestpath */
ffd71765 877DEFUN (debug_bgp_bestpath_prefix,
9fbdd100 878 debug_bgp_bestpath_prefix_cmd,
ffd71765 879 "debug bgp bestpath <A.B.C.D/M|X:X::X:X/M>",
9fbdd100
DS
880 DEBUG_STR
881 BGP_STR
882 "BGP bestpath\n"
0c7b1b01
QY
883 "IPv4 prefix\n"
884 "IPv6 prefix\n")
9fbdd100 885{
0be4b77c
DW
886 struct prefix *argv_p;
887 int idx_ipv4_ipv6_prefixlen = 3;
888
889 argv_p = prefix_new();
ffd71765 890 (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
0be4b77c
DW
891 apply_mask(argv_p);
892
d62a17ae 893 if (!bgp_debug_bestpath_prefixes)
894 bgp_debug_bestpath_prefixes = list_new();
895
896 if (bgp_debug_list_has_entry(bgp_debug_bestpath_prefixes, NULL,
ffd71765 897 argv_p)) {
d62a17ae 898 vty_out(vty,
899 "BGP bestpath debugging is already enabled for %s\n",
ffd71765 900 argv[idx_ipv4_ipv6_prefixlen]->arg);
d62a17ae 901 return CMD_SUCCESS;
902 }
903
ffd71765 904 bgp_debug_list_add_entry(bgp_debug_bestpath_prefixes, NULL, argv_p);
d62a17ae 905
906 if (vty->node == CONFIG_NODE) {
907 DEBUG_ON(bestpath, BESTPATH);
908 } else {
909 TERM_DEBUG_ON(bestpath, BESTPATH);
910 vty_out(vty, "BGP bestpath debugging is on for %s\n",
ffd71765 911 argv[idx_ipv4_ipv6_prefixlen]->arg);
d62a17ae 912 }
913
914 return CMD_SUCCESS;
9fbdd100
DS
915}
916
917DEFUN (no_debug_bgp_bestpath_prefix,
918 no_debug_bgp_bestpath_prefix_cmd,
6147e2c6 919 "no debug bgp bestpath <A.B.C.D/M|X:X::X:X/M>",
9fbdd100
DS
920 NO_STR
921 DEBUG_STR
922 BGP_STR
923 "BGP bestpath\n"
0c7b1b01
QY
924 "IPv4 prefix\n"
925 "IPv6 prefix\n")
9fbdd100 926{
d62a17ae 927 int idx_ipv4_ipv6_prefixlen = 4;
928 struct prefix *argv_p;
929 int found_prefix = 0;
d62a17ae 930
931 argv_p = prefix_new();
ffd71765 932 (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
0be4b77c 933 apply_mask(argv_p);
d62a17ae 934
935 if (bgp_debug_bestpath_prefixes
936 && !list_isempty(bgp_debug_bestpath_prefixes)) {
937 found_prefix = bgp_debug_list_remove_entry(
938 bgp_debug_bestpath_prefixes, NULL, argv_p);
939
940 if (list_isempty(bgp_debug_bestpath_prefixes)) {
941 if (vty->node == CONFIG_NODE) {
942 DEBUG_OFF(bestpath, BESTPATH);
943 } else {
944 TERM_DEBUG_OFF(bestpath, BESTPATH);
945 vty_out(vty,
946 "BGP bestpath debugging (per prefix) is off\n");
947 }
948 }
949 }
950
951 if (found_prefix)
952 vty_out(vty, "BGP bestpath debugging is off for %s\n",
953 argv[idx_ipv4_ipv6_prefixlen]->arg);
954 else
955 vty_out(vty, "BGP bestpath debugging was not enabled for %s\n",
956 argv[idx_ipv4_ipv6_prefixlen]->arg);
957
958 return CMD_SUCCESS;
9fbdd100
DS
959}
960
961DEFUN (no_debug_bgp_bestpath,
962 no_debug_bgp_bestpath_cmd,
963 "no debug bgp bestpath",
964 NO_STR
965 DEBUG_STR
966 BGP_STR
967 "BGP bestpath\n")
968{
d62a17ae 969 bgp_debug_list_free(bgp_debug_bestpath_prefixes);
970
971 if (vty->node == CONFIG_NODE)
972 DEBUG_OFF(bestpath, BESTPATH);
973 else {
974 TERM_DEBUG_OFF(bestpath, BESTPATH);
975 vty_out(vty, "BGP bestpath debugging is off\n");
976 }
977 return CMD_SUCCESS;
9fbdd100
DS
978}
979
16286195 980/* debug bgp updates */
718e3744 981DEFUN (debug_bgp_update,
982 debug_bgp_update_cmd,
983 "debug bgp updates",
984 DEBUG_STR
985 BGP_STR
986 "BGP updates\n")
987{
d62a17ae 988 bgp_debug_list_free(bgp_debug_update_in_peers);
989 bgp_debug_list_free(bgp_debug_update_out_peers);
990 bgp_debug_list_free(bgp_debug_update_prefixes);
991
992 if (vty->node == CONFIG_NODE) {
993 DEBUG_ON(update, UPDATE_IN);
994 DEBUG_ON(update, UPDATE_OUT);
995 } else {
996 TERM_DEBUG_ON(update, UPDATE_IN);
997 TERM_DEBUG_ON(update, UPDATE_OUT);
998 vty_out(vty, "BGP updates debugging is on\n");
999 }
1000 return CMD_SUCCESS;
718e3744 1001}
1002
1003DEFUN (debug_bgp_update_direct,
1004 debug_bgp_update_direct_cmd,
6147e2c6 1005 "debug bgp updates <in|out>",
718e3744 1006 DEBUG_STR
1007 BGP_STR
1008 "BGP updates\n"
1009 "Inbound updates\n"
1010 "Outbound updates\n")
1011{
d62a17ae 1012 int idx_in_out = 3;
1013
1014 if (strncmp("i", argv[idx_in_out]->arg, 1) == 0)
1015 bgp_debug_list_free(bgp_debug_update_in_peers);
1016 else
1017 bgp_debug_list_free(bgp_debug_update_out_peers);
1018
1019 if (vty->node == CONFIG_NODE) {
1020 if (strncmp("i", argv[idx_in_out]->arg, 1) == 0)
1021 DEBUG_ON(update, UPDATE_IN);
1022 else
1023 DEBUG_ON(update, UPDATE_OUT);
1024 } else {
1025 if (strncmp("i", argv[idx_in_out]->arg, 1) == 0) {
1026 TERM_DEBUG_ON(update, UPDATE_IN);
1027 vty_out(vty, "BGP updates debugging is on (inbound)\n");
1028 } else {
1029 TERM_DEBUG_ON(update, UPDATE_OUT);
1030 vty_out(vty,
1031 "BGP updates debugging is on (outbound)\n");
1032 }
1033 }
1034 return CMD_SUCCESS;
718e3744 1035}
1036
16286195
DS
1037DEFUN (debug_bgp_update_direct_peer,
1038 debug_bgp_update_direct_peer_cmd,
6147e2c6 1039 "debug bgp updates <in|out> <A.B.C.D|X:X::X:X|WORD>",
718e3744 1040 DEBUG_STR
1041 BGP_STR
16286195
DS
1042 "BGP updates\n"
1043 "Inbound updates\n"
1044 "Outbound updates\n"
1045 "BGP neighbor IP address to debug\n"
1046 "BGP IPv6 neighbor to debug\n"
1047 "BGP neighbor on interface to debug\n")
718e3744 1048{
d62a17ae 1049 int idx_in_out = 3;
1050 int idx_peer = 4;
1051 const char *host = argv[idx_peer]->arg;
1052 int inbound;
1053
1054 if (!bgp_debug_update_in_peers)
1055 bgp_debug_update_in_peers = list_new();
1056
1057 if (!bgp_debug_update_out_peers)
1058 bgp_debug_update_out_peers = list_new();
1059
1060 if (strncmp("i", argv[idx_in_out]->arg, 1) == 0)
1061 inbound = 1;
1062 else
1063 inbound = 0;
1064
1065 if (inbound) {
1066 if (bgp_debug_list_has_entry(bgp_debug_update_in_peers, host,
1067 NULL)) {
1068 vty_out(vty,
1069 "BGP inbound update debugging is already enabled for %s\n",
1070 host);
1071 return CMD_SUCCESS;
1072 }
1073 }
1074
1075 else {
1076 if (bgp_debug_list_has_entry(bgp_debug_update_out_peers, host,
1077 NULL)) {
1078 vty_out(vty,
1079 "BGP outbound update debugging is already enabled for %s\n",
1080 host);
1081 return CMD_SUCCESS;
1082 }
1083 }
1084
1085 if (inbound)
1086 bgp_debug_list_add_entry(bgp_debug_update_in_peers, host, NULL);
1087 else {
1088 struct peer *peer;
1089 struct peer_af *paf;
1090 int afidx;
1091
1092 bgp_debug_list_add_entry(bgp_debug_update_out_peers, host,
1093 NULL);
1094 peer = bgp_find_peer(vty, host);
1095
1096 if (peer) {
1097 for (afidx = BGP_AF_START; afidx < BGP_AF_MAX;
1098 afidx++) {
1099 paf = peer->peer_af_array[afidx];
1100 if (paf != NULL) {
1101 if (PAF_SUBGRP(paf)) {
1102 UPDGRP_PEER_DBG_EN(
1103 PAF_SUBGRP(paf)
1104 ->update_group);
1105 }
1106 }
1107 }
1108 }
1109 }
1110
1111 if (vty->node == CONFIG_NODE) {
1112 if (inbound)
1113 DEBUG_ON(update, UPDATE_IN);
1114 else
1115 DEBUG_ON(update, UPDATE_OUT);
1116 } else {
1117 if (inbound) {
1118 TERM_DEBUG_ON(update, UPDATE_IN);
1119 vty_out(vty,
1120 "BGP updates debugging is on (inbound) for %s\n",
1121 argv[idx_peer]->arg);
1122 } else {
1123 TERM_DEBUG_ON(update, UPDATE_OUT);
1124 vty_out(vty,
1125 "BGP updates debugging is on (outbound) for %s\n",
1126 argv[idx_peer]->arg);
1127 }
1128 }
1129 return CMD_SUCCESS;
718e3744 1130}
1131
91ba2c8b
DS
1132DEFUN (no_debug_bgp_update_direct,
1133 no_debug_bgp_update_direct_cmd,
6147e2c6 1134 "no debug bgp updates <in|out>",
91ba2c8b
DS
1135 NO_STR
1136 DEBUG_STR
1137 BGP_STR
1138 "BGP updates\n"
1139 "Inbound updates\n"
1140 "Outbound updates\n")
1141{
d62a17ae 1142 int idx_in_out = 4;
1143 if (strncmp("i", argv[idx_in_out]->arg, 1) == 0) {
1144 bgp_debug_list_free(bgp_debug_update_in_peers);
1145
1146 if (vty->node == CONFIG_NODE) {
1147 DEBUG_OFF(update, UPDATE_IN);
1148 } else {
1149 TERM_DEBUG_OFF(update, UPDATE_IN);
1150 vty_out(vty,
1151 "BGP updates debugging is off (inbound)\n");
1152 }
1153 } else {
1154 bgp_debug_list_free(bgp_debug_update_out_peers);
1155
1156 if (vty->node == CONFIG_NODE) {
1157 DEBUG_OFF(update, UPDATE_OUT);
1158 } else {
1159 TERM_DEBUG_OFF(update, UPDATE_OUT);
1160 vty_out(vty,
1161 "BGP updates debugging is off (outbound)\n");
1162 }
1163 }
1164
1165 return CMD_SUCCESS;
91ba2c8b
DS
1166}
1167
16286195
DS
1168DEFUN (no_debug_bgp_update_direct_peer,
1169 no_debug_bgp_update_direct_peer_cmd,
6147e2c6 1170 "no debug bgp updates <in|out> <A.B.C.D|X:X::X:X|WORD>",
16286195
DS
1171 NO_STR
1172 DEBUG_STR
718e3744 1173 BGP_STR
16286195
DS
1174 "BGP updates\n"
1175 "Inbound updates\n"
1176 "Outbound updates\n"
1177 "BGP neighbor IP address to debug\n"
1178 "BGP IPv6 neighbor to debug\n"
1179 "BGP neighbor on interface to debug\n")
1180{
d62a17ae 1181 int idx_in_out = 4;
1182 int idx_peer = 5;
1183 int inbound;
1184 int found_peer = 0;
1185 const char *host = argv[idx_peer]->arg;
1186
1187 if (strncmp("i", argv[idx_in_out]->arg, 1) == 0)
1188 inbound = 1;
1189 else
1190 inbound = 0;
1191
1192 if (inbound && bgp_debug_update_in_peers
1193 && !list_isempty(bgp_debug_update_in_peers)) {
1194 found_peer = bgp_debug_list_remove_entry(
1195 bgp_debug_update_in_peers, host, NULL);
1196
1197 if (list_isempty(bgp_debug_update_in_peers)) {
1198 if (vty->node == CONFIG_NODE)
1199 DEBUG_OFF(update, UPDATE_IN);
1200 else {
1201 TERM_DEBUG_OFF(update, UPDATE_IN);
1202 vty_out(vty,
1203 "BGP updates debugging (inbound) is off\n");
1204 }
1205 }
1206 }
1207
1208 if (!inbound && bgp_debug_update_out_peers
1209 && !list_isempty(bgp_debug_update_out_peers)) {
1210 found_peer = bgp_debug_list_remove_entry(
1211 bgp_debug_update_out_peers, host, NULL);
1212
1213 if (list_isempty(bgp_debug_update_out_peers)) {
1214 if (vty->node == CONFIG_NODE)
1215 DEBUG_OFF(update, UPDATE_OUT);
1216 else {
1217 TERM_DEBUG_OFF(update, UPDATE_OUT);
1218 vty_out(vty,
1219 "BGP updates debugging (outbound) is off\n");
1220 }
1221 }
1222
1223 struct peer *peer;
1224 struct peer_af *paf;
1225 int afidx;
1226 peer = bgp_find_peer(vty, host);
1227
1228 if (peer) {
1229 for (afidx = BGP_AF_START; afidx < BGP_AF_MAX;
1230 afidx++) {
1231 paf = peer->peer_af_array[afidx];
1232 if (paf != NULL) {
1233 if (PAF_SUBGRP(paf)) {
1234 UPDGRP_PEER_DBG_DIS(
1235 PAF_SUBGRP(paf)
1236 ->update_group);
1237 }
1238 }
1239 }
1240 }
1241 }
1242
1243 if (found_peer)
1244 if (inbound)
1245 vty_out(vty,
1246 "BGP updates debugging (inbound) is off for %s\n",
1247 host);
1248 else
1249 vty_out(vty,
1250 "BGP updates debugging (outbound) is off for %s\n",
1251 host);
1252 else if (inbound)
1253 vty_out(vty,
1254 "BGP updates debugging (inbound) was not enabled for %s\n",
1255 host);
1256 else
1257 vty_out(vty,
1258 "BGP updates debugging (outbound) was not enabled for %s\n",
1259 host);
1260
1261 return CMD_SUCCESS;
16286195
DS
1262}
1263
1264DEFUN (debug_bgp_update_prefix,
1265 debug_bgp_update_prefix_cmd,
6147e2c6 1266 "debug bgp updates prefix <A.B.C.D/M|X:X::X:X/M>",
718e3744 1267 DEBUG_STR
16286195
DS
1268 BGP_STR
1269 "BGP updates\n"
1270 "Specify a prefix to debug\n"
0c7b1b01
QY
1271 "IPv4 prefix\n"
1272 "IPv6 prefix\n")
718e3744 1273{
d62a17ae 1274 int idx_ipv4_ipv6_prefixlen = 4;
1275 struct prefix *argv_p;
d62a17ae 1276
1277 argv_p = prefix_new();
ffd71765 1278 (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
0be4b77c 1279 apply_mask(argv_p);
d62a17ae 1280
1281 if (!bgp_debug_update_prefixes)
1282 bgp_debug_update_prefixes = list_new();
1283
1284 if (bgp_debug_list_has_entry(bgp_debug_update_prefixes, NULL, argv_p)) {
1285 vty_out(vty,
1286 "BGP updates debugging is already enabled for %s\n",
1287 argv[idx_ipv4_ipv6_prefixlen]->arg);
1288 return CMD_SUCCESS;
1289 }
1290
1291 bgp_debug_list_add_entry(bgp_debug_update_prefixes, NULL, argv_p);
1292
1293 if (vty->node == CONFIG_NODE) {
1294 DEBUG_ON(update, UPDATE_PREFIX);
1295 } else {
1296 TERM_DEBUG_ON(update, UPDATE_PREFIX);
1297 vty_out(vty, "BGP updates debugging is on for %s\n",
1298 argv[idx_ipv4_ipv6_prefixlen]->arg);
1299 }
1300
1301 return CMD_SUCCESS;
718e3744 1302}
1303
16286195
DS
1304DEFUN (no_debug_bgp_update_prefix,
1305 no_debug_bgp_update_prefix_cmd,
6147e2c6 1306 "no debug bgp updates prefix <A.B.C.D/M|X:X::X:X/M>",
718e3744 1307 NO_STR
1308 DEBUG_STR
16286195
DS
1309 BGP_STR
1310 "BGP updates\n"
1311 "Specify a prefix to debug\n"
0c7b1b01
QY
1312 "IPv4 prefix\n"
1313 "IPv6 prefix\n")
16286195 1314{
d62a17ae 1315 int idx_ipv4_ipv6_prefixlen = 5;
1316 struct prefix *argv_p;
1317 int found_prefix = 0;
d62a17ae 1318
1319 argv_p = prefix_new();
ffd71765 1320 (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
0be4b77c 1321 apply_mask(argv_p);
d62a17ae 1322
1323 if (bgp_debug_update_prefixes
1324 && !list_isempty(bgp_debug_update_prefixes)) {
1325 found_prefix = bgp_debug_list_remove_entry(
1326 bgp_debug_update_prefixes, NULL, argv_p);
1327
1328 if (list_isempty(bgp_debug_update_prefixes)) {
1329 if (vty->node == CONFIG_NODE) {
1330 DEBUG_OFF(update, UPDATE_PREFIX);
1331 } else {
1332 TERM_DEBUG_OFF(update, UPDATE_PREFIX);
1333 vty_out(vty,
1334 "BGP updates debugging (per prefix) is off\n");
1335 }
1336 }
1337 }
1338
1339 if (found_prefix)
1340 vty_out(vty, "BGP updates debugging is off for %s\n",
1341 argv[idx_ipv4_ipv6_prefixlen]->arg);
1342 else
1343 vty_out(vty, "BGP updates debugging was not enabled for %s\n",
1344 argv[idx_ipv4_ipv6_prefixlen]->arg);
1345
1346 return CMD_SUCCESS;
16286195
DS
1347}
1348
1349DEFUN (no_debug_bgp_update,
1350 no_debug_bgp_update_cmd,
1351 "no debug bgp updates",
1352 NO_STR
1353 DEBUG_STR
1354 BGP_STR
1355 "BGP updates\n")
718e3744 1356{
87f42c2c
QY
1357 struct listnode *ln;
1358 struct bgp *bgp;
1359
d62a17ae 1360 bgp_debug_list_free(bgp_debug_update_in_peers);
1361 bgp_debug_list_free(bgp_debug_update_out_peers);
1362 bgp_debug_list_free(bgp_debug_update_prefixes);
1363
87f42c2c
QY
1364 for (ALL_LIST_ELEMENTS_RO(bm->bgp, ln, bgp))
1365 bgp_debug_clear_updgrp_update_dbg(bgp);
d62a17ae 1366
1367 if (vty->node == CONFIG_NODE) {
1368 DEBUG_OFF(update, UPDATE_IN);
1369 DEBUG_OFF(update, UPDATE_OUT);
1370 DEBUG_OFF(update, UPDATE_PREFIX);
1371 } else {
1372 TERM_DEBUG_OFF(update, UPDATE_IN);
1373 TERM_DEBUG_OFF(update, UPDATE_OUT);
1374 TERM_DEBUG_OFF(update, UPDATE_PREFIX);
1375 vty_out(vty, "BGP updates debugging is off\n");
1376 }
1377 return CMD_SUCCESS;
718e3744 1378}
1379
16286195 1380/* debug bgp zebra */
a39275d7
AS
1381DEFUN (debug_bgp_zebra,
1382 debug_bgp_zebra_cmd,
1383 "debug bgp zebra",
1384 DEBUG_STR
1385 BGP_STR
1386 "BGP Zebra messages\n")
1387{
d62a17ae 1388 if (vty->node == CONFIG_NODE)
1389 DEBUG_ON(zebra, ZEBRA);
1390 else {
1391 TERM_DEBUG_ON(zebra, ZEBRA);
1392 vty_out(vty, "BGP zebra debugging is on\n");
1393 }
1394 return CMD_SUCCESS;
a39275d7
AS
1395}
1396
16286195
DS
1397DEFUN (debug_bgp_zebra_prefix,
1398 debug_bgp_zebra_prefix_cmd,
6147e2c6 1399 "debug bgp zebra prefix <A.B.C.D/M|X:X::X:X/M>",
16286195
DS
1400 DEBUG_STR
1401 BGP_STR
1402 "BGP Zebra messages\n"
1403 "Specify a prefix to debug\n"
0c7b1b01
QY
1404 "IPv4 prefix\n"
1405 "IPv6 prefix\n")
16286195 1406{
d62a17ae 1407 int idx_ipv4_ipv6_prefixlen = 4;
1408 struct prefix *argv_p;
d62a17ae 1409
1410 argv_p = prefix_new();
ffd71765 1411 (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
0be4b77c 1412 apply_mask(argv_p);
d62a17ae 1413
1414 if (!bgp_debug_zebra_prefixes)
1415 bgp_debug_zebra_prefixes = list_new();
1416
1417 if (bgp_debug_list_has_entry(bgp_debug_zebra_prefixes, NULL, argv_p)) {
1418 vty_out(vty, "BGP zebra debugging is already enabled for %s\n",
1419 argv[idx_ipv4_ipv6_prefixlen]->arg);
1420 return CMD_SUCCESS;
1421 }
1422
1423 bgp_debug_list_add_entry(bgp_debug_zebra_prefixes, NULL, argv_p);
1424
1425 if (vty->node == CONFIG_NODE)
1426 DEBUG_ON(zebra, ZEBRA);
1427 else {
1428 TERM_DEBUG_ON(zebra, ZEBRA);
1429 vty_out(vty, "BGP zebra debugging is on for %s\n",
1430 argv[idx_ipv4_ipv6_prefixlen]->arg);
1431 }
1432
1433 return CMD_SUCCESS;
16286195
DS
1434}
1435
a39275d7
AS
1436DEFUN (no_debug_bgp_zebra,
1437 no_debug_bgp_zebra_cmd,
1438 "no debug bgp zebra",
1439 NO_STR
1440 DEBUG_STR
1441 BGP_STR
1442 "BGP Zebra messages\n")
1443{
d62a17ae 1444 bgp_debug_list_free(bgp_debug_zebra_prefixes);
1445
1446 if (vty->node == CONFIG_NODE)
1447 DEBUG_OFF(zebra, ZEBRA);
1448 else {
1449 TERM_DEBUG_OFF(zebra, ZEBRA);
1450 vty_out(vty, "BGP zebra debugging is off\n");
1451 }
1452 return CMD_SUCCESS;
a39275d7
AS
1453}
1454
16286195
DS
1455DEFUN (no_debug_bgp_zebra_prefix,
1456 no_debug_bgp_zebra_prefix_cmd,
6147e2c6 1457 "no debug bgp zebra prefix <A.B.C.D/M|X:X::X:X/M>",
16286195
DS
1458 NO_STR
1459 DEBUG_STR
a39275d7 1460 BGP_STR
16286195
DS
1461 "BGP Zebra messages\n"
1462 "Specify a prefix to debug\n"
0c7b1b01
QY
1463 "IPv4 prefix\n"
1464 "IPv6 prefix\n")
16286195 1465{
d62a17ae 1466 int idx_ipv4_ipv6_prefixlen = 5;
1467 struct prefix *argv_p;
1468 int found_prefix = 0;
d62a17ae 1469
1470 argv_p = prefix_new();
ffd71765 1471 (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
0be4b77c 1472 apply_mask(argv_p);
d62a17ae 1473
1474 if (bgp_debug_zebra_prefixes
1475 && !list_isempty(bgp_debug_zebra_prefixes)) {
1476 found_prefix = bgp_debug_list_remove_entry(
1477 bgp_debug_zebra_prefixes, NULL, argv_p);
1478
1479 if (list_isempty(bgp_debug_zebra_prefixes)) {
1480 if (vty->node == CONFIG_NODE)
1481 DEBUG_OFF(zebra, ZEBRA);
1482 else {
1483 TERM_DEBUG_OFF(zebra, ZEBRA);
1484 vty_out(vty, "BGP zebra debugging is off\n");
1485 }
1486 }
1487 }
1488
1489 if (found_prefix)
1490 vty_out(vty, "BGP zebra debugging is off for %s\n",
1491 argv[idx_ipv4_ipv6_prefixlen]->arg);
1492 else
1493 vty_out(vty, "BGP zebra debugging was not enabled for %s\n",
1494 argv[idx_ipv4_ipv6_prefixlen]->arg);
1495
1496 return CMD_SUCCESS;
16286195
DS
1497}
1498
cebb7440
LB
1499DEFUN (debug_bgp_allow_martians,
1500 debug_bgp_allow_martians_cmd,
1501 "debug bgp allow-martians",
1502 DEBUG_STR
1503 BGP_STR
1504 "BGP allow martian next hops\n")
1505{
d62a17ae 1506 if (vty->node == CONFIG_NODE)
1507 DEBUG_ON(allow_martians, ALLOW_MARTIANS);
1508 else {
1509 TERM_DEBUG_ON(allow_martians, ALLOW_MARTIANS);
1510 vty_out(vty, "BGP allow_martian next hop debugging is on\n");
1511 }
1512 return CMD_SUCCESS;
cebb7440
LB
1513}
1514
1515DEFUN (no_debug_bgp_allow_martians,
1516 no_debug_bgp_allow_martians_cmd,
1517 "no debug bgp allow-martians",
1518 NO_STR
1519 DEBUG_STR
1520 BGP_STR
1521 "BGP allow martian next hops\n")
1522{
d62a17ae 1523 if (vty->node == CONFIG_NODE)
1524 DEBUG_OFF(allow_martians, ALLOW_MARTIANS);
1525 else {
1526 TERM_DEBUG_OFF(allow_martians, ALLOW_MARTIANS);
1527 vty_out(vty, "BGP allow martian next hop debugging is off\n");
1528 }
1529 return CMD_SUCCESS;
cebb7440
LB
1530}
1531
cebb7440 1532
3f9c7369
DS
1533/* debug bgp update-groups */
1534DEFUN (debug_bgp_update_groups,
1535 debug_bgp_update_groups_cmd,
1536 "debug bgp update-groups",
1537 DEBUG_STR
1538 BGP_STR
1539 "BGP update-groups\n")
1540{
d62a17ae 1541 if (vty->node == CONFIG_NODE)
1542 DEBUG_ON(update_groups, UPDATE_GROUPS);
1543 else {
1544 TERM_DEBUG_ON(update_groups, UPDATE_GROUPS);
1545 vty_out(vty, "BGP update-groups debugging is on\n");
1546 }
1547 return CMD_SUCCESS;
3f9c7369
DS
1548}
1549
1550DEFUN (no_debug_bgp_update_groups,
1551 no_debug_bgp_update_groups_cmd,
1552 "no debug bgp update-groups",
1553 NO_STR
1554 DEBUG_STR
1555 BGP_STR
1556 "BGP update-groups\n")
1557{
d62a17ae 1558 if (vty->node == CONFIG_NODE)
1559 DEBUG_OFF(update_groups, UPDATE_GROUPS);
1560 else {
1561 TERM_DEBUG_OFF(update_groups, UPDATE_GROUPS);
1562 vty_out(vty, "BGP update-groups debugging is off\n");
1563 }
1564 return CMD_SUCCESS;
3f9c7369
DS
1565}
1566
16286195
DS
1567DEFUN (no_debug_bgp,
1568 no_debug_bgp_cmd,
1569 "no debug bgp",
718e3744 1570 NO_STR
1571 DEBUG_STR
718e3744 1572 BGP_STR)
1573{
87f42c2c
QY
1574 struct bgp *bgp;
1575 struct listnode *ln;
1576
d62a17ae 1577 bgp_debug_list_free(bgp_debug_neighbor_events_peers);
1578 bgp_debug_list_free(bgp_debug_keepalive_peers);
1579 bgp_debug_list_free(bgp_debug_update_in_peers);
1580 bgp_debug_list_free(bgp_debug_update_out_peers);
1581 bgp_debug_list_free(bgp_debug_update_prefixes);
1582 bgp_debug_list_free(bgp_debug_bestpath_prefixes);
1583 bgp_debug_list_free(bgp_debug_zebra_prefixes);
1584
87f42c2c
QY
1585 for (ALL_LIST_ELEMENTS_RO(bm->bgp, ln, bgp))
1586 bgp_debug_clear_updgrp_update_dbg(bgp);
d62a17ae 1587
1588 TERM_DEBUG_OFF(keepalive, KEEPALIVE);
1589 TERM_DEBUG_OFF(update, UPDATE_IN);
1590 TERM_DEBUG_OFF(update, UPDATE_OUT);
1591 TERM_DEBUG_OFF(update, UPDATE_PREFIX);
1592 TERM_DEBUG_OFF(bestpath, BESTPATH);
1593 TERM_DEBUG_OFF(as4, AS4);
1594 TERM_DEBUG_OFF(as4, AS4_SEGMENT);
1595 TERM_DEBUG_OFF(neighbor_events, NEIGHBOR_EVENTS);
1596 TERM_DEBUG_OFF(zebra, ZEBRA);
1597 TERM_DEBUG_OFF(allow_martians, ALLOW_MARTIANS);
c33b83b3 1598 TERM_DEBUG_OFF(nht, NHT);
d62a17ae 1599 vty_out(vty, "All possible debugging has been turned off\n");
1600
1601 return CMD_SUCCESS;
718e3744 1602}
1603
87f6dc50
DS
1604DEFUN_NOSH (show_debugging_bgp,
1605 show_debugging_bgp_cmd,
1606 "show debugging [bgp]",
1607 SHOW_STR
1608 DEBUG_STR
1609 BGP_STR)
718e3744 1610{
d62a17ae 1611 vty_out(vty, "BGP debugging status:\n");
718e3744 1612
d62a17ae 1613 if (BGP_DEBUG(as4, AS4))
1614 vty_out(vty, " BGP as4 debugging is on\n");
16286195 1615
d62a17ae 1616 if (BGP_DEBUG(as4, AS4_SEGMENT))
1617 vty_out(vty, " BGP as4 aspath segment debugging is on\n");
16286195 1618
d62a17ae 1619 if (BGP_DEBUG(bestpath, BESTPATH))
1620 bgp_debug_list_print(vty, " BGP bestpath debugging is on",
1621 bgp_debug_bestpath_prefixes);
16286195 1622
d62a17ae 1623 if (BGP_DEBUG(keepalive, KEEPALIVE))
1624 bgp_debug_list_print(vty, " BGP keepalives debugging is on",
1625 bgp_debug_keepalive_peers);
16286195 1626
d62a17ae 1627 if (BGP_DEBUG(neighbor_events, NEIGHBOR_EVENTS))
1628 bgp_debug_list_print(vty,
1629 " BGP neighbor-events debugging is on",
1630 bgp_debug_neighbor_events_peers);
91ba2c8b 1631
d62a17ae 1632 if (BGP_DEBUG(nht, NHT))
1633 vty_out(vty, " BGP next-hop tracking debugging is on\n");
16286195 1634
d62a17ae 1635 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1636 vty_out(vty, " BGP update-groups debugging is on\n");
91ba2c8b 1637
d62a17ae 1638 if (BGP_DEBUG(update, UPDATE_PREFIX))
1639 bgp_debug_list_print(vty, " BGP updates debugging is on",
1640 bgp_debug_update_prefixes);
16286195 1641
d62a17ae 1642 if (BGP_DEBUG(update, UPDATE_IN))
1643 bgp_debug_list_print(vty,
1644 " BGP updates debugging is on (inbound)",
1645 bgp_debug_update_in_peers);
16286195 1646
d62a17ae 1647 if (BGP_DEBUG(update, UPDATE_OUT))
1648 bgp_debug_list_print(vty,
1649 " BGP updates debugging is on (outbound)",
1650 bgp_debug_update_out_peers);
16286195 1651
d62a17ae 1652 if (BGP_DEBUG(zebra, ZEBRA))
1653 bgp_debug_list_print(vty, " BGP zebra debugging is on",
1654 bgp_debug_zebra_prefixes);
16286195 1655
d62a17ae 1656 if (BGP_DEBUG(allow_martians, ALLOW_MARTIANS))
1657 vty_out(vty, " BGP allow martian next hop debugging is on\n");
1658 vty_out(vty, "\n");
1659 return CMD_SUCCESS;
718e3744 1660}
1661
90dcf2d7 1662/* return count of number of debug flags set */
d62a17ae 1663int bgp_debug_count(void)
90dcf2d7 1664{
d62a17ae 1665 int ret = 0;
1666 if (BGP_DEBUG(as4, AS4))
1667 ret++;
90dcf2d7 1668
d62a17ae 1669 if (BGP_DEBUG(as4, AS4_SEGMENT))
1670 ret++;
90dcf2d7 1671
d62a17ae 1672 if (BGP_DEBUG(bestpath, BESTPATH))
1673 ret++;
90dcf2d7 1674
d62a17ae 1675 if (BGP_DEBUG(keepalive, KEEPALIVE))
1676 ret++;
90dcf2d7 1677
d62a17ae 1678 if (BGP_DEBUG(neighbor_events, NEIGHBOR_EVENTS))
1679 ret++;
90dcf2d7 1680
d62a17ae 1681 if (BGP_DEBUG(nht, NHT))
1682 ret++;
90dcf2d7 1683
d62a17ae 1684 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1685 ret++;
90dcf2d7 1686
d62a17ae 1687 if (BGP_DEBUG(update, UPDATE_PREFIX))
1688 ret++;
90dcf2d7 1689
d62a17ae 1690 if (BGP_DEBUG(update, UPDATE_IN))
1691 ret++;
90dcf2d7 1692
d62a17ae 1693 if (BGP_DEBUG(update, UPDATE_OUT))
1694 ret++;
90dcf2d7 1695
d62a17ae 1696 if (BGP_DEBUG(zebra, ZEBRA))
1697 ret++;
90dcf2d7 1698
d62a17ae 1699 if (BGP_DEBUG(allow_martians, ALLOW_MARTIANS))
1700 ret++;
90dcf2d7 1701
d62a17ae 1702 return ret;
90dcf2d7
LB
1703}
1704
d62a17ae 1705static int bgp_config_write_debug(struct vty *vty)
718e3744 1706{
d62a17ae 1707 int write = 0;
718e3744 1708
d62a17ae 1709 if (CONF_BGP_DEBUG(as4, AS4)) {
1710 vty_out(vty, "debug bgp as4\n");
1711 write++;
1712 }
718e3744 1713
d62a17ae 1714 if (CONF_BGP_DEBUG(as4, AS4_SEGMENT)) {
1715 vty_out(vty, "debug bgp as4 segment\n");
1716 write++;
1717 }
16286195 1718
d62a17ae 1719 if (CONF_BGP_DEBUG(bestpath, BESTPATH)) {
1720 write += bgp_debug_list_conf_print(vty, "debug bgp bestpath",
1721 bgp_debug_bestpath_prefixes);
1722 }
1723
1724 if (CONF_BGP_DEBUG(keepalive, KEEPALIVE)) {
1725 write += bgp_debug_list_conf_print(vty, "debug bgp keepalives",
1726 bgp_debug_keepalive_peers);
1727 }
1728
1729 if (CONF_BGP_DEBUG(neighbor_events, NEIGHBOR_EVENTS)) {
1730 write += bgp_debug_list_conf_print(
1731 vty, "debug bgp neighbor-events",
1732 bgp_debug_neighbor_events_peers);
1733 }
1734
1735 if (CONF_BGP_DEBUG(nht, NHT)) {
1736 vty_out(vty, "debug bgp nht\n");
1737 write++;
1738 }
1739
1740 if (CONF_BGP_DEBUG(update_groups, UPDATE_GROUPS)) {
1741 vty_out(vty, "debug bgp update-groups\n");
1742 write++;
1743 }
1744
1745 if (CONF_BGP_DEBUG(update, UPDATE_PREFIX)) {
1746 write += bgp_debug_list_conf_print(vty,
1747 "debug bgp updates prefix",
1748 bgp_debug_update_prefixes);
1749 }
1750
1751 if (CONF_BGP_DEBUG(update, UPDATE_IN)) {
1752 write += bgp_debug_list_conf_print(vty, "debug bgp updates in",
1753 bgp_debug_update_in_peers);
1754 }
1755
1756 if (CONF_BGP_DEBUG(update, UPDATE_OUT)) {
1757 write += bgp_debug_list_conf_print(vty, "debug bgp updates out",
1758 bgp_debug_update_out_peers);
1759 }
16286195 1760
d62a17ae 1761 if (CONF_BGP_DEBUG(zebra, ZEBRA)) {
1762 if (!bgp_debug_zebra_prefixes
1763 || list_isempty(bgp_debug_zebra_prefixes)) {
1764 vty_out(vty, "debug bgp zebra\n");
1765 write++;
1766 } else {
1767 write += bgp_debug_list_conf_print(
1768 vty, "debug bgp zebra prefix",
1769 bgp_debug_zebra_prefixes);
1770 }
1771 }
16286195 1772
d62a17ae 1773 if (CONF_BGP_DEBUG(allow_martians, ALLOW_MARTIANS)) {
1774 vty_out(vty, "debug bgp allow-martians\n");
1775 write++;
1776 }
16286195 1777
d62a17ae 1778 return write;
1779}
16286195 1780
d62a17ae 1781static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
1782
1783void bgp_debug_init(void)
1784{
1785 install_node(&debug_node, bgp_config_write_debug);
1786
1787 install_element(ENABLE_NODE, &show_debugging_bgp_cmd);
1788
1789 install_element(ENABLE_NODE, &debug_bgp_as4_cmd);
1790 install_element(CONFIG_NODE, &debug_bgp_as4_cmd);
1791 install_element(ENABLE_NODE, &debug_bgp_as4_segment_cmd);
1792 install_element(CONFIG_NODE, &debug_bgp_as4_segment_cmd);
1793
1794 install_element(ENABLE_NODE, &debug_bgp_neighbor_events_cmd);
1795 install_element(CONFIG_NODE, &debug_bgp_neighbor_events_cmd);
1796 install_element(ENABLE_NODE, &debug_bgp_nht_cmd);
1797 install_element(CONFIG_NODE, &debug_bgp_nht_cmd);
1798 install_element(ENABLE_NODE, &debug_bgp_keepalive_cmd);
1799 install_element(CONFIG_NODE, &debug_bgp_keepalive_cmd);
1800 install_element(ENABLE_NODE, &debug_bgp_update_cmd);
1801 install_element(CONFIG_NODE, &debug_bgp_update_cmd);
1802 install_element(ENABLE_NODE, &debug_bgp_zebra_cmd);
1803 install_element(CONFIG_NODE, &debug_bgp_zebra_cmd);
1804 install_element(ENABLE_NODE, &debug_bgp_allow_martians_cmd);
1805 install_element(CONFIG_NODE, &debug_bgp_allow_martians_cmd);
1806 install_element(ENABLE_NODE, &debug_bgp_update_groups_cmd);
1807 install_element(CONFIG_NODE, &debug_bgp_update_groups_cmd);
1808 install_element(ENABLE_NODE, &debug_bgp_bestpath_prefix_cmd);
1809 install_element(CONFIG_NODE, &debug_bgp_bestpath_prefix_cmd);
1810
1811 /* debug bgp updates (in|out) */
1812 install_element(ENABLE_NODE, &debug_bgp_update_direct_cmd);
1813 install_element(CONFIG_NODE, &debug_bgp_update_direct_cmd);
1814 install_element(ENABLE_NODE, &no_debug_bgp_update_direct_cmd);
1815 install_element(CONFIG_NODE, &no_debug_bgp_update_direct_cmd);
1816
1817 /* debug bgp updates (in|out) A.B.C.D */
1818 install_element(ENABLE_NODE, &debug_bgp_update_direct_peer_cmd);
1819 install_element(CONFIG_NODE, &debug_bgp_update_direct_peer_cmd);
1820 install_element(ENABLE_NODE, &no_debug_bgp_update_direct_peer_cmd);
1821 install_element(CONFIG_NODE, &no_debug_bgp_update_direct_peer_cmd);
1822
1823 /* debug bgp updates prefix A.B.C.D/M */
1824 install_element(ENABLE_NODE, &debug_bgp_update_prefix_cmd);
1825 install_element(CONFIG_NODE, &debug_bgp_update_prefix_cmd);
1826 install_element(ENABLE_NODE, &no_debug_bgp_update_prefix_cmd);
1827 install_element(CONFIG_NODE, &no_debug_bgp_update_prefix_cmd);
1828
1829 /* debug bgp zebra prefix A.B.C.D/M */
1830 install_element(ENABLE_NODE, &debug_bgp_zebra_prefix_cmd);
1831 install_element(CONFIG_NODE, &debug_bgp_zebra_prefix_cmd);
1832 install_element(ENABLE_NODE, &no_debug_bgp_zebra_prefix_cmd);
1833 install_element(CONFIG_NODE, &no_debug_bgp_zebra_prefix_cmd);
1834
1835 install_element(ENABLE_NODE, &no_debug_bgp_as4_cmd);
1836 install_element(CONFIG_NODE, &no_debug_bgp_as4_cmd);
1837 install_element(ENABLE_NODE, &no_debug_bgp_as4_segment_cmd);
1838 install_element(CONFIG_NODE, &no_debug_bgp_as4_segment_cmd);
1839
1840 /* debug bgp neighbor-events A.B.C.D */
1841 install_element(ENABLE_NODE, &debug_bgp_neighbor_events_peer_cmd);
1842 install_element(CONFIG_NODE, &debug_bgp_neighbor_events_peer_cmd);
1843 install_element(ENABLE_NODE, &no_debug_bgp_neighbor_events_peer_cmd);
1844 install_element(CONFIG_NODE, &no_debug_bgp_neighbor_events_peer_cmd);
1845
1846 /* debug bgp keepalive A.B.C.D */
1847 install_element(ENABLE_NODE, &debug_bgp_keepalive_peer_cmd);
1848 install_element(CONFIG_NODE, &debug_bgp_keepalive_peer_cmd);
1849 install_element(ENABLE_NODE, &no_debug_bgp_keepalive_peer_cmd);
1850 install_element(CONFIG_NODE, &no_debug_bgp_keepalive_peer_cmd);
1851
1852 install_element(ENABLE_NODE, &no_debug_bgp_neighbor_events_cmd);
1853 install_element(CONFIG_NODE, &no_debug_bgp_neighbor_events_cmd);
1854 install_element(ENABLE_NODE, &no_debug_bgp_nht_cmd);
1855 install_element(CONFIG_NODE, &no_debug_bgp_nht_cmd);
1856 install_element(ENABLE_NODE, &no_debug_bgp_keepalive_cmd);
1857 install_element(CONFIG_NODE, &no_debug_bgp_keepalive_cmd);
1858 install_element(ENABLE_NODE, &no_debug_bgp_update_cmd);
1859 install_element(CONFIG_NODE, &no_debug_bgp_update_cmd);
1860 install_element(ENABLE_NODE, &no_debug_bgp_zebra_cmd);
1861 install_element(CONFIG_NODE, &no_debug_bgp_zebra_cmd);
1862 install_element(ENABLE_NODE, &no_debug_bgp_allow_martians_cmd);
1863 install_element(CONFIG_NODE, &no_debug_bgp_allow_martians_cmd);
1864 install_element(ENABLE_NODE, &no_debug_bgp_update_groups_cmd);
1865 install_element(CONFIG_NODE, &no_debug_bgp_update_groups_cmd);
1866 install_element(ENABLE_NODE, &no_debug_bgp_cmd);
1867 install_element(ENABLE_NODE, &no_debug_bgp_bestpath_cmd);
1868 install_element(CONFIG_NODE, &no_debug_bgp_bestpath_cmd);
1869 install_element(ENABLE_NODE, &no_debug_bgp_bestpath_prefix_cmd);
1870 install_element(CONFIG_NODE, &no_debug_bgp_bestpath_prefix_cmd);
1871}
16286195 1872
d62a17ae 1873/* Return true if this prefix is on the per_prefix_list of prefixes to debug
1874 * for BGP_DEBUG_TYPE
1875 */
1876static int bgp_debug_per_prefix(struct prefix *p,
1877 unsigned long term_bgp_debug_type,
1878 unsigned int BGP_DEBUG_TYPE,
1879 struct list *per_prefix_list)
1880{
1881 struct bgp_debug_filter *filter;
1882 struct listnode *node, *nnode;
1883
1884 if (term_bgp_debug_type & BGP_DEBUG_TYPE) {
1885 /* We are debugging all prefixes so return true */
1886 if (!per_prefix_list || list_isempty(per_prefix_list))
1887 return 1;
1888
1889 else {
1890 if (!p)
1891 return 0;
1892
1893 for (ALL_LIST_ELEMENTS(per_prefix_list, node, nnode,
1894 filter))
1895 if (filter->p->prefixlen == p->prefixlen
1896 && prefix_match(filter->p, p))
1897 return 1;
1898
1899 return 0;
1900 }
1901 }
1902
1903 return 0;
16286195
DS
1904}
1905
1906/* Return true if this peer is on the per_peer_list of peers to debug
1907 * for BGP_DEBUG_TYPE
1908 */
d62a17ae 1909static int bgp_debug_per_peer(char *host, unsigned long term_bgp_debug_type,
1910 unsigned int BGP_DEBUG_TYPE,
1911 struct list *per_peer_list)
16286195 1912{
d62a17ae 1913 struct bgp_debug_filter *filter;
1914 struct listnode *node, *nnode;
16286195 1915
d62a17ae 1916 if (term_bgp_debug_type & BGP_DEBUG_TYPE) {
1917 /* We are debugging all peers so return true */
1918 if (!per_peer_list || list_isempty(per_peer_list))
1919 return 1;
16286195 1920
d62a17ae 1921 else {
1922 if (!host)
1923 return 0;
16286195 1924
d62a17ae 1925 for (ALL_LIST_ELEMENTS(per_peer_list, node, nnode,
1926 filter))
1927 if (strcmp(filter->host, host) == 0)
1928 return 1;
16286195 1929
d62a17ae 1930 return 0;
1931 }
1932 }
16286195 1933
d62a17ae 1934 return 0;
16286195
DS
1935}
1936
d62a17ae 1937int bgp_debug_neighbor_events(struct peer *peer)
16286195 1938{
d62a17ae 1939 char *host = NULL;
167d390a 1940
d62a17ae 1941 if (peer)
1942 host = peer->host;
167d390a 1943
d62a17ae 1944 return bgp_debug_per_peer(host, term_bgp_debug_neighbor_events,
1945 BGP_DEBUG_NEIGHBOR_EVENTS,
1946 bgp_debug_neighbor_events_peers);
16286195
DS
1947}
1948
d62a17ae 1949int bgp_debug_keepalive(struct peer *peer)
16286195 1950{
d62a17ae 1951 char *host = NULL;
167d390a 1952
d62a17ae 1953 if (peer)
1954 host = peer->host;
167d390a 1955
d62a17ae 1956 return bgp_debug_per_peer(host, term_bgp_debug_keepalive,
1957 BGP_DEBUG_KEEPALIVE,
1958 bgp_debug_keepalive_peers);
16286195
DS
1959}
1960
d62a17ae 1961int bgp_debug_update(struct peer *peer, struct prefix *p,
1962 struct update_group *updgrp, unsigned int inbound)
16286195 1963{
d62a17ae 1964 char *host = NULL;
1965
1966 if (peer)
1967 host = peer->host;
1968
1969 if (inbound) {
1970 if (bgp_debug_per_peer(host, term_bgp_debug_update,
1971 BGP_DEBUG_UPDATE_IN,
1972 bgp_debug_update_in_peers))
1973 return 1;
1974 }
1975
1976 /* outbound */
1977 else {
1978 if (bgp_debug_per_peer(host, term_bgp_debug_update,
1979 BGP_DEBUG_UPDATE_OUT,
1980 bgp_debug_update_out_peers))
1981 return 1;
1982
1983 /* Check if update debugging implicitly enabled for the group.
1984 */
1985 if (updgrp && UPDGRP_DBG_ON(updgrp))
1986 return 1;
1987 }
1988
1989
1990 if (BGP_DEBUG(update, UPDATE_PREFIX)) {
1991 if (bgp_debug_per_prefix(p, term_bgp_debug_update,
1992 BGP_DEBUG_UPDATE_PREFIX,
1993 bgp_debug_update_prefixes))
1994 return 1;
1995 }
1996
1997 return 0;
16286195
DS
1998}
1999
d62a17ae 2000int bgp_debug_bestpath(struct prefix *p)
9fbdd100 2001{
d62a17ae 2002 if (BGP_DEBUG(bestpath, BESTPATH)) {
2003 if (bgp_debug_per_prefix(p, term_bgp_debug_bestpath,
2004 BGP_DEBUG_BESTPATH,
2005 bgp_debug_bestpath_prefixes))
2006 return 1;
2007 }
2008
2009 return 0;
9fbdd100
DS
2010}
2011
d62a17ae 2012int bgp_debug_zebra(struct prefix *p)
16286195 2013{
d62a17ae 2014 if (BGP_DEBUG(zebra, ZEBRA)) {
2015 if (bgp_debug_per_prefix(p, term_bgp_debug_zebra,
2016 BGP_DEBUG_ZEBRA,
2017 bgp_debug_zebra_prefixes))
2018 return 1;
2019 }
2020
2021 return 0;
718e3744 2022}
906ad49b 2023
d62a17ae 2024const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
2025 struct prefix_rd *prd,
2026 union prefixconstptr pu,
b57ba6d2
MK
2027 mpls_label_t *label, u_int32_t num_labels,
2028 int addpath_valid, u_int32_t addpath_id,
2029 char *str, int size)
d62a17ae 2030{
2031 char rd_buf[RD_ADDRSTRLEN];
2032 char pfx_buf[PREFIX_STRLEN];
2033 char tag_buf[30];
2034 /* ' with addpath ID ' 17
2035 * max strlen of uint32 + 10
2036 * +/- (just in case) + 1
2037 * null terminator + 1
2038 * ============================ 29 */
2039 char pathid_buf[30];
2040
2041 if (size < BGP_PRD_PATH_STRLEN)
2042 return NULL;
2043
2044 /* Note: Path-id is created by default, but only included in update
2045 * sometimes. */
2046 pathid_buf[0] = '\0';
2047 if (addpath_valid)
2048 snprintf(pathid_buf, sizeof(pathid_buf), " with addpath ID %u",
2049 addpath_id);
2050
2051 tag_buf[0] = '\0';
b57ba6d2 2052 if (bgp_labeled_safi(safi) && num_labels) {
d62a17ae 2053
b57ba6d2
MK
2054 if (safi == SAFI_EVPN) {
2055 char tag_buf2[20];
2056
2057 bgp_evpn_label2str(label, num_labels, tag_buf2, 20);
2058 sprintf(tag_buf, " label %s", tag_buf2);
2059 } else {
2060 u_int32_t label_value;
2061
2062 label_value = decode_label(label);
2063 sprintf(tag_buf, " label %u", label_value);
2064 }
d62a17ae 2065 }
2066
2067 if (prd)
e1af3f16 2068 snprintf(str, size, "RD %s %s%s%s %s %s",
d62a17ae 2069 prefix_rd2str(prd, rd_buf, sizeof(rd_buf)),
2070 prefix2str(pu, pfx_buf, sizeof(pfx_buf)), tag_buf,
e1af3f16 2071 pathid_buf, afi2str(afi), safi2str(safi));
d62a17ae 2072 else
e1af3f16 2073 snprintf(str, size, "%s%s%s %s %s",
d62a17ae 2074 prefix2str(pu, pfx_buf, sizeof(pfx_buf)), tag_buf,
e1af3f16 2075 pathid_buf, afi2str(afi), safi2str(safi));
d62a17ae 2076
2077 return str;
906ad49b 2078}