blob: e5fa79d60e9cafe9a7c2820869a14bc23ab55c2d [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"
paul718e3742002-12-13 20:15:29 +000039
40#include "bgpd/bgpd.h"
41#include "bgpd/bgp_attr.h"
42#include "bgpd/bgp_mplsvpn.h"
Chris Caputo228da422009-07-18 05:44:03 +000043#include "bgpd/bgp_aspath.h"
44#include "bgpd/bgp_dump.h"
45#include "bgpd/bgp_route.h"
46#include "bgpd/bgp_nexthop.h"
47#include "bgpd/bgp_regex.h"
48#include "bgpd/bgp_clist.h"
49#include "bgpd/bgp_debug.h"
50#include "bgpd/bgp_filter.h"
Josh Bailey8196f132011-07-20 20:47:07 -070051#include "bgpd/bgp_zebra.h"
paul718e3742002-12-13 20:15:29 +000052
53/* bgpd options, we use GNU getopt library. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -070054static const struct option longopts[] =
paul718e3742002-12-13 20:15:29 +000055{
56 { "daemon", no_argument, NULL, 'd'},
57 { "config_file", required_argument, NULL, 'f'},
58 { "pid_file", required_argument, NULL, 'i'},
59 { "bgp_port", required_argument, NULL, 'p'},
Paul Jakma3a02d1f2007-11-01 14:29:11 +000060 { "listenon", required_argument, NULL, 'l'},
paul718e3742002-12-13 20:15:29 +000061 { "vty_addr", required_argument, NULL, 'A'},
62 { "vty_port", required_argument, NULL, 'P'},
63 { "retain", no_argument, NULL, 'r'},
64 { "no_kernel", no_argument, NULL, 'n'},
pauledd7c242003-06-04 13:59:38 +000065 { "user", required_argument, NULL, 'u'},
hassoc0652302004-11-25 19:33:48 +000066 { "group", required_argument, NULL, 'g'},
paul718e3742002-12-13 20:15:29 +000067 { "version", no_argument, NULL, 'v'},
Paul Jakma876b8be2006-10-15 23:35:57 +000068 { "dryrun", no_argument, NULL, 'C'},
paul718e3742002-12-13 20:15:29 +000069 { "help", no_argument, NULL, 'h'},
70 { 0 }
71};
72
paul2d75d052004-01-19 21:31:15 +000073/* signal definitions */
74void sighup (void);
75void sigint (void);
76void sigusr1 (void);
77
Chris Caputo228da422009-07-18 05:44:03 +000078static void bgp_exit (int);
79
Stephen Hemminger372b3c72009-05-15 10:29:41 -070080static struct quagga_signal_t bgp_signals[] =
paul2d75d052004-01-19 21:31:15 +000081{
82 {
83 .signal = SIGHUP,
84 .handler = &sighup,
85 },
86 {
87 .signal = SIGUSR1,
88 .handler = &sigusr1,
89 },
90 {
91 .signal = SIGINT,
92 .handler = &sigint,
93 },
hassof571dab2004-03-22 08:55:25 +000094 {
95 .signal = SIGTERM,
96 .handler = &sigint,
97 },
paul2d75d052004-01-19 21:31:15 +000098};
99
paul718e3742002-12-13 20:15:29 +0000100/* Configuration file and directory. */
paul718e3742002-12-13 20:15:29 +0000101char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
102
103/* Route retain mode flag. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700104static int retain_mode = 0;
paul718e3742002-12-13 20:15:29 +0000105
106/* Master of threads. */
107struct thread_master *master;
108
109/* Manually specified configuration file name. */
110char *config_file = NULL;
111
112/* Process ID saved for use by init system */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700113static const char *pid_file = PATH_BGPD_PID;
paul718e3742002-12-13 20:15:29 +0000114
115/* VTY port number and address. */
116int vty_port = BGP_VTY_PORT;
117char *vty_addr = NULL;
118
pauledd7c242003-06-04 13:59:38 +0000119/* privileges */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700120static zebra_capabilities_t _caps_p [] =
pauledd7c242003-06-04 13:59:38 +0000121{
paul98f51632004-10-25 14:19:15 +0000122 ZCAP_BIND,
paulceacedb2005-09-29 14:39:32 +0000123 ZCAP_NET_RAW,
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\
154-p, --bgp_port Set bgp protocol's port number\n\
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000155-l, --listenon Listen on specified address (implies -n)\n\
paul718e3742002-12-13 20:15:29 +0000156-A, --vty_addr Set vty's bind address\n\
157-P, --vty_port Set vty's port number\n\
158-r, --retain When program terminates, retain added route by bgpd.\n\
159-n, --no_kernel Do not install route to kernel.\n\
hassoc0652302004-11-25 19:33:48 +0000160-u, --user User to run as\n\
161-g, --group Group to run as\n\
paul718e3742002-12-13 20:15:29 +0000162-v, --version Print program version\n\
Paul Jakma876b8be2006-10-15 23:35:57 +0000163-C, --dryrun Check configuration for validity and exit\n\
paul718e3742002-12-13 20:15:29 +0000164-h, --help Display this help and exit\n\
165\n\
166Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
167 }
168
169 exit (status);
170}
171
172/* SIGHUP handler. */
173void
paul2d75d052004-01-19 21:31:15 +0000174sighup (void)
paul718e3742002-12-13 20:15:29 +0000175{
176 zlog (NULL, LOG_INFO, "SIGHUP received");
177
178 /* Terminate all thread. */
179 bgp_terminate ();
180 bgp_reset ();
181 zlog_info ("bgpd restarting!");
182
183 /* Reload config file. */
hasso320ec102004-06-20 19:54:37 +0000184 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000185
186 /* Create VTY's socket */
paul4fc4e7a2003-01-22 19:47:09 +0000187 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
paul718e3742002-12-13 20:15:29 +0000188
189 /* Try to return to normal operation. */
190}
191
192/* SIGINT handler. */
193void
paul2d75d052004-01-19 21:31:15 +0000194sigint (void)
paul718e3742002-12-13 20:15:29 +0000195{
ajs887c44a2004-12-03 16:36:46 +0000196 zlog_notice ("Terminating on signal");
paul718e3742002-12-13 20:15:29 +0000197
198 if (! retain_mode)
199 bgp_terminate ();
200
Chris Caputo228da422009-07-18 05:44:03 +0000201 bgp_exit (0);
paul718e3742002-12-13 20:15:29 +0000202}
203
204/* SIGUSR1 handler. */
205void
paul2d75d052004-01-19 21:31:15 +0000206sigusr1 (void)
paul718e3742002-12-13 20:15:29 +0000207{
208 zlog_rotate (NULL);
209}
Chris Caputo228da422009-07-18 05:44:03 +0000210
211/*
212 Try to free up allocations we know about so that diagnostic tools such as
213 valgrind are able to better illuminate leaks.
214
215 Zebra route removal and protocol teardown are not meant to be done here.
216 For example, "retain_mode" may be set.
217*/
218static void
219bgp_exit (int status)
220{
221 struct bgp *bgp;
222 struct listnode *node, *nnode;
223 int *socket;
224 struct interface *ifp;
225 extern struct zclient *zclient;
226 extern struct zclient *zlookup;
227
228 /* it only makes sense for this to be called on a clean exit */
229 assert (status == 0);
230
231 /* reverse bgp_master_init */
232 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
233 bgp_delete (bgp);
234 list_free (bm->bgp);
235
236 /* reverse bgp_master_init */
237 for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
238 {
239 if (close ((int)(long)socket) == -1)
240 zlog_err ("close (%d): %s", (int)(long)socket, safe_strerror (errno));
241 }
242 list_delete (bm->listen_sockets);
243
244 /* reverse bgp_zebra_init/if_init */
245 if (retain_mode)
246 if_add_hook (IF_DELETE_HOOK, NULL);
247 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
Chris Caputo6c88b442010-07-27 16:28:55 +0000248 {
249 struct listnode *c_node, *c_nnode;
250 struct connected *c;
251
252 for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
253 bgp_connected_delete (c);
254
255 if_delete (ifp);
256 }
Chris Caputo228da422009-07-18 05:44:03 +0000257 list_free (iflist);
258
259 /* reverse bgp_attr_init */
260 bgp_attr_finish ();
261
262 /* reverse bgp_dump_init */
263 bgp_dump_finish ();
264
265 /* reverse bgp_route_init */
266 bgp_route_finish ();
267
268 /* reverse bgp_route_map_init/route_map_init */
269 route_map_finish ();
270
271 /* reverse bgp_scan_init */
272 bgp_scan_finish ();
273
274 /* reverse access_list_init */
275 access_list_add_hook (NULL);
276 access_list_delete_hook (NULL);
277 access_list_reset ();
278
279 /* reverse bgp_filter_init */
280 as_list_add_hook (NULL);
281 as_list_delete_hook (NULL);
282 bgp_filter_reset ();
283
284 /* reverse prefix_list_init */
285 prefix_list_add_hook (NULL);
286 prefix_list_delete_hook (NULL);
287 prefix_list_reset ();
288
289 /* reverse community_list_init */
290 community_list_terminate (bgp_clist);
291
292 cmd_terminate ();
293 vty_terminate ();
294 if (zclient)
295 zclient_free (zclient);
296 if (zlookup)
297 zclient_free (zlookup);
Josh Bailey8196f132011-07-20 20:47:07 -0700298 if (bgp_nexthop_buf)
299 stream_free (bgp_nexthop_buf);
Chris Caputo228da422009-07-18 05:44:03 +0000300
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 {
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000342 opt = getopt_long (argc, argv, "df:i: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;
360 case 'p':
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000361 tmp_port = atoi (optarg);
362 if (tmp_port <= 0 || tmp_port > 0xffff)
363 bm->port = BGP_PORT_DEFAULT;
364 else
365 bm->port = tmp_port;
paul718e3742002-12-13 20:15:29 +0000366 break;
367 case 'A':
368 vty_addr = optarg;
369 break;
370 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000371 /* Deal with atoi() returning 0 on failure, and bgpd not
372 listening on bgp port... */
373 if (strcmp(optarg, "0") == 0)
374 {
375 vty_port = 0;
376 break;
377 }
378 vty_port = atoi (optarg);
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000379 if (vty_port <= 0 || vty_port > 0xffff)
380 vty_port = BGP_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000381 break;
382 case 'r':
383 retain_mode = 1;
384 break;
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000385 case 'l':
386 bm->address = optarg;
387 /* listenon implies -n */
paul718e3742002-12-13 20:15:29 +0000388 case 'n':
389 bgp_option_set (BGP_OPT_NO_FIB);
390 break;
hassoc0652302004-11-25 19:33:48 +0000391 case 'u':
392 bgpd_privs.user = optarg;
393 break;
394 case 'g':
395 bgpd_privs.group = optarg;
396 break;
paul718e3742002-12-13 20:15:29 +0000397 case 'v':
398 print_version (progname);
399 exit (0);
400 break;
Paul Jakma876b8be2006-10-15 23:35:57 +0000401 case 'C':
402 dryrun = 1;
403 break;
paul718e3742002-12-13 20:15:29 +0000404 case 'h':
405 usage (progname, 0);
406 break;
407 default:
408 usage (progname, 1);
409 break;
410 }
411 }
412
413 /* Make thread master. */
414 master = bm->master;
415
416 /* Initializations. */
417 srand (time (NULL));
paul2d75d052004-01-19 21:31:15 +0000418 signal_init (master, Q_SIGC(bgp_signals), bgp_signals);
pauledd7c242003-06-04 13:59:38 +0000419 zprivs_init (&bgpd_privs);
paul718e3742002-12-13 20:15:29 +0000420 cmd_init (1);
paulb21b19c2003-06-15 01:28:29 +0000421 vty_init (master);
paul718e3742002-12-13 20:15:29 +0000422 memory_init ();
423
424 /* BGP related initialization. */
425 bgp_init ();
426
427 /* Sort CLI commands. */
428 sort_node ();
429
430 /* Parse config file. */
hasso320ec102004-06-20 19:54:37 +0000431 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000432
Paul Jakma876b8be2006-10-15 23:35:57 +0000433 /* Start execution only if not in dry-run mode */
434 if(dryrun)
435 return(0);
436
paul718e3742002-12-13 20:15:29 +0000437 /* Turn into daemon if daemon_mode is set. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700438 if (daemon_mode && daemon (0, 0) < 0)
439 {
440 zlog_err("BGPd daemon failed: %s", strerror(errno));
441 return (1);
442 }
443
paul718e3742002-12-13 20:15:29 +0000444
445 /* Process ID file creation. */
446 pid_output (pid_file);
447
448 /* Make bgp vty socket. */
449 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
450
451 /* Print banner. */
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000452 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", QUAGGA_VERSION,
Paul Jakma7e992e92007-11-13 09:32:23 +0000453 vty_port,
Paul Jakmab63e6082007-11-21 21:25:34 +0000454 (bm->address ? bm->address : "<all>"),
Paul Jakma7e992e92007-11-13 09:32:23 +0000455 bm->port);
paul718e3742002-12-13 20:15:29 +0000456
457 /* Start finite state machine, here we go! */
458 while (thread_fetch (master, &thread))
459 thread_call (&thread);
460
461 /* Not reached. */
paule8e19462006-01-19 20:16:55 +0000462 return (0);
paul718e3742002-12-13 20:15:29 +0000463}