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