- Fix a bug that can lead to displaying an incorrect value. (r224210)

- Fix an abnormal termination caused by twice of "rtadvctl disable". (r224303)
- Use poll() to wait for the control message socket instead of a spin loop.
  (r224304)
- s/cmsg_/cm_/ to avoid conflict with CMSG_* symbols for struct cmsghdr.
  (r224619)
- Ignore an interface that never sent RAs for graceful shut-down. (r224620)
- Refine log messages. (r225148)
- Fix SIGSEGV when receiving RAs that contain RDNSS and/or DNSSL options.
  (r225149)

Approved by:	re (kib)
This commit is contained in:
Hiroki Sato 2011-09-12 23:52:55 +00:00
parent 5bb3652f05
commit aed378729e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=225519
8 changed files with 240 additions and 188 deletions

View file

@ -260,13 +260,13 @@ action_plgeneric(int action, char *plstr, char *buf)
*q++ = '\0';
cp.cp_val = q;
}
cm->cm_len += cmsg_pl2bin(msg, &cp);
cm->cm_len += cm_pl2bin(msg, &cp);
mysyslog(LOG_DEBUG, "<%s> key=%s, val_len=%d, ifname=%s",
__func__,cp.cp_key, cp.cp_val_len, cp.cp_ifname);
}
return (cmsg_handler_client(s->si_fd, CM_STATE_MSG_DISPATCH, buf));
return (cm_handler_client(s->si_fd, CM_STATE_MSG_DISPATCH, buf));
}
static int
@ -285,7 +285,7 @@ action_propget(char *argv, struct ctrl_msg_pl *cp)
if (error || cm->cm_len <= sizeof(*cm))
return (1);
cmsg_bin2pl(msg, cp);
cm_bin2pl(msg, cp);
mysyslog(LOG_DEBUG, "<%s> type=%d, len=%d",
__func__, cm->cm_type, cm->cm_len);
mysyslog(LOG_DEBUG, "<%s> key=%s, val_len=%d, ifname=%s",
@ -571,9 +571,9 @@ action_show(int argc, char **argv)
printf("\n");
printf("\tMinAdvInterval/MaxAdvInterval: %s/%s\n",
sec2str(rai->rai_mininterval, ssbuf),
sec2str(rai->rai_maxinterval, ssbuf));
printf("\tMinAdvInterval/MaxAdvInterval: ");
printf("%s/", sec2str(rai->rai_mininterval, ssbuf));
printf("%s\n", sec2str(rai->rai_maxinterval, ssbuf));
if (rai->rai_linkmtu)
printf("\tAdvLinkMTU: %d", rai->rai_linkmtu);
else
@ -593,11 +593,10 @@ action_show(int argc, char **argv)
printf("Preference: %s\n",
rtpref_str[(rai->rai_rtpref >> 3) & 0xff]);
printf("\t"
"ReachableTime: %s, "
"RetransTimer: %s, "
printf("\tReachableTime: %s, ",
sec2str(rai->rai_reachabletime, ssbuf));
printf("RetransTimer: %s, "
"CurHopLimit: %d\n",
sec2str(rai->rai_reachabletime, ssbuf),
sec2str(rai->rai_retranstimer, ssbuf),
rai->rai_hoplimit);
printf("\tAdvIfPrefixes: %s\n",

View file

@ -41,6 +41,7 @@
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#include <poll.h>
#include <signal.h>
#include <string.h>
#include <stdarg.h>
@ -53,12 +54,16 @@
#include "pathnames.h"
#include "control.h"
#define CM_RECV_TIMEOUT 30
int
cmsg_recv(int fd, char *buf)
cm_recv(int fd, char *buf)
{
int n;
struct ctrl_msg_hdr *cm;
char *msg;
struct pollfd pfds[1];
int i;
syslog(LOG_DEBUG, "<%s> enter, fd=%d", __func__, fd);
@ -66,35 +71,52 @@ cmsg_recv(int fd, char *buf)
cm = (struct ctrl_msg_hdr *)buf;
msg = (char *)buf + sizeof(*cm);
pfds[0].fd = fd;
pfds[0].events = POLLIN;
for (;;) {
n = read(fd, cm, sizeof(*cm));
if (n < 0 && errno == EAGAIN) {
syslog(LOG_DEBUG,
"<%s> waiting...", __func__);
i = poll(pfds, sizeof(pfds)/sizeof(pfds[0]),
CM_RECV_TIMEOUT);
if (i == 0)
continue;
if (i < 0) {
syslog(LOG_ERR, "<%s> poll error: %s",
__func__, strerror(errno));
continue;
}
break;
if (pfds[0].revents & POLLIN) {
n = read(fd, cm, sizeof(*cm));
if (n < 0 && errno == EAGAIN) {
syslog(LOG_DEBUG,
"<%s> waiting...", __func__);
continue;
}
break;
}
}
if (n != sizeof(*cm)) {
syslog(LOG_WARNING,
"<%s> received a too small message.", __func__);
goto cmsg_recv_err;
goto cm_recv_err;
}
if (cm->cm_len > CM_MSG_MAXLEN) {
syslog(LOG_WARNING,
"<%s> received a too large message.", __func__);
goto cmsg_recv_err;
goto cm_recv_err;
}
if (cm->cm_version != CM_VERSION) {
syslog(LOG_WARNING,
"<%s> version mismatch", __func__);
goto cmsg_recv_err;
goto cm_recv_err;
}
if (cm->cm_type >= CM_TYPE_MAX) {
syslog(LOG_WARNING,
"<%s> invalid msg type.", __func__);
goto cmsg_recv_err;
goto cm_recv_err;
}
syslog(LOG_DEBUG,
@ -109,31 +131,45 @@ cmsg_recv(int fd, char *buf)
msglen);
for (;;) {
n = read(fd, msg, msglen);
if (n < 0 && errno == EAGAIN) {
syslog(LOG_DEBUG,
"<%s> waiting...", __func__);
i = poll(pfds, sizeof(pfds)/sizeof(pfds[0]),
CM_RECV_TIMEOUT);
if (i == 0)
continue;
if (i < 0) {
syslog(LOG_ERR, "<%s> poll error: %s",
__func__, strerror(errno));
continue;
}
if (pfds[0].revents & POLLIN) {
n = read(fd, msg, msglen);
if (n < 0 && errno == EAGAIN) {
syslog(LOG_DEBUG,
"<%s> waiting...", __func__);
continue;
}
}
break;
}
if (n != msglen) {
syslog(LOG_WARNING,
"<%s> payload size mismatch.", __func__);
goto cmsg_recv_err;
goto cm_recv_err;
}
buf[CM_MSG_MAXLEN - 1] = '\0';
}
return (0);
cmsg_recv_err:
cm_recv_err:
close(fd);
return (-1);
}
int
cmsg_send(int fd, char *buf)
cm_send(int fd, char *buf)
{
struct iovec iov[2];
int iovcnt;
@ -304,7 +340,7 @@ csock_open(struct sockinfo *s, mode_t mode)
}
struct ctrl_msg_pl *
cmsg_bin2pl(char *str, struct ctrl_msg_pl *cp)
cm_bin2pl(char *str, struct ctrl_msg_pl *cp)
{
size_t len;
size_t *lenp;
@ -364,7 +400,7 @@ cmsg_bin2pl(char *str, struct ctrl_msg_pl *cp)
}
size_t
cmsg_pl2bin(char *str, struct ctrl_msg_pl *cp)
cm_pl2bin(char *str, struct ctrl_msg_pl *cp)
{
size_t len;
size_t *lenp;
@ -427,7 +463,7 @@ cmsg_pl2bin(char *str, struct ctrl_msg_pl *cp)
}
size_t
cmsg_str2bin(char *bin, void *str, size_t len)
cm_str2bin(char *bin, void *str, size_t len)
{
struct ctrl_msg_hdr *cm;
@ -445,7 +481,7 @@ cmsg_str2bin(char *bin, void *str, size_t len)
}
void *
cmsg_bin2str(char *bin, void *str, size_t len)
cm_bin2str(char *bin, void *str, size_t len)
{
syslog(LOG_DEBUG, "<%s> enter", __func__);

View file

@ -65,10 +65,10 @@ int csock_open(struct sockinfo *, mode_t);
int csock_close(struct sockinfo *);
int csock_listen(struct sockinfo *);
int csock_accept(struct sockinfo *);
int cmsg_send(int, char *);
int cmsg_recv(int, char *);
int cm_send(int, char *);
int cm_recv(int, char *);
size_t cmsg_pl2bin(char *, struct ctrl_msg_pl *);
struct ctrl_msg_pl *cmsg_bin2pl(char *, struct ctrl_msg_pl *);
size_t cmsg_str2bin(char *, void *, size_t);
void *cmsg_bin2str(char *, void *, size_t);
size_t cm_pl2bin(char *, struct ctrl_msg_pl *);
struct ctrl_msg_pl *cm_bin2pl(char *, struct ctrl_msg_pl *);
size_t cm_str2bin(char *, void *, size_t);
void *cm_bin2str(char *, void *, size_t);

View file

@ -55,7 +55,7 @@
#include "control_client.h"
int
cmsg_handler_client(int fd, int state, char *buf_orig)
cm_handler_client(int fd, int state, char *buf_orig)
{
char buf[CM_MSG_MAXLEN];
struct ctrl_msg_hdr *cm;
@ -91,17 +91,17 @@ cmsg_handler_client(int fd, int state, char *buf_orig)
break;
case CM_STATE_MSG_DISPATCH:
cm->cm_version = CM_VERSION;
error = cmsg_send(fd, buf);
error = cm_send(fd, buf);
if (error)
syslog(LOG_WARNING,
"<%s> cmsg_send()", __func__);
"<%s> cm_send()", __func__);
state = CM_STATE_ACK_WAIT;
break;
case CM_STATE_ACK_WAIT:
error = cmsg_recv(fd, buf);
error = cm_recv(fd, buf);
if (error) {
syslog(LOG_ERR,
"<%s> cmsg_recv()", __func__);
"<%s> cm_recv()", __func__);
close(fd);
return (-1);
}

View file

@ -27,4 +27,4 @@
*
*/
int cmsg_handler_client(int, int, char *);
int cm_handler_client(int, int, char *);

View file

@ -51,6 +51,7 @@
#include "pathnames.h"
#include "rtadvd.h"
#include "if.h"
#include "config.h"
#include "control.h"
#include "control_server.h"
#include "timer.h"
@ -68,28 +69,28 @@ int is_do_reload(void) { return (do_reload); }
int is_do_shutdown(void) { return (do_shutdown); }
char *reload_ifname(void) { return (do_reload_ifname); }
#define DEF_PL_HANDLER(key) { #key, cmsg_getprop_##key }
#define DEF_PL_HANDLER(key) { #key, cm_getprop_##key }
static int cmsg_getprop_echo(struct ctrl_msg_pl *);
static int cmsg_getprop_version(struct ctrl_msg_pl *);
static int cmsg_getprop_ifilist(struct ctrl_msg_pl *);
static int cmsg_getprop_ifi(struct ctrl_msg_pl *);
static int cmsg_getprop_ifi_ra_timer(struct ctrl_msg_pl *);
static int cmsg_getprop_rai(struct ctrl_msg_pl *);
static int cmsg_getprop_pfx(struct ctrl_msg_pl *);
static int cmsg_getprop_rdnss(struct ctrl_msg_pl *);
static int cmsg_getprop_dnssl(struct ctrl_msg_pl *);
static int cmsg_getprop_rti(struct ctrl_msg_pl *);
static int cm_getprop_echo(struct ctrl_msg_pl *);
static int cm_getprop_version(struct ctrl_msg_pl *);
static int cm_getprop_ifilist(struct ctrl_msg_pl *);
static int cm_getprop_ifi(struct ctrl_msg_pl *);
static int cm_getprop_ifi_ra_timer(struct ctrl_msg_pl *);
static int cm_getprop_rai(struct ctrl_msg_pl *);
static int cm_getprop_pfx(struct ctrl_msg_pl *);
static int cm_getprop_rdnss(struct ctrl_msg_pl *);
static int cm_getprop_dnssl(struct ctrl_msg_pl *);
static int cm_getprop_rti(struct ctrl_msg_pl *);
static int cmsg_setprop_reload(struct ctrl_msg_pl *);
static int cmsg_setprop_enable(struct ctrl_msg_pl *);
static int cmsg_setprop_disable(struct ctrl_msg_pl *);
static int cm_setprop_reload(struct ctrl_msg_pl *);
static int cm_setprop_enable(struct ctrl_msg_pl *);
static int cm_setprop_disable(struct ctrl_msg_pl *);
static struct dispatch_table {
const char *dt_comm;
int (*dt_act)(struct ctrl_msg_pl *cp);
} getprop_dtable[] = {
{ "", cmsg_getprop_echo },
{ "", cm_getprop_echo },
DEF_PL_HANDLER(echo),
DEF_PL_HANDLER(version),
DEF_PL_HANDLER(ifilist),
@ -103,7 +104,7 @@ static struct dispatch_table {
};
static int
cmsg_getprop_echo(struct ctrl_msg_pl *cp)
cm_getprop_echo(struct ctrl_msg_pl *cp)
{
syslog(LOG_DEBUG, "<%s> enter", __func__);
@ -114,7 +115,7 @@ cmsg_getprop_echo(struct ctrl_msg_pl *cp)
}
static int
cmsg_getprop_version(struct ctrl_msg_pl *cp)
cm_getprop_version(struct ctrl_msg_pl *cp)
{
syslog(LOG_DEBUG, "<%s> enter", __func__);
@ -125,7 +126,7 @@ cmsg_getprop_version(struct ctrl_msg_pl *cp)
}
static int
cmsg_getprop_ifilist(struct ctrl_msg_pl *cp)
cm_getprop_ifilist(struct ctrl_msg_pl *cp)
{
struct ifinfo *ifi;
char *p;
@ -159,7 +160,7 @@ cmsg_getprop_ifilist(struct ctrl_msg_pl *cp)
}
static int
cmsg_getprop_ifi(struct ctrl_msg_pl *cp)
cm_getprop_ifi(struct ctrl_msg_pl *cp)
{
struct ifinfo *ifi;
char *p;
@ -180,7 +181,7 @@ cmsg_getprop_ifi(struct ctrl_msg_pl *cp)
p = malloc(sizeof(*ifi));
if (p == NULL)
exit(1);
len = cmsg_str2bin(p, ifi, sizeof(*ifi));
len = cm_str2bin(p, ifi, sizeof(*ifi));
syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
@ -194,7 +195,7 @@ cmsg_getprop_ifi(struct ctrl_msg_pl *cp)
}
static int
cmsg_getprop_rai(struct ctrl_msg_pl *cp)
cm_getprop_rai(struct ctrl_msg_pl *cp)
{
struct ifinfo *ifi;
struct rainfo *rai;
@ -221,7 +222,7 @@ cmsg_getprop_rai(struct ctrl_msg_pl *cp)
p = malloc(sizeof(*rai));
if (p == NULL)
exit(1);
len = cmsg_str2bin(p, rai, sizeof(*rai));
len = cm_str2bin(p, rai, sizeof(*rai));
syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
@ -235,7 +236,7 @@ cmsg_getprop_rai(struct ctrl_msg_pl *cp)
}
static int
cmsg_getprop_ifi_ra_timer(struct ctrl_msg_pl *cp)
cm_getprop_ifi_ra_timer(struct ctrl_msg_pl *cp)
{
struct ifinfo *ifi;
struct rainfo *rai;
@ -267,7 +268,7 @@ cmsg_getprop_ifi_ra_timer(struct ctrl_msg_pl *cp)
p = malloc(sizeof(*rtimer));
if (p == NULL)
exit(1);
len = cmsg_str2bin(p, rtimer, sizeof(*rtimer));
len = cm_str2bin(p, rtimer, sizeof(*rtimer));
syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
@ -281,7 +282,7 @@ cmsg_getprop_ifi_ra_timer(struct ctrl_msg_pl *cp)
}
static int
cmsg_getprop_rti(struct ctrl_msg_pl *cp)
cm_getprop_rti(struct ctrl_msg_pl *cp)
{
struct ifinfo *ifi;
struct rainfo *rai;
@ -330,7 +331,7 @@ cmsg_getprop_rti(struct ctrl_msg_pl *cp)
}
static int
cmsg_getprop_pfx(struct ctrl_msg_pl *cp)
cm_getprop_pfx(struct ctrl_msg_pl *cp)
{
struct ifinfo *ifi;
struct rainfo *rai;
@ -379,7 +380,7 @@ cmsg_getprop_pfx(struct ctrl_msg_pl *cp)
}
static int
cmsg_getprop_rdnss(struct ctrl_msg_pl *cp)
cm_getprop_rdnss(struct ctrl_msg_pl *cp)
{
struct ifinfo *ifi;
struct rainfo *rai;
@ -448,7 +449,7 @@ cmsg_getprop_rdnss(struct ctrl_msg_pl *cp)
}
static int
cmsg_getprop_dnssl(struct ctrl_msg_pl *cp)
cm_getprop_dnssl(struct ctrl_msg_pl *cp)
{
struct ifinfo *ifi;
struct rainfo *rai;
@ -516,7 +517,7 @@ cmsg_getprop_dnssl(struct ctrl_msg_pl *cp)
}
int
cmsg_getprop(struct ctrl_msg_pl *cp)
cm_getprop(struct ctrl_msg_pl *cp)
{
size_t i;
@ -535,7 +536,7 @@ cmsg_getprop(struct ctrl_msg_pl *cp)
}
int
cmsg_setprop(struct ctrl_msg_pl *cp)
cm_setprop(struct ctrl_msg_pl *cp)
{
syslog(LOG_DEBUG, "<%s> enter", __func__);
@ -543,13 +544,13 @@ cmsg_setprop(struct ctrl_msg_pl *cp)
return (1);
if (strncmp(cp->cp_key, "reload", sizeof("reload")) == 0)
cmsg_setprop_reload(cp);
cm_setprop_reload(cp);
else if (strncmp(cp->cp_key, "shutdown", sizeof("shutdown")) == 0)
set_do_shutdown(0);
else if (strncmp(cp->cp_key, "enable", sizeof("enable")) == 0)
cmsg_setprop_enable(cp);
cm_setprop_enable(cp);
else if (strncmp(cp->cp_key, "disable", sizeof("disable")) == 0)
cmsg_setprop_disable(cp);
cm_setprop_disable(cp);
else if (strncmp(cp->cp_key, "echo", 8) == 0)
; /* do nothing */
else
@ -559,7 +560,7 @@ cmsg_setprop(struct ctrl_msg_pl *cp)
}
static int
cmsg_setprop_reload(struct ctrl_msg_pl *cp)
cm_setprop_reload(struct ctrl_msg_pl *cp)
{
syslog(LOG_DEBUG, "<%s> enter", __func__);
@ -571,7 +572,7 @@ cmsg_setprop_reload(struct ctrl_msg_pl *cp)
}
static int
cmsg_setprop_enable(struct ctrl_msg_pl *cp)
cm_setprop_enable(struct ctrl_msg_pl *cp)
{
struct ifinfo *ifi;
@ -595,7 +596,7 @@ cmsg_setprop_enable(struct ctrl_msg_pl *cp)
}
static int
cmsg_setprop_disable(struct ctrl_msg_pl *cp)
cm_setprop_disable(struct ctrl_msg_pl *cp)
{
struct ifinfo *ifi;
@ -611,13 +612,22 @@ cmsg_setprop_disable(struct ctrl_msg_pl *cp)
return (1);
}
ifi->ifi_persist = 0;
if (ifi->ifi_persist == 1) {
ifi->ifi_persist = 0;
rm_ifinfo(ifi);
/* MC leaving needed here */
sock_mc_leave(&sock, ifi->ifi_ifindex);
set_do_reload_ifname(ifi->ifi_ifname);
set_do_reload(0);
}
return (0);
}
int
cmsg_handler_server(int fd)
cm_handler_server(int fd)
{
int state;
char *msg;
@ -644,17 +654,17 @@ cmsg_handler_server(int fd)
break;
case CM_STATE_MSG_DISPATCH:
cm->cm_version = CM_VERSION;
error = cmsg_send(fd, buf);
error = cm_send(fd, buf);
if (error)
syslog(LOG_WARNING,
"<%s> cmsg_send()", __func__);
"<%s> cm_send()", __func__);
state = CM_STATE_EOM;
break;
case CM_STATE_ACK_WAIT:
error = cmsg_recv(fd, buf);
error = cm_recv(fd, buf);
if (error) {
syslog(LOG_ERR,
"<%s> cmsg_recv()", __func__);
"<%s> cm_recv()", __func__);
close(fd);
return (-1);
}
@ -676,11 +686,11 @@ cmsg_handler_server(int fd)
state = CM_STATE_EOM;
break;
case CM_STATE_MSG_RECV:
error = cmsg_recv(fd, buf);
error = cm_recv(fd, buf);
if (error) {
syslog(LOG_ERR,
"<%s> cmsg_recv()", __func__);
"<%s> cm_recv()", __func__);
close(fd);
return (-1);
}
@ -699,22 +709,22 @@ cmsg_handler_server(int fd)
cm->cm_len = sizeof(*cm);
break;
case CM_TYPE_REQ_GET_PROP:
cmsg_bin2pl(msg, &cp);
error = cmsg_getprop(&cp);
cm_bin2pl(msg, &cp);
error = cm_getprop(&cp);
if (error) {
cm->cm_type = CM_TYPE_ERR;
cm->cm_len = sizeof(*cm);
} else {
cm->cm_type = CM_TYPE_ACK;
cm->cm_len = sizeof(*cm);
cm->cm_len += cmsg_pl2bin(msg, &cp);
cm->cm_len += cm_pl2bin(msg, &cp);
}
if (cp.cp_val != NULL)
free(cp.cp_val);
break;
case CM_TYPE_REQ_SET_PROP:
cmsg_bin2pl(msg, &cp);
error = cmsg_setprop(&cp);
cm_bin2pl(msg, &cp);
error = cm_setprop(&cp);
if (error) {
cm->cm_type = CM_TYPE_ERR;
cm->cm_len = sizeof(*cm);

View file

@ -27,10 +27,10 @@
*
*/
int cmsg_getprop(struct ctrl_msg_pl *);
int cmsg_setprop(struct ctrl_msg_pl *);
int cm_getprop(struct ctrl_msg_pl *);
int cm_setprop(struct ctrl_msg_pl *);
int cmsg_handler_server(int);
int cm_handler_server(int);
void set_do_reload(int);
void set_do_reload_ifname(char *);

View file

@ -189,7 +189,7 @@ main(int argc, char *argv[])
dflag++;
break;
case 'D':
dflag += 2;
dflag += 3;
break;
case 'f':
fflag = 1;
@ -227,10 +227,12 @@ main(int argc, char *argv[])
openlog("rtadvd", logopt, LOG_DAEMON);
/* set log level */
if (dflag > 1)
if (dflag > 2)
(void)setlogmask(LOG_UPTO(LOG_DEBUG));
else if (dflag > 0)
else if (dflag > 1)
(void)setlogmask(LOG_UPTO(LOG_INFO));
else if (dflag > 0)
(void)setlogmask(LOG_UPTO(LOG_NOTICE));
else
(void)setlogmask(LOG_UPTO(LOG_ERR));
@ -251,8 +253,8 @@ main(int argc, char *argv[])
errx(1, "%s already running, pid: %d",
getprogname(), otherpid);
syslog(LOG_ERR,
"<%s> failed to open the pid log file, run anyway.",
__func__);
"failed to open the pid file %s, run anyway.",
pidfilename);
}
if (!fflag)
daemon(1, 0);
@ -265,7 +267,8 @@ main(int argc, char *argv[])
csock_open(&ctrlsock, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (ctrlsock.si_fd == -1) {
syslog(LOG_ERR, "<%s> cannot open control socket", __func__);
syslog(LOG_ERR, "cannot open control socket: %s",
strerror(errno));
exit(1);
}
@ -289,7 +292,8 @@ main(int argc, char *argv[])
error = csock_listen(&ctrlsock);
if (error) {
syslog(LOG_ERR, "<%s> listen failed", __func__);
syslog(LOG_ERR, "cannot listen control socket: %s",
strerror(errno));
exit(1);
}
@ -332,10 +336,11 @@ main(int argc, char *argv[])
if ((i = poll(set, sizeof(set)/sizeof(set[0]),
timeout ? (timeout->tv_sec * 1000 +
timeout->tv_usec / 1000) : INFTIM)) < 0) {
/* EINTR would occur upon SIGUSR1 for status dump */
/* EINTR would occur if a signal was delivered */
if (errno != EINTR)
syslog(LOG_ERR, "<%s> select: %s",
__func__, strerror(errno));
syslog(LOG_ERR, "poll() failed: %s",
strerror(errno));
continue;
}
if (i == 0) /* timeout */
@ -351,9 +356,11 @@ main(int argc, char *argv[])
fd = csock_accept(&ctrlsock);
if (fd == -1)
syslog(LOG_ERR, "<%s> accept", __func__);
syslog(LOG_ERR,
"cannot accept() control socket: %s",
strerror(errno));
else {
cmsg_handler_server(fd);
cm_handler_server(fd);
close(fd);
}
}
@ -371,14 +378,14 @@ rtadvd_shutdown(void)
if (wait_shutdown) {
syslog(LOG_INFO,
"waiting expiration of the all RA timers\n");
"waiting expiration of the all RA timers.");
TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
if (ifi->ifi_ra_timer != NULL)
break;
}
if (ifi == NULL) {
syslog(LOG_INFO, "gracefully terminated.\n");
syslog(LOG_NOTICE, "gracefully terminated.");
exit(0);
}
@ -386,7 +393,7 @@ rtadvd_shutdown(void)
return;
}
syslog(LOG_DEBUG, "<%s> cease to be an advertising router\n",
syslog(LOG_DEBUG, "<%s> cease to be an advertising router",
__func__);
wait_shutdown = 1;
@ -405,6 +412,18 @@ rtadvd_shutdown(void)
continue;
if (ifi->ifi_ra_timer == NULL)
continue;
if (ifi->ifi_ra_lastsent.tv_sec == 0 &&
ifi->ifi_ra_lastsent.tv_usec == 0 &&
ifi->ifi_ra_timer != NULL) {
/*
* When RA configured but never sent,
* ignore the IF immediately.
*/
rtadvd_remove_timer(ifi->ifi_ra_timer);
ifi->ifi_ra_timer = NULL;
ifi->ifi_state = IFI_STATE_UNCONFIGURED;
continue;
}
ifi->ifi_state = IFI_STATE_TRANSITIVE;
@ -419,8 +438,7 @@ rtadvd_shutdown(void)
rtadvd_set_timer(&ifi->ifi_ra_timer->rat_tm,
ifi->ifi_ra_timer);
}
syslog(LOG_INFO,
"<%s> final RA transmission started.\n", __func__);
syslog(LOG_NOTICE, "final RA transmission started.");
pidfile_remove(pfh);
csock_close(&ctrlsock);
@ -506,20 +524,20 @@ rtmsg_input(struct sockinfo *s)
continue;
}
syslog(LOG_INFO, "<%s>: if_announcemsg (idx=%d:%d)",
syslog(LOG_DEBUG, "<%s>: if_announcemsg (idx=%d:%d)",
__func__, ifan->ifan_index, ifan->ifan_what);
switch (ifan->ifan_what) {
case IFAN_ARRIVAL:
syslog(LOG_INFO,
"<%s>: interface added (idx=%d)",
__func__, ifan->ifan_index);
syslog(LOG_NOTICE,
"interface added (idx=%d)",
ifan->ifan_index);
update_ifinfo(&ifilist, ifan->ifan_index);
loadconfig_index(ifan->ifan_index);
break;
case IFAN_DEPARTURE:
syslog(LOG_INFO,
"<%s>: interface removed (idx=%d)",
__func__, ifan->ifan_index);
syslog(LOG_NOTICE,
"interface removed (idx=%d)",
ifan->ifan_index);
rm_ifinfo_index(ifan->ifan_index);
/* Clear ifi_ifindex */
@ -645,16 +663,16 @@ rtmsg_input(struct sockinfo *s)
/* check if an interface flag is changed */
if ((oldifflags & IFF_UP) && /* UP to DOWN */
!(ifi->ifi_flags & IFF_UP)) {
syslog(LOG_INFO,
"<%s> interface %s becomes down. stop timer.",
__func__, ifi->ifi_ifname);
syslog(LOG_NOTICE,
"<interface %s becomes down. stop timer.",
ifi->ifi_ifname);
rtadvd_remove_timer(ifi->ifi_ra_timer);
ifi->ifi_ra_timer = NULL;
} else if (!(oldifflags & IFF_UP) && /* DOWN to UP */
(ifi->ifi_flags & IFF_UP)) {
syslog(LOG_INFO,
"<%s> interface %s becomes up. restart timer.",
__func__, ifi->ifi_ifname);
syslog(LOG_NOTICE,
"interface %s becomes up. restart timer.",
ifi->ifi_ifname);
ifi->ifi_state = IFI_STATE_TRANSITIVE;
ifi->ifi_burstcount =
@ -728,15 +746,11 @@ rtadvd_input(struct sockinfo *s)
hlimp = (int *)CMSG_DATA(cm);
}
if (ifindex == 0) {
syslog(LOG_ERR,
"<%s> failed to get receiving interface",
__func__);
syslog(LOG_ERR, "failed to get receiving interface");
return;
}
if (hlimp == NULL) {
syslog(LOG_ERR,
"<%s> failed to get receiving hop limit",
__func__);
syslog(LOG_ERR, "failed to get receiving hop limit");
return;
}
@ -756,8 +770,7 @@ rtadvd_input(struct sockinfo *s)
#ifdef OLDRAWSOCKET
if ((size_t)i < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr)) {
syslog(LOG_ERR,
"<%s> packet size(%d) is too short",
__func__, i);
"packet size(%d) is too short", i);
return;
}
@ -765,9 +778,7 @@ rtadvd_input(struct sockinfo *s)
icp = (struct icmp6_hdr *)(ip + 1); /* XXX: ext. hdr? */
#else
if ((size_t)i < sizeof(struct icmp6_hdr)) {
syslog(LOG_ERR,
"<%s> packet size(%zd) is too short",
__func__, i);
syslog(LOG_ERR, "packet size(%zd) is too short", i);
return;
}
@ -783,9 +794,9 @@ rtadvd_input(struct sockinfo *s)
*/
if (*hlimp != 255) {
syslog(LOG_NOTICE,
"<%s> RS with invalid hop limit(%d) "
"RS with invalid hop limit(%d) "
"received from %s on %s",
__func__, *hlimp,
*hlimp,
inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
@ -793,9 +804,9 @@ rtadvd_input(struct sockinfo *s)
}
if (icp->icmp6_code) {
syslog(LOG_NOTICE,
"<%s> RS with invalid ICMP6 code(%d) "
"RS with invalid ICMP6 code(%d) "
"received from %s on %s",
__func__, icp->icmp6_code,
icp->icmp6_code,
inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
@ -803,9 +814,8 @@ rtadvd_input(struct sockinfo *s)
}
if ((size_t)i < sizeof(struct nd_router_solicit)) {
syslog(LOG_NOTICE,
"<%s> RS from %s on %s does not have enough "
"RS from %s on %s does not have enough "
"length (len = %zd)",
__func__,
inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf), i);
@ -820,18 +830,18 @@ rtadvd_input(struct sockinfo *s)
*/
if (!IN6_IS_ADDR_LINKLOCAL(&rcvfrom.sin6_addr)) {
syslog(LOG_NOTICE,
"<%s> RA witn non-linklocal source address "
"RA witn non-linklocal source address "
"received from %s on %s",
__func__, inet_ntop(AF_INET6, &rcvfrom.sin6_addr,
inet_ntop(AF_INET6, &rcvfrom.sin6_addr,
ntopbuf, sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
return;
}
if (*hlimp != 255) {
syslog(LOG_NOTICE,
"<%s> RA with invalid hop limit(%d) "
"RA with invalid hop limit(%d) "
"received from %s on %s",
__func__, *hlimp,
*hlimp,
inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
@ -839,9 +849,9 @@ rtadvd_input(struct sockinfo *s)
}
if (icp->icmp6_code) {
syslog(LOG_NOTICE,
"<%s> RA with invalid ICMP6 code(%d) "
"RA with invalid ICMP6 code(%d) "
"received from %s on %s",
__func__, icp->icmp6_code,
icp->icmp6_code,
inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
@ -849,9 +859,8 @@ rtadvd_input(struct sockinfo *s)
}
if ((size_t)i < sizeof(struct nd_router_advert)) {
syslog(LOG_NOTICE,
"<%s> RA from %s on %s does not have enough "
"RA from %s on %s does not have enough "
"length (len = %zd)",
__func__,
inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf), i);
@ -861,9 +870,8 @@ rtadvd_input(struct sockinfo *s)
break;
case ICMP6_ROUTER_RENUMBERING:
if (mcastif == NULL) {
syslog(LOG_ERR, "<%s> received a router renumbering "
"message, but not allowed to be accepted",
__func__);
syslog(LOG_ERR, "received a router renumbering "
"message, but not allowed to be accepted");
break;
}
rr_input(i, (struct icmp6_router_renum *)icp, pi, &rcvfrom,
@ -876,8 +884,7 @@ rtadvd_input(struct sockinfo *s)
* could receive message after opening the socket and
* before setting ICMP6 type filter(see sock_open()).
*/
syslog(LOG_ERR, "<%s> invalid icmp type(%d)",
__func__, icp->icmp6_type);
syslog(LOG_ERR, "invalid icmp type(%d)", icp->icmp6_type);
return;
}
@ -903,6 +910,7 @@ rs_input(int len, struct nd_router_solicit *rs,
/* ND option check */
memset(&ndopts, 0, sizeof(ndopts));
TAILQ_INIT(&ndopts.opt_list);
if (nd6_options((struct nd_opt_hdr *)(rs + 1),
len - sizeof(struct nd_router_solicit),
&ndopts, NDOPT_FLAG_SRCLINKADDR)) {
@ -1030,7 +1038,7 @@ check_accept_rtadv(int idx)
break;
}
if (ifi == NULL) {
syslog(LOG_ERR,
syslog(LOG_DEBUG,
"<%s> if (idx=%d) not found. Why?",
__func__, idx);
return (0);
@ -1048,9 +1056,7 @@ check_accept_rtadv(int idx)
* RA_SEND: ip6.forwarding
*/
if (update_ifinfo_nd_flags(ifi) != 0) {
syslog(LOG_ERR,
"<%s> nd6 flags failed (idx=%d)",
__func__, idx);
syslog(LOG_ERR, "cannot get nd6 flags (idx=%d)", idx);
return (0);
}
@ -1078,6 +1084,7 @@ ra_input(int len, struct nd_router_advert *nra,
/* ND option check */
memset(&ndopts, 0, sizeof(ndopts));
TAILQ_INIT(&ndopts.opt_list);
error = nd6_options((struct nd_opt_hdr *)(nra + 1),
len - sizeof(struct nd_router_advert), &ndopts,
NDOPT_FLAG_SRCLINKADDR | NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU |
@ -1108,16 +1115,16 @@ ra_input(int len, struct nd_router_advert *nra,
}
rai = ifi->ifi_rainfo;
ifi->ifi_rainput++;
syslog(LOG_DEBUG, "<%s> ifi->ifi_rainput = %" PRIu64 "\n", __func__,
syslog(LOG_DEBUG, "<%s> ifi->ifi_rainput = %" PRIu64, __func__,
ifi->ifi_rainput);
/* Cur Hop Limit value */
if (nra->nd_ra_curhoplimit && rai->rai_hoplimit &&
nra->nd_ra_curhoplimit != rai->rai_hoplimit) {
syslog(LOG_INFO,
"<%s> CurHopLimit inconsistent on %s:"
syslog(LOG_NOTICE,
"CurHopLimit inconsistent on %s:"
" %d from %s, %d from us",
__func__, ifi->ifi_ifname, nra->nd_ra_curhoplimit,
ifi->ifi_ifname, nra->nd_ra_curhoplimit,
inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
sizeof(ntopbuf)), rai->rai_hoplimit);
inconsistent++;
@ -1125,10 +1132,10 @@ ra_input(int len, struct nd_router_advert *nra,
/* M flag */
if ((nra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) !=
rai->rai_managedflg) {
syslog(LOG_INFO,
"<%s> M flag inconsistent on %s:"
syslog(LOG_NOTICE,
"M flag inconsistent on %s:"
" %s from %s, %s from us",
__func__, ifi->ifi_ifname, on_off[!rai->rai_managedflg],
ifi->ifi_ifname, on_off[!rai->rai_managedflg],
inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
sizeof(ntopbuf)), on_off[rai->rai_managedflg]);
inconsistent++;
@ -1136,10 +1143,10 @@ ra_input(int len, struct nd_router_advert *nra,
/* O flag */
if ((nra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) !=
rai->rai_otherflg) {
syslog(LOG_INFO,
"<%s> O flag inconsistent on %s:"
syslog(LOG_NOTICE,
"O flag inconsistent on %s:"
" %s from %s, %s from us",
__func__, ifi->ifi_ifname, on_off[!rai->rai_otherflg],
ifi->ifi_ifname, on_off[!rai->rai_otherflg],
inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
sizeof(ntopbuf)), on_off[rai->rai_otherflg]);
inconsistent++;
@ -1148,10 +1155,10 @@ ra_input(int len, struct nd_router_advert *nra,
reachabletime = ntohl(nra->nd_ra_reachable);
if (reachabletime && rai->rai_reachabletime &&
reachabletime != rai->rai_reachabletime) {
syslog(LOG_INFO,
"<%s> ReachableTime inconsistent on %s:"
syslog(LOG_NOTICE,
"ReachableTime inconsistent on %s:"
" %d from %s, %d from us",
__func__, ifi->ifi_ifname, reachabletime,
ifi->ifi_ifname, reachabletime,
inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
sizeof(ntopbuf)), rai->rai_reachabletime);
inconsistent++;
@ -1160,10 +1167,10 @@ ra_input(int len, struct nd_router_advert *nra,
retranstimer = ntohl(nra->nd_ra_retransmit);
if (retranstimer && rai->rai_retranstimer &&
retranstimer != rai->rai_retranstimer) {
syslog(LOG_INFO,
"<%s> RetranceTimer inconsistent on %s:"
syslog(LOG_NOTICE,
"RetranceTimer inconsistent on %s:"
" %d from %s, %d from us",
__func__, ifi->ifi_ifname, retranstimer,
ifi->ifi_ifname, retranstimer,
inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
sizeof(ntopbuf)), rai->rai_retranstimer);
inconsistent++;
@ -1172,10 +1179,10 @@ ra_input(int len, struct nd_router_advert *nra,
if (ndopts.opt_mtu) {
mtu = ntohl(ndopts.opt_mtu->nd_opt_mtu_mtu);
if (mtu && rai->rai_linkmtu && mtu != rai->rai_linkmtu) {
syslog(LOG_INFO,
"<%s> MTU option value inconsistent on %s:"
syslog(LOG_NOTICE,
"MTU option value inconsistent on %s:"
" %d from %s, %d from us",
__func__, ifi->ifi_ifname, mtu,
ifi->ifi_ifname, mtu,
inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
sizeof(ntopbuf)), rai->rai_linkmtu);
inconsistent++;
@ -1684,18 +1691,18 @@ ra_output(struct ifinfo *ifi)
ifi->ifi_ifname);
if (rai->rai_lifetime != 0) {
if (check_accept_rtadv(ifi->ifi_ifindex)) {
syslog(LOG_INFO,
"<%s> non-zero lifetime RA "
"on RA receiving interface %s."
" Ignored.", __func__, ifi->ifi_ifname);
if (getinet6sysctl(IPV6CTL_FORWARDING) == 0) {
syslog(LOG_ERR,
"non-zero lifetime RA "
"but net.inet6.ip6.forwarding=0. "
"Ignored.");
return;
}
if (getinet6sysctl(IPV6CTL_FORWARDING) == 0) {
syslog(LOG_INFO,
"<%s> non-zero lifetime RA "
"but net.inet6.ip6.forwarding=0. "
"Ignored.", __func__);
if (check_accept_rtadv(ifi->ifi_ifindex)) {
syslog(LOG_ERR,
"non-zero lifetime RA "
"on RA receiving interface %s."
" Ignored.", ifi->ifi_ifname);
return;
}
}