File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / bgpd / bgp_main.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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>