summaryrefslogtreecommitdiff
path: root/babeld/babel_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'babeld/babel_main.c')
-rw-r--r--babeld/babel_main.c533
1 files changed, 0 insertions, 533 deletions
diff --git a/babeld/babel_main.c b/babeld/babel_main.c
deleted file mode 100644
index 21b2513d70..0000000000
--- a/babeld/babel_main.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * 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
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-/* include zebra library */
-#include <zebra.h>
-#include "getopt.h"
-#include "if.h"
-#include "log.h"
-#include "thread.h"
-#include "privs.h"
-#include "sigevent.h"
-#include "version.h"
-#include "command.h"
-#include "vty.h"
-#include "memory.h"
-#include "systemd.h"
-
-#include "babel_main.h"
-#include "babeld.h"
-#include "util.h"
-#include "kernel.h"
-#include "babel_interface.h"
-#include "neighbour.h"
-#include "route.h"
-#include "xroute.h"
-#include "message.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);
-
-
-struct thread_master *master; /* quagga's threads handler */
-struct timeval babel_now; /* current time */
-
-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] =
- {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
-
-static const char *state_file = DAEMON_VTY_DIR "/babel-state";
-
-unsigned char protocol_group[16]; /* babel's link-local multicast address */
-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 =
-{
-#if defined(QUAGGA_USER)
- .user = QUAGGA_USER,
-#endif
-#if defined QUAGGA_GROUP
- .group = QUAGGA_GROUP,
-#endif
-#ifdef VTY_GROUP
- .vty_group = VTY_GROUP,
-#endif
- .caps_p = _caps_p,
- .cap_num_p = 2,
- .cap_num_i = 0
-};
-
-
-int
-main(int argc, char **argv)
-{
- struct thread thread;
- /* and print banner too */
- babel_init(argc, argv);
- while (thread_fetch (master, &thread)) {
- thread_call (&thread);
- }
- return 0;
-}
-
-static void
-babel_usage (char *progname, int status)
-{
- 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);
-}
-
-/* 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;
-
- /* Set umask before anything for security */
- umask (0027);
- progname = babel_get_progname(argv[0]);
-
- /* set default log (lib/log.h) */
- zlog_default = openzlog(progname, ZLOG_BABEL, 0,
- 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);
-
- babel_init_random();
-
- /* set the Babel's default link-local multicast address and Babel's port */
- parse_address("ff02:0:0:0:0:0:1:6", protocol_group, NULL);
- protocol_port = 6696;
-
- /* 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;
- }
- }
-
- /* create the threads handler */
- master = thread_master_create ();
-
- /* Library inits. */
- zprivs_init (&babeld_privs);
- babel_init_signals();
- cmd_init (1);
- vty_init (master);
- memory_init ();
-
- resend_delay = BABEL_DEFAULT_RESEND_DELAY;
-
- 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);
- };
-
- systemd_send_started (master);
- /* 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(master);
-
- /* 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)
- babel_fail();
-
- schedule_neighbours_check(5000, 1);
-
- zlog_notice ("BABELd %s starting: vty@%d", BABEL_VERSION, babel_vty_port);
-}
-
-/* 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);
-}
-
-static void
-babel_fail(void)
-{
- systemd_send_stopping ();
- exit(1);
-}
-
-/* initialize random value, and set 'babel_now' by the way. */
-static void
-babel_init_random(void)
-{
- gettime(&babel_now);
- int rc;
- unsigned int seed;
-
- rc = read_random_bytes(&seed, sizeof(seed));
- if(rc < 0) {
- zlog_err("read(random): %s", safe_strerror(errno));
- seed = 42;
- }
-
- seed ^= (babel_now.tv_sec ^ babel_now.tv_usec);
- srandom(seed);
-}
-
-/*
- close fd, and replace it by "/dev/null"
- exit if error
- */
-static void
-babel_replace_by_null(int fd)
-{
- int fd_null;
- int rc;
-
- fd_null = open("/dev/null", O_RDONLY);
- if(fd_null < 0) {
- zlog_err("open(null): %s", safe_strerror(errno));
- exit(1);
- }
-
- rc = dup2(fd_null, fd);
- if(rc < 0) {
- zlog_err("dup2(null, 0): %s", safe_strerror(errno));
- exit(1);
- }
-
- close(fd_null);
-}
-
-/*
- Load the state file: check last babeld's running state, usefull in case of
- "/etc/init.d/babeld restart"
- */
-void
-babel_load_state_file(void)
-{
- int fd;
- int rc;
-
- fd = open(state_file, O_RDONLY);
- if(fd < 0 && errno != ENOENT)
- zlog_err("open(babel-state: %s)", safe_strerror(errno));
- rc = unlink(state_file);
- 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;
- }
- if(fd >= 0) {
- char buf[100];
- char buf2[100];
- int s;
- long t;
- rc = read(fd, buf, 99);
- if(rc < 0) {
- zlog_err("read(babel-state): %s", safe_strerror(errno));
- } else {
- buf[rc] = '\0';
- rc = sscanf(buf, "%99s %d %ld\n", buf2, &s, &t);
- if(rc == 3 && s >= 0 && s <= 0xFFFF) {
- unsigned char sid[8];
- rc = parse_eui64(buf2, sid);
- if(rc < 0) {
- zlog_err("Couldn't parse babel-state.");
- } else {
- struct timeval realnow;
- debugf(BABEL_DEBUG_COMMON,
- "Got %s %d %ld from babel-state.",
- format_eui64(sid), s, t);
- gettimeofday(&realnow, NULL);
- if(memcmp(sid, myid, 8) == 0)
- myseqno = seqno_plus(s, 1);
- else
- zlog_err("ID mismatch in babel-state. id=%s; old=%s",
- format_eui64(myid),
- format_eui64(sid));
- }
- } else {
- zlog_err("Couldn't parse babel-state.");
- }
- }
- close(fd);
- fd = -1;
- }
-}
-
-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, array_size(babel_signals), babel_signals);
-}
-
-static void
-babel_exit_properly(void)
-{
- debugf(BABEL_DEBUG_COMMON, "Exiting...");
- usleep(roughly(10000));
- gettime(&babel_now);
-
- /* Uninstall and flush all routes. */
- debugf(BABEL_DEBUG_COMMON, "Uninstall routes.");
- flush_all_routes();
- babel_interface_close_all();
- babel_zebra_close_connexion();
- babel_save_state_file();
- debugf(BABEL_DEBUG_COMMON, "Remove pid file.");
- if(pidfile)
- unlink(pidfile);
- debugf(BABEL_DEBUG_COMMON, "Done.");
-
- systemd_send_stopping ();
- exit(0);
-}
-
-static void
-babel_save_state_file(void)
-{
- int fd;
- int rc;
-
- debugf(BABEL_DEBUG_COMMON, "Save state file.");
- fd = open(state_file, O_WRONLY | O_TRUNC | O_CREAT, 0644);
- if(fd < 0) {
- zlog_err("creat(babel-state): %s", safe_strerror(errno));
- unlink(state_file);
- } else {
- struct timeval realnow;
- char buf[100];
- gettimeofday(&realnow, NULL);
- rc = snprintf(buf, 100, "%s %d %ld\n",
- format_eui64(myid), (int)myseqno,
- (long)realnow.tv_sec);
- if(rc < 0 || rc >= 100) {
- zlog_err("write(babel-state): overflow.");
- unlink(state_file);
- } else {
- rc = write(fd, buf, rc);
- if(rc < 0) {
- zlog_err("write(babel-state): %s", safe_strerror(errno));
- unlink(state_file);
- }
- fsync(fd);
- }
- close(fd);
- }
-}
-
-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,
- 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);
-}