LCOV - code coverage report
Current view: top level - zebra - main.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 72 116 62.1 %
Date: 2015-11-19 Functions: 3 5 60.0 %

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

Generated by: LCOV version 1.10