bird/sysdep/unix/main.c
Martin Mares 7e5f5ffdda Moved to a much more systematic way of configuring kernel protocols.
o  Nothing is configured automatically. You _need_ to specify
     the kernel syncer in config file in order to get it started.
  o  Syncing has been split to route syncer (protocol "Kernel") and
     interface syncer (protocol "Device"), device routes are generated
     by protocol "Direct" (now can exist in multiple instances, so that
     it will be possible to feed different device routes to different
     routing tables once multiple tables get supported).

See doc/bird.conf.example for a living example of these shiny features.
1999-03-26 21:44:38 +00:00

223 lines
3.5 KiB
C

/*
* BIRD Internet Routing Daemon -- Unix Entry Point
*
* (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/signal.h>
#include "nest/bird.h"
#include "lib/lists.h"
#include "lib/resource.h"
#include "lib/socket.h"
#include "lib/event.h"
#include "nest/route.h"
#include "nest/protocol.h"
#include "nest/iface.h"
#include "conf/conf.h"
#include "filter/filter.h"
#include "unix.h"
#include "krt.h"
int shutting_down;
/*
* Debugging
*/
void
async_dump(void)
{
debug("INTERNAL STATE DUMP\n\n");
sk_dump_all();
tm_dump_all();
if_dump_all();
neigh_dump_all();
rta_dump_all();
rt_dump_all();
protos_dump_all();
debug("\n");
}
/*
* Reading the Configuration
*/
static int conf_fd;
static char *config_name = PATH_CONFIG;
static int
cf_read(byte *dest, unsigned int len)
{
int l = read(conf_fd, dest, len);
if (l < 0)
cf_error("Read error");
return l;
}
static void
read_config(void)
{
struct config *conf = config_alloc(config_name);
conf_fd = open(config_name, O_RDONLY);
if (conf_fd < 0)
die("Unable to open configuration file %s: %m", config_name);
cf_read_hook = cf_read;
if (!config_parse(conf))
die("%s, line %d: %s", config_name, conf->err_lino, conf->err_msg);
config_commit(conf);
}
void
async_config(void)
{
debug("Asynchronous reconfigurations are not supported in demo version\n");
}
/*
* Shutdown
*/
void
async_shutdown(void)
{
debug("Shutting down...\n");
shutting_down = 1;
protos_shutdown();
}
void
protos_shutdown_notify(void)
{
die("System shutdown completed");
}
/*
* Signals
*/
static void
handle_sighup(int sig)
{
debug("Caught SIGHUP...\n");
async_config_flag = 1;
}
static void
handle_sigusr(int sig)
{
debug("Caught SIGUSR...\n");
async_dump_flag = 1;
}
static void
handle_sigterm(int sig)
{
debug("Caught SIGTERM...\n");
async_shutdown_flag = 1;
}
static void
signal_init(void)
{
struct sigaction sa;
bzero(&sa, sizeof(sa));
sa.sa_handler = handle_sigusr;
sa.sa_flags = SA_RESTART;
sigaction(SIGUSR1, &sa, NULL);
sa.sa_handler = handle_sighup;
sa.sa_flags = SA_RESTART;
sigaction(SIGHUP, &sa, NULL);
sa.sa_handler = handle_sigterm;
sa.sa_flags = SA_RESTART;
sigaction(SIGTERM, &sa, NULL);
signal(SIGPIPE, SIG_IGN);
}
/*
* Parsing of command-line arguments
*/
static char *opt_list = "c:d:";
static void
usage(void)
{
fprintf(stderr, "Usage: bird [-c <config-file>] [-d <debug-file>]\n");
exit(1);
}
static void
parse_args(int argc, char **argv)
{
int c;
while ((c = getopt(argc, argv, opt_list)) >= 0)
switch (c)
{
case 'c':
config_name = optarg;
break;
case 'd':
log_init_debug(optarg);
break;
default:
usage();
}
if (optind < argc)
usage();
}
/*
* Hic Est main()
*/
int
main(int argc, char **argv)
{
#ifdef HAVE_LIBDMALLOC
if (!getenv("DMALLOC_OPTIONS"))
dmalloc_debug(0x2f03d00);
#endif
log_init_debug(NULL);
parse_args(argc, argv);
log(L_INFO "Launching BIRD 0.0.0...");
debug("Initializing.\n");
resource_init();
io_init();
rt_init();
if_init();
protos_build();
add_tail(&protocol_list, &proto_unix_kernel.n);
add_tail(&protocol_list, &proto_unix_iface.n);
read_config();
signal_init();
protos_start();
ev_run_list(&global_event_list);
async_dump();
debug("Entering I/O loop.\n");
io_loop();
bug("I/O loop died");
}