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

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

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