]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/main.c
Merge branch 'frr/pull/546' ("bgpd: resolve issue with sending vpn labels")
[mirror_frr.git] / zebra / main.c
index 4fea0104f51d8efe8c25a7c9c6cb1586d863b0de..b136f8ae93e12e4ccb9a69385cb995b9c8a3e354 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
@@ -35,6 +34,7 @@
 #include "privs.h"
 #include "sigevent.h"
 #include "vrf.h"
+#include "libfrr.h"
 
 #include "zebra/rib.h"
 #include "zebra/zserv.h"
 #include "zebra/router-id.h"
 #include "zebra/irdp.h"
 #include "zebra/rtadv.h"
-#include "zebra/zebra_fpm.h"
 #include "zebra/zebra_ptm.h"
 #include "zebra/zebra_ns.h"
 #include "zebra/redistribute.h"
 #include "zebra/zebra_mpls.h"
+#include "zebra/label_manager.h"
 
 #define ZEBRA_PTM_SUPPORT
 
@@ -59,7 +59,7 @@ struct zebra_t zebrad =
 /* process id. */
 pid_t pid;
 
-/* Pacify zclient.o in libzebra, which expects this variable. */
+/* Pacify zclient.o in libfrr, which expects this variable. */
 struct thread_master *master;
 
 /* Route retain mode flag. */
@@ -77,31 +77,22 @@ u_int32_t nl_rcvbufsize = 4194304;
 #endif /* HAVE_NETLINK */
 
 /* Command line options. */
-struct option longopts[] = 
+struct option longopts[] =
 {
   { "batch",        no_argument,       NULL, 'b'},
-  { "daemon",       no_argument,       NULL, 'd'},
   { "allow_delete", no_argument,       NULL, 'a'},
   { "keep_kernel",  no_argument,       NULL, 'k'},
-  { "fpm_format",   required_argument, NULL, 'F'},
-  { "config_file",  required_argument, NULL, 'f'},
-  { "pid_file",     required_argument, NULL, 'i'},
   { "socket",       required_argument, NULL, 'z'},
-  { "help",         no_argument,       NULL, 'h'},
-  { "vty_addr",     required_argument, NULL, 'A'},
-  { "vty_port",     required_argument, NULL, 'P'},
+  { "ecmp",         required_argument, NULL, 'e'},
+  { "label_socket", no_argument,       NULL, 'l'},
   { "retain",       no_argument,       NULL, 'r'},
-  { "dryrun",       no_argument,       NULL, 'C'},
 #ifdef HAVE_NETLINK
   { "nl-bufsize",   required_argument, NULL, 's'},
 #endif /* HAVE_NETLINK */
-  { "user",         required_argument, NULL, 'u'},
-  { "group",        required_argument, NULL, 'g'},
-  { "version",      no_argument,       NULL, 'v'},
   { 0 }
 };
 
