-/*
- * 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
#include "command.h"
#include "vty.h"
#include "memory.h"
+#include "libfrr.h"
#include "babel_main.h"
#include "babeld.h"
#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);
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] =
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 */
/* 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)
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
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];
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
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);
}
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);
}