File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / isisd / isis_main.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:38 2013 UTC (11 years ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

    1: /*
    2:  * IS-IS Rout(e)ing protocol - isis_main.c
    3:  *
    4:  * Copyright (C) 2001,2002   Sampo Saaristo
    5:  *                           Tampere University of Technology      
    6:  *                           Institute of Communications Engineering
    7:  *
    8:  * This program is free software; you can redistribute it and/or modify it 
    9:  * under the terms of the GNU General Public Licenseas published by the Free 
   10:  * Software Foundation; either version 2 of the License, or (at your option) 
   11:  * any later version.
   12:  *
   13:  * This program is distributed in the hope that it will be useful,but WITHOUT 
   14:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
   15:  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
   16:  * more details.
   17: 
   18:  * You should have received a copy of the GNU General Public License along 
   19:  * with this program; if not, write to the Free Software Foundation, Inc., 
   20:  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   21:  */
   22: 
   23: #include <zebra.h>
   24: 
   25: #include "getopt.h"
   26: #include "thread.h"
   27: #include "log.h"
   28: #include <lib/version.h>
   29: #include "command.h"
   30: #include "vty.h"
   31: #include "memory.h"
   32: #include "stream.h"
   33: #include "if.h"
   34: #include "privs.h"
   35: #include "sigevent.h"
   36: #include "filter.h"
   37: #include "zclient.h"
   38: 
   39: #include "isisd/dict.h"
   40: #include "include-netbsd/iso.h"
   41: #include "isisd/isis_constants.h"
   42: #include "isisd/isis_common.h"
   43: #include "isisd/isis_flags.h"
   44: #include "isisd/isis_circuit.h"
   45: #include "isisd/isisd.h"
   46: #include "isisd/isis_dynhn.h"
   47: #include "isisd/isis_spf.h"
   48: #include "isisd/isis_route.h"
   49: #include "isisd/isis_zebra.h"
   50: 
   51: /* Default configuration file name */
   52: #define ISISD_DEFAULT_CONFIG "isisd.conf"
   53: /* Default vty port */
   54: #define ISISD_VTY_PORT       2608
   55: 
   56: /* isisd privileges */
   57: zebra_capabilities_t _caps_p[] = {
   58:   ZCAP_NET_RAW,
   59:   ZCAP_BIND
   60: };
   61: 
   62: struct zebra_privs_t isisd_privs = {
   63: #if defined(QUAGGA_USER)
   64:   .user = QUAGGA_USER,
   65: #endif
   66: #if defined QUAGGA_GROUP
   67:   .group = QUAGGA_GROUP,
   68: #endif
   69: #ifdef VTY_GROUP
   70:   .vty_group = VTY_GROUP,
   71: #endif
   72:   .caps_p = _caps_p,
   73:   .cap_num_p = sizeof (_caps_p) / sizeof (*_caps_p),
   74:   .cap_num_i = 0
   75: };
   76: 
   77: /* isisd options */
   78: struct option longopts[] = {
   79:   {"daemon",      no_argument,       NULL, 'd'},
   80:   {"config_file", required_argument, NULL, 'f'},
   81:   {"pid_file",    required_argument, NULL, 'i'},
   82:   {"socket",      required_argument, NULL, 'z'},
   83:   {"vty_addr",    required_argument, NULL, 'A'},
   84:   {"vty_port",    required_argument, NULL, 'P'},
   85:   {"user",        required_argument, NULL, 'u'},
   86:   {"group",       required_argument, NULL, 'g'},
   87:   {"version",     no_argument,       NULL, 'v'},
   88:   {"dryrun",      no_argument,       NULL, 'C'},
   89:   {"help",        no_argument,       NULL, 'h'},
   90:   {0}
   91: };
   92: 
   93: /* Configuration file and directory. */
   94: char config_default[] = SYSCONFDIR ISISD_DEFAULT_CONFIG;
   95: char *config_file = NULL;
   96: 
   97: /* isisd program name. */
   98: char *progname;
   99: 
  100: int daemon_mode = 0;
  101: 
  102: /* Master of threads. */
  103: struct thread_master *master;
  104: 
  105: /* Process ID saved for use by init system */
  106: const char *pid_file = PATH_ISISD_PID;
  107: 
  108: /* for reload */
  109: char _cwd[MAXPATHLEN];
  110: char _progpath[MAXPATHLEN];
  111: int _argc;
  112: char **_argv;
  113: char **_envp;
  114: 
  115: /*
  116:  * Prototypes.
  117:  */
  118: void reload(void);
  119: void sighup(void);
  120: void sigint(void);
  121: void sigterm(void);
  122: void sigusr1(void);
  123: 
  124: 
  125: /* Help information display. */
  126: static void
  127: usage (int status)
  128: {
  129:   if (status != 0)
  130:     fprintf (stderr, "Try `%s --help' for more information.\n", progname);
  131:   else
  132:     {
  133:       printf ("Usage : %s [OPTION...]\n\n\
  134: Daemon which manages IS-IS routing\n\n\
  135: -d, --daemon       Runs in daemon mode\n\
  136: -f, --config_file  Set configuration file name\n\
  137: -i, --pid_file     Set process identifier file name\n\
  138: -z, --socket       Set path of zebra socket\n\
  139: -A, --vty_addr     Set vty's bind address\n\
  140: -P, --vty_port     Set vty's port number\n\
  141: -u, --user         User to run as\n\
  142: -g, --group        Group to run as\n\
  143: -v, --version      Print program version\n\
  144: -C, --dryrun       Check configuration for validity and exit\n\
  145: -h, --help         Display this help and exit\n\
  146: \n\
  147: Report bugs to http://bugzilla.quagga.net\n", progname);
  148:     }
  149: 
  150:   exit (status);
  151: }
  152: 
  153: 
  154: void
  155: reload ()
  156: {
  157:   zlog_debug ("Reload");
  158:   /* FIXME: Clean up func call here */
  159:   vty_reset ();
  160:   (void) isisd_privs.change (ZPRIVS_RAISE);
  161:   execve (_progpath, _argv, _envp);
  162:   zlog_err ("Reload failed: cannot exec %s: %s", _progpath,
  163:       safe_strerror (errno));
  164: }
  165: 
  166: static void
  167: terminate (int i)
  168: {
  169:   exit (i);
  170: }
  171: 
  172: /*
  173:  * Signal handlers
  174:  */
  175: 
  176: void
  177: sighup (void)
  178: {
  179:   zlog_debug ("SIGHUP received");
  180:   reload ();
  181: 
  182:   return;
  183: }
  184: 
  185: void
  186: sigint (void)
  187: {
  188:   zlog_notice ("Terminating on signal SIGINT");
  189:   terminate (0);
  190: }
  191: 
  192: void
  193: sigterm (void)
  194: {
  195:   zlog_notice ("Terminating on signal SIGTERM");
  196:   terminate (0);
  197: }
  198: 
  199: void
  200: sigusr1 (void)
  201: {
  202:   zlog_debug ("SIGUSR1 received");
  203:   zlog_rotate (NULL);
  204: }
  205: 
  206: struct quagga_signal_t isisd_signals[] =
  207: {
  208:   {
  209:    .signal = SIGHUP,
  210:    .handler = &sighup,
  211:    },
  212:   {
  213:    .signal = SIGUSR1,
  214:    .handler = &sigusr1,
  215:    },
  216:   {
  217:    .signal = SIGINT,
  218:    .handler = &sigint,
  219:    },
  220:   {
  221:    .signal = SIGTERM,
  222:    .handler = &sigterm,
  223:    },
  224: };
  225: 
  226: /*
  227:  * Main routine of isisd. Parse arguments and handle IS-IS state machine.
  228:  */
  229: int
  230: main (int argc, char **argv, char **envp)
  231: {
  232:   char *p;
  233:   int opt, vty_port = ISISD_VTY_PORT;
  234:   struct thread thread;
  235:   char *config_file = NULL;
  236:   char *vty_addr = NULL;
  237:   int dryrun = 0;
  238: 
  239:   /* Get the programname without the preceding path. */
  240:   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
  241: 
  242:   zlog_default = openzlog (progname, ZLOG_ISIS,
  243: 			   LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
  244: 
  245:   /* for reload */
  246:   _argc = argc;
  247:   _argv = argv;
  248:   _envp = envp;
  249:   getcwd (_cwd, sizeof (_cwd));
  250:   if (*argv[0] == '.')
  251:     snprintf (_progpath, sizeof (_progpath), "%s/%s", _cwd, _argv[0]);
  252:   else
  253:     snprintf (_progpath, sizeof (_progpath), "%s", argv[0]);
  254: 
  255:   /* Command line argument treatment. */
  256:   while (1)
  257:     {
  258:       opt = getopt_long (argc, argv, "df:i:z:hA:p:P:u:g:vC", longopts, 0);
  259: 
  260:       if (opt == EOF)
  261: 	break;
  262: 
  263:       switch (opt)
  264: 	{
  265: 	case 0:
  266: 	  break;
  267: 	case 'd':
  268: 	  daemon_mode = 1;
  269: 	  break;
  270: 	case 'f':
  271: 	  config_file = optarg;
  272: 	  break;
  273: 	case 'i':
  274: 	  pid_file = optarg;
  275: 	  break;
  276: 	case 'z':
  277: 	  zclient_serv_path_set (optarg);
  278: 	  break;
  279: 	case 'A':
  280: 	  vty_addr = optarg;
  281: 	  break;
  282: 	case 'P':
  283: 	  /* Deal with atoi() returning 0 on failure, and isisd not
  284: 	     listening on isisd port... */
  285: 	  if (strcmp (optarg, "0") == 0)
  286: 	    {
  287: 	      vty_port = 0;
  288: 	      break;
  289: 	    }
  290: 	  vty_port = atoi (optarg);
  291: 	  vty_port = (vty_port ? vty_port : ISISD_VTY_PORT);
  292: 	  break;
  293: 	case 'u':
  294: 	  isisd_privs.user = optarg;
  295: 	  break;
  296: 	case 'g':
  297: 	  isisd_privs.group = optarg;
  298: 	  break;
  299: 	case 'v':
  300: 	  printf ("ISISd version %s\n", ISISD_VERSION);
  301: 	  printf ("Copyright (c) 2001-2002 Sampo Saaristo,"
  302: 		  " Ofer Wald and Hannes Gredler\n");
  303: 	  print_version ("Zebra");
  304: 	  exit (0);
  305: 	  break;
  306: 	case 'C':
  307: 	  dryrun = 1;
  308: 	  break;
  309: 	case 'h':
  310: 	  usage (0);
  311: 	  break;
  312: 	default:
  313: 	  usage (1);
  314: 	  break;
  315: 	}
  316:     }
  317: 
  318:   /* thread master */
  319:   master = thread_master_create ();
  320: 
  321:   /* random seed from time */
  322:   srand (time (NULL));
  323: 
  324:   /*
  325:    *  initializations
  326:    */
  327:   zprivs_init (&isisd_privs);
  328:   signal_init (master, array_size (isisd_signals), isisd_signals);
  329:   cmd_init (1);
  330:   vty_init (master);
  331:   memory_init ();
  332:   access_list_init();
  333:   isis_init ();
  334:   isis_circuit_init ();
  335:   isis_spf_cmds_init ();
  336: 
  337:   /* create the global 'isis' instance */
  338:   isis_new (1);
  339: 
  340:   isis_zebra_init ();
  341: 
  342:   sort_node ();
  343: 
  344:   /* parse config file */
  345:   /* this is needed three times! because we have interfaces before the areas */
  346:   vty_read_config (config_file, config_default);
  347: 
  348:   /* Start execution only if not in dry-run mode */
  349:   if (dryrun)
  350:     return(0);
  351:   
  352:   /* demonize */
  353:   if (daemon_mode)
  354:     daemon (0, 0);
  355: 
  356:   /* Process ID file creation. */
  357:   if (pid_file[0] != '\0')
  358:     pid_output (pid_file);
  359: 
  360:   /* Make isis vty socket. */
  361:   vty_serv_sock (vty_addr, vty_port, ISIS_VTYSH_PATH);
  362: 
  363:   /* Print banner. */
  364:   zlog_notice ("Quagga-ISISd %s starting: vty@%d", QUAGGA_VERSION, vty_port);
  365: 
  366:   /* Start finite state machine. */
  367:   while (thread_fetch (master, &thread))
  368:     thread_call (&thread);
  369: 
  370:   /* Not reached. */
  371:   exit (0);
  372: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>