Annotation of embedaddon/quagga/zebra/main.c, revision 1.1.1.4
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"
1.1.1.4 ! misho 35: #include "vrf.h"
1.1 misho 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"
1.1.1.3 misho 43: #include "zebra/zebra_fpm.h"
1.1 misho 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'},
1.1.1.2 misho 76: { "socket", required_argument, NULL, 'z'},
1.1 misho 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,
1.1.1.3 misho 109: .cap_num_p = array_size(_caps_p),
1.1 misho 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"\
1.1.1.2 misho 134: "-z, --socket Set path of zebra socket\n"\
1.1 misho 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: }
1.1.1.4 ! misho 155:
1.1 misho 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: };
1.1.1.4 ! misho 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:
1.1 misho 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;
1.1.1.2 misho 297: char *zserv_path = NULL;
1.1 misho 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
1.1.1.2 misho 313: opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vs:C", longopts, 0);
1.1 misho 314: #else
1.1.1.2 misho 315: opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vC", longopts, 0);
1.1 misho 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;
1.1.1.2 misho 345: case 'z':
346: zserv_path = optarg;
347: break;
1.1 misho 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. */
1.1.1.3 misho 394: signal_init (zebrad.master, array_size(zebra_signals), zebra_signals);
1.1 misho 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 ();
1.1.1.4 ! misho 404: router_id_cmd_init ();
1.1 misho 405: zebra_vty_init ();
406: access_list_init ();
407: prefix_list_init ();
1.1.1.4 ! misho 408: #if defined (HAVE_RTADV)
! 409: rtadv_cmd_init ();
1.1.1.3 misho 410: #endif
1.1 misho 411: #ifdef HAVE_IRDP
412: irdp_init();
413: #endif
414:
415: /* For debug purpose. */
416: /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
417:
1.1.1.4 ! misho 418: /* Initialize VRF module, and make kernel routing socket. */
! 419: zebra_vrf_init ();
1.1 misho 420:
421: #ifdef HAVE_SNMP
422: zebra_snmp_init ();
423: #endif /* HAVE_SNMP */
424:
1.1.1.3 misho 425: #ifdef HAVE_FPM
426: zfpm_init (zebrad.master, 1, 0);
427: #else
428: zfpm_init (zebrad.master, 0, 0);
429: #endif
430:
1.1 misho 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). */
1.1.1.2 misho 476: zebra_zserv_socket_init (zserv_path);
1.1 misho 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>