Annotation of embedaddon/quagga/zebra/main.c, revision 1.1.1.4

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"
1.1.1.4 ! misho      35: #include "vrf.h"
1.1       misho      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"
1.1.1.3   misho      43: #include "zebra/zebra_fpm.h"
1.1       misho      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'},
1.1.1.2   misho      76:   { "socket",      required_argument, NULL, 'z'},
1.1       misho      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,
1.1.1.3   misho     109:   .cap_num_p = array_size(_caps_p),
1.1       misho     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"\
1.1.1.2   misho     134:              "-z, --socket       Set path of zebra socket\n"\
1.1       misho     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: }
1.1.1.4 ! misho     155: 
1.1       misho     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: };
1.1.1.4 ! misho     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: 
1.1       misho     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;
1.1.1.2   misho     297:   char *zserv_path = NULL;
1.1       misho     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  
1.1.1.2   misho     313:       opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vs:C", longopts, 0);
1.1       misho     314: #else
1.1.1.2   misho     315:       opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vC", longopts, 0);
1.1       misho     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;
1.1.1.2   misho     345:        case 'z':
                    346:          zserv_path = optarg;
                    347:          break;
1.1       misho     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. */
1.1.1.3   misho     394:   signal_init (zebrad.master, array_size(zebra_signals), zebra_signals);
1.1       misho     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 ();
1.1.1.4 ! misho     404:   router_id_cmd_init ();
1.1       misho     405:   zebra_vty_init ();
                    406:   access_list_init ();
                    407:   prefix_list_init ();
1.1.1.4 ! misho     408: #if defined (HAVE_RTADV)
        !           409:   rtadv_cmd_init ();
1.1.1.3   misho     410: #endif
1.1       misho     411: #ifdef HAVE_IRDP
                    412:   irdp_init();
                    413: #endif
                    414: 
                    415:   /* For debug purpose. */
                    416:   /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
                    417: 
1.1.1.4 ! misho     418:   /* Initialize VRF module, and make kernel routing socket. */
        !           419:   zebra_vrf_init ();
1.1       misho     420: 
                    421: #ifdef HAVE_SNMP
                    422:   zebra_snmp_init ();
                    423: #endif /* HAVE_SNMP */
                    424: 
1.1.1.3   misho     425: #ifdef HAVE_FPM
                    426:   zfpm_init (zebrad.master, 1, 0);
                    427: #else
                    428:   zfpm_init (zebrad.master, 0, 0);
                    429: #endif
                    430: 
1.1       misho     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). */
1.1.1.2   misho     476:   zebra_zserv_socket_init (zserv_path);
1.1       misho     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>