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

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

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