]>
git.proxmox.com Git - mirror_frr.git/blob - lib/libfrr.c
2 * libfrr overall management functions
4 * Copyright (C) 2016 David Lamparter for NetDEF, Inc.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 * Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "memory_vty.h"
32 const char frr_sysconfdir
[] = SYSCONFDIR
;
33 const char frr_vtydir
[] = DAEMON_VTY_DIR
;
35 char config_default
[256];
36 static char pidfile_default
[256];
37 static char vtypath_default
[256];
39 static char comb_optstr
[256];
40 static struct option comb_lo
[64];
41 static struct option
*comb_next_lo
= &comb_lo
[0];
42 static char comb_helpstr
[4096];
47 const struct option
*longopts
;
50 static void opt_extend(const struct optspec
*os
)
52 const struct option
*lo
;
54 strcat(comb_optstr
, os
->optstr
);
55 strcat(comb_helpstr
, os
->helpstr
);
56 for (lo
= os
->longopts
; lo
->name
; lo
++)
57 memcpy(comb_next_lo
++, lo
, sizeof(*lo
));
61 #define OPTION_VTYSOCK 1000
63 static const struct option lo_always
[] = {
64 { "help", no_argument
, NULL
, 'h' },
65 { "version", no_argument
, NULL
, 'v' },
66 { "daemon", no_argument
, NULL
, 'd' },
67 { "vty_socket", required_argument
, NULL
, OPTION_VTYSOCK
},
70 static const struct optspec os_always
= {
72 " -h, --help Display this help and exit\n"
73 " -v, --version Print program version\n"
74 " -d, --daemon Runs in daemon mode\n"
75 " --vty_socket Override vty socket path\n",
80 static const struct option lo_cfg_pid_dry
[] = {
81 { "pid_file", required_argument
, NULL
, 'i' },
82 { "config_file", required_argument
, NULL
, 'f' },
83 { "dryrun", no_argument
, NULL
, 'C' },
86 static const struct optspec os_cfg_pid_dry
= {
88 " -f, --config_file Set configuration file name\n"
89 " -i, --pid_file Set process identifier file name\n"
90 " -C, --dryrun Check configuration for validity and exit\n",
95 static const struct option lo_zclient
[] = {
96 { "socket", required_argument
, NULL
, 'z' },
99 static const struct optspec os_zclient
= {
101 " -z, --socket Set path of zebra socket\n",
106 static const struct option lo_vty
[] = {
107 { "vty_addr", required_argument
, NULL
, 'A'},
108 { "vty_port", required_argument
, NULL
, 'P'},
111 static const struct optspec os_vty
= {
113 " -A, --vty_addr Set vty's bind address\n"
114 " -P, --vty_port Set vty's port number\n",
119 static const struct option lo_user
[] = {
120 { "user", required_argument
, NULL
, 'u'},
121 { "group", required_argument
, NULL
, 'g'},
124 static const struct optspec os_user
= {
126 " -u, --user User to run as\n"
127 " -g, --group Group to run as\n",
132 static struct frr_daemon_info
*di
= NULL
;
134 void frr_preinit(struct frr_daemon_info
*daemon
, int argc
, char **argv
)
138 /* basename(), opencoded. */
139 char *p
= strrchr(argv
[0], '/');
140 di
->progname
= p
? p
+ 1 : argv
[0];
144 opt_extend(&os_always
);
145 if (!(di
->flags
& FRR_NO_CFG_PID_DRY
))
146 opt_extend(&os_cfg_pid_dry
);
147 if (!(di
->flags
& FRR_NO_PRIVSEP
))
148 opt_extend(&os_user
);
149 if (!(di
->flags
& FRR_NO_ZCLIENT
))
150 opt_extend(&os_zclient
);
151 if (!(di
->flags
& FRR_NO_TCPVTY
))
154 snprintf(config_default
, sizeof(config_default
), "%s/%s.conf",
155 frr_sysconfdir
, di
->name
);
156 snprintf(pidfile_default
, sizeof(pidfile_default
), "%s/%s.pid",
157 frr_vtydir
, di
->name
);
160 void frr_opt_add(const char *optstr
, const struct option
*longopts
,
163 const struct optspec main_opts
= { optstr
, helpstr
, longopts
};
164 opt_extend(&main_opts
);
167 void frr_help_exit(int status
)
169 FILE *target
= status
? stderr
: stdout
;
172 fprintf(stderr
, "Invalid options.\n\n");
175 di
->printhelp(target
);
177 fprintf(target
, "Usage: %s [OPTION...]\n\n%s%s%s\n\n%s",
180 di
->copyright
? "\n\n" : "",
181 di
->copyright
? di
->copyright
: "",
183 fprintf(target
, "\nReport bugs to %s\n", FRR_BUG_ADDRESS
);
187 static int errors
= 0;
189 static int frr_opt(int opt
)
191 static int vty_port_set
= 0;
192 static int vty_addr_set
= 0;
200 print_version(di
->progname
);
207 if (di
->flags
& FRR_NO_CFG_PID_DRY
)
209 di
->pid_file
= optarg
;
212 if (di
->flags
& FRR_NO_CFG_PID_DRY
)
214 di
->config_file
= optarg
;
217 if (di
->flags
& FRR_NO_CFG_PID_DRY
)
222 if (di
->flags
& FRR_NO_ZCLIENT
)
224 zclient_serv_path_set(optarg
);
227 if (di
->flags
& FRR_NO_TCPVTY
)
230 fprintf(stderr
, "-A option specified more than once!\n");
235 di
->vty_addr
= optarg
;
238 if (di
->flags
& FRR_NO_TCPVTY
)
241 fprintf(stderr
, "-P option specified more than once!\n");
246 di
->vty_port
= strtoul(optarg
, &err
, 0);
247 if (*err
|| !*optarg
) {
248 fprintf(stderr
, "invalid port number \"%s\" for -P option\n",
255 if (di
->vty_sock_path
) {
256 fprintf(stderr
, "--vty_socket option specified more than once!\n");
260 di
->vty_sock_path
= optarg
;
263 if (di
->flags
& FRR_NO_PRIVSEP
)
265 di
->privs
->user
= optarg
;
268 if (di
->flags
& FRR_NO_PRIVSEP
)
270 di
->privs
->group
= optarg
;
278 int frr_getopt(int argc
, char * const argv
[], int *longindex
)
283 comb_next_lo
->name
= NULL
;
286 opt
= getopt_long(argc
, argv
, comb_optstr
, comb_lo
, &lidx
);
291 if (opt
== -1 && errors
)
298 struct thread_master
*frr_init(void)
300 struct thread_master
*master
;
304 openzlog (di
->progname
, di
->logname
, di
->instance
,
305 LOG_CONS
|LOG_NDELAY
|LOG_PID
, LOG_DAEMON
);
306 #if defined(HAVE_CUMULUS)
307 zlog_set_level (ZLOG_DEST_SYSLOG
, zlog_default
->default_lvl
);
310 zprivs_init(di
->privs
);
312 master
= thread_master_create();
313 signal_init(master
, di
->n_signals
, di
->signals
);
315 if (di
->flags
& FRR_LIMITED_CLI
)
325 void frr_config_fork(void)
328 snprintf(config_default
, sizeof(config_default
), "%s/%s-%d.conf",
329 frr_sysconfdir
, di
->name
, di
->instance
);
330 snprintf(pidfile_default
, sizeof(pidfile_default
), "%s/%s-%d.pid",
331 frr_vtydir
, di
->name
, di
->instance
);
334 vty_read_config(di
->config_file
, config_default
);
336 /* Don't start execution if we are in dry-run mode */
341 if (di
->daemon_mode
&& daemon (0, 0) < 0) {
342 zlog_err("Zebra daemon failed: %s", strerror(errno
));
347 di
->pid_file
= pidfile_default
;
348 pid_output (di
->pid_file
);
351 void frr_vty_serv(void)
353 /* allow explicit override of vty_path in the future
354 * (not currently set anywhere) */
357 dir
= di
->vty_sock_path
? di
->vty_sock_path
: frr_vtydir
;
360 snprintf(vtypath_default
, sizeof(vtypath_default
),
362 dir
, di
->name
, di
->instance
);
364 snprintf(vtypath_default
, sizeof(vtypath_default
),
365 "%s/%s.vty", dir
, di
->name
);
367 di
->vty_path
= vtypath_default
;
370 vty_serv_sock(di
->vty_addr
, di
->vty_port
, di
->vty_path
);
373 void frr_run(struct thread_master
*master
)
375 char instanceinfo
[64] = "";
380 snprintf(instanceinfo
, sizeof(instanceinfo
), "instance %u ",
383 zlog_notice("%s %s starting: %svty@%d%s",
390 struct thread thread
;
391 while (thread_fetch(master
, &thread
))
392 thread_call(&thread
);