diff options
author | hrs <hrs@FreeBSD.org> | 2011-09-12 23:52:55 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2011-09-12 23:52:55 +0000 |
commit | 2652dfc6f92bbcd0c714b04442954911f1e5377a (patch) | |
tree | 5d253725204ad7ad06ada9199c18698349a3f20e /usr.sbin/rtadvd | |
parent | ebd93e5aff0f6d81473632a976e39d5d4cb26f8b (diff) | |
download | FreeBSD-src-2652dfc6f92bbcd0c714b04442954911f1e5377a.zip FreeBSD-src-2652dfc6f92bbcd0c714b04442954911f1e5377a.tar.gz |
- 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)
Diffstat (limited to 'usr.sbin/rtadvd')
-rw-r--r-- | usr.sbin/rtadvd/control.c | 78 | ||||
-rw-r--r-- | usr.sbin/rtadvd/control.h | 12 | ||||
-rw-r--r-- | usr.sbin/rtadvd/control_client.c | 10 | ||||
-rw-r--r-- | usr.sbin/rtadvd/control_client.h | 2 | ||||
-rw-r--r-- | usr.sbin/rtadvd/control_server.c | 108 | ||||
-rw-r--r-- | usr.sbin/rtadvd/control_server.h | 6 | ||||
-rw-r--r-- | usr.sbin/rtadvd/rtadvd.c | 193 |
7 files changed, 231 insertions, 178 deletions
diff --git a/usr.sbin/rtadvd/control.c b/usr.sbin/rtadvd/control.c index 709fae3..5e4a68b 100644 --- a/usr.sbin/rtadvd/control.c +++ b/usr.sbin/rtadvd/control.c @@ -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_err: } 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__); diff --git a/usr.sbin/rtadvd/control.h b/usr.sbin/rtadvd/control.h index a7de2ce..2168302 100644 --- a/usr.sbin/rtadvd/control.h +++ b/usr.sbin/rtadvd/control.h @@ -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); diff --git a/usr.sbin/rtadvd/control_client.c b/usr.sbin/rtadvd/control_client.c index a78bcc9..33efe37 100644 --- a/usr.sbin/rtadvd/control_client.c +++ b/usr.sbin/rtadvd/control_client.c @@ -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); } diff --git a/usr.sbin/rtadvd/control_client.h b/usr.sbin/rtadvd/control_client.h index 89a7d80..2f50f17 100644 --- a/usr.sbin/rtadvd/control_client.h +++ b/usr.sbin/rtadvd/control_client.h @@ -27,4 +27,4 @@ * */ -int cmsg_handler_client(int, int, char *); +int cm_handler_client(int, int, char *); diff --git a/usr.sbin/rtadvd/control_server.c b/usr.sbin/rtadvd/control_server.c index 7d2ddc5..76ca541 100644 --- a/usr.sbin/rtadvd/control_server.c +++ b/usr.sbin/rtadvd/control_server.c @@ -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); diff --git a/usr.sbin/rtadvd/control_server.h b/usr.sbin/rtadvd/control_server.h index 2aab0cd..76fe9cd 100644 --- a/usr.sbin/rtadvd/control_server.h +++ b/usr.sbin/rtadvd/control_server.h @@ -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 *); diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c index 2d94b06..43e0e71 100644 --- a/usr.sbin/rtadvd/rtadvd.c +++ b/usr.sbin/rtadvd/rtadvd.c @@ -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); - return; - } if (getinet6sysctl(IPV6CTL_FORWARDING) == 0) { - syslog(LOG_INFO, - "<%s> non-zero lifetime RA " + syslog(LOG_ERR, + "non-zero lifetime RA " "but net.inet6.ip6.forwarding=0. " - "Ignored.", __func__); + "Ignored."); + return; + } + if (check_accept_rtadv(ifi->ifi_ifindex)) { + syslog(LOG_ERR, + "non-zero lifetime RA " + "on RA receiving interface %s." + " Ignored.", ifi->ifi_ifname); return; } } |