blob: 3384d7dd8830e39dfea0b03797b29efe7436600d [file] [log] [blame]
pauledd7c242003-06-04 13:59:38 +00001/* zebra daemon main routine.
paul718e3742002-12-13 20:15:29 +00002 * 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
gdt5e4fa162004-03-16 14:38:36 +000024#include <lib/version.h>
paul718e3742002-12-13 20:15:29 +000025#include "getopt.h"
26#include "command.h"
27#include "thread.h"
28#include "filter.h"
29#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"
paul718e3742002-12-13 20:15:29 +000034
35#include "zebra/rib.h"
36#include "zebra/zserv.h"
37#include "zebra/debug.h"
38#include "zebra/rib.h"
hassoca776982004-06-12 14:33:05 +000039#include "zebra/irdp.h"
paul718e3742002-12-13 20:15:29 +000040
paulb21b19c2003-06-15 01:28:29 +000041/* Zebra instance */
42struct zebra_t zebrad =
43{
44 .rtm_table_default = 0,
45};
paul718e3742002-12-13 20:15:29 +000046
47/* process id. */
48pid_t old_pid;
49pid_t pid;
50
51/* Route retain mode flag. */
52int retain_mode = 0;
53
54/* Don't delete kernel route. */
55int keep_kernel_mode = 0;
56
57/* Command line options. */
58struct option longopts[] =
59{
60 { "batch", no_argument, NULL, 'b'},
61 { "daemon", no_argument, NULL, 'd'},
62 { "keep_kernel", no_argument, NULL, 'k'},
63 { "log_mode", no_argument, NULL, 'l'},
64 { "config_file", required_argument, NULL, 'f'},
65 { "pid_file", required_argument, NULL, 'i'},
66 { "help", no_argument, NULL, 'h'},
67 { "vty_addr", required_argument, NULL, 'A'},
68 { "vty_port", required_argument, NULL, 'P'},
69 { "retain", no_argument, NULL, 'r'},
pauledd7c242003-06-04 13:59:38 +000070 { "user", required_argument, NULL, 'u'},
paul718e3742002-12-13 20:15:29 +000071 { "version", no_argument, NULL, 'v'},
72 { 0 }
73};
74
pauledd7c242003-06-04 13:59:38 +000075zebra_capabilities_t _caps_p [] =
76{
77 ZCAP_ADMIN,
78 ZCAP_SYS_ADMIN,
hasso41908812003-06-05 11:33:10 +000079 ZCAP_RAW,
pauledd7c242003-06-04 13:59:38 +000080};
81
82/* zebra privileges to run with */
83struct zebra_privs_t zserv_privs =
84{
pauld81fadf2003-08-14 05:32:12 +000085#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
86 .user = QUAGGA_USER,
87 .group = QUAGGA_GROUP,
pauledd7c242003-06-04 13:59:38 +000088#endif
89#ifdef VTY_GROUP
90 .vty_group = VTY_GROUP,
91#endif
92 .caps_p = _caps_p,
93 .cap_num_p = sizeof(_caps_p)/sizeof(_caps_p[0]),
94 .cap_num_i = 0
95};
96
paul718e3742002-12-13 20:15:29 +000097/* Default configuration file path. */
98char config_current[] = DEFAULT_CONFIG_FILE;
99char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
100
101/* Process ID saved for use by init system */
102char *pid_file = PATH_ZEBRA_PID;
103
104/* Help information display. */
105static void
106usage (char *progname, int status)
107{
108 if (status != 0)
109 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
110 else
111 {
112 printf ("Usage : %s [OPTION...]\n\n\
113Daemon which manages kernel routing table management and \
114redistribution between different routing protocols.\n\n\
115-b, --batch Runs in batch mode\n\
116-d, --daemon Runs in daemon mode\n\
117-f, --config_file Set configuration file name\n\
118-i, --pid_file Set process identifier file name\n\
119-k, --keep_kernel Don't delete old routes which installed by zebra.\n\
120-l, --log_mode Set verbose log mode flag\n\
121-A, --vty_addr Set vty's bind address\n\
122-P, --vty_port Set vty's port number\n\
123-r, --retain When program terminates, retain added route by zebra.\n\
pauledd7c242003-06-04 13:59:38 +0000124-u, --user User and group to run as\n\
paul718e3742002-12-13 20:15:29 +0000125-v, --version Print program version\n\
126-h, --help Display this help and exit\n\
127\n\
128Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
129 }
130
131 exit (status);
132}
133
134/* SIGHUP handler. */
135void
paul2d75d052004-01-19 21:31:15 +0000136sighup (void)
paul718e3742002-12-13 20:15:29 +0000137{
138 zlog_info ("SIGHUP received");
139
140 /* Reload of config file. */
141 ;
142}
143
144/* SIGINT handler. */
145void
paul2d75d052004-01-19 21:31:15 +0000146sigint (void)
paul718e3742002-12-13 20:15:29 +0000147{
148 /* Decrared in rib.c */
149 void rib_close ();
150
151 zlog_info ("Terminating on signal");
152
153 if (!retain_mode)
154 rib_close ();
hassoca776982004-06-12 14:33:05 +0000155#ifdef HAVE_IRDP
156 irdp_finish();
157#endif
paul718e3742002-12-13 20:15:29 +0000158
159 exit (0);
160}
161
162/* SIGUSR1 handler. */
163void
paul2d75d052004-01-19 21:31:15 +0000164sigusr1 (void)
paul718e3742002-12-13 20:15:29 +0000165{
166 zlog_rotate (NULL);
167}
168
paul2d75d052004-01-19 21:31:15 +0000169struct quagga_signal_t zebra_signals[] =
paul718e3742002-12-13 20:15:29 +0000170{
paul2d75d052004-01-19 21:31:15 +0000171 {
172 .signal = SIGHUP,
173 .handler = &sighup,
174 },
175 {
176 .signal = SIGUSR1,
177 .handler = &sigusr1,
178 },
179 {
180 .signal = SIGINT,
hasso8c903fb2004-03-17 20:39:18 +0000181 .handler = &sigint,
paul2d75d052004-01-19 21:31:15 +0000182 },
hassof571dab2004-03-22 08:55:25 +0000183 {
184 .signal = SIGTERM,
185 .handler = &sigint,
186 },
paul2d75d052004-01-19 21:31:15 +0000187};
paul718e3742002-12-13 20:15:29 +0000188
189/* Main startup routine. */
190int
191main (int argc, char **argv)
192{
193 char *p;
194 char *vty_addr = NULL;
paul4fc4e7a2003-01-22 19:47:09 +0000195 int vty_port = ZEBRA_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000196 int batch_mode = 0;
197 int daemon_mode = 0;
198 char *config_file = NULL;
199 char *progname;
200 struct thread thread;
201 void rib_weed_tables ();
202 void zebra_vty_init ();
203
204 /* Set umask before anything for security */
205 umask (0027);
206
207 /* preserve my name */
208 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
209
210 zlog_default = openzlog (progname, ZLOG_STDOUT, ZLOG_ZEBRA,
211 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
212
213 while (1)
214 {
215 int opt;
216
paul96735ee2003-08-10 02:51:22 +0000217 opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:v", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000218
219 if (opt == EOF)
220 break;
221
222 switch (opt)
223 {
224 case 0:
225 break;
226 case 'b':
227 batch_mode = 1;
228 case 'd':
229 daemon_mode = 1;
230 break;
231 case 'k':
232 keep_kernel_mode = 1;
233 break;
234 case 'l':
235 /* log_mode = 1; */
236 break;
237 case 'f':
238 config_file = optarg;
239 break;
240 case 'A':
241 vty_addr = optarg;
242 break;
243 case 'i':
244 pid_file = optarg;
245 break;
246 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000247 /* Deal with atoi() returning 0 on failure, and zebra not
248 listening on zebra port... */
249 if (strcmp(optarg, "0") == 0)
250 {
251 vty_port = 0;
252 break;
253 }
paul718e3742002-12-13 20:15:29 +0000254 vty_port = atoi (optarg);
paul4fc4e7a2003-01-22 19:47:09 +0000255 vty_port = (vty_port ? vty_port : ZEBRA_VTY_PORT);
paul718e3742002-12-13 20:15:29 +0000256 break;
257 case 'r':
258 retain_mode = 1;
259 break;
pauledd7c242003-06-04 13:59:38 +0000260 case 'u':
261 zserv_privs.user = zserv_privs.group = optarg;
262 break;
paul718e3742002-12-13 20:15:29 +0000263 case 'v':
264 print_version (progname);
265 exit (0);
266 break;
267 case 'h':
268 usage (progname, 0);
269 break;
270 default:
271 usage (progname, 1);
272 break;
273 }
274 }
275
276 /* Make master thread emulator. */
paulb21b19c2003-06-15 01:28:29 +0000277 zebrad.master = thread_master_create ();
paul718e3742002-12-13 20:15:29 +0000278
pauledd7c242003-06-04 13:59:38 +0000279 /* privs initialise */
280 zprivs_init (&zserv_privs);
281
paul718e3742002-12-13 20:15:29 +0000282 /* Vty related initialize. */
paul2d75d052004-01-19 21:31:15 +0000283 signal_init (zebrad.master, Q_SIGC(zebra_signals), zebra_signals);
paul718e3742002-12-13 20:15:29 +0000284 cmd_init (1);
paulb21b19c2003-06-15 01:28:29 +0000285 vty_init (zebrad.master);
paul718e3742002-12-13 20:15:29 +0000286 memory_init ();
287
288 /* Zebra related initialize. */
289 zebra_init ();
290 rib_init ();
291 zebra_if_init ();
292 zebra_debug_init ();
293 zebra_vty_init ();
294 access_list_init ();
295 rtadv_init ();
hassoca776982004-06-12 14:33:05 +0000296#ifdef HAVE_IRDP
297 irdp_init();
298#endif
paul718e3742002-12-13 20:15:29 +0000299
300 /* For debug purpose. */
301 /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
302
303 /* Make kernel routing socket. */
304 kernel_init ();
305 interface_list ();
306 route_read ();
307
308 /* Sort VTY commands. */
309 sort_node ();
310
311#ifdef HAVE_SNMP
312 zebra_snmp_init ();
313#endif /* HAVE_SNMP */
314
315 /* Clean up self inserted route. */
316 if (! keep_kernel_mode)
317 rib_sweep_route ();
318
319 /* Configuration file read*/
320 vty_read_config (config_file, config_current, config_default);
321
322 /* Clean up rib. */
323 rib_weed_tables ();
324
325 /* Exit when zebra is working in batch mode. */
326 if (batch_mode)
327 exit (0);
328
329 /* Needed for BSD routing socket. */
330 old_pid = getpid ();
331
332 /* Daemonize. */
333 if (daemon_mode)
334 daemon (0, 0);
335
336 /* Output pid of zebra. */
337 pid_output (pid_file);
338
339 /* Needed for BSD routing socket. */
340 pid = getpid ();
341
342 /* Make vty server socket. */
paul4fc4e7a2003-01-22 19:47:09 +0000343 vty_serv_sock (vty_addr, vty_port, ZEBRA_VTYSH_PATH);
paul718e3742002-12-13 20:15:29 +0000344
paulb21b19c2003-06-15 01:28:29 +0000345 while (thread_fetch (zebrad.master, &thread))
paul718e3742002-12-13 20:15:29 +0000346 thread_call (&thread);
347
348 /* Not reached... */
349 exit (0);
350}