summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_main.c164
-rw-r--r--bgpd/bgpd.c4
-rw-r--r--bgpd/bgpd.h2
-rw-r--r--isisd/isis_main.c128
-rw-r--r--ldpd/ldpd.c127
-rw-r--r--lib/Makefile.am5
-rw-r--r--lib/command.c1
-rw-r--r--lib/libfrr.c262
-rw-r--r--lib/libfrr.h80
-rw-r--r--lib/sockopt.c23
-rw-r--r--lib/sockopt.h4
-rw-r--r--nhrpd/nhrp_main.c93
-rw-r--r--ospf6d/ospf6_main.c131
-rw-r--r--ospfd/ospf_main.c135
-rw-r--r--ospfd/ospfd.c4
-rw-r--r--ospfd/ospfd.h2
-rw-r--r--pimd/pim_main.c101
-rw-r--r--pimd/pim_signals.c8
-rw-r--r--pimd/pim_signals.h3
-rw-r--r--pimd/pimd.c2
-rw-r--r--ripd/rip_main.c125
-rw-r--r--ripd/ripd.c3
-rw-r--r--ripngd/ripng_main.c126
-rw-r--r--ripngd/ripngd.c3
-rw-r--r--tests/bgpd/test_aspath.c2
-rw-r--r--tests/bgpd/test_capability.c2
-rw-r--r--tests/bgpd/test_mp_attr.c2
-rw-r--r--tests/bgpd/test_mpath.c2
-rw-r--r--watchfrr/watchfrr.c150
-rw-r--r--zebra/main.c151
30 files changed, 727 insertions, 1118 deletions
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 2598d66656..26605be547 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -39,7 +39,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "queue.h"
#include "vrf.h"
#include "bfd.h"
-#include "sockopt.h"
+#include "libfrr.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
@@ -60,7 +60,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#endif
/* bgpd options, we use GNU getopt library. */
-#define OPTION_VTYSOCK 1000
static const struct option longopts[] =
{
{ "daemon", no_argument, NULL, 'd'},
@@ -69,18 +68,10 @@ static const struct option longopts[] =
{ "socket", required_argument, NULL, 'z'},
{ "bgp_port", required_argument, NULL, 'p'},
{ "listenon", required_argument, NULL, 'l'},
- { "vty_addr", required_argument, NULL, 'A'},
- { "vty_port", required_argument, NULL, 'P'},
- { "vty_socket", required_argument, NULL, OPTION_VTYSOCK },
{ "retain", no_argument, NULL, 'r'},
{ "no_kernel", no_argument, NULL, 'n'},
{ "ecmp", required_argument, NULL, 'e'},
- { "user", required_argument, NULL, 'u'},
- { "group", required_argument, NULL, 'g'},
- { "skip_runas", no_argument, NULL, 'S'},
- { "version", no_argument, NULL, 'v'},
{ "dryrun", no_argument, NULL, 'C'},
- { "help", no_argument, NULL, 'h'},
{ 0 }
};
@@ -115,9 +106,6 @@ static struct quagga_signal_t bgp_signals[] =
/* Configuration file and directory. */
char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
-/* VTY Socket prefix */
-char vty_sock_path[MAXPATHLEN] = BGP_VTYSH_PATH;
-
/* Route retain mode flag. */
static int retain_mode = 0;
@@ -127,11 +115,6 @@ char *config_file = NULL;
/* Process ID saved for use by init system */
static const char *pid_file = PATH_BGPD_PID;
-/* VTY port number and address. */
-int vty_port = BGP_VTY_PORT;
-char *vty_addr = NULL;
-char *vty_sock_name;
-
/* privileges */
static zebra_capabilities_t _caps_p [] =
{
@@ -154,42 +137,6 @@ struct zebra_privs_t bgpd_privs =
.cap_num_i = 0,
};
-/* Help information display. */
-static void
-usage (char *progname, int status)
-{
- if (status != 0)
- fprintf (stderr, "Try `%s --help' for more information.\n", progname);
- else
- {
- printf ("Usage : %s [OPTION...]\n\n\
-Daemon which manages kernel routing table management and \
-redistribution between different routing protocols.\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\
--p, --bgp_port Set bgp protocol's port number\n\
--l, --listenon Listen on specified address (implies -n)\n\
--A, --vty_addr Set vty's bind address\n\
--P, --vty_port Set vty's port number\n\
- --vty_socket Override vty socket path\n\
--r, --retain When program terminates, retain added route by bgpd.\n\
--n, --no_kernel Do not install route to kernel.\n\
--e, --ecmp Specify ECMP to use.\n\
--u, --user User to run as\n\
--g, --group Group to run as\n\
--S, --skip_runas Skip user and group run as\n\
--v, --version Print program version\n\
--C, --dryrun Check configuration for validity and exit\n\
--h, --help Display this help and exit\n\
-\n\
-Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
- }
-
- exit (status);
-}
-
/* SIGHUP handler. */
void
sighup (void)
@@ -204,9 +151,6 @@ sighup (void)
/* Reload config file. */
vty_read_config (config_file, config_default);
- /* Create VTY's socket */
- vty_serv_sock (vty_addr, vty_port, vty_sock_path);
-
/* Try to return to normal operation. */
}
@@ -219,8 +163,7 @@ sigint (void)
if (! retain_mode)
{
bgp_terminate ();
- if (bgpd_privs.user) /* NULL if skip_runas flag set */
- zprivs_terminate (&bgpd_privs);
+ zprivs_terminate (&bgpd_privs);
}
bgp_exit (0);
@@ -412,33 +355,48 @@ bgp_vrf_terminate (void)
vrf_terminate ();
}
+FRR_DAEMON_INFO(bgpd, BGP,
+ .vty_port = BGP_VTY_PORT,
+
+ .proghelp = "Implementation of the BGP routing protocol.",
+
+ .signals = bgp_signals,
+ .n_signals = array_size(bgp_signals),
+
+ .privs = &bgpd_privs,
+)
+
/* Main routine of bgpd. Treatment of argument and start bgp finite
state machine is handled at here. */
int
main (int argc, char **argv)
{
- char *p;
int opt;
int daemon_mode = 0;
int dryrun = 0;
- char *progname;
struct thread thread;
int tmp_port;
- int skip_runas = 0;
-
- /* Set umask before anything for security */
- umask (0027);
- /* Preserve name of myself. */
- progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
-
- /* BGP master init. */
- bgp_master_init ();
+ int bgp_port = BGP_PORT_DEFAULT;
+ char *bgp_address = NULL;
+
+ frr_preinit(&bgpd_di, argc, argv);
+ frr_opt_add("df:i:z:p:l:rnC", longopts,
+ " -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"
+ " -p, --bgp_port Set bgp protocol's port number\n"
+ " -l, --listenon Listen on specified address (implies -n)\n"
+ " -r, --retain When program terminates, retain added route by bgpd.\n"
+ " -n, --no_kernel Do not install route to kernel.\n"
+ " -e, --ecmp Specify ECMP to use.\n"
+ " -C, --dryrun Check configuration for validity and exit\n");
/* Command line argument treatment. */
- while (1)
+ while (1)
{
- opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vCS", longopts, 0);
+ opt = frr_getopt (argc, argv, 0);
if (opt == EOF)
break;
@@ -462,13 +420,10 @@ main (int argc, char **argv)
case 'p':
tmp_port = atoi (optarg);
if (tmp_port <= 0 || tmp_port > 0xffff)
- bm->port = BGP_PORT_DEFAULT;
+ bgp_port = BGP_PORT_DEFAULT;
else
bm->port = tmp_port;
break;
- case 'A':
- vty_addr = optarg;
- break;
case 'e':
multipath_num = atoi (optarg);
if (multipath_num > MULTIPATH_NUM || multipath_num <= 0)
@@ -477,69 +432,30 @@ main (int argc, char **argv)
return 1;
}
break;
- case 'P':
- /* Deal with atoi() returning 0 on failure, and bgpd not
- listening on bgp port... */
- if (strcmp(optarg, "0") == 0)
- {
- vty_port = 0;
- break;
- }
- vty_port = atoi (optarg);
- if (vty_port <= 0 || vty_port > 0xffff)
- vty_port = BGP_VTY_PORT;
- break;
- case OPTION_VTYSOCK:
- set_socket_path(vty_sock_path, BGP_VTYSH_PATH, optarg, sizeof (vty_sock_path));
- break;
case 'r':
retain_mode = 1;
break;
case 'l':
- bm->address = optarg;
+ bgp_address = optarg;
/* listenon implies -n */
case 'n':
bgp_option_set (BGP_OPT_NO_FIB);
break;
- case 'u':
- bgpd_privs.user = optarg;
- break;
- case 'g':
- bgpd_privs.group = optarg;
- break;
- case 'S': /* skip run as = override bgpd_privs */
- skip_runas = 1;
- break;
- case 'v':
- print_version (progname);
- exit (0);
- break;
case 'C':
dryrun = 1;
break;
- case 'h':
- usage (progname, 0);
- break;
default:
- usage (progname, 1);
+ frr_help_exit (1);
break;
}
}
- zlog_default = openzlog (progname, ZLOG_BGP, 0,
- LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
-
- if (skip_runas)
- memset (&bgpd_privs, 0, sizeof (bgpd_privs));
- zprivs_init (&bgpd_privs);
-
-#if defined(HAVE_CUMULUS)
- zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
-#endif
+ /* BGP master init. */
+ bgp_master_init (frr_init ());
+ bm->port = bgp_port;
+ bm->address = bgp_address;
/* Initializations. */
- srandom (time (NULL));
- signal_init (bm->master, array_size(bgp_signals), bgp_signals);
cmd_init (1);
vty_init (bm->master);
memory_init ();
@@ -567,11 +483,11 @@ main (int argc, char **argv)
pid_output (pid_file);
/* Make bgp vty socket. */
- vty_serv_sock (vty_addr, vty_port, vty_sock_path);
+ frr_vty_serv (BGP_VTYSH_PATH);
/* Print banner. */
- zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", FRR_COPYRIGHT,
- vty_port,
+ zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", FRR_VERSION,
+ bgpd_di.vty_port,
(bm->address ? bm->address : "<all>"),
bm->port);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 095f0fce6f..9d76b3d58b 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -7588,7 +7588,7 @@ bgp_config_write (struct vty *vty)
}
void
-bgp_master_init (void)
+bgp_master_init (struct thread_master *master)
{
qobj_init ();
@@ -7598,7 +7598,7 @@ bgp_master_init (void)
bm->bgp = list_new ();
bm->listen_sockets = list_new ();
bm->port = BGP_PORT_DEFAULT;
- bm->master = thread_master_create ();
+ bm->master = master;
bm->start_time = bgp_clock ();
bm->t_rmap_update = NULL;
bm->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER;
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 99d87d785c..9ccc0e39de 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -1218,7 +1218,7 @@ extern char *peer_uptime (time_t, char *, size_t, u_char, json_object *);
extern int bgp_config_write (struct vty *);
extern void bgp_config_write_family_header (struct vty *, afi_t, safi_t, int *);
-extern void bgp_master_init (void);
+extern void bgp_master_init (struct thread_master *master);
extern void bgp_init (void);
extern void bgp_route_map_init (void);
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index 1b9fa68051..453e77e10f 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -38,8 +38,8 @@
#include "plist.h"
#include "zclient.h"
#include "vrf.h"
-#include "sockopt.h"
#include "qobj.h"
+#include "libfrr.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
@@ -82,20 +82,12 @@ struct zebra_privs_t isisd_privs = {
};
/* isisd options */
-#define OPTION_VTYSOCK 1000
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'},
- {"vty_addr", required_argument, NULL, 'A'},
- {"vty_port", required_argument, NULL, 'P'},
- {"vty_socket", required_argument, NULL, OPTION_VTYSOCK},
- {"user", required_argument, NULL, 'u'},
- {"group", required_argument, NULL, 'g'},
- {"version", no_argument, NULL, 'v'},
{"dryrun", no_argument, NULL, 'C'},
- {"help", no_argument, NULL, 'h'},
{0}
};
@@ -103,12 +95,6 @@ struct option longopts[] = {
char config_default[] = SYSCONFDIR ISISD_DEFAULT_CONFIG;
char *config_file = NULL;
-/* isisd program name. */
-char *progname;
-
-/* VTY Socket prefix */
-char vty_sock_path[MAXPATHLEN] = ISIS_VTYSH_PATH;
-
int daemon_mode = 0;
/* Master of threads. */
@@ -134,36 +120,6 @@ void sigterm(void);
void sigusr1(void);
-/* Help information display. */
-static void
-usage (int status)
-{
- if (status != 0)
- fprintf (stderr, "Try `%s --help' for more information.\n", progname);
- else
- {
- printf ("Usage : %s [OPTION...]\n\n\
-Daemon which manages IS-IS routing\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\
- --vty_socket Override vty socket path\n\
--u, --user User to run as\n\
--g, --group Group to run as\n\
--v, --version Print program version\n\
--C, --dryrun Check configuration for validity and exit\n\
--h, --help Display this help and exit\n\
-\n\
-Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
- }
-
- exit (status);
-}
-
-
void
reload ()
{
@@ -236,29 +192,30 @@ struct quagga_signal_t isisd_signals[] =
},
};
+FRR_DAEMON_INFO(isisd, ISIS,
+ .vty_port = ISISD_VTY_PORT,
+
+ .proghelp = "Implementation of the IS-IS routing protocol.",
+ .copyright = "Copyright (c) 2001-2002 Sampo Saaristo,"
+ " Ofer Wald and Hannes Gredler",
+
+ .signals = isisd_signals,
+ .n_signals = array_size(isisd_signals),
+
+ .privs = &isisd_privs,
+)
+
/*
* Main routine of isisd. Parse arguments and handle IS-IS state machine.
*/
int
main (int argc, char **argv, char **envp)
{
- char *p;
- int opt, vty_port = ISISD_VTY_PORT;
+ int opt;
struct thread thread;
char *config_file = NULL;
- char *vty_addr = NULL;
int dryrun = 0;
- /* Get the programname without the preceding path. */
- progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
-
- zlog_default = openzlog (progname, ZLOG_ISIS, 0,
- LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
- zprivs_init (&isisd_privs);
-#if defined(HAVE_CUMULUS)
- zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
-#endif
-
/* for reload */
_argc = argc;
_argv = argv;
@@ -274,10 +231,18 @@ main (int argc, char **argv, char **envp)
else
snprintf (_progpath, sizeof (_progpath), "%s", argv[0]);
+ frr_preinit (&isisd_di, argc, argv);
+ frr_opt_add ("df:i:z:C", longopts,
+ " -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"
+ " -C, --dryrun Check configuration for validity and exit\n");
+
/* Command line argument treatment. */
while (1)
{
- opt = getopt_long (argc, argv, "df:i:z:hA:p:P:u:g:vC", longopts, 0);
+ opt = frr_getopt (argc, argv, NULL);
if (opt == EOF)
break;
@@ -298,58 +263,21 @@ main (int argc, char **argv, char **envp)
case 'z':
zclient_serv_path_set (optarg);
break;
- case 'A':
- vty_addr = optarg;
- break;
- case 'P':
- /* Deal with atoi() returning 0 on failure, and isisd not
- listening on isisd port... */
- if (strcmp (optarg, "0") == 0)
- {
- vty_port = 0;
- break;
- }
- vty_port = atoi (optarg);
- vty_port = (vty_port ? vty_port : ISISD_VTY_PORT);
- break;
- case OPTION_VTYSOCK:
- set_socket_path(vty_sock_path, ISIS_VTYSH_PATH, optarg, sizeof (vty_sock_path));
- break;
- case 'u':
- isisd_privs.user = optarg;
- break;
- case 'g':
- isisd_privs.group = optarg;
- break;
- case 'v':
- printf ("ISISd version %s\n", ISISD_VERSION);
- printf ("Copyright (c) 2001-2002 Sampo Saaristo,"
- " Ofer Wald and Hannes Gredler\n");
- print_version ("Zebra");
- exit (0);
- break;
case 'C':
dryrun = 1;
break;
- case 'h':
- usage (0);
- break;
default:
- usage (1);
+ frr_help_exit (1);
break;
}
}
/* thread master */
- master = thread_master_create ();
-
- /* random seed from time */
- srandom (time (NULL));
+ master = frr_init ();
/*
* initializations
*/
- signal_init (master, array_size (isisd_signals), isisd_signals);
cmd_init (1);
vty_config_lockless ();
vty_init (master);
@@ -389,10 +317,10 @@ main (int argc, char **argv, char **envp)
pid_output (pid_file);
/* Make isis vty socket. */
- vty_serv_sock (vty_addr, vty_port, vty_sock_path);
+ frr_vty_serv (ISIS_VTYSH_PATH);
/* Print banner. */
- zlog_notice ("Quagga-ISISd %s starting: vty@%d", FRR_VERSION, vty_port);
+ zlog_notice ("Quagga-ISISd %s starting: vty@%d", FRR_VERSION, isisd_di.vty_port);
/* Start finite state machine. */
while (thread_fetch (master, &thread))
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index 4e79f8b8ab..4fd40c7bb1 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -40,8 +40,8 @@
#include "zclient.h"
#include "vrf.h"
#include "filter.h"
-#include "sockopt.h"
#include "qobj.h"
+#include "libfrr.h"
static void ldpd_shutdown(void);
static pid_t start_child(enum ldpd_process, char *, int, int,
@@ -117,14 +117,10 @@ struct zebra_privs_t ldpd_privs =
.cap_num_i = 0
};
-/* VTY Socket prefix */
-char vty_sock_path[MAXPATHLEN] = LDP_VTYSH_PATH;
-
/* CTL Socket path */
char ctl_sock_path[MAXPATHLEN] = LDPD_SOCKET;
/* LDPd options. */
-#define OPTION_VTYSOCK 1000
#define OPTION_CTLSOCK 1001
static struct option longopts[] =
{
@@ -133,47 +129,10 @@ static struct option longopts[] =
{ "pid_file", required_argument, NULL, 'i'},
{ "socket", required_argument, NULL, 'z'},
{ "dryrun", no_argument, NULL, 'C'},
- { "help", no_argument, NULL, 'h'},
- { "vty_addr", required_argument, NULL, 'A'},
- { "vty_port", required_argument, NULL, 'P'},
- { "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
{ "ctl_socket", required_argument, NULL, OPTION_CTLSOCK},
- { "user", required_argument, NULL, 'u'},
- { "group", required_argument, NULL, 'g'},
- { "version", no_argument, NULL, 'v'},
{ 0 }
};
-/* Help information display. */
-static void __attribute__ ((noreturn))
-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 LDP.\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\
- --vty_socket Override vty socket path\n\
- --ctl_socket Override ctl socket path\n\
--u, --user User to run as\n\
--g, --group Group to run as\n\
--v, --version Print program version\n\
--C, --dryrun Check configuration for validity and exit\n\
--h, --help Display this help and exit\n\
-\n\
-Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
- }
-
- exit(status);
-}
-
/* SIGHUP handler. */
static void
sighup(void)
@@ -216,6 +175,17 @@ static struct quagga_signal_t ldp_signals[] =
}
};
+FRR_DAEMON_INFO(ldpd, LDP,
+ .vty_port = LDP_VTY_PORT,
+
+ .proghelp = "Implementation of the LDP protocol.",
+
+ .signals = ldp_signals,
+ .n_signals = array_size(ldp_signals),
+
+ .privs = &ldpd_privs,
+)
+
int
main(int argc, char *argv[])
{
@@ -223,36 +193,34 @@ main(int argc, char *argv[])
int lflag = 0, eflag = 0;
int pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2];
int pipe_parent2lde[2], pipe_parent2lde_sync[2];
- char *p;
- char *vty_addr = NULL;
- int vty_port = LDP_VTY_PORT;
char *ctl_sock_custom_path = NULL;
char *ctl_sock_name;
int daemon_mode = 0;
const char *user = NULL;
const char *group = NULL;
char *config_file = NULL;
- char *progname;
struct thread thread;
int dryrun = 0;
ldpd_process = PROC_MAIN;
- /* Set umask before anything for security */
- umask(0027);
-
- /* get program name */
- progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]);
-
saved_argv0 = argv[0];
if (saved_argv0 == NULL)
saved_argv0 = (char *)"ldpd";
+ frr_preinit(&ldpd_di, argc, argv);
+ frr_opt_add("df:i:z:CLE", longopts,
+ " -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"
+ " --ctl_socket Override ctl socket path\n"
+ " -C, --dryrun Check configuration for validity and exit\n");
+
while (1) {
int opt;
- opt = getopt_long(argc, argv, "df:i:z:hA:P:u:g:vCLE",
- longopts, 0);
+ opt = frr_getopt(argc, argv, NULL);
if (opt == EOF)
break;
@@ -266,31 +234,12 @@ main(int argc, char *argv[])
case 'f':
config_file = optarg;
break;
- case 'A':
- vty_addr = optarg;
- break;
case 'i':
pid_file = optarg;
break;
case 'z':
zclient_serv_path_set(optarg);
break;
- case 'P':
- /*
- * Deal with atoi() returning 0 on failure, and ldpd
- * not listening on ldpd port.
- */
- if (strcmp(optarg, "0") == 0) {
- vty_port = 0;
- break;
- }
- vty_port = atoi(optarg);
- if (vty_port <= 0 || vty_port > 0xffff)
- vty_port = LDP_VTY_PORT;
- break;
- case OPTION_VTYSOCK:
- set_socket_path(vty_sock_path, LDP_VTYSH_PATH, optarg, sizeof (vty_sock_path));
- break;
case OPTION_CTLSOCK:
ctl_sock_name = strrchr(LDPD_SOCKET, '/');
if (ctl_sock_name)
@@ -310,22 +259,9 @@ main(int argc, char *argv[])
strlcat(ctl_sock_path, ctl_sock_name,
sizeof(ctl_sock_path));
break;
- case 'u':
- user = optarg;
- break;
- case 'g':
- group = optarg;
- break;
- case 'v':
- print_version(progname);
- exit(0);
- break;
case 'C':
dryrun = 1;
break;
- case 'h':
- usage(progname, 0);
- break;
case 'L':
lflag = 1;
break;
@@ -333,24 +269,27 @@ main(int argc, char *argv[])
eflag = 1;
break;
default:
- usage(progname, 1);
+ frr_help_exit(1);
break;
}
}
+ user = ldpd_privs.user;
+ group = ldpd_privs.group;
+
argc -= optind;
argv += optind;
if (argc > 0 || (lflag && eflag))
- usage(progname, 1);
+ frr_help_exit(1);
/* check for root privileges */
if (geteuid() != 0) {
errno = EPERM;
- perror(progname);
+ perror(ldpd_di.progname);
exit(1);
}
- zlog_default = openzlog(progname, ZLOG_LDP, 0,
+ zlog_default = openzlog(ldpd_di.progname, ZLOG_LDP, 0,
LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
if (lflag)
@@ -418,10 +357,6 @@ main(int argc, char *argv[])
user, group, ctl_sock_custom_path);
/* drop privileges */
- if (user)
- ldpd_privs.user = user;
- if (group)
- ldpd_privs.group = group;
zprivs_init(&ldpd_privs);
/* setup signal handler */
@@ -475,10 +410,10 @@ main(int argc, char *argv[])
pid_output(pid_file);
/* Create VTY socket */
- vty_serv_sock(vty_addr, vty_port, vty_sock_path);
+ frr_vty_serv(LDP_VTYSH_PATH);
/* Print banner. */
- log_notice("LDPd %s starting: vty@%d", FRR_VERSION, vty_port);
+ log_notice("LDPd %s starting: vty@%d", FRR_VERSION, ldpd_di.vty_port);
/* Fetch next active thread. */
while (thread_fetch(master, &thread))
diff --git a/lib/Makefile.am b/lib/Makefile.am
index a9fe646938..b9f318cedc 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -29,6 +29,7 @@ libfrr_la_SOURCES = \
grammar_sandbox.c \
srcdest_table.c \
spf_backoff.c \
+ libfrr.c \
strlcpy.c \
strlcat.c
@@ -52,7 +53,9 @@ pkginclude_HEADERS = \
event_counter.h \
monotime.h \
spf_backoff.h \
- srcdest_table.h
+ srcdest_table.h \
+ libfrr.h \
+ # end
noinst_HEADERS = \
plist_int.h
diff --git a/lib/command.c b/lib/command.c
index 50976f2010..d87381f1ef 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -2726,7 +2726,6 @@ cmd_init (int terminal)
vrf_install_commands ();
}
- srandom(time(NULL));
#ifdef DEV_BUILD
grammar_sandbox_init();
diff --git a/lib/libfrr.c b/lib/libfrr.c
new file mode 100644
index 0000000000..6d55223f55
--- /dev/null
+++ b/lib/libfrr.c
@@ -0,0 +1,262 @@
+/*
+ * libfrr overall management functions
+ *
+ * Copyright (C) 2016 David Lamparter for NetDEF, Inc.
+ *
+ * This program is free software; you can redistribute it 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 program 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, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <zebra.h>
+
+#include "libfrr.h"
+#include "getopt.h"
+#include "vty.h"
+#include "command.h"
+#include "version.h"
+
+static char comb_optstr[256];
+static struct option comb_lo[64];
+static struct option *comb_next_lo = &comb_lo[0];
+static char comb_helpstr[4096];
+
+struct optspec {
+ const char *optstr;
+ const char *helpstr;
+ const struct option *longopts;
+};
+
+static void opt_extend(const struct optspec *os)
+{
+ const struct option *lo;
+
+ strcat(comb_optstr, os->optstr);
+ strcat(comb_helpstr, os->helpstr);
+ for (lo = os->longopts; lo->name; lo++)
+ memcpy(comb_next_lo++, lo, sizeof(*lo));
+}
+
+
+#define OPTION_VTYSOCK 1000
+
+static const struct option lo_always[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { "vty_socket", required_argument, NULL, OPTION_VTYSOCK },
+ { NULL }
+};
+static const struct optspec os_always = {
+ "hv",
+ " -h, --help Display this help and exit\n"
+ " -v, --version Print program version\n"
+ " --vty_socket Override vty socket path\n",
+ lo_always
+};
+
+
+static const struct option lo_vty[] = {
+ { "vty_addr", required_argument, NULL, 'A'},
+ { "vty_port", required_argument, NULL, 'P'},
+ { NULL }
+};
+static const struct optspec os_vty = {
+ "A:P:",
+ " -A, --vty_addr Set vty's bind address\n"
+ " -P, --vty_port Set vty's port number\n",
+ lo_vty
+};
+
+
+static const struct option lo_user[] = {
+ { "user", required_argument, NULL, 'u'},
+ { "group", required_argument, NULL, 'g'},
+ { NULL }
+};
+static const struct optspec os_user = {
+ "u:g:",
+ " -u, --user User to run as\n"
+ " -g, --group Group to run as\n",
+ lo_user
+};
+
+
+static struct frr_daemon_info *di = NULL;
+
+void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv)
+{
+ di = daemon;
+
+ /* basename(), opencoded. */
+ char *p = strrchr(argv[0], '/');
+ di->progname = p ? p + 1 : argv[0];
+
+ umask(0027);
+
+ opt_extend(&os_always);
+ if (!(di->flags & FRR_NO_PRIVSEP))
+ opt_extend(&os_user);
+ if (!(di->flags & FRR_NO_TCPVTY))
+ opt_extend(&os_vty);
+}
+
+void frr_opt_add(const char *optstr, const struct option *longopts,
+ const char *helpstr)
+{
+ const struct optspec main_opts = { optstr, helpstr, longopts };
+ opt_extend(&main_opts);
+}
+
+void frr_help_exit(int status)
+{
+ FILE *target = status ? stderr : stdout;
+
+ if (status != 0)
+ fprintf(stderr, "Invalid options.\n\n");
+
+ if (di->printhelp)
+ di->printhelp(target);
+ else
+ fprintf(target, "Usage: %s [OPTION...]\n\n%s%s%s\n\n%s",
+ di->progname,
+ di->proghelp,
+ di->copyright ? "\n\n" : "",
+ di->copyright ? di->copyright : "",
+ comb_helpstr);
+ fprintf(target, "\nReport bugs to %s\n", FRR_BUG_ADDRESS);
+ exit(status);
+}
+
+static int errors = 0;
+
+static int frr_opt(int opt)
+{
+ static int vty_port_set = 0;
+ static int vty_addr_set = 0;
+ char *err;
+
+ switch (opt) {
+ case 'h':
+ frr_help_exit(0);
+ break;
+ case 'v':
+ print_version(di->progname);
+ exit(0);
+ break;
+ case 'A':
+ if (di->flags & FRR_NO_TCPVTY)
+ return 1;
+ if (vty_addr_set) {
+ fprintf(stderr, "-A option specified more than once!\n");
+ errors++;
+ break;
+ }
+ vty_addr_set = 1;
+ di->vty_addr = optarg;
+ break;
+ case 'P':
+ if (di->flags & FRR_NO_TCPVTY)
+ return 1;
+ if (vty_port_set) {
+ fprintf(stderr, "-P option specified more than once!\n");
+ errors++;
+ break;
+ }
+ vty_port_set = 1;
+ di->vty_port = strtoul(optarg, &err, 0);
+ if (*err || !*optarg) {
+ fprintf(stderr, "invalid port number \"%s\" for -P option\n",
+ optarg);
+ errors++;
+ break;
+ }
+ break;
+ case OPTION_VTYSOCK:
+ if (di->vty_sock_path) {
+ fprintf(stderr, "--vty_socket option specified more than once!\n");
+ errors++;
+ break;
+ }
+ di->vty_sock_path = optarg;
+ break;
+ case 'u':
+ if (di->flags & FRR_NO_PRIVSEP)
+ return 1;
+ di->privs->user = optarg;
+ break;
+ case 'g':
+ if (di->flags & FRR_NO_PRIVSEP)
+ return 1;
+ di->privs->group = optarg;
+ break;
+ default:
+ return 1;
+ }
+ return 0;
+}
+
+int frr_getopt(int argc, char * const argv[], int *longindex)
+{
+ int opt;
+ int lidx;
+
+ comb_next_lo->name = NULL;
+
+ do {
+ opt = getopt_long(argc, argv, comb_optstr, comb_lo, &lidx);
+ if (frr_opt(opt))
+ break;
+ } while (opt != -1);
+
+ if (opt == -1 && errors)
+ frr_help_exit(1);
+ if (longindex)
+ *longindex = lidx;
+ return opt;
+}
+
+struct thread_master *frr_init(void)
+{
+ struct thread_master *master;
+
+ srandom(time(NULL));
+
+ zlog_default = openzlog (di->progname, di->log_id, di->instance,
+ LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
+#if defined(HAVE_CUMULUS)
+ zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
+#endif
+
+ zprivs_init(di->privs);
+
+ master = thread_master_create();
+ signal_init(master, di->n_signals, di->signals);
+
+ return master;
+}
+
+void frr_vty_serv(const char *path)
+{
+ if (di->vty_sock_path) {
+ char newpath[MAXPATHLEN];
+ const char *name;
+ name = strrchr(path, '/');
+ name = name ? name + 1 : path;
+
+ snprintf(newpath, sizeof(newpath), "%s/%s",
+ di->vty_sock_path, name);
+ vty_serv_sock(di->vty_addr, di->vty_port, newpath);
+ } else
+ vty_serv_sock(di->vty_addr, di->vty_port, path);
+}
+
diff --git a/lib/libfrr.h b/lib/libfrr.h
new file mode 100644
index 0000000000..42c4e548cc
--- /dev/null
+++ b/lib/libfrr.h
@@ -0,0 +1,80 @@
+/*
+ * libfrr overall management functions
+ *
+ * Copyright (C) 2016 David Lamparter for NetDEF, Inc.
+ *
+ * This program is free software; you can redistribute it 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 program 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, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ZEBRA_FRR_H
+#define _ZEBRA_FRR_H
+
+#include "sigevent.h"
+#include "privs.h"
+#include "thread.h"
+#include "log.h"
+#include "getopt.h"
+
+#define FRR_NO_PRIVSEP (1 << 0)
+#define FRR_NO_TCPVTY (1 << 1)
+
+struct frr_daemon_info {
+ unsigned flags;
+
+ const char *progname;
+ zlog_proto_t log_id;
+ unsigned short instance;
+
+ char *vty_addr;
+ int vty_port;
+ char *vty_sock_path;
+
+ const char *proghelp;
+ void (*printhelp)(FILE *target);
+ const char *copyright;
+
+ struct quagga_signal_t *signals;
+ size_t n_signals;
+
+ struct zebra_privs_t *privs;
+};
+
+/* execname is the daemon's executable (and pidfile and configfile) name,
+ * i.e. "zebra" or "bgpd"
+ * constname is the daemons source-level name, primarily for the logging ID,
+ * i.e. "ZEBRA" or "BGP"
+ *
+ * note that this macro is also a latch-on point for other changes (e.g.
+ * upcoming plugin support) that need to place some per-daemon things. Each
+ * daemon should have one of these.
+ */
+#define FRR_DAEMON_INFO(execname, constname, ...) \
+ static struct frr_daemon_info execname ##_di = { \
+ .log_id = ZLOG_ ## constname, \
+ __VA_ARGS__ \
+ };
+
+extern void frr_preinit(struct frr_daemon_info *daemon,
+ int argc, char **argv);
+extern void frr_opt_add(const char *optstr,
+ const struct option *longopts, const char *helpstr);
+extern int frr_getopt(int argc, char * const argv[], int *longindex);
+extern void frr_help_exit(int status);
+
+extern struct thread_master *frr_init(void);
+
+extern void frr_vty_serv(const char *path);
+
+#endif /* _ZEBRA_FRR_H */
diff --git a/lib/sockopt.c b/lib/sockopt.c
index 91b0602b3a..2a9f907cb3 100644
--- a/lib/sockopt.c
+++ b/lib/sockopt.c
@@ -29,29 +29,6 @@
#include "sockopt.h"
#include "sockunion.h"
-/* Replace the path of given defaultpath with newpath, but keep filename */
-void
-set_socket_path (char *path, const char *defaultpath, char *newpath, int maxsize)
-{
- const char *sock_name;
-
- sock_name = strrchr(defaultpath, '/');
- if (sock_name)
- /* skip '/' */
- sock_name++;
- else
- /*
- * VTYSH_PATH configured as relative path
- * during config? Should really never happen for
- * sensible config
- */
- sock_name = defaultpath;
-
- strlcpy (path, newpath, maxsize);
- strlcat (path, "/", maxsize);
- strlcat (path, sock_name, maxsize);
-}
-
void
setsockopt_so_recvbuf (int sock, int size)
{
diff --git a/lib/sockopt.h b/lib/sockopt.h
index d5724ce60f..1b7be1e49f 100644
--- a/lib/sockopt.h
+++ b/lib/sockopt.h
@@ -24,10 +24,6 @@
#include "sockunion.h"
-/* Override (vty) socket paths, but keep the filename */
-extern void set_socket_path (char *path, const char *defaultpath,
- char *newpath, int maxsize);
-
extern void setsockopt_so_recvbuf (int sock, int size);
extern void setsockopt_so_sendbuf (const int sock, int size);
extern int getsockopt_so_sendbuf (const int sock);
diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c
index dfb76a4081..b2edea009c 100644
--- a/nhrpd/nhrp_main.c
+++ b/nhrpd/nhrp_main.c
@@ -19,6 +19,7 @@
#include "memory.h"
#include "memory_vty.h"
#include "command.h"
+#include "libfrr.h"
#include "nhrpd.h"
#include "netlink.h"
@@ -32,8 +33,6 @@ 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. */
@@ -42,12 +41,6 @@ struct option longopts[] = {
{ "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 }
};
@@ -72,36 +65,12 @@ static struct zebra_privs_t nhrpd_privs = {
.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\
-Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
-
- exit(status);
-}
-
-static void parse_arguments(const char *progname, int argc, char **argv)
+static void parse_arguments(int argc, char **argv)
{
int opt;
while (1) {
- opt = getopt_long(argc, argv, "df:i:z:hA:P:u:g:v", longopts, 0);
+ opt = frr_getopt(argc, argv, 0);
if(opt < 0) break;
switch (opt) {
@@ -119,29 +88,8 @@ static void parse_arguments(const char *progname, int argc, char **argv)
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);
+ frr_help_exit(1);
break;
}
}
@@ -184,23 +132,32 @@ static struct quagga_signal_t sighandlers[] = {
{ .signal = SIGTERM, .handler = &nhrp_request_stop, },
};
+FRR_DAEMON_INFO(nhrpd, NHRP,
+ .vty_port = NHRP_VTY_PORT,
+
+ .proghelp = "Implementation of the NHRP routing protocol.",
+
+ .signals = sighandlers,
+ .n_signals = array_size(sighandlers),
+
+ .privs = &nhrpd_privs,
+)
+
int main(int argc, char **argv)
{
struct thread thread;
- const char *progname, *p;
- /* Set umask before anything for security */
- umask(0027);
- progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
- zlog_default = openzlog(progname, ZLOG_NHRP, 0, LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
- zlog_set_level(NULL, ZLOG_DEST_STDOUT, LOG_WARNING);
+ frr_preinit(&nhrpd_di, argc, argv);
+ frr_opt_add("df:i:z:", longopts,
+ " -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");
- parse_arguments(progname, argc, argv);
+ parse_arguments(argc, argv);
/* Library inits. */
- master = thread_master_create();
- zprivs_init(&nhrpd_privs);
- signal_init(master, array_size(sighandlers), sighandlers);
+ master = frr_init();
cmd_init(1);
vty_init(master);
memory_init();
@@ -238,8 +195,8 @@ int main(int argc, char **argv)
}
/* Create VTY socket */
- vty_serv_sock(vty_addr, vty_port, NHRP_VTYSH_PATH);
- zlog_notice("nhrpd starting: vty@%d", vty_port);
+ frr_vty_serv(NHRP_VTYSH_PATH);
+ zlog_notice("nhrpd starting: vty@%d", nhrpd_di.vty_port);
/* Main loop */
while (thread_fetch(master, &thread))
diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c
index f85580fa59..f7df47cacb 100644
--- a/ospf6d/ospf6_main.c
+++ b/ospf6d/ospf6_main.c
@@ -39,7 +39,7 @@
#include "zclient.h"
#include "vrf.h"
#include "bfd.h"
-#include "sockopt.h"
+#include "libfrr.h"
#include "ospf6d.h"
#include "ospf6_top.h"
@@ -52,9 +52,6 @@
/* Default configuration file name for ospf6d. */
#define OSPF6_DEFAULT_CONFIG "ospf6d.conf"
-/* VTY Socket prefix */
-char vty_sock_path[MAXPATHLEN] = OSPF6_VTYSH_PATH;
-
/* Default port values. */
#define OSPF6_VTY_PORT 2606
@@ -82,30 +79,19 @@ struct zebra_privs_t ospf6d_privs =
};
/* ospf6d options, we use GNU getopt library. */
-#define OPTION_VTYSOCK 1000
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'},
- { "vty_addr", required_argument, NULL, 'A'},
- { "vty_port", required_argument, NULL, 'P'},
- { "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
- { "user", required_argument, NULL, 'u'},
- { "group", required_argument, NULL, 'g'},
- { "version", no_argument, NULL, 'v'},
{ "dryrun", no_argument, NULL, 'C'},
- { "help", no_argument, NULL, 'h'},
{ 0 }
};
/* Configuration file and directory. */
char config_default[] = SYSCONFDIR OSPF6_DEFAULT_CONFIG;
-/* ospf6d program name. */
-char *progname;
-
/* is daemon? */
int daemon_mode = 0;
@@ -115,35 +101,6 @@ struct thread_master *master;
/* Process ID saved for use by init system */
const char *pid_file = PATH_OSPF6D_PID;
-/* Help information display. */
-static void
-usage (char *progname, int status)
-{
- if (status != 0)
- fprintf (stderr, "Try `%s --help' for more information.\n", progname);
- else
- {
- printf ("Usage : %s [OPTION...]\n\n\
-Daemon which manages OSPF version 3.\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\
- --vty_socket Override vty socket path\n\
--u, --user User to run as\n\
--g, --group Group to run as\n\
--v, --version Print program version\n\
--C, --dryrun Check configuration for validity and exit\n\
--h, --help Display this help and exit\n\
-\n\
-Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
- }
-
- exit (status);
-}
-
static void __attribute__ ((noreturn))
ospf6_exit (int status)
{
@@ -231,32 +188,39 @@ struct quagga_signal_t ospf6_signals[] =
},
};
+FRR_DAEMON_INFO(ospf6d, OSPF6,
+ .vty_port = OSPF6_VTY_PORT,
+
+ .proghelp = "Implementation of the OSPFv3 routing protocol.",
+
+ .signals = ospf6_signals,
+ .n_signals = array_size(ospf6_signals),
+
+ .privs = &ospf6d_privs,
+)
+
/* Main routine of ospf6d. Treatment of argument and starting ospf finite
state machine is handled here. */
int
main (int argc, char *argv[], char *envp[])
{
- char *p;
int opt;
- char *vty_addr = NULL;
- int vty_port = 0;
char *config_file = NULL;
struct thread thread;
int dryrun = 0;
- /* Set umask before anything for security */
- umask (0027);
-
- /* Preserve name of myself. */
- progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
-
- /* Seed random number for LSA ID */
- srandom (time(NULL));
+ frr_preinit (&ospf6d_di, argc, argv);
+ frr_opt_add ("df:i:z:C", longopts,
+ " -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"
+ " -C, --dryrun Check configuration for validity and exit\n");
/* Command line argument treatment. */
while (1)
{
- opt = getopt_long (argc, argv, "df:i:z:hp:A:P:u:g:vC", longopts, 0);
+ opt = frr_getopt (argc, argv, NULL);
if (opt == EOF)
break;
@@ -271,48 +235,17 @@ main (int argc, char *argv[], char *envp[])
case 'f':
config_file = optarg;
break;
- case 'A':
- vty_addr = optarg;
- break;
case 'i':
pid_file = optarg;
break;
case 'z':
zclient_serv_path_set (optarg);
break;
- case 'P':
- /* Deal with atoi() returning 0 on failure, and ospf6d not
- listening on ospf6d port... */
- if (strcmp(optarg, "0") == 0)
- {
- vty_port = 0;
- break;
- }
- vty_port = atoi (optarg);
- if (vty_port <= 0 || vty_port > 0xffff)
- vty_port = OSPF6_VTY_PORT;
- break;
- case OPTION_VTYSOCK:
- set_socket_path(vty_sock_path, OSPF6_VTYSH_PATH, optarg, sizeof (vty_sock_path));
- break;
- case 'u':
- ospf6d_privs.user = optarg;
- break;
- case 'g':
- ospf6d_privs.group = optarg;
- break;
- case 'v':
- print_version (progname);
- exit (0);
- break;
case 'C':
dryrun = 1;
break;
- case 'h':
- usage (progname, 0);
- break;
default:
- usage (progname, 1);
+ frr_help_exit (1);
break;
}
}
@@ -320,24 +253,13 @@ main (int argc, char *argv[], char *envp[])
if (geteuid () != 0)
{
errno = EPERM;
- perror (progname);
+ perror (ospf6d_di.progname);
exit (1);
}
/* thread master */
- master = thread_master_create ();
-
- /* Initializations. */
- zlog_default = openzlog (progname, ZLOG_OSPF6, 0,
- LOG_CONS|LOG_NDELAY|LOG_PID,
- LOG_DAEMON);
- zprivs_init (&ospf6d_privs);
-#if defined(HAVE_CUMULUS)
- zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
-#endif
+ master = frr_init ();
- /* initialize zebra libraries */
- signal_init (master, array_size(ospf6_signals), ospf6_signals);
cmd_init (1);
vty_init (master);
memory_init ();
@@ -364,14 +286,11 @@ main (int argc, char *argv[], char *envp[])
/* pid file create */
pid_output (pid_file);
- /* Make ospf6 vty socket. */
- if (!vty_port)
- vty_port = OSPF6_VTY_PORT;
- vty_serv_sock (vty_addr, vty_port, vty_sock_path);
+ frr_vty_serv (OSPF6_VTYSH_PATH);
/* Print start message */
zlog_notice ("OSPF6d (Quagga-%s ospf6d-%s) starts: vty@%d",
- FRR_VERSION, OSPF6_DAEMON_VERSION,vty_port);
+ FRR_VERSION, OSPF6_DAEMON_VERSION, ospf6d_di.vty_port);
/* Start finite state machine, here we go! */
while (thread_fetch (master, &thread))
diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c
index edb1ca470e..c119f4e392 100644
--- a/ospfd/ospf_main.c
+++ b/ospfd/ospf_main.c
@@ -41,7 +41,7 @@
#include "sigevent.h"
#include "zclient.h"
#include "vrf.h"
-#include "sockopt.h"
+#include "libfrr.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@@ -80,7 +80,6 @@ struct zebra_privs_t ospfd_privs =
char config_default[100];
/* OSPFd options. */
-#define OPTION_VTYSOCK 1000
struct option longopts[] =
{
{ "daemon", no_argument, NULL, 'd'},
@@ -89,22 +88,12 @@ struct option longopts[] =
{ "pid_file", required_argument, NULL, 'i'},
{ "socket", required_argument, NULL, 'z'},
{ "dryrun", no_argument, NULL, 'C'},
- { "help", no_argument, NULL, 'h'},
- { "vty_addr", required_argument, NULL, 'A'},
- { "vty_port", required_argument, NULL, 'P'},
- { "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
- { "user", required_argument, NULL, 'u'},
- { "group", required_argument, NULL, 'g'},
{ "apiserver", no_argument, NULL, 'a'},
- { "version", no_argument, NULL, 'v'},
{ 0 }
};
/* OSPFd program name */
-/* VTY Socket prefix */
-char vty_sock_path[MAXPATHLEN] = OSPF_VTYSH_PATH;
-
/* Master of threads. */
struct thread_master *master;
@@ -124,21 +113,6 @@ usage (char *progname, int status)
else
{
printf ("Usage : %s [OPTION...]\n\
-Daemon which manages OSPF.\n\n\
--d, --daemon Runs in daemon mode\n\
--n, --instance Set the instance id\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\
- --vty_socket Override vty socket path\n\
--u, --user User to run as\n\
--g, --group Group to run as\n\
--a. --apiserver Enable OSPF apiserver\n\
--v, --version Print program version\n\
--C, --dryrun Check configuration for validity and exit\n\
--h, --help Display this help and exit\n\
\n\
Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
}
@@ -187,24 +161,28 @@ struct quagga_signal_t ospf_signals[] =
},
};
+FRR_DAEMON_INFO(ospfd, OSPF,
+ .vty_port = OSPF_VTY_PORT,
+
+ .proghelp = "Implementation of the OSPFv2 routing protocol.",
+
+ .signals = ospf_signals,
+ .n_signals = array_size(ospf_signals),
+
+ .privs = &ospfd_privs,
+)
+
/* OSPFd main routine. */
int
main (int argc, char **argv)
{
- char *p;
- char *vty_addr = NULL;
- int vty_port = OSPF_VTY_PORT;
- char vty_path[100];
+ char vty_path[MAXPATHLEN];
int daemon_mode = 0;
char *config_file = NULL;
- char *progname;
u_short instance = 0;
struct thread thread;
int dryrun = 0;
- /* Set umask before anything for security */
- umask (0027);
-
#ifdef SUPPORT_OSPF_API
/* OSPF apiserver is disabled by default. */
ospf_apiserver_enable = 0;
@@ -212,14 +190,21 @@ main (int argc, char **argv)
strcpy(pid_file, PATH_OSPFD_PID);
- /* get program name */
- progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
+ frr_preinit (&ospfd_di, argc, argv);
+ frr_opt_add ("df:i:n:z:aC", longopts,
+ " -d, --daemon Runs in daemon mode\n"
+ " -n, --instance Set the instance id\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. --apiserver Enable OSPF apiserver\n"
+ " -C, --dryrun Check configuration for validity and exit\n");
while (1)
{
int opt;
- opt = getopt_long (argc, argv, "df:i:n:z:hA:P:u:g:avC", longopts, 0);
+ opt = frr_getopt (argc, argv, NULL);
if (opt == EOF)
break;
@@ -227,7 +212,7 @@ main (int argc, char **argv)
switch (opt)
{
case 'n':
- instance = atoi(optarg);
+ ospfd_di.instance = instance = atoi(optarg);
if (instance < 1)
exit(0);
break;
@@ -239,53 +224,22 @@ main (int argc, char **argv)
case 'f':
config_file = optarg;
break;
- case 'A':
- vty_addr = optarg;
- break;
case 'i':
strcpy(pid_file,optarg);
break;
case 'z':
zclient_serv_path_set (optarg);
break;
- case 'P':
- /* Deal with atoi() returning 0 on failure, and ospfd not
- listening on ospfd port... */
- if (strcmp(optarg, "0") == 0)
- {
- vty_port = 0;
- break;
- }
- vty_port = atoi (optarg);
- if (vty_port <= 0 || vty_port > 0xffff)
- vty_port = OSPF_VTY_PORT;
- break;
- case OPTION_VTYSOCK:
- set_socket_path(vty_sock_path, OSPF_VTYSH_PATH, optarg, sizeof (vty_sock_path));
- break;
- case 'u':
- ospfd_privs.user = optarg;
- break;
- case 'g':
- ospfd_privs.group = optarg;
- break;
#ifdef SUPPORT_OSPF_API
case 'a':
ospf_apiserver_enable = 1;
break;
#endif /* SUPPORT_OSPF_API */
- case 'v':
- print_version (progname);
- exit (0);
- break;
case 'C':
dryrun = 1;
break;
- case 'h':
- usage (progname, 0);
- break;
default:
- usage (progname, 1);
+ frr_help_exit (1);
break;
}
}
@@ -294,25 +248,17 @@ main (int argc, char **argv)
if (geteuid () != 0)
{
errno = EPERM;
- perror (progname);
+ perror (ospfd_di.progname);
exit (1);
}
- zlog_default = openzlog (progname, ZLOG_OSPF, instance,
- LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
- zprivs_init (&ospfd_privs);
-#if defined(HAVE_CUMULUS)
- zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
-#endif
-
/* OSPF master init. */
- ospf_master_init ();
+ ospf_master_init (frr_init ());
/* Initializations. */
master = om->master;
/* Library inits. */
- signal_init (master, array_size(ospf_signals), ospf_signals);
cmd_init (1);
debug_init ();
vty_init (master);
@@ -389,30 +335,19 @@ main (int argc, char **argv)
pid_output (pid_file);
/* Create VTY socket */
+ strlcpy(vty_path, OSPF_VTYSH_PATH, sizeof(vty_path));
if (instance)
{
- /* Multi-Instance. Use only path section of vty_sock_path with new file incl instance */
- if (strrchr(vty_sock_path, '/') != NULL)
- {
- /* cut of pid_file at last / char * to get directory */
- *strrchr(vty_sock_path, '/') = '\0';
- }
- else
- {
- /* pid_file contains no directory - should never happen, but deal with it anyway */
- /* throw-away all pid_file and assume it's only the filename */
- vty_sock_path[0] = '\0';
- }
- snprintf(vty_path, sizeof(vty_path), "%s/ospfd-%d.vty", vty_sock_path, instance );
+ char *slash = strrchr(vty_path, '/');
+ slash = slash ? slash + 1 : vty_path;
+ snprintf(slash, vty_path + sizeof(vty_path) - slash, "ospfd-%d.vty",
+ instance);
}
- else
- {
- strlcpy(vty_path, vty_sock_path, sizeof(vty_path));
- }
- vty_serv_sock (vty_addr, vty_port, vty_path);
+
+ frr_vty_serv (vty_path);
/* Print banner. */
- zlog_notice ("OSPFd %s starting: vty@%d, %s", FRR_VERSION, vty_port, vty_path);
+ zlog_notice ("OSPFd %s starting: vty@%d, %s", FRR_VERSION, ospfd_di.vty_port, vty_path);
/* Fetch next active thread. */
while (thread_fetch (master, &thread))
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 570734bd8c..7cd3903678 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -1917,11 +1917,11 @@ ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
}
void
-ospf_master_init ()
+ospf_master_init (struct thread_master *master)
{
memset (&ospf_master, 0, sizeof (struct ospf_master));
om = &ospf_master;
om->ospf = list_new ();
- om->master = thread_master_create ();
+ om->master = master;
}
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index 8ebd3c4ec6..a3bd0ca12f 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -576,7 +576,7 @@ extern void ospf_area_del_if (struct ospf_area *, struct ospf_interface *);
extern void ospf_route_map_init (void);
extern void ospf_snmp_init (void);
-extern void ospf_master_init (void);
+extern void ospf_master_init (struct thread_master *master);
extern int ospf_interface_set (struct interface *ifp, struct in_addr area_id);
extern int ospf_interface_unset (struct interface *ifp);
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index 2e81ac53fd..b8212542ab 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -38,7 +38,7 @@
#include "prefix.h"
#include "plist.h"
#include "vrf.h"
-#include "sockopt.h"
+#include "libfrr.h"
#include "pimd.h"
#include "pim_version.h"
@@ -53,24 +53,14 @@ extern struct host host;
char config_default[] = SYSCONFDIR PIMD_DEFAULT_CONFIG;
/* pimd options */
-#define OPTION_VTYSOCK 1000
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'},
- { "vty_addr", required_argument, NULL, 'A'},
- { "vty_port", required_argument, NULL, 'P'},
- { "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
- { "version", no_argument, NULL, 'v'},
- { "debug_zclient", no_argument, NULL, 'Z'},
- { "help", no_argument, NULL, 'h'},
{ 0 }
};
-/* VTY Socket prefix */
-char vty_sock_path[MAXPATHLEN] = PIM_VTYSH_PATH;
-
/* pimd privileges */
zebra_capabilities_t _caps_p [] =
{
@@ -95,59 +85,39 @@ struct zebra_privs_t pimd_privs =
.cap_num_i = 0
};
-char* progname;
const char *pid_file = PATH_PIMD_PID;
-static void usage(int status)
-{
- if (status != 0)
- fprintf (stderr, "Try `%s --help' for more information.\n", progname);
- else {
- printf ("Usage : %s [OPTION...]\n\
-Daemon which manages PIM.\n\n\
--d, --daemon Run 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\
- --vty_socket Override vty socket path\n\
--v, --version Print program version\n\
--h, --help Display this help and exit\n\
-\n\
-Report bugs to %s\n", progname, PACKAGE_BUGREPORT);
- }
+FRR_DAEMON_INFO(pimd, PIM,
+ .vty_port = PIMD_VTY_PORT,
- exit (status);
-}
+ .proghelp = "Implementation of the PIM routing protocol.",
+ .signals = pimd_signals,
+ .n_signals = 4 /* XXX array_size(pimd_signals) XXX*/,
+
+ .privs = &pimd_privs,
+)
int main(int argc, char** argv, char** envp) {
- char *p;
- char *vty_addr = NULL;
- int vty_port = -1;
int daemon_mode = 0;
char *config_file = NULL;
char *zebra_sock_path = NULL;
struct thread thread;
-
- umask(0027);
-
- progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]);
-
- zlog_default = openzlog(progname, ZLOG_PIM, 0,
- LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
- zprivs_init (&pimd_privs);
-#if defined(HAVE_CUMULUS)
- zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
-#endif
- /* this while just reads the options */
+ frr_preinit(&pimd_di, argc, argv);
+ frr_opt_add("df:i:z:", longopts,
+ " -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"
+ );
+
+ /* this while just reads the options */
while (1) {
int opt;
-
- opt = getopt_long (argc, argv, "df:i:z:A:P:vZh", longopts, 0);
-
+
+ opt = frr_getopt(argc, argv, NULL);
+
if (opt == EOF)
break;
@@ -166,30 +136,13 @@ int main(int argc, char** argv, char** envp) {
case 'z':
zebra_sock_path = optarg;
break;
- case 'A':
- vty_addr = optarg;
- break;
- case 'P':
- vty_port = atoi (optarg);
- break;
- case OPTION_VTYSOCK:
- set_socket_path(vty_sock_path, PIM_VTYSH_PATH, optarg, sizeof (vty_sock_path));
- break;
- case 'v':
- printf(PIMD_PROGNAME " version %s\n", PIMD_VERSION);
- print_version(progname);
- exit (0);
- break;
- case 'h':
- usage (0);
- break;
default:
- usage (1);
+ frr_help_exit (1);
break;
}
}
- master = thread_master_create();
+ master = frr_init();
zlog_notice("Quagga %s " PIMD_PROGNAME " %s starting",
FRR_VERSION, PIMD_VERSION);
@@ -197,7 +150,6 @@ int main(int argc, char** argv, char** envp) {
/*
* Initializations
*/
- pim_signals_init();
cmd_init(1);
vty_init(master);
memory_init();
@@ -237,13 +189,10 @@ int main(int argc, char** argv, char** envp) {
/* Process ID file creation. */
pid_output(pid_file);
- /* Create pimd VTY socket */
- if (vty_port < 0)
- vty_port = PIMD_VTY_PORT;
- vty_serv_sock(vty_addr, vty_port, vty_sock_path);
+ frr_vty_serv (PIM_VTYSH_PATH);
zlog_notice("Quagga %s " PIMD_PROGNAME " %s starting, VTY interface at port TCP %d",
- FRR_VERSION, PIMD_VERSION, vty_port);
+ FRR_VERSION, PIMD_VERSION, pimd_di.vty_port);
#ifdef PIM_DEBUG_BYDEFAULT
zlog_notice("PIM_DEBUG_BYDEFAULT: Enabling all debug commands");
diff --git a/pimd/pim_signals.c b/pimd/pim_signals.c
index bd4d9e4857..11360e00cb 100644
--- a/pimd/pim_signals.c
+++ b/pimd/pim_signals.c
@@ -58,7 +58,7 @@ static void pim_sigusr1()
zlog_rotate (NULL);
}
-static struct quagga_signal_t pimd_signals[] =
+struct quagga_signal_t pimd_signals[] =
{
{
.signal = SIGHUP,
@@ -77,9 +77,3 @@ static struct quagga_signal_t pimd_signals[] =
.handler = &pim_sigterm,
},
};
-
-void pim_signals_init()
-{
- signal_init(master, array_size(pimd_signals), pimd_signals);
-}
-
diff --git a/pimd/pim_signals.h b/pimd/pim_signals.h
index 7b25608c10..d7a4926d4d 100644
--- a/pimd/pim_signals.h
+++ b/pimd/pim_signals.h
@@ -21,6 +21,7 @@
#ifndef PIM_SIGNALS_H
#define PIM_SIGNALS_H
-void pim_signals_init(void);
+#include "sigevent.h"
+extern struct quagga_signal_t pimd_signals[];
#endif /* PIM_SIGNALS_H */
diff --git a/pimd/pimd.c b/pimd/pimd.c
index aa863fd47f..c8a0efc401 100644
--- a/pimd/pimd.c
+++ b/pimd/pimd.c
@@ -98,8 +98,6 @@ static void pim_free()
void pim_init()
{
- srandom(time(NULL));
-
qpim_rp_keep_alive_time = PIM_RP_KEEPALIVE_PERIOD;
pim_rp_init ();
diff --git a/ripd/rip_main.c b/ripd/rip_main.c
index 58dd2df6fa..2f497f0022 100644
--- a/ripd/rip_main.c
+++ b/ripd/rip_main.c
@@ -35,27 +35,19 @@
#include "sigevent.h"
#include "zclient.h"
#include "vrf.h"
-#include "sockopt.h"
+#include "libfrr.h"
#include "ripd/ripd.h"
/* ripd options. */
-#define OPTION_VTYSOCK 1000
static 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'},
{ "dryrun", no_argument, NULL, 'C'},
- { "vty_addr", required_argument, NULL, 'A'},
- { "vty_port", required_argument, NULL, 'P'},
- { "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
{ "retain", no_argument, NULL, 'r'},
- { "user", required_argument, NULL, 'u'},
- { "group", required_argument, NULL, 'g'},
- { "version", no_argument, NULL, 'v'},
{ 0 }
};
@@ -94,48 +86,12 @@ char vty_sock_path[MAXPATHLEN] = RIP_VTYSH_PATH;
/* Route retain mode flag. */
int retain_mode = 0;
-/* RIP VTY bind address. */
-char *vty_addr = NULL;
-
-/* RIP VTY connection port. */
-int vty_port = RIP_VTY_PORT;
-
/* Master of threads. */
struct thread_master *master;
/* Process ID saved for use by init system */
const char *pid_file = PATH_RIPD_PID;
-/* Help information display. */
-static void
-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 RIP version 1 and 2.\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\
- --vty_socket Override vty socket path\n\
--C, --dryrun Check configuration for validity and exit\n\
--r, --retain When program terminates, retain added route by ripd.\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, FRR_BUG_ADDRESS);
- }
-
- exit (status);
-}
-
/* SIGHUP handler. */
static void
sighup (void)
@@ -148,9 +104,6 @@ sighup (void)
/* Reload config file. */
vty_read_config (config_file, config_default);
- /* Create VTY's socket */
- vty_serv_sock (vty_addr, vty_port, vty_sock_path);
-
/* Try to return to normal operation. */
}
@@ -193,36 +146,40 @@ static struct quagga_signal_t ripd_signals[] =
},
};
+FRR_DAEMON_INFO(ripd, RIP,
+ .vty_port = RIP_VTY_PORT,
+
+ .proghelp = "Implementation of the RIP routing protocol.",
+
+ .signals = ripd_signals,
+ .n_signals = array_size(ripd_signals),
+
+ .privs = &ripd_privs,
+)
+
/* Main routine of ripd. */
int
main (int argc, char **argv)
{
- char *p;
int daemon_mode = 0;
int dryrun = 0;
- char *progname;
struct thread thread;
- /* Set umask before anything for security */
- umask (0027);
-
- /* Get program name. */
- progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
-
- /* First of all we need logging init. */
- zlog_default = openzlog (progname, ZLOG_RIP, 0,
- LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
- zprivs_init (&ripd_privs);
-#if defined(HAVE_CUMULUS)
- zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
-#endif
+ frr_preinit (&ripd_di, argc, argv);
+ frr_opt_add ("df:i:z:rC", longopts,
+ " -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"
+ " -C, --dryrun Check configuration for validity and exit\n"
+ " -r, --retain When program terminates, retain added route by ripd.\n");
/* Command line option parse. */
while (1)
{
int opt;
- opt = getopt_long (argc, argv, "df:i:z:hA:P:u:g:rvC", longopts, 0);
+ opt = frr_getopt (argc, argv, NULL);
if (opt == EOF)
break;
@@ -237,60 +194,28 @@ main (int argc, char **argv)
case 'f':
config_file = optarg;
break;
- case 'A':
- vty_addr = optarg;
- break;
case 'i':
pid_file = optarg;
break;
case 'z':
zclient_serv_path_set (optarg);
break;
- case 'P':
- /* Deal with atoi() returning 0 on failure, and ripd not
- listening on rip port... */
- if (strcmp(optarg, "0") == 0)
- {
- vty_port = 0;
- break;
- }
- vty_port = atoi (optarg);
- if (vty_port <= 0 || vty_port > 0xffff)
- vty_port = RIP_VTY_PORT;
- break;
- case OPTION_VTYSOCK:
- set_socket_path(vty_sock_path, RIP_VTYSH_PATH, optarg, sizeof (vty_sock_path));
- break;
case 'r':
retain_mode = 1;
break;
case 'C':
dryrun = 1;
break;
- case 'u':
- ripd_privs.user = optarg;
- break;
- case 'g':
- ripd_privs.group = optarg;
- break;
- case 'v':
- print_version (progname);
- exit (0);
- break;
- case 'h':
- usage (progname, 0);
- break;
default:
- usage (progname, 1);
+ frr_help_exit (1);
break;
}
}
/* Prepare master thread. */
- master = thread_master_create ();
+ master = frr_init ();
/* Library initialization. */
- signal_init (master, array_size(ripd_signals), ripd_signals);
cmd_init (1);
vty_init (master);
memory_init ();
@@ -321,10 +246,10 @@ main (int argc, char **argv)
pid_output (pid_file);
/* Create VTY's socket */
- vty_serv_sock (vty_addr, vty_port, vty_sock_path);
+ frr_vty_serv (RIP_VTYSH_PATH);
/* Print banner. */
- zlog_notice ("RIPd %s starting: vty@%d", FRR_VERSION, vty_port);
+ zlog_notice ("RIPd %s starting: vty@%d", FRR_VERSION, ripd_di.vty_port);
/* Execute each thread. */
while (thread_fetch (master, &thread))
diff --git a/ripd/ripd.c b/ripd/ripd.c
index bcf4cd3347..e0f96f9aaf 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -4034,9 +4034,6 @@ rip_routemap_update (const char *notused)
void
rip_init (void)
{
- /* Randomize for triggered update random(). */
- srandom (time (NULL));
-
/* Install top nodes. */
install_node (&rip_node, config_write_rip);
diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c
index a90dffce14..b081da2333 100644
--- a/ripngd/ripng_main.c
+++ b/ripngd/ripng_main.c
@@ -36,7 +36,7 @@
#include "privs.h"
#include "sigevent.h"
#include "vrf.h"
-#include "sockopt.h"
+#include "libfrr.h"
#include "ripngd/ripngd.h"
@@ -45,7 +45,6 @@ char config_default[] = SYSCONFDIR RIPNG_DEFAULT_CONFIG;
char *config_file = NULL;
/* RIPngd options. */
-#define OPTION_VTYSOCK 1000
struct option longopts[] =
{
{ "daemon", no_argument, NULL, 'd'},
@@ -53,14 +52,7 @@ struct option longopts[] =
{ "pid_file", required_argument, NULL, 'i'},
{ "socket", required_argument, NULL, 'z'},
{ "dryrun", no_argument, NULL, 'C'},
- { "help", no_argument, NULL, 'h'},
- { "vty_addr", required_argument, NULL, 'A'},
- { "vty_port", required_argument, NULL, 'P'},
- { "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
{ "retain", no_argument, NULL, 'r'},
- { "user", required_argument, NULL, 'u'},
- { "group", required_argument, NULL, 'g'},
- { "version", no_argument, NULL, 'v'},
{ 0 }
};
@@ -90,53 +82,15 @@ struct zebra_privs_t ripngd_privs =
/* RIPngd program name */
-/* VTY Socket prefix */
-char vty_sock_path[MAXPATHLEN] = RIPNG_VTYSH_PATH;
-
/* Route retain mode flag. */
int retain_mode = 0;
-/* RIPng VTY bind address. */
-char *vty_addr = NULL;
-
-/* RIPng VTY connection port. */
-int vty_port = RIPNG_VTY_PORT;
-
/* Master of threads. */
struct thread_master *master;
/* Process ID saved for use by init system */
const char *pid_file = PATH_RIPNGD_PID;
-/* Help information display. */
-static void
-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 RIPng.\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\
- --vty_socket Override vty socket path\n\
--r, --retain When program terminates, retain added route by ripngd.\n\
--u, --user User to run as\n\
--g, --group Group to run as\n\
--v, --version Print program version\n\
--C, --dryrun Check configuration for validity and exit\n\
--h, --help Display this help and exit\n\
-\n\
-Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
- }
- exit (status);
-}
-
/* SIGHUP handler. */
static void
sighup (void)
@@ -147,8 +101,6 @@ sighup (void)
/* Reload config file. */
vty_read_config (config_file, config_default);
- /* Create VTY's socket */
- vty_serv_sock (vty_addr, vty_port, vty_sock_path);
/* Try to return to normal operation. */
}
@@ -192,35 +144,39 @@ struct quagga_signal_t ripng_signals[] =
},
};
+FRR_DAEMON_INFO(ripngd, RIPNG,
+ .vty_port = RIPNG_VTY_PORT,
+
+ .proghelp = "Implementation of the RIPng routing protocol.",
+
+ .signals = ripng_signals,
+ .n_signals = array_size(ripng_signals),
+
+ .privs = &ripngd_privs,
+)
+
/* RIPngd main routine. */
int
main (int argc, char **argv)
{
- char *p;
- int vty_port = RIPNG_VTY_PORT;
int daemon_mode = 0;
- char *progname;
struct thread thread;
int dryrun = 0;
- /* Set umask before anything for security */
- umask (0027);
-
- /* get program name */
- progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
-
- zlog_default = openzlog(progname, ZLOG_RIPNG, 0,
- LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
- zprivs_init (&ripngd_privs);
-#if defined(HAVE_CUMULUS)
- zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
-#endif
+ frr_preinit (&ripngd_di, argc, argv);
+ frr_opt_add ("df:i:z:rC", longopts,
+ " -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"
+ " -C, --dryrun Check configuration for validity and exit\n"
+ " -r, --retain When program terminates, retain added route by ripd.\n");
while (1)
{
int opt;
- opt = getopt_long (argc, argv, "df:i:z:hA:P:u:g:vC", longopts, 0);
+ opt = frr_getopt (argc, argv, NULL);
if (opt == EOF)
break;
@@ -235,59 +191,27 @@ main (int argc, char **argv)
case 'f':
config_file = optarg;
break;
- case 'A':
- vty_addr = optarg;
- break;
case 'i':
pid_file = optarg;
break;
case 'z':
zclient_serv_path_set (optarg);
break;
- case 'P':
- /* Deal with atoi() returning 0 on failure, and ripngd not
- listening on ripngd port... */
- if (strcmp(optarg, "0") == 0)
- {
- vty_port = 0;
- break;
- }
- vty_port = atoi (optarg);
- if (vty_port <= 0 || vty_port > 0xffff)
- vty_port = RIPNG_VTY_PORT;
- break;
- case OPTION_VTYSOCK:
- set_socket_path(vty_sock_path, RIPNG_VTYSH_PATH, optarg, sizeof (vty_sock_path));
- break;
case 'r':
retain_mode = 1;
break;
- case 'u':
- ripngd_privs.user = optarg;
- break;
- case 'g':
- ripngd_privs.group = optarg;
- break;
- case 'v':
- print_version (progname);
- exit (0);
- break;
case 'C':
dryrun = 1;
break;
- case 'h':
- usage (progname, 0);
- break;
default:
- usage (progname, 1);
+ frr_help_exit (1);
break;
}
}
- master = thread_master_create ();
+ master = frr_init ();
/* Library inits. */
- signal_init (master, array_size(ripng_signals), ripng_signals);
cmd_init (1);
vty_init (master);
memory_init ();
@@ -313,13 +237,13 @@ main (int argc, char **argv)
}
/* Create VTY socket */
- vty_serv_sock (vty_addr, vty_port, vty_sock_path);
+ frr_vty_serv (RIPNG_VTYSH_PATH);
/* Process id file create. */
pid_output (pid_file);
/* Print banner. */
- zlog_notice ("RIPNGd %s starting: vty@%d", FRR_VERSION, vty_port);
+ zlog_notice ("RIPNGd %s starting: vty@%d", FRR_VERSION, ripngd_di.vty_port);
/* Fetch next active thread. */
while (thread_fetch (master, &thread))
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index c8c18928c9..b4f82575a5 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -3081,9 +3081,6 @@ ripng_routemap_update (const char *unused)
void
ripng_init ()
{
- /* Randomize. */
- srandom (time (NULL));
-
/* Install RIPNG_NODE. */
install_node (&cmd_ripng_node, ripng_config_write);
diff --git a/tests/bgpd/test_aspath.c b/tests/bgpd/test_aspath.c
index f3999cbcff..e5ff6a1377 100644
--- a/tests/bgpd/test_aspath.c
+++ b/tests/bgpd/test_aspath.c
@@ -1332,7 +1332,7 @@ main (void)
{
int i = 0;
qobj_init ();
- bgp_master_init ();
+ bgp_master_init (thread_master_create ());
master = bm->master;
bgp_option_set (BGP_OPT_NO_LISTEN);
bgp_attr_init ();
diff --git a/tests/bgpd/test_capability.c b/tests/bgpd/test_capability.c
index f83dee5e1c..c3de6a16e8 100644
--- a/tests/bgpd/test_capability.c
+++ b/tests/bgpd/test_capability.c
@@ -650,7 +650,7 @@ main (void)
qobj_init ();
master = thread_master_create ();
- bgp_master_init ();
+ bgp_master_init (master);
vrf_init ();
bgp_option_set (BGP_OPT_NO_LISTEN);
diff --git a/tests/bgpd/test_mp_attr.c b/tests/bgpd/test_mp_attr.c
index 883cac0cc6..6824c11fea 100644
--- a/tests/bgpd/test_mp_attr.c
+++ b/tests/bgpd/test_mp_attr.c
@@ -750,7 +750,7 @@ main (void)
qobj_init ();
master = thread_master_create ();
- bgp_master_init ();
+ bgp_master_init (master);
vrf_init ();
bgp_option_set (BGP_OPT_NO_LISTEN);
bgp_attr_init ();
diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c
index f9eb1534f3..a2fd66528c 100644
--- a/tests/bgpd/test_mpath.c
+++ b/tests/bgpd/test_mpath.c
@@ -379,7 +379,7 @@ global_test_init (void)
qobj_init ();
master = thread_master_create ();
zclient = zclient_new(master);
- bgp_master_init ();
+ bgp_master_init (master);
vrf_init ();
bgp_option_set (BGP_OPT_NO_LISTEN);
diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c
index f61dd3858b..f6ea77b605 100644
--- a/watchfrr/watchfrr.c
+++ b/watchfrr/watchfrr.c
@@ -26,6 +26,7 @@
#include <lib/version.h>
#include "command.h"
#include "memory_vty.h"
+#include "libfrr.h"
#include <getopt.h>
#include <sys/un.h>
@@ -202,13 +203,10 @@ static int wakeup_send_echo(struct thread *t_wakeup);
static void try_restart(struct daemon *dmn);
static void phase_check(void);
-static int usage(const char *progname, int status)
+static const char *progname;
+static void printhelp(FILE *target)
{
- if (status != 0)
- fprintf(stderr, "Try `%s --help' for more information.\n",
- progname);
- else {
- printf("Usage : %s [OPTION...] <daemon name> ...\n\n\
+ fprintf(target, "Usage : %s [OPTION...] <daemon name> ...\n\n\
Watchdog program to monitor status of frr daemons and try to restart\n\
them if they are down or unresponsive. It determines whether a daemon is\n\
up based on whether it can connect to the daemon's vty unix stream socket.\n\
@@ -254,7 +252,7 @@ a restart is attempted: if the time since the last restart attempt exceeds\n\
twice the -M value, then the restart delay is set to the -m value.\n\
Otherwise, the interval is doubled (but capped at the -M value).\n\n", progname, mode_str[0], progname, mode_str[1], progname, mode_str[2], progname, mode_str[3], progname, mode_str[4], progname, mode_str[2], mode_str[3]);
- printf("Options:\n\
+ fprintf(target, "Options:\n\
-d, --daemon Run in daemon mode. In this mode, error messages are sent\n\
to syslog instead of stdout.\n\
-S, --statedir Set the vty socket directory (default is %s)\n\
@@ -313,9 +311,6 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n", progname,
passing command-line arguments with embedded spaces.\n\
-v, --version Print program version\n\
-h, --help Display this help and exit\n", VTYDIR, DEFAULT_LOGLEVEL, LOG_EMERG, LOG_DEBUG, LOG_DEBUG, DEFAULT_MIN_RESTART, DEFAULT_MAX_RESTART, DEFAULT_PERIOD, DEFAULT_TIMEOUT, DEFAULT_RESTART_TIMEOUT, DEFAULT_PIDFILE);
- }
-
- return status;
}
static pid_t run_background(char *shell_cmd)
@@ -1011,38 +1006,48 @@ struct zebra_privs_t watchfrr_privs = {
#endif
};
+static struct quagga_signal_t watchfrr_signals[] = {
+ {
+ .signal = SIGINT,
+ .handler = sigint,
+ },
+ {
+ .signal = SIGTERM,
+ .handler = sigint,
+ },
+ {
+ .signal = SIGCHLD,
+ .handler = sigchild,
+ },
+};
+
+FRR_DAEMON_INFO(watchfrr, WATCHFRR,
+ .flags = FRR_NO_PRIVSEP | FRR_NO_TCPVTY,
+
+ .printhelp = printhelp,
+ .copyright = "Copyright 2004 Andrew J. Schorr",
+
+ .signals = watchfrr_signals,
+ .n_signals = array_size(watchfrr_signals),
+
+ .privs = &watchfrr_privs,
+)
+
int main(int argc, char **argv)
{
- const char *progname;
int opt;
int daemon_mode = 0;
const char *pidfile = DEFAULT_PIDFILE;
const char *special = "zebra";
const char *blankstr = NULL;
- static struct quagga_signal_t my_signals[] = {
- {
- .signal = SIGINT,
- .handler = sigint,
- },
- {
- .signal = SIGTERM,
- .handler = sigint,
- },
- {
- .signal = SIGCHLD,
- .handler = sigchild,
- },
- };
- if ((progname = strrchr(argv[0], '/')) != NULL)
- progname++;
- else
- progname = argv[0];
+ frr_preinit(&watchfrr_di, argc, argv);
+ progname = watchfrr_di.progname;
+
+ frr_opt_add("aAb:dek:l:m:M:i:p:r:R:S:s:t:T:z", longopts, "");
gs.restart.name = "all";
- while ((opt =
- getopt_long(argc, argv, "aAb:dek:l:m:M:i:p:r:R:S:s:t:T:zvh",
- longopts, 0)) != EOF) {
+ while ((opt = frr_getopt(argc, argv, NULL)) != EOF) {
switch (opt) {
case 0:
break;
@@ -1051,7 +1056,7 @@ int main(int argc, char **argv)
&& (gs.mode != MODE_SEPARATE_RESTART)) {
fputs("Ambiguous operating mode selected.\n",
stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.mode = MODE_PHASED_ZEBRA_RESTART;
break;
@@ -1060,7 +1065,7 @@ int main(int argc, char **argv)
&& (gs.mode != MODE_SEPARATE_RESTART)) {
fputs("Ambiguous operating mode selected.\n",
stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.mode = MODE_PHASED_ALL_RESTART;
break;
@@ -1078,7 +1083,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid kill command, must contain '%%s': %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.stop_command = optarg;
break;
@@ -1092,7 +1097,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid loglevel argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
break;
@@ -1106,7 +1111,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid min_restart_interval argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
break;
@@ -1120,7 +1125,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid max_restart_interval argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
break;
@@ -1133,7 +1138,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid interval argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.period = 1000 * period;
}
@@ -1146,13 +1151,13 @@ int main(int argc, char **argv)
(gs.mode == MODE_SEPARATE_RESTART)) {
fputs("Ambiguous operating mode selected.\n",
stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
if (!valid_command(optarg)) {
fprintf(stderr,
"Invalid restart command, must contain '%%s': %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.restart_command = optarg;
if (gs.mode == MODE_MONITOR)
@@ -1162,13 +1167,13 @@ int main(int argc, char **argv)
if (gs.mode != MODE_MONITOR) {
fputs("Ambiguous operating mode selected.\n",
stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
if (strchr(optarg, '%')) {
fprintf(stderr,
"Invalid restart-all arg, must not contain '%%s': %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.restart_command = optarg;
gs.mode = MODE_GLOBAL_RESTART;
@@ -1178,7 +1183,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid start command, must contain '%%s': %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
gs.start_command = optarg;
break;
@@ -1194,7 +1199,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid timeout argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
break;
@@ -1208,29 +1213,23 @@ int main(int argc, char **argv)
fprintf(stderr,
"Invalid restart timeout argument: %s\n",
optarg);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
break;
case 'z':
gs.unresponsive_restart = 1;
break;
- case 'v':
- printf("%s version %s\n", progname, FRR_VERSION);
- puts("Copyright 2004 Andrew J. Schorr");
- return 0;
- case 'h':
- return usage(progname, 0);
default:
fputs("Invalid option.\n", stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
}
if (gs.unresponsive_restart && (gs.mode == MODE_MONITOR)) {
fputs("Option -z requires a -r or -R restart option.\n",
stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
switch (gs.mode) {
case MODE_MONITOR:
@@ -1238,7 +1237,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"No kill/(re)start commands needed for %s mode.\n",
mode_str[gs.mode]);
- return usage(progname, 1);
+ frr_help_exit(1);
}
break;
case MODE_GLOBAL_RESTART:
@@ -1247,7 +1246,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"No start/kill commands needed in [%s] mode.\n",
mode_str[gs.mode]);
- return usage(progname, 1);
+ frr_help_exit(1);
}
break;
case MODE_PHASED_ZEBRA_RESTART:
@@ -1257,7 +1256,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Need start, kill, and restart commands in [%s] mode.\n",
mode_str[gs.mode]);
- return usage(progname, 1);
+ frr_help_exit(1);
}
break;
}
@@ -1276,17 +1275,25 @@ int main(int argc, char **argv)
gs.restart.interval = gs.min_restart_interval;
- zprivs_init(&watchfrr_privs);
+ master = frr_init();
+
+ zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
+ if (daemon_mode) {
+ zlog_set_level(NULL, ZLOG_DEST_SYSLOG, MIN(gs.loglevel, LOG_DEBUG));
+ if (daemon (0, 0) < 0) {
+ fprintf(stderr, "Watchquagga daemon failed: %s",
+ strerror(errno));
+ exit (1);
+ }
+ } else
+ zlog_set_level(NULL, ZLOG_DEST_STDOUT, MIN(gs.loglevel, LOG_DEBUG));
- master = thread_master_create();
cmd_init(-1);
memory_init();
vty_init(master);
watchfrr_vty_init();
- vty_serv_sock(NULL, 0, WATCHFRR_VTYSH_PATH);
- signal_init(master, array_size(my_signals), my_signals);
- srandom(time(NULL));
+ frr_vty_serv(WATCHFRR_VTYSH_PATH);
{
int i;
@@ -1324,31 +1331,16 @@ int main(int argc, char **argv)
}
if (!gs.daemons) {
fputs("Must specify one or more daemons to monitor.\n", stderr);
- return usage(progname, 1);
+ frr_help_exit(1);
}
if (((gs.mode == MODE_PHASED_ZEBRA_RESTART) ||
(gs.mode == MODE_PHASED_ALL_RESTART)) && !gs.special) {
fprintf(stderr,
"In mode [%s], but cannot find master daemon %s\n",
mode_str[gs.mode], special);
- return usage(progname, 1);
+ frr_help_exit(1);
}
- zlog_default = openzlog(progname, ZLOG_WATCHFRR, 0,
- LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
- zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
- if (daemon_mode) {
- zlog_set_level(NULL, ZLOG_DEST_SYSLOG,
- MIN(gs.loglevel, LOG_DEBUG));
- if (daemon(0, 0) < 0) {
- fprintf(stderr, "Watchfrr daemon failed: %s",
- strerror(errno));
- exit(1);
- }
- } else
- zlog_set_level(NULL, ZLOG_DEST_STDOUT,
- MIN(gs.loglevel, LOG_DEBUG));
-
/* Make sure we're not already running. */
pid_output(pidfile);
diff --git a/zebra/main.c b/zebra/main.c
index b72ce84cd6..06a260f370 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -35,7 +35,7 @@
#include "privs.h"
#include "sigevent.h"
#include "vrf.h"
-#include "sockopt.h"
+#include "libfrr.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"
@@ -60,9 +60,6 @@ struct zebra_t zebrad =
/* process id. */
pid_t pid;
-/* VTY Socket prefix */
-char vty_sock_path[MAXPATHLEN] = ZEBRA_VTYSH_PATH;
-
/* Pacify zclient.o in libfrr, which expects this variable. */
struct thread_master *master;
@@ -81,7 +78,6 @@ u_int32_t nl_rcvbufsize = 4194304;
#endif /* HAVE_NETLINK */
/* Command line options. */
-#define OPTION_VTYSOCK 1000
struct option longopts[] =
{
{ "batch", no_argument, NULL, 'b'},
@@ -92,19 +88,12 @@ struct option longopts[] =
{ "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'},
- { "vty_socket", required_argument, NULL, OPTION_VTYSOCK },
{ "ecmp", required_argument, NULL, 'e'},
{ "retain", no_argument, NULL, 'r'},
{ "dryrun", no_argument, NULL, 'C'},
#ifdef HAVE_NETLINK
{ "nl-bufsize", required_argument, NULL, 's'},
#endif /* HAVE_NETLINK */
- { "user", required_argument, NULL, 'u'},
- { "group", required_argument, NULL, 'g'},
- { "version", no_argument, NULL, 'v'},
{ 0 }
};
@@ -138,46 +127,6 @@ const char *pid_file = PATH_ZEBRA_PID;
unsigned int multipath_num = MULTIPATH_NUM;
-/* Help information display. */
-static void
-usage (char *progname, int status)
-{
- if (status != 0)
- fprintf (stderr, "Try `%s --help' for more information.\n", progname);
- else
- {
- printf ("Usage : %s [OPTION...]\n\n"\
- "Daemon which manages kernel routing table management and "\
- "redistribution between different routing protocols.\n\n"\
- "-b, --batch Runs in batch mode\n"\
- "-d, --daemon Runs in daemon mode\n"\
- "-a, --allow_delete Allow other processes to delete Quagga Routes\n" \
- "-f, --config_file Set configuration file name\n"\
- "-F, --fpm_format Set fpm format to 'netlink' or 'protobuf'\n"\
- "-i, --pid_file Set process identifier file name\n"\
- "-z, --socket Set path of zebra socket\n"\
- "-k, --keep_kernel Don't delete old routes which installed by "\
- "zebra.\n"\
- "-C, --dryrun Check configuration for validity and exit\n"\
- "-A, --vty_addr Set vty's bind address\n"\
- "-P, --vty_port Set vty's port number\n"\
- " --vty_socket Override vty socket path\n"\
- "-r, --retain When program terminates, retain added route "\
- "by zebra.\n"\
- "-u, --user User to run as\n"\
- "-g, --group Group to run as\n", progname);
-#ifdef HAVE_NETLINK
- printf ("-s, --nl-bufsize Set netlink receive buffer size\n");
-#endif /* HAVE_NETLINK */
- printf ("-v, --version Print program version\n"\
- "-h, --help Display this help and exit\n"\
- "\n"\
- "Report bugs to %s\n", FRR_BUG_ADDRESS);
- }
-
- exit (status);
-}
-
/* SIGHUP handler. */
static void
sighup (void)
@@ -262,44 +211,55 @@ struct quagga_signal_t zebra_signals[] =
},
};
+FRR_DAEMON_INFO(zebra, ZEBRA,
+ .vty_port = ZEBRA_VTY_PORT,
+
+ .proghelp = "Daemon which manages kernel routing table management "
+ "and\nredistribution between different routing protocols.",
+
+ .signals = zebra_signals,
+ .n_signals = array_size(zebra_signals),
+
+ .privs = &zserv_privs,
+)
+
/* Main startup routine. */
int
main (int argc, char **argv)
{
- char *p;
- char *vty_addr = NULL;
- int vty_port = ZEBRA_VTY_PORT;
int dryrun = 0;
int batch_mode = 0;
int daemon_mode = 0;
char *config_file = NULL;
- char *progname;
struct thread thread;
char *zserv_path = NULL;
char *fpm_format = NULL;
- /* Set umask before anything for security */
- umask (0027);
-
- /* preserve my name */
- progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
+ frr_preinit(&zebra_di, argc, argv);
- zlog_default = openzlog (progname, ZLOG_ZEBRA, 0,
- LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
- zprivs_init (&zserv_privs);
-#if defined(HAVE_CUMULUS)
- zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
+ frr_opt_add("bdakf:F:i:z:rC"
+#ifdef HAVE_NETLINK
+ "s:"
#endif
+ , longopts,
+ "-b, --batch Runs in batch mode\n"
+ "-d, --daemon Runs in daemon mode\n"
+ "-a, --allow_delete Allow other processes to delete Quagga Routes\n"
+ "-f, --config_file Set configuration file name\n"
+ "-F, --fpm_format Set fpm format to 'netlink' or 'protobuf'\n"
+ "-i, --pid_file Set process identifier file name\n"
+ "-z, --socket Set path of zebra socket\n"
+ "-k, --keep_kernel Don't delete old routes which installed by zebra.\n"
+ "-C, --dryrun Check configuration for validity and exit\n"
+ "-r, --retain When program terminates, retain added route by zebra.\n"
+#ifdef HAVE_NETLINK
+ "-s, --nl-bufsize Set netlink receive buffer size\n"
+#endif /* HAVE_NETLINK */
+ );
- while (1)
+ while (1)
{
- int opt;
-
-#ifdef HAVE_NETLINK
- opt = getopt_long (argc, argv, "bdakf:F:i:z:hA:P:ru:g:vs:C", longopts, 0);
-#else
- opt = getopt_long (argc, argv, "bdakf:F:i:z:hA:P:ru:g:vC", longopts, 0);
-#endif /* HAVE_NETLINK */
+ int opt = frr_getopt(argc, argv, NULL);
if (opt == EOF)
break;
@@ -328,9 +288,6 @@ main (int argc, char **argv)
case 'F':
fpm_format = optarg;
break;
- case 'A':
- vty_addr = optarg;
- break;
case 'e':
multipath_num = atoi (optarg);
if (multipath_num > MULTIPATH_NUM || multipath_num <= 0)
@@ -345,21 +302,6 @@ main (int argc, char **argv)
case 'z':
zserv_path = optarg;
break;
- case 'P':
- /* Deal with atoi() returning 0 on failure, and zebra not
- listening on zebra port... */
- if (strcmp(optarg, "0") == 0)
- {
- vty_port = 0;
- break;
- }
- vty_port = atoi (optarg);
- if (vty_port <= 0 || vty_port > 0xffff)
- vty_port = ZEBRA_VTY_PORT;
- break;
- case OPTION_VTYSOCK:
- set_socket_path(vty_sock_path, ZEBRA_VTYSH_PATH, optarg, sizeof (vty_sock_path));
- break;
case 'r':
retain_mode = 1;
break;
@@ -368,30 +310,14 @@ main (int argc, char **argv)
nl_rcvbufsize = atoi (optarg);
break;
#endif /* HAVE_NETLINK */
- case 'u':
- zserv_privs.user = optarg;
- break;
- case 'g':
- zserv_privs.group = optarg;
- break;
- case 'v':
- print_version (progname);
- exit (0);
- break;
- case 'h':
- usage (progname, 0);
- break;
default:
- usage (progname, 1);
+ frr_help_exit (1);
break;
}
}
- /* Make master thread emulator. */
- zebrad.master = thread_master_create ();
+ zebrad.master = frr_init();
- /* Vty related initialize. */
- signal_init (zebrad.master, array_size(zebra_signals), zebra_signals);
cmd_init (1);
vty_config_lockless ();
vty_init (zebrad.master);
@@ -483,11 +409,10 @@ main (int argc, char **argv)
/* This must be done only after locking pidfile (bug #403). */
zebra_zserv_socket_init (zserv_path);
- /* Make vty server socket. */
- vty_serv_sock (vty_addr, vty_port, vty_sock_path);
+ frr_vty_serv (ZEBRA_VTYSH_PATH);
/* Print banner. */
- zlog_notice ("Zebra %s starting: vty@%d", FRR_VERSION, vty_port);
+ zlog_notice ("Zebra %s starting: vty@%d", FRR_VERSION, zebra_di.vty_port);
while (thread_fetch (zebrad.master, &thread))
thread_call (&thread);