2017-01-19 16:27:01 +01:00
|
|
|
/* NHRP daemon main functions
|
|
|
|
* Copyright (c) 2014-2015 Timo Teräs
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include "zebra.h"
|
|
|
|
#include "privs.h"
|
|
|
|
#include "getopt.h"
|
|
|
|
#include "thread.h"
|
|
|
|
#include "sigevent.h"
|
|
|
|
#include "version.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "memory.h"
|
2017-02-11 21:29:57 +01:00
|
|
|
#include "memory_vty.h"
|
2017-01-19 16:27:01 +01:00
|
|
|
#include "command.h"
|
|
|
|
|
|
|
|
#include "nhrpd.h"
|
|
|
|
#include "netlink.h"
|
|
|
|
|
2017-02-11 21:29:57 +01:00
|
|
|
DEFINE_MGROUP(NHRPD, "NHRP")
|
|
|
|
|
2017-01-19 16:27:01 +01:00
|
|
|
unsigned int debug_flags = 0;
|
|
|
|
|
|
|
|
struct thread_master *master;
|
|
|
|
struct timeval current_time;
|
|
|
|
static const char *pid_file = PATH_NHRPD_PID;
|
|
|
|
static char config_default[] = SYSCONFDIR NHRP_DEFAULT_CONFIG;
|
|
|
|
static char *config_file = NULL;
|
|
|
|
static char *vty_addr = NULL;
|
|
|
|
static int vty_port = NHRP_VTY_PORT;
|
|
|
|
static int do_daemonise = 0;
|
|
|
|
|
|
|
|
/* nhrpd 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 }
|
|
|
|
};
|
|
|
|
|
|
|
|
/* nhrpd privileges */
|
|
|
|
static zebra_capabilities_t _caps_p [] = {
|
|
|
|
ZCAP_NET_RAW,
|
|
|
|
ZCAP_NET_ADMIN,
|
|
|
|
ZCAP_DAC_OVERRIDE, /* for now needed to write to /proc/sys/net/ipv4/<if>/send_redirect */
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct zebra_privs_t nhrpd_privs = {
|
|
|
|
#ifdef QUAGGA_USER
|
|
|
|
.user = QUAGGA_USER,
|
|
|
|
#endif
|
|
|
|
#ifdef QUAGGA_GROUP
|
|
|
|
.group = QUAGGA_GROUP,
|
|
|
|
#endif
|
|
|
|
#ifdef VTY_GROUP
|
|
|
|
.vty_group = VTY_GROUP,
|
|
|
|
#endif
|
|
|
|
.caps_p = _caps_p,
|
|
|
|
.cap_num_p = ZEBRA_NUM_OF(_caps_p),
|
|
|
|
};
|
|
|
|
|
|
|
|
static void usage(const 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 NHRP 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\
|
2017-02-11 21:29:57 +01:00
|
|
|
Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
|
2017-01-19 16:27:01 +01:00
|
|
|
|
|
|
|
exit(status);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void parse_arguments(const char *progname, int argc, char **argv)
|
|
|
|
{
|
|
|
|
int opt;
|
|
|
|
|
|
|
|
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':
|
|
|
|
config_file = optarg;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
pid_file = optarg;
|
|
|
|
break;
|
|
|
|
case 'z':
|
|
|
|
zclient_serv_path_set(optarg);
|
|
|
|
break;
|
|
|
|
case 'A':
|
|
|
|
vty_addr = optarg;
|
|
|
|
break;
|
|
|
|
case 'P':
|
|
|
|
vty_port = atoi (optarg);
|
|
|
|
if (vty_port <= 0 || vty_port > 0xffff)
|
|
|
|
vty_port = NHRP_VTY_PORT;
|
|
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
nhrpd_privs.user = optarg;
|
|
|
|
break;
|
|
|
|
case 'g':
|
|
|
|
nhrpd_privs.group = optarg;
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
print_version(progname);
|
|
|
|
exit(0);
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
usage(progname, 0);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
usage(progname, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void nhrp_sigusr1(void)
|
|
|
|
{
|
|
|
|
zlog_rotate(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void nhrp_request_stop(void)
|
|
|
|
{
|
|
|
|
debugf(NHRP_DEBUG_COMMON, "Exiting...");
|
|
|
|
|
|
|
|
nhrp_shortcut_terminate();
|
|
|
|
nhrp_nhs_terminate();
|
|
|
|
nhrp_zebra_terminate();
|
|
|
|
vici_terminate();
|
|
|
|
evmgr_terminate();
|
|
|
|
nhrp_vc_terminate();
|
|
|
|
vrf_terminate();
|
|
|
|
/* memory_terminate(); */
|
|
|
|
/* vty_terminate(); */
|
|
|
|
cmd_terminate();
|
|
|
|
/* signal_terminate(); */
|
|
|
|
zprivs_terminate(&nhrpd_privs);
|
|
|
|
|
|
|
|
debugf(NHRP_DEBUG_COMMON, "Remove pid file.");
|
|
|
|
if (pid_file) unlink(pid_file);
|
|
|
|
debugf(NHRP_DEBUG_COMMON, "Done.");
|
|
|
|
|
|
|
|
closezlog(zlog_default);
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct quagga_signal_t sighandlers[] = {
|
|
|
|
{ .signal = SIGUSR1, .handler = &nhrp_sigusr1, },
|
|
|
|
{ .signal = SIGINT, .handler = &nhrp_request_stop, },
|
|
|
|
{ .signal = SIGTERM, .handler = &nhrp_request_stop, },
|
|
|
|
};
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
struct thread thread;
|
2017-02-11 21:29:57 +01:00
|
|
|
const char *progname, *p;
|
2017-01-19 16:27:01 +01:00
|
|
|
|
|
|
|
/* Set umask before anything for security */
|
|
|
|
umask(0027);
|
2017-02-11 21:29:57 +01:00
|
|
|
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
|
|
|
zlog_default = openzlog(progname, ZLOG_NHRP, 0, LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
2017-01-19 16:27:01 +01:00
|
|
|
zlog_set_level(NULL, ZLOG_DEST_STDOUT, LOG_WARNING);
|
|
|
|
|
|
|
|
parse_arguments(progname, argc, argv);
|
|
|
|
|
|
|
|
/* Library inits. */
|
|
|
|
master = thread_master_create();
|
|
|
|
zprivs_init(&nhrpd_privs);
|
|
|
|
signal_init(master, array_size(sighandlers), sighandlers);
|
|
|
|
cmd_init(1);
|
|
|
|
vty_init(master);
|
|
|
|
memory_init();
|
|
|
|
nhrp_interface_init();
|
|
|
|
vrf_init();
|
|
|
|
resolver_init();
|
|
|
|
|
|
|
|
/* Run with elevated capabilities, as for all netlink activity
|
|
|
|
* we need privileges anyway. */
|
|
|
|
nhrpd_privs.change(ZPRIVS_RAISE);
|
|
|
|
|
|
|
|
netlink_init();
|
|
|
|
evmgr_init();
|
|
|
|
nhrp_vc_init();
|
|
|
|
nhrp_packet_init();
|
|
|
|
vici_init();
|
|
|
|
nhrp_zebra_init();
|
|
|
|
nhrp_shortcut_init();
|
|
|
|
|
|
|
|
nhrp_config_init();
|
|
|
|
|
|
|
|
/* Get zebra configuration file. */
|
|
|
|
zlog_set_level(NULL, ZLOG_DEST_STDOUT, do_daemonise ? ZLOG_DISABLED : LOG_DEBUG);
|
|
|
|
vty_read_config(config_file, config_default);
|
|
|
|
|
|
|
|
if (do_daemonise && daemon(0, 0) < 0) {
|
|
|
|
zlog_err("daemonise: %s", safe_strerror(errno));
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* write pid file */
|
|
|
|
if (pid_output(pid_file) < 0) {
|
|
|
|
zlog_err("error while writing pidfile");
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create VTY socket */
|
|
|
|
vty_serv_sock(vty_addr, vty_port, NHRP_VTYSH_PATH);
|
|
|
|
zlog_notice("nhrpd starting: vty@%d", vty_port);
|
|
|
|
|
|
|
|
/* Main loop */
|
|
|
|
while (thread_fetch(master, &thread))
|
|
|
|
thread_call(&thread);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|