Support SIGHUP for reloading /etc/rtadvd.conf.
This commit is contained in:
parent
52737ec557
commit
729d2abb51
@ -141,6 +141,33 @@ dname_labelenc(char *dst, const char *src)
|
||||
memset(p, 0, sizeof(*p)); \
|
||||
} while(0)
|
||||
|
||||
int
|
||||
loadconfig(char *ifl_names[], const int ifl_len)
|
||||
{
|
||||
int i;
|
||||
int idx;
|
||||
int error;
|
||||
|
||||
for (i = 0; i < ifl_len; i++) {
|
||||
idx = if_nametoindex(ifl_names[i]);
|
||||
if (idx == 0) {
|
||||
syslog(LOG_ERR,
|
||||
"<%s> interface %s not found. "
|
||||
"Ignored at this moment.", __func__, ifl_names[i]);
|
||||
continue;
|
||||
}
|
||||
syslog(LOG_INFO,
|
||||
"<%s> loading config for %s.", __func__, ifl_names[i]);
|
||||
error = getconfig(idx);
|
||||
if (error)
|
||||
syslog(LOG_ERR,
|
||||
"<%s> invalid configuration for %s. "
|
||||
"Ignored at this moment.", __func__, ifl_names[i]);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rmconfig(int idx)
|
||||
{
|
||||
@ -207,6 +234,7 @@ getconfig(int idx)
|
||||
int stat, i;
|
||||
char tbuf[BUFSIZ];
|
||||
struct rainfo *rai;
|
||||
struct rainfo *rai_old;
|
||||
long val;
|
||||
int64_t val64;
|
||||
char buf[BUFSIZ];
|
||||
@ -220,6 +248,10 @@ getconfig(int idx)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(rai_old, &railist, rai_next)
|
||||
if (idx == rai_old->rai_ifindex)
|
||||
break;
|
||||
|
||||
if ((stat = agetent(tbuf, intface)) <= 0) {
|
||||
memset(tbuf, 0, sizeof(tbuf));
|
||||
syslog(LOG_INFO,
|
||||
@ -254,7 +286,7 @@ getconfig(int idx)
|
||||
syslog(LOG_ERR,
|
||||
"<%s> can't get information of %s",
|
||||
__func__, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_rai;
|
||||
}
|
||||
rai->rai_ifindex = rai->rai_sdl->sdl_index;
|
||||
} else
|
||||
@ -280,7 +312,7 @@ getconfig(int idx)
|
||||
"<%s> maxinterval (%ld) on %s is invalid "
|
||||
"(must be between %u and %u)", __func__, val,
|
||||
intface, MIN_MAXINTERVAL, MAX_MAXINTERVAL);
|
||||
return (-1);
|
||||
goto getconfig_free_rai;
|
||||
}
|
||||
rai->rai_maxinterval = (u_int)val;
|
||||
|
||||
@ -292,7 +324,7 @@ getconfig(int idx)
|
||||
"(must be between %d and %d)",
|
||||
__func__, val, intface, MIN_MININTERVAL,
|
||||
(rai->rai_maxinterval * 3) / 4);
|
||||
return (-1);
|
||||
goto getconfig_free_rai;
|
||||
}
|
||||
rai->rai_mininterval = (u_int)val;
|
||||
|
||||
@ -311,7 +343,7 @@ getconfig(int idx)
|
||||
if ((val & ND_RA_FLAG_RTPREF_HIGH)) {
|
||||
syslog(LOG_ERR, "<%s> the \'h\' and \'l\'"
|
||||
" router flags are exclusive", __func__);
|
||||
return (-1);
|
||||
goto getconfig_free_rai;
|
||||
}
|
||||
val |= ND_RA_FLAG_RTPREF_LOW;
|
||||
}
|
||||
@ -328,7 +360,7 @@ getconfig(int idx)
|
||||
if (rai->rai_rtpref == ND_RA_FLAG_RTPREF_RSV) {
|
||||
syslog(LOG_ERR, "<%s> invalid router preference (%02x) on %s",
|
||||
__func__, rai->rai_rtpref, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_rai;
|
||||
}
|
||||
|
||||
MAYHAVE(val, "rltime", rai->rai_maxinterval * 3);
|
||||
@ -339,7 +371,7 @@ getconfig(int idx)
|
||||
"(must be 0 or between %d and %d)",
|
||||
__func__, val, intface, rai->rai_maxinterval,
|
||||
MAXROUTERLIFETIME);
|
||||
return (-1);
|
||||
goto getconfig_free_rai;
|
||||
}
|
||||
rai->rai_lifetime = val & 0xffff;
|
||||
|
||||
@ -349,7 +381,7 @@ getconfig(int idx)
|
||||
"<%s> reachable time (%ld) on %s is invalid "
|
||||
"(must be no greater than %d)",
|
||||
__func__, val, intface, MAXREACHABLETIME);
|
||||
return (-1);
|
||||
goto getconfig_free_rai;
|
||||
}
|
||||
rai->rai_reachabletime = (u_int32_t)val;
|
||||
|
||||
@ -357,7 +389,7 @@ getconfig(int idx)
|
||||
if (val64 < 0 || val64 > 0xffffffff) {
|
||||
syslog(LOG_ERR, "<%s> retrans time (%lld) on %s out of range",
|
||||
__func__, (long long)val64, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_rai;
|
||||
}
|
||||
rai->rai_retranstimer = (u_int32_t)val64;
|
||||
|
||||
@ -365,7 +397,7 @@ getconfig(int idx)
|
||||
syslog(LOG_ERR,
|
||||
"<%s> mobile-ip6 configuration not supported",
|
||||
__func__);
|
||||
return (-1);
|
||||
goto getconfig_free_rai;
|
||||
}
|
||||
/* prefix information */
|
||||
|
||||
@ -395,14 +427,14 @@ getconfig(int idx)
|
||||
syslog(LOG_ERR,
|
||||
"<%s> inet_pton failed for %s",
|
||||
__func__, addr);
|
||||
return (-1);
|
||||
goto getconfig_free_pfx;
|
||||
}
|
||||
if (IN6_IS_ADDR_MULTICAST(&pfx->pfx_prefix)) {
|
||||
syslog(LOG_ERR,
|
||||
"<%s> multicast prefix (%s) must "
|
||||
"not be advertised on %s",
|
||||
__func__, addr, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_pfx;
|
||||
}
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&pfx->pfx_prefix))
|
||||
syslog(LOG_NOTICE,
|
||||
@ -416,7 +448,7 @@ getconfig(int idx)
|
||||
syslog(LOG_ERR, "<%s> prefixlen (%ld) for %s "
|
||||
"on %s out of range",
|
||||
__func__, val, addr, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_pfx;
|
||||
}
|
||||
pfx->pfx_prefixlen = (int)val;
|
||||
|
||||
@ -441,7 +473,7 @@ getconfig(int idx)
|
||||
"%s/%d on %s is out of range",
|
||||
__func__, (long long)val64,
|
||||
addr, pfx->pfx_prefixlen, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_pfx;
|
||||
}
|
||||
pfx->pfx_validlifetime = (u_int32_t)val64;
|
||||
|
||||
@ -461,7 +493,7 @@ getconfig(int idx)
|
||||
"is out of range",
|
||||
__func__, (long long)val64,
|
||||
addr, pfx->pfx_prefixlen, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_pfx;
|
||||
}
|
||||
pfx->pfx_preflifetime = (u_int32_t)val64;
|
||||
|
||||
@ -475,6 +507,9 @@ getconfig(int idx)
|
||||
/* link into chain */
|
||||
TAILQ_INSERT_TAIL(&rai->rai_prefix, pfx, pfx_next);
|
||||
rai->rai_pfxs++;
|
||||
continue;
|
||||
getconfig_free_pfx:
|
||||
free(pfx);
|
||||
}
|
||||
if (rai->rai_advifprefix && rai->rai_pfxs == 0)
|
||||
get_prefix(rai);
|
||||
@ -484,7 +519,7 @@ getconfig(int idx)
|
||||
syslog(LOG_ERR,
|
||||
"<%s> mtu (%ld) on %s out of range",
|
||||
__func__, val, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_rai;
|
||||
}
|
||||
rai->rai_linkmtu = (u_int32_t)val;
|
||||
if (rai->rai_linkmtu == 0) {
|
||||
@ -501,7 +536,7 @@ getconfig(int idx)
|
||||
"be between least MTU (%d) and physical link MTU (%d)",
|
||||
__func__, (unsigned long)rai->rai_linkmtu, intface,
|
||||
IPV6_MMTU, rai->rai_phymtu);
|
||||
return (-1);
|
||||
goto getconfig_free_rai;
|
||||
}
|
||||
|
||||
#ifdef SIOCSIFINFO_IN6
|
||||
@ -553,14 +588,10 @@ getconfig(int idx)
|
||||
/* allocate memory to store prefix information */
|
||||
ELM_MALLOC(rti, exit(1));
|
||||
|
||||
/* link into chain */
|
||||
TAILQ_INSERT_TAIL(&rai->rai_route, rti, rti_next);
|
||||
rai->rai_routes++;
|
||||
|
||||
if (inet_pton(AF_INET6, addr, &rti->rti_prefix) != 1) {
|
||||
syslog(LOG_ERR, "<%s> inet_pton failed for %s",
|
||||
__func__, addr);
|
||||
return (-1);
|
||||
goto getconfig_free_rti;
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
@ -575,14 +606,14 @@ getconfig(int idx)
|
||||
"<%s> multicast route (%s) must "
|
||||
"not be advertised on %s",
|
||||
__func__, addr, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_rti;
|
||||
}
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&rti->prefix)) {
|
||||
syslog(LOG_NOTICE,
|
||||
"<%s> link-local route (%s) will "
|
||||
"be advertised on %s",
|
||||
__func__, addr, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_rti;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -602,7 +633,7 @@ getconfig(int idx)
|
||||
syslog(LOG_ERR, "<%s> prefixlen (%ld) for %s on %s "
|
||||
"out of range",
|
||||
__func__, val, addr, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_rti;
|
||||
}
|
||||
rti->rti_prefixlen = (int)val;
|
||||
|
||||
@ -617,7 +648,7 @@ getconfig(int idx)
|
||||
"<%s> the \'h\' and \'l\' route"
|
||||
" preferences are exclusive",
|
||||
__func__);
|
||||
exit(1);
|
||||
goto getconfig_free_rti;
|
||||
}
|
||||
val |= ND_RA_FLAG_RTPREF_LOW;
|
||||
}
|
||||
@ -638,7 +669,7 @@ getconfig(int idx)
|
||||
"for %s/%d on %s",
|
||||
__func__, rti->rti_rtpref, addr,
|
||||
rti->rti_prefixlen, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_rti;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -665,9 +696,16 @@ getconfig(int idx)
|
||||
syslog(LOG_ERR, "<%s> route lifetime (%lld) for "
|
||||
"%s/%d on %s out of range", __func__,
|
||||
(long long)val64, addr, rti->rti_prefixlen, intface);
|
||||
return (-1);
|
||||
goto getconfig_free_rti;
|
||||
}
|
||||
rti->rti_ltime = (u_int32_t)val64;
|
||||
|
||||
/* link into chain */
|
||||
TAILQ_INSERT_TAIL(&rai->rai_route, rti, rti_next);
|
||||
rai->rai_routes++;
|
||||
continue;
|
||||
getconfig_free_rti:
|
||||
free(rti);
|
||||
}
|
||||
#endif
|
||||
/* DNS server and DNS search list information */
|
||||
@ -689,12 +727,12 @@ getconfig(int idx)
|
||||
c = strcspn(ap, ",");
|
||||
strncpy(abuf, ap, c);
|
||||
abuf[c] = '\0';
|
||||
ELM_MALLOC(rdna, exit(1));
|
||||
ELM_MALLOC(rdna, goto getconfig_free_rdn);
|
||||
if (inet_pton(AF_INET6, abuf, &rdna->ra_dns) != 1) {
|
||||
syslog(LOG_ERR, "<%s> inet_pton failed for %s",
|
||||
__func__, abuf);
|
||||
free(rdna);
|
||||
return (-1);
|
||||
goto getconfig_free_rdn;
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&rdn->rd_list, rdna, ra_next);
|
||||
}
|
||||
@ -707,12 +745,19 @@ getconfig(int idx)
|
||||
"(must be between %d and %d)",
|
||||
entbuf, val, intface, rai->rai_maxinterval,
|
||||
rai->rai_maxinterval * 2);
|
||||
return (-1);
|
||||
goto getconfig_free_rdn;
|
||||
}
|
||||
rdn->rd_ltime = val;
|
||||
|
||||
/* link into chain */
|
||||
TAILQ_INSERT_TAIL(&rai->rai_rdnss, rdn, rd_next);
|
||||
continue;
|
||||
getconfig_free_rdn:
|
||||
while ((rdna = TAILQ_FIRST(&rdn->rd_list)) != NULL) {
|
||||
TAILQ_REMOVE(&rdn->rd_list, rdna, ra_next);
|
||||
free(rdna);
|
||||
}
|
||||
free(rdn);
|
||||
}
|
||||
|
||||
for (i = -1; i < MAXDNSSLENT ; i++) {
|
||||
@ -734,7 +779,7 @@ getconfig(int idx)
|
||||
c = strcspn(ap, ",");
|
||||
strncpy(abuf, ap, c);
|
||||
abuf[c] = '\0';
|
||||
ELM_MALLOC(dnsa, exit(1));
|
||||
ELM_MALLOC(dnsa, goto getconfig_free_dns);
|
||||
dnsa->da_len = dname_labelenc(dnsa->da_dom, abuf);
|
||||
syslog(LOG_DEBUG, "<%s>: dnsa->da_len = %d", __func__,
|
||||
dnsa->da_len);
|
||||
@ -749,15 +794,46 @@ getconfig(int idx)
|
||||
"(must be between %d and %d)",
|
||||
entbuf, val, intface, rai->rai_maxinterval,
|
||||
rai->rai_maxinterval * 2);
|
||||
return (-1);
|
||||
goto getconfig_free_dns;
|
||||
}
|
||||
dns->dn_ltime = val;
|
||||
|
||||
/* link into chain */
|
||||
TAILQ_INSERT_TAIL(&rai->rai_dnssl, dns, dn_next);
|
||||
continue;
|
||||
getconfig_free_dns:
|
||||
while ((dnsa = TAILQ_FIRST(&dns->dn_list)) != NULL) {
|
||||
TAILQ_REMOVE(&dns->dn_list, dnsa, da_next);
|
||||
free(dnsa);
|
||||
}
|
||||
free(dns);
|
||||
}
|
||||
/* construct the sending packet */
|
||||
make_packet(rai);
|
||||
|
||||
/*
|
||||
* If an entry with the same ifindex exists, remove it first.
|
||||
* Before the removal, RDNSS and DNSSL options with
|
||||
* zero-lifetime will be sent.
|
||||
*/
|
||||
if (rai_old != NULL) {
|
||||
const int retrans = MAX_FINAL_RTR_ADVERTISEMENTS;
|
||||
struct rdnss *rdn;
|
||||
struct dnssl *dns;
|
||||
|
||||
rai_old->rai_lifetime = 0;
|
||||
TAILQ_FOREACH(rdn, &rai_old->rai_rdnss, rd_next)
|
||||
rdn->rd_ltime = 0;
|
||||
TAILQ_FOREACH(dns, &rai_old->rai_dnssl, dn_next)
|
||||
dns->dn_ltime = 0;
|
||||
|
||||
make_packet(rai_old);
|
||||
for (i = 0; i < retrans; i++) {
|
||||
ra_output(rai_old);
|
||||
sleep(MIN_DELAY_BETWEEN_RAS);
|
||||
}
|
||||
rmconfig(idx);
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&railist, rai, rai_next);
|
||||
|
||||
/* set timer */
|
||||
@ -767,6 +843,9 @@ getconfig(int idx)
|
||||
rtadvd_set_timer(&rai->rai_timer->rat_tm, rai->rai_timer);
|
||||
|
||||
return (0);
|
||||
getconfig_free_rai:
|
||||
free(rai);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
extern int getconfig(int);
|
||||
extern int rmconfig(int);
|
||||
extern int loadconfig(char *[], const int);
|
||||
extern void delete_prefix(struct prefix *);
|
||||
extern void invalidate_prefix(struct prefix *);
|
||||
extern void update_prefix(struct prefix *);
|
||||
|
@ -169,6 +169,18 @@ or the file specified with option
|
||||
.Fl F .
|
||||
.Pp
|
||||
Use
|
||||
.Dv SIGHUP
|
||||
to reload the configuration file
|
||||
.Pa /etc/rtadvd.conf .
|
||||
If an invalid parameter is found in the configuration file upon the reload,
|
||||
the entry will be ignored and the old configuration will be used.
|
||||
When parameters in an existing entry are updated,
|
||||
.Nm
|
||||
will send Router Advertisement messages with the old configuration but
|
||||
zero router lifetime to the interface first, and then start to send a new
|
||||
message.
|
||||
.Pp
|
||||
Use
|
||||
.Dv SIGTERM
|
||||
to kill
|
||||
.Nm
|
||||
|
@ -83,6 +83,7 @@ static u_char *sndcmsgbuf = NULL;
|
||||
static size_t sndcmsgbuflen;
|
||||
volatile sig_atomic_t do_dump;
|
||||
volatile sig_atomic_t do_die;
|
||||
volatile sig_atomic_t do_reload;
|
||||
struct msghdr sndmhdr;
|
||||
struct iovec rcviov[2];
|
||||
struct iovec sndiov[2];
|
||||
@ -161,6 +162,7 @@ struct sockaddr_in6 sin6_sitelocal_allrouters = {
|
||||
.sin6_addr = IN6ADDR_SITELOCAL_ALLROUTERS_INIT,
|
||||
};
|
||||
|
||||
static void set_reload(int);
|
||||
static void set_die(int);
|
||||
static void die(void);
|
||||
static void sock_open(void);
|
||||
@ -175,7 +177,6 @@ static int prefix_check(struct nd_opt_prefix_info *, struct rainfo *,
|
||||
static int nd6_options(struct nd_opt_hdr *, int,
|
||||
union nd_opt *, u_int32_t);
|
||||
static void free_ndopts(union nd_opt *);
|
||||
static void ra_output(struct rainfo *);
|
||||
static void rtmsg_input(void);
|
||||
static void rtadvd_set_dump_file(int);
|
||||
static void set_short_delay(struct rainfo *);
|
||||
@ -197,7 +198,6 @@ main(int argc, char *argv[])
|
||||
int i, ch;
|
||||
int fflag = 0, logopt;
|
||||
pid_t pid, otherpid;
|
||||
int error;
|
||||
|
||||
/* get command line options and arguments */
|
||||
while ((ch = getopt(argc, argv, "c:dDfF:M:p:Rs")) != -1) {
|
||||
@ -273,22 +273,7 @@ main(int argc, char *argv[])
|
||||
ifl_names = argv;
|
||||
ifl_len = argc;
|
||||
|
||||
for (i = 0; i < ifl_len; i++) {
|
||||
int idx;
|
||||
|
||||
idx = if_nametoindex(ifl_names[i]);
|
||||
if (idx == 0) {
|
||||
syslog(LOG_INFO,
|
||||
"<%s> interface %s not found."
|
||||
"Ignored at this moment.", __func__, ifl_names[i]);
|
||||
continue;
|
||||
}
|
||||
error = getconfig(idx);
|
||||
if (error)
|
||||
syslog(LOG_INFO,
|
||||
"<%s> invalid configuration for %s."
|
||||
"Ignored at this moment.", __func__, ifl_names[i]);
|
||||
}
|
||||
loadconfig(argv, argc);
|
||||
|
||||
pfh = pidfile_open(pidfilename, 0600, &otherpid);
|
||||
if (pfh == NULL) {
|
||||
@ -343,6 +328,7 @@ main(int argc, char *argv[])
|
||||
#endif
|
||||
signal(SIGTERM, set_die);
|
||||
signal(SIGUSR1, rtadvd_set_dump_file);
|
||||
signal(SIGHUP, set_reload);
|
||||
|
||||
while (1) {
|
||||
#ifndef HAVE_POLL_H
|
||||
@ -358,6 +344,11 @@ main(int argc, char *argv[])
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if (do_reload) {
|
||||
loadconfig(argv, argc);
|
||||
do_reload = 0;
|
||||
}
|
||||
|
||||
/* timer expiration check and reset the timer */
|
||||
timeout = rtadvd_check_timer();
|
||||
|
||||
@ -420,6 +411,13 @@ rtadvd_set_dump_file(int sig __unused)
|
||||
do_dump = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
set_reload(int sig __unused)
|
||||
{
|
||||
|
||||
do_reload = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
set_die(int sig __unused)
|
||||
{
|
||||
@ -1698,7 +1696,7 @@ if_indextorainfo(int idx)
|
||||
return (NULL); /* search failed */
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
ra_output(struct rainfo *rai)
|
||||
{
|
||||
int i;
|
||||
|
@ -233,6 +233,7 @@ extern TAILQ_HEAD(railist_head_t, rainfo) railist;
|
||||
|
||||
struct rtadvd_timer *ra_timeout(void *);
|
||||
void ra_timer_update(void *, struct timeval *);
|
||||
void ra_output(struct rainfo *);
|
||||
|
||||
int prefix_match(struct in6_addr *, int,
|
||||
struct in6_addr *, int);
|
||||
|
Loading…
Reference in New Issue
Block a user