1: /* zebra daemon main routine.
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:
24: #include <lib/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"
32: #include "plist.h"
33: #include "privs.h"
34: #include "sigevent.h"
35:
36: #include "zebra/rib.h"
37: #include "zebra/zserv.h"
38: #include "zebra/debug.h"
39: #include "zebra/router-id.h"
40: #include "zebra/irdp.h"
41: #include "zebra/rtadv.h"
42: #include "zebra/zebra_fpm.h"
43:
44: /* Zebra instance */
45: struct zebra_t zebrad =
46: {
47: .rtm_table_default = 0,
48: };
49:
50: /* process id. */
51: pid_t pid;
52:
53: /* Pacify zclient.o in libzebra, which expects this variable. */
54: struct thread_master *master;
55:
56: /* Route retain mode flag. */
57: int retain_mode = 0;
58:
59: /* Don't delete kernel route. */
60: int keep_kernel_mode = 0;
61:
62: #ifdef HAVE_NETLINK
63: /* Receive buffer size for netlink socket */
64: u_int32_t nl_rcvbufsize = 0;
65: #endif /* HAVE_NETLINK */
66:
67: /* Command line options. */
68: struct option longopts[] =
69: {
70: { "batch", no_argument, NULL, 'b'},
71: { "daemon", no_argument, NULL, 'd'},
72: { "keep_kernel", no_argument, NULL, 'k'},
73: { "config_file", required_argument, NULL, 'f'},
74: { "pid_file", required_argument, NULL, 'i'},
75: { "socket", required_argument, NULL, 'z'},
76: { "help", no_argument, NULL, 'h'},
77: { "vty_addr", required_argument, NULL, 'A'},
78: { "vty_port", required_argument, NULL, 'P'},
79: { "retain", no_argument, NULL, 'r'},
80: { "dryrun", no_argument, NULL, 'C'},
81: #ifdef HAVE_NETLINK
82: { "nl-bufsize", required_argument, NULL, 's'},
83: #endif /* HAVE_NETLINK */
84: { "user", required_argument, NULL, 'u'},
85: { "group", required_argument, NULL, 'g'},
86: { "version", no_argument, NULL, 'v'},
87: { 0 }
88: };
89:
90: zebra_capabilities_t _caps_p [] =
91: {
92: ZCAP_NET_ADMIN,
93: ZCAP_SYS_ADMIN,
94: ZCAP_NET_RAW,
95: };
96:
97: /* zebra privileges to run with */
98: struct zebra_privs_t zserv_privs =
99: {
100: #if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
101: .user = QUAGGA_USER,
102: .group = QUAGGA_GROUP,
103: #endif
104: #ifdef VTY_GROUP
105: .vty_group = VTY_GROUP,
106: #endif
107: .caps_p = _caps_p,
108: .cap_num_p = array_size(_caps_p),
109: .cap_num_i = 0
110: };
111:
112: /* Default configuration file path. */
113: char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
114:
115: /* Process ID saved for use by init system */
116: const char *pid_file = PATH_ZEBRA_PID;
117:
118: /* Help information display. */
119: static void
120: usage (char *progname, int status)
121: {
122: if (status != 0)
123: fprintf (stderr, "Try `%s --help' for more information.\n", progname);
124: else
125: {
126: printf ("Usage : %s [OPTION...]\n\n"\
127: "Daemon which manages kernel routing table management and "\
128: "redistribution between different routing protocols.\n\n"\
129: "-b, --batch Runs in batch mode\n"\
130: "-d, --daemon Runs in daemon mode\n"\
131: "-f, --config_file Set configuration file name\n"\
132: "-i, --pid_file Set process identifier file name\n"\
133: "-z, --socket Set path of zebra socket\n"\
134: "-k, --keep_kernel Don't delete old routes which installed by "\
135: "zebra.\n"\
136: "-C, --dryrun Check configuration for validity and exit\n"\
137: "-A, --vty_addr Set vty's bind address\n"\
138: "-P, --vty_port Set vty's port number\n"\
139: "-r, --retain When program terminates, retain added route "\
140: "by zebra.\n"\
141: "-u, --user User to run as\n"\
142: "-g, --group Group to run as\n", progname);
143: #ifdef HAVE_NETLINK
144: printf ("-s, --nl-bufsize Set netlink receive buffer size\n");
145: #endif /* HAVE_NETLINK */
146: printf ("-v, --version Print program version\n"\
147: "-h, --help Display this help and exit\n"\
148: "\n"\
149: "Report bugs to %s\n", ZEBRA_BUG_ADDRESS);
150: }
151:
152: exit (status);
153: }
154:
155: /* SIGHUP handler. */
156: static void
157: sighup (void)
158: {
159: zlog_info ("SIGHUP received");
160:
161: /* Reload of config file. */
162: ;
163: }
164:
165: /* SIGINT handler. */
166: static void
167: sigint (void)
168: {
169: zlog_notice ("Terminating on signal");
170:
171: if (!retain_mode)
172: rib_close ();
173: #ifdef HAVE_IRDP
174: irdp_finish();
175: #endif
176:
177: exit (0);
178: }
179:
180: /* SIGUSR1 handler. */
181: static void
182: sigusr1 (void)
183: {
184: zlog_rotate (NULL);
185: }
186:
187: struct quagga_signal_t zebra_signals[] =
188: {
189: {
190: .signal = SIGHUP,
191: .handler = &sighup,
192: },
193: {
194: .signal = SIGUSR1,
195: .handler = &sigusr1,
196: },
197: {
198: .signal = SIGINT,
199: .handler = &sigint,
200: },
201: {
202: .signal = SIGTERM,
203: .handler = &sigint,
204: },
205: };
206:
207: /* Main startup routine. */
208: int
209: main (int argc, char **argv)
210: {
211: char *p;
212: char *vty_addr = NULL;
213: int vty_port = ZEBRA_VTY_PORT;
214: int dryrun = 0;
215: int batch_mode = 0;
216: int daemon_mode = 0;
217: char *config_file = NULL;
218: char *progname;
219: struct thread thread;
220: char *zserv_path = NULL;
221:
222: /* Set umask before anything for security */
223: umask (0027);
224:
225: /* preserve my name */
226: progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
227:
228: zlog_default = openzlog (progname, ZLOG_ZEBRA,
229: LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
230:
231: while (1)
232: {
233: int opt;
234:
235: #ifdef HAVE_NETLINK
236: opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vs:C", longopts, 0);
237: #else
238: opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vC", longopts, 0);
239: #endif /* HAVE_NETLINK */
240:
241: if (opt == EOF)
242: break;
243:
244: switch (opt)
245: {
246: case 0:
247: break;
248: case 'b':
249: batch_mode = 1;
250: case 'd':
251: daemon_mode = 1;
252: break;
253: case 'k':
254: keep_kernel_mode = 1;
255: break;
256: case 'C':
257: dryrun = 1;
258: break;
259: case 'f':
260: config_file = optarg;
261: break;
262: case 'A':
263: vty_addr = optarg;
264: break;
265: case 'i':
266: pid_file = optarg;
267: break;
268: case 'z':
269: zserv_path = optarg;
270: break;
271: case 'P':
272: /* Deal with atoi() returning 0 on failure, and zebra not
273: listening on zebra port... */
274: if (strcmp(optarg, "0") == 0)
275: {
276: vty_port = 0;
277: break;
278: }
279: vty_port = atoi (optarg);
280: if (vty_port <= 0 || vty_port > 0xffff)
281: vty_port = ZEBRA_VTY_PORT;
282: break;
283: case 'r':
284: retain_mode = 1;
285: break;
286: #ifdef HAVE_NETLINK
287: case 's':
288: nl_rcvbufsize = atoi (optarg);
289: break;
290: #endif /* HAVE_NETLINK */
291: case 'u':
292: zserv_privs.user = optarg;
293: break;
294: case 'g':
295: zserv_privs.group = optarg;
296: break;
297: case 'v':
298: print_version (progname);
299: exit (0);
300: break;
301: case 'h':
302: usage (progname, 0);
303: break;
304: default:
305: usage (progname, 1);
306: break;
307: }
308: }
309:
310: /* Make master thread emulator. */
311: zebrad.master = thread_master_create ();
312:
313: /* privs initialise */
314: zprivs_init (&zserv_privs);
315:
316: /* Vty related initialize. */
317: signal_init (zebrad.master, array_size(zebra_signals), zebra_signals);
318: cmd_init (1);
319: vty_init (zebrad.master);
320: memory_init ();
321:
322: /* Zebra related initialize. */
323: zebra_init ();
324: rib_init ();
325: zebra_if_init ();
326: zebra_debug_init ();
327: router_id_init();
328: zebra_vty_init ();
329: access_list_init ();
330: prefix_list_init ();
331: #ifdef RTADV
332: rtadv_init ();
333: #endif
334: #ifdef HAVE_IRDP
335: irdp_init();
336: #endif
337:
338: /* For debug purpose. */
339: /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
340:
341: /* Make kernel routing socket. */
342: kernel_init ();
343: interface_list ();
344: route_read ();
345:
346: /* Sort VTY commands. */
347: sort_node ();
348:
349: #ifdef HAVE_SNMP
350: zebra_snmp_init ();
351: #endif /* HAVE_SNMP */
352:
353: #ifdef HAVE_FPM
354: zfpm_init (zebrad.master, 1, 0);
355: #else
356: zfpm_init (zebrad.master, 0, 0);
357: #endif
358:
359: /* Process the configuration file. Among other configuration
360: * directives we can meet those installing static routes. Such
361: * requests will not be executed immediately, but queued in
362: * zebra->ribq structure until we enter the main execution loop.
363: * The notifications from kernel will show originating PID equal
364: * to that after daemon() completes (if ever called).
365: */
366: vty_read_config (config_file, config_default);
367:
368: /* Don't start execution if we are in dry-run mode */
369: if (dryrun)
370: return(0);
371:
372: /* Clean up rib. */
373: rib_weed_tables ();
374:
375: /* Exit when zebra is working in batch mode. */
376: if (batch_mode)
377: exit (0);
378:
379: /* Daemonize. */
380: if (daemon_mode && daemon (0, 0) < 0)
381: {
382: zlog_err("Zebra daemon failed: %s", strerror(errno));
383: exit (1);
384: }
385:
386: /* Output pid of zebra. */
387: pid_output (pid_file);
388:
389: /* After we have successfully acquired the pidfile, we can be sure
390: * about being the only copy of zebra process, which is submitting
391: * changes to the FIB.
392: * Clean up zebra-originated routes. The requests will be sent to OS
393: * immediately, so originating PID in notifications from kernel
394: * will be equal to the current getpid(). To know about such routes,
395: * we have to have route_read() called before.
396: */
397: if (! keep_kernel_mode)
398: rib_sweep_route ();
399:
400: /* Needed for BSD routing socket. */
401: pid = getpid ();
402:
403: /* This must be done only after locking pidfile (bug #403). */
404: zebra_zserv_socket_init (zserv_path);
405:
406: /* Make vty server socket. */
407: vty_serv_sock (vty_addr, vty_port, ZEBRA_VTYSH_PATH);
408:
409: /* Print banner. */
410: zlog_notice ("Zebra %s starting: vty@%d", QUAGGA_VERSION, vty_port);
411:
412: while (thread_fetch (zebrad.master, &thread))
413: thread_call (&thread);
414:
415: /* Not reached... */
416: return 0;
417: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>