blob: 778067a81ca13ca103ebfd9457ea1857c7c46b20 [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 Trushkin271ee732011-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 Luke90d181b2011-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 Trushkin271ee732011-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
Chris Caputo228da422009-07-18 05:44:03 +0000202 bgp_exit (0);
paul718e3742002-12-13 20:15:29 +0000203}
204
205/* SIGUSR1 handler. */
206void
paul2d75d052004-01-19 21:31:15 +0000207sigusr1 (void)
paul718e3742002-12-13 20:15:29 +0000208{
209 zlog_rotate (NULL);
210}
Chris Caputo228da422009-07-18 05:44:03 +0000211
212/*
213 Try to free up allocations we know about so that diagnostic tools such as
214 valgrind are able to better illuminate leaks.
215
216 Zebra route removal and protocol teardown are not meant to be done here.
217 For example, "retain_mode" may be set.
218*/
219static void
220bgp_exit (int status)
221{
222 struct bgp *bgp;
223 struct listnode *node, *nnode;
224 int *socket;
225 struct interface *ifp;
226 extern struct zclient *zclient;
227 extern struct zclient *zlookup;
228
229 /* it only makes sense for this to be called on a clean exit */
230 assert (status == 0);
231
232 /* reverse bgp_master_init */
233 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
234 bgp_delete (bgp);
235 list_free (bm->bgp);
236
237 /* reverse bgp_master_init */
238 for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
239 {
240 if (close ((int)(long)socket) == -1)
241 zlog_err ("close (%d): %s", (int)(long)socket, safe_strerror (errno));
242 }
243 list_delete (bm->listen_sockets);
244
245 /* reverse bgp_zebra_init/if_init */
246 if (retain_mode)
247 if_add_hook (IF_DELETE_HOOK, NULL);
248 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
249 if_delete (ifp);
250 list_free (iflist);
251
252 /* reverse bgp_attr_init */
253 bgp_attr_finish ();
254
255 /* reverse bgp_dump_init */
256 bgp_dump_finish ();
257
258 /* reverse bgp_route_init */
259 bgp_route_finish ();
260
261 /* reverse bgp_route_map_init/route_map_init */
262 route_map_finish ();
263
264 /* reverse bgp_scan_init */
265 bgp_scan_finish ();
266
267 /* reverse access_list_init */
268 access_list_add_hook (NULL);
269 access_list_delete_hook (NULL);
270 access_list_reset ();
271
272 /* reverse bgp_filter_init */
273 as_list_add_hook (NULL);
274 as_list_delete_hook (NULL);
275 bgp_filter_reset ();
276
277 /* reverse prefix_list_init */
278 prefix_list_add_hook (NULL);
279 prefix_list_delete_hook (NULL);
280 prefix_list_reset ();
281
282 /* reverse community_list_init */
283 community_list_terminate (bgp_clist);
284
285 cmd_terminate ();
286 vty_terminate ();
287 if (zclient)
288 zclient_free (zclient);
289 if (zlookup)
290 zclient_free (zlookup);
291
292 /* reverse bgp_master_init */
293 if (master)
294 thread_master_free (master);
295
296 if (zlog_default)
297 closezlog (zlog_default);
298
299 if (CONF_BGP_DEBUG (normal, NORMAL))
300 log_memstats_stderr ("bgpd");
301
302 exit (status);
303}
paul718e3742002-12-13 20:15:29 +0000304
305/* Main routine of bgpd. Treatment of argument and start bgp finite
306 state machine is handled at here. */
307int
308main (int argc, char **argv)
309{
310 char *p;
311 int opt;
312 int daemon_mode = 0;
Paul Jakma876b8be2006-10-15 23:35:57 +0000313 int dryrun = 0;
paul718e3742002-12-13 20:15:29 +0000314 char *progname;
315 struct thread thread;
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000316 int tmp_port;
paul718e3742002-12-13 20:15:29 +0000317
318 /* Set umask before anything for security */
319 umask (0027);
320
321 /* Preserve name of myself. */
322 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
323
ajs274a4a42004-12-07 15:39:31 +0000324 zlog_default = openzlog (progname, ZLOG_BGP,
paul718e3742002-12-13 20:15:29 +0000325 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
326
327 /* BGP master init. */
328 bgp_master_init ();
329
330 /* Command line argument treatment. */
331 while (1)
332 {
Vyacheslav Trushkin271ee732011-11-25 18:51:48 +0400333 opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vC", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000334
335 if (opt == EOF)
336 break;
337
338 switch (opt)
339 {
340 case 0:
341 break;
342 case 'd':
343 daemon_mode = 1;
344 break;
345 case 'f':
346 config_file = optarg;
347 break;
348 case 'i':
349 pid_file = optarg;
350 break;
Vyacheslav Trushkin271ee732011-11-25 18:51:48 +0400351 case 'z':
352 zclient_serv_path_set (optarg);
353 break;
paul718e3742002-12-13 20:15:29 +0000354 case 'p':
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000355 tmp_port = atoi (optarg);
356 if (tmp_port <= 0 || tmp_port > 0xffff)
357 bm->port = BGP_PORT_DEFAULT;
358 else
359 bm->port = tmp_port;
paul718e3742002-12-13 20:15:29 +0000360 break;
361 case 'A':
362 vty_addr = optarg;
363 break;
364 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000365 /* Deal with atoi() returning 0 on failure, and bgpd not
366 listening on bgp port... */
367 if (strcmp(optarg, "0") == 0)
368 {
369 vty_port = 0;
370 break;
371 }
372 vty_port = atoi (optarg);
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000373 if (vty_port <= 0 || vty_port > 0xffff)
374 vty_port = BGP_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000375 break;
376 case 'r':
377 retain_mode = 1;
378 break;
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000379 case 'l':
380 bm->address = optarg;
381 /* listenon implies -n */
paul718e3742002-12-13 20:15:29 +0000382 case 'n':
383 bgp_option_set (BGP_OPT_NO_FIB);
384 break;
hassoc0652302004-11-25 19:33:48 +0000385 case 'u':
386 bgpd_privs.user = optarg;
387 break;
388 case 'g':
389 bgpd_privs.group = optarg;
390 break;
paul718e3742002-12-13 20:15:29 +0000391 case 'v':
392 print_version (progname);
393 exit (0);
394 break;
Paul Jakma876b8be2006-10-15 23:35:57 +0000395 case 'C':
396 dryrun = 1;
397 break;
paul718e3742002-12-13 20:15:29 +0000398 case 'h':
399 usage (progname, 0);
400 break;
401 default:
402 usage (progname, 1);
403 break;
404 }
405 }
406
407 /* Make thread master. */
408 master = bm->master;
409
410 /* Initializations. */
411 srand (time (NULL));
paul2d75d052004-01-19 21:31:15 +0000412 signal_init (master, Q_SIGC(bgp_signals), bgp_signals);
pauledd7c242003-06-04 13:59:38 +0000413 zprivs_init (&bgpd_privs);
paul718e3742002-12-13 20:15:29 +0000414 cmd_init (1);
paulb21b19c2003-06-15 01:28:29 +0000415 vty_init (master);
paul718e3742002-12-13 20:15:29 +0000416 memory_init ();
417
418 /* BGP related initialization. */
419 bgp_init ();
420
421 /* Sort CLI commands. */
422 sort_node ();
423
424 /* Parse config file. */
hasso320ec102004-06-20 19:54:37 +0000425 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000426
Paul Jakma876b8be2006-10-15 23:35:57 +0000427 /* Start execution only if not in dry-run mode */
428 if(dryrun)
429 return(0);
430
paul718e3742002-12-13 20:15:29 +0000431 /* Turn into daemon if daemon_mode is set. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700432 if (daemon_mode && daemon (0, 0) < 0)
433 {
434 zlog_err("BGPd daemon failed: %s", strerror(errno));
435 return (1);
436 }
437
paul718e3742002-12-13 20:15:29 +0000438
439 /* Process ID file creation. */
440 pid_output (pid_file);
441
442 /* Make bgp vty socket. */
443 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
444
445 /* Print banner. */
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000446 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", QUAGGA_VERSION,
Paul Jakma7e992e92007-11-13 09:32:23 +0000447 vty_port,
Paul Jakmab63e6082007-11-21 21:25:34 +0000448 (bm->address ? bm->address : "<all>"),
Paul Jakma7e992e92007-11-13 09:32:23 +0000449 bm->port);
paul718e3742002-12-13 20:15:29 +0000450
451 /* Start finite state machine, here we go! */
452 while (thread_fetch (master, &thread))
453 thread_call (&thread);
454
455 /* Not reached. */
paule8e19462006-01-19 20:16:55 +0000456 return (0);
paul718e3742002-12-13 20:15:29 +0000457}