[ospfd] Restructure opsf_if_update() and ospf_network_run()
[jleu-quagga.git] / bgpd / bgp_dump.c
blobe815ea3cc90f284fef1c46a9605c60609b11ae92
1 /* BGP-4 dump routine
2 Copyright (C) 1999 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
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.
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.
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
21 #include <zebra.h>
23 #include "log.h"
24 #include "stream.h"
25 #include "sockunion.h"
26 #include "command.h"
27 #include "prefix.h"
28 #include "thread.h"
29 #include "linklist.h"
30 #include "bgpd/bgp_table.h"
32 #include "bgpd/bgpd.h"
33 #include "bgpd/bgp_route.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_dump.h"
37 enum bgp_dump_type
39 BGP_DUMP_ALL,
40 BGP_DUMP_UPDATES,
41 BGP_DUMP_ROUTES
44 enum MRT_MSG_TYPES {
45 MSG_NULL,
46 MSG_START, /* sender is starting up */
47 MSG_DIE, /* receiver should shut down */
48 MSG_I_AM_DEAD, /* sender is shutting down */
49 MSG_PEER_DOWN, /* sender's peer is down */
50 MSG_PROTOCOL_BGP, /* msg is a BGP packet */
51 MSG_PROTOCOL_RIP, /* msg is a RIP packet */
52 MSG_PROTOCOL_IDRP, /* msg is an IDRP packet */
53 MSG_PROTOCOL_RIPNG, /* msg is a RIPNG packet */
54 MSG_PROTOCOL_BGP4PLUS, /* msg is a BGP4+ packet */
55 MSG_PROTOCOL_BGP4PLUS_01, /* msg is a BGP4+ (draft 01) packet */
56 MSG_PROTOCOL_OSPF, /* msg is an OSPF packet */
57 MSG_TABLE_DUMP, /* routing table dump */
58 MSG_TABLE_DUMP_V2 /* routing table dump, version 2 */
61 static int bgp_dump_interval_func (struct thread *);
63 struct bgp_dump
65 enum bgp_dump_type type;
67 char *filename;
69 FILE *fp;
71 unsigned int interval;
73 char *interval_str;
75 struct thread *t_interval;
78 /* BGP packet dump output buffer. */
79 struct stream *bgp_dump_obuf;
81 /* BGP dump strucuture for 'dump bgp all' */
82 struct bgp_dump bgp_dump_all;
84 /* BGP dump structure for 'dump bgp updates' */
85 struct bgp_dump bgp_dump_updates;
87 /* BGP dump structure for 'dump bgp routes' */
88 struct bgp_dump bgp_dump_routes;
90 /* Dump whole BGP table is very heavy process. */
91 struct thread *t_bgp_dump_routes;
93 /* Some define for BGP packet dump. */
94 static FILE *
95 bgp_dump_open_file (struct bgp_dump *bgp_dump)
97 int ret;
98 time_t clock;
99 struct tm *tm;
100 char fullpath[MAXPATHLEN];
101 char realpath[MAXPATHLEN];
102 mode_t oldumask;
104 time (&clock);
105 tm = localtime (&clock);
107 if (bgp_dump->filename[0] != DIRECTORY_SEP)
109 sprintf (fullpath, "%s/%s", vty_get_cwd (), bgp_dump->filename);
110 ret = strftime (realpath, MAXPATHLEN, fullpath, tm);
112 else
113 ret = strftime (realpath, MAXPATHLEN, bgp_dump->filename, tm);
115 if (ret == 0)
117 zlog_warn ("bgp_dump_open_file: strftime error");
118 return NULL;
121 if (bgp_dump->fp)
122 fclose (bgp_dump->fp);
125 oldumask = umask(0777 & ~LOGFILE_MASK);
126 bgp_dump->fp = fopen (realpath, "w");
128 if (bgp_dump->fp == NULL)
130 zlog_warn ("bgp_dump_open_file: %s: %s", realpath, strerror (errno));
131 umask(oldumask);
132 return NULL;
134 umask(oldumask);
136 return bgp_dump->fp;
139 static int
140 bgp_dump_interval_add (struct bgp_dump *bgp_dump, int interval)
142 int secs_into_day;
143 time_t t;
144 struct tm *tm;
146 if (interval > 0)
148 /* Periodic dump every interval seconds */
149 if ((interval < 86400) && ((86400 % interval) == 0))
151 /* Dump at predictable times: if a day has a whole number of
152 * intervals, dump every interval seconds starting from midnight
154 (void) time(&t);
155 tm = localtime(&t);
156 secs_into_day = tm->tm_sec + 60*tm->tm_min + 60*60*tm->tm_hour;
157 interval = interval - secs_into_day % interval; /* always > 0 */
159 bgp_dump->t_interval = thread_add_timer (master, bgp_dump_interval_func,
160 bgp_dump, interval);
162 else
164 /* One-off dump: execute immediately, don't affect any scheduled dumps */
165 bgp_dump->t_interval = thread_add_event (master, bgp_dump_interval_func,
166 bgp_dump, 0);
169 return 0;
172 /* Dump common header. */
173 static void
174 bgp_dump_header (struct stream *obuf, int type, int subtype)
176 time_t now;
178 /* Set header. */
179 time (&now);
181 /* Put dump packet header. */
182 stream_putl (obuf, now);
183 stream_putw (obuf, type);
184 stream_putw (obuf, subtype);
186 stream_putl (obuf, 0); /* len */
189 static void
190 bgp_dump_set_size (struct stream *s, int type)
192 stream_putl_at (s, 8, stream_get_endp (s) - BGP_DUMP_HEADER_SIZE);
195 static void
196 bgp_dump_routes_index_table(struct bgp *bgp)
198 struct peer *peer;
199 struct listnode *node;
200 uint16_t peerno = 0;
201 struct stream *obuf;
203 obuf = bgp_dump_obuf;
204 stream_reset (obuf);
206 /* MRT header */
207 bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_PEER_INDEX_TABLE);
209 /* Collector BGP ID */
210 stream_put_in_addr (obuf, &bgp->router_id);
212 /* View name */
213 if(bgp->name)
215 stream_putw (obuf, strlen(bgp->name));
216 stream_put(obuf, bgp->name, strlen(bgp->name));
218 else
220 stream_putw(obuf, 0);
223 /* Peer count */
224 stream_putw (obuf, listcount(bgp->peer));
226 /* Walk down all peers */
227 for(ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
230 /* Peer's type */
231 if (sockunion_family(&peer->su) == AF_INET)
233 stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP);
235 #ifdef HAVE_IPV6
236 else if (sockunion_family(&peer->su) == AF_INET6)
238 stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP6);
240 #endif /* HAVE_IPV6 */
242 /* Peer's BGP ID */
243 stream_put_in_addr (obuf, &peer->remote_id);
245 /* Peer's IP address */
246 if (sockunion_family(&peer->su) == AF_INET)
248 stream_put_in_addr (obuf, &peer->su.sin.sin_addr);
250 #ifdef HAVE_IPV6
251 else if (sockunion_family(&peer->su) == AF_INET6)
253 stream_write (obuf, (u_char *)&peer->su.sin6.sin6_addr,
254 IPV6_MAX_BYTELEN);
256 #endif /* HAVE_IPV6 */
258 /* Peer's AS number. */
259 /* Note that, as this is an AS4 compliant quagga, the RIB is always AS4 */
260 stream_putl (obuf, peer->as);
262 /* Store the peer number for this peer */
263 peer->table_dump_index = peerno;
264 peerno++;
267 bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2);
269 fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp);
270 fflush (bgp_dump_routes.fp);
274 /* Runs under child process. */
275 static unsigned int
276 bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
278 struct stream *obuf;
279 struct bgp_info *info;
280 struct bgp_node *rn;
281 struct bgp *bgp;
282 struct bgp_table *table;
284 bgp = bgp_get_default ();
285 if (!bgp)
286 return seq;
288 if (bgp_dump_routes.fp == NULL)
289 return seq;
291 /* Note that bgp_dump_routes_index_table will do ipv4 and ipv6 peers,
292 so this should only be done on the first call to bgp_dump_routes_func.
293 ( this function will be called once for ipv4 and once for ipv6 ) */
294 if(first_run)
295 bgp_dump_routes_index_table(bgp);
297 obuf = bgp_dump_obuf;
298 stream_reset(obuf);
300 /* Walk down each BGP route. */
301 table = bgp->rib[afi][SAFI_UNICAST];
303 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
305 if(!rn->info)
306 continue;
308 stream_reset(obuf);
310 /* MRT header */
311 if (afi == AFI_IP)
313 bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV4_UNICAST);
315 #ifdef HAVE_IPV6
316 else if (afi == AFI_IP6)
318 bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV6_UNICAST);
320 #endif /* HAVE_IPV6 */
322 /* Sequence number */
323 stream_putl(obuf, seq);
325 /* Prefix length */
326 stream_putc (obuf, rn->p.prefixlen);
328 /* Prefix */
329 if (afi == AFI_IP)
331 /* We'll dump only the useful bits (those not 0), but have to align on 8 bits */
332 stream_write(obuf, (u_char *)&rn->p.u.prefix4, (rn->p.prefixlen+7)/8);
334 #ifdef HAVE_IPV6
335 else if (afi == AFI_IP6)
337 /* We'll dump only the useful bits (those not 0), but have to align on 8 bits */
338 stream_write (obuf, (u_char *)&rn->p.u.prefix6, (rn->p.prefixlen+7)/8);
340 #endif /* HAVE_IPV6 */
342 /* Save where we are now, so we can overwride the entry count later */
343 int sizep = stream_get_endp(obuf);
345 /* Entry count */
346 uint16_t entry_count = 0;
348 /* Entry count, note that this is overwritten later */
349 stream_putw(obuf, 0);
351 for (info = rn->info; info; info = info->next)
353 entry_count++;
355 /* Peer index */
356 stream_putw(obuf, info->peer->table_dump_index);
358 /* Originated */
359 stream_putl (obuf, info->uptime);
361 /* Dump attribute. */
362 /* Skip prefix & AFI/SAFI for MP_NLRI */
363 bgp_dump_routes_attr (obuf, info->attr, &rn->p);
366 /* Overwrite the entry count, now that we know the right number */
367 stream_putw_at (obuf, sizep, entry_count);
369 seq++;
371 bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2);
372 fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp);
376 fflush (bgp_dump_routes.fp);
378 return seq;
381 static int
382 bgp_dump_interval_func (struct thread *t)
384 struct bgp_dump *bgp_dump;
385 bgp_dump = THREAD_ARG (t);
386 bgp_dump->t_interval = NULL;
388 /* Reschedule dump even if file couldn't be opened this time... */
389 if (bgp_dump_open_file (bgp_dump) != NULL)
391 /* In case of bgp_dump_routes, we need special route dump function. */
392 if (bgp_dump->type == BGP_DUMP_ROUTES)
394 unsigned int seq = bgp_dump_routes_func (AFI_IP, 1, 0);
395 #ifdef HAVE_IPV6
396 bgp_dump_routes_func (AFI_IP6, 0, seq);
397 #endif /* HAVE_IPV6 */
398 /* Close the file now. For a RIB dump there's no point in leaving
399 * it open until the next scheduled dump starts. */
400 fclose(bgp_dump->fp); bgp_dump->fp = NULL;
404 /* if interval is set reschedule */
405 if (bgp_dump->interval > 0)
406 bgp_dump_interval_add (bgp_dump, bgp_dump->interval);
408 return 0;
411 /* Dump common information. */
412 static void
413 bgp_dump_common (struct stream *obuf, struct peer *peer, int forceas4)
415 char empty[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
417 /* Source AS number and Destination AS number. */
418 if (forceas4 || CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) )
420 stream_putl (obuf, peer->as);
421 stream_putl (obuf, peer->local_as);
423 else
425 stream_putw (obuf, peer->as);
426 stream_putw (obuf, peer->local_as);
429 if (peer->su.sa.sa_family == AF_INET)
431 stream_putw (obuf, peer->ifindex);
432 stream_putw (obuf, AFI_IP);
434 stream_put (obuf, &peer->su.sin.sin_addr, IPV4_MAX_BYTELEN);
436 if (peer->su_local)
437 stream_put (obuf, &peer->su_local->sin.sin_addr, IPV4_MAX_BYTELEN);
438 else
439 stream_put (obuf, empty, IPV4_MAX_BYTELEN);
441 #ifdef HAVE_IPV6
442 else if (peer->su.sa.sa_family == AF_INET6)
444 /* Interface Index and Address family. */
445 stream_putw (obuf, peer->ifindex);
446 stream_putw (obuf, AFI_IP6);
448 /* Source IP Address and Destination IP Address. */
449 stream_put (obuf, &peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN);
451 if (peer->su_local)
452 stream_put (obuf, &peer->su_local->sin6.sin6_addr, IPV6_MAX_BYTELEN);
453 else
454 stream_put (obuf, empty, IPV6_MAX_BYTELEN);
456 #endif /* HAVE_IPV6 */
459 /* Dump BGP status change. */
460 void
461 bgp_dump_state (struct peer *peer, int status_old, int status_new)
463 struct stream *obuf;
465 /* If dump file pointer is disabled return immediately. */
466 if (bgp_dump_all.fp == NULL)
467 return;
469 /* Make dump stream. */
470 obuf = bgp_dump_obuf;
471 stream_reset (obuf);
473 bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_STATE_CHANGE_AS4);
474 bgp_dump_common (obuf, peer, 1);/* force this in as4speak*/
476 stream_putw (obuf, status_old);
477 stream_putw (obuf, status_new);
479 /* Set length. */
480 bgp_dump_set_size (obuf, MSG_PROTOCOL_BGP4MP);
482 /* Write to the stream. */
483 fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_all.fp);
484 fflush (bgp_dump_all.fp);
487 static void
488 bgp_dump_packet_func (struct bgp_dump *bgp_dump, struct peer *peer,
489 struct stream *packet)
491 struct stream *obuf;
493 /* If dump file pointer is disabled return immediately. */
494 if (bgp_dump->fp == NULL)
495 return;
497 /* Make dump stream. */
498 obuf = bgp_dump_obuf;
499 stream_reset (obuf);
501 /* Dump header and common part. */
502 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) )
504 bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE_AS4);
506 else
508 bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE);
510 bgp_dump_common (obuf, peer, 0);
512 /* Packet contents. */
513 stream_put (obuf, STREAM_DATA (packet), stream_get_endp (packet));
515 /* Set length. */
516 bgp_dump_set_size (obuf, MSG_PROTOCOL_BGP4MP);
518 /* Write to the stream. */
519 fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump->fp);
520 fflush (bgp_dump->fp);
523 /* Called from bgp_packet.c when BGP packet is received. */
524 void
525 bgp_dump_packet (struct peer *peer, int type, struct stream *packet)
527 /* bgp_dump_all. */
528 bgp_dump_packet_func (&bgp_dump_all, peer, packet);
530 /* bgp_dump_updates. */
531 if (type == BGP_MSG_UPDATE)
532 bgp_dump_packet_func (&bgp_dump_updates, peer, packet);
535 static unsigned int
536 bgp_dump_parse_time (const char *str)
538 int i;
539 int len;
540 int seen_h;
541 int seen_m;
542 int time;
543 unsigned int total;
545 time = 0;
546 total = 0;
547 seen_h = 0;
548 seen_m = 0;
549 len = strlen (str);
551 for (i = 0; i < len; i++)
553 if (isdigit ((int) str[i]))
555 time *= 10;
556 time += str[i] - '0';
558 else if (str[i] == 'H' || str[i] == 'h')
560 if (seen_h)
561 return 0;
562 if (seen_m)
563 return 0;
564 total += time * 60 *60;
565 time = 0;
566 seen_h = 1;
568 else if (str[i] == 'M' || str[i] == 'm')
570 if (seen_m)
571 return 0;
572 total += time * 60;
573 time = 0;
574 seen_h = 1;
576 else
577 return 0;
579 return total + time;
582 static int
583 bgp_dump_set (struct vty *vty, struct bgp_dump *bgp_dump,
584 enum bgp_dump_type type, const char *path,
585 const char *interval_str)
587 unsigned int interval;
589 if (interval_str)
592 /* Check interval string. */
593 interval = bgp_dump_parse_time (interval_str);
594 if (interval == 0)
596 vty_out (vty, "Malformed interval string%s", VTY_NEWLINE);
597 return CMD_WARNING;
600 /* Don't schedule duplicate dumps if the dump command is given twice */
601 if (interval == bgp_dump->interval &&
602 type == bgp_dump->type &&
603 path && bgp_dump->filename && !strcmp (path, bgp_dump->filename))
605 return CMD_SUCCESS;
608 /* Set interval. */
609 bgp_dump->interval = interval;
610 if (bgp_dump->interval_str)
611 free (bgp_dump->interval_str);
612 bgp_dump->interval_str = strdup (interval_str);
615 else
617 interval = 0;
620 /* Create interval thread. */
621 bgp_dump_interval_add (bgp_dump, interval);
623 /* Set type. */
624 bgp_dump->type = type;
626 /* Set file name. */
627 if (bgp_dump->filename)
628 free (bgp_dump->filename);
629 bgp_dump->filename = strdup (path);
631 /* This should be called when interval is expired. */
632 bgp_dump_open_file (bgp_dump);
634 return CMD_SUCCESS;
637 static int
638 bgp_dump_unset (struct vty *vty, struct bgp_dump *bgp_dump)
640 /* Set file name. */
641 if (bgp_dump->filename)
643 free (bgp_dump->filename);
644 bgp_dump->filename = NULL;
647 /* This should be called when interval is expired. */
648 if (bgp_dump->fp)
650 fclose (bgp_dump->fp);
651 bgp_dump->fp = NULL;
654 /* Create interval thread. */
655 if (bgp_dump->t_interval)
657 thread_cancel (bgp_dump->t_interval);
658 bgp_dump->t_interval = NULL;
661 bgp_dump->interval = 0;
663 if (bgp_dump->interval_str)
665 free (bgp_dump->interval_str);
666 bgp_dump->interval_str = NULL;
670 return CMD_SUCCESS;
673 DEFUN (dump_bgp_all,
674 dump_bgp_all_cmd,
675 "dump bgp all PATH",
676 "Dump packet\n"
677 "BGP packet dump\n"
678 "Dump all BGP packets\n"
679 "Output filename\n")
681 return bgp_dump_set (vty, &bgp_dump_all, BGP_DUMP_ALL, argv[0], NULL);
684 DEFUN (dump_bgp_all_interval,
685 dump_bgp_all_interval_cmd,
686 "dump bgp all PATH INTERVAL",
687 "Dump packet\n"
688 "BGP packet dump\n"
689 "Dump all BGP packets\n"
690 "Output filename\n"
691 "Interval of output\n")
693 return bgp_dump_set (vty, &bgp_dump_all, BGP_DUMP_ALL, argv[0], argv[1]);
696 DEFUN (no_dump_bgp_all,
697 no_dump_bgp_all_cmd,
698 "no dump bgp all [PATH] [INTERVAL]",
699 NO_STR
700 "Dump packet\n"
701 "BGP packet dump\n"
702 "Dump all BGP packets\n")
704 return bgp_dump_unset (vty, &bgp_dump_all);
707 DEFUN (dump_bgp_updates,
708 dump_bgp_updates_cmd,
709 "dump bgp updates PATH",
710 "Dump packet\n"
711 "BGP packet dump\n"
712 "Dump BGP updates only\n"
713 "Output filename\n")
715 return bgp_dump_set (vty, &bgp_dump_updates, BGP_DUMP_UPDATES, argv[0], NULL);
718 DEFUN (dump_bgp_updates_interval,
719 dump_bgp_updates_interval_cmd,
720 "dump bgp updates PATH INTERVAL",
721 "Dump packet\n"
722 "BGP packet dump\n"
723 "Dump BGP updates only\n"
724 "Output filename\n"
725 "Interval of output\n")
727 return bgp_dump_set (vty, &bgp_dump_updates, BGP_DUMP_UPDATES, argv[0], argv[1]);
730 DEFUN (no_dump_bgp_updates,
731 no_dump_bgp_updates_cmd,
732 "no dump bgp updates [PATH] [INTERVAL]",
733 NO_STR
734 "Dump packet\n"
735 "BGP packet dump\n"
736 "Dump BGP updates only\n")
738 return bgp_dump_unset (vty, &bgp_dump_updates);
741 DEFUN (dump_bgp_routes,
742 dump_bgp_routes_cmd,
743 "dump bgp routes-mrt PATH",
744 "Dump packet\n"
745 "BGP packet dump\n"
746 "Dump whole BGP routing table\n"
747 "Output filename\n")
749 return bgp_dump_set (vty, &bgp_dump_routes, BGP_DUMP_ROUTES, argv[0], NULL);
752 DEFUN (dump_bgp_routes_interval,
753 dump_bgp_routes_interval_cmd,
754 "dump bgp routes-mrt PATH INTERVAL",
755 "Dump packet\n"
756 "BGP packet dump\n"
757 "Dump whole BGP routing table\n"
758 "Output filename\n"
759 "Interval of output\n")
761 return bgp_dump_set (vty, &bgp_dump_routes, BGP_DUMP_ROUTES, argv[0], argv[1]);
764 DEFUN (no_dump_bgp_routes,
765 no_dump_bgp_routes_cmd,
766 "no dump bgp routes-mrt [PATH] [INTERVAL]",
767 NO_STR
768 "Dump packet\n"
769 "BGP packet dump\n"
770 "Dump whole BGP routing table\n")
772 return bgp_dump_unset (vty, &bgp_dump_routes);
775 /* BGP node structure. */
776 struct cmd_node bgp_dump_node =
778 DUMP_NODE,
783 #if 0
784 char *
785 config_time2str (unsigned int interval)
787 static char buf[BUFSIZ];
789 buf[0] = '\0';
791 if (interval / 3600)
793 sprintf (buf, "%dh", interval / 3600);
794 interval %= 3600;
796 if (interval / 60)
798 sprintf (buf + strlen (buf), "%dm", interval /60);
799 interval %= 60;
801 if (interval)
803 sprintf (buf + strlen (buf), "%d", interval);
805 return buf;
807 #endif
809 static int
810 config_write_bgp_dump (struct vty *vty)
812 if (bgp_dump_all.filename)
814 if (bgp_dump_all.interval_str)
815 vty_out (vty, "dump bgp all %s %s%s",
816 bgp_dump_all.filename, bgp_dump_all.interval_str,
817 VTY_NEWLINE);
818 else
819 vty_out (vty, "dump bgp all %s%s",
820 bgp_dump_all.filename, VTY_NEWLINE);
822 if (bgp_dump_updates.filename)
824 if (bgp_dump_updates.interval_str)
825 vty_out (vty, "dump bgp updates %s %s%s",
826 bgp_dump_updates.filename, bgp_dump_updates.interval_str,
827 VTY_NEWLINE);
828 else
829 vty_out (vty, "dump bgp updates %s%s",
830 bgp_dump_updates.filename, VTY_NEWLINE);
832 if (bgp_dump_routes.filename)
834 if (bgp_dump_routes.interval_str)
835 vty_out (vty, "dump bgp routes-mrt %s %s%s",
836 bgp_dump_routes.filename, bgp_dump_routes.interval_str,
837 VTY_NEWLINE);
838 else
839 vty_out (vty, "dump bgp routes-mrt %s%s",
840 bgp_dump_routes.filename, VTY_NEWLINE);
842 return 0;
845 /* Initialize BGP packet dump functionality. */
846 void
847 bgp_dump_init (void)
849 memset (&bgp_dump_all, 0, sizeof (struct bgp_dump));
850 memset (&bgp_dump_updates, 0, sizeof (struct bgp_dump));
851 memset (&bgp_dump_routes, 0, sizeof (struct bgp_dump));
853 bgp_dump_obuf = stream_new (BGP_MAX_PACKET_SIZE + BGP_DUMP_MSG_HEADER
854 + BGP_DUMP_HEADER_SIZE);
856 install_node (&bgp_dump_node, config_write_bgp_dump);
858 install_element (CONFIG_NODE, &dump_bgp_all_cmd);
859 install_element (CONFIG_NODE, &dump_bgp_all_interval_cmd);
860 install_element (CONFIG_NODE, &no_dump_bgp_all_cmd);
861 install_element (CONFIG_NODE, &dump_bgp_updates_cmd);
862 install_element (CONFIG_NODE, &dump_bgp_updates_interval_cmd);
863 install_element (CONFIG_NODE, &no_dump_bgp_updates_cmd);
864 install_element (CONFIG_NODE, &dump_bgp_routes_cmd);
865 install_element (CONFIG_NODE, &dump_bgp_routes_interval_cmd);
866 install_element (CONFIG_NODE, &no_dump_bgp_routes_cmd);