File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / main.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    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>