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