-zebra_capabilities_t _caps_p [] = 
+zebra_capabilities_t _caps_p [] =
 {
   ZCAP_NET_ADMIN,
   ZCAP_SYS_ADMIN,
@@ -111,9 +102,9 @@ zebra_capabilities_t _caps_p [] =
 /* zebra privileges to run with */
 struct zebra_privs_t zserv_privs =
 {
-#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
-  .user = QUAGGA_USER,
-  .group = QUAGGA_GROUP,
+#if defined(FRR_USER) && defined(FRR_GROUP)
+  .user = FRR_USER,
+  .group = FRR_GROUP,
 #endif
 #ifdef VTY_GROUP
   .vty_group = VTY_GROUP,
@@ -123,53 +114,10 @@ struct zebra_privs_t zserv_privs =
   .cap_num_i = 0
 };
 
-/* Default configuration file path. */
-char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
-
-/* Process ID saved for use by init system */
-const char *pid_file = PATH_ZEBRA_PID;
-
-/* Help information display. */
-static void
-usage (char *progname, int status)
-{
-  if (status != 0)
-    fprintf (stderr, "Try `%s --help' for more information.\n", progname);
-  else
-    {    
-      printf ("Usage : %s [OPTION...]\n\n"\
-             "Daemon which manages kernel routing table management and "\
-             "redistribution between different routing protocols.\n\n"\
-             "-b, --batch        Runs in batch mode\n"\
-             "-d, --daemon       Runs in daemon mode\n"\
-             "-a, --allow_delete Allow other processes to delete Quagga Routes\n" \
-             "-f, --config_file  Set configuration file name\n"\
-             "-F, --fpm_format   Set fpm format to 'netlink' or 'protobuf'\n"\
-             "-i, --pid_file     Set process identifier file name\n"\
-             "-z, --socket       Set path of zebra socket\n"\
-             "-k, --keep_kernel  Don't delete old routes which installed by "\
-                                 "zebra.\n"\
-             "-C, --dryrun       Check configuration for validity and exit\n"\
-             "-A, --vty_addr     Set vty's bind address\n"\
-             "-P, --vty_port     Set vty's port number\n"\
-             "-r, --retain       When program terminates, retain added route "\
-                                 "by zebra.\n"\
-             "-u, --user         User to run as\n"\
-             "-g, --group        Group to run as\n", progname);
-#ifdef HAVE_NETLINK
-      printf ("-s, --nl-bufsize   Set netlink receive buffer size\n");
-#endif /* HAVE_NETLINK */
-      printf ("-v, --version      Print program version\n"\
-             "-h, --help         Display this help and exit\n"\
-             "\n"\
-             "Report bugs to %s\n", ZEBRA_BUG_ADDRESS);
-    }
-
-  exit (status);
-}
+unsigned int multipath_num = MULTIPATH_NUM;
 
 /* SIGHUP handler. */
-static void 
+static void
 sighup (void)
 {
   zlog_info ("SIGHUP received");
@@ -219,8 +167,7 @@ sigint (void)
     work_queue_free (zebrad.lsp_process_q);
   meta_queue_free (zebrad.mq);
   thread_master_free (zebrad.master);
-  if (zlog_default)
-    closezlog (zlog_default);
+  closezlog ();
 
   exit (0);
 }
@@ -229,13 +176,13 @@ sigint (void)
 static void
 sigusr1 (void)
 {
-  zlog_rotate (NULL);
+  zlog_rotate();
 }
 
 struct quagga_signal_t zebra_signals[] =
 {
-  { 
-    .signal = SIGHUP, 
+  {
+    .signal = SIGHUP,
     .handler = &sighup,
   },
   {
@@ -252,56 +199,60 @@ struct quagga_signal_t zebra_signals[] =
   },
 };
 
+FRR_DAEMON_INFO(zebra, ZEBRA,
+       .vty_port = ZEBRA_VTY_PORT,
+       .flags = FRR_NO_ZCLIENT,
+
+       .proghelp = "Daemon which manages kernel routing table management "
+               "and\nredistribution between different routing protocols.",
+
+       .signals = zebra_signals,
+       .n_signals = array_size(zebra_signals),
+
+       .privs = &zserv_privs,
+)
+
 /* Main startup routine. */
 int
 main (int argc, char **argv)
 {
-  char *p;
-  char *vty_addr = NULL;
-  int vty_port = ZEBRA_VTY_PORT;
-  int dryrun = 0;
-  int batch_mode = 0;
-  int daemon_mode = 0;
-  char *config_file = NULL;
-  char *progname;
-  struct thread thread;
+  // int batch_mode = 0;
   char *zserv_path = NULL;
-  char *fpm_format = NULL;
+  /* Socket to external label manager */
+  char *lblmgr_path = NULL;
 
-  /* Set umask before anything for security */
-  umask (0027);
+  frr_preinit(&zebra_di, argc, argv);
 
-  /* preserve my name */
-  progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
-
-  zlog_default = openzlog (progname, ZLOG_ZEBRA, 0,
-                          LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
-  zprivs_init (&zserv_privs);
-#if defined(HAVE_CUMULUS)
-  zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
+  frr_opt_add("bakz:e:l:r"
+#ifdef HAVE_NETLINK
+       "s:"
 #endif
+       , longopts,
+       "  -b, --batch        Runs in batch mode\n"
+       "  -a, --allow_delete Allow other processes to delete zebra routes\n"
+       "  -z, --socket       Set path of zebra socket\n"
+       "  -e, --ecmp         Specify ECMP to use.\n"
+       "  -l, --label_socket Socket to external label manager\n"\
+       "  -k, --keep_kernel  Don't delete old routes which installed by zebra.\n"
+       "  -r, --retain       When program terminates, retain added route by zebra.\n"
+#ifdef HAVE_NETLINK
+       "  -s, --nl-bufsize   Set netlink receive buffer size\n"
+#endif /* HAVE_NETLINK */
+       );
 
-  while (1) 
+  while (1)
     {
-      int opt;
-  
-#ifdef HAVE_NETLINK  
-      opt = getopt_long (argc, argv, "bdakf:F:i:z:hA:P:ru:g:vs:C", longopts, 0);
-#else
-      opt = getopt_long (argc, argv, "bdakf:F:i:z:hA:P:ru:g:vC", longopts, 0);
-#endif /* HAVE_NETLINK */
+      int opt = frr_getopt(argc, argv, NULL);
 
       if (opt == EOF)
        break;
 
-      switch (opt) 
+      switch (opt)
        {
        case 0:
          break;
        case 'b':
-         batch_mode = 1;
-       case 'd':
-         daemon_mode = 1;
+         // batch_mode = 1;
          break;
        case 'a':
          allow_delete = 1;
@@ -309,35 +260,19 @@ main (int argc, char **argv)
        case 'k':
          keep_kernel_mode = 1;
          break;
-       case 'C':
-         dryrun = 1;
-         break;
-       case 'f':
-         config_file = optarg;
-         break;
-       case 'F':
-         fpm_format = optarg;
-         break;
-       case 'A':
-         vty_addr = optarg;
-         break;
-        case 'i':
-          pid_file = optarg;
+        case 'e':
+          multipath_num = atoi (optarg);
+          if (multipath_num > MULTIPATH_NUM || multipath_num <= 0)
+            {
+              zlog_err ("Multipath Number specified must be less than %d and greater than 0", MULTIPATH_NUM);
+              return 1;
+            }
           break;
        case 'z':
          zserv_path = optarg;
          break;
-       case 'P':
-         /* Deal with atoi() returning 0 on failure, and zebra not
-            listening on zebra port... */
-         if (strcmp(optarg, "0") == 0) 
-           {
-             vty_port = 0;
-             break;
-           } 
-         vty_port = atoi (optarg);
-         if (vty_port <= 0 || vty_port > 0xffff)
-           vty_port = ZEBRA_VTY_PORT;
+       case 'l':
+         lblmgr_path = optarg;
          break;
        case 'r':
          retain_mode = 1;
@@ -347,34 +282,14 @@ main (int argc, char **argv)
          nl_rcvbufsize = atoi (optarg);
          break;
 #endif /* HAVE_NETLINK */
-       case 'u':
-         zserv_privs.user = optarg;
-         break;
-       case 'g':
-         zserv_privs.group = optarg;
-         break;
-       case 'v':
-         print_version (progname);
-         exit (0);
-         break;
-       case 'h':
-         usage (progname, 0);
-         break;
        default:
-         usage (progname, 1);
+         frr_help_exit (1);
          break;
        }
     }
 
-  /* Make master thread emulator. */
-  zebrad.master = thread_master_create ();
-
-  /* Vty related initialize. */
-  signal_init (zebrad.master, array_size(zebra_signals), zebra_signals);
-  cmd_init (1);
   vty_config_lockless ();
-  vty_init (zebrad.master);
-  memory_init ();
+  zebrad.master = frr_init();
 
   /* Zebra related initialize. */
   zebra_init ();
@@ -405,16 +320,6 @@ main (int argc, char **argv)
   /* Initialize NS( and implicitly the VRF module), and make kernel routing socket. */
   zebra_ns_init ();
 
-#ifdef HAVE_SNMP
-  zebra_snmp_init ();
-#endif /* HAVE_SNMP */
-
-#ifdef HAVE_FPM
-  zfpm_init (zebrad.master, 1, 0, fpm_format);
-#else
-  zfpm_init (zebrad.master, 0, 0, fpm_format);
-#endif
-
   /* Process the configuration file. Among other configuration
   *  directives we can meet those installing static routes. Such
   *  requests will not be executed immediately, but queued in
@@ -422,29 +327,11 @@ main (int argc, char **argv)
   *  The notifications from kernel will show originating PID equal
   *  to that after daemon() completes (if ever called).
   */
-  vty_read_config (config_file, config_default);
+  frr_config_fork();
 
-  /* Don't start execution if we are in dry-run mode */
-  if (dryrun)
-    return(0);
-  
-  /* Clean up rib. */
+  /* Clean up rib -- before fork (?) */
   /* rib_weed_tables (); */
 
-  /* Exit when zebra is working in batch mode. */
-  if (batch_mode)
-    exit (0);
-
-  /* Daemonize. */
-  if (daemon_mode && daemon (0, 0) < 0)
-    {
-      zlog_err("Zebra daemon failed: %s", strerror(errno));
-      exit (1);
-    }
-
-  /* Output pid of zebra. */
-  pid_output (pid_file);
-
   /* After we have successfully acquired the pidfile, we can be sure
   *  about being the only copy of zebra process, which is submitting
   *  changes to the FIB.
@@ -462,14 +349,10 @@ main (int argc, char **argv)
   /* This must be done only after locking pidfile (bug #403). */
   zebra_zserv_socket_init (zserv_path);
 
-  /* Make vty server socket. */
-  vty_serv_sock (vty_addr, vty_port, ZEBRA_VTYSH_PATH);
-
-  /* Print banner. */
-  zlog_notice ("Zebra %s starting: vty@%d", QUAGGA_VERSION, vty_port);
+  /* Init label manager */
+  label_manager_init (lblmgr_path);
 
-  while (thread_fetch (zebrad.master, &thread))
-    thread_call (&thread);
+  frr_run (zebrad.master);
 
   /* Not reached... */
   return 0;