blob: 4a38c15aa41ccdb1c42ef94b285a649ec2d06d26 [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"
paul718e3742002-12-13 20:15:29 +000038
39#include "bgpd/bgpd.h"
40#include "bgpd/bgp_attr.h"
41#include "bgpd/bgp_mplsvpn.h"
Chris Caputo228da422009-07-18 05:44:03 +000042#include "bgpd/bgp_aspath.h"
43#include "bgpd/bgp_dump.h"
44#include "bgpd/bgp_route.h"
45#include "bgpd/bgp_nexthop.h"
46#include "bgpd/bgp_regex.h"
47#include "bgpd/bgp_clist.h"
48#include "bgpd/bgp_debug.h"
49#include "bgpd/bgp_filter.h"
paul718e3742002-12-13 20:15:29 +000050
51/* bgpd options, we use GNU getopt library. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -070052static const struct option longopts[] =
paul718e3742002-12-13 20:15:29 +000053{
54 { "daemon", no_argument, NULL, 'd'},
55 { "config_file", required_argument, NULL, 'f'},
56 { "pid_file", required_argument, NULL, 'i'},
57 { "bgp_port", required_argument, NULL, 'p'},
Paul Jakma3a02d1f2007-11-01 14:29:11 +000058 { "listenon", required_argument, NULL, 'l'},
paul718e3742002-12-13 20:15:29 +000059 { "vty_addr", required_argument, NULL, 'A'},
60 { "vty_port", required_argument, NULL, 'P'},
61 { "retain", no_argument, NULL, 'r'},
62 { "no_kernel", no_argument, NULL, 'n'},
pauledd7c242003-06-04 13:59:38 +000063 { "user", required_argument, NULL, 'u'},
hassoc0652302004-11-25 19:33:48 +000064 { "group", required_argument, NULL, 'g'},
paul718e3742002-12-13 20:15:29 +000065 { "version", no_argument, NULL, 'v'},
Paul Jakma876b8be2006-10-15 23:35:57 +000066 { "dryrun", no_argument, NULL, 'C'},
paul718e3742002-12-13 20:15:29 +000067 { "help", no_argument, NULL, 'h'},
68 { 0 }
69};
70
paul2d75d052004-01-19 21:31:15 +000071/* signal definitions */
72void sighup (void);
73void sigint (void);
74void sigusr1 (void);
75
Chris Caputo228da422009-07-18 05:44:03 +000076static void bgp_exit (int);
77
Stephen Hemminger372b3c72009-05-15 10:29:41 -070078static struct quagga_signal_t bgp_signals[] =
paul2d75d052004-01-19 21:31:15 +000079{
80 {
81 .signal = SIGHUP,
82 .handler = &sighup,
83 },
84 {
85 .signal = SIGUSR1,
86 .handler = &sigusr1,
87 },
88 {
89 .signal = SIGINT,
90 .handler = &sigint,
91 },
hassof571dab2004-03-22 08:55:25 +000092 {
93 .signal = SIGTERM,
94 .handler = &sigint,
95 },
paul2d75d052004-01-19 21:31:15 +000096};
97
paul718e3742002-12-13 20:15:29 +000098/* Configuration file and directory. */
paul718e3742002-12-13 20:15:29 +000099char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
100
101/* Route retain mode flag. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700102static int retain_mode = 0;
paul718e3742002-12-13 20:15:29 +0000103
104/* Master of threads. */
105struct thread_master *master;
106
107/* Manually specified configuration file name. */
108char *config_file = NULL;
109
110/* Process ID saved for use by init system */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700111static const char *pid_file = PATH_BGPD_PID;
paul718e3742002-12-13 20:15:29 +0000112
113/* VTY port number and address. */
114int vty_port = BGP_VTY_PORT;
115char *vty_addr = NULL;
116
pauledd7c242003-06-04 13:59:38 +0000117/* privileges */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700118static zebra_capabilities_t _caps_p [] =
pauledd7c242003-06-04 13:59:38 +0000119{
paul98f51632004-10-25 14:19:15 +0000120 ZCAP_BIND,
paulceacedb2005-09-29 14:39:32 +0000121 ZCAP_NET_RAW,
Chris Luke90d181b2011-10-18 17:26:51 +0400122 ZCAP_NET_ADMIN,
pauledd7c242003-06-04 13:59:38 +0000123};
124
125struct zebra_privs_t bgpd_privs =
126{
pauld81fadf2003-08-14 05:32:12 +0000127#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
128 .user = QUAGGA_USER,
129 .group = QUAGGA_GROUP,
130#endif
131#ifdef VTY_GROUP
132 .vty_group = VTY_GROUP,
pauledd7c242003-06-04 13:59:38 +0000133#endif
134 .caps_p = _caps_p,
135 .cap_num_p = sizeof(_caps_p)/sizeof(_caps_p[0]),
136 .cap_num_i = 0,
137};
138
paul718e3742002-12-13 20:15:29 +0000139/* Help information display. */
140static void
141usage (char *progname, int status)
142{
143 if (status != 0)
144 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
145 else
146 {
147 printf ("Usage : %s [OPTION...]\n\n\
148Daemon which manages kernel routing table management and \
149redistribution between different routing protocols.\n\n\
150-d, --daemon Runs in daemon mode\n\
151-f, --config_file Set configuration file name\n\
152-i, --pid_file Set process identifier file name\n\
153-p, --bgp_port Set bgp protocol's port number\n\
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000154-l, --listenon Listen on specified address (implies -n)\n\
paul718e3742002-12-13 20:15:29 +0000155-A, --vty_addr Set vty's bind address\n\
156-P, --vty_port Set vty's port number\n\
157-r, --retain When program terminates, retain added route by bgpd.\n\
158-n, --no_kernel Do not install route to kernel.\n\
hassoc0652302004-11-25 19:33:48 +0000159-u, --user User to run as\n\
160-g, --group Group to run as\n\
paul718e3742002-12-13 20:15:29 +0000161-v, --version Print program version\n\
Paul Jakma876b8be2006-10-15 23:35:57 +0000162-C, --dryrun Check configuration for validity and exit\n\
paul718e3742002-12-13 20:15:29 +0000163-h, --help Display this help and exit\n\
164\n\
165Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
166 }
167
168 exit (status);
169}
170
171/* SIGHUP handler. */
172void
paul2d75d052004-01-19 21:31:15 +0000173sighup (void)
paul718e3742002-12-13 20:15:29 +0000174{
175 zlog (NULL, LOG_INFO, "SIGHUP received");
176
177 /* Terminate all thread. */
178 bgp_terminate ();
179 bgp_reset ();
180 zlog_info ("bgpd restarting!");
181
182 /* Reload config file. */
hasso320ec102004-06-20 19:54:37 +0000183 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000184
185 /* Create VTY's socket */
paul4fc4e7a2003-01-22 19:47:09 +0000186 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
paul718e3742002-12-13 20:15:29 +0000187
188 /* Try to return to normal operation. */
189}
190
191/* SIGINT handler. */
192void
paul2d75d052004-01-19 21:31:15 +0000193sigint (void)
paul718e3742002-12-13 20:15:29 +0000194{
ajs887c44a2004-12-03 16:36:46 +0000195 zlog_notice ("Terminating on signal");
paul718e3742002-12-13 20:15:29 +0000196
197 if (! retain_mode)
198 bgp_terminate ();
199
Chris Caputo228da422009-07-18 05:44:03 +0000200 bgp_exit (0);
paul718e3742002-12-13 20:15:29 +0000201}
202
203/* SIGUSR1 handler. */
204void
paul2d75d052004-01-19 21:31:15 +0000205sigusr1 (void)
paul718e3742002-12-13 20:15:29 +0000206{
207 zlog_rotate (NULL);
208}
Chris Caputo228da422009-07-18 05:44:03 +0000209
210/*
211 Try to free up allocations we know about so that diagnostic tools such as
212 valgrind are able to better illuminate leaks.
213
214 Zebra route removal and protocol teardown are not meant to be done here.
215 For example, "retain_mode" may be set.
216*/
217static void
218bgp_exit (int status)
219{
220 struct bgp *bgp;
221 struct listnode *node, *nnode;
222 int *socket;
223 struct interface *ifp;
224 extern struct zclient *zclient;
225 extern struct zclient *zlookup;
226
227 /* it only makes sense for this to be called on a clean exit */
228 assert (status == 0);
229
230 /* reverse bgp_master_init */
231 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
232 bgp_delete (bgp);
233 list_free (bm->bgp);
234
235 /* reverse bgp_master_init */
236 for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
237 {
238 if (close ((int)(long)socket) == -1)
239 zlog_err ("close (%d): %s", (int)(long)socket, safe_strerror (errno));
240 }
241 list_delete (bm->listen_sockets);
242
243 /* reverse bgp_zebra_init/if_init */
244 if (retain_mode)
245 if_add_hook (IF_DELETE_HOOK, NULL);
246 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
247 if_delete (ifp);
248 list_free (iflist);
249
250 /* reverse bgp_attr_init */
251 bgp_attr_finish ();
252
253 /* reverse bgp_dump_init */
254 bgp_dump_finish ();
255
256 /* reverse bgp_route_init */
257 bgp_route_finish ();
258
259 /* reverse bgp_route_map_init/route_map_init */
260 route_map_finish ();
261
262 /* reverse bgp_scan_init */
263 bgp_scan_finish ();
264
265 /* reverse access_list_init */
266 access_list_add_hook (NULL);
267 access_list_delete_hook (NULL);
268 access_list_reset ();
269
270 /* reverse bgp_filter_init */
271 as_list_add_hook (NULL);
272 as_list_delete_hook (NULL);
273 bgp_filter_reset ();
274
275 /* reverse prefix_list_init */
276 prefix_list_add_hook (NULL);
277 prefix_list_delete_hook (NULL);
278 prefix_list_reset ();
279
280 /* reverse community_list_init */
281 community_list_terminate (bgp_clist);
282
283 cmd_terminate ();
284 vty_terminate ();
285 if (zclient)
286 zclient_free (zclient);
287 if (zlookup)
288 zclient_free (zlookup);
289
290 /* reverse bgp_master_init */
291 if (master)
292 thread_master_free (master);
293
294 if (zlog_default)
295 closezlog (zlog_default);
296
297 if (CONF_BGP_DEBUG (normal, NORMAL))
298 log_memstats_stderr ("bgpd");
299
300 exit (status);
301}
paul718e3742002-12-13 20:15:29 +0000302
303/* Main routine of bgpd. Treatment of argument and start bgp finite
304 state machine is handled at here. */
305int
306main (int argc, char **argv)
307{
308 char *p;
309 int opt;
310 int daemon_mode = 0;
Paul Jakma876b8be2006-10-15 23:35:57 +0000311 int dryrun = 0;
paul718e3742002-12-13 20:15:29 +0000312 char *progname;
313 struct thread thread;
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000314 int tmp_port;
paul718e3742002-12-13 20:15:29 +0000315
316 /* Set umask before anything for security */
317 umask (0027);
318
319 /* Preserve name of myself. */
320 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
321
ajs274a4a42004-12-07 15:39:31 +0000322 zlog_default = openzlog (progname, ZLOG_BGP,
paul718e3742002-12-13 20:15:29 +0000323 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
324
325 /* BGP master init. */
326 bgp_master_init ();
327
328 /* Command line argument treatment. */
329 while (1)
330 {
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000331 opt = getopt_long (argc, argv, "df:i:hp:l:A:P:rnu:g:vC", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000332
333 if (opt == EOF)
334 break;
335
336 switch (opt)
337 {
338 case 0:
339 break;
340 case 'd':
341 daemon_mode = 1;
342 break;
343 case 'f':
344 config_file = optarg;
345 break;
346 case 'i':
347 pid_file = optarg;
348 break;
349 case 'p':
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000350 tmp_port = atoi (optarg);
351 if (tmp_port <= 0 || tmp_port > 0xffff)
352 bm->port = BGP_PORT_DEFAULT;
353 else
354 bm->port = tmp_port;
paul718e3742002-12-13 20:15:29 +0000355 break;
356 case 'A':
357 vty_addr = optarg;
358 break;
359 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000360 /* Deal with atoi() returning 0 on failure, and bgpd not
361 listening on bgp port... */
362 if (strcmp(optarg, "0") == 0)
363 {
364 vty_port = 0;
365 break;
366 }
367 vty_port = atoi (optarg);
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000368 if (vty_port <= 0 || vty_port > 0xffff)
369 vty_port = BGP_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000370 break;
371 case 'r':
372 retain_mode = 1;
373 break;
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000374 case 'l':
375 bm->address = optarg;
376 /* listenon implies -n */
paul718e3742002-12-13 20:15:29 +0000377 case 'n':
378 bgp_option_set (BGP_OPT_NO_FIB);
379 break;
hassoc0652302004-11-25 19:33:48 +0000380 case 'u':
381 bgpd_privs.user = optarg;
382 break;
383 case 'g':
384 bgpd_privs.group = optarg;
385 break;
paul718e3742002-12-13 20:15:29 +0000386 case 'v':
387 print_version (progname);
388 exit (0);
389 break;
Paul Jakma876b8be2006-10-15 23:35:57 +0000390 case 'C':
391 dryrun = 1;
392 break;
paul718e3742002-12-13 20:15:29 +0000393 case 'h':
394 usage (progname, 0);
395 break;
396 default:
397 usage (progname, 1);
398 break;
399 }
400 }
401
402 /* Make thread master. */
403 master = bm->master;
404
405 /* Initializations. */
406 srand (time (NULL));
paul2d75d052004-01-19 21:31:15 +0000407 signal_init (master, Q_SIGC(bgp_signals), bgp_signals);
pauledd7c242003-06-04 13:59:38 +0000408 zprivs_init (&bgpd_privs);
paul718e3742002-12-13 20:15:29 +0000409 cmd_init (1);
paulb21b19c2003-06-15 01:28:29 +0000410 vty_init (master);
paul718e3742002-12-13 20:15:29 +0000411 memory_init ();
412
413 /* BGP related initialization. */
414 bgp_init ();
415
416 /* Sort CLI commands. */
417 sort_node ();
418
419 /* Parse config file. */
hasso320ec102004-06-20 19:54:37 +0000420 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000421
Paul Jakma876b8be2006-10-15 23:35:57 +0000422 /* Start execution only if not in dry-run mode */
423 if(dryrun)
424 return(0);
425
paul718e3742002-12-13 20:15:29 +0000426 /* Turn into daemon if daemon_mode is set. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700427 if (daemon_mode && daemon (0, 0) < 0)
428 {
429 zlog_err("BGPd daemon failed: %s", strerror(errno));
430 return (1);
431 }
432
paul718e3742002-12-13 20:15:29 +0000433
434 /* Process ID file creation. */
435 pid_output (pid_file);
436
437 /* Make bgp vty socket. */
438 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
439
440 /* Print banner. */
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000441 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", QUAGGA_VERSION,
Paul Jakma7e992e92007-11-13 09:32:23 +0000442 vty_port,
Paul Jakmab63e6082007-11-21 21:25:34 +0000443 (bm->address ? bm->address : "<all>"),
Paul Jakma7e992e92007-11-13 09:32:23 +0000444 bm->port);
paul718e3742002-12-13 20:15:29 +0000445
446 /* Start finite state machine, here we go! */
447 while (thread_fetch (master, &thread))
448 thread_call (&thread);
449
450 /* Not reached. */
paule8e19462006-01-19 20:16:55 +0000451 return (0);
paul718e3742002-12-13 20:15:29 +0000452}