File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / test_main.c
Revision 1.1.1.3 (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: /* main routine.
    2:  * Copyright (C) 1997, 98 Kunihiro Ishiguro
    3:  *
    4:  * GNU Zebra is free software; you can redistribute it and/or modify it
    5:  * under the terms of the GNU General Public License as published by the
    6:  * Free Software Foundation; either version 2, or (at your option) any
    7:  * later version.
    8:  *
    9:  * GNU Zebra is distributed in the hope that it will be useful, but
   10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
   11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12:  * General Public License for more details.
   13:  *
   14:  * You should have received a copy of the GNU General Public License
   15:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
   16:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   17:  * 02111-1307, USA.  
   18:  */
   19: 
   20: #include <zebra.h>
   21: 
   22: #include <lib/version.h>
   23: #include "getopt.h"
   24: #include "command.h"
   25: #include "thread.h"
   26: #include "filter.h"
   27: #include "memory.h"
   28: #include "prefix.h"
   29: #include "log.h"
   30: #include "privs.h"
   31: #include "sigevent.h"
   32: #include "vrf.h"
   33: 
   34: #include "zebra/rib.h"
   35: #include "zebra/zserv.h"
   36: #include "zebra/debug.h"
   37: #include "zebra/router-id.h"
   38: #include "zebra/interface.h"
   39: 
   40: /* Zebra instance */
   41: struct zebra_t zebrad =
   42: {
   43:   .rtm_table_default = 0,
   44: };
   45: 
   46: /* process id. */
   47: pid_t pid;
   48: 
   49: /* zebra_rib's workqueue hold time. Private export for use by test code only */
   50: extern int rib_process_hold_time;
   51: 
   52: /* Pacify zclient.o in libzebra, which expects this variable. */
   53: struct thread_master *master;
   54: 
   55: /* Command line options. */
   56: struct option longopts[] = 
   57: {
   58:   { "batch",       no_argument,       NULL, 'b'},
   59:   { "daemon",      no_argument,       NULL, 'd'},
   60:   { "config_file", required_argument, NULL, 'f'},
   61:   { "help",        no_argument,       NULL, 'h'},
   62:   { "vty_addr",    required_argument, NULL, 'A'},
   63:   { "vty_port",    required_argument, NULL, 'P'},
   64:   { "version",     no_argument,       NULL, 'v'},
   65:   { "rib_hold",	   required_argument, NULL, 'r'},
   66:   { 0 }
   67: };
   68: 
   69: zebra_capabilities_t _caps_p [] = 
   70: {
   71:   ZCAP_NET_ADMIN,
   72:   ZCAP_SYS_ADMIN,
   73:   ZCAP_NET_RAW,
   74: };
   75: 
   76: /* Default configuration file path. */
   77: char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
   78: 
   79: /* Process ID saved for use by init system */
   80: const char *pid_file = PATH_ZEBRA_PID;
   81: 
   82: /* Help information display. */
   83: static void
   84: usage (char *progname, int status)
   85: {
   86:   if (status != 0)
   87:     fprintf (stderr, "Try `%s --help' for more information.\n", progname);
   88:   else
   89:     {    
   90:       printf ("Usage : %s [OPTION...]\n\n"\
   91: 	      "Daemon which manages kernel routing table management and "\
   92: 	      "redistribution between different routing protocols.\n\n"\
   93: 	      "-b, --batch        Runs in batch mode\n"\
   94: 	      "-d, --daemon       Runs in daemon mode\n"\
   95: 	      "-f, --config_file  Set configuration file name\n"\
   96: 	      "-A, --vty_addr     Set vty's bind address\n"\
   97: 	      "-P, --vty_port     Set vty's port number\n"\
   98: 	      "-r, --rib_hold	  Set rib-queue hold time\n"\
   99:               "-v, --version      Print program version\n"\
  100: 	      "-h, --help         Display this help and exit\n"\
  101: 	      "\n"\
  102: 	      "Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
  103:     }
  104: 
  105:   exit (status);
  106: }
  107: 
  108: static ifindex_t test_ifindex = 0;
  109: 
  110: /* testrib commands */
  111: DEFUN (test_interface_state,
  112:        test_interface_state_cmd,
  113:        "state (up|down)",
  114:        "configure interface\n"
  115:        "up\n"
  116:        "down\n")
  117: {
  118:   struct interface *ifp;
  119:   if (argc < 1)
  120:     return CMD_WARNING;
  121:   
  122:   ifp = vty->index;
  123:   if (ifp->ifindex == IFINDEX_INTERNAL)
  124:     {
  125:       ifp->ifindex = ++test_ifindex;
  126:       ifp->mtu = 1500;
  127:       ifp->flags = IFF_BROADCAST|IFF_MULTICAST;
  128:     }
  129:   
  130:   switch (argv[0][0])
  131:     {
  132:       case 'u':
  133:         SET_FLAG (ifp->flags, IFF_UP);
  134:         if_add_update (ifp);
  135:         printf ("up\n");
  136:         break;
  137:       case 'd':
  138:         UNSET_FLAG (ifp->flags, IFF_UP);
  139:         if_delete_update (ifp);
  140:         printf ("down\n");
  141:         break;
  142:       default:
  143:         return CMD_WARNING;
  144:     }
  145:   return CMD_SUCCESS;
  146: }
  147: 
  148: static void
  149: test_cmd_init (void)
  150: {
  151:   install_element (INTERFACE_NODE, &test_interface_state_cmd);
  152: }
  153: 
  154: /* SIGHUP handler. */
  155: static void 
  156: sighup (void)
  157: {
  158:   zlog_info ("SIGHUP received");
  159: 
  160:   /* Reload of config file. */
  161:   ;
  162: }
  163: 
  164: /* SIGINT handler. */
  165: static void
  166: sigint (void)
  167: {
  168:   zlog_notice ("Terminating on signal");
  169: 
  170:   exit (0);
  171: }
  172: 
  173: /* SIGUSR1 handler. */
  174: static void
  175: sigusr1 (void)
  176: {
  177:   zlog_rotate (NULL);
  178: }
  179: 
  180: struct quagga_signal_t zebra_signals[] =
  181: {
  182:   { 
  183:     .signal = SIGHUP, 
  184:     .handler = &sighup,
  185:   },
  186:   {
  187:     .signal = SIGUSR1,
  188:     .handler = &sigusr1,
  189:   },
  190:   {
  191:     .signal = SIGINT,
  192:     .handler = &sigint,
  193:   },
  194:   {
  195:     .signal = SIGTERM,
  196:     .handler = &sigint,
  197:   },
  198: };
  199: 
  200: /* Callback upon creating a new VRF. */
  201: static int
  202: zebra_vrf_new (vrf_id_t vrf_id, void **info)
  203: {
  204:   struct zebra_vrf *zvrf = *info;
  205: 
  206:   if (! zvrf)
  207:     {
  208:       zvrf = zebra_vrf_alloc (vrf_id);
  209:       *info = (void *)zvrf;
  210:     }
  211: 
  212:   return 0;
  213: }
  214: 
  215: /* Callback upon enabling a VRF. */
  216: static int
  217: zebra_vrf_enable (vrf_id_t vrf_id, void **info)
  218: {
  219:   struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
  220: 
  221:   assert (zvrf);
  222: 
  223:   kernel_init (zvrf);
  224:   route_read (zvrf);
  225: 
  226:   return 0;
  227: }
  228: 
  229: /* Callback upon disabling a VRF. */
  230: static int
  231: zebra_vrf_disable (vrf_id_t vrf_id, void **info)
  232: {
  233:   struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
  234:   struct listnode *list_node;
  235:   struct interface *ifp;
  236: 
  237:   assert (zvrf);
  238: 
  239:   rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
  240:   rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
  241: 
  242:   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), list_node, ifp))
  243:     {
  244:       int operative = if_is_operative (ifp);
  245:       UNSET_FLAG (ifp->flags, IFF_UP);
  246:       if (operative)
  247:         if_down (ifp);
  248:     }
  249: 
  250:   kernel_terminate (zvrf);
  251: 
  252:   return 0;
  253: }
  254: 
  255: /* Zebra VRF initialization. */
  256: static void
  257: zebra_vrf_init (void)
  258: {
  259:   vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);
  260:   vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable);
  261:   vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
  262:   vrf_init ();
  263: }
  264: 
  265: /* Main startup routine. */
  266: int
  267: main (int argc, char **argv)
  268: {
  269:   char *p;
  270:   char *vty_addr = NULL;
  271:   int vty_port = 0;
  272:   int batch_mode = 0;
  273:   int daemon_mode = 0;
  274:   char *config_file = NULL;
  275:   char *progname;
  276:   struct thread thread;
  277: 
  278:   /* Set umask before anything for security */
  279:   umask (0027);
  280: 
  281:   /* preserve my name */
  282:   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
  283: 
  284:   zlog_default = openzlog (progname, ZLOG_ZEBRA,
  285: 			   LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
  286: 
  287:   while (1) 
  288:     {
  289:       int opt;
  290:   
  291:       opt = getopt_long (argc, argv, "bdf:hA:P:r:v", longopts, 0);
  292: 
  293:       if (opt == EOF)
  294: 	break;
  295: 
  296:       switch (opt) 
  297: 	{
  298: 	case 0:
  299: 	  break;
  300: 	case 'b':
  301: 	  batch_mode = 1;
  302: 	case 'd':
  303: 	  daemon_mode = 1;
  304: 	  break;
  305: 	case 'f':
  306: 	  config_file = optarg;
  307: 	  break;
  308: 	case 'A':
  309: 	  vty_addr = optarg;
  310: 	  break;
  311: 	case 'P':
  312: 	  /* Deal with atoi() returning 0 on failure, and zebra not
  313: 	     listening on zebra port... */
  314: 	  if (strcmp(optarg, "0") == 0) 
  315: 	    {
  316: 	      vty_port = 0;
  317: 	      break;
  318: 	    } 
  319: 	  vty_port = atoi (optarg);
  320: 	  break;
  321: 	case 'r':
  322: 	  rib_process_hold_time = atoi(optarg);
  323: 	  break;
  324: 	case 'v':
  325: 	  print_version (progname);
  326: 	  exit (0);
  327: 	  break;
  328: 	case 'h':
  329: 	  usage (progname, 0);
  330: 	  break;
  331: 	default:
  332: 	  usage (progname, 1);
  333: 	  break;
  334: 	}
  335:     }
  336:   
  337:   /* port and conf file mandatory */
  338:   if (!vty_port || !config_file)
  339:     {
  340:       fprintf (stderr, "Error: --vty_port and --config_file arguments"
  341:                        " are both required\n");
  342:       usage (progname, 1);
  343:     }
  344:   
  345:   /* Make master thread emulator. */
  346:   zebrad.master = thread_master_create ();
  347: 
  348:   /* Vty related initialize. */
  349:   signal_init (zebrad.master, array_size(zebra_signals), zebra_signals);
  350:   cmd_init (1);
  351:   vty_init (zebrad.master);
  352:   memory_init ();
  353:   zebra_debug_init ();
  354:   zebra_if_init ();
  355:   test_cmd_init ();
  356: 
  357:   /* Zebra related initialize. */
  358:   rib_init ();
  359:   access_list_init ();
  360: 
  361:   /* Make kernel routing socket. */
  362:   zebra_vrf_init ();
  363:   zebra_vty_init();
  364: 
  365:   /* Configuration file read*/
  366:   vty_read_config (config_file, config_default);
  367: 
  368:   /* Clean up rib. */
  369:   rib_weed_tables ();
  370: 
  371:   /* Exit when zebra is working in batch mode. */
  372:   if (batch_mode)
  373:     exit (0);
  374: 
  375:   /* Daemonize. */
  376:   if (daemon_mode && daemon (0, 0) < 0)
  377:     {
  378:       perror("daemon start failed");
  379:       exit (1);
  380:     }
  381: 
  382:   /* Needed for BSD routing socket. */
  383:   pid = getpid ();
  384: 
  385:   /* Make vty server socket. */
  386:   vty_serv_sock (vty_addr, vty_port, "/tmp/test_zebra");
  387: 
  388:   /* Print banner. */
  389:   zlog_notice ("Zebra %s starting: vty@%d", QUAGGA_VERSION, vty_port);
  390: 
  391:   while (thread_fetch (zebrad.master, &thread))
  392:     thread_call (&thread);
  393: 
  394:   /* Not reached... */
  395:   return 0;
  396: }

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