blob: c9a19eda6ce511366a4b8e72cd938f8d9cd4407d [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
24#include "version.h"
25#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"
paul718e3742002-12-13 20:15:29 +000033
34#include "zebra/rib.h"
35#include "zebra/zserv.h"
36#include "zebra/debug.h"
37#include "zebra/rib.h"
38
paulb21b19c2003-06-15 01:28:29 +000039/* Zebra instance */
40struct zebra_t zebrad =
41{
42 .rtm_table_default = 0,
43};
paul718e3742002-12-13 20:15:29 +000044
45/* process id. */
46pid_t old_pid;
47pid_t pid;
48
49/* Route retain mode flag. */
50int retain_mode = 0;
51
52/* Don't delete kernel route. */
53int keep_kernel_mode = 0;
54
55/* Command line options. */
56struct option longopts[] =
57{
58 { "batch", no_argument, NULL, 'b'},
59 { "daemon", no_argument, NULL, 'd'},
60 { "keep_kernel", no_argument, NULL, 'k'},
61 { "log_mode", no_argument, NULL, 'l'},
62 { "config_file", required_argument, NULL, 'f'},
63 { "pid_file", required_argument, NULL, 'i'},
64 { "help", no_argument, NULL, 'h'},
65 { "vty_addr", required_argument, NULL, 'A'},
66 { "vty_port", required_argument, NULL, 'P'},
67 { "retain", no_argument, NULL, 'r'},
pauledd7c242003-06-04 13:59:38 +000068 { "user", required_argument, NULL, 'u'},
paul718e3742002-12-13 20:15:29 +000069 { "version", no_argument, NULL, 'v'},
70 { 0 }
71};
72
pauledd7c242003-06-04 13:59:38 +000073zebra_capabilities_t _caps_p [] =
74{
75 ZCAP_ADMIN,
76 ZCAP_SYS_ADMIN,
hasso41908812003-06-05 11:33:10 +000077 ZCAP_RAW,
pauledd7c242003-06-04 13:59:38 +000078};
79
80/* zebra privileges to run with */
81struct zebra_privs_t zserv_privs =
82{
83#if defined(ZEBRA_USER) && defined(ZEBRA_GROUP)
84 .user = ZEBRA_USER,
85 .group = ZEBRA_GROUP,
86#endif
87#ifdef VTY_GROUP
88 .vty_group = VTY_GROUP,
89#endif
90 .caps_p = _caps_p,
91 .cap_num_p = sizeof(_caps_p)/sizeof(_caps_p[0]),
92 .cap_num_i = 0
93};
94
paul718e3742002-12-13 20:15:29 +000095/* Default configuration file path. */
96char config_current[] = DEFAULT_CONFIG_FILE;
97char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
98
99/* Process ID saved for use by init system */
100char *pid_file = PATH_ZEBRA_PID;
101
102/* Help information display. */
103static void
104usage (char *progname, int status)
105{
106 if (status != 0)
107 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
108 else
109 {
110 printf ("Usage : %s [OPTION...]\n\n\
111Daemon which manages kernel routing table management and \
112redistribution between different routing protocols.\n\n\
113-b, --batch Runs in batch mode\n\
114-d, --daemon Runs in daemon mode\n\
115-f, --config_file Set configuration file name\n\
116-i, --pid_file Set process identifier file name\n\
117-k, --keep_kernel Don't delete old routes which installed by zebra.\n\
118-l, --log_mode Set verbose log mode flag\n\
119-A, --vty_addr Set vty's bind address\n\
120-P, --vty_port Set vty's port number\n\
121-r, --retain When program terminates, retain added route by zebra.\n\
pauledd7c242003-06-04 13:59:38 +0000122-u, --user User and group to run as\n\
paul718e3742002-12-13 20:15:29 +0000123-v, --version Print program version\n\
124-h, --help Display this help and exit\n\
125\n\
126Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
127 }
128
129 exit (status);
130}
131
132/* SIGHUP handler. */
133void
134sighup (int sig)
135{
136 zlog_info ("SIGHUP received");
137
138 /* Reload of config file. */
139 ;
140}
141
142/* SIGINT handler. */
143void
144sigint (int sig)
145{
146 /* Decrared in rib.c */
147 void rib_close ();
148
149 zlog_info ("Terminating on signal");
150
151 if (!retain_mode)
152 rib_close ();
153
154 exit (0);
155}
156
157/* SIGUSR1 handler. */
158void
159sigusr1 (int sig)
160{
161 zlog_rotate (NULL);
162}
163
164/* Signale wrapper. */
165RETSIGTYPE *
166signal_set (int signo, void (*func)(int))
167{
168 int ret;
169 struct sigaction sig;
170 struct sigaction osig;
171
172 sig.sa_handler = func;
173 sigemptyset (&sig.sa_mask);
174 sig.sa_flags = 0;
175#ifdef SA_RESTART
176 sig.sa_flags |= SA_RESTART;
177#endif /* SA_RESTART */
178
179 ret = sigaction (signo, &sig, &osig);
180
181 if (ret < 0)
182 return (SIG_ERR);
183 else
184 return (osig.sa_handler);
185}
186
187/* Initialization of signal handles. */
188void
189signal_init ()
190{
191 signal_set (SIGHUP, sighup);
192 signal_set (SIGINT, sigint);
193 signal_set (SIGTERM, sigint);
194 signal_set (SIGPIPE, SIG_IGN);
195 signal_set (SIGUSR1, sigusr1);
196}
197
198/* Main startup routine. */
199int
200main (int argc, char **argv)
201{
202 char *p;
203 char *vty_addr = NULL;
paul4fc4e7a2003-01-22 19:47:09 +0000204 int vty_port = ZEBRA_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000205 int batch_mode = 0;
206 int daemon_mode = 0;
207 char *config_file = NULL;
208 char *progname;
209 struct thread thread;
210 void rib_weed_tables ();
211 void zebra_vty_init ();
212
213 /* Set umask before anything for security */
214 umask (0027);
215
216 /* preserve my name */
217 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
218
219 zlog_default = openzlog (progname, ZLOG_STDOUT, ZLOG_ZEBRA,
220 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
221
222 while (1)
223 {
224 int opt;
225
paul96735ee2003-08-10 02:51:22 +0000226 opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:v", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000227
228 if (opt == EOF)
229 break;
230
231 switch (opt)
232 {
233 case 0:
234 break;
235 case 'b':
236 batch_mode = 1;
237 case 'd':
238 daemon_mode = 1;
239 break;
240 case 'k':
241 keep_kernel_mode = 1;
242 break;
243 case 'l':
244 /* log_mode = 1; */
245 break;
246 case 'f':
247 config_file = optarg;
248 break;
249 case 'A':
250 vty_addr = optarg;
251 break;
252 case 'i':
253 pid_file = optarg;
254 break;
255 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000256 /* Deal with atoi() returning 0 on failure, and zebra not
257 listening on zebra port... */
258 if (strcmp(optarg, "0") == 0)
259 {
260 vty_port = 0;
261 break;
262 }
paul718e3742002-12-13 20:15:29 +0000263 vty_port = atoi (optarg);
paul4fc4e7a2003-01-22 19:47:09 +0000264 vty_port = (vty_port ? vty_port : ZEBRA_VTY_PORT);
paul718e3742002-12-13 20:15:29 +0000265 break;
266 case 'r':
267 retain_mode = 1;
268 break;
pauledd7c242003-06-04 13:59:38 +0000269 case 'u':
270 zserv_privs.user = zserv_privs.group = optarg;
271 break;
paul718e3742002-12-13 20:15:29 +0000272 case 'v':
273 print_version (progname);
274 exit (0);
275 break;
276 case 'h':
277 usage (progname, 0);
278 break;
279 default:
280 usage (progname, 1);
281 break;
282 }
283 }
284
285 /* Make master thread emulator. */
paulb21b19c2003-06-15 01:28:29 +0000286 zebrad.master = thread_master_create ();
paul718e3742002-12-13 20:15:29 +0000287
pauledd7c242003-06-04 13:59:38 +0000288 /* privs initialise */
289 zprivs_init (&zserv_privs);
290
paul718e3742002-12-13 20:15:29 +0000291 /* Vty related initialize. */
292 signal_init ();
293 cmd_init (1);
paulb21b19c2003-06-15 01:28:29 +0000294 vty_init (zebrad.master);
paul718e3742002-12-13 20:15:29 +0000295 memory_init ();
296
297 /* Zebra related initialize. */
298 zebra_init ();
299 rib_init ();
300 zebra_if_init ();
301 zebra_debug_init ();
302 zebra_vty_init ();
303 access_list_init ();
304 rtadv_init ();
305
306 /* For debug purpose. */
307 /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
308
309 /* Make kernel routing socket. */
310 kernel_init ();
311 interface_list ();
312 route_read ();
313
314 /* Sort VTY commands. */
315 sort_node ();
316
317#ifdef HAVE_SNMP
318 zebra_snmp_init ();
319#endif /* HAVE_SNMP */
320
321 /* Clean up self inserted route. */
322 if (! keep_kernel_mode)
323 rib_sweep_route ();
324
325 /* Configuration file read*/
326 vty_read_config (config_file, config_current, config_default);
327
328 /* Clean up rib. */
329 rib_weed_tables ();
330
331 /* Exit when zebra is working in batch mode. */
332 if (batch_mode)
333 exit (0);
334
335 /* Needed for BSD routing socket. */
336 old_pid = getpid ();
337
338 /* Daemonize. */
339 if (daemon_mode)
340 daemon (0, 0);
341
342 /* Output pid of zebra. */
343 pid_output (pid_file);
344
345 /* Needed for BSD routing socket. */
346 pid = getpid ();
347
348 /* Make vty server socket. */
paul4fc4e7a2003-01-22 19:47:09 +0000349 vty_serv_sock (vty_addr, vty_port, ZEBRA_VTYSH_PATH);
paul718e3742002-12-13 20:15:29 +0000350
paulb21b19c2003-06-15 01:28:29 +0000351 while (thread_fetch (zebrad.master, &thread))
paul718e3742002-12-13 20:15:29 +0000352 thread_call (&thread);
353
354 /* Not reached... */
355 exit (0);
356}