]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_main.c
If the .conf file for a process is missing have /etc/init.d/quagga touch it so we...
[mirror_frr.git] / bgpd / bgp_main.c
CommitLineData
718e3744 1/* 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"
5e4fa164 28#include <lib/version.h>
718e3744 29#include "memory.h"
30#include "prefix.h"
31#include "log.h"
edd7c245 32#include "privs.h"
2d75d052 33#include "sigevent.h"
228da428
CC
34#include "zclient.h"
35#include "routemap.h"
36#include "filter.h"
37#include "plist.h"
8196f13d 38#include "stream.h"
718e3744 39
40#include "bgpd/bgpd.h"
41#include "bgpd/bgp_attr.h"
42#include "bgpd/bgp_mplsvpn.h"
228da428
CC
43#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"
8196f13d 51#include "bgpd/bgp_zebra.h"
718e3744 52
53/* bgpd options, we use GNU getopt library. */
372b3c70 54static const struct option longopts[] =
718e3744 55{
56 { "daemon", no_argument, NULL, 'd'},
57 { "config_file", required_argument, NULL, 'f'},
58 { "pid_file", required_argument, NULL, 'i'},
b5114685 59 { "socket", required_argument, NULL, 'z'},
718e3744 60 { "bgp_port", required_argument, NULL, 'p'},
3a02d1f7 61 { "listenon", required_argument, NULL, 'l'},
718e3744 62 { "vty_addr", required_argument, NULL, 'A'},
63 { "vty_port", required_argument, NULL, 'P'},
64 { "retain", no_argument, NULL, 'r'},
65 { "no_kernel", no_argument, NULL, 'n'},
edd7c245 66 { "user", required_argument, NULL, 'u'},
c065230a 67 { "group", required_argument, NULL, 'g'},
718e3744 68 { "version", no_argument, NULL, 'v'},
876b8be0 69 { "dryrun", no_argument, NULL, 'C'},
718e3744 70 { "help", no_argument, NULL, 'h'},
71 { 0 }
72};
73
2d75d052 74/* signal definitions */
75void sighup (void);
76void sigint (void);
77void sigusr1 (void);
78
228da428
CC
79static void bgp_exit (int);
80
372b3c70 81static struct quagga_signal_t bgp_signals[] =
2d75d052 82{
83 {
84 .signal = SIGHUP,
85 .handler = &sighup,
86 },
87 {
88 .signal = SIGUSR1,
89 .handler = &sigusr1,
90 },
91 {
92 .signal = SIGINT,
93 .handler = &sigint,
f571dab0 94 },
95 {
96 .signal = SIGTERM,
97 .handler = &sigint,
2d75d052 98 },
99};
100
718e3744 101/* Configuration file and directory. */
718e3744 102char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
103
104/* Route retain mode flag. */
372b3c70 105static int retain_mode = 0;
718e3744 106
107/* Master of threads. */
108struct thread_master *master;
109
110/* Manually specified configuration file name. */
111char *config_file = NULL;
112
113/* Process ID saved for use by init system */
372b3c70 114static const char *pid_file = PATH_BGPD_PID;
718e3744 115
116/* VTY port number and address. */
117int vty_port = BGP_VTY_PORT;
118char *vty_addr = NULL;
119
edd7c245 120/* privileges */
372b3c70 121static zebra_capabilities_t _caps_p [] =
edd7c245 122{
98f5163c 123 ZCAP_BIND,
ceacedba 124 ZCAP_NET_RAW,
5c88f19d 125 ZCAP_NET_ADMIN,
edd7c245 126};
127
128struct zebra_privs_t bgpd_privs =
129{
d81fadfd 130#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
131 .user = QUAGGA_USER,
132 .group = QUAGGA_GROUP,
133#endif
134#ifdef VTY_GROUP
135 .vty_group = VTY_GROUP,
edd7c245 136#endif
137 .caps_p = _caps_p,
837d16cc 138 .cap_num_p = array_size(_caps_p),
edd7c245 139 .cap_num_i = 0,
140};
141
718e3744 142/* Help information display. */
143static void
144usage (char *progname, int status)
145{
146 if (status != 0)
147 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
148 else
149 {
150 printf ("Usage : %s [OPTION...]\n\n\
151Daemon which manages kernel routing table management and \
152redistribution between different routing protocols.\n\n\
153-d, --daemon Runs in daemon mode\n\
154-f, --config_file Set configuration file name\n\
155-i, --pid_file Set process identifier file name\n\
b5114685 156-z, --socket Set path of zebra socket\n\
718e3744 157-p, --bgp_port Set bgp protocol's port number\n\
3a02d1f7 158-l, --listenon Listen on specified address (implies -n)\n\
718e3744 159-A, --vty_addr Set vty's bind address\n\
160-P, --vty_port Set vty's port number\n\
161-r, --retain When program terminates, retain added route by bgpd.\n\
162-n, --no_kernel Do not install route to kernel.\n\
c065230a 163-u, --user User to run as\n\
164-g, --group Group to run as\n\
718e3744 165-v, --version Print program version\n\
876b8be0 166-C, --dryrun Check configuration for validity and exit\n\
718e3744 167-h, --help Display this help and exit\n\
168\n\
169Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
170 }
171
172 exit (status);
173}
6b0655a2 174
718e3744 175/* SIGHUP handler. */
176void
2d75d052 177sighup (void)
718e3744 178{
16286195 179 zlog_info ("SIGHUP received");
718e3744 180
181 /* Terminate all thread. */
182 bgp_terminate ();
183 bgp_reset ();
184 zlog_info ("bgpd restarting!");
185
186 /* Reload config file. */
320ec10a 187 vty_read_config (config_file, config_default);
718e3744 188
189 /* Create VTY's socket */
4fc4e7ab 190 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
718e3744 191
192 /* Try to return to normal operation. */
193}
194
195/* SIGINT handler. */
196void
2d75d052 197sigint (void)
718e3744 198{
887c44a4 199 zlog_notice ("Terminating on signal");
718e3744 200
201 if (! retain_mode)
202 bgp_terminate ();
203
04d5e24d 204 zprivs_terminate (&bgpd_privs);
228da428 205 bgp_exit (0);
718e3744 206}
207
208/* SIGUSR1 handler. */
209void
2d75d052 210sigusr1 (void)
718e3744 211{
212 zlog_rotate (NULL);
213}
228da428
CC
214
215/*
216 Try to free up allocations we know about so that diagnostic tools such as
217 valgrind are able to better illuminate leaks.
218
219 Zebra route removal and protocol teardown are not meant to be done here.
220 For example, "retain_mode" may be set.
221*/
222static void
223bgp_exit (int status)
224{
225 struct bgp *bgp;
226 struct listnode *node, *nnode;
227 int *socket;
228 struct interface *ifp;
229 extern struct zclient *zclient;
228da428
CC
230
231 /* it only makes sense for this to be called on a clean exit */
232 assert (status == 0);
233
1ff9a340
DS
234 bgp_close();
235
228da428
CC
236 /* reverse bgp_master_init */
237 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
238 bgp_delete (bgp);
239 list_free (bm->bgp);
240
228da428
CC
241 /* reverse bgp_zebra_init/if_init */
242 if (retain_mode)
243 if_add_hook (IF_DELETE_HOOK, NULL);
244 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
6c88b44d
CC
245 {
246 struct listnode *c_node, *c_nnode;
247 struct connected *c;
248
249 for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
250 bgp_connected_delete (c);
251
252 if_delete (ifp);
253 }
228da428
CC
254 list_free (iflist);
255
256 /* reverse bgp_attr_init */
257 bgp_attr_finish ();
258
259 /* reverse bgp_dump_init */
260 bgp_dump_finish ();
261
262 /* reverse bgp_route_init */
263 bgp_route_finish ();
264
518f0eb1
DS
265 /* cleanup route maps */
266 bgp_route_map_terminate();
228da428 267
228da428
CC
268 /* reverse access_list_init */
269 access_list_add_hook (NULL);
270 access_list_delete_hook (NULL);
271 access_list_reset ();
272
273 /* reverse bgp_filter_init */
274 as_list_add_hook (NULL);
275 as_list_delete_hook (NULL);
276 bgp_filter_reset ();
277
278 /* reverse prefix_list_init */
279 prefix_list_add_hook (NULL);
280 prefix_list_delete_hook (NULL);
281 prefix_list_reset ();
282
283 /* reverse community_list_init */
284 community_list_terminate (bgp_clist);
285
286 cmd_terminate ();
287 vty_terminate ();
288 if (zclient)
289 zclient_free (zclient);
8196f13d
JB
290 if (bgp_nexthop_buf)
291 stream_free (bgp_nexthop_buf);
431aa9f9
DS
292 if (bgp_ifindices_buf)
293 stream_free (bgp_ifindices_buf);
228da428 294
fc9a856f
DS
295 /* reverse bgp_scan_init */
296 bgp_scan_finish ();
297
228da428
CC
298 /* reverse bgp_master_init */
299 if (master)
300 thread_master_free (master);
301
302 if (zlog_default)
303 closezlog (zlog_default);
304
228da428
CC
305 exit (status);
306}
6b0655a2 307
718e3744 308/* Main routine of bgpd. Treatment of argument and start bgp finite
309 state machine is handled at here. */
310int
311main (int argc, char **argv)
312{
313 char *p;
314 int opt;
315 int daemon_mode = 0;
876b8be0 316 int dryrun = 0;
718e3744 317 char *progname;
318 struct thread thread;
0d6b2ee2 319 int tmp_port;
718e3744 320
321 /* Set umask before anything for security */
322 umask (0027);
323
324 /* Preserve name of myself. */
325 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
326
7c8ff89e 327 zlog_default = openzlog (progname, ZLOG_BGP, 0,
718e3744 328 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
329
330 /* BGP master init. */
331 bgp_master_init ();
332
333 /* Command line argument treatment. */
334 while (1)
335 {
b5114685 336 opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vC", longopts, 0);
718e3744 337
338 if (opt == EOF)
339 break;
340
341 switch (opt)
342 {
343 case 0:
344 break;
345 case 'd':
346 daemon_mode = 1;
347 break;
348 case 'f':
349 config_file = optarg;
350 break;
351 case 'i':
352 pid_file = optarg;
353 break;
b5114685
VT
354 case 'z':
355 zclient_serv_path_set (optarg);
356 break;
718e3744 357 case 'p':
0d6b2ee2
PJ
358 tmp_port = atoi (optarg);
359 if (tmp_port <= 0 || tmp_port > 0xffff)
360 bm->port = BGP_PORT_DEFAULT;
361 else
362 bm->port = tmp_port;
718e3744 363 break;
364 case 'A':
365 vty_addr = optarg;
366 break;
367 case 'P':
4fc4e7ab 368 /* Deal with atoi() returning 0 on failure, and bgpd not
369 listening on bgp port... */
370 if (strcmp(optarg, "0") == 0)
371 {
372 vty_port = 0;
373 break;
374 }
375 vty_port = atoi (optarg);
0d6b2ee2
PJ
376 if (vty_port <= 0 || vty_port > 0xffff)
377 vty_port = BGP_VTY_PORT;
718e3744 378 break;
379 case 'r':
380 retain_mode = 1;
381 break;
3a02d1f7
PJ
382 case 'l':
383 bm->address = optarg;
384 /* listenon implies -n */
718e3744 385 case 'n':
386 bgp_option_set (BGP_OPT_NO_FIB);
387 break;
c065230a 388 case 'u':
389 bgpd_privs.user = optarg;
390 break;
391 case 'g':
392 bgpd_privs.group = optarg;
393 break;
718e3744 394 case 'v':
395 print_version (progname);
396 exit (0);
397 break;
876b8be0
PJ
398 case 'C':
399 dryrun = 1;
400 break;
718e3744 401 case 'h':
402 usage (progname, 0);
403 break;
404 default:
405 usage (progname, 1);
406 break;
407 }
408 }
409
410 /* Make thread master. */
411 master = bm->master;
412
413 /* Initializations. */
414 srand (time (NULL));
837d16cc 415 signal_init (master, array_size(bgp_signals), bgp_signals);
edd7c245 416 zprivs_init (&bgpd_privs);
718e3744 417 cmd_init (1);
b21b19c5 418 vty_init (master);
718e3744 419 memory_init ();
420
421 /* BGP related initialization. */
422 bgp_init ();
423
718e3744 424 /* Parse config file. */
320ec10a 425 vty_read_config (config_file, config_default);
718e3744 426
876b8be0
PJ
427 /* Start execution only if not in dry-run mode */
428 if(dryrun)
429 return(0);
430
718e3744 431 /* Turn into daemon if daemon_mode is set. */
372b3c70
SH
432 if (daemon_mode && daemon (0, 0) < 0)
433 {
434 zlog_err("BGPd daemon failed: %s", strerror(errno));
435 return (1);
436 }
437
718e3744 438
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. */
3a02d1f7 446 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", QUAGGA_VERSION,
7e992e95 447 vty_port,
b63e6089 448 (bm->address ? bm->address : "<all>"),
7e992e95 449 bm->port);
718e3744 450
451 /* Start finite state machine, here we go! */
452 while (thread_fetch (master, &thread))
453 thread_call (&thread);
454
455 /* Not reached. */
e8e1946e 456 return (0);
718e3744 457}