]> git.proxmox.com Git - mirror_frr.git/blame - zebra/main.c
*: add frr_init() infrastructure
[mirror_frr.git] / zebra / main.c
CommitLineData
edd7c245 1/* zebra daemon main routine.
718e3744 2 * Copyright (C) 1997, 98 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
5e4fa164 24#include <lib/version.h>
718e3744 25#include "getopt.h"
26#include "command.h"
27#include "thread.h"
28#include "filter.h"
29#include "memory.h"
4a1ab8e4 30#include "zebra_memory.h"
fc7948fa 31#include "memory_vty.h"
718e3744 32#include "prefix.h"
33#include "log.h"
7514fb77 34#include "plist.h"
edd7c245 35#include "privs.h"
2d75d052 36#include "sigevent.h"
b72ede27 37#include "vrf.h"
4f04a76b 38#include "libfrr.h"
718e3744 39
40#include "zebra/rib.h"
41#include "zebra/zserv.h"
42#include "zebra/debug.h"
18a6dce6 43#include "zebra/router-id.h"
ca776988 44#include "zebra/irdp.h"
a1ac18c4 45#include "zebra/rtadv.h"
5adc2528 46#include "zebra/zebra_fpm.h"
244c1cdc 47#include "zebra/zebra_ptm.h"
fe18ee2d 48#include "zebra/zebra_ns.h"
e2b1be64 49#include "zebra/redistribute.h"
7758e3f3 50#include "zebra/zebra_mpls.h"
244c1cdc
DS
51
52#define ZEBRA_PTM_SUPPORT
718e3744 53
b21b19c5 54/* Zebra instance */
55struct zebra_t zebrad =
56{
57 .rtm_table_default = 0,
58};
718e3744 59
60/* process id. */
718e3744 61pid_t pid;
62
55c72803 63/* Pacify zclient.o in libfrr, which expects this variable. */
87efd646 64struct thread_master *master;
65
718e3744 66/* Route retain mode flag. */
67int retain_mode = 0;
68
6baf7bb8
DS
69/* Allow non-quagga entities to delete quagga routes */
70int allow_delete = 0;
71
718e3744 72/* Don't delete kernel route. */
73int keep_kernel_mode = 0;
74
c34b6b57 75#ifdef HAVE_NETLINK
76/* Receive buffer size for netlink socket */
b6286c70 77u_int32_t nl_rcvbufsize = 4194304;
c34b6b57 78#endif /* HAVE_NETLINK */
79
718e3744 80/* Command line options. */
81struct option longopts[] =
82{
6baf7bb8
DS
83 { "batch", no_argument, NULL, 'b'},
84 { "daemon", no_argument, NULL, 'd'},
85 { "allow_delete", no_argument, NULL, 'a'},
86 { "keep_kernel", no_argument, NULL, 'k'},
fb0aa886 87 { "fpm_format", required_argument, NULL, 'F'},
6baf7bb8
DS
88 { "config_file", required_argument, NULL, 'f'},
89 { "pid_file", required_argument, NULL, 'i'},
90 { "socket", required_argument, NULL, 'z'},
37fe7731 91 { "ecmp", required_argument, NULL, 'e'},
6baf7bb8
DS
92 { "retain", no_argument, NULL, 'r'},
93 { "dryrun", no_argument, NULL, 'C'},
c34b6b57 94#ifdef HAVE_NETLINK
6baf7bb8 95 { "nl-bufsize", required_argument, NULL, 's'},
c34b6b57 96#endif /* HAVE_NETLINK */
718e3744 97 { 0 }
98};
99
edd7c245 100zebra_capabilities_t _caps_p [] =
101{
ceacedba 102 ZCAP_NET_ADMIN,
edd7c245 103 ZCAP_SYS_ADMIN,
ceacedba 104 ZCAP_NET_RAW,
edd7c245 105};
106
107/* zebra privileges to run with */
108struct zebra_privs_t zserv_privs =
109{
b2f36157
DL
110#if defined(FRR_USER) && defined(FRR_GROUP)
111 .user = FRR_USER,
112 .group = FRR_GROUP,
edd7c245 113#endif
114#ifdef VTY_GROUP
115 .vty_group = VTY_GROUP,
116#endif
117 .caps_p = _caps_p,
837d16cc 118 .cap_num_p = array_size(_caps_p),
edd7c245 119 .cap_num_i = 0
120};
121
718e3744 122/* Default configuration file path. */
718e3744 123char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
124
125/* Process ID saved for use by init system */
fce954f8 126const char *pid_file = PATH_ZEBRA_PID;
718e3744 127
37fe7731
DS
128unsigned int multipath_num = MULTIPATH_NUM;
129
718e3744 130/* SIGHUP handler. */
a1ac18c4 131static void
2d75d052 132sighup (void)
718e3744 133{
134 zlog_info ("SIGHUP received");
135
136 /* Reload of config file. */
137 ;
138}
139
140/* SIGINT handler. */
a1ac18c4 141static void
2d75d052 142sigint (void)
718e3744 143{
5a8dfcd8
RW
144 struct vrf *vrf;
145 struct zebra_vrf *zvrf;
fe18ee2d
DS
146 struct zebra_ns *zns;
147
887c44a4 148 zlog_notice ("Terminating on signal");
718e3744 149
ca776988 150#ifdef HAVE_IRDP
151 irdp_finish();
152#endif
718e3744 153
c8ed14dd 154 zebra_ptm_finish();
5a8dfcd8
RW
155 list_delete_all_node (zebrad.client_list);
156
157 if (retain_mode)
158 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
159 {
160 zvrf = vrf->info;
161 if (zvrf)
162 SET_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN);
163 }
164 vrf_terminate ();
fe18ee2d
DS
165
166 zns = zebra_ns_lookup (NS_DEFAULT);
167 zebra_ns_disable (0, (void **)&zns);
58ac32e2
RW
168
169 access_list_reset ();
170 prefix_list_reset ();
171 route_map_finish ();
172 cmd_terminate ();
173 vty_terminate ();
174 zprivs_terminate (&zserv_privs);
175 list_delete (zebrad.client_list);
5a8dfcd8
RW
176 work_queue_free (zebrad.ribq);
177 if (zebrad.lsp_process_q)
178 work_queue_free (zebrad.lsp_process_q);
179 meta_queue_free (zebrad.mq);
58ac32e2
RW
180 thread_master_free (zebrad.master);
181 if (zlog_default)
182 closezlog (zlog_default);
183
718e3744 184 exit (0);
185}
186
187/* SIGUSR1 handler. */
a1ac18c4 188static void
2d75d052 189sigusr1 (void)
718e3744 190{
191 zlog_rotate (NULL);
192}
193
2d75d052 194struct quagga_signal_t zebra_signals[] =
718e3744 195{
2d75d052 196 {
197 .signal = SIGHUP,
198 .handler = &sighup,
199 },
200 {
201 .signal = SIGUSR1,
202 .handler = &sigusr1,
203 },
204 {
205 .signal = SIGINT,
8c903fbb 206 .handler = &sigint,
2d75d052 207 },
f571dab0 208 {
209 .signal = SIGTERM,
210 .handler = &sigint,
211 },
2d75d052 212};
b72ede27 213
4f04a76b
DL
214FRR_DAEMON_INFO(zebra, ZEBRA,
215 .vty_port = ZEBRA_VTY_PORT,
216
217 .proghelp = "Daemon which manages kernel routing table management "
218 "and\nredistribution between different routing protocols.",
219
220 .signals = zebra_signals,
221 .n_signals = array_size(zebra_signals),
222
223 .privs = &zserv_privs,
224)
225
718e3744 226/* Main startup routine. */
227int
228main (int argc, char **argv)
229{
876b8be0 230 int dryrun = 0;
718e3744 231 int batch_mode = 0;
232 int daemon_mode = 0;
233 char *config_file = NULL;
718e3744 234 struct thread thread;
b5114685 235 char *zserv_path = NULL;
fb0aa886 236 char *fpm_format = NULL;
718e3744 237
4f04a76b 238 frr_preinit(&zebra_di, argc, argv);
718e3744 239
4f04a76b
DL
240 frr_opt_add("bdakf:F:i:z:rC"
241#ifdef HAVE_NETLINK
242 "s:"
c05795b1 243#endif
4f04a76b
DL
244 , longopts,
245 "-b, --batch Runs in batch mode\n"
246 "-d, --daemon Runs in daemon mode\n"
247 "-a, --allow_delete Allow other processes to delete Quagga Routes\n"
248 "-f, --config_file Set configuration file name\n"
249 "-F, --fpm_format Set fpm format to 'netlink' or 'protobuf'\n"
250 "-i, --pid_file Set process identifier file name\n"
251 "-z, --socket Set path of zebra socket\n"
252 "-k, --keep_kernel Don't delete old routes which installed by zebra.\n"
253 "-C, --dryrun Check configuration for validity and exit\n"
254 "-r, --retain When program terminates, retain added route by zebra.\n"
255#ifdef HAVE_NETLINK
256 "-s, --nl-bufsize Set netlink receive buffer size\n"
257#endif /* HAVE_NETLINK */
258 );
718e3744 259
4f04a76b 260 while (1)
718e3744 261 {
4f04a76b 262 int opt = frr_getopt(argc, argv, NULL);
718e3744 263
264 if (opt == EOF)
265 break;
266
267 switch (opt)
268 {
269 case 0:
270 break;
271 case 'b':
272 batch_mode = 1;
273 case 'd':
274 daemon_mode = 1;
275 break;
6baf7bb8
DS
276 case 'a':
277 allow_delete = 1;
278 break;
718e3744 279 case 'k':
280 keep_kernel_mode = 1;
281 break;
876b8be0
PJ
282 case 'C':
283 dryrun = 1;
284 break;
718e3744 285 case 'f':
286 config_file = optarg;
287 break;
fb0aa886
AS
288 case 'F':
289 fpm_format = optarg;
290 break;
37fe7731
DS
291 case 'e':
292 multipath_num = atoi (optarg);
293 if (multipath_num > MULTIPATH_NUM || multipath_num <= 0)
294 {
295 zlog_err ("Multipath Number specified must be less than %d and greater than 0", MULTIPATH_NUM);
296 return 1;
297 }
298 break;
718e3744 299 case 'i':
300 pid_file = optarg;
301 break;
b5114685
VT
302 case 'z':
303 zserv_path = optarg;
304 break;
718e3744 305 case 'r':
306 retain_mode = 1;
307 break;
c34b6b57 308#ifdef HAVE_NETLINK
309 case 's':
310 nl_rcvbufsize = atoi (optarg);
311 break;
312#endif /* HAVE_NETLINK */
718e3744 313 default:
4f04a76b 314 frr_help_exit (1);
718e3744 315 break;
316 }
317 }
318
4f04a76b 319 zebrad.master = frr_init();
718e3744 320
718e3744 321 cmd_init (1);
3ddccf18 322 vty_config_lockless ();
b21b19c5 323 vty_init (zebrad.master);
718e3744 324 memory_init ();
325
326 /* Zebra related initialize. */
327 zebra_init ();
328 rib_init ();
329 zebra_if_init ();
330 zebra_debug_init ();
c6ffe645 331 router_id_cmd_init ();
718e3744 332 zebra_vty_init ();
333 access_list_init ();
7514fb77 334 prefix_list_init ();
8da4e946 335#if defined (HAVE_RTADV)
cd80d74f 336 rtadv_cmd_init ();
36735ed9 337#endif
ca776988 338#ifdef HAVE_IRDP
339 irdp_init();
340#endif
244c1cdc
DS
341 /* PTM socket */
342#ifdef ZEBRA_PTM_SUPPORT
343 zebra_ptm_init();
344#endif
718e3744 345
7758e3f3 346 zebra_mpls_init ();
fe6c7157 347 zebra_mpls_vty_init ();
7758e3f3 348
718e3744 349 /* For debug purpose. */
350 /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
351
fe18ee2d
DS
352 /* Initialize NS( and implicitly the VRF module), and make kernel routing socket. */
353 zebra_ns_init ();
718e3744 354
718e3744 355#ifdef HAVE_SNMP
356 zebra_snmp_init ();
357#endif /* HAVE_SNMP */
358
5adc2528 359#ifdef HAVE_FPM
fb0aa886 360 zfpm_init (zebrad.master, 1, 0, fpm_format);
5adc2528 361#else
fb0aa886 362 zfpm_init (zebrad.master, 0, 0, fpm_format);
5adc2528
AS
363#endif
364
91b7351d
DO
365 /* Process the configuration file. Among other configuration
366 * directives we can meet those installing static routes. Such
367 * requests will not be executed immediately, but queued in
368 * zebra->ribq structure until we enter the main execution loop.
369 * The notifications from kernel will show originating PID equal
370 * to that after daemon() completes (if ever called).
371 */
320ec10a 372 vty_read_config (config_file, config_default);
718e3744 373
876b8be0
PJ
374 /* Don't start execution if we are in dry-run mode */
375 if (dryrun)
376 return(0);
377
718e3744 378 /* Clean up rib. */
7a4bb9c5 379 /* rib_weed_tables (); */
718e3744 380
381 /* Exit when zebra is working in batch mode. */
382 if (batch_mode)
383 exit (0);
384
718e3744 385 /* Daemonize. */
065de903
SH
386 if (daemon_mode && daemon (0, 0) < 0)
387 {
388 zlog_err("Zebra daemon failed: %s", strerror(errno));
389 exit (1);
390 }
718e3744 391
392 /* Output pid of zebra. */
393 pid_output (pid_file);
394
91b7351d
DO
395 /* After we have successfully acquired the pidfile, we can be sure
396 * about being the only copy of zebra process, which is submitting
397 * changes to the FIB.
398 * Clean up zebra-originated routes. The requests will be sent to OS
399 * immediately, so originating PID in notifications from kernel
400 * will be equal to the current getpid(). To know about such routes,
401 * we have to have route_read() called before.
402 */
403 if (! keep_kernel_mode)
404 rib_sweep_route ();
405
718e3744 406 /* Needed for BSD routing socket. */
407 pid = getpid ();
408
97be79f9 409 /* This must be done only after locking pidfile (bug #403). */
b5114685 410 zebra_zserv_socket_init (zserv_path);
97be79f9 411
4f04a76b 412 frr_vty_serv (ZEBRA_VTYSH_PATH);
718e3744 413
887c44a4 414 /* Print banner. */
4f04a76b 415 zlog_notice ("Zebra %s starting: vty@%d", FRR_VERSION, zebra_di.vty_port);
887c44a4 416
b21b19c5 417 while (thread_fetch (zebrad.master, &thread))
718e3744 418 thread_call (&thread);
419
420 /* Not reached... */
e8e1946e 421 return 0;
718e3744 422}