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