Annotation of embedaddon/quagga/bgpd/bgp_main.c, revision 1.1.1.4

1.1       misho       1: /* Main routine of bgpd.
                      2:    Copyright (C) 1996, 97, 98, 1999 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: #include <zebra.h>
                     22: 
                     23: #include "vector.h"
                     24: #include "vty.h"
                     25: #include "command.h"
                     26: #include "getopt.h"
                     27: #include "thread.h"
                     28: #include <lib/version.h>
                     29: #include "memory.h"
                     30: #include "prefix.h"
                     31: #include "log.h"
                     32: #include "privs.h"
                     33: #include "sigevent.h"
                     34: #include "zclient.h"
                     35: #include "routemap.h"
                     36: #include "filter.h"
                     37: #include "plist.h"
1.1.1.2   misho      38: #include "stream.h"
1.1.1.4 ! misho      39: #include "vrf.h"
        !            40: #include "workqueue.h"
1.1       misho      41: 
                     42: #include "bgpd/bgpd.h"
                     43: #include "bgpd/bgp_attr.h"
                     44: #include "bgpd/bgp_mplsvpn.h"
                     45: #include "bgpd/bgp_aspath.h"
                     46: #include "bgpd/bgp_dump.h"
                     47: #include "bgpd/bgp_route.h"
                     48: #include "bgpd/bgp_nexthop.h"
                     49: #include "bgpd/bgp_regex.h"
                     50: #include "bgpd/bgp_clist.h"
                     51: #include "bgpd/bgp_debug.h"
                     52: #include "bgpd/bgp_filter.h"
1.1.1.2   misho      53: #include "bgpd/bgp_zebra.h"
1.1       misho      54: 
                     55: /* bgpd options, we use GNU getopt library. */
                     56: static const struct option longopts[] = 
                     57: {
                     58:   { "daemon",      no_argument,       NULL, 'd'},
                     59:   { "config_file", required_argument, NULL, 'f'},
                     60:   { "pid_file",    required_argument, NULL, 'i'},
1.1.1.2   misho      61:   { "socket",      required_argument, NULL, 'z'},
1.1       misho      62:   { "bgp_port",    required_argument, NULL, 'p'},
                     63:   { "listenon",    required_argument, NULL, 'l'},
                     64:   { "vty_addr",    required_argument, NULL, 'A'},
                     65:   { "vty_port",    required_argument, NULL, 'P'},
                     66:   { "retain",      no_argument,       NULL, 'r'},
                     67:   { "no_kernel",   no_argument,       NULL, 'n'},
                     68:   { "user",        required_argument, NULL, 'u'},
                     69:   { "group",       required_argument, NULL, 'g'},
                     70:   { "version",     no_argument,       NULL, 'v'},
                     71:   { "dryrun",      no_argument,       NULL, 'C'},
                     72:   { "help",        no_argument,       NULL, 'h'},
                     73:   { 0 }
                     74: };
                     75: 
                     76: /* signal definitions */
                     77: void sighup (void);
                     78: void sigint (void);
                     79: void sigusr1 (void);
                     80: 
                     81: static void bgp_exit (int);
                     82: 
                     83: static struct quagga_signal_t bgp_signals[] = 
                     84: {
                     85:   { 
                     86:     .signal = SIGHUP, 
                     87:     .handler = &sighup,
                     88:   },
                     89:   {
                     90:     .signal = SIGUSR1,
                     91:     .handler = &sigusr1,
                     92:   },
                     93:   {
                     94:     .signal = SIGINT,
                     95:     .handler = &sigint,
                     96:   },
                     97:   {
                     98:     .signal = SIGTERM,
                     99:     .handler = &sigint,
                    100:   },
                    101: };
                    102: 
                    103: /* Configuration file and directory. */
                    104: char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
                    105: 
                    106: /* Route retain mode flag. */
                    107: static int retain_mode = 0;
                    108: 
                    109: /* Manually specified configuration file name.  */
                    110: char *config_file = NULL;
                    111: 
                    112: /* Process ID saved for use by init system */
                    113: static const char *pid_file = PATH_BGPD_PID;
                    114: 
                    115: /* VTY port number and address.  */
                    116: int vty_port = BGP_VTY_PORT;
                    117: char *vty_addr = NULL;
                    118: 
                    119: /* privileges */
                    120: static zebra_capabilities_t _caps_p [] =  
                    121: {
                    122:     ZCAP_BIND, 
                    123:     ZCAP_NET_RAW,
1.1.1.2   misho     124:     ZCAP_NET_ADMIN,
1.1       misho     125: };
                    126: 
                    127: struct zebra_privs_t bgpd_privs =
                    128: {
                    129: #if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
                    130:   .user = QUAGGA_USER,
                    131:   .group = QUAGGA_GROUP,
                    132: #endif
                    133: #ifdef VTY_GROUP
                    134:   .vty_group = VTY_GROUP,
                    135: #endif
                    136:   .caps_p = _caps_p,
1.1.1.3   misho     137:   .cap_num_p = array_size(_caps_p),
1.1       misho     138:   .cap_num_i = 0,
                    139: };
                    140: 
                    141: /* Help information display. */
                    142: static void
                    143: usage (char *progname, int status)
                    144: {
                    145:   if (status != 0)
                    146:     fprintf (stderr, "Try `%s --help' for more information.\n", progname);
                    147:   else
                    148:     {    
                    149:       printf ("Usage : %s [OPTION...]\n\n\
                    150: Daemon which manages kernel routing table management and \
                    151: redistribution between different routing protocols.\n\n\
                    152: -d, --daemon       Runs in daemon mode\n\
                    153: -f, --config_file  Set configuration file name\n\
                    154: -i, --pid_file     Set process identifier file name\n\
1.1.1.2   misho     155: -z, --socket       Set path of zebra socket\n\
1.1       misho     156: -p, --bgp_port     Set bgp protocol's port number\n\
                    157: -l, --listenon     Listen on specified address (implies -n)\n\
                    158: -A, --vty_addr     Set vty's bind address\n\
                    159: -P, --vty_port     Set vty's port number\n\
                    160: -r, --retain       When program terminates, retain added route by bgpd.\n\
                    161: -n, --no_kernel    Do not install route to kernel.\n\
                    162: -u, --user         User to run as\n\
                    163: -g, --group        Group to run as\n\
                    164: -v, --version      Print program version\n\
                    165: -C, --dryrun       Check configuration for validity and exit\n\
                    166: -h, --help         Display this help and exit\n\
                    167: \n\
                    168: Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
                    169:     }
                    170: 
                    171:   exit (status);
                    172: }
1.1.1.4 ! misho     173: 
1.1       misho     174: /* SIGHUP handler. */
                    175: void 
                    176: sighup (void)
                    177: {
                    178:   zlog (NULL, LOG_INFO, "SIGHUP received");
                    179: 
                    180:   /* Terminate all thread. */
                    181:   bgp_terminate ();
                    182:   bgp_reset ();
                    183:   zlog_info ("bgpd restarting!");
                    184: 
                    185:   /* Reload config file. */
                    186:   vty_read_config (config_file, config_default);
                    187: 
                    188:   /* Create VTY's socket */
                    189:   vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
                    190: 
                    191:   /* Try to return to normal operation. */
                    192: }
                    193: 
                    194: /* SIGINT handler. */
                    195: void
                    196: sigint (void)
                    197: {
                    198:   zlog_notice ("Terminating on signal");
                    199: 
1.1.1.4 ! misho     200:   if (! retain_mode) 
        !           201:     {
        !           202:       bgp_terminate ();
        !           203:       zprivs_terminate (&bgpd_privs);
        !           204:     }
1.1       misho     205: 
                    206:   bgp_exit (0);
                    207: }
                    208: 
                    209: /* SIGUSR1 handler. */
                    210: void
                    211: sigusr1 (void)
                    212: {
                    213:   zlog_rotate (NULL);
                    214: }
                    215: 
                    216: /*
                    217:   Try to free up allocations we know about so that diagnostic tools such as
                    218:   valgrind are able to better illuminate leaks.
                    219: 
                    220:   Zebra route removal and protocol teardown are not meant to be done here.
                    221:   For example, "retain_mode" may be set.
                    222: */
                    223: static void
                    224: bgp_exit (int status)
                    225: {
                    226:   struct bgp *bgp;
                    227:   struct listnode *node, *nnode;
                    228:   int *socket;
                    229:   struct interface *ifp;
                    230:   extern struct zclient *zlookup;
                    231: 
                    232:   /* it only makes sense for this to be called on a clean exit */
                    233:   assert (status == 0);
                    234: 
                    235:   /* reverse bgp_master_init */
                    236:   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
                    237:     bgp_delete (bgp);
                    238:   list_free (bm->bgp);
1.1.1.4 ! misho     239:   bm->bgp = NULL;
        !           240:   
        !           241:   /*
        !           242:    * bgp_delete can re-allocate the process queues after they were
        !           243:    * deleted in bgp_terminate. delete them again.
        !           244:    *
        !           245:    * It might be better to ensure the RIBs (including static routes)
        !           246:    * are cleared by bgp_terminate() during its call to bgp_cleanup_routes(),
        !           247:    * which currently only deletes the kernel routes.
        !           248:    */
        !           249:   if (bm->process_main_queue)
        !           250:     {
        !           251:      work_queue_free (bm->process_main_queue);
        !           252:      bm->process_main_queue = NULL;
        !           253:     }
        !           254:   if (bm->process_rsclient_queue)
        !           255:     {
        !           256:       work_queue_free (bm->process_rsclient_queue);
        !           257:       bm->process_rsclient_queue = NULL;
        !           258:     }
        !           259:   
1.1       misho     260:   /* reverse bgp_master_init */
                    261:   for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
                    262:     {
                    263:       if (close ((int)(long)socket) == -1)
                    264:         zlog_err ("close (%d): %s", (int)(long)socket, safe_strerror (errno));
                    265:     }
                    266:   list_delete (bm->listen_sockets);
                    267: 
                    268:   /* reverse bgp_zebra_init/if_init */
                    269:   if (retain_mode)
                    270:     if_add_hook (IF_DELETE_HOOK, NULL);
1.1.1.4 ! misho     271:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
1.1       misho     272:     {
                    273:       struct listnode *c_node, *c_nnode;
                    274:       struct connected *c;
                    275: 
                    276:       for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
                    277:         bgp_connected_delete (c);
                    278:     }
                    279: 
                    280:   /* reverse bgp_attr_init */
                    281:   bgp_attr_finish ();
                    282: 
                    283:   /* reverse bgp_dump_init */
                    284:   bgp_dump_finish ();
                    285: 
                    286:   /* reverse bgp_route_init */
                    287:   bgp_route_finish ();
                    288: 
                    289:   /* reverse bgp_route_map_init/route_map_init */
                    290:   route_map_finish ();
                    291: 
                    292:   /* reverse bgp_scan_init */
                    293:   bgp_scan_finish ();
                    294: 
                    295:   /* reverse access_list_init */
                    296:   access_list_add_hook (NULL);
                    297:   access_list_delete_hook (NULL);
                    298:   access_list_reset ();
                    299: 
                    300:   /* reverse bgp_filter_init */
                    301:   as_list_add_hook (NULL);
                    302:   as_list_delete_hook (NULL);
                    303:   bgp_filter_reset ();
                    304: 
                    305:   /* reverse prefix_list_init */
                    306:   prefix_list_add_hook (NULL);
                    307:   prefix_list_delete_hook (NULL);
                    308:   prefix_list_reset ();
                    309: 
                    310:   /* reverse community_list_init */
                    311:   community_list_terminate (bgp_clist);
                    312: 
1.1.1.4 ! misho     313:   vrf_terminate ();
1.1       misho     314:   cmd_terminate ();
                    315:   vty_terminate ();
1.1.1.4 ! misho     316:   bgp_address_destroy();
        !           317:   bgp_scan_destroy();
        !           318:   bgp_zebra_destroy();
1.1       misho     319:   if (zlookup)
                    320:     zclient_free (zlookup);
1.1.1.2   misho     321:   if (bgp_nexthop_buf)
                    322:     stream_free (bgp_nexthop_buf);
1.1       misho     323: 
                    324:   /* reverse bgp_master_init */
1.1.1.4 ! misho     325:   if (bm->master)
        !           326:     thread_master_free (bm->master);
1.1       misho     327: 
                    328:   if (zlog_default)
                    329:     closezlog (zlog_default);
                    330: 
                    331:   if (CONF_BGP_DEBUG (normal, NORMAL))
                    332:     log_memstats_stderr ("bgpd");
                    333: 
                    334:   exit (status);
                    335: }
1.1.1.4 ! misho     336: 
1.1       misho     337: /* Main routine of bgpd. Treatment of argument and start bgp finite
                    338:    state machine is handled at here. */
                    339: int
                    340: main (int argc, char **argv)
                    341: {
                    342:   char *p;
                    343:   int opt;
                    344:   int daemon_mode = 0;
                    345:   int dryrun = 0;
                    346:   char *progname;
                    347:   struct thread thread;
                    348:   int tmp_port;
                    349: 
                    350:   /* Set umask before anything for security */
                    351:   umask (0027);
                    352: 
                    353:   /* Preserve name of myself. */
                    354:   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
                    355: 
                    356:   zlog_default = openzlog (progname, ZLOG_BGP,
                    357:                           LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
                    358: 
                    359:   /* BGP master init. */
                    360:   bgp_master_init ();
                    361: 
                    362:   /* Command line argument treatment. */
                    363:   while (1) 
                    364:     {
1.1.1.2   misho     365:       opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vC", longopts, 0);
1.1       misho     366:     
                    367:       if (opt == EOF)
                    368:        break;
                    369: 
                    370:       switch (opt) 
                    371:        {
                    372:        case 0:
                    373:          break;
                    374:        case 'd':
                    375:          daemon_mode = 1;
                    376:          break;
                    377:        case 'f':
                    378:          config_file = optarg;
                    379:          break;
                    380:         case 'i':
                    381:           pid_file = optarg;
                    382:           break;
1.1.1.2   misho     383:        case 'z':
                    384:          zclient_serv_path_set (optarg);
                    385:          break;
1.1       misho     386:        case 'p':
                    387:          tmp_port = atoi (optarg);
                    388:          if (tmp_port <= 0 || tmp_port > 0xffff)
                    389:            bm->port = BGP_PORT_DEFAULT;
                    390:          else
                    391:            bm->port = tmp_port;
                    392:          break;
                    393:        case 'A':
                    394:          vty_addr = optarg;
                    395:          break;
                    396:        case 'P':
                    397:           /* Deal with atoi() returning 0 on failure, and bgpd not
                    398:              listening on bgp port... */
                    399:           if (strcmp(optarg, "0") == 0) 
                    400:             {
                    401:               vty_port = 0;
                    402:               break;
                    403:             } 
                    404:           vty_port = atoi (optarg);
                    405:          if (vty_port <= 0 || vty_port > 0xffff)
                    406:            vty_port = BGP_VTY_PORT;
                    407:          break;
                    408:        case 'r':
                    409:          retain_mode = 1;
                    410:          break;
                    411:        case 'l':
                    412:          bm->address = optarg;
                    413:          /* listenon implies -n */
                    414:        case 'n':
                    415:          bgp_option_set (BGP_OPT_NO_FIB);
                    416:          break;
                    417:        case 'u':
                    418:          bgpd_privs.user = optarg;
                    419:          break;
                    420:        case 'g':
                    421:          bgpd_privs.group = optarg;
                    422:          break;
                    423:        case 'v':
                    424:          print_version (progname);
                    425:          exit (0);
                    426:          break;
                    427:        case 'C':
                    428:          dryrun = 1;
                    429:          break;
                    430:        case 'h':
                    431:          usage (progname, 0);
                    432:          break;
                    433:        default:
                    434:          usage (progname, 1);
                    435:          break;
                    436:        }
                    437:     }
                    438: 
                    439:   /* Initializations. */
1.1.1.4 ! misho     440:   srandom (time (NULL));
        !           441:   signal_init (bm->master, array_size(bgp_signals), bgp_signals);
1.1       misho     442:   zprivs_init (&bgpd_privs);
                    443:   cmd_init (1);
1.1.1.4 ! misho     444:   vty_init (bm->master);
1.1       misho     445:   memory_init ();
1.1.1.4 ! misho     446:   vrf_init ();
1.1       misho     447: 
                    448:   /* BGP related initialization.  */
                    449:   bgp_init ();
                    450: 
                    451:   /* Parse config file. */
                    452:   vty_read_config (config_file, config_default);
                    453: 
                    454:   /* Start execution only if not in dry-run mode */
                    455:   if(dryrun)
                    456:     return(0);
                    457:   
                    458:   /* Turn into daemon if daemon_mode is set. */
                    459:   if (daemon_mode && daemon (0, 0) < 0)
                    460:     {
                    461:       zlog_err("BGPd daemon failed: %s", strerror(errno));
                    462:       return (1);
                    463:     }
                    464: 
                    465: 
                    466:   /* Process ID file creation. */
                    467:   pid_output (pid_file);
                    468: 
                    469:   /* Make bgp vty socket. */
                    470:   vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
                    471: 
                    472:   /* Print banner. */
1.1.1.4 ! misho     473:   zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d pid %d", QUAGGA_VERSION,
1.1       misho     474:               vty_port, 
                    475:               (bm->address ? bm->address : "<all>"),
1.1.1.4 ! misho     476:               bm->port,
        !           477:               getpid ());
1.1       misho     478: 
                    479:   /* Start finite state machine, here we go! */
1.1.1.4 ! misho     480:   while (thread_fetch (bm->master, &thread))
1.1       misho     481:     thread_call (&thread);
                    482: 
                    483:   /* Not reached. */
                    484:   return (0);
                    485: }

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