Sun Nov 1 14:24:01 2020 UTC ()
Sync with dhcpcd-9.3.2
(roy)
diff -r1.41 -r1.42 src/external/bsd/dhcpcd/dist/src/dhcp.c
diff -r1.8 -r1.9 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in
diff -r1.44 -r1.45 src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/src/logerr.c
diff -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/src/privsep.c
--- src/external/bsd/dhcpcd/dist/src/dhcp.c 2020/10/12 14:09:03 1.41
+++ src/external/bsd/dhcpcd/dist/src/dhcp.c 2020/11/01 14:24:01 1.42
@@ -1520,21 +1520,15 @@
#endif
}
-void
-dhcp_close(struct interface *ifp)
+static void
+dhcp_closebpf(struct interface *ifp)
{
struct dhcpcd_ctx *ctx = ifp->ctx;
struct dhcp_state *state = D_STATE(ifp);
- if (state == NULL)
- return;
-
#ifdef PRIVSEP
- if (IN_PRIVSEP_SE(ctx)) {
+ if (IN_PRIVSEP_SE(ctx))
ps_bpf_closebootp(ifp);
- if (state->addr != NULL)
- ps_inet_closebootp(state->addr);
- }
#endif
if (state->bpf != NULL) {
@@ -1542,12 +1536,39 @@
bpf_close(state->bpf);
state->bpf = NULL;
}
+}
+
+static void
+dhcp_closeinet(struct interface *ifp)
+{
+ struct dhcpcd_ctx *ctx = ifp->ctx;
+ struct dhcp_state *state = D_STATE(ifp);
+
+#ifdef PRIVSEP
+ if (IN_PRIVSEP_SE(ctx)) {
+ if (state->addr != NULL)
+ ps_inet_closebootp(state->addr);
+ }
+#endif
+
if (state->udp_rfd != -1) {
eloop_event_delete(ctx->eloop, state->udp_rfd);
close(state->udp_rfd);
state->udp_rfd = -1;
}
+}
+void
+dhcp_close(struct interface *ifp)
+{
+ struct dhcp_state *state = D_STATE(ifp);
+
+ if (state == NULL)
+ return;
+
+ dhcp_closebpf(ifp);
+ dhcp_closeinet(ifp);
+
state->interval = 0;
}
@@ -2061,12 +2082,14 @@
#ifdef ARP
#ifdef KERNEL_RFC5227
+#ifdef ARPING
static void
dhcp_arp_announced(struct arp_state *state)
{
arp_free(state);
}
+#endif
#else
static void
dhcp_arp_defend_failed(struct arp_state *astate)
@@ -2321,23 +2344,24 @@
logerr("dhcp_writefile: %s", state->leasefile);
}
+ old_state = state->added;
+
/* Close the BPF filter as we can now receive DHCP messages
* on a UDP socket. */
- old_state = state->added;
- if (ctx->options & DHCPCD_MASTER ||
- state->old == NULL ||
- state->old->yiaddr != state->new->yiaddr || old_state & STATE_FAKE)
- dhcp_close(ifp);
+ dhcp_closebpf(ifp);
+ /* Add the address */
ipv4_applyaddr(ifp);
/* If not in master mode, open an address specific socket. */
if (ctx->options & DHCPCD_MASTER ||
(state->old != NULL &&
- state->old->yiaddr == state->new->yiaddr &&
- old_state & STATE_ADDED && !(old_state & STATE_FAKE)))
+ state->old->yiaddr == state->new->yiaddr &&
+ old_state & STATE_ADDED && !(old_state & STATE_FAKE)))
return;
+ dhcp_closeinet(ifp);
+
#ifdef PRIVSEP
if (IN_PRIVSEP_SE(ctx)) {
if (ps_inet_openbootp(state->addr) == -1)
@@ -2926,6 +2950,8 @@
unsigned int i;
char *msg;
bool bootp_copied;
+ uint32_t v6only_time = 0;
+ bool use_v6only = false;
#ifdef AUTH
const uint8_t *auth;
size_t auth_len;
@@ -3143,6 +3169,23 @@
}
}
+ if (has_option_mask(ifo->requestmask, DHO_IPV6_PREFERRED_ONLY)) {
+ if (get_option_uint32(ifp->ctx, &v6only_time, bootp, bootp_len,
+ DHO_IPV6_PREFERRED_ONLY) == 0 &&
+ (state->state == DHS_DISCOVER || state->state == DHS_REBOOT))
+ {
+ char v6msg[128];
+
+ use_v6only = true;
+ if (v6only_time < MIN_V6ONLY_WAIT)
+ v6only_time = MIN_V6ONLY_WAIT;
+ snprintf(v6msg, sizeof(v6msg),
+ "IPv6-Only Preferred received (%u seconds)",
+ v6only_time);
+ LOGDHCP(LOG_INFO, v6msg);
+ }
+ }
+
/* DHCP Auto-Configure, RFC 2563 */
if (type == DHCP_OFFER && bootp->yiaddr == 0) {
LOGDHCP(LOG_WARNING, "no address given");
@@ -3177,9 +3220,19 @@
}
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
eloop_timeout_add_sec(ifp->ctx->eloop,
- DHCP_MAX, dhcp_discover, ifp);
+ use_v6only ? v6only_time : DHCP_MAX,
+ dhcp_discover, ifp);
}
#endif
+ return;
+ }
+
+ if (use_v6only) {
+ dhcp_drop(ifp, "EXPIRE");
+ dhcp_unlink(ifp->ctx, state->leasefile);
+ eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
+ eloop_timeout_add_sec(ifp->ctx->eloop, v6only_time,
+ dhcp_discover, ifp);
return;
}
--- src/external/bsd/dhcpcd/dist/src/Attic/dhcpcd.8.in 2020/09/06 14:55:34 1.8
+++ src/external/bsd/dhcpcd/dist/src/Attic/dhcpcd.8.in 2020/11/01 14:24:01 1.9
@@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 2, 2020
+.Dd October 30, 2020
.Dt DHCPCD 8
.Os
.Sh NAME
@@ -846,13 +846,5 @@
.Sh AUTHORS
.An Roy Marples Aq Mt roy@marples.name
.Sh BUGS
-If
-.Nm
-is running in a
-.Xr chroot 2
-then re-opening the
-.Fl Fl logfile
-from SIGUSR2 may not work.
-.Pp
Please report them to
.Lk http://roy.marples.name/projects/dhcpcd
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c 2020/10/12 14:09:03 1.44
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c 2020/11/01 14:24:01 1.45
@@ -1422,10 +1422,15 @@
return;
case SIGUSR2:
loginfox(sigmsg, "SIGUSR2", "reopening log");
- /* XXX This may not work that well in a chroot */
- logclose();
+#ifdef PRIVSEP
+ if (IN_PRIVSEP(ctx)) {
+ if (ps_root_logreopen(ctx) == -1)
+ logerr("ps_root_logreopen");
+ return;
+ }
+#endif
if (logopen(ctx->logfile) == -1)
- logerr(__func__);
+ logerr("logopen");
return;
case SIGCHLD:
while (waitpid(-1, NULL, WNOHANG) > 0)
@@ -1860,7 +1865,7 @@
ctx.dhcp6_wfd = -1;
#endif
#ifdef PRIVSEP
- ctx.ps_root_fd = ctx.ps_data_fd = -1;
+ ctx.ps_root_fd = ctx.ps_log_fd = ctx.ps_data_fd = -1;
ctx.ps_inet_fd = ctx.ps_control_fd = -1;
TAILQ_INIT(&ctx.ps_processes);
#endif
@@ -2328,6 +2333,7 @@
/* We have now forked, setsid, forked once more.
* From this point on, we are the controlling daemon. */
ctx.options |= DHCPCD_STARTED;
+ logdebugx("spawned master process on PID %d", getpid());
if ((pid = pidfile_lock(ctx.pidfile)) != 0) {
logerr("%s: pidfile_lock %d", __func__, pid);
#ifdef PRIVSEP
--- src/external/bsd/dhcpcd/dist/src/logerr.c 2020/10/12 14:09:03 1.10
+++ src/external/bsd/dhcpcd/dist/src/logerr.c 2020/11/01 14:24:01 1.11
@@ -47,11 +47,16 @@
#undef LOGERR_TAG
#endif
+/* syslog protocol is 1k message max, RFC 3164 section 4.1 */
+#define LOGERR_SYSLOGBUF 1024 + sizeof(int) + sizeof(pid_t)
+
#define UNUSED(a) (void)(a)
struct logctx {
char log_buf[BUFSIZ];
unsigned int log_opts;
+ int log_fd;
+ pid_t log_pid;
#ifndef SMALL
FILE *log_file;
#ifdef LOGERR_TAG
@@ -63,9 +68,11 @@
static struct logctx _logctx = {
/* syslog style, but without the hostname or tag. */
.log_opts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID,
+ .log_fd = -1,
+ .log_pid = 0,
};
-#if defined(LOGERR_TAG) && defined(__linux__)
+#if defined(__linux__)
/* Poor man's getprogname(3). */
static char *_logprog;
static const char *
@@ -79,9 +86,12 @@
* so zero the buffer. */
if ((_logprog = calloc(1, PATH_MAX + 1)) == NULL)
return NULL;
+ if (readlink("/proc/self/exe", _logprog, PATH_MAX + 1) == -1) {
+ free(_logprog);
+ _logprog = NULL;
+ return NULL;
+ }
}
- if (readlink("/proc/self/exe", _logprog, PATH_MAX + 1) == -1)
- return NULL;
if (_logprog[0] == '[')
return NULL;
p = strrchr(_logprog, '/');
@@ -147,7 +157,13 @@
log_pid = ((stream == stderr && ctx->log_opts & LOGERR_ERR_PID) ||
(stream != stderr && ctx->log_opts & LOGERR_LOG_PID));
if (log_pid) {
- if ((e = fprintf(stream, "[%d]", getpid())) == -1)
+ pid_t pid;
+
+ if (ctx->log_pid == 0)
+ pid = getpid();
+ else
+ pid = ctx->log_pid;
+ if ((e = fprintf(stream, "[%d]", pid)) == -1)
return -1;
len += e;
}
@@ -198,22 +214,37 @@
struct logctx *ctx = &_logctx;
int len = 0;
+ if (ctx->log_fd != -1) {
+ char buf[LOGERR_SYSLOGBUF];
+ pid_t pid;
+
+ memcpy(buf, &pri, sizeof(pri));
+ pid = getpid();
+ memcpy(buf + sizeof(pri), &pid, sizeof(pid));
+ len = vsnprintf(buf + sizeof(pri) + sizeof(pid),
+ sizeof(buf) - sizeof(pri) - sizeof(pid),
+ fmt, args);
+ if (len != -1)
+ len = (int)write(ctx->log_fd, buf,
+ ((size_t)++len) + sizeof(pri) + sizeof(pid));
+ return len;
+ }
+
if (ctx->log_opts & LOGERR_ERR &&
(pri <= LOG_ERR ||
(!(ctx->log_opts & LOGERR_QUIET) && pri <= LOG_INFO) ||
(ctx->log_opts & LOGERR_DEBUG && pri <= LOG_DEBUG)))
len = vlogprintf_r(ctx, stderr, fmt, args);
- if (!(ctx->log_opts & LOGERR_LOG))
- return len;
-
#ifndef SMALL
if (ctx->log_file != NULL &&
(pri != LOG_DEBUG || (ctx->log_opts & LOGERR_DEBUG)))
len = vlogprintf_r(ctx, ctx->log_file, fmt, args);
#endif
- vsyslog(pri, fmt, args);
+ if (ctx->log_opts & LOGERR_LOG)
+ vsyslog(pri, fmt, args);
+
return len;
}
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5))
@@ -331,6 +362,54 @@
va_end(args);
}
+int
+loggetfd(void)
+{
+ struct logctx *ctx = &_logctx;
+
+ return ctx->log_fd;
+}
+
+void
+logsetfd(int fd)
+{
+ struct logctx *ctx = &_logctx;
+
+ ctx->log_fd = fd;
+#ifndef SMALL
+ if (fd != -1 && ctx->log_file != NULL) {
+ fclose(ctx->log_file);
+ ctx->log_file = NULL;
+ }
+#endif
+}
+
+int
+logreadfd(int fd)
+{
+ struct logctx *ctx = &_logctx;
+ char buf[LOGERR_SYSLOGBUF];
+ int len, pri;
+
+ len = (int)read(fd, buf, sizeof(buf));
+ if (len == -1)
+ return -1;
+
+ /* Ensure we have pri, pid and a terminator */
+ if (len < (int)(sizeof(pri) + sizeof(pid_t) + 1) ||
+ buf[len - 1] != '\0')
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ memcpy(&pri, buf, sizeof(pri));
+ memcpy(&ctx->log_pid, buf + sizeof(pri), sizeof(ctx->log_pid));
+ logmessage(pri, "%s", buf + sizeof(pri) + sizeof(ctx->log_pid));
+ ctx->log_pid = 0;
+ return len;
+}
+
unsigned int
loggetopts(void)
{
@@ -373,15 +452,16 @@
(void)setvbuf(stderr, ctx->log_buf, _IOLBF, sizeof(ctx->log_buf));
- if (!(ctx->log_opts & LOGERR_LOG))
- return 1;
-
-#ifdef LOG_NDELAY
- opts |= LOG_NDELAY;
+#ifndef SMALL
+ if (ctx->log_file != NULL) {
+ fclose(ctx->log_file);
+ ctx->log_file = NULL;
+ }
#endif
+
if (ctx->log_opts & LOGERR_LOG_PID)
opts |= LOG_PID;
- openlog(NULL, opts, LOGERR_SYSLOG_FACILITY);
+ openlog(getprogname(), opts, LOGERR_SYSLOG_FACILITY);
if (path == NULL)
return 1;
@@ -410,7 +490,7 @@
fclose(ctx->log_file);
ctx->log_file = NULL;
#endif
-#if defined(LOGERR_TAG) && defined(__linux__)
+#if defined(__linux__)
free(_logprog);
#endif
}
--- src/external/bsd/dhcpcd/dist/src/privsep.c 2020/10/12 14:09:03 1.9
+++ src/external/bsd/dhcpcd/dist/src/privsep.c 2020/11/01 14:24:01 1.10
@@ -542,6 +542,19 @@
dropped = ps_dropprivs(ctx);
if (forked)
ctx->options |= DHCPCD_FORKED;
+
+ /*
+ * If we don't have a root process, we cannot use syslog.
+ * If it cannot be opened before chrooting then syslog(3) will fail.
+ * openlog(3) does not return an error which doubly sucks.
+ */
+ if (ctx->ps_root_fd == -1) {
+ unsigned int logopts = loggetopts();
+
+ logopts &= ~LOGERR_LOG;
+ logsetopts(logopts);
+ }
+
if (dropped == -1) {
logerr("%s: ps_dropprivs", __func__);
return -1;