blob: ad4de7989f0b68bb5c6665b99f507d83fc7c3e6e [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Main routine of bgpd.
2 Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "vector.h"
24#include "vty.h"
25#include "command.h"
26#include "getopt.h"
27#include "thread.h"
gdt5e4fa162004-03-16 14:38:36 +000028#include <lib/version.h>
paul718e3742002-12-13 20:15:29 +000029#include "memory.h"
30#include "prefix.h"
31#include "log.h"
pauledd7c242003-06-04 13:59:38 +000032#include "privs.h"
paul2d75d052004-01-19 21:31:15 +000033#include "sigevent.h"
Chris Caputo228da422009-07-18 05:44:03 +000034#include "zclient.h"
35#include "routemap.h"
36#include "filter.h"
37#include "plist.h"
Josh Bailey8196f132011-07-20 20:47:07 -070038#include "stream.h"
Feng Lu126215c2015-05-22 11:39:58 +020039#include "vrf.h"
paul718e3742002-12-13 20:15:29 +000040
41#include "bgpd/bgpd.h"
42#include "bgpd/bgp_attr.h"
43#include "bgpd/bgp_mplsvpn.h"
Chris Caputo228da422009-07-18 05:44:03 +000044#include "bgpd/bgp_aspath.h"
45#include "bgpd/bgp_dump.h"
46#include "bgpd/bgp_route.h"
47#include "bgpd/bgp_nexthop.h"
48#include "bgpd/bgp_regex.h"
49#include "bgpd/bgp_clist.h"
50#include "bgpd/bgp_debug.h"
51#include "bgpd/bgp_filter.h"
Josh Bailey8196f132011-07-20 20:47:07 -070052#include "bgpd/bgp_zebra.h"
paul718e3742002-12-13 20:15:29 +000053
54/* bgpd options, we use GNU getopt library. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -070055static const struct option longopts[] =
paul718e3742002-12-13 20:15:29 +000056{
57 { "daemon", no_argument, NULL, 'd'},
58 { "config_file", required_argument, NULL, 'f'},
59 { "pid_file", required_argument, NULL, 'i'},
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +040060 { "socket", required_argument, NULL, 'z'},
paul718e3742002-12-13 20:15:29 +000061 { "bgp_port", required_argument, NULL, 'p'},
Paul Jakma3a02d1f2007-11-01 14:29:11 +000062 { "listenon", required_argument, NULL, 'l'},
paul718e3742002-12-13 20:15:29 +000063 { "vty_addr", required_argument, NULL, 'A'},
64 { "vty_port", required_argument, NULL, 'P'},
65 { "retain", no_argument, NULL, 'r'},
66 { "no_kernel", no_argument, NULL, 'n'},
pauledd7c242003-06-04 13:59:38 +000067 { "user", required_argument, NULL, 'u'},
hassoc0652302004-11-25 19:33:48 +000068 { "group", required_argument, NULL, 'g'},
paul718e3742002-12-13 20:15:29 +000069 { "version", no_argument, NULL, 'v'},
Paul Jakma876b8be2006-10-15 23:35:57 +000070 { "dryrun", no_argument, NULL, 'C'},
paul718e3742002-12-13 20:15:29 +000071 { "help", no_argument, NULL, 'h'},
72 { 0 }
73};
74
paul2d75d052004-01-19 21:31:15 +000075/* signal definitions */
76void sighup (void);
77void sigint (void);
78void sigusr1 (void);
79
Chris Caputo228da422009-07-18 05:44:03 +000080static void bgp_exit (int);
81
Stephen Hemminger372b3c72009-05-15 10:29:41 -070082static struct quagga_signal_t bgp_signals[] =
paul2d75d052004-01-19 21:31:15 +000083{
84 {
85 .signal = SIGHUP,
86 .handler = &sighup,
87 },
88 {
89 .signal = SIGUSR1,
90 .handler = &sigusr1,
91 },
92 {
93 .signal = SIGINT,
94 .handler = &sigint,
95 },
hassof571dab2004-03-22 08:55:25 +000096 {
97 .signal = SIGTERM,
98 .handler = &sigint,
99 },
paul2d75d052004-01-19 21:31:15 +0000100};
101
paul718e3742002-12-13 20:15:29 +0000102/* Configuration file and directory. */
paul718e3742002-12-13 20:15:29 +0000103char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
104
105/* Route retain mode flag. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700106static int retain_mode = 0;
paul718e3742002-12-13 20:15:29 +0000107
108/* Master of threads. */
109struct thread_master *master;
110
111/* Manually specified configuration file name. */
112char *config_file = NULL;
113
114/* Process ID saved for use by init system */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700115static const char *pid_file = PATH_BGPD_PID;
paul718e3742002-12-13 20:15:29 +0000116
117/* VTY port number and address. */
118int vty_port = BGP_VTY_PORT;
119char *vty_addr = NULL;
120
pauledd7c242003-06-04 13:59:38 +0000121/* privileges */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700122static zebra_capabilities_t _caps_p [] =
pauledd7c242003-06-04 13:59:38 +0000123{
paul98f51632004-10-25 14:19:15 +0000124 ZCAP_BIND,
paulceacedb2005-09-29 14:39:32 +0000125 ZCAP_NET_RAW,
Chris Luke5c88f192011-10-18 17:26:51 +0400126 ZCAP_NET_ADMIN,
pauledd7c242003-06-04 13:59:38 +0000127};
128
129struct zebra_privs_t bgpd_privs =
130{
pauld81fadf2003-08-14 05:32:12 +0000131#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
132 .user = QUAGGA_USER,
133 .group = QUAGGA_GROUP,
134#endif
135#ifdef VTY_GROUP
136 .vty_group = VTY_GROUP,
pauledd7c242003-06-04 13:59:38 +0000137#endif
138 .caps_p = _caps_p,
Balaji.G837d16c2012-09-26 14:09:10 +0530139 .cap_num_p = array_size(_caps_p),
pauledd7c242003-06-04 13:59:38 +0000140 .cap_num_i = 0,
141};
142
paul718e3742002-12-13 20:15:29 +0000143/* Help information display. */
144static void
145usage (char *progname, int status)
146{
147 if (status != 0)
148 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
149 else
150 {
151 printf ("Usage : %s [OPTION...]\n\n\
152Daemon which manages kernel routing table management and \
153redistribution between different routing protocols.\n\n\
154-d, --daemon Runs in daemon mode\n\
155-f, --config_file Set configuration file name\n\
156-i, --pid_file Set process identifier file name\n\
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400157-z, --socket Set path of zebra socket\n\
paul718e3742002-12-13 20:15:29 +0000158-p, --bgp_port Set bgp protocol's port number\n\
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000159-l, --listenon Listen on specified address (implies -n)\n\
paul718e3742002-12-13 20:15:29 +0000160-A, --vty_addr Set vty's bind address\n\
161-P, --vty_port Set vty's port number\n\
162-r, --retain When program terminates, retain added route by bgpd.\n\
163-n, --no_kernel Do not install route to kernel.\n\
hassoc0652302004-11-25 19:33:48 +0000164-u, --user User to run as\n\
165-g, --group Group to run as\n\
paul718e3742002-12-13 20:15:29 +0000166-v, --version Print program version\n\
Paul Jakma876b8be2006-10-15 23:35:57 +0000167-C, --dryrun Check configuration for validity and exit\n\
paul718e3742002-12-13 20:15:29 +0000168-h, --help Display this help and exit\n\
169\n\
170Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
171 }
172
173 exit (status);
174}
David Lamparter6b0655a2014-06-04 06:53:35 +0200175
paul718e3742002-12-13 20:15:29 +0000176/* SIGHUP handler. */
177void
paul2d75d052004-01-19 21:31:15 +0000178sighup (void)
paul718e3742002-12-13 20:15:29 +0000179{
180 zlog (NULL, LOG_INFO, "SIGHUP received");
181
182 /* Terminate all thread. */
183 bgp_terminate ();
184 bgp_reset ();
185 zlog_info ("bgpd restarting!");
186
187 /* Reload config file. */
hasso320ec102004-06-20 19:54:37 +0000188 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000189
190 /* Create VTY's socket */
paul4fc4e7a2003-01-22 19:47:09 +0000191 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
paul718e3742002-12-13 20:15:29 +0000192
193 /* Try to return to normal operation. */
194}
195
196/* SIGINT handler. */
197void
paul2d75d052004-01-19 21:31:15 +0000198sigint (void)
paul718e3742002-12-13 20:15:29 +0000199{
ajs887c44a2004-12-03 16:36:46 +0000200 zlog_notice ("Terminating on signal");
paul718e3742002-12-13 20:15:29 +0000201
202 if (! retain_mode)
203 bgp_terminate ();
204
Stephen Hemminger04d5e242011-12-07 00:04:46 +0400205 zprivs_terminate (&bgpd_privs);
Chris Caputo228da422009-07-18 05:44:03 +0000206 bgp_exit (0);
paul718e3742002-12-13 20:15:29 +0000207}
208
209/* SIGUSR1 handler. */
210void
paul2d75d052004-01-19 21:31:15 +0000211sigusr1 (void)
paul718e3742002-12-13 20:15:29 +0000212{
213 zlog_rotate (NULL);
214}
Chris Caputo228da422009-07-18 05:44:03 +0000215
216/*
217 Try to free up allocations we know about so that diagnostic tools such as
218 valgrind are able to better illuminate leaks.
219
220 Zebra route removal and protocol teardown are not meant to be done here.
221 For example, "retain_mode" may be set.
222*/
223static void
224bgp_exit (int status)
225{
226 struct bgp *bgp;
227 struct listnode *node, *nnode;
228 int *socket;
229 struct interface *ifp;
230 extern struct zclient *zclient;
231 extern struct zclient *zlookup;
232
233 /* it only makes sense for this to be called on a clean exit */
234 assert (status == 0);
235
236 /* reverse bgp_master_init */
237 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
238 bgp_delete (bgp);
239 list_free (bm->bgp);
240
241 /* reverse bgp_master_init */
242 for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
243 {
244 if (close ((int)(long)socket) == -1)
245 zlog_err ("close (%d): %s", (int)(long)socket, safe_strerror (errno));
246 }
247 list_delete (bm->listen_sockets);
248
249 /* reverse bgp_zebra_init/if_init */
250 if (retain_mode)
251 if_add_hook (IF_DELETE_HOOK, NULL);
Feng Lu126215c2015-05-22 11:39:58 +0200252 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
Chris Caputo6c88b442010-07-27 16:28:55 +0000253 {
254 struct listnode *c_node, *c_nnode;
255 struct connected *c;
256
257 for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
258 bgp_connected_delete (c);
Chris Caputo6c88b442010-07-27 16:28:55 +0000259 }
Chris Caputo228da422009-07-18 05:44:03 +0000260
261 /* reverse bgp_attr_init */
262 bgp_attr_finish ();
263
264 /* reverse bgp_dump_init */
265 bgp_dump_finish ();
266
267 /* reverse bgp_route_init */
268 bgp_route_finish ();
269
270 /* reverse bgp_route_map_init/route_map_init */
271 route_map_finish ();
272
273 /* reverse bgp_scan_init */
274 bgp_scan_finish ();
275
276 /* reverse access_list_init */
277 access_list_add_hook (NULL);
278 access_list_delete_hook (NULL);
279 access_list_reset ();
280
281 /* reverse bgp_filter_init */
282 as_list_add_hook (NULL);
283 as_list_delete_hook (NULL);
284 bgp_filter_reset ();
285
286 /* reverse prefix_list_init */
287 prefix_list_add_hook (NULL);
288 prefix_list_delete_hook (NULL);
289 prefix_list_reset ();
290
291 /* reverse community_list_init */
292 community_list_terminate (bgp_clist);
293
Feng Lu126215c2015-05-22 11:39:58 +0200294 vrf_terminate ();
Chris Caputo228da422009-07-18 05:44:03 +0000295 cmd_terminate ();
296 vty_terminate ();
297 if (zclient)
298 zclient_free (zclient);
299 if (zlookup)
300 zclient_free (zlookup);
Josh Bailey8196f132011-07-20 20:47:07 -0700301 if (bgp_nexthop_buf)
302 stream_free (bgp_nexthop_buf);
Chris Caputo228da422009-07-18 05:44:03 +0000303
304 /* reverse bgp_master_init */
305 if (master)
306 thread_master_free (master);
307
308 if (zlog_default)
309 closezlog (zlog_default);
310
311 if (CONF_BGP_DEBUG (normal, NORMAL))
312 log_memstats_stderr ("bgpd");
313
314 exit (status);
315}
David Lamparter6b0655a2014-06-04 06:53:35 +0200316
paul718e3742002-12-13 20:15:29 +0000317/* Main routine of bgpd. Treatment of argument and start bgp finite
318 state machine is handled at here. */
319int
320main (int argc, char **argv)
321{
322 char *p;
323 int opt;
324 int daemon_mode = 0;
Paul Jakma876b8be2006-10-15 23:35:57 +0000325 int dryrun = 0;
paul718e3742002-12-13 20:15:29 +0000326 char *progname;
327 struct thread thread;
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000328 int tmp_port;
paul718e3742002-12-13 20:15:29 +0000329
330 /* Set umask before anything for security */
331 umask (0027);
332
333 /* Preserve name of myself. */
334 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
335
ajs274a4a42004-12-07 15:39:31 +0000336 zlog_default = openzlog (progname, ZLOG_BGP,
paul718e3742002-12-13 20:15:29 +0000337 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
338
339 /* BGP master init. */
340 bgp_master_init ();
341
342 /* Command line argument treatment. */
343 while (1)
344 {
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400345 opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vC", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000346
347 if (opt == EOF)
348 break;
349
350 switch (opt)
351 {
352 case 0:
353 break;
354 case 'd':
355 daemon_mode = 1;
356 break;
357 case 'f':
358 config_file = optarg;
359 break;
360 case 'i':
361 pid_file = optarg;
362 break;
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400363 case 'z':
364 zclient_serv_path_set (optarg);
365 break;
paul718e3742002-12-13 20:15:29 +0000366 case 'p':
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000367 tmp_port = atoi (optarg);
368 if (tmp_port <= 0 || tmp_port > 0xffff)
369 bm->port = BGP_PORT_DEFAULT;
370 else
371 bm->port = tmp_port;
paul718e3742002-12-13 20:15:29 +0000372 break;
373 case 'A':
374 vty_addr = optarg;
375 break;
376 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000377 /* Deal with atoi() returning 0 on failure, and bgpd not
378 listening on bgp port... */
379 if (strcmp(optarg, "0") == 0)
380 {
381 vty_port = 0;
382 break;
383 }
384 vty_port = atoi (optarg);
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000385 if (vty_port <= 0 || vty_port > 0xffff)
386 vty_port = BGP_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000387 break;
388 case 'r':
389 retain_mode = 1;
390 break;
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000391 case 'l':
392 bm->address = optarg;
393 /* listenon implies -n */
paul718e3742002-12-13 20:15:29 +0000394 case 'n':
395 bgp_option_set (BGP_OPT_NO_FIB);
396 break;
hassoc0652302004-11-25 19:33:48 +0000397 case 'u':
398 bgpd_privs.user = optarg;
399 break;
400 case 'g':
401 bgpd_privs.group = optarg;
402 break;
paul718e3742002-12-13 20:15:29 +0000403 case 'v':
404 print_version (progname);
405 exit (0);
406 break;
Paul Jakma876b8be2006-10-15 23:35:57 +0000407 case 'C':
408 dryrun = 1;
409 break;
paul718e3742002-12-13 20:15:29 +0000410 case 'h':
411 usage (progname, 0);
412 break;
413 default:
414 usage (progname, 1);
415 break;
416 }
417 }
418
419 /* Make thread master. */
420 master = bm->master;
421
422 /* Initializations. */
423 srand (time (NULL));
Balaji.G837d16c2012-09-26 14:09:10 +0530424 signal_init (master, array_size(bgp_signals), bgp_signals);
pauledd7c242003-06-04 13:59:38 +0000425 zprivs_init (&bgpd_privs);
paul718e3742002-12-13 20:15:29 +0000426 cmd_init (1);
paulb21b19c2003-06-15 01:28:29 +0000427 vty_init (master);
paul718e3742002-12-13 20:15:29 +0000428 memory_init ();
Feng Lu126215c2015-05-22 11:39:58 +0200429 vrf_init ();
paul718e3742002-12-13 20:15:29 +0000430
431 /* BGP related initialization. */
432 bgp_init ();
433
paul718e3742002-12-13 20:15:29 +0000434 /* Parse config file. */
hasso320ec102004-06-20 19:54:37 +0000435 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000436
Paul Jakma876b8be2006-10-15 23:35:57 +0000437 /* Start execution only if not in dry-run mode */
438 if(dryrun)
439 return(0);
440
paul718e3742002-12-13 20:15:29 +0000441 /* Turn into daemon if daemon_mode is set. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700442 if (daemon_mode && daemon (0, 0) < 0)
443 {
444 zlog_err("BGPd daemon failed: %s", strerror(errno));
445 return (1);
446 }
447
paul718e3742002-12-13 20:15:29 +0000448
449 /* Process ID file creation. */
450 pid_output (pid_file);
451
452 /* Make bgp vty socket. */
453 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
454
455 /* Print banner. */
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000456 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", QUAGGA_VERSION,
Paul Jakma7e992e92007-11-13 09:32:23 +0000457 vty_port,
Paul Jakmab63e6082007-11-21 21:25:34 +0000458 (bm->address ? bm->address : "<all>"),
Paul Jakma7e992e92007-11-13 09:32:23 +0000459 bm->port);
paul718e3742002-12-13 20:15:29 +0000460
461 /* Start finite state machine, here we go! */
462 while (thread_fetch (master, &thread))
463 thread_call (&thread);
464
465 /* Not reached. */
paule8e19462006-01-19 20:16:55 +0000466 return (0);
paul718e3742002-12-13 20:15:29 +0000467}