blob: 591a6f930d68a1498ce9a3891baa8574964e812c [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"
Lou Berger056f3762013-04-10 12:30:04 -070040#include "workqueue.h"
paul718e3742002-12-13 20:15:29 +000041
42#include "bgpd/bgpd.h"
43#include "bgpd/bgp_attr.h"
44#include "bgpd/bgp_mplsvpn.h"
Chris Caputo228da422009-07-18 05:44:03 +000045#include "bgpd/bgp_aspath.h"
46#include "bgpd/bgp_dump.h"
47#include "bgpd/bgp_route.h"
48#include "bgpd/bgp_nexthop.h"
49#include "bgpd/bgp_regex.h"
50#include "bgpd/bgp_clist.h"
51#include "bgpd/bgp_debug.h"
52#include "bgpd/bgp_filter.h"
Josh Bailey8196f132011-07-20 20:47:07 -070053#include "bgpd/bgp_zebra.h"
paul718e3742002-12-13 20:15:29 +000054
55/* bgpd options, we use GNU getopt library. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -070056static const struct option longopts[] =
paul718e3742002-12-13 20:15:29 +000057{
58 { "daemon", no_argument, NULL, 'd'},
59 { "config_file", required_argument, NULL, 'f'},
60 { "pid_file", required_argument, NULL, 'i'},
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +040061 { "socket", required_argument, NULL, 'z'},
paul718e3742002-12-13 20:15:29 +000062 { "bgp_port", required_argument, NULL, 'p'},
Paul Jakma3a02d1f2007-11-01 14:29:11 +000063 { "listenon", required_argument, NULL, 'l'},
paul718e3742002-12-13 20:15:29 +000064 { "vty_addr", required_argument, NULL, 'A'},
65 { "vty_port", required_argument, NULL, 'P'},
66 { "retain", no_argument, NULL, 'r'},
67 { "no_kernel", no_argument, NULL, 'n'},
pauledd7c242003-06-04 13:59:38 +000068 { "user", required_argument, NULL, 'u'},
hassoc0652302004-11-25 19:33:48 +000069 { "group", required_argument, NULL, 'g'},
paul718e3742002-12-13 20:15:29 +000070 { "version", no_argument, NULL, 'v'},
Paul Jakma876b8be2006-10-15 23:35:57 +000071 { "dryrun", no_argument, NULL, 'C'},
paul718e3742002-12-13 20:15:29 +000072 { "help", no_argument, NULL, 'h'},
73 { 0 }
74};
75
paul2d75d052004-01-19 21:31:15 +000076/* signal definitions */
77void sighup (void);
78void sigint (void);
79void sigusr1 (void);
80
Chris Caputo228da422009-07-18 05:44:03 +000081static void bgp_exit (int);
82
Stephen Hemminger372b3c72009-05-15 10:29:41 -070083static struct quagga_signal_t bgp_signals[] =
paul2d75d052004-01-19 21:31:15 +000084{
85 {
86 .signal = SIGHUP,
87 .handler = &sighup,
88 },
89 {
90 .signal = SIGUSR1,
91 .handler = &sigusr1,
92 },
93 {
94 .signal = SIGINT,
95 .handler = &sigint,
96 },
hassof571dab2004-03-22 08:55:25 +000097 {
98 .signal = SIGTERM,
99 .handler = &sigint,
100 },
paul2d75d052004-01-19 21:31:15 +0000101};
102
paul718e3742002-12-13 20:15:29 +0000103/* Configuration file and directory. */
paul718e3742002-12-13 20:15:29 +0000104char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
105
106/* Route retain mode flag. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700107static int retain_mode = 0;
paul718e3742002-12-13 20:15:29 +0000108
paul718e3742002-12-13 20:15:29 +0000109/* 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,
Chris Luke5c88f192011-10-18 17:26:51 +0400124 ZCAP_NET_ADMIN,
pauledd7c242003-06-04 13:59:38 +0000125};
126
127struct zebra_privs_t bgpd_privs =
128{
pauld81fadf2003-08-14 05:32:12 +0000129#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
130 .user = QUAGGA_USER,
131 .group = QUAGGA_GROUP,
132#endif
133#ifdef VTY_GROUP
134 .vty_group = VTY_GROUP,
pauledd7c242003-06-04 13:59:38 +0000135#endif
136 .caps_p = _caps_p,
Balaji.G837d16c2012-09-26 14:09:10 +0530137 .cap_num_p = array_size(_caps_p),
pauledd7c242003-06-04 13:59:38 +0000138 .cap_num_i = 0,
139};
140
paul718e3742002-12-13 20:15:29 +0000141/* Help information display. */
142static void
143usage (char *progname, int status)
144{
145 if (status != 0)
146 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
147 else
148 {
149 printf ("Usage : %s [OPTION...]\n\n\
150Daemon which manages kernel routing table management and \
151redistribution between different routing protocols.\n\n\
152-d, --daemon Runs in daemon mode\n\
153-f, --config_file Set configuration file name\n\
154-i, --pid_file Set process identifier file name\n\
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400155-z, --socket Set path of zebra socket\n\
paul718e3742002-12-13 20:15:29 +0000156-p, --bgp_port Set bgp protocol's port number\n\
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000157-l, --listenon Listen on specified address (implies -n)\n\
paul718e3742002-12-13 20:15:29 +0000158-A, --vty_addr Set vty's bind address\n\
159-P, --vty_port Set vty's port number\n\
160-r, --retain When program terminates, retain added route by bgpd.\n\
161-n, --no_kernel Do not install route to kernel.\n\
hassoc0652302004-11-25 19:33:48 +0000162-u, --user User to run as\n\
163-g, --group Group to run as\n\
paul718e3742002-12-13 20:15:29 +0000164-v, --version Print program version\n\
Paul Jakma876b8be2006-10-15 23:35:57 +0000165-C, --dryrun Check configuration for validity and exit\n\
paul718e3742002-12-13 20:15:29 +0000166-h, --help Display this help and exit\n\
167\n\
168Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
169 }
170
171 exit (status);
172}
David Lamparter6b0655a2014-06-04 06:53:35 +0200173
paul718e3742002-12-13 20:15:29 +0000174/* SIGHUP handler. */
175void
paul2d75d052004-01-19 21:31:15 +0000176sighup (void)
paul718e3742002-12-13 20:15:29 +0000177{
178 zlog (NULL, LOG_INFO, "SIGHUP received");
179
180 /* Terminate all thread. */
181 bgp_terminate ();
182 bgp_reset ();
183 zlog_info ("bgpd restarting!");
184
185 /* Reload config file. */
hasso320ec102004-06-20 19:54:37 +0000186 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000187
188 /* Create VTY's socket */
paul4fc4e7a2003-01-22 19:47:09 +0000189 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
paul718e3742002-12-13 20:15:29 +0000190
191 /* Try to return to normal operation. */
192}
193
194/* SIGINT handler. */
195void
paul2d75d052004-01-19 21:31:15 +0000196sigint (void)
paul718e3742002-12-13 20:15:29 +0000197{
ajs887c44a2004-12-03 16:36:46 +0000198 zlog_notice ("Terminating on signal");
paul718e3742002-12-13 20:15:29 +0000199
Lou Berger056f3762013-04-10 12:30:04 -0700200 if (! retain_mode)
201 {
202 bgp_terminate ();
203 zprivs_terminate (&bgpd_privs);
204 }
paul718e3742002-12-13 20:15:29 +0000205
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);
Lou Berger056f3762013-04-10 12:30:04 -0700240 bm->bgp = NULL;
241
242 /*
243 * bgp_delete can re-allocate the process queues after they were
244 * deleted in bgp_terminate. delete them again.
245 *
246 * It might be better to ensure the RIBs (including static routes)
247 * are cleared by bgp_terminate() during its call to bgp_cleanup_routes(),
248 * which currently only deletes the kernel routes.
249 */
250 if (bm->process_main_queue)
251 {
252 work_queue_free (bm->process_main_queue);
253 bm->process_main_queue = NULL;
254 }
255 if (bm->process_rsclient_queue)
256 {
257 work_queue_free (bm->process_rsclient_queue);
258 bm->process_rsclient_queue = NULL;
259 }
260
Chris Caputo228da422009-07-18 05:44:03 +0000261 /* reverse bgp_master_init */
262 for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
263 {
264 if (close ((int)(long)socket) == -1)
265 zlog_err ("close (%d): %s", (int)(long)socket, safe_strerror (errno));
266 }
267 list_delete (bm->listen_sockets);
268
269 /* reverse bgp_zebra_init/if_init */
270 if (retain_mode)
271 if_add_hook (IF_DELETE_HOOK, NULL);
Feng Lu126215c2015-05-22 11:39:58 +0200272 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
Chris Caputo6c88b442010-07-27 16:28:55 +0000273 {
274 struct listnode *c_node, *c_nnode;
275 struct connected *c;
276
277 for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
278 bgp_connected_delete (c);
Chris Caputo6c88b442010-07-27 16:28:55 +0000279 }
Chris Caputo228da422009-07-18 05:44:03 +0000280
281 /* reverse bgp_attr_init */
282 bgp_attr_finish ();
283
284 /* reverse bgp_dump_init */
285 bgp_dump_finish ();
286
287 /* reverse bgp_route_init */
288 bgp_route_finish ();
289
290 /* reverse bgp_route_map_init/route_map_init */
291 route_map_finish ();
292
293 /* reverse bgp_scan_init */
294 bgp_scan_finish ();
295
296 /* reverse access_list_init */
297 access_list_add_hook (NULL);
298 access_list_delete_hook (NULL);
299 access_list_reset ();
300
301 /* reverse bgp_filter_init */
302 as_list_add_hook (NULL);
303 as_list_delete_hook (NULL);
304 bgp_filter_reset ();
305
306 /* reverse prefix_list_init */
307 prefix_list_add_hook (NULL);
308 prefix_list_delete_hook (NULL);
309 prefix_list_reset ();
310
311 /* reverse community_list_init */
312 community_list_terminate (bgp_clist);
313
Feng Lu126215c2015-05-22 11:39:58 +0200314 vrf_terminate ();
Chris Caputo228da422009-07-18 05:44:03 +0000315 cmd_terminate ();
316 vty_terminate ();
317 if (zclient)
318 zclient_free (zclient);
319 if (zlookup)
320 zclient_free (zlookup);
Josh Bailey8196f132011-07-20 20:47:07 -0700321 if (bgp_nexthop_buf)
322 stream_free (bgp_nexthop_buf);
Chris Caputo228da422009-07-18 05:44:03 +0000323
324 /* reverse bgp_master_init */
Donald Sharp774914f2015-10-14 08:50:39 -0400325 if (bm->master)
326 thread_master_free (bm->master);
Chris Caputo228da422009-07-18 05:44:03 +0000327
328 if (zlog_default)
329 closezlog (zlog_default);
330
331 if (CONF_BGP_DEBUG (normal, NORMAL))
332 log_memstats_stderr ("bgpd");
333
334 exit (status);
335}
David Lamparter6b0655a2014-06-04 06:53:35 +0200336
paul718e3742002-12-13 20:15:29 +0000337/* Main routine of bgpd. Treatment of argument and start bgp finite
338 state machine is handled at here. */
339int
340main (int argc, char **argv)
341{
342 char *p;
343 int opt;
344 int daemon_mode = 0;
Paul Jakma876b8be2006-10-15 23:35:57 +0000345 int dryrun = 0;
paul718e3742002-12-13 20:15:29 +0000346 char *progname;
347 struct thread thread;
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000348 int tmp_port;
paul718e3742002-12-13 20:15:29 +0000349
350 /* Set umask before anything for security */
351 umask (0027);
352
353 /* Preserve name of myself. */
354 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
355
ajs274a4a42004-12-07 15:39:31 +0000356 zlog_default = openzlog (progname, ZLOG_BGP,
paul718e3742002-12-13 20:15:29 +0000357 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
358
359 /* BGP master init. */
360 bgp_master_init ();
361
362 /* Command line argument treatment. */
363 while (1)
364 {
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400365 opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vC", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000366
367 if (opt == EOF)
368 break;
369
370 switch (opt)
371 {
372 case 0:
373 break;
374 case 'd':
375 daemon_mode = 1;
376 break;
377 case 'f':
378 config_file = optarg;
379 break;
380 case 'i':
381 pid_file = optarg;
382 break;
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400383 case 'z':
384 zclient_serv_path_set (optarg);
385 break;
paul718e3742002-12-13 20:15:29 +0000386 case 'p':
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000387 tmp_port = atoi (optarg);
388 if (tmp_port <= 0 || tmp_port > 0xffff)
389 bm->port = BGP_PORT_DEFAULT;
390 else
391 bm->port = tmp_port;
paul718e3742002-12-13 20:15:29 +0000392 break;
393 case 'A':
394 vty_addr = optarg;
395 break;
396 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000397 /* Deal with atoi() returning 0 on failure, and bgpd not
398 listening on bgp port... */
399 if (strcmp(optarg, "0") == 0)
400 {
401 vty_port = 0;
402 break;
403 }
404 vty_port = atoi (optarg);
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000405 if (vty_port <= 0 || vty_port > 0xffff)
406 vty_port = BGP_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000407 break;
408 case 'r':
409 retain_mode = 1;
410 break;
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000411 case 'l':
412 bm->address = optarg;
413 /* listenon implies -n */
paul718e3742002-12-13 20:15:29 +0000414 case 'n':
415 bgp_option_set (BGP_OPT_NO_FIB);
416 break;
hassoc0652302004-11-25 19:33:48 +0000417 case 'u':
418 bgpd_privs.user = optarg;
419 break;
420 case 'g':
421 bgpd_privs.group = optarg;
422 break;
paul718e3742002-12-13 20:15:29 +0000423 case 'v':
424 print_version (progname);
425 exit (0);
426 break;
Paul Jakma876b8be2006-10-15 23:35:57 +0000427 case 'C':
428 dryrun = 1;
429 break;
paul718e3742002-12-13 20:15:29 +0000430 case 'h':
431 usage (progname, 0);
432 break;
433 default:
434 usage (progname, 1);
435 break;
436 }
437 }
438
paul718e3742002-12-13 20:15:29 +0000439 /* Initializations. */
Donald Sharpf31bab42015-06-19 19:26:19 -0400440 srandom (time (NULL));
Donald Sharp774914f2015-10-14 08:50:39 -0400441 signal_init (bm->master, array_size(bgp_signals), bgp_signals);
pauledd7c242003-06-04 13:59:38 +0000442 zprivs_init (&bgpd_privs);
paul718e3742002-12-13 20:15:29 +0000443 cmd_init (1);
Donald Sharp774914f2015-10-14 08:50:39 -0400444 vty_init (bm->master);
paul718e3742002-12-13 20:15:29 +0000445 memory_init ();
Feng Lu126215c2015-05-22 11:39:58 +0200446 vrf_init ();
paul718e3742002-12-13 20:15:29 +0000447
448 /* BGP related initialization. */
449 bgp_init ();
450
paul718e3742002-12-13 20:15:29 +0000451 /* Parse config file. */
hasso320ec102004-06-20 19:54:37 +0000452 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000453
Paul Jakma876b8be2006-10-15 23:35:57 +0000454 /* Start execution only if not in dry-run mode */
455 if(dryrun)
456 return(0);
457
paul718e3742002-12-13 20:15:29 +0000458 /* Turn into daemon if daemon_mode is set. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700459 if (daemon_mode && daemon (0, 0) < 0)
460 {
461 zlog_err("BGPd daemon failed: %s", strerror(errno));
462 return (1);
463 }
464
paul718e3742002-12-13 20:15:29 +0000465
466 /* Process ID file creation. */
467 pid_output (pid_file);
468
469 /* Make bgp vty socket. */
470 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
471
472 /* Print banner. */
Lou Berger056f3762013-04-10 12:30:04 -0700473 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d pid %d", QUAGGA_VERSION,
Paul Jakma7e992e92007-11-13 09:32:23 +0000474 vty_port,
Paul Jakmab63e6082007-11-21 21:25:34 +0000475 (bm->address ? bm->address : "<all>"),
Lou Berger056f3762013-04-10 12:30:04 -0700476 bm->port,
477 getpid ());
paul718e3742002-12-13 20:15:29 +0000478
479 /* Start finite state machine, here we go! */
Donald Sharp774914f2015-10-14 08:50:39 -0400480 while (thread_fetch (bm->master, &thread))
paul718e3742002-12-13 20:15:29 +0000481 thread_call (&thread);
482
483 /* Not reached. */
paule8e19462006-01-19 20:16:55 +0000484 return (0);
paul718e3742002-12-13 20:15:29 +0000485}