Annotation of embedaddon/quagga/bgpd/bgp_main.c, revision 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>