blob: 8dede587104f99e0dcb06c3597ccff7b530b5568 [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'},
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +040057 { "socket", required_argument, NULL, 'z'},
paul718e3742002-12-13 20:15:29 +000058 { "bgp_port", required_argument, NULL, 'p'},
Paul Jakma3a02d1f2007-11-01 14:29:11 +000059 { "listenon", required_argument, NULL, 'l'},
paul718e3742002-12-13 20:15:29 +000060 { "vty_addr", required_argument, NULL, 'A'},
61 { "vty_port", required_argument, NULL, 'P'},
62 { "retain", no_argument, NULL, 'r'},
63 { "no_kernel", no_argument, NULL, 'n'},
pauledd7c242003-06-04 13:59:38 +000064 { "user", required_argument, NULL, 'u'},
hassoc0652302004-11-25 19:33:48 +000065 { "group", required_argument, NULL, 'g'},
paul718e3742002-12-13 20:15:29 +000066 { "version", no_argument, NULL, 'v'},
Paul Jakma876b8be2006-10-15 23:35:57 +000067 { "dryrun", no_argument, NULL, 'C'},
paul718e3742002-12-13 20:15:29 +000068 { "help", no_argument, NULL, 'h'},
69 { 0 }
70};
71
paul2d75d052004-01-19 21:31:15 +000072/* signal definitions */
73void sighup (void);
74void sigint (void);
75void sigusr1 (void);
76
Chris Caputo228da422009-07-18 05:44:03 +000077static void bgp_exit (int);
78
Stephen Hemminger372b3c72009-05-15 10:29:41 -070079static struct quagga_signal_t bgp_signals[] =
paul2d75d052004-01-19 21:31:15 +000080{
81 {
82 .signal = SIGHUP,
83 .handler = &sighup,
84 },
85 {
86 .signal = SIGUSR1,
87 .handler = &sigusr1,
88 },
89 {
90 .signal = SIGINT,
91 .handler = &sigint,
92 },
hassof571dab2004-03-22 08:55:25 +000093 {
94 .signal = SIGTERM,
95 .handler = &sigint,
96 },
paul2d75d052004-01-19 21:31:15 +000097};
98
paul718e3742002-12-13 20:15:29 +000099/* Configuration file and directory. */
paul718e3742002-12-13 20:15:29 +0000100char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
101
102/* Route retain mode flag. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700103static int retain_mode = 0;
paul718e3742002-12-13 20:15:29 +0000104
105/* Master of threads. */
106struct thread_master *master;
107
108/* Manually specified configuration file name. */
109char *config_file = NULL;
110
111/* Process ID saved for use by init system */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700112static const char *pid_file = PATH_BGPD_PID;
paul718e3742002-12-13 20:15:29 +0000113
114/* VTY port number and address. */
115int vty_port = BGP_VTY_PORT;
116char *vty_addr = NULL;
117
pauledd7c242003-06-04 13:59:38 +0000118/* privileges */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700119static zebra_capabilities_t _caps_p [] =
pauledd7c242003-06-04 13:59:38 +0000120{
paul98f51632004-10-25 14:19:15 +0000121 ZCAP_BIND,
paulceacedb2005-09-29 14:39:32 +0000122 ZCAP_NET_RAW,
Chris Luke5c88f192011-10-18 17:26:51 +0400123 ZCAP_NET_ADMIN,
pauledd7c242003-06-04 13:59:38 +0000124};
125
126struct zebra_privs_t bgpd_privs =
127{
pauld81fadf2003-08-14 05:32:12 +0000128#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
129 .user = QUAGGA_USER,
130 .group = QUAGGA_GROUP,
131#endif
132#ifdef VTY_GROUP
133 .vty_group = VTY_GROUP,
pauledd7c242003-06-04 13:59:38 +0000134#endif
135 .caps_p = _caps_p,
136 .cap_num_p = sizeof(_caps_p)/sizeof(_caps_p[0]),
137 .cap_num_i = 0,
138};
139
paul718e3742002-12-13 20:15:29 +0000140/* Help information display. */
141static void
142usage (char *progname, int status)
143{
144 if (status != 0)
145 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
146 else
147 {
148 printf ("Usage : %s [OPTION...]\n\n\
149Daemon which manages kernel routing table management and \
150redistribution between different routing protocols.\n\n\
151-d, --daemon Runs in daemon mode\n\
152-f, --config_file Set configuration file name\n\
153-i, --pid_file Set process identifier file name\n\
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400154-z, --socket Set path of zebra socket\n\
paul718e3742002-12-13 20:15:29 +0000155-p, --bgp_port Set bgp protocol's port number\n\
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000156-l, --listenon Listen on specified address (implies -n)\n\
paul718e3742002-12-13 20:15:29 +0000157-A, --vty_addr Set vty's bind address\n\
158-P, --vty_port Set vty's port number\n\
159-r, --retain When program terminates, retain added route by bgpd.\n\
160-n, --no_kernel Do not install route to kernel.\n\
hassoc0652302004-11-25 19:33:48 +0000161-u, --user User to run as\n\
162-g, --group Group to run as\n\
paul718e3742002-12-13 20:15:29 +0000163-v, --version Print program version\n\
Paul Jakma876b8be2006-10-15 23:35:57 +0000164-C, --dryrun Check configuration for validity and exit\n\
paul718e3742002-12-13 20:15:29 +0000165-h, --help Display this help and exit\n\
166\n\
167Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
168 }
169
170 exit (status);
171}
172
173/* SIGHUP handler. */
174void
paul2d75d052004-01-19 21:31:15 +0000175sighup (void)
paul718e3742002-12-13 20:15:29 +0000176{
177 zlog (NULL, LOG_INFO, "SIGHUP received");
178
179 /* Terminate all thread. */
180 bgp_terminate ();
181 bgp_reset ();
182 zlog_info ("bgpd restarting!");
183
184 /* Reload config file. */
hasso320ec102004-06-20 19:54:37 +0000185 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000186
187 /* Create VTY's socket */
paul4fc4e7a2003-01-22 19:47:09 +0000188 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
paul718e3742002-12-13 20:15:29 +0000189
190 /* Try to return to normal operation. */
191}
192
193/* SIGINT handler. */
194void
paul2d75d052004-01-19 21:31:15 +0000195sigint (void)
paul718e3742002-12-13 20:15:29 +0000196{
ajs887c44a2004-12-03 16:36:46 +0000197 zlog_notice ("Terminating on signal");
paul718e3742002-12-13 20:15:29 +0000198
199 if (! retain_mode)
200 bgp_terminate ();
201
Stephen Hemminger04d5e242011-12-07 00:04:46 +0400202 zprivs_terminate (&bgpd_privs);
Chris Caputo228da422009-07-18 05:44:03 +0000203 bgp_exit (0);
paul718e3742002-12-13 20:15:29 +0000204}
205
206/* SIGUSR1 handler. */
207void
paul2d75d052004-01-19 21:31:15 +0000208sigusr1 (void)
paul718e3742002-12-13 20:15:29 +0000209{
210 zlog_rotate (NULL);
211}
Chris Caputo228da422009-07-18 05:44:03 +0000212
213/*
214 Try to free up allocations we know about so that diagnostic tools such as
215 valgrind are able to better illuminate leaks.
216
217 Zebra route removal and protocol teardown are not meant to be done here.
218 For example, "retain_mode" may be set.
219*/
220static void
221bgp_exit (int status)
222{
223 struct bgp *bgp;
224 struct listnode *node, *nnode;
225 int *socket;
226 struct interface *ifp;
227 extern struct zclient *zclient;
228 extern struct zclient *zlookup;
229
230 /* it only makes sense for this to be called on a clean exit */
231 assert (status == 0);
232
233 /* reverse bgp_master_init */
234 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
235 bgp_delete (bgp);
236 list_free (bm->bgp);
237
238 /* reverse bgp_master_init */
239 for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
240 {
241 if (close ((int)(long)socket) == -1)
242 zlog_err ("close (%d): %s", (int)(long)socket, safe_strerror (errno));
243 }
244 list_delete (bm->listen_sockets);
245
246 /* reverse bgp_zebra_init/if_init */
247 if (retain_mode)
248 if_add_hook (IF_DELETE_HOOK, NULL);
249 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
Chris Caputo6c88b442010-07-27 16:28:55 +0000250 {
251 struct listnode *c_node, *c_nnode;
252 struct connected *c;
253
254 for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
255 bgp_connected_delete (c);
256
257 if_delete (ifp);
258 }
Chris Caputo228da422009-07-18 05:44:03 +0000259 list_free (iflist);
260
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
294 cmd_terminate ();
295 vty_terminate ();
296 if (zclient)
297 zclient_free (zclient);
298 if (zlookup)
299 zclient_free (zlookup);
300
301 /* reverse bgp_master_init */
302 if (master)
303 thread_master_free (master);
304
305 if (zlog_default)
306 closezlog (zlog_default);
307
308 if (CONF_BGP_DEBUG (normal, NORMAL))
309 log_memstats_stderr ("bgpd");
310
311 exit (status);
312}
paul718e3742002-12-13 20:15:29 +0000313
314/* Main routine of bgpd. Treatment of argument and start bgp finite
315 state machine is handled at here. */
316int
317main (int argc, char **argv)
318{
319 char *p;
320 int opt;
321 int daemon_mode = 0;
Paul Jakma876b8be2006-10-15 23:35:57 +0000322 int dryrun = 0;
paul718e3742002-12-13 20:15:29 +0000323 char *progname;
324 struct thread thread;
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000325 int tmp_port;
paul718e3742002-12-13 20:15:29 +0000326
327 /* Set umask before anything for security */
328 umask (0027);
329
330 /* Preserve name of myself. */
331 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
332
ajs274a4a42004-12-07 15:39:31 +0000333 zlog_default = openzlog (progname, ZLOG_BGP,
paul718e3742002-12-13 20:15:29 +0000334 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
335
336 /* BGP master init. */
337 bgp_master_init ();
338
339 /* Command line argument treatment. */
340 while (1)
341 {
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400342 opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vC", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000343
344 if (opt == EOF)
345 break;
346
347 switch (opt)
348 {
349 case 0:
350 break;
351 case 'd':
352 daemon_mode = 1;
353 break;
354 case 'f':
355 config_file = optarg;
356 break;
357 case 'i':
358 pid_file = optarg;
359 break;
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400360 case 'z':
361 zclient_serv_path_set (optarg);
362 break;
paul718e3742002-12-13 20:15:29 +0000363 case 'p':
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000364 tmp_port = atoi (optarg);
365 if (tmp_port <= 0 || tmp_port > 0xffff)
366 bm->port = BGP_PORT_DEFAULT;
367 else
368 bm->port = tmp_port;
paul718e3742002-12-13 20:15:29 +0000369 break;
370 case 'A':
371 vty_addr = optarg;
372 break;
373 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000374 /* Deal with atoi() returning 0 on failure, and bgpd not
375 listening on bgp port... */
376 if (strcmp(optarg, "0") == 0)
377 {
378 vty_port = 0;
379 break;
380 }
381 vty_port = atoi (optarg);
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000382 if (vty_port <= 0 || vty_port > 0xffff)
383 vty_port = BGP_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000384 break;
385 case 'r':
386 retain_mode = 1;
387 break;
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000388 case 'l':
389 bm->address = optarg;
390 /* listenon implies -n */
paul718e3742002-12-13 20:15:29 +0000391 case 'n':
392 bgp_option_set (BGP_OPT_NO_FIB);
393 break;
hassoc0652302004-11-25 19:33:48 +0000394 case 'u':
395 bgpd_privs.user = optarg;
396 break;
397 case 'g':
398 bgpd_privs.group = optarg;
399 break;
paul718e3742002-12-13 20:15:29 +0000400 case 'v':
401 print_version (progname);
402 exit (0);
403 break;
Paul Jakma876b8be2006-10-15 23:35:57 +0000404 case 'C':
405 dryrun = 1;
406 break;
paul718e3742002-12-13 20:15:29 +0000407 case 'h':
408 usage (progname, 0);
409 break;
410 default:
411 usage (progname, 1);
412 break;
413 }
414 }
415
416 /* Make thread master. */
417 master = bm->master;
418
419 /* Initializations. */
420 srand (time (NULL));
paul2d75d052004-01-19 21:31:15 +0000421 signal_init (master, Q_SIGC(bgp_signals), bgp_signals);
pauledd7c242003-06-04 13:59:38 +0000422 zprivs_init (&bgpd_privs);
paul718e3742002-12-13 20:15:29 +0000423 cmd_init (1);
paulb21b19c2003-06-15 01:28:29 +0000424 vty_init (master);
paul718e3742002-12-13 20:15:29 +0000425 memory_init ();
426
427 /* BGP related initialization. */
428 bgp_init ();
429
430 /* Sort CLI commands. */
431 sort_node ();
432
433 /* Parse config file. */
hasso320ec102004-06-20 19:54:37 +0000434 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000435
Paul Jakma876b8be2006-10-15 23:35:57 +0000436 /* Start execution only if not in dry-run mode */
437 if(dryrun)
438 return(0);
439
paul718e3742002-12-13 20:15:29 +0000440 /* Turn into daemon if daemon_mode is set. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700441 if (daemon_mode && daemon (0, 0) < 0)
442 {
443 zlog_err("BGPd daemon failed: %s", strerror(errno));
444 return (1);
445 }
446
paul718e3742002-12-13 20:15:29 +0000447
448 /* Process ID file creation. */
449 pid_output (pid_file);
450
451 /* Make bgp vty socket. */
452 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
453
454 /* Print banner. */
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000455 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", QUAGGA_VERSION,
Paul Jakma7e992e92007-11-13 09:32:23 +0000456 vty_port,
Paul Jakmab63e6082007-11-21 21:25:34 +0000457 (bm->address ? bm->address : "<all>"),
Paul Jakma7e992e92007-11-13 09:32:23 +0000458 bm->port);
paul718e3742002-12-13 20:15:29 +0000459
460 /* Start finite state machine, here we go! */
461 while (thread_fetch (master, &thread))
462 thread_call (&thread);
463
464 /* Not reached. */
paule8e19462006-01-19 20:16:55 +0000465 return (0);
paul718e3742002-12-13 20:15:29 +0000466}