]> git.proxmox.com Git - mirror_frr.git/blobdiff - babeld/babel_main.c
Merge branch 'master' into bfd-final
[mirror_frr.git] / babeld / babel_main.c
index 2f3b5552e5df4451c96a931a4422c4210f25780e..2b87bed0fb886b4b738473d4e84365f47749983b 100644 (file)
@@ -1,21 +1,4 @@
-/*  
- *  This file is free software: you may copy, redistribute and/or modify it  
- *  under the terms of the GNU General Public License as published by the  
- *  Free Software Foundation, either version 2 of the License, or (at your  
- *  option) any later version.  
- *  
- *  This file is distributed in the hope that it will be useful, but  
- *  WITHOUT ANY WARRANTY; without even the implied warranty of  
- *  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 this program.  If not, see <http://www.gnu.org/licenses/>.  
- *  
- * This file incorporates work covered by the following copyright and  
- * permission notice:  
- *  
-
+/*
 Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -49,6 +32,7 @@ THE SOFTWARE.
 #include "command.h"
 #include "vty.h"
 #include "memory.h"
+#include "libfrr.h"
 
 #include "babel_main.h"
 #include "babeld.h"
@@ -62,13 +46,9 @@ THE SOFTWARE.
 #include "resend.h"
 #include "babel_zebra.h"
 
-
-static void babel_init (int argc, char **argv);
-static char *babel_get_progname(char *argv_0);
 static void babel_fail(void);
 static void babel_init_random(void);
 static void babel_replace_by_null(int fd);
-static void babel_init_signals(void);
 static void babel_exit_properly(void);
 static void babel_save_state_file(void);
 
@@ -80,7 +60,6 @@ unsigned char myid[8];            /* unique id (mac address of an interface) */
 int debug = 0;
 
 int resend_delay = -1;
-static const char *pidfile = PATH_BABELD_PID;
 
 const unsigned char zeroes[16] = {0};
 const unsigned char ones[16] =
@@ -94,104 +73,85 @@ int protocol_port;                /* babel's port */
 int protocol_socket = -1;         /* socket: communicate with others babeld */
 
 static char babel_config_default[] = SYSCONFDIR BABEL_DEFAULT_CONFIG;
-static char *babel_config_file = NULL;
 static char *babel_vty_addr = NULL;
 static int babel_vty_port = BABEL_VTY_PORT;
 
-/* Babeld options. */
-struct option longopts[] =
-{
-    { "daemon",      no_argument,       NULL, 'd'},
-    { "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'},
-    { "user",        required_argument, NULL, 'u'},
-    { "group",       required_argument, NULL, 'g'},
-    { "version",     no_argument,       NULL, 'v'},
-    { 0 }
-};
-
 /* babeld privileges */
 static zebra_capabilities_t _caps_p [] =
 {
     ZCAP_NET_RAW,
     ZCAP_BIND
 };
-static struct zebra_privs_t babeld_privs =
+
+struct zebra_privs_t babeld_privs =
 {
-#if defined(QUAGGA_USER)
-    .user = QUAGGA_USER,
+#if defined(FRR_USER)
+    .user = FRR_USER,
 #endif
-#if defined QUAGGA_GROUP
-    .group = QUAGGA_GROUP,
+#if defined FRR_GROUP
+    .group = FRR_GROUP,
 #endif
 #ifdef VTY_GROUP
     .vty_group = VTY_GROUP,
 #endif
     .caps_p = _caps_p,
-    .cap_num_p = 2,
+    .cap_num_p = array_size(_caps_p),
     .cap_num_i = 0
 };
 
-
-int
-main(int argc, char **argv)
+static void
+babel_sigexit(void)
 {
-    struct thread thread;
-    /* and print banner too */
-    babel_init(argc, argv);
-    while (thread_fetch (master, &thread)) {
-        thread_call (&thread);
-    }
-    return 0;
+    zlog_notice("Terminating on signal");
+
+    babel_exit_properly();
 }
 
 static void
-babel_usage (char *progname, int status)
+babel_sigusr1 (void)
 {
-  if (status != 0)
-    fprintf (stderr, "Try `%s --help' for more information.\n", progname);
-  else
-    {
-      printf ("Usage : %s [OPTION...]\n\
-Daemon which manages Babel routing protocol.\n\n\
--d, --daemon       Runs in daemon mode\n\
--f, --config_file  Set configuration file name\n\
--i, --pid_file     Set process identifier file name\n\
--z, --socket       Set path of zebra socket\n\
--A, --vty_addr     Set vty's bind address\n\
--P, --vty_port     Set vty's port number\n\
--u, --user         User to run as\n\
--g, --group        Group to run as\n\
--v, --version      Print program version\n\
--h, --help         Display this help and exit\n\
-\n\
-Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
-    }
-  exit (status);
+    zlog_rotate ();
 }
 
-/* make initialisations witch don't need infos about kernel(interfaces, etc.) */
-static void
-babel_init(int argc, char **argv)
-{
-    int rc, opt;
-    int do_daemonise = 0;
-    char *progname = NULL;
+static struct quagga_signal_t babel_signals[] =
+  {
+    {
+      .signal = SIGUSR1,
+      .handler = &babel_sigusr1,
+    },
+    {
+      .signal = SIGINT,
+      .handler = &babel_sigexit,
+    },
+    {
+      .signal = SIGTERM,
+      .handler = &babel_sigexit,
+    },
+  };
 
-    /* Set umask before anything for security */
-    umask (0027);
-    progname = babel_get_progname(argv[0]);
+struct option longopts[] =
+  {
+    { 0 }
+  };
+
+FRR_DAEMON_INFO(babeld, BABELD,
+               .vty_port = BABEL_VTY_PORT,
+               .proghelp = "Implementation of the BABEL routing protocol.",
+
+               .signals = babel_signals,
+               .n_signals = array_size(babel_signals),
 
-    /* set default log (lib/log.h) */
-    zlog_default = openzlog(progname, ZLOG_BABEL,
-                            LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
-    /* set log destination as stdout until the config file is read */
-    zlog_set_level(NULL, ZLOG_DEST_STDOUT, LOG_WARNING);
+               .privs = &babeld_privs,
+               )
 
+int
+main(int argc, char **argv)
+{
+    int rc;
+
+    frr_preinit (&babeld_di, argc, argv);
+    frr_opt_add ("", longopts, "");
+  
     babel_init_random();
 
     /* set the Babel's default link-local multicast address and Babel's port */
@@ -200,93 +160,42 @@ babel_init(int argc, char **argv)
 
     /* get options */
     while(1) {
-        opt = getopt_long(argc, argv, "df:i:z:hA:P:u:g:v", longopts, 0);
-        if(opt < 0)
-            break;
-
-        switch(opt) {
-            case 0:
-                break;
-            case 'd':
-                do_daemonise = -1;
-                break;
-            case 'f':
-                babel_config_file = optarg;
-                break;
-            case 'i':
-                pidfile = optarg;
-                break;
-            case 'z':
-                zclient_serv_path_set (optarg);
-                break;
-            case 'A':
-                babel_vty_addr = optarg;
-                break;
-            case 'P':
-                babel_vty_port = atoi (optarg);
-                if (babel_vty_port <= 0 || babel_vty_port > 0xffff)
-                    babel_vty_port = BABEL_VTY_PORT;
-                break;
-            case 'u':
-                babeld_privs.user = optarg;
-                break;
-            case 'g':
-                babeld_privs.group = optarg;
-                break;
-            case 'v':
-                print_version (progname);
-                exit (0);
-                break;
-            case 'h':
-                babel_usage (progname, 0);
-                break;
-            default:
-                babel_usage (progname, 1);
-                break;
-        }
+        int opt;
+
+       opt = frr_getopt (argc, argv, NULL);
+
+       if (opt == EOF)
+         break;
+
+       switch (opt)
+         {
+         case 0:
+           break;
+         default:
+           frr_help_exit (1);
+           break;
+         }
     }
 
     /* create the threads handler */
-    master = thread_master_create ();
+    master = frr_init ();
 
     /* Library inits. */
     zprivs_init (&babeld_privs);
-    babel_init_signals();
     cmd_init (1);
     vty_init (master);
-    memory_init ();
 
     resend_delay = BABEL_DEFAULT_RESEND_DELAY;
+    change_smoothing_half_life(BABEL_DEFAULT_SMOOTHING_HALF_LIFE);
 
     babel_replace_by_null(STDIN_FILENO);
 
-    if (do_daemonise && daemonise() < 0) {
-        zlog_err("daemonise: %s", safe_strerror(errno));
-        exit (1);
-    }
-
-    /* write pid file */
-    if (pid_output(pidfile) < 0) {
-        zlog_err("error while writing pidfile");
-        exit (1);
-    };
-
     /* init some quagga's dependencies, and babeld's commands */
     babeld_quagga_init();
     /* init zebra client's structure and it's commands */
     /* this replace kernel_setup && kernel_setup_socket */
     babelz_zebra_init ();
 
-    /* Sort all installed commands. */
-    sort_node ();
-
-    /* Get zebra configuration file. */
-    zlog_set_level (NULL, ZLOG_DEST_STDOUT, ZLOG_DISABLED);
-    vty_read_config (babel_config_file, babel_config_default);
-
-    /* Create VTY socket */
-    vty_serv_sock (babel_vty_addr, babel_vty_port, BABEL_VTYSH_PATH);
-
     /* init buffer */
     rc = resize_receive_buffer(1500);
     if(rc < 0)
@@ -294,14 +203,10 @@ babel_init(int argc, char **argv)
 
     schedule_neighbours_check(5000, 1);
 
-    zlog_notice ("BABELd %s starting: vty@%d", BABEL_VERSION, babel_vty_port);
-}
+    frr_config_fork();
+    frr_run(master);
 
-/* return the progname (without path, example: "./x/progname" --> "progname") */
-static char *
-babel_get_progname(char *argv_0) {
-    char *p = strrchr (argv_0, '/');
-    return (p ? ++p : argv_0);
+    return 0;
 }
 
 static void
@@ -370,8 +275,7 @@ babel_load_state_file(void)
     if(fd >= 0 && rc < 0) {
         zlog_err("unlink(babel-state): %s", safe_strerror(errno));
         /* If we couldn't unlink it, it's probably stale. */
-        close(fd);
-        fd = -1;
+        goto fini;
     }
     if(fd >= 0) {
         char buf[100];
@@ -406,45 +310,12 @@ babel_load_state_file(void)
                 zlog_err("Couldn't parse babel-state.");
             }
         }
-        close(fd);
-        fd = -1;
+        goto fini;
     }
-}
-
-static void
-babel_sigexit(void)
-{
-    zlog_notice("Terminating on signal");
-
-    babel_exit_properly();
-}
-
-static void
-babel_sigusr1 (void)
-{
-    zlog_rotate (NULL);
-}
-
-static void
-babel_init_signals(void)
-{
-    static struct quagga_signal_t babel_signals[] =
-    {
-        {
-            .signal = SIGUSR1,
-            .handler = &babel_sigusr1,
-        },
-        {
-            .signal = SIGINT,
-            .handler = &babel_sigexit,
-        },
-        {
-            .signal = SIGTERM,
-            .handler = &babel_sigexit,
-        },
-    };
-
-    signal_init (master, Q_SIGC(babel_signals), babel_signals);
+fini:
+    if (fd >= 0)
+        close(fd);
+    return ;
 }
 
 static void
@@ -461,9 +332,8 @@ babel_exit_properly(void)
     babel_zebra_close_connexion();
     babel_save_state_file();
     debugf(BABEL_DEBUG_COMMON, "Remove pid file.");
-    if(pidfile)
-        unlink(pidfile);
     debugf(BABEL_DEBUG_COMMON, "Done.");
+    frr_fini();
 
     exit(0);
 }
@@ -504,29 +374,22 @@ babel_save_state_file(void)
 void
 show_babel_main_configuration (struct vty *vty)
 {
-    vty_out(vty,
-            "pid file                = %s%s"
-            "state file              = %s%s"
-            "configuration file      = %s%s"
-            "protocol informations:%s"
-            "  multicast address     = %s%s"
-            "  port                  = %d%s"
-            "vty address             = %s%s"
-            "vty port                = %d%s"
-            "id                      = %s%s"
-            "allow_duplicates        = %s%s"
-            "kernel_metric           = %d%s",
-            pidfile, VTY_NEWLINE,
-            state_file, VTY_NEWLINE,
-            babel_config_file ? babel_config_file : babel_config_default,
-            VTY_NEWLINE,
-            VTY_NEWLINE,
-            format_address(protocol_group), VTY_NEWLINE,
-            protocol_port, VTY_NEWLINE,
+    vty_out (vty,
+            "state file              = %s\n"
+            "configuration file      = %s\n"
+            "protocol informations:\n"
+            "  multicast address     = %s\n"
+            "  port                  = %d\n"
+            "vty address             = %s\n"
+            "vty port                = %d\n"
+            "id                      = %s\n"
+            "kernel_metric           = %d\n",
+            state_file,
+            babeld_di.config_file ? babeld_di.config_file : babel_config_default,
+            format_address(protocol_group),
+            protocol_port,
             babel_vty_addr ? babel_vty_addr : "None",
-            VTY_NEWLINE,
-            babel_vty_port, VTY_NEWLINE,
-            format_eui64(myid), VTY_NEWLINE,
-            format_bool(allow_duplicates), VTY_NEWLINE,
-            kernel_metric, VTY_NEWLINE);
+            babel_vty_port,
+            format_eui64(myid),
+            kernel_metric);
 }