Module Name: src
Committed By: roy
Date: Sat May 16 23:31:32 UTC 2015
Modified Files:
src/external/bsd/dhcpcd/dist: arp.c arp.h auth.h common.c common.h
config.h control.c defs.h dhcp-common.c dhcp-common.h dhcp.c
dhcp6.c dhcpcd-definitions.conf dhcpcd-embedded.c dhcpcd-embedded.h
dhcpcd-run-hooks.8.in dhcpcd.8.in dhcpcd.c dhcpcd.conf.5.in
dhcpcd.h eloop.c eloop.h if-bsd.c if-options.c if-options.h ipv4.c
ipv4.h ipv6.c ipv6.h ipv6nd.c ipv6nd.h script.c
src/external/bsd/dhcpcd/dist/dhcpcd-hooks: 20-resolv.conf
Log Message:
Sync
To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/arp.c \
src/external/bsd/dhcpcd/dist/common.c \
src/external/bsd/dhcpcd/dist/dhcp6.c src/external/bsd/dhcpcd/dist/ipv6.h
cvs rdiff -u -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/arp.h
cvs rdiff -u -r1.8 -r1.9 src/external/bsd/dhcpcd/dist/auth.h \
src/external/bsd/dhcpcd/dist/common.h \
src/external/bsd/dhcpcd/dist/config.h \
src/external/bsd/dhcpcd/dist/control.c \
src/external/bsd/dhcpcd/dist/dhcp-common.c \
src/external/bsd/dhcpcd/dist/dhcp-common.h \
src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c \
src/external/bsd/dhcpcd/dist/eloop.h
cvs rdiff -u -r1.17 -r1.18 src/external/bsd/dhcpcd/dist/defs.h
cvs rdiff -u -r1.30 -r1.31 src/external/bsd/dhcpcd/dist/dhcp.c
cvs rdiff -u -r1.7 -r1.8 src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf \
src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h
cvs rdiff -u -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in
cvs rdiff -u -r1.41 -r1.42 src/external/bsd/dhcpcd/dist/dhcpcd.8.in
cvs rdiff -u -r1.24 -r1.25 src/external/bsd/dhcpcd/dist/dhcpcd.c
cvs rdiff -u -r1.20 -r1.21 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in \
src/external/bsd/dhcpcd/dist/if-bsd.c
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/dhcpcd.h \
src/external/bsd/dhcpcd/dist/eloop.c \
src/external/bsd/dhcpcd/dist/if-options.h \
src/external/bsd/dhcpcd/dist/ipv4.h
cvs rdiff -u -r1.23 -r1.24 src/external/bsd/dhcpcd/dist/if-options.c \
src/external/bsd/dhcpcd/dist/ipv6nd.c
cvs rdiff -u -r1.14 -r1.15 src/external/bsd/dhcpcd/dist/ipv4.c
cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/ipv6.c \
src/external/bsd/dhcpcd/dist/ipv6nd.h
cvs rdiff -u -r1.19 -r1.20 src/external/bsd/dhcpcd/dist/script.c
cvs rdiff -u -r1.6 -r1.7 \
src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/external/bsd/dhcpcd/dist/arp.c
diff -u src/external/bsd/dhcpcd/dist/arp.c:1.12 src/external/bsd/dhcpcd/dist/arp.c:1.13
--- src/external/bsd/dhcpcd/dist/arp.c:1.12 Sat May 2 15:18:36 2015
+++ src/external/bsd/dhcpcd/dist/arp.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: arp.c,v 1.12 2015/05/02 15:18:36 roy Exp $");
+ __RCSID("$NetBSD: arp.c,v 1.13 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -297,17 +297,19 @@ arp_probe(struct arp_state *astate)
arp_probe1(astate);
}
-static struct arp_state *
+struct arp_state *
arp_find(struct interface *ifp, const struct in_addr *addr)
{
struct arp_state *astate;
struct dhcp_state *state;
- state = D_STATE(ifp);
+ if ((state = D_STATE(ifp)) == NULL)
+ goto out;
TAILQ_FOREACH(astate, &state->arp_states, next) {
if (astate->addr.s_addr == addr->s_addr && astate->iface == ifp)
return astate;
}
+out:
errno = ESRCH;
return NULL;
}
@@ -380,7 +382,7 @@ arp_close(struct interface *ifp)
return;
if (state->arp_fd != -1) {
- eloop_event_delete(ifp->ctx->eloop, state->arp_fd, 0);
+ eloop_event_delete(ifp->ctx->eloop, state->arp_fd);
close(state->arp_fd);
state->arp_fd = -1;
}
Index: src/external/bsd/dhcpcd/dist/common.c
diff -u src/external/bsd/dhcpcd/dist/common.c:1.12 src/external/bsd/dhcpcd/dist/common.c:1.13
--- src/external/bsd/dhcpcd/dist/common.c:1.12 Sat May 2 15:18:36 2015
+++ src/external/bsd/dhcpcd/dist/common.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: common.c,v 1.12 2015/05/02 15:18:36 roy Exp $");
+ __RCSID("$NetBSD: common.c,v 1.13 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -28,11 +28,6 @@
* SUCH DAMAGE.
*/
-#ifdef __APPLE__
-# include <mach/mach_time.h>
-# include <mach/kern_return.h>
-#endif
-
#include <sys/param.h>
#include <sys/time.h>
@@ -84,64 +79,6 @@ get_hostname(char *buf, size_t buflen, i
return buf;
}
-/* Handy function to get the time.
- * We only care about time advancements, not the actual time itself
- * Which is why we use CLOCK_MONOTONIC, but it is not available on all
- * platforms.
- */
-#define NO_MONOTONIC "host does not support a monotonic clock - timing can skew"
-int
-get_monotonic(struct timespec *ts)
-{
-
-#if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC)
- return clock_gettime(CLOCK_MONOTONIC, ts);
-#elif defined(__APPLE__)
- /* We can use mach kernel functions here.
- * This is crap though - why can't they implement clock_gettime?*/
- static struct mach_timebase_info info = { 0, 0 };
- static double factor = 0.0;
- uint64_t nano;
- long rem;
-
- if (!posix_clock_set) {
- if (mach_timebase_info(&info) == KERN_SUCCESS) {
- factor = (double)info.numer / (double)info.denom;
- clock_monotonic = posix_clock_set = 1;
- }
- }
- if (clock_monotonic) {
- nano = mach_absolute_time();
- if ((info.denom != 1 || info.numer != 1) && factor != 0.0)
- nano *= factor;
- ts->tv_sec = nano / NSEC_PER_SEC;
- ts->tv_nsec = nano % NSEC_PER_SEC;
- if (ts->tv_nsec < 0) {
- ts->tv_sec--;
- ts->tv_nsec += NSEC_PER_SEC;
- }
- return 0;
- }
-#endif
-
-#if 0
- /* Something above failed, so fall back to gettimeofday */
- if (!posix_clock_set) {
- logger(NULL, LOG_WARNING, NO_MONOTONIC);
- posix_clock_set = 1;
- }
-#endif
- {
- struct timeval tv;
- if (gettimeofday(&tv, NULL) == 0) {
- TIMEVAL_TO_TIMESPEC(&tv, ts);
- return 0;
- }
- }
-
- return -1;
-}
-
#if USE_LOGFILE
void
logger_open(struct dhcpcd_ctx *ctx)
@@ -269,42 +206,64 @@ logger(struct dhcpcd_ctx *ctx, int pri,
ssize_t
setvar(struct dhcpcd_ctx *ctx,
- char ***e, const char *prefix, const char *var, const char *value)
+ char **e, const char *prefix, const char *var, const char *value)
{
size_t len = strlen(var) + strlen(value) + 3;
if (prefix)
len += strlen(prefix) + 1;
- **e = malloc(len);
- if (**e == NULL) {
+ *e = malloc(len);
+ if (*e == NULL) {
logger(ctx, LOG_ERR, "%s: %m", __func__);
return -1;
}
if (prefix)
- snprintf(**e, len, "%s_%s=%s", prefix, var, value);
+ snprintf(*e, len, "%s_%s=%s", prefix, var, value);
else
- snprintf(**e, len, "%s=%s", var, value);
- (*e)++;
+ snprintf(*e, len, "%s=%s", var, value);
return (ssize_t)len;
}
ssize_t
setvard(struct dhcpcd_ctx *ctx,
- char ***e, const char *prefix, const char *var, size_t value)
+ char **e, const char *prefix, const char *var, size_t value)
{
+
char buffer[32];
snprintf(buffer, sizeof(buffer), "%zu", value);
return setvar(ctx, e, prefix, var, buffer);
}
+ssize_t
+addvar(struct dhcpcd_ctx *ctx,
+ char ***e, const char *prefix, const char *var, const char *value)
+{
+ ssize_t len;
+
+ len = setvar(ctx, *e, prefix, var, value);
+ if (len != -1)
+ (*e)++;
+ return (ssize_t)len;
+}
+
+ssize_t
+addvard(struct dhcpcd_ctx *ctx,
+ char ***e, const char *prefix, const char *var, size_t value)
+{
+ char buffer[32];
+
+ snprintf(buffer, sizeof(buffer), "%zu", value);
+ return addvar(ctx, e, prefix, var, buffer);
+}
+
time_t
uptime(void)
{
struct timespec tv;
- if (get_monotonic(&tv) == -1)
+ if (clock_gettime(CLOCK_MONOTONIC, &tv) == -1)
return -1;
return tv.tv_sec;
}
Index: src/external/bsd/dhcpcd/dist/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/dhcp6.c:1.12 src/external/bsd/dhcpcd/dist/dhcp6.c:1.13
--- src/external/bsd/dhcpcd/dist/dhcp6.c:1.12 Sat May 2 15:18:36 2015
+++ src/external/bsd/dhcpcd/dist/dhcp6.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp6.c,v 1.12 2015/05/02 15:18:36 roy Exp $");
+ __RCSID("$NetBSD: dhcp6.c,v 1.13 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -1022,6 +1022,9 @@ dhcp6_sendmessage(struct interface *ifp,
const char *broad_uni;
const struct in6_addr alldhcp = IN6ADDR_LINKLOCAL_ALLDHCP_INIT;
+ if (!callback && ifp->carrier == LINK_DOWN)
+ return 0;
+
memset(&dst, 0, sizeof(dst));
dst.sin6_family = AF_INET6;
dst.sin6_port = htons(DHCP6_SERVER_PORT);
@@ -1109,16 +1112,17 @@ dhcp6_sendmessage(struct interface *ifp,
}
logsend:
- logger(ifp->ctx, LOG_DEBUG,
- "%s: %s %s (xid 0x%02x%02x%02x),"
- " next in %0.1f seconds",
- ifp->name,
- broad_uni,
- dhcp6_get_op(state->send->type),
- state->send->xid[0],
- state->send->xid[1],
- state->send->xid[2],
- timespec_to_double(&state->RT));
+ if (ifp->carrier != LINK_DOWN)
+ logger(ifp->ctx, LOG_DEBUG,
+ "%s: %s %s (xid 0x%02x%02x%02x),"
+ " next in %0.1f seconds",
+ ifp->name,
+ broad_uni,
+ dhcp6_get_op(state->send->type),
+ state->send->xid[0],
+ state->send->xid[1],
+ state->send->xid[2],
+ timespec_to_double(&state->RT));
/* Wait the initial delay */
if (state->IMD) {
@@ -1129,6 +1133,9 @@ logsend:
}
}
+ if (ifp->carrier == LINK_DOWN)
+ return 0;
+
/* Update the elapsed time */
dhcp6_updateelapsed(ifp, state->send, state->send_len);
if (ifp->options->auth.options & DHCPCD_AUTH_SEND &&
@@ -2109,7 +2116,7 @@ dhcp6_validatelease(struct interface *if
state->renew = state->rebind = state->expire = 0;
state->lowpl = ND6_INFINITE_LIFETIME;
if (!acquired) {
- get_monotonic(&aq);
+ clock_gettime(CLOCK_MONOTONIC, &aq);
acquired = &aq;
}
nia = dhcp6_findia(ifp, m, len, sfrom, acquired);
@@ -2184,7 +2191,7 @@ dhcp6_readlease(struct interface *ifp, i
if ((now = time(NULL)) == -1)
goto ex;
- get_monotonic(&acquired);
+ clock_gettime(CLOCK_MONOTONIC, &acquired);
acquired.tv_sec -= now - st.st_mtime;
/* Check to see if the lease is still valid */
@@ -2618,7 +2625,7 @@ dhcp6_handledata(void *arg)
if (bytes == -1) {
logger(dctx, LOG_ERR, "%s: recvmsg: %m", __func__);
close(ctx->dhcp_fd);
- eloop_event_delete(dctx->eloop, ctx->dhcp_fd, 0);
+ eloop_event_delete(dctx->eloop, ctx->dhcp_fd);
ctx->dhcp_fd = -1;
return;
}
@@ -3394,7 +3401,7 @@ dhcp6_freedrop(struct interface *ifp, in
}
if (ifp == NULL && ctx->ipv6) {
if (ctx->ipv6->dhcp_fd != -1) {
- eloop_event_delete(ctx->eloop, ctx->ipv6->dhcp_fd, 0);
+ eloop_event_delete(ctx->eloop, ctx->ipv6->dhcp_fd);
close(ctx->ipv6->dhcp_fd);
ctx->ipv6->dhcp_fd = -1;
}
Index: src/external/bsd/dhcpcd/dist/ipv6.h
diff -u src/external/bsd/dhcpcd/dist/ipv6.h:1.12 src/external/bsd/dhcpcd/dist/ipv6.h:1.13
--- src/external/bsd/dhcpcd/dist/ipv6.h:1.12 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/ipv6.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6.h,v 1.12 2015/05/02 15:18:37 roy Exp $ */
+/* $NetBSD: ipv6.h,v 1.13 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -33,6 +33,19 @@
#include <sys/uio.h>
#include <netinet/in.h>
+#ifndef __linux__
+# ifndef __QNX__
+# include <sys/endian.h>
+# endif
+# include <net/if.h>
+# ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */
+# include <net/if_var.h>
+# endif
+# ifndef __sun
+# include <netinet6/in6_var.h>
+# endif
+#endif
+
#include "config.h"
#include "dhcpcd.h"
@@ -268,6 +281,7 @@ void ipv6_buildroutes(struct dhcpcd_ctx
#else
#define ipv6_init(a) (NULL)
#define ipv6_start(a) (-1)
+#define ipv6_iffindaddr(a, b) (NULL)
#define ipv6_free_ll_callbacks(a) {}
#define ipv6_free(a) {}
#define ipv6_drop(a) {}
Index: src/external/bsd/dhcpcd/dist/arp.h
diff -u src/external/bsd/dhcpcd/dist/arp.h:1.9 src/external/bsd/dhcpcd/dist/arp.h:1.10
--- src/external/bsd/dhcpcd/dist/arp.h:1.9 Sat May 2 15:18:36 2015
+++ src/external/bsd/dhcpcd/dist/arp.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: arp.h,v 1.9 2015/05/02 15:18:36 roy Exp $ */
+/* $NetBSD: arp.h,v 1.10 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -75,6 +75,7 @@ struct arp_state *arp_new(struct interfa
void arp_cancel(struct arp_state *);
void arp_free(struct arp_state *);
void arp_free_but(struct arp_state *);
+struct arp_state *arp_find(struct interface *, const struct in_addr *);
void arp_close(struct interface *);
void arp_handleifa(int, struct interface *, const struct in_addr *, int);
Index: src/external/bsd/dhcpcd/dist/auth.h
diff -u src/external/bsd/dhcpcd/dist/auth.h:1.8 src/external/bsd/dhcpcd/dist/auth.h:1.9
--- src/external/bsd/dhcpcd/dist/auth.h:1.8 Fri Jan 30 09:47:05 2015
+++ src/external/bsd/dhcpcd/dist/auth.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: auth.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */
+/* $NetBSD: auth.h,v 1.9 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -32,6 +32,10 @@
#include "config.h"
+#ifdef HAVE_SYS_QUEUE_H
+#include <sys/queue.h>
+#endif
+
#define DHCPCD_AUTH_SEND (1 << 0)
#define DHCPCD_AUTH_REQUIRE (1 << 1)
#define DHCPCD_AUTH_RDM_COUNTER (1 << 2)
Index: src/external/bsd/dhcpcd/dist/common.h
diff -u src/external/bsd/dhcpcd/dist/common.h:1.8 src/external/bsd/dhcpcd/dist/common.h:1.9
--- src/external/bsd/dhcpcd/dist/common.h:1.8 Thu Mar 26 10:26:37 2015
+++ src/external/bsd/dhcpcd/dist/common.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: common.h,v 1.8 2015/03/26 10:26:37 roy Exp $ */
+/* $NetBSD: common.h,v 1.9 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -56,8 +56,8 @@
#define USEC_PER_SEC 1000000L
#define USEC_PER_NSEC 1000L
#define NSEC_PER_SEC 1000000000L
+#define NSEC_PER_MSEC 1000000L
#define MSEC_PER_SEC 1000L
-#define MSEC_PER_NSEC 1000000L
/* Some systems don't define timespec macros */
#ifndef timespecclear
@@ -97,12 +97,12 @@
} while (0 /* CONSTCOND */);
#define ts_to_ms(ms, tv) do { \
ms = (tv)->tv_sec * MSEC_PER_SEC; \
- ms += (tv)->tv_nsec / MSEC_PER_NSEC; \
+ ms += (tv)->tv_nsec / NSEC_PER_MSEC; \
} while (0 /* CONSTCOND */);
#define ms_to_ts(tv, ms) do { \
(tv)->tv_sec = ms / MSEC_PER_SEC; \
(tv)->tv_nsec = (suseconds_t)(ms - ((tv)->tv_sec * MSEC_PER_SEC)) \
- * MSEC_PER_NSEC; \
+ * NSEC_PER_MSEC; \
} while (0 /* CONSTCOND */);
#ifndef TIMEVAL_TO_TIMESPEC
@@ -140,6 +140,10 @@
# endif
#endif
+#ifndef __arraycount
+#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))
+#endif
+
/* We don't really need this as our supported systems define __restrict
* automatically for us, but it is here for completeness. */
#ifndef __restrict
@@ -182,8 +186,12 @@ void logger_close(struct dhcpcd_ctx *);
#endif
ssize_t setvar(struct dhcpcd_ctx *,
- char ***, const char *, const char *, const char *);
+ char **, const char *, const char *, const char *);
ssize_t setvard(struct dhcpcd_ctx *,
+ char **, const char *, const char *, size_t);
+ssize_t addvar(struct dhcpcd_ctx *,
+ char ***, const char *, const char *, const char *);
+ssize_t addvard(struct dhcpcd_ctx *,
char ***, const char *, const char *, size_t);
time_t uptime(void);
Index: src/external/bsd/dhcpcd/dist/config.h
diff -u src/external/bsd/dhcpcd/dist/config.h:1.8 src/external/bsd/dhcpcd/dist/config.h:1.9
--- src/external/bsd/dhcpcd/dist/config.h:1.8 Thu Mar 26 10:26:37 2015
+++ src/external/bsd/dhcpcd/dist/config.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: config.h,v 1.8 2015/03/26 10:26:37 roy Exp $ */
+/* $NetBSD: config.h,v 1.9 2015/05/16 23:31:32 roy Exp $ */
/* netbsd */
#define SYSCONFDIR "/etc"
@@ -7,7 +7,7 @@
#define LIBEXECDIR "/libexec"
#define DBDIR "/var/db"
#define RUNDIR "/var/run"
-#include <sys/queue.h>
+#define HAVE_SYS_QUEUE_H
#define HAVE_SPAWN_H
#define HAVE_KQUEUE
#define HAVE_KQUEUE1
Index: src/external/bsd/dhcpcd/dist/control.c
diff -u src/external/bsd/dhcpcd/dist/control.c:1.8 src/external/bsd/dhcpcd/dist/control.c:1.9
--- src/external/bsd/dhcpcd/dist/control.c:1.8 Thu Mar 26 10:26:37 2015
+++ src/external/bsd/dhcpcd/dist/control.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: control.c,v 1.8 2015/03/26 10:26:37 roy Exp $");
+ __RCSID("$NetBSD: control.c,v 1.9 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -95,7 +95,7 @@ control_delete(struct fd_list *fd)
{
TAILQ_REMOVE(&fd->ctx->control_fds, fd, next);
- eloop_event_delete(fd->ctx->eloop, fd->fd, 0);
+ eloop_event_delete(fd->ctx->eloop, fd->fd);
close(fd->fd);
control_queue_free(fd);
free(fd);
@@ -306,14 +306,14 @@ control_stop(struct dhcpcd_ctx *ctx)
if (ctx->control_fd == -1)
return 0;
- eloop_event_delete(ctx->eloop, ctx->control_fd, 0);
+ eloop_event_delete(ctx->eloop, ctx->control_fd);
close(ctx->control_fd);
ctx->control_fd = -1;
if (unlink(ctx->control_sock) == -1)
retval = -1;
if (ctx->control_unpriv_fd != -1) {
- eloop_event_delete(ctx->eloop, ctx->control_unpriv_fd, 0);
+ eloop_event_delete(ctx->eloop, ctx->control_unpriv_fd);
close(ctx->control_unpriv_fd);
ctx->control_unpriv_fd = -1;
if (unlink(UNPRIVSOCKET) == -1)
@@ -323,7 +323,7 @@ control_stop(struct dhcpcd_ctx *ctx)
freeit:
while ((l = TAILQ_FIRST(&ctx->control_fds))) {
TAILQ_REMOVE(&ctx->control_fds, l, next);
- eloop_event_delete(ctx->eloop, l->fd, 0);
+ eloop_event_delete(ctx->eloop, l->fd);
close(l->fd);
control_queue_free(l);
free(l);
@@ -402,7 +402,7 @@ control_writeone(void *arg)
TAILQ_INSERT_TAIL(&fd->free_queue, data, next);
if (TAILQ_FIRST(&fd->queue) == NULL)
- eloop_event_delete(fd->ctx->eloop, fd->fd, 1);
+ eloop_event_remove_writecb(fd->ctx->eloop, fd->fd);
}
int
Index: src/external/bsd/dhcpcd/dist/dhcp-common.c
diff -u src/external/bsd/dhcpcd/dist/dhcp-common.c:1.8 src/external/bsd/dhcpcd/dist/dhcp-common.c:1.9
--- src/external/bsd/dhcpcd/dist/dhcp-common.c:1.8 Thu Mar 26 10:26:37 2015
+++ src/external/bsd/dhcpcd/dist/dhcp-common.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp-common.c,v 1.8 2015/03/26 10:26:37 roy Exp $");
+ __RCSID("$NetBSD: dhcp-common.c,v 1.9 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -79,6 +79,8 @@ dhcp_print_option_encoding(const struct
printf(" ip6address");
else if (opt->type & FLAG)
printf(" flag");
+ else if (opt->type & BITFLAG)
+ printf(" bitflags");
else if (opt->type & RFC3397)
printf(" domain");
else if (opt->type & DOMAIN)
@@ -89,9 +91,9 @@ dhcp_print_option_encoding(const struct
printf(" raw");
else if (opt->type & BINHEX)
printf(" binhex");
- else if (opt->type & STRING)
+ else if (opt->type & STRING)
printf(" string");
- if (opt->type & RFC3361)
+ if (opt->type & RFC3361)
printf(" rfc3361");
if (opt->type & RFC3442)
printf(" rfc3442");
@@ -562,7 +564,7 @@ dhcp_optlen(const struct dhcp_opt *opt,
sz = sizeof(uint32_t);
else if (opt->type & UINT16)
sz = sizeof(uint16_t);
- else if (opt->type & UINT8)
+ else if (opt->type & (UINT8 | BITFLAG))
sz = sizeof(uint8_t);
else if (opt->type & ADDRIPV6)
sz = ADDR6SZ;
@@ -572,15 +574,9 @@ dhcp_optlen(const struct dhcp_opt *opt,
return (dl < sz ? 0 : sz);
}
-#ifdef INET6
-#define PO_IFNAME
-#else
-#define PO_IFNAME __unused
-#endif
-
-ssize_t
-print_option(char *s, size_t len, int type, const uint8_t *data, size_t dl,
- PO_IFNAME const char *ifname)
+static ssize_t
+print_option(char *s, size_t len, const struct dhcp_opt *opt,
+ const uint8_t *data, size_t dl, const char *ifname)
{
const uint8_t *e, *t;
uint16_t u16;
@@ -592,7 +588,11 @@ print_option(char *s, size_t len, int ty
size_t l;
char *tmp;
- if (type & RFC3397) {
+#ifndef INET6
+ UNUSED(ifname);
+#endif
+
+ if (opt->type & RFC3397) {
sl = decode_rfc3397(NULL, 0, data, dl);
if (sl == 0 || sl == -1)
return sl;
@@ -601,32 +601,32 @@ print_option(char *s, size_t len, int ty
if (tmp == NULL)
return -1;
decode_rfc3397(tmp, l, data, dl);
- sl = print_string(s, len, type, (uint8_t *)tmp, l - 1);
+ sl = print_string(s, len, opt->type, (uint8_t *)tmp, l - 1);
free(tmp);
return sl;
}
#ifdef INET
- if (type & RFC3361) {
+ if (opt->type & RFC3361) {
if ((tmp = decode_rfc3361(data, dl)) == NULL)
return -1;
l = strlen(tmp);
- sl = print_string(s, len, type, (uint8_t *)tmp, l);
+ sl = print_string(s, len, opt->type, (uint8_t *)tmp, l);
free(tmp);
return sl;
}
- if (type & RFC3442)
+ if (opt->type & RFC3442)
return decode_rfc3442(s, len, data, dl);
- if (type & RFC5969)
+ if (opt->type & RFC5969)
return decode_rfc5969(s, len, data, dl);
#endif
- if (type & STRING)
- return print_string(s, len, type, data, dl);
+ if (opt->type & STRING)
+ return print_string(s, len, opt->type, data, dl);
- if (type & FLAG) {
+ if (opt->type & FLAG) {
if (s) {
*s++ = '1';
*s = '\0';
@@ -634,27 +634,50 @@ print_option(char *s, size_t len, int ty
return 1;
}
+ if (opt->type & BITFLAG) {
+ /* bitflags are a string, MSB first, such as ABCDEFGH
+ * where A is 10000000, B is 01000000, etc. */
+ bytes = 0;
+ for (l = 0, sl = sizeof(opt->bitflags) - 1;
+ l < sizeof(opt->bitflags);
+ l++, sl--)
+ {
+ /* Don't print NULL or 0 flags */
+ if (opt->bitflags[l] != '\0' &&
+ opt->bitflags[l] != '0' &&
+ *data & (1 << sl))
+ {
+ if (s)
+ *s++ = opt->bitflags[l];
+ bytes++;
+ }
+ }
+ if (s)
+ *s = '\0';
+ return bytes;
+ }
+
if (!s) {
- if (type & UINT8)
+ if (opt->type & UINT8)
l = 3;
- else if (type & UINT16) {
+ else if (opt->type & UINT16) {
l = 5;
dl /= 2;
- } else if (type & SINT16) {
+ } else if (opt->type & SINT16) {
l = 6;
dl /= 2;
- } else if (type & UINT32) {
+ } else if (opt->type & UINT32) {
l = 10;
dl /= 4;
- } else if (type & SINT32) {
+ } else if (opt->type & SINT32) {
l = 11;
dl /= 4;
- } else if (type & ADDRIPV4) {
+ } else if (opt->type & ADDRIPV4) {
l = 16;
dl /= 4;
}
#ifdef INET6
- else if (type & ADDRIPV6) {
+ else if (opt->type & ADDRIPV6) {
e = data + dl;
l = 0;
while (data < e) {
@@ -683,36 +706,36 @@ print_option(char *s, size_t len, int ty
bytes++;
len--;
}
- if (type & UINT8) {
+ if (opt->type & UINT8) {
sl = snprintf(s, len, "%u", *data);
data++;
- } else if (type & UINT16) {
+ } else if (opt->type & UINT16) {
memcpy(&u16, data, sizeof(u16));
u16 = ntohs(u16);
sl = snprintf(s, len, "%u", u16);
data += sizeof(u16);
- } else if (type & SINT16) {
+ } else if (opt->type & SINT16) {
memcpy(&u16, data, sizeof(u16));
s16 = (int16_t)ntohs(u16);
sl = snprintf(s, len, "%d", s16);
data += sizeof(u16);
- } else if (type & UINT32) {
+ } else if (opt->type & UINT32) {
memcpy(&u32, data, sizeof(u32));
u32 = ntohl(u32);
sl = snprintf(s, len, "%u", u32);
data += sizeof(u32);
- } else if (type & SINT32) {
+ } else if (opt->type & SINT32) {
memcpy(&u32, data, sizeof(u32));
s32 = (int32_t)ntohl(u32);
sl = snprintf(s, len, "%d", s32);
data += sizeof(u32);
- } else if (type & ADDRIPV4) {
+ } else if (opt->type & ADDRIPV4) {
memcpy(&addr.s_addr, data, sizeof(addr.s_addr));
sl = snprintf(s, len, "%s", inet_ntoa(addr));
data += sizeof(addr.s_addr);
}
#ifdef INET6
- else if (type & ADDRIPV6) {
+ else if (opt->type & ADDRIPV6) {
ssize_t r;
r = ipv6_printaddr(s, len, data, ifname);
@@ -776,7 +799,7 @@ dhcp_envoption1(struct dhcpcd_ctx *ctx,
if (opt->len && opt->len < ol)
ol = opt->len;
- len = print_option(NULL, 0, opt->type, od, ol, ifname);
+ len = print_option(NULL, 0, opt, od, ol, ifname);
if (len < 0)
return 0;
if (vname)
@@ -798,7 +821,7 @@ dhcp_envoption1(struct dhcpcd_ctx *ctx,
else
v += snprintf(val, e, "%s=", prefix);
if (len != 0)
- print_option(v, (size_t)len + 1, opt->type, od, ol, ifname);
+ print_option(v, (size_t)len + 1, opt, od, ol, ifname);
return e;
}
@@ -819,7 +842,8 @@ dhcp_envoption(struct dhcpcd_ctx *ctx, c
/* If no embedded or encapsulated options, it's easy */
if (opt->embopts_len == 0 && opt->encopts_len == 0) {
- if (dhcp_envoption1(ctx, env == NULL ? NULL : &env[0],
+ if (!(opt->type & RESERVED) &&
+ dhcp_envoption1(ctx, env == NULL ? NULL : &env[0],
prefix, opt, 1, od, ol, ifname))
return 1;
return 0;
@@ -860,10 +884,12 @@ dhcp_envoption(struct dhcpcd_ctx *ctx, c
/* Use the option prefix if the embedded option
* name is different.
* This avoids new_fqdn_fqdn which would be silly. */
- ov = strcmp(opt->var, eopt->var);
- if (dhcp_envoption1(ctx, env == NULL ? NULL : &env[n],
- pfx, eopt, ov, od, e, ifname))
- n++;
+ if (!(eopt->type & RESERVED)) {
+ ov = strcmp(opt->var, eopt->var);
+ if (dhcp_envoption1(ctx, env == NULL ? NULL : &env[n],
+ pfx, eopt, ov, od, e, ifname))
+ n++;
+ }
od += e;
ol -= e;
}
Index: src/external/bsd/dhcpcd/dist/dhcp-common.h
diff -u src/external/bsd/dhcpcd/dist/dhcp-common.h:1.8 src/external/bsd/dhcpcd/dist/dhcp-common.h:1.9
--- src/external/bsd/dhcpcd/dist/dhcp-common.h:1.8 Thu Mar 26 10:26:37 2015
+++ src/external/bsd/dhcpcd/dist/dhcp-common.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp-common.h,v 1.8 2015/03/26 10:26:37 roy Exp $ */
+/* $NetBSD: dhcp-common.h,v 1.9 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -68,6 +68,8 @@
#define RAW (1 << 23)
#define ESCSTRING (1 << 24)
#define ESCFILE (1 << 25)
+#define BITFLAG (1 << 26)
+#define RESERVED (1 << 27)
struct dhcp_opt {
uint32_t option; /* Also used for IANA Enterpise Number */
@@ -76,6 +78,7 @@ struct dhcp_opt {
char *var;
int index; /* Index counter for many instances of the same option */
+ char bitflags[8];
/* Embedded options.
* The option code is irrelevant here. */
@@ -105,8 +108,6 @@ int make_option_mask(const struct dhcp_o
size_t encode_rfc1035(const char *src, uint8_t *dst);
ssize_t decode_rfc3397(char *, size_t, const uint8_t *, size_t);
ssize_t print_string(char *, size_t, int, const uint8_t *, size_t);
-ssize_t print_option(char *, size_t, int, const uint8_t *, size_t,
- const char *);
int dhcp_set_leasefile(char *, size_t, int,
const struct interface *, const char *);
Index: src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.8 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.9
--- src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.8 Thu Mar 26 10:26:37 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.8 2015/03/26 10:26:37 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.9 2015/05/16 23:31:32 roy Exp $");
/*
* DO NOT EDIT!
@@ -122,7 +122,7 @@ const char * const dhcpcd_embedded_conf[
"embed ascii scope_list",
"define 80 norequest flag rapid_commit",
"define 81 embed fqdn",
-"embed byte flags",
+"embed bitflags=0000NEOS flags",
"embed byte rcode1",
"embed byte rcode2",
"embed domain fqdn",
@@ -201,6 +201,26 @@ const char * const dhcpcd_embedded_conf[
"encap 0 string nvt",
"encap 1 binhex vpn_id",
"encap 255 flag global",
+"definend 1 binhex source_address",
+"definend 2 binhex target_address",
+"definend 3 index embed prefix_information",
+"embed byte length",
+"embed bitflags=LA flags",
+"embed uint32 vltime",
+"embed uint32 pltime",
+"embed uint32 reserved",
+"embed array ip6address prefix",
+"definend 5 embed mtu",
+"embed uint16 reserved",
+"embed uint32 mtu",
+"definend 25 index embed rdnss",
+"embed uint16 reserved",
+"embed uint32 lifetime",
+"embed array ip6address servers",
+"definend 31 index embed dnssl",
+"embed uint16 reserved",
+"embed uint32 lifetime",
+"embed domain search",
"define6 1 binhex client_id",
"define6 2 binhex server_id",
"define6 3 norequest index embed ia_na",
@@ -272,7 +292,7 @@ const char * const dhcpcd_embedded_conf[
"embed binhex remote_id",
"define6 38 binhex subscriber_id",
"define6 39 embed fqdn",
-"embed byte flags",
+"embed bitflags=00000NOS flags",
"embed domain fqdn",
"define6 40 array ip6address pana_agent",
"define6 41 string posix_timezone",
Index: src/external/bsd/dhcpcd/dist/eloop.h
diff -u src/external/bsd/dhcpcd/dist/eloop.h:1.8 src/external/bsd/dhcpcd/dist/eloop.h:1.9
--- src/external/bsd/dhcpcd/dist/eloop.h:1.8 Thu Mar 26 10:26:37 2015
+++ src/external/bsd/dhcpcd/dist/eloop.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: eloop.h,v 1.8 2015/03/26 10:26:37 roy Exp $ */
+/* $NetBSD: eloop.h,v 1.9 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -32,16 +32,79 @@
#include <time.h>
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#else
+/* Attempt to autodetect kqueue or epoll.
+ * If we can't, the system has to support pselect, which is a POSIX call. */
+#if (defined(__unix__) || defined(unix)) && !defined(USG)
+#include <sys/param.h>
+#endif
+#if defined(BSD)
+/* Assume BSD has a working sys/queue.h and kqueue(2) interface */
+#define HAVE_SYS_QUEUE_H
+#define HAVE_KQUEUE
+#elif defined(__linux__)
+/* Assume Linux has a working epoll(3) interface */
+#define HAVE_EPOLL
+#endif
+#endif
+
+/* Our structures require TAILQ macros, which really every libc should
+ * ship as they are useful beyond belief.
+ * Sadly some libc's don't have sys/queue.h and some that do don't have
+ * the TAILQ_FOREACH macro. For those that don't, the application using
+ * this implementation will need to ship a working queue.h somewhere.
+ * If we don't have sys/queue.h found in config.h, then
+ * allow QUEUE_H to override loading queue.h in the current directory. */
+#ifndef TAILQ_FOREACH
+#ifdef HAVE_SYS_QUEUE_H
+#include <sys/queue.h>
+#elif defined(QUEUE_H)
+#define __QUEUE_HEADER(x) #x
+#define _QUEUE_HEADER(x) __QUEUE_HEADER(x)
+#include _QUEUE_HEADER(QUEUE_H)
+#else
+#include "queue.h"
+#endif
+#endif
+/* Some systems don't define timespec macros */
+#ifndef timespecclear
+#define timespecclear(tsp) (tsp)->tv_sec = (time_t)((tsp)->tv_nsec = 0L)
+#define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec)
+#define timespeccmp(tsp, usp, cmp) \
+ (((tsp)->tv_sec == (usp)->tv_sec) ? \
+ ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
+ ((tsp)->tv_sec cmp (usp)->tv_sec))
+#define timespecadd(tsp, usp, vsp) \
+ do { \
+ (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
+ (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
+ if ((vsp)->tv_nsec >= 1000000000L) { \
+ (vsp)->tv_sec++; \
+ (vsp)->tv_nsec -= 1000000000L; \
+ } \
+ } while (/* CONSTCOND */ 0)
+#define timespecsub(tsp, usp, vsp) \
+ do { \
+ (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
+ (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
+ if ((vsp)->tv_nsec < 0) { \
+ (vsp)->tv_sec--; \
+ (vsp)->tv_nsec += 1000000000L; \
+ } \
+ } while (/* CONSTCOND */ 0)
+#endif
+
+/* eloop queues are really only for deleting timeouts registered
+ * for a function or object.
+ * The idea being that one interface as different timeouts for
+ * say DHCP and DHCPv6. */
#ifndef ELOOP_QUEUE
#define ELOOP_QUEUE 1
#endif
-/* EXIT_FAILURE is a non zero value and EXIT_SUCCESS is zero.
- * To add a CONTINUE definition, simply do the opposite of EXIT_FAILURE. */
-#define ELOOP_CONTINUE -EXIT_FAILURE
-
struct eloop_event {
TAILQ_ENTRY(eloop_event) next;
int fd;
@@ -62,9 +125,7 @@ struct eloop_timeout {
int queue;
};
-struct eloop_ctx {
- struct dhcpcd_ctx *ctx;
-
+struct eloop {
size_t events_len;
TAILQ_HEAD (event_head, eloop_event) events;
struct event_head free_events;
@@ -74,6 +135,10 @@ struct eloop_ctx {
void (*timeout0)(void *);
void *timeout0_arg;
+ const int *signals;
+ size_t signals_len;
+ void (*signal_cb)(int, void *);
+ void *signal_cb_ctx;
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
int poll_fd;
@@ -86,33 +151,43 @@ struct eloop_ctx {
int exitcode;
};
-#define eloop_timeout_add_tv(a, b, c, d) \
- eloop_q_timeout_add_tv(a, ELOOP_QUEUE, b, c, d)
-#define eloop_timeout_add_sec(a, b, c, d) \
- eloop_q_timeout_add_sec(a, ELOOP_QUEUE, b, c, d)
-#define eloop_timeout_delete(a, b, c) \
- eloop_q_timeout_delete(a, ELOOP_QUEUE, b, c)
-
-int eloop_event_add(struct eloop_ctx *, int,
+int eloop_event_add(struct eloop *, int,
void (*)(void *), void *,
void (*)(void *), void *);
-void eloop_event_delete(struct eloop_ctx *, int, int);
-int eloop_q_timeout_add_sec(struct eloop_ctx *, int queue,
- time_t, void (*)(void *), void *);
-int eloop_q_timeout_add_tv(struct eloop_ctx *, int queue,
+#define eloop_event_delete(eloop, fd) \
+ eloop_event_delete_write((eloop), (fd), 0)
+#define eloop_event_remove_writecb(eloop, fd) \
+ eloop_event_delete_write((eloop), (fd), 1)
+void eloop_event_delete_write(struct eloop *, int, int);
+
+#define eloop_timeout_add_tv(eloop, tv, cb, ctx) \
+ eloop_q_timeout_add_tv((eloop), ELOOP_QUEUE, (tv), (cb), (ctx))
+#define eloop_timeout_add_sec(eloop, tv, cb, ctx) \
+ eloop_q_timeout_add_sec((eloop), ELOOP_QUEUE, (tv), (cb), (ctx))
+#define eloop_timeout_add_msec(eloop, ms, cb, ctx) \
+ eloop_q_timeout_add_msec((eloop), ELOOP_QUEUE, (ms), (cb), (ctx))
+#define eloop_timeout_delete(eloop, cb, ctx) \
+ eloop_q_timeout_delete((eloop), ELOOP_QUEUE, (cb), (ctx))
+int eloop_q_timeout_add_tv(struct eloop *, int,
const struct timespec *, void (*)(void *), void *);
-#if !defined(HAVE_KQUEUE)
-int eloop_timeout_add_now(struct eloop_ctx *, void (*)(void *), void *);
-#endif
-void eloop_q_timeout_delete(struct eloop_ctx *, int, void (*)(void *), void *);
-struct eloop_ctx * eloop_init(struct dhcpcd_ctx *);
+int eloop_q_timeout_add_sec(struct eloop *, int,
+ time_t, void (*)(void *), void *);
+int eloop_q_timeout_add_msec(struct eloop *, int,
+ long, void (*)(void *), void *);
+void eloop_q_timeout_delete(struct eloop *, int, void (*)(void *), void *);
+
+int eloop_signal_set_cb(struct eloop *, const int *, size_t,
+ void (*)(int, void *), void *);
+int eloop_signal_mask(struct eloop *, sigset_t *oldset);
+
+struct eloop * eloop_new(void);
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
-int eloop_requeue(struct eloop_ctx *);
+int eloop_requeue(struct eloop *);
#else
-#define eloop_requeue(a) (0)
+#define eloop_requeue(eloop) (0)
#endif
-void eloop_free(struct eloop_ctx *);
-void eloop_exit(struct eloop_ctx *, int);
-int eloop_start(struct eloop_ctx *);
+void eloop_free(struct eloop *);
+void eloop_exit(struct eloop *, int);
+int eloop_start(struct eloop *, sigset_t *);
#endif
Index: src/external/bsd/dhcpcd/dist/defs.h
diff -u src/external/bsd/dhcpcd/dist/defs.h:1.17 src/external/bsd/dhcpcd/dist/defs.h:1.18
--- src/external/bsd/dhcpcd/dist/defs.h:1.17 Sat May 2 15:18:36 2015
+++ src/external/bsd/dhcpcd/dist/defs.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: defs.h,v 1.17 2015/05/02 15:18:36 roy Exp $ */
+/* $NetBSD: defs.h,v 1.18 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -30,7 +30,7 @@
#define CONFIG_H
#define PACKAGE "dhcpcd"
-#define VERSION "6.8.2"
+#define VERSION "6.9.0"
#ifndef CONFIG
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
Index: src/external/bsd/dhcpcd/dist/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.30 src/external/bsd/dhcpcd/dist/dhcp.c:1.31
--- src/external/bsd/dhcpcd/dist/dhcp.c:1.30 Sat May 2 15:18:36 2015
+++ src/external/bsd/dhcpcd/dist/dhcp.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp.c,v 1.30 2015/05/02 15:18:36 roy Exp $");
+ __RCSID("$NetBSD: dhcp.c,v 1.31 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -1277,35 +1277,35 @@ dhcp_env(char **env, const char *prefix,
/* Set some useful variables that we derive from the DHCP
* message but are not necessarily in the options */
addr.s_addr = dhcp->yiaddr ? dhcp->yiaddr : dhcp->ciaddr;
- setvar(ifp->ctx, &ep, prefix, "ip_address", inet_ntoa(addr));
+ addvar(ifp->ctx, &ep, prefix, "ip_address", inet_ntoa(addr));
if (get_option_addr(ifp->ctx, &net,
dhcp, DHO_SUBNETMASK) == -1) {
net.s_addr = ipv4_getnetmask(addr.s_addr);
- setvar(ifp->ctx, &ep, prefix,
+ addvar(ifp->ctx, &ep, prefix,
"subnet_mask", inet_ntoa(net));
}
snprintf(cidr, sizeof(cidr), "%d", inet_ntocidr(net));
- setvar(ifp->ctx, &ep, prefix, "subnet_cidr", cidr);
+ addvar(ifp->ctx, &ep, prefix, "subnet_cidr", cidr);
if (get_option_addr(ifp->ctx, &brd,
dhcp, DHO_BROADCAST) == -1) {
brd.s_addr = addr.s_addr | ~net.s_addr;
- setvar(ifp->ctx, &ep, prefix,
+ addvar(ifp->ctx, &ep, prefix,
"broadcast_address", inet_ntoa(brd));
}
addr.s_addr = dhcp->yiaddr & net.s_addr;
- setvar(ifp->ctx, &ep, prefix,
+ addvar(ifp->ctx, &ep, prefix,
"network_number", inet_ntoa(addr));
}
if (*dhcp->bootfile && !(overl & 1)) {
print_string(safe, sizeof(safe), STRING,
dhcp->bootfile, sizeof(dhcp->bootfile));
- setvar(ifp->ctx, &ep, prefix, "filename", safe);
+ addvar(ifp->ctx, &ep, prefix, "filename", safe);
}
if (*dhcp->servername && !(overl & 2)) {
print_string(safe, sizeof(safe), STRING | DOMAIN,
dhcp->servername, sizeof(dhcp->servername));
- setvar(ifp->ctx, &ep, prefix, "server_name", safe);
+ addvar(ifp->ctx, &ep, prefix, "server_name", safe);
}
/* Zero our indexes */
@@ -1440,7 +1440,7 @@ dhcp_close(struct interface *ifp)
return;
if (state->raw_fd != -1) {
- eloop_event_delete(ifp->ctx->eloop, state->raw_fd, 0);
+ eloop_event_delete(ifp->ctx->eloop, state->raw_fd);
close(state->raw_fd);
state->raw_fd = -1;
}
@@ -1596,12 +1596,16 @@ send_message(struct interface *ifp, uint
struct ipv4_addr *ia;
#endif
- if (!callback)
+ s = -1;
+ if (!callback) {
+ /* No carrier? Don't bother sending the packet. */
+ if (ifp->carrier == LINK_DOWN)
+ return;
logger(ifp->ctx, LOG_DEBUG, "%s: sending %s with xid 0x%x",
ifp->name,
ifo->options & DHCPCD_BOOTP ? "BOOTP" : get_dhcp_op(type),
state->xid);
- else {
+ } else {
if (state->interval == 0)
state->interval = 4;
else {
@@ -1613,6 +1617,10 @@ send_message(struct interface *ifp, uint
tv.tv_nsec = (suseconds_t)arc4random_uniform(
(DHCP_RAND_MAX - DHCP_RAND_MIN) * NSEC_PER_SEC);
timespecnorm(&tv);
+ /* No carrier? Don't bother sending the packet.
+ * However, we do need to advance the timeout. */
+ if (ifp->carrier == LINK_DOWN)
+ goto fail;
logger(ifp->ctx, LOG_DEBUG,
"%s: sending %s (xid 0x%x), next in %0.1f seconds",
ifp->name,
@@ -1638,8 +1646,7 @@ send_message(struct interface *ifp, uint
if (s == -1 && errno != EADDRINUSE)
logger(ifp->ctx, LOG_ERR,
"%s: dhcp_openudp: %m", ifp->name);
- } else
- s = -1;
+ }
/* If we couldn't open a UDP port for our IP address
* then we cannot renew.
@@ -1862,6 +1869,104 @@ dhcp_rebind(void *arg)
send_rebind(ifp);
}
+static void
+dhcp_arp_probed(struct arp_state *astate)
+{
+ struct dhcp_state *state;
+ struct if_options *ifo;
+
+ /* We didn't find a profile for this
+ * address or hwaddr, so move to the next
+ * arping profile */
+ state = D_STATE(astate->iface);
+ ifo = astate->iface->options;
+ if (state->arping_index < ifo->arping_len) {
+ if (++state->arping_index < ifo->arping_len) {
+ astate->addr.s_addr =
+ ifo->arping[state->arping_index - 1];
+ arp_probe(astate);
+ }
+ dhcpcd_startinterface(astate->iface);
+ return;
+ }
+ dhcp_close(astate->iface);
+ eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate->iface);
+#ifdef IN_IFF_TENTATIVE
+ ipv4_finaliseaddr(astate->iface);
+ arp_close(astate->iface);
+#else
+ dhcp_bind(astate->iface, astate);
+#endif
+}
+
+static void
+dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
+{
+ struct dhcp_state *state;
+ struct if_options *ifo;
+
+ state = D_STATE(astate->iface);
+ ifo = astate->iface->options;
+ if (state->arping_index &&
+ state->arping_index <= ifo->arping_len &&
+ amsg &&
+ (amsg->sip.s_addr == ifo->arping[state->arping_index - 1] ||
+ (amsg->sip.s_addr == 0 &&
+ amsg->tip.s_addr == ifo->arping[state->arping_index - 1])))
+ {
+ char buf[HWADDR_LEN * 3];
+
+ astate->failed.s_addr = ifo->arping[state->arping_index - 1];
+ arp_report_conflicted(astate, amsg);
+ hwaddr_ntoa(amsg->sha, astate->iface->hwlen, buf, sizeof(buf));
+ if (dhcpcd_selectprofile(astate->iface, buf) == -1 &&
+ dhcpcd_selectprofile(astate->iface,
+ inet_ntoa(astate->failed)) == -1)
+ {
+ /* We didn't find a profile for this
+ * address or hwaddr, so move to the next
+ * arping profile */
+ dhcp_arp_probed(astate);
+ return;
+ }
+ dhcp_close(astate->iface);
+ arp_close(astate->iface);
+ eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
+ astate->iface);
+ dhcpcd_startinterface(astate->iface);
+ }
+
+ /* RFC 2131 3.1.5, Client-server interaction
+ * NULL amsg means IN_IFF_DUPLICATED */
+ if (amsg == NULL || (state->offer &&
+ (amsg->sip.s_addr == state->offer->yiaddr ||
+ (amsg->sip.s_addr == 0 &&
+ amsg->tip.s_addr == state->offer->yiaddr))))
+ {
+#ifdef IN_IFF_DUPLICATED
+ struct ipv4_addr *ia;
+#endif
+
+ if (amsg)
+ astate->failed.s_addr = state->offer->yiaddr;
+ else
+ astate->failed = astate->addr;
+ arp_report_conflicted(astate, amsg);
+ unlink(state->leasefile);
+ if (!state->lease.frominfo)
+ dhcp_decline(astate->iface);
+#ifdef IN_IFF_DUPLICATED
+ ia = ipv4_iffindaddr(astate->iface, &astate->addr, NULL);
+ if (ia)
+ ipv4_deladdr(astate->iface, &ia->addr, &ia->net);
+#endif
+ eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
+ astate->iface);
+ eloop_timeout_add_sec(astate->iface->ctx->eloop,
+ DHCP_RAND_MAX, dhcp_discover, astate->iface);
+ }
+}
+
void
dhcp_bind(struct interface *ifp, struct arp_state *astate)
{
@@ -1872,6 +1977,9 @@ dhcp_bind(struct interface *ifp, struct
if (state->state == DHS_BOUND)
goto applyaddr;
+#ifdef IN_IFF_TENTATIVE
+ state->added |= STATE_TENTATIVE;
+#endif
state->reason = NULL;
free(state->old);
state->old = state->new;
@@ -1989,6 +2097,16 @@ dhcp_bind(struct interface *ifp, struct
"%s: write_lease: %m", __func__);
applyaddr:
+#ifdef IN_IFF_TENTATIVE
+ if (astate == NULL) {
+ astate = arp_new(ifp, &lease->addr);
+ if (astate) {
+ astate->probed_cb = dhcp_arp_probed;
+ astate->conflicted_cb = dhcp_arp_conflicted;
+ }
+ }
+#endif
+
ipv4_applyaddr(ifp);
if (ifo->options & DHCPCD_ARP &&
!(ifp->ctx->options & DHCPCD_FORKED))
@@ -2345,104 +2463,6 @@ whitelisted_ip(const struct if_options *
}
static void
-dhcp_arp_probed(struct arp_state *astate)
-{
- struct dhcp_state *state;
- struct if_options *ifo;
-
- /* We didn't find a profile for this
- * address or hwaddr, so move to the next
- * arping profile */
- state = D_STATE(astate->iface);
- ifo = astate->iface->options;
- if (state->arping_index < ifo->arping_len) {
- if (++state->arping_index < ifo->arping_len) {
- astate->addr.s_addr =
- ifo->arping[state->arping_index - 1];
- arp_probe(astate);
- }
- dhcpcd_startinterface(astate->iface);
- return;
- }
- dhcp_close(astate->iface);
- eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate->iface);
-#ifdef IN_IFF_TENTATIVE
- ipv4_finaliseaddr(astate->iface);
- arp_close(astate->iface);
-#else
- dhcp_bind(astate->iface, astate);
-#endif
-}
-
-static void
-dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
-{
- struct dhcp_state *state;
- struct if_options *ifo;
-
- state = D_STATE(astate->iface);
- ifo = astate->iface->options;
- if (state->arping_index &&
- state->arping_index <= ifo->arping_len &&
- amsg &&
- (amsg->sip.s_addr == ifo->arping[state->arping_index - 1] ||
- (amsg->sip.s_addr == 0 &&
- amsg->tip.s_addr == ifo->arping[state->arping_index - 1])))
- {
- char buf[HWADDR_LEN * 3];
-
- astate->failed.s_addr = ifo->arping[state->arping_index - 1];
- arp_report_conflicted(astate, amsg);
- hwaddr_ntoa(amsg->sha, astate->iface->hwlen, buf, sizeof(buf));
- if (dhcpcd_selectprofile(astate->iface, buf) == -1 &&
- dhcpcd_selectprofile(astate->iface,
- inet_ntoa(astate->failed)) == -1)
- {
- /* We didn't find a profile for this
- * address or hwaddr, so move to the next
- * arping profile */
- dhcp_arp_probed(astate);
- return;
- }
- dhcp_close(astate->iface);
- arp_close(astate->iface);
- eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
- astate->iface);
- dhcpcd_startinterface(astate->iface);
- }
-
- /* RFC 2131 3.1.5, Client-server interaction
- * NULL amsg means IN_IFF_DUPLICATED */
- if (amsg == NULL || (state->offer &&
- (amsg->sip.s_addr == state->offer->yiaddr ||
- (amsg->sip.s_addr == 0 &&
- amsg->tip.s_addr == state->offer->yiaddr))))
- {
-#ifdef IN_IFF_DUPLICATED
- struct ipv4_addr *ia;
-#endif
-
- if (amsg)
- astate->failed.s_addr = state->offer->yiaddr;
- else
- astate->failed = astate->addr;
- arp_report_conflicted(astate, amsg);
- unlink(state->leasefile);
- if (!state->lease.frominfo)
- dhcp_decline(astate->iface);
-#ifdef IN_IFF_DUPLICATED
- ia = ipv4_iffindaddr(astate->iface, &astate->addr, NULL);
- if (ia)
- ipv4_deladdr(astate->iface, &ia->addr, &ia->net);
-#endif
- eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
- astate->iface);
- eloop_timeout_add_sec(astate->iface->ctx->eloop,
- DHCP_RAND_MAX, dhcp_discover, astate->iface);
- }
-}
-
-static void
dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
const struct in_addr *from)
{
@@ -2762,28 +2782,22 @@ dhcp_handledhcp(struct interface *ifp, s
#ifndef IN_IFF_TENTATIVE
if (ifo->options & DHCPCD_ARP
&& state->addr.s_addr != state->offer->yiaddr)
-#endif
{
addr.s_addr = state->offer->yiaddr;
-#ifndef IN_IFF_TENTATIVE
/* If the interface already has the address configured
* then we can't ARP for duplicate detection. */
ia = ipv4_findaddr(ifp->ctx, &addr);
if (ia) {
-#endif
astate = arp_new(ifp, &addr);
if (astate) {
astate->probed_cb = dhcp_arp_probed;
astate->conflicted_cb = dhcp_arp_conflicted;
-#ifndef IN_IFF_TENTATIVE
arp_probe(astate);
-#endif
}
-#ifndef IN_IFF_TENTATIVE
return;
}
-#endif
}
+#endif
dhcp_bind(ifp, astate);
}
@@ -2954,7 +2968,7 @@ dhcp_handleudp(void *arg)
* from the raw fd */
if (read(ctx->udp_fd, buffer, sizeof(buffer)) == -1) {
logger(ctx, LOG_ERR, "%s: %m", __func__);
- eloop_event_delete(ctx->eloop, ctx->udp_fd, 0);
+ eloop_event_delete(ctx->eloop, ctx->udp_fd);
close(ctx->udp_fd);
ctx->udp_fd = -1;
}
@@ -3049,7 +3063,7 @@ dhcp_free(struct interface *ifp)
}
if (ifp == NULL) {
if (ctx->udp_fd != -1) {
- eloop_event_delete(ctx->eloop, ctx->udp_fd, 0);
+ eloop_event_delete(ctx->eloop, ctx->udp_fd);
close(ctx->udp_fd);
ctx->udp_fd = -1;
}
Index: src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.7 src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.8
--- src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.7 Fri Jan 30 09:47:05 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-# $NetBSD: dhcpcd-definitions.conf,v 1.7 2015/01/30 09:47:05 roy Exp $
+# $NetBSD: dhcpcd-definitions.conf,v 1.8 2015/05/16 23:31:32 roy Exp $
# Copyright (c) 2006-2015 Roy Marples
# All rights reserved
@@ -109,7 +109,7 @@ define 80 norequest flag rapid_commit
# DHCP Fully Qualified Domain Name, RFC4702
define 81 embed fqdn
-embed byte flags
+embed bitflags=0000NEOS flags
embed byte rcode1
embed byte rcode2
embed domain fqdn
@@ -289,6 +289,36 @@ encap 255 flag global
# Option 255 End
##############################################################################
+# ND6 options, RFC4861
+definend 1 binhex source_address
+definend 2 binhex target_address
+
+definend 3 index embed prefix_information
+embed byte length
+embed bitflags=LA flags
+embed uint32 vltime
+embed uint32 pltime
+embed uint32 reserved
+embed array ip6address prefix
+
+# option 4 is only for Redirect messages
+
+definend 5 embed mtu
+embed uint16 reserved
+embed uint32 mtu
+
+# ND6 options, RFC6101
+definend 25 index embed rdnss
+embed uint16 reserved
+embed uint32 lifetime
+embed array ip6address servers
+
+definend 31 index embed dnssl
+embed uint16 reserved
+embed uint32 lifetime
+embed domain search
+
+##############################################################################
# DHCPv6 options, RFC3315
define6 1 binhex client_id
define6 2 binhex server_id
@@ -399,7 +429,7 @@ define6 38 binhex subscriber_id
# DHCPv6 Fully Qualified Domain Name, RFC4704
define6 39 embed fqdn
-embed byte flags
+embed bitflags=00000NOS flags
embed domain fqdn
# DHCPv6 PANA Authentication Agnet, RC5192
Index: src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h:1.7 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h:1.8
--- src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h:1.7 Fri Jan 30 09:47:05 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcpcd-embedded.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */
+/* $NetBSD: dhcpcd-embedded.h,v 1.8 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -28,6 +28,7 @@
*/
#define INITDEFINES 121
+#define INITDEFINENDS 6
#define INITDEFINE6S 68
extern const char * const dhcpcd_embedded_conf[];
Index: src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.13 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.14
--- src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.13 Fri Jan 30 09:47:05 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-.\" $NetBSD: dhcpcd-run-hooks.8.in,v 1.13 2015/01/30 09:47:05 roy Exp $
+.\" $NetBSD: dhcpcd-run-hooks.8.in,v 1.14 2015/05/16 23:31:32 roy Exp $
.\" Copyright (c) 2006-2015 Roy Marples
.\" All rights reserved
.\"
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd October 3, 2014
+.Dd May 14, 2015
.Dt DHCPCD-RUN-HOOKS 8
.Os
.Sh NAME
@@ -187,11 +187,6 @@ is down, otherwise
.It Ev $if_oneup
.Dv true
if any interface is up, otherwise false.
-.It Ev $if_ipwaited
-.Dv true
-if any interface has been assigned an IP address which matches any wait
-requirements specified in
-.Xr dhcpcd.conf 5 .
.It Ev $profile
the name of the profile selected from
.Xr dhcpcd.conf 5 .
Index: src/external/bsd/dhcpcd/dist/dhcpcd.8.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.41 src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.42
--- src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.41 Thu Mar 26 10:26:37 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.8.in Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-.\" $NetBSD: dhcpcd.8.in,v 1.41 2015/03/26 10:26:37 roy Exp $
+.\" $NetBSD: dhcpcd.8.in,v 1.42 2015/05/16 23:31:32 roy Exp $
.\" Copyright (c) 2006-2015 Roy Marples
.\" All rights reserved
.\"
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd March 17, 2015
+.Dd May 9, 2015
.Dt DHCPCD 8
.Os
.Sh NAME
@@ -418,7 +418,7 @@ If
fails to contact a DHCP server then it returns a failure instead of falling
back on IPv4LL.
.It Fl S, Fl Fl static Ar value
-Configures a static
+Configures a static DHCP
.Ar value .
If you set
.Ic ip_address
@@ -432,6 +432,11 @@ Here is an example which configures a st
.D1 -S routers=192.168.0.1 \e
.D1 -S domain_name_servers=192.168.0.1 \e
.D1 eth0
+.Pp
+You cannot presently set static DHCPv6 values.
+Use the
+.Fl e , Fl Fl env
+option instead.
.It Fl t , Fl Fl timeout Ar seconds
Timeout after
.Ar seconds ,
Index: src/external/bsd/dhcpcd/dist/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.c:1.24 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.25
--- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.24 Sat May 2 15:18:36 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd.c,v 1.24 2015/05/02 15:18:36 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd.c,v 1.25 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -69,19 +69,16 @@ const char dhcpcd_copyright[] = "Copyrig
#include "script.h"
#ifdef USE_SIGNALS
-const int dhcpcd_handlesigs[] = {
+const int dhcpcd_signals[] = {
SIGTERM,
SIGINT,
SIGALRM,
SIGHUP,
SIGUSR1,
SIGUSR2,
- SIGPIPE,
- 0
+ SIGPIPE
};
-
-/* Handling signals needs *some* context */
-static struct dhcpcd_ctx *dhcpcd_ctx;
+const size_t dhcpcd_signals_len = __arraycount(dhcpcd_signals);
#endif
#if defined(USE_SIGNALS) || !defined(THERE_IS_NO_FORK)
@@ -170,6 +167,14 @@ free_globals(struct dhcpcd_ctx *ctx)
}
#endif
#ifdef INET6
+ if (ctx->nd_opts) {
+ for (opt = ctx->nd_opts;
+ ctx->nd_opts_len > 0;
+ opt++, ctx->nd_opts_len--)
+ free_dhcp_opt_embenc(opt);
+ free(ctx->nd_opts);
+ ctx->nd_opts = NULL;
+ }
if (ctx->dhcp6_opts) {
for (opt = ctx->dhcp6_opts;
ctx->dhcp6_opts_len > 0;
@@ -218,26 +223,50 @@ dhcpcd_oneup(struct dhcpcd_ctx *ctx)
return 0;
}
-int
-dhcpcd_ipwaited(struct dhcpcd_ctx *ctx)
+static int
+dhcpcd_ifipwaited(struct interface *ifp, unsigned long long opts)
{
- if (ctx->options & DHCPCD_WAITIP4 &&
- !ipv4_addrexists(ctx, NULL))
+ if (opts & DHCPCD_WAITIP4 && !ipv4_ifaddrexists(ifp))
return 0;
- if (ctx->options & DHCPCD_WAITIP6 &&
- !ipv6nd_findaddr(ctx, NULL, 0) &&
- !dhcp6_findaddr(ctx, NULL, 0))
+ if (opts & DHCPCD_WAITIP6 && !ipv6_iffindaddr(ifp, NULL))
return 0;
- if (ctx->options & DHCPCD_WAITIP &&
- !(ctx->options & (DHCPCD_WAITIP4 | DHCPCD_WAITIP6)) &&
- !ipv4_addrexists(ctx, NULL) &&
- !ipv6nd_findaddr(ctx, NULL, 0) &&
- !dhcp6_findaddr(ctx, NULL, 0))
+ if (opts & DHCPCD_WAITIP &&
+ !(opts & (DHCPCD_WAITIP4 | DHCPCD_WAITIP6)) &&
+ !ipv4_ifaddrexists(ifp) &&
+ !ipv6_iffindaddr(ifp, NULL))
return 0;
return 1;
}
+static int
+dhcpcd_ipwaited(struct dhcpcd_ctx *ctx)
+{
+ struct interface *ifp;
+
+ TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+ if (ifp->options->options & DHCPCD_WAITOPTS) {
+ if (!dhcpcd_ifipwaited(ifp, ifp->options->options)) {
+ logger(ctx, LOG_DEBUG,
+ "%s: waiting for an ip address",
+ ifp->name);
+ return 0;
+ }
+ }
+ }
+
+ if (!(ctx->options & DHCPCD_WAITOPTS))
+ return 1;
+
+ TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+ if (dhcpcd_ifipwaited(ifp, ctx->options))
+ return 1;
+ }
+
+ logger(ctx, LOG_DEBUG, "waiting for an ip address");
+ return 0;
+}
+
/* Returns the pid of the child, otherwise 0. */
pid_t
dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
@@ -590,7 +619,7 @@ dhcpcd_pollup(void *arg)
struct timespec tv;
tv.tv_sec = 0;
- tv.tv_nsec = IF_POLL_UP * MSEC_PER_NSEC;
+ tv.tv_nsec = IF_POLL_UP * NSEC_PER_MSEC;
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcpcd_pollup, ifp);
return;
}
@@ -643,7 +672,8 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *
script_runreason(ifp, "NOCARRIER");
#ifdef NOCARRIER_PRESERVE_IP
arp_close(ifp);
- ipv4_buildroutes(ifp->ctx);
+ if_sortinterfaces(ctx);
+ ipv4_preferanother(ifp);
ipv6nd_expire(ifp, 0);
#else
dhcpcd_drop(ifp, 0);
@@ -757,7 +787,7 @@ dhcpcd_startinterface(void *arg)
* Loop until both IFF_UP and IFF_RUNNING are set */
if ((carrier = if_carrier(ifp)) == LINK_UNKNOWN) {
tv.tv_sec = 0;
- tv.tv_nsec = IF_POLL_UP * MSEC_PER_NSEC;
+ tv.tv_nsec = IF_POLL_UP * NSEC_PER_MSEC;
eloop_timeout_add_tv(ifp->ctx->eloop,
&tv, dhcpcd_startinterface, ifp);
} else
@@ -877,7 +907,7 @@ handle_link(void *arg)
ctx = arg;
if (if_managelink(ctx) == -1) {
logger(ctx, LOG_ERR, "if_managelink: %m");
- eloop_event_delete(ctx->eloop, ctx->link_fd, 0);
+ eloop_event_delete(ctx->eloop, ctx->link_fd);
close(ctx->link_fd);
ctx->link_fd = -1;
}
@@ -1119,21 +1149,17 @@ stop_all_interfaces(struct dhcpcd_ctx *c
}
#ifdef USE_SIGNALS
-struct dhcpcd_siginfo dhcpcd_siginfo;
#define sigmsg "received %s, %s"
-void
-dhcpcd_handle_signal(void *arg)
+static void
+signal_cb(int sig, void *arg)
{
- struct dhcpcd_ctx *ctx;
- struct dhcpcd_siginfo *si;
+ struct dhcpcd_ctx *ctx = arg;
struct interface *ifp;
- int do_release, exit_code;;
+ int do_release, exit_code;
- ctx = dhcpcd_ctx;
- si = arg;
do_release = 0;
exit_code = EXIT_FAILURE;
- switch (si->signo) {
+ switch (sig) {
case SIGINT:
logger(ctx, LOG_INFO, sigmsg, "SIGINT", "stopping");
break;
@@ -1172,7 +1198,7 @@ dhcpcd_handle_signal(void *arg)
logger(ctx, LOG_ERR,
"received signal %d, "
"but don't know what to do with it",
- si->signo);
+ sig);
return;
}
@@ -1180,47 +1206,6 @@ dhcpcd_handle_signal(void *arg)
stop_all_interfaces(ctx, do_release);
eloop_exit(ctx->eloop, exit_code);
}
-
-#ifndef HAVE_KQUEUE
-static void
-handle_signal(int sig, __unused siginfo_t *siginfo, __unused void *context)
-{
-
- /* So that we can operate safely under a signal we instruct
- * eloop to pass a copy of the siginfo structure to handle_signal1
- * as the very first thing to do. */
- dhcpcd_siginfo.signo = sig;
- eloop_timeout_add_now(dhcpcd_ctx->eloop,
- dhcpcd_handle_signal, &dhcpcd_siginfo);
-}
-#endif
-
-static int
-signal_init(sigset_t *oldset)
-{
- sigset_t newset;
-#ifndef HAVE_KQUEUE
- int i;
- struct sigaction sa;
-#endif
-
- sigfillset(&newset);
- if (sigprocmask(SIG_SETMASK, &newset, oldset) == -1)
- return -1;
-
-#ifndef HAVE_KQUEUE
- memset(&sa, 0, sizeof(sa));
- sa.sa_sigaction = handle_signal;
- sa.sa_flags = SA_SIGINFO;
- sigemptyset(&sa.sa_mask);
-
- for (i = 0; dhcpcd_handlesigs[i]; i++) {
- if (sigaction(dhcpcd_handlesigs[i], &sa, NULL) == -1)
- return -1;
- }
-#endif
- return 0;
-}
#endif
static void
@@ -1242,7 +1227,7 @@ dhcpcd_getinterfaces(void *arg)
}
if (write(fd->fd, &len, sizeof(len)) != sizeof(len))
return;
- eloop_event_delete(fd->ctx->eloop, fd->fd, 1);
+ eloop_event_remove_writecb(fd->ctx->eloop, fd->fd);
TAILQ_FOREACH(ifp, fd->ctx->ifaces, next) {
if (send_interface(fd, ifp) == -1)
logger(ifp->ctx, LOG_ERR,
@@ -1344,7 +1329,7 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx
reload_config(ctx);
/* XXX: Respect initial commandline options? */
- reconf_reboot(ctx, do_reboot, argc, argv, optind);
+ reconf_reboot(ctx, do_reboot, argc, argv, optind - 1);
return 0;
}
@@ -1362,8 +1347,8 @@ main(int argc, char **argv)
pid_t pid;
#endif
#ifdef USE_SIGNALS
- int sig;
- const char *siga;
+ int sig = 0;
+ const char *siga = NULL;
#endif
/* Test for --help and --version */
@@ -1378,11 +1363,6 @@ main(int argc, char **argv)
}
memset(&ctx, 0, sizeof(ctx));
-#ifdef USE_SIGNALS
- dhcpcd_ctx = &ctx;
- sig = 0;
- siga = NULL;
-#endif
closefrom(3);
ctx.log_fd = -1;
@@ -1486,6 +1466,9 @@ main(int argc, char **argv)
#endif
#ifdef INET6
if (family == 0 || family == AF_INET6) {
+ printf("\nND options:\n");
+ ipv6nd_printoptions(&ctx,
+ ifo->nd_override, ifo->nd_override_len);
printf("\nDHCPv6 options:\n");
dhcp6_printoptions(&ctx,
ifo->dhcp6_override, ifo->dhcp6_override_len);
@@ -1558,8 +1541,7 @@ main(int argc, char **argv)
/* Freeing allocated addresses from dumping leases can trigger
* eloop removals as well, so init here. */
- ctx.eloop = eloop_init(&ctx);
- if (ctx.eloop == NULL) {
+ if ((ctx.eloop = eloop_new()) == NULL) {
logger(&ctx, LOG_ERR, "%s: eloop_init: %m", __func__);
goto exit_failure;
}
@@ -1747,9 +1729,16 @@ main(int argc, char **argv)
logger(&ctx, LOG_DEBUG, PACKAGE "-" VERSION " starting");
ctx.options |= DHCPCD_STARTED;
#ifdef USE_SIGNALS
+ if (eloop_signal_set_cb(ctx.eloop,
+ dhcpcd_signals, dhcpcd_signals_len,
+ signal_cb, &ctx) == -1)
+ {
+ logger(&ctx, LOG_ERR, "eloop_signal_mask: %m");
+ goto exit_failure;
+ }
/* Save signal mask, block and redirect signals to our handler */
- if (signal_init(&ctx.sigset) == -1) {
- logger(&ctx, LOG_ERR, "signal_setup: %m");
+ if (eloop_signal_mask(ctx.eloop, &ctx.sigset) == -1) {
+ logger(&ctx, LOG_ERR, "eloop_signal_mask: %m");
goto exit_failure;
}
#endif
@@ -1846,7 +1835,11 @@ main(int argc, char **argv)
dhcpcd_prestartinterface, ifp);
}
- i = eloop_start(ctx.eloop);
+ i = eloop_start(ctx.eloop, &ctx.sigset);
+ if (i < 0) {
+ syslog(LOG_ERR, "eloop_start: %m");
+ goto exit_failure;
+ }
goto exit1;
exit_success:
@@ -1867,7 +1860,7 @@ exit1:
}
free(ctx.duid);
if (ctx.link_fd != -1) {
- eloop_event_delete(ctx.eloop, ctx.link_fd, 0);
+ eloop_event_delete(ctx.eloop, ctx.link_fd);
close(ctx.link_fd);
}
Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.20 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.21
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.20 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-.\" $NetBSD: dhcpcd.conf.5.in,v 1.20 2015/05/02 15:18:37 roy Exp $
+.\" $NetBSD: dhcpcd.conf.5.in,v 1.21 2015/05/16 23:31:32 roy Exp $
.\" Copyright (c) 2006-2015 Roy Marples
.\" All rights reserved
.\"
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 6, 2015
+.Dd May 15, 2015
.Dt DHCPCD.CONF 5
.Os
.Sh NAME
@@ -463,14 +463,39 @@ You can specify more
separated by commas, spaces or more
.Ic option
lines.
+.Ar option
Prepend dhcp6_ to
.Ar option
to request a DHCPv6 option.
DHCPv4 options are mapped to DHCPv6 where applicable.
+.Pp
+Prepend nd_ to
+.Ar option
+to handle ND options, but this only works for the
+.Ic nooption ,
+.Ic reject
+and
+.Ic require
+options.
.It Ic nooption Ar option
-Remove the option from the DHCP message.
-This should only be used when a DHCP server sends a non requested option
-that should not be processed.
+Remove the option from the message before it's processed.
+.It Ic require Ar option
+Requires the
+.Ar option
+to be present in all messages, otherwise the message is ignored.
+To enforce that
+.Nm dhcpcd
+only responds to DHCP servers and not BOOTP servers, you can
+.Ic require
+.Ar dhcp_message_type .
+This isn't an exact science though because a BOOTP server can send DHCP like
+options.
+.It Ic reject Ar option
+Reject a message that contains the
+.Ar option .
+This is useful when you cannot use
+.Ic require
+to select / de-select BOOTP messages.
.It Ic destination Ar option
If
.Nm
@@ -500,27 +525,6 @@ will timeout before moving back to the D
.It Ic release
.Nm dhcpcd
will release the lease prior to stopping the interface.
-.It Ic require Ar option
-Requires the
-.Ar option
-to be present in all DHCP messages, otherwise the message is ignored.
-It can be a variable to be used in
-.Xr dhcpcd-run-hooks 8
-or the numerical value.
-You can specify more options separated by commas, spaces or more require lines.
-To enforce that
-.Nm dhcpcd
-only responds to DHCP servers and not BOOTP servers, you can
-.Ic require
-.Ar dhcp_message_type .
-This isn't an exact science though because a BOOTP server can send DHCP like
-options.
-.It Ic reject Ar option
-Reject a DHCP message that contains the
-.Ar option .
-This is useful when you cannot use
-.Ic require
-to select / de-select BOOTP messages.
.It Ic script Ar script
Use
.Ar script
@@ -631,9 +635,10 @@ Use the last four bytes of the hardware
of a randomly generated number.
.El
.Ss Defining new options
-DHCP allows for the use of custom options.
+DHCP, ND and DHCPv6 allow for the use of custom options.
Each option needs to be started with the
-.Ic define
+.Ic define ,
+.If definend
or
.Ic define6
directive.
@@ -656,6 +661,17 @@ with a name of
.Ar variable
exported to
.Xr dhcpcd-run-hooks 8 .
+.It Ic definend Ar code Ar type Ar variable
+Defines the ND option
+.Ar code
+of
+.Ar type
+with a name of
+.Ar variable
+exported to
+.Xr dhcpcd-run-hooks 8 ,
+with a prefix of
+.Va _nd .
.It Ic define6 Ar code Ar type Ar variable
Defines the DHCPv6 option
.Ar code
@@ -688,6 +704,11 @@ is not the same as defined in the parent
it is prefixed with the parent
.Ar variable
first with an underscore.
+If the
+.Ar variable
+has the name of
+.Ar reserved
+then it is not processed.
.It Ic encap Ar code Ar type Ar variable
Defines an encapsulated variable within the defined option.
The length is determined by the
@@ -721,35 +742,42 @@ Lengths can be specified for string and
with other data embedded afterwards in the same option.
.Bl -tag -width indent
.It Ic ipaddress
-An IPv4 address, 4 bytes
+An IPv4 address, 4 bytes.
.It Ic ip6address
-An IPv6 address, 16 bytes
+An IPv6 address, 16 bytes.
.It Ic string Op : Ic length
A NVT ASCII string of printable characters.
.It Ic byte
-A byte
+A byte.
+.It Ic bitflags : Ic flags
+A byte represented as a string of flags, most significant bit first.
+For example, using ABCDEFGH then A would equal 10000000, B 01000000,
+C 00100000, etc.
+If the bit is not set, the flag is not printed.
+A flag of 0 is not printed even if the bit postition is set.
+This is to allow reservation of the first bits while assinging the last bits.
.It Ic int16
-A signed 16bit integer, 2 bytes
+A signed 16bit integer, 2 bytes.
.It Ic uint16
-An unsigned 16bit integer, 2 bytes
+An unsigned 16bit integer, 2 bytes.
.It Ic int32
-A signed 32bit integer, 4 bytes
+A signed 32bit integer, 4 bytes.
.It Ic uint32
-An unsigned 32bit integer, 4 bytes
-.It Ic flag
-A fixed value (1) to indicate that the option is present, 0 bytes
+An unsigned 32bit integer, 4 bytes.
+.It Ic flag
+A fixed value (1) to indicate that the option is present, 0 bytes.
.It Ic domain
-A RFC 3397 encoded string
+A RFC 3397 encoded string.
.It Ic dname
-A RFC 1035 validated string
+A RFC 1035 validated string.
.It Ic binhex Op : Ic length
-Binary data expressed as hexadecimal
+Binary data expressed as hexadecimal.
.It Ic embed
-Contains embedded options (implies encap as well)
+Contains embedded options (implies encap as well).
.It Ic encap
-Contains encapsulated options (implies embed as well)
+Contains encapsulated options (implies embed as well).
.It Ic option
-References an option from the global definition
+References an option from the global definition.
.El
.Ss Example definition
.D1 # DHCP option 81, Fully Qualified Domain Name, RFC4702
Index: src/external/bsd/dhcpcd/dist/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.20 src/external/bsd/dhcpcd/dist/if-bsd.c:1.21
--- src/external/bsd/dhcpcd/dist/if-bsd.c:1.20 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/if-bsd.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: if-bsd.c,v 1.20 2015/05/02 15:18:37 roy Exp $");
+ __RCSID("$NetBSD: if-bsd.c,v 1.21 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -1128,7 +1128,7 @@ if_getlifetime6(struct ipv6_addr *ia)
(uint32_t)(lifetime->ia6t_expire -
MIN(t, lifetime->ia6t_expire));
/* Calculate the created time */
- get_monotonic(&ia->created);
+ clock_gettime(CLOCK_MONOTONIC, &ia->created);
ia->created.tv_sec -=
lifetime->ia6t_vltime - ia->prefix_vltime;
} else
Index: src/external/bsd/dhcpcd/dist/dhcpcd.h
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.h:1.10 src/external/bsd/dhcpcd/dist/dhcpcd.h:1.11
--- src/external/bsd/dhcpcd/dist/dhcpcd.h:1.10 Thu Mar 26 10:26:37 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcpcd.h,v 1.10 2015/03/26 10:26:37 roy Exp $ */
+/* $NetBSD: dhcpcd.h,v 1.11 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -34,6 +34,10 @@
#include <net/if.h>
#include "config.h"
+#ifdef HAVE_SYS_QUEUE_H
+#include <sys/queue.h>
+#endif
+
#include "defs.h"
#include "control.h"
#include "if-options.h"
@@ -107,7 +111,7 @@ struct dhcpcd_ctx {
#ifdef USE_SIGNALS
sigset_t sigset;
#endif
- struct eloop_ctx *eloop;
+ struct eloop *eloop;
int control_fd;
int control_unpriv_fd;
@@ -137,6 +141,8 @@ struct dhcpcd_ctx {
unsigned char secret[SECRET_LEN];
size_t secret_len;
+ struct dhcp_opt *nd_opts;
+ size_t nd_opts_len;
struct dhcp_opt *dhcp6_opts;
size_t dhcp6_opts_len;
struct ipv6_ctx *ipv6;
@@ -154,16 +160,11 @@ struct dhcpcd_ctx {
};
#ifdef USE_SIGNALS
-struct dhcpcd_siginfo {
- int signo;
-};
-
-extern const int dhcpcd_handlesigs[];
-void dhcpcd_handle_signal(void *);
+extern const int dhcpcd_signals[];
+extern const size_t dhcpcd_signals_len;
#endif
int dhcpcd_oneup(struct dhcpcd_ctx *);
-int dhcpcd_ipwaited(struct dhcpcd_ctx *);
pid_t dhcpcd_daemonise(struct dhcpcd_ctx *);
int dhcpcd_handleargs(struct dhcpcd_ctx *, struct fd_list *, int, char **);
Index: src/external/bsd/dhcpcd/dist/eloop.c
diff -u src/external/bsd/dhcpcd/dist/eloop.c:1.10 src/external/bsd/dhcpcd/dist/eloop.c:1.11
--- src/external/bsd/dhcpcd/dist/eloop.c:1.10 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/eloop.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: eloop.c,v 1.10 2015/05/02 15:18:37 roy Exp $");
+ __RCSID("$NetBSD: eloop.c,v 1.11 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -30,6 +30,7 @@
#include <sys/time.h>
+#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
@@ -37,11 +38,26 @@
#include <string.h>
#include <unistd.h>
+/* config.h should define HAVE_KQUEUE, HAVE_EPOLL, etc */
#include "config.h"
-#include "common.h"
-#include "dhcpcd.h"
#include "eloop.h"
+#ifndef UNUSED
+#define UNUSED(a) (void)((a))
+#endif
+#ifndef __unused
+#ifdef __GNUC__
+#define __unused __attribute__((__unused__))
+#else
+#define __unused
+#endif
+#endif
+
+#ifndef MSEC_PER_SEC
+#define MSEC_PER_SEC 1000L
+#define NSEC_PER_MSEC 1000000L
+#endif
+
#if defined(HAVE_KQUEUE)
#include <sys/event.h>
#include <fcntl.h>
@@ -54,35 +70,67 @@
#define UPTR(x) (x)
#define LENC(x) ((int)(x))
#endif
-#define eloop_event_setup_fds(ctx)
+#define eloop_event_setup_fds(eloop)
#elif defined(HAVE_EPOLL)
#include <sys/epoll.h>
-#define eloop_event_setup_fds(ctx)
+#define eloop_event_setup_fds(eloop)
#else
#include <poll.h>
static void
-eloop_event_setup_fds(struct eloop_ctx *ctx)
+eloop_event_setup_fds(struct eloop *eloop)
{
struct eloop_event *e;
size_t i;
i = 0;
- TAILQ_FOREACH(e, &ctx->events, next) {
- ctx->fds[i].fd = e->fd;
- ctx->fds[i].events = 0;
+ TAILQ_FOREACH(e, &eloop->events, next) {
+ eloop->fds[i].fd = e->fd;
+ eloop->fds[i].events = 0;
if (e->read_cb)
- ctx->fds[i].events |= POLLIN;
+ eloop->fds[i].events |= POLLIN;
if (e->write_cb)
- ctx->fds[i].events |= POLLOUT;
- ctx->fds[i].revents = 0;
- e->pollfd = &ctx->fds[i];
+ eloop->fds[i].events |= POLLOUT;
+ eloop->fds[i].revents = 0;
+ e->pollfd = &eloop->fds[i];
i++;
}
}
+
+#ifndef pollts
+/* Wrapper around pselect, to imitate the NetBSD pollts call. */
+static int
+pollts(struct pollfd * fds, nfds_t nfds,
+ const struct timespec *ts, const sigset_t *sigmask)
+{
+ fd_set read_fds;
+ nfds_t n;
+ int maxfd, r;
+
+ FD_ZERO(&read_fds);
+ maxfd = 0;
+ for (n = 0; n < nfds; n++) {
+ if (fds[n].events & POLLIN) {
+ FD_SET(fds[n].fd, &read_fds);
+ if (fds[n].fd > maxfd)
+ maxfd = fds[n].fd;
+ }
+ }
+
+ r = pselect(maxfd + 1, &read_fds, NULL, NULL, ts, sigmask);
+ if (r > 0) {
+ for (n = 0; n < nfds; n++) {
+ fds[n].revents =
+ FD_ISSET(fds[n].fd, &read_fds) ? POLLIN : 0;
+ }
+ }
+
+ return r;
+}
+#endif
#endif
int
-eloop_event_add(struct eloop_ctx *ctx, int fd,
+eloop_event_add(struct eloop *eloop, int fd,
void (*read_cb)(void *), void *read_cb_arg,
void (*write_cb)(void *), void *write_cb_arg)
{
@@ -95,6 +143,13 @@ eloop_event_add(struct eloop_ctx *ctx, i
struct pollfd *nfds;
#endif
+ assert(eloop != NULL);
+ assert(read_cb != NULL || write_cb != NULL);
+ if (fd == -1) {
+ errno = EINVAL;
+ return -1;
+ }
+
#ifdef HAVE_EPOLL
memset(&epe, 0, sizeof(epe));
epe.data.fd = fd;
@@ -104,7 +159,7 @@ eloop_event_add(struct eloop_ctx *ctx, i
#endif
/* We should only have one callback monitoring the fd */
- TAILQ_FOREACH(e, &ctx->events, next) {
+ TAILQ_FOREACH(e, &eloop->events, next) {
if (e->fd == fd) {
int error;
@@ -117,11 +172,11 @@ eloop_event_add(struct eloop_ctx *ctx, i
else if (e->write_cb)
EV_SET(&ke[1], (uintptr_t)fd, EVFILT_WRITE,
EV_DELETE, 0, 0, UPTR(e));
- error = kevent(ctx->poll_fd, ke,
+ error = kevent(eloop->poll_fd, ke,
e->write_cb || write_cb ? 2 : 1, NULL, 0, NULL);
#elif defined(HAVE_EPOLL)
epe.data.ptr = e;
- error = epoll_ctl(ctx->poll_fd, EPOLL_CTL_MOD,
+ error = epoll_ctl(eloop->poll_fd, EPOLL_CTL_MOD,
fd, &epe);
#else
error = 0;
@@ -134,14 +189,14 @@ eloop_event_add(struct eloop_ctx *ctx, i
e->write_cb = write_cb;
e->write_cb_arg = write_cb_arg;
}
- eloop_event_setup_fds(ctx);
+ eloop_event_setup_fds(eloop);
return error;
}
}
/* Allocate a new event if no free ones already allocated */
- if ((e = TAILQ_FIRST(&ctx->free_events))) {
- TAILQ_REMOVE(&ctx->free_events, e, next);
+ if ((e = TAILQ_FIRST(&eloop->free_events))) {
+ TAILQ_REMOVE(&eloop->free_events, e, next);
} else {
e = malloc(sizeof(*e));
if (e == NULL)
@@ -149,14 +204,15 @@ eloop_event_add(struct eloop_ctx *ctx, i
}
/* Ensure we can actually listen to it */
- ctx->events_len++;
+ eloop->events_len++;
#if !defined(HAVE_KQUEUE) && !defined(HAVE_EPOLL)
- if (ctx->events_len > ctx->fds_len) {
- nfds = realloc(ctx->fds, sizeof(*ctx->fds) * (ctx->fds_len+5));
+ if (eloop->events_len > eloop->fds_len) {
+ nfds = realloc(eloop->fds,
+ sizeof(*eloop->fds) * (eloop->fds_len + 5));
if (nfds == NULL)
goto err;
- ctx->fds_len += 5;
- ctx->fds = nfds;
+ eloop->fds_len += 5;
+ eloop->fds = nfds;
}
#endif
@@ -168,15 +224,17 @@ eloop_event_add(struct eloop_ctx *ctx, i
e->write_cb_arg = write_cb_arg;
#if defined(HAVE_KQUEUE)
- EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ, EV_ADD, 0, 0, UPTR(e));
- if (write_cb)
+ if (read_cb != NULL)
+ EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ,
+ EV_ADD, 0, 0, UPTR(e));
+ if (write_cb != NULL)
EV_SET(&ke[1], (uintptr_t)fd, EVFILT_WRITE,
EV_ADD, 0, 0, UPTR(e));
- if (kevent(ctx->poll_fd, ke, write_cb ? 2 : 1, NULL, 0, NULL) == -1)
+ if (kevent(eloop->poll_fd, ke, write_cb ? 2 : 1, NULL, 0, NULL) == -1)
goto err;
#elif defined(HAVE_EPOLL)
epe.data.ptr = e;
- if (epoll_ctl(ctx->poll_fd, EPOLL_CTL_ADD, fd, &epe) == -1)
+ if (epoll_ctl(eloop->poll_fd, EPOLL_CTL_ADD, fd, &epe) == -1)
goto err;
#endif
@@ -186,21 +244,20 @@ eloop_event_add(struct eloop_ctx *ctx, i
* message (which is likely to be that the DHCP addresses are wrong)
* we insert new events at the queue head as the link fd will be
* the first event added. */
- TAILQ_INSERT_HEAD(&ctx->events, e, next);
- eloop_event_setup_fds(ctx);
+ TAILQ_INSERT_HEAD(&eloop->events, e, next);
+ eloop_event_setup_fds(eloop);
return 0;
err:
- logger(ctx->ctx, LOG_ERR, "%s: %m", __func__);
if (e) {
- ctx->events_len--;
- TAILQ_INSERT_TAIL(&ctx->free_events, e, next);
+ eloop->events_len--;
+ TAILQ_INSERT_TAIL(&eloop->free_events, e, next);
}
return -1;
}
void
-eloop_event_delete(struct eloop_ctx *ctx, int fd, int write_only)
+eloop_event_delete_write(struct eloop *eloop, int fd, int write_only)
{
struct eloop_event *e;
#if defined(HAVE_KQUEUE)
@@ -209,30 +266,31 @@ eloop_event_delete(struct eloop_ctx *ctx
struct epoll_event epe;
#endif
- TAILQ_FOREACH(e, &ctx->events, next) {
+ assert(eloop != NULL);
+
+ TAILQ_FOREACH(e, &eloop->events, next) {
if (e->fd == fd) {
- if (write_only) {
- if (e->write_cb) {
+ if (write_only && e->read_cb != NULL) {
+ if (e->write_cb != NULL) {
e->write_cb = NULL;
e->write_cb_arg = NULL;
#if defined(HAVE_KQUEUE)
EV_SET(&ke[0], (uintptr_t)fd,
EVFILT_WRITE, EV_DELETE,
0, 0, UPTR(NULL));
- kevent(ctx->poll_fd, ke, 1, NULL, 0,
+ kevent(eloop->poll_fd, ke, 1, NULL, 0,
NULL);
#elif defined(HAVE_EPOLL)
memset(&epe, 0, sizeof(epe));
epe.data.fd = e->fd;
epe.data.ptr = e;
epe.events = EPOLLIN;
- epoll_ctl(ctx->poll_fd, EPOLL_CTL_MOD,
- fd, &epe);
+ epoll_ctl(eloop->poll_fd,
+ EPOLL_CTL_MOD, fd, &epe);
#endif
}
-
} else {
- TAILQ_REMOVE(&ctx->events, e, next);
+ TAILQ_REMOVE(&eloop->events, e, next);
#if defined(HAVE_KQUEUE)
EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ,
EV_DELETE, 0, 0, UPTR(NULL));
@@ -240,32 +298,36 @@ eloop_event_delete(struct eloop_ctx *ctx
EV_SET(&ke[1], (uintptr_t)fd,
EVFILT_WRITE, EV_DELETE,
0, 0, UPTR(NULL));
- kevent(ctx->poll_fd, ke, e->write_cb ? 2 : 1,
+ kevent(eloop->poll_fd, ke, e->write_cb ? 2 : 1,
NULL, 0, NULL);
#elif defined(HAVE_EPOLL)
/* NULL event is safe because we
* rely on epoll_pwait which as added
* after the delete without event was fixed. */
- epoll_ctl(ctx->poll_fd, EPOLL_CTL_DEL,
+ epoll_ctl(eloop->poll_fd, EPOLL_CTL_DEL,
fd, NULL);
#endif
- TAILQ_INSERT_TAIL(&ctx->free_events, e, next);
- ctx->events_len--;
+ TAILQ_INSERT_TAIL(&eloop->free_events, e, next);
+ eloop->events_len--;
}
- eloop_event_setup_fds(ctx);
+ eloop_event_setup_fds(eloop);
break;
}
}
}
int
-eloop_q_timeout_add_tv(struct eloop_ctx *ctx, int queue,
+eloop_q_timeout_add_tv(struct eloop *eloop, int queue,
const struct timespec *when, void (*callback)(void *), void *arg)
{
struct timespec now, w;
struct eloop_timeout *t, *tt = NULL;
- get_monotonic(&now);
+ assert(eloop != NULL);
+ assert(when != NULL);
+ assert(callback != NULL);
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
timespecadd(&now, when, &w);
/* Check for time_t overflow. */
if (timespeccmp(&w, &now, <)) {
@@ -274,23 +336,20 @@ eloop_q_timeout_add_tv(struct eloop_ctx
}
/* Remove existing timeout if present */
- TAILQ_FOREACH(t, &ctx->timeouts, next) {
+ TAILQ_FOREACH(t, &eloop->timeouts, next) {
if (t->callback == callback && t->arg == arg) {
- TAILQ_REMOVE(&ctx->timeouts, t, next);
+ TAILQ_REMOVE(&eloop->timeouts, t, next);
break;
}
}
if (t == NULL) {
/* No existing, so allocate or grab one from the free pool */
- if ((t = TAILQ_FIRST(&ctx->free_timeouts))) {
- TAILQ_REMOVE(&ctx->free_timeouts, t, next);
+ if ((t = TAILQ_FIRST(&eloop->free_timeouts))) {
+ TAILQ_REMOVE(&eloop->free_timeouts, t, next);
} else {
- t = malloc(sizeof(*t));
- if (t == NULL) {
- logger(ctx->ctx, LOG_ERR, "%s: %m", __func__);
+ if ((t = malloc(sizeof(*t))) == NULL)
return -1;
- }
}
}
@@ -301,97 +360,108 @@ eloop_q_timeout_add_tv(struct eloop_ctx
/* The timeout list should be in chronological order,
* soonest first. */
- TAILQ_FOREACH(tt, &ctx->timeouts, next) {
+ TAILQ_FOREACH(tt, &eloop->timeouts, next) {
if (timespeccmp(&t->when, &tt->when, <)) {
TAILQ_INSERT_BEFORE(tt, t, next);
return 0;
}
}
- TAILQ_INSERT_TAIL(&ctx->timeouts, t, next);
+ TAILQ_INSERT_TAIL(&eloop->timeouts, t, next);
return 0;
}
int
-eloop_q_timeout_add_sec(struct eloop_ctx *ctx, int queue, time_t when,
+eloop_q_timeout_add_sec(struct eloop *eloop, int queue, time_t when,
void (*callback)(void *), void *arg)
{
struct timespec tv;
tv.tv_sec = when;
tv.tv_nsec = 0;
- return eloop_q_timeout_add_tv(ctx, queue, &tv, callback, arg);
+ return eloop_q_timeout_add_tv(eloop, queue, &tv, callback, arg);
}
-#if !defined(HAVE_KQUEUE)
int
-eloop_timeout_add_now(struct eloop_ctx *ctx,
+eloop_q_timeout_add_msec(struct eloop *eloop, int queue, long when,
void (*callback)(void *), void *arg)
{
+ struct timespec tv;
- if (ctx->timeout0 != NULL) {
- logger(ctx->ctx, LOG_WARNING,
- "%s: timeout0 already set", __func__);
- return eloop_q_timeout_add_sec(ctx, 0, 0, callback, arg);
- }
+ tv.tv_sec = when / MSEC_PER_SEC;
+ tv.tv_nsec = (when % MSEC_PER_SEC) * NSEC_PER_MSEC;
+ return eloop_q_timeout_add_tv(eloop, queue, &tv, callback, arg);
+}
- ctx->timeout0 = callback;
- ctx->timeout0_arg = arg;
+#if !defined(HAVE_KQUEUE)
+static int
+eloop_timeout_add_now(struct eloop *eloop,
+ void (*callback)(void *), void *arg)
+{
+
+ assert(eloop->timeout0 == NULL);
+ eloop->timeout0 = callback;
+ eloop->timeout0_arg = arg;
return 0;
}
#endif
void
-eloop_q_timeout_delete(struct eloop_ctx *ctx, int queue,
+eloop_q_timeout_delete(struct eloop *eloop, int queue,
void (*callback)(void *), void *arg)
{
struct eloop_timeout *t, *tt;
- TAILQ_FOREACH_SAFE(t, &ctx->timeouts, next, tt) {
+ assert(eloop != NULL);
+
+ TAILQ_FOREACH_SAFE(t, &eloop->timeouts, next, tt) {
if ((queue == 0 || t->queue == queue) &&
t->arg == arg &&
(!callback || t->callback == callback))
{
- TAILQ_REMOVE(&ctx->timeouts, t, next);
- TAILQ_INSERT_TAIL(&ctx->free_timeouts, t, next);
+ TAILQ_REMOVE(&eloop->timeouts, t, next);
+ TAILQ_INSERT_TAIL(&eloop->free_timeouts, t, next);
}
}
}
void
-eloop_exit(struct eloop_ctx *ctx, int code)
+eloop_exit(struct eloop *eloop, int code)
{
- ctx->exitcode = code;
- ctx->exitnow = 1;
+ assert(eloop != NULL);
+
+ eloop->exitcode = code;
+ eloop->exitnow = 1;
}
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
static int
-eloop_open(struct eloop_ctx *ctx)
+eloop_open(struct eloop *eloop)
{
+
#if defined(HAVE_KQUEUE1)
- return (ctx->poll_fd = kqueue1(O_CLOEXEC));
+ return (eloop->poll_fd = kqueue1(O_CLOEXEC));
#elif defined(HAVE_KQUEUE)
int i;
- if ((ctx->poll_fd = kqueue()) == -1)
+ if ((eloop->poll_fd = kqueue()) == -1)
return -1;
- if ((i = fcntl(ctx->poll_fd, F_GETFD, 0)) == -1 ||
- fcntl(ctx->poll_fd, F_SETFD, i | FD_CLOEXEC) == -1)
+ if ((i = fcntl(eloop->poll_fd, F_GETFD, 0)) == -1 ||
+ fcntl(eloop->poll_fd, F_SETFD, i | FD_CLOEXEC) == -1)
{
- close(ctx->poll_fd);
- ctx->poll_fd = -1;
+ close(eloop->poll_fd);
+ eloop->poll_fd = -1;
return -1;
}
- return ctx->poll_fd;
+ return eloop->poll_fd;
#elif defined (HAVE_EPOLL)
- return (ctx->poll_fd = epoll_create1(EPOLL_CLOEXEC));
+ return (eloop->poll_fd = epoll_create1(EPOLL_CLOEXEC));
#endif
}
int
-eloop_requeue(struct eloop_ctx *ctx)
+eloop_requeue(struct eloop *eloop)
{
struct eloop_event *e;
int error;
@@ -402,15 +472,15 @@ eloop_requeue(struct eloop_ctx *ctx)
struct epoll_event epe;
#endif
- if (ctx->poll_fd != -1)
- close(ctx->poll_fd);
- if (eloop_open(ctx) == -1)
+ assert(eloop != NULL);
+
+ if (eloop->poll_fd != -1)
+ close(eloop->poll_fd);
+ if (eloop_open(eloop) == -1)
return -1;
#if defined (HAVE_KQUEUE)
- i = 0;
- while (dhcpcd_handlesigs[i])
- i++;
- TAILQ_FOREACH(e, &ctx->events, next) {
+ i = eloop->signals_len;
+ TAILQ_FOREACH(e, &eloop->events, next) {
i++;
if (e->write_cb)
i++;
@@ -419,11 +489,11 @@ eloop_requeue(struct eloop_ctx *ctx)
if ((ke = malloc(sizeof(*ke) * i)) == NULL)
return -1;
- for (i = 0; dhcpcd_handlesigs[i]; i++)
- EV_SET(&ke[i], (uintptr_t)dhcpcd_handlesigs[i],
+ for (i = 0; i < eloop->signals_len; i++)
+ EV_SET(&ke[i], (uintptr_t)eloop->signals[i],
EVFILT_SIGNAL, EV_ADD, 0, 0, UPTR(NULL));
- TAILQ_FOREACH(e, &ctx->events, next) {
+ TAILQ_FOREACH(e, &eloop->events, next) {
EV_SET(&ke[i], (uintptr_t)e->fd, EVFILT_READ,
EV_ADD, 0, 0, UPTR(e));
i++;
@@ -434,20 +504,20 @@ eloop_requeue(struct eloop_ctx *ctx)
}
}
- error = kevent(ctx->poll_fd, ke, LENC(i), NULL, 0, NULL);
+ error = kevent(eloop->poll_fd, ke, LENC(i), NULL, 0, NULL);
free(ke);
#elif defined(HAVE_EPOLL)
error = 0;
- TAILQ_FOREACH(e, &ctx->events, next) {
+ TAILQ_FOREACH(e, &eloop->events, next) {
memset(&epe, 0, sizeof(epe));
epe.data.fd = e->fd;
epe.events = EPOLLIN;
if (e->write_cb)
epe.events |= EPOLLOUT;
epe.data.ptr = e;
- if (epoll_ctl(ctx->poll_fd, EPOLL_CTL_ADD, e->fd, &epe) == -1)
+ if (epoll_ctl(eloop->poll_fd, EPOLL_CTL_ADD, e->fd, &epe) == -1)
error = -1;
}
#endif
@@ -456,102 +526,179 @@ eloop_requeue(struct eloop_ctx *ctx)
}
#endif
-struct eloop_ctx *
-eloop_init(struct dhcpcd_ctx *dctx)
+int
+eloop_signal_set_cb(struct eloop *eloop,
+ const int *signals, size_t signals_len,
+ void (*signal_cb)(int, void *), void *signal_cb_ctx)
+{
+
+ assert(eloop != NULL);
+
+ eloop->signals = signals;
+ eloop->signals_len = signals_len;
+ eloop->signal_cb = signal_cb;
+ eloop->signal_cb_ctx = signal_cb_ctx;
+ return eloop_requeue(eloop);
+}
+
+#ifndef HAVE_KQUEUE
+struct eloop_siginfo {
+ int sig;
+ struct eloop *eloop;
+};
+static struct eloop_siginfo _eloop_siginfo;
+static struct eloop *_eloop;
+
+static void
+eloop_signal1(void *arg)
+{
+ struct eloop_siginfo *si = arg;
+
+ si->eloop->signal_cb(si->sig, si->eloop->signal_cb_ctx);
+}
+
+static void
+eloop_signal3(int sig, __unused siginfo_t *siginfo, __unused void *arg)
+{
+
+ /* So that we can operate safely under a signal we instruct
+ * eloop to pass a copy of the siginfo structure to handle_signal1
+ * as the very first thing to do. */
+ _eloop_siginfo.eloop = _eloop;
+ _eloop_siginfo.sig = sig;
+ eloop_timeout_add_now(_eloop_siginfo.eloop,
+ eloop_signal1, &_eloop_siginfo);
+}
+#endif
+
+int
+eloop_signal_mask(struct eloop *eloop, sigset_t *oldset)
{
- struct eloop_ctx *ctx;
+ sigset_t newset;
+#ifndef HAVE_KQUEUE
+ size_t i;
+ struct sigaction sa;
+#endif
+
+ assert(eloop != NULL);
+
+ sigfillset(&newset);
+ if (sigprocmask(SIG_SETMASK, &newset, oldset) == -1)
+ return -1;
+
+#ifdef HAVE_KQUEUE
+ UNUSED(eloop);
+#else
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = eloop_signal3;
+ sa.sa_flags = SA_SIGINFO;
+ sigemptyset(&sa.sa_mask);
+
+ for (i = 0; i < eloop->signals_len; i++) {
+ if (sigaction(eloop->signals[i], &sa, NULL) == -1)
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+struct eloop *
+eloop_new(void)
+{
+ struct eloop *eloop;
struct timespec now;
/* Check we have a working monotonic clock. */
- if (get_monotonic(&now) == -1)
+ if (clock_gettime(CLOCK_MONOTONIC, &now) == -1)
return NULL;
- ctx = calloc(1, sizeof(*ctx));
- if (ctx) {
- ctx->ctx = dctx;
- TAILQ_INIT(&ctx->events);
- TAILQ_INIT(&ctx->free_events);
- TAILQ_INIT(&ctx->timeouts);
- TAILQ_INIT(&ctx->free_timeouts);
- ctx->exitcode = EXIT_FAILURE;
+ eloop = calloc(1, sizeof(*eloop));
+ if (eloop) {
+ TAILQ_INIT(&eloop->events);
+ TAILQ_INIT(&eloop->free_events);
+ TAILQ_INIT(&eloop->timeouts);
+ TAILQ_INIT(&eloop->free_timeouts);
+ eloop->exitcode = EXIT_FAILURE;
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
- ctx->poll_fd = -1;
+ eloop->poll_fd = -1;
+ eloop_open(eloop);
#endif
- if (eloop_requeue(ctx) == -1) {
- free(ctx);
- return NULL;
- }
}
- return ctx;
+ return eloop;
}
-void eloop_free(struct eloop_ctx *ctx)
+void eloop_free(struct eloop *eloop)
{
struct eloop_event *e;
struct eloop_timeout *t;
- if (ctx == NULL)
+ if (eloop == NULL)
return;
- while ((e = TAILQ_FIRST(&ctx->events))) {
- TAILQ_REMOVE(&ctx->events, e, next);
+ while ((e = TAILQ_FIRST(&eloop->events))) {
+ TAILQ_REMOVE(&eloop->events, e, next);
free(e);
}
- while ((e = TAILQ_FIRST(&ctx->free_events))) {
- TAILQ_REMOVE(&ctx->free_events, e, next);
+ while ((e = TAILQ_FIRST(&eloop->free_events))) {
+ TAILQ_REMOVE(&eloop->free_events, e, next);
free(e);
}
- while ((t = TAILQ_FIRST(&ctx->timeouts))) {
- TAILQ_REMOVE(&ctx->timeouts, t, next);
+ while ((t = TAILQ_FIRST(&eloop->timeouts))) {
+ TAILQ_REMOVE(&eloop->timeouts, t, next);
free(t);
}
- while ((t = TAILQ_FIRST(&ctx->free_timeouts))) {
- TAILQ_REMOVE(&ctx->free_timeouts, t, next);
+ while ((t = TAILQ_FIRST(&eloop->free_timeouts))) {
+ TAILQ_REMOVE(&eloop->free_timeouts, t, next);
free(t);
}
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
- close(ctx->poll_fd);
+ close(eloop->poll_fd);
#else
- free(ctx->fds);
+ free(eloop->fds);
#endif
- free(ctx);
+ free(eloop);
}
int
-eloop_start(struct eloop_ctx *ctx)
+eloop_start(struct eloop *eloop, sigset_t *signals)
{
int n;
struct eloop_event *e;
struct eloop_timeout *t;
struct timespec now, ts, *tsp;
void (*t0)(void *);
-#if defined(HAVE_EPOLL) || !defined(USE_SIGNALS)
- int timeout;
-#endif
#if defined(HAVE_KQUEUE)
struct kevent ke;
+ UNUSED(signals);
#elif defined(HAVE_EPOLL)
struct epoll_event epe;
#endif
+#ifndef HAVE_KQUEUE
+ int timeout;
+
+ _eloop = eloop;
+#endif
+
+ assert(eloop != NULL);
for (;;) {
- if (ctx->exitnow)
+ if (eloop->exitnow)
break;
/* Run all timeouts first */
- if (ctx->timeout0) {
- t0 = ctx->timeout0;
- ctx->timeout0 = NULL;
- t0(ctx->timeout0_arg);
+ if (eloop->timeout0) {
+ t0 = eloop->timeout0;
+ eloop->timeout0 = NULL;
+ t0(eloop->timeout0_arg);
continue;
}
- if ((t = TAILQ_FIRST(&ctx->timeouts))) {
- get_monotonic(&now);
+ if ((t = TAILQ_FIRST(&eloop->timeouts))) {
+ clock_gettime(CLOCK_MONOTONIC, &now);
if (timespeccmp(&now, &t->when, >)) {
- TAILQ_REMOVE(&ctx->timeouts, t, next);
+ TAILQ_REMOVE(&eloop->timeouts, t, next);
t->callback(t->arg);
- TAILQ_INSERT_TAIL(&ctx->free_timeouts, t, next);
+ TAILQ_INSERT_TAIL(&eloop->free_timeouts, t, next);
continue;
}
timespecsub(&t->when, &now, &ts);
@@ -560,12 +707,10 @@ eloop_start(struct eloop_ctx *ctx)
/* No timeouts, so wait forever */
tsp = NULL;
- if (tsp == NULL && ctx->events_len == 0) {
- logger(ctx->ctx, LOG_ERR, "nothing to do");
+ if (tsp == NULL && eloop->events_len == 0)
break;
- }
-#if defined(HAVE_EPOLL) || !defined(USE_SIGNALS)
+#ifndef HAVE_KQUEUE
if (tsp == NULL)
timeout = -1;
else if (tsp->tv_sec > INT_MAX / 1000 ||
@@ -578,27 +723,25 @@ eloop_start(struct eloop_ctx *ctx)
#endif
#if defined(HAVE_KQUEUE)
- n = kevent(ctx->poll_fd, NULL, 0, &ke, 1, tsp);
+ n = kevent(eloop->poll_fd, NULL, 0, &ke, 1, tsp);
#elif defined(HAVE_EPOLL)
-#ifdef USE_SIGNALS
- n = epoll_pwait(ctx->poll_fd, &epe, 1, timeout,
- &ctx->ctx->sigset);
-#else
- n = epoll_wait(ctx->poll_fd, &epe, 1, timeout);
-#endif
-#else
-#ifdef USE_SIGNALS
- n = pollts(ctx->fds, (nfds_t)ctx->events_len, tsp,
- &ctx->ctx->sigset);
+ if (signals)
+ n = epoll_pwait(eloop->poll_fd, &epe, 1,
+ timeout, signals);
+ else
+ n = epoll_wait(eloop->poll_fd, &epe, 1, timeout);
#else
- n = poll(ctx->fds, (nfds_t)ctx->events_len, timeout);
-#endif
+ if (signals)
+ n = pollts(eloop->fds, (nfds_t)eloop->events_len,
+ tsp, signals);
+ else
+ n = poll(eloop->fds, (nfds_t)eloop->events_len,
+ timeout);
#endif
if (n == -1) {
if (errno == EINTR)
continue;
- logger(ctx->ctx, LOG_ERR, "poll: %m");
- break;
+ return -errno;
}
/* Process any triggered events.
@@ -607,10 +750,8 @@ eloop_start(struct eloop_ctx *ctx)
#if defined(HAVE_KQUEUE)
if (n) {
if (ke.filter == EVFILT_SIGNAL) {
- struct dhcpcd_siginfo si;
-
- si.signo = (int)ke.ident;
- dhcpcd_handle_signal(&si);
+ eloop->signal_cb((int)ke.ident,
+ eloop->signal_cb_ctx);
continue;
}
e = (struct eloop_event *)ke.udata;
@@ -625,12 +766,13 @@ eloop_start(struct eloop_ctx *ctx)
#elif defined(HAVE_EPOLL)
if (n) {
e = (struct eloop_event *)epe.data.ptr;
- if (epe.events & EPOLLOUT && e->write_cb) {
+ if (epe.events & EPOLLOUT && e->write_cb != NULL) {
e->write_cb(e->write_cb_arg);
continue;
}
if (epe.events &
- (EPOLLIN | EPOLLERR | EPOLLHUP))
+ (EPOLLIN | EPOLLERR | EPOLLHUP) &&
+ e->read_cb != NULL)
{
e->read_cb(e->read_cb_arg);
continue;
@@ -638,14 +780,14 @@ eloop_start(struct eloop_ctx *ctx)
}
#else
if (n > 0) {
- TAILQ_FOREACH(e, &ctx->events, next) {
+ TAILQ_FOREACH(e, &eloop->events, next) {
if (e->pollfd->revents & POLLOUT &&
- e->write_cb)
+ e->write_cb != NULL)
{
e->write_cb(e->write_cb_arg);
break;
}
- if (e->pollfd->revents) {
+ if (e->pollfd->revents && e->read_cb != NULL) {
e->read_cb(e->read_cb_arg);
break;
}
@@ -654,5 +796,5 @@ eloop_start(struct eloop_ctx *ctx)
#endif
}
- return ctx->exitcode;
+ return eloop->exitcode;
}
Index: src/external/bsd/dhcpcd/dist/if-options.h
diff -u src/external/bsd/dhcpcd/dist/if-options.h:1.10 src/external/bsd/dhcpcd/dist/if-options.h:1.11
--- src/external/bsd/dhcpcd/dist/if-options.h:1.10 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/if-options.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if-options.h,v 1.10 2015/05/02 15:18:37 roy Exp $ */
+/* $NetBSD: if-options.h,v 1.11 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -114,6 +114,8 @@
#define DHCPCD_IPV6RA_ACCEPT_NOPUBLIC (1ULL << 56)
#define DHCPCD_BOOTP (1ULL << 57)
+#define DHCPCD_WAITOPTS (DHCPCD_WAITIP | DHCPCD_WAITIP4 | DHCPCD_WAITIP6)
+
#define DHCPCD_WARNINGS (DHCPCD_CSR_WARNED | \
DHCPCD_ROUTER_HOST_ROUTE_WARNED)
#define DHCPCD_CONF (DHCPCD_NOPFXDLG | DHCPCD_PFXDLGONLY)
@@ -153,11 +155,15 @@ struct if_options {
uint8_t requiremask[256 / NBBY];
uint8_t nomask[256 / NBBY];
uint8_t rejectmask[256 / NBBY];
+ uint8_t dstmask[256 / NBBY];
+ uint8_t requestmasknd[(UINT16_MAX + 1) / NBBY];
+ uint8_t requiremasknd[(UINT16_MAX + 1) / NBBY];
+ uint8_t nomasknd[(UINT16_MAX + 1) / NBBY];
+ uint8_t rejectmasknd[(UINT16_MAX + 1) / NBBY];
uint8_t requestmask6[(UINT16_MAX + 1) / NBBY];
uint8_t requiremask6[(UINT16_MAX + 1) / NBBY];
uint8_t nomask6[(UINT16_MAX + 1) / NBBY];
uint8_t rejectmask6[(UINT16_MAX + 1) / NBBY];
- uint8_t dstmask[256 / NBBY];
uint32_t leasetime;
time_t timeout;
time_t reboot;
@@ -191,6 +197,8 @@ struct if_options {
struct dhcp_opt *dhcp_override;
size_t dhcp_override_len;
+ struct dhcp_opt *nd_override;
+ size_t nd_override_len;
struct dhcp_opt *dhcp6_override;
size_t dhcp6_override_len;
uint32_t vivco_en;
Index: src/external/bsd/dhcpcd/dist/ipv4.h
diff -u src/external/bsd/dhcpcd/dist/ipv4.h:1.10 src/external/bsd/dhcpcd/dist/ipv4.h:1.11
--- src/external/bsd/dhcpcd/dist/ipv4.h:1.10 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/ipv4.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv4.h,v 1.10 2015/05/02 15:18:37 roy Exp $ */
+/* $NetBSD: ipv4.h,v 1.11 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -77,15 +77,18 @@ int ipv4_ifcmp(const struct interface *,
uint8_t inet_ntocidr(struct in_addr);
int inet_cidrtoaddr(int, struct in_addr *);
uint32_t ipv4_getnetmask(uint32_t);
+int ipv4_ifaddrexists(const struct interface *);
int ipv4_addrexists(struct dhcpcd_ctx *, const struct in_addr *);
#define STATE_ADDED 0x01
#define STATE_FAKE 0x02
+#define STATE_TENTATIVE 0x04
void ipv4_buildroutes(struct dhcpcd_ctx *);
void ipv4_finaliseaddr(struct interface *);
int ipv4_deladdr(struct interface *ifp, const struct in_addr *,
const struct in_addr *);
+int ipv4_preferanother(struct interface *ifp);
void ipv4_applyaddr(void *);
int ipv4_handlert(struct dhcpcd_ctx *, int, struct rt *);
void ipv4_freerts(struct rt_head *);
@@ -109,7 +112,7 @@ void ipv4_ctxfree(struct dhcpcd_ctx *);
#define ipv4_freeroutes(a) {}
#define ipv4_free(a) {}
#define ipv4_ctxfree(a) {}
-#define ipv4_addrexists(a, b) (0)
+#define ipv4_ifaddrexists(a) (0)
#endif
#endif
Index: src/external/bsd/dhcpcd/dist/if-options.c
diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.23 src/external/bsd/dhcpcd/dist/if-options.c:1.24
--- src/external/bsd/dhcpcd/dist/if-options.c:1.23 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/if-options.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: if-options.c,v 1.23 2015/05/02 15:18:37 roy Exp $");
+ __RCSID("$NetBSD: if-options.c,v 1.24 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -103,6 +103,7 @@
#define O_REJECT O_BASE + 40
#define O_IPV6RA_ACCEPT_NOPUBLIC O_BASE + 41
#define O_BOOTP O_BASE + 42
+#define O_DEFINEND O_BASE + 43
const struct option cf_options[] = {
{"background", no_argument, NULL, 'b'},
@@ -178,6 +179,7 @@ const struct option cf_options[] = {
{"dev", required_argument, NULL, O_DEV},
{"nodev", no_argument, NULL, O_NODEV},
{"define", required_argument, NULL, O_DEFINE},
+ {"definend", required_argument, NULL, O_DEFINEND},
{"define6", required_argument, NULL, O_DEFINE6},
{"embed", required_argument, NULL, O_EMBED},
{"encap", required_argument, NULL, O_ENCAP},
@@ -522,11 +524,22 @@ set_option_space(struct dhcpcd_ctx *ctx,
{
#if !defined(INET) && !defined(INET6)
- /* Satisfy use */
- ctx = NULL;
+ UNUSED(ctx);
#endif
#ifdef INET6
+ if (strncmp(arg, "nd_", strlen("nd_")) == 0) {
+ *d = ctx->nd_opts;
+ *dl = ctx->nd_opts_len;
+ *od = ifo->nd_override;
+ *odl = ifo->nd_override_len;
+ *request = ifo->requestmasknd;
+ *require = ifo->requiremasknd;
+ *no = ifo->nomasknd;
+ *reject = ifo->rejectmasknd;
+ return arg + strlen("nd_");
+ }
+
if (strncmp(arg, "dhcp6_", strlen("dhcp6_")) == 0) {
*d = ctx->dhcp6_opts;
*dl = ctx->dhcp6_opts_len;
@@ -636,7 +649,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
int e, i, t;
long l;
unsigned long u;
- char *p = NULL, *fp, *np, **nconf;
+ char *p = NULL, *bp, *fp, *np, **nconf;
ssize_t s;
struct in_addr addr, addr2;
in_addr_t *naddr;
@@ -1469,6 +1482,12 @@ err_sla:
dop = &ifo->dhcp_override;
dop_len = &ifo->dhcp_override_len;
/* FALLTHROUGH */
+ case O_DEFINEND:
+ if (dop == NULL) {
+ dop = &ifo->nd_override;
+ dop_len = &ifo->nd_override_len;
+ }
+ /* FALLTHROUGH */
case O_DEFINE6:
if (dop == NULL) {
dop = &ifo->dhcp6_override;
@@ -1538,13 +1557,18 @@ err_sla:
/* length */
if (np) {
*np++ = '\0';
+ bp = NULL; /* No bitflag */
l = (long)strtou(np, NULL, 0, 0, LONG_MAX, &e);
if (e) {
- logger(ctx, LOG_ERR, "failed to convert length");
+ logger(ctx,LOG_ERR, "failed to convert length");
return -1;
}
- } else
+ } else {
l = 0;
+ bp = strchr(arg, '='); /* bitflag assignment */
+ if (bp)
+ *bp++ = '\0';
+ }
t = 0;
if (strcasecmp(arg, "request") == 0) {
t |= REQUEST;
@@ -1593,6 +1617,8 @@ err_sla:
t |= STRING;
else if (strcasecmp(arg, "byte") == 0)
t |= UINT8;
+ else if (strcasecmp(arg, "bitflags") == 0)
+ t |= BITFLAG;
else if (strcasecmp(arg, "uint16") == 0)
t |= UINT16;
else if (strcasecmp(arg, "int16") == 0)
@@ -1640,6 +1666,11 @@ err_sla:
logger(ctx, LOG_WARNING, "ignoring array for strings");
t &= ~ARRAY;
}
+ if (t & BITFLAG) {
+ if (bp == NULL)
+ logger(ctx, LOG_WARNING,
+ "missing bitflag assignment");
+ }
/* variable */
if (!fp) {
if (!(t & OPTION)) {
@@ -1653,10 +1684,16 @@ err_sla:
fp = strwhite(arg);
if (fp)
*fp++ = '\0';
- np = strdup(arg);
- if (np == NULL) {
- logger(ctx, LOG_ERR, "%s: %m", __func__);
- return -1;
+ if (strcasecmp(arg, "reserved")) {
+ np = strdup(arg);
+ if (np == NULL) {
+ logger(ctx, LOG_ERR,
+ "%s: %m", __func__);
+ return -1;
+ }
+ } else {
+ np = NULL;
+ t |= RESERVED;
}
}
if (opt != O_EMBED) {
@@ -1691,11 +1728,25 @@ err_sla:
ndop->type = t;
ndop->len = (size_t)l;
ndop->var = np;
+ if (bp) {
+ dl = strlen(bp);
+ memcpy(ndop->bitflags, bp, dl);
+ memset(ndop->bitflags + dl, 0,
+ sizeof(ndop->bitflags) - dl);
+ } else
+ memset(ndop->bitflags, 0, sizeof(ndop->bitflags));
/* Save the define for embed and encap options */
- if (opt == O_DEFINE || opt == O_DEFINE6 || opt == O_VENDOPT)
+ switch (opt) {
+ case O_DEFINE:
+ case O_DEFINEND:
+ case O_DEFINE6:
+ case O_VENDOPT:
*ldop = ndop;
- else if (opt == O_ENCAP)
+ break;
+ case O_ENCAP:
*edop = ndop;
+ break;
+ }
break;
case O_VENDCLASS:
fp = strwhite(arg);
@@ -2103,6 +2154,14 @@ read_config(struct dhcpcd_ctx *ctx,
ifo->dhcp_override_len = INITDEFINES;
#endif
+#if defined(INET6) && defined(INITDEFINENDS)
+ ifo->nd_override =
+ calloc(INITDEFINENDS, sizeof(*ifo->nd_override));
+ if (ifo->nd_override == NULL)
+ logger(ctx, LOG_ERR, "%s: %m", __func__);
+ else
+ ifo->nd_override_len = INITDEFINENDS;
+#endif
#if defined(INET6) && defined(INITDEFINE6S)
ifo->dhcp6_override =
calloc(INITDEFINE6S, sizeof(*ifo->dhcp6_override));
@@ -2175,15 +2234,24 @@ read_config(struct dhcpcd_ctx *ctx,
ifo->dhcp_override_len = 0;
#ifdef INET6
+ ctx->nd_opts = ifo->nd_override;
+ ctx->nd_opts_len = ifo->nd_override_len;
ctx->dhcp6_opts = ifo->dhcp6_override;
ctx->dhcp6_opts_len = ifo->dhcp6_override_len;
#else
+ for (i = 0, opt = ifo->nd_override;
+ i < ifo->nd_override_len;
+ i++, opt++)
+ free_dhcp_opt_embenc(opt);
+ free(ifo->nd_override);
for (i = 0, opt = ifo->dhcp6_override;
i < ifo->dhcp6_override_len;
i++, opt++)
free_dhcp_opt_embenc(opt);
free(ifo->dhcp6_override);
#endif
+ ifo->nd_override = NULL;
+ ifo->nd_override_len = 0;
ifo->dhcp6_override = NULL;
ifo->dhcp6_override_len = 0;
@@ -2337,6 +2405,11 @@ free_options(struct if_options *ifo)
opt++, ifo->dhcp_override_len--)
free_dhcp_opt_embenc(opt);
free(ifo->dhcp_override);
+ for (opt = ifo->nd_override;
+ ifo->nd_override_len > 0;
+ opt++, ifo->nd_override_len--)
+ free_dhcp_opt_embenc(opt);
+ free(ifo->nd_override);
for (opt = ifo->dhcp6_override;
ifo->dhcp6_override_len > 0;
opt++, ifo->dhcp6_override_len--)
Index: src/external/bsd/dhcpcd/dist/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.23 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.24
--- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.23 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/ipv6nd.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6nd.c,v 1.23 2015/05/02 15:18:37 roy Exp $");
+ __RCSID("$NetBSD: ipv6nd.c,v 1.24 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -157,6 +157,31 @@ static void ipv6nd_handledata(void *);
#define IPV6_RECVPKTINFO IPV6_PKTINFO
#endif
+void
+ipv6nd_printoptions(const struct dhcpcd_ctx *ctx,
+ const struct dhcp_opt *opts, size_t opts_len)
+{
+ size_t i, j;
+ const struct dhcp_opt *opt, *opt2;
+ int cols;
+
+ for (i = 0, opt = ctx->nd_opts;
+ i < ctx->nd_opts_len; i++, opt++)
+ {
+ for (j = 0, opt2 = opts; j < opts_len; j++, opt2++)
+ if (opt2->option == opt->option)
+ break;
+ if (j == opts_len) {
+ cols = printf("%03d %s", opt->option, opt->var);
+ dhcp_print_option_encoding(opt, cols);
+ }
+ }
+ for (i = 0, opt = opts; i < opts_len; i++, opt++) {
+ cols = printf("%03d %s", opt->option, opt->var);
+ dhcp_print_option_encoding(opt, cols);
+ }
+}
+
static int
ipv6nd_open(struct dhcpcd_ctx *dctx)
{
@@ -220,7 +245,7 @@ ipv6nd_open(struct dhcpcd_ctx *dctx)
eexit:
if (ctx->nd_fd != -1) {
- eloop_event_delete(dctx->eloop, ctx->nd_fd, 0);
+ eloop_event_delete(dctx->eloop, ctx->nd_fd);
close(ctx->nd_fd);
ctx->nd_fd = -1;
}
@@ -325,14 +350,16 @@ ipv6nd_expire(struct interface *ifp, uin
struct ra *rap;
struct timespec now;
- get_monotonic(&now);
+ if (ifp->ctx->ipv6 == NULL)
+ return;
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
if (rap->iface == ifp) {
- rap->received = now;
+ rap->acquired = now;
rap->expired = seconds ? 0 : 1;
if (seconds) {
- struct ra_opt *rao;
struct ipv6_addr *ap;
rap->lifetime = seconds;
@@ -343,9 +370,6 @@ ipv6nd_expire(struct interface *ifp, uin
}
}
ipv6_addaddrs(&rap->addrs);
- TAILQ_FOREACH(rao, &rap->options, next) {
- timespecclear(&rao->expire);
- }
}
}
}
@@ -397,18 +421,6 @@ ipv6nd_neighbour(struct dhcpcd_ctx *ctx,
}
}
-static void
-ipv6nd_free_opts(struct ra *rap)
-{
- struct ra_opt *rao;
-
- while ((rao = TAILQ_FIRST(&rap->options))) {
- TAILQ_REMOVE(&rap->options, rao, next);
- free(rao->option);
- free(rao);
- }
-}
-
struct ipv6_addr *
ipv6nd_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
short flags)
@@ -435,19 +447,26 @@ ipv6nd_findaddr(struct dhcpcd_ctx *ctx,
return NULL;
}
-void ipv6nd_freedrop_ra(struct ra *rap, int drop)
+static void
+ipv6nd_removefreedrop_ra(struct ra *rap, int remove_ra, int drop_ra)
{
eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap->iface);
eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap);
- if (!drop)
+ if (remove_ra && !drop_ra)
TAILQ_REMOVE(rap->iface->ctx->ipv6->ra_routers, rap, next);
- ipv6_freedrop_addrs(&rap->addrs, drop, NULL);
- ipv6nd_free_opts(rap);
+ ipv6_freedrop_addrs(&rap->addrs, drop_ra, NULL);
free(rap->data);
free(rap);
}
+void
+ipv6nd_freedrop_ra(struct ra *rap, int drop)
+{
+
+ ipv6nd_removefreedrop_ra(rap, 1, drop);
+}
+
ssize_t
ipv6nd_free(struct interface *ifp)
{
@@ -480,7 +499,7 @@ ipv6nd_free(struct interface *ifp)
}
if (ifp == NULL) {
if (ctx->ipv6->nd_fd != -1) {
- eloop_event_delete(ctx->eloop, ctx->ipv6->nd_fd, 0);
+ eloop_event_delete(ctx->eloop, ctx->ipv6->nd_fd);
close(ctx->ipv6->nd_fd);
ctx->ipv6->nd_fd = -1;
}
@@ -531,7 +550,6 @@ ipv6nd_scriptrun(struct ra *rap)
{
int hasdns, hasaddress, pid;
struct ipv6_addr *ap;
- const struct ra_opt *rao;
hasaddress = 0;
/* If all addresses have completed DAD run the script */
@@ -557,16 +575,7 @@ ipv6nd_scriptrun(struct ra *rap)
if (!(rap->iface->options->options & DHCPCD_IPV6RA_REQRDNSS))
hasdns = 1;
else {
- hasdns = 0;
- TAILQ_FOREACH(rao, &rap->options, next) {
- if (rao->type == ND_OPT_RDNSS &&
- rao->option &&
- timespecisset(&rao->expire))
- {
- hasdns = 1;
- break;
- }
- }
+ hasdns = rap->hasdns;
}
script_runreason(rap->iface, "ROUTERADVERT");
@@ -729,24 +738,19 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
struct icmp6_hdr *icp, size_t len)
{
struct ipv6_ctx *ctx = dctx->ipv6;
- size_t olen, l, n;
- ssize_t r;
+ size_t i, olen;
struct nd_router_advert *nd_ra;
struct nd_opt_prefix_info *pi;
struct nd_opt_mtu *mtu;
struct nd_opt_rdnss *rdnss;
- struct nd_opt_dnssl *dnssl;
- uint32_t lifetime, mtuv;
- uint8_t *p, *op;
- struct in6_addr addr;
+ uint32_t mtuv;
+ uint8_t *p;
char buf[INET6_ADDRSTRLEN];
const char *cbp;
struct ra *rap;
struct nd_opt_hdr *ndo;
- struct ra_opt *rao;
struct ipv6_addr *ap;
- char *opt, *opt2, *tmp;
- struct timespec expire;
+ struct dhcp_opt *dho;
uint8_t new_rap, new_data;
#ifdef IPV6_MANAGETEMPADDR
uint8_t new_ap;
@@ -830,7 +834,6 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
rap->from = ctx->from.sin6_addr;
strlcpy(rap->sfrom, ctx->sfrom, sizeof(rap->sfrom));
TAILQ_INIT(&rap->addrs);
- TAILQ_INIT(&rap->options);
new_rap = 1;
} else
new_rap = 0;
@@ -846,7 +849,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
rap->data_len = len;
}
- get_monotonic(&rap->received);
+ clock_gettime(CLOCK_MONOTONIC, &rap->acquired);
rap->flags = nd_ra->nd_ra_flags_reserved;
if (new_rap == 0 && rap->lifetime == 0)
logger(ifp->ctx, LOG_WARNING, "%s: %s router available",
@@ -861,6 +864,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
rap->retrans = ntohl(nd_ra->nd_ra_retransmit);
if (rap->lifetime)
rap->expired = 0;
+ rap->hasdns = 0;
ipv6_settempstale(ifp);
TAILQ_FOREACH(ap, &rap->addrs, next) {
@@ -869,7 +873,6 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
len -= sizeof(struct nd_router_advert);
p = ((uint8_t *)icp) + sizeof(struct nd_router_advert);
- lifetime = ~0U;
for (; len > 0; p += olen, len -= olen) {
if (len < sizeof(struct nd_opt_hdr)) {
logger(ifp->ctx, LOG_ERR,
@@ -889,7 +892,34 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
break;
}
- opt = opt2 = NULL;
+ if (has_option_mask(ifp->options->rejectmasknd,
+ ndo->nd_opt_type))
+ {
+ for (i = 0, dho = dctx->nd_opts;
+ i < dctx->nd_opts_len;
+ i++, dho++)
+ {
+ if (dho->option == ndo->nd_opt_type)
+ break;
+ }
+ if (dho != NULL)
+ logger(ifp->ctx, LOG_WARNING,
+ "%s: reject RA (option %s) from %s",
+ ifp->name, dho->var, ctx->sfrom);
+ else
+ logger(ifp->ctx, LOG_WARNING,
+ "%s: reject RA (option %d) from %s",
+ ifp->name, ndo->nd_opt_type, ctx->sfrom);
+ if (new_rap)
+ ipv6nd_removefreedrop_ra(rap, 0, 0);
+ else
+ ipv6nd_free_ra(rap);
+ return;
+ }
+
+ if (has_option_mask(ifp->options->nomasknd, ndo->nd_opt_type))
+ continue;
+
switch (ndo->nd_opt_type) {
case ND_OPT_PREFIX_INFORMATION:
pi = (struct nd_opt_prefix_info *)(void *)ndo;
@@ -966,7 +996,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
ap->saddr[0] = '\0';
}
ap->dadcallback = ipv6nd_dadcallback;
- ap->created = ap->acquired = rap->received;
+ ap->created = ap->acquired = rap->acquired;
TAILQ_INSERT_TAIL(&rap->addrs, ap, next);
#ifdef IPV6_MANAGETEMPADDR
@@ -986,7 +1016,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
new_ap = 0;
#endif
ap->flags &= ~IPV6_AF_STALE;
- ap->acquired = rap->received;
+ ap->acquired = rap->acquired;
}
if (pi->nd_opt_pi_flags_reserved &
ND_OPT_PI_FLAG_ONLINK)
@@ -996,16 +1026,6 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
ap->prefix_pltime =
ntohl(pi->nd_opt_pi_preferred_time);
ap->nsprobes = 0;
- cbp = inet_ntop(AF_INET6, &ap->prefix, buf, sizeof(buf));
- if (cbp) {
- l = strlen(cbp);
- opt = malloc(l + 5);
- if (opt) {
- snprintf(opt, l + 5, "%s/%d", cbp,
- ap->prefix_len);
- opt2 = strdup(ap->saddr);
- }
- }
#ifdef IPV6_MANAGETEMPADDR
/* RFC4941 Section 3.3.3 */
@@ -1025,8 +1045,6 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
}
}
#endif
-
- lifetime = ap->prefix_vltime;
break;
case ND_OPT_MTU:
@@ -1038,140 +1056,40 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
break;
}
rap->mtu = mtuv;
- snprintf(buf, sizeof(buf), "%d", mtuv);
- opt = strdup(buf);
break;
case ND_OPT_RDNSS:
- rdnss = (struct nd_opt_rdnss *)p;
- lifetime = ntohl(rdnss->nd_opt_rdnss_lifetime);
- op = (uint8_t *)ndo;
- op += offsetof(struct nd_opt_rdnss,
- nd_opt_rdnss_lifetime);
- op += sizeof(rdnss->nd_opt_rdnss_lifetime);
- l = 0;
- for (n = (size_t)ndo->nd_opt_len - 1; n > 1; n -= 2,
- op += sizeof(addr))
- {
- r = ipv6_printaddr(NULL, 0, op, ifp->name);
- if (r != -1)
- l += (size_t)r + 1;
- }
- op = (uint8_t *)ndo;
- op += offsetof(struct nd_opt_rdnss,
- nd_opt_rdnss_lifetime);
- op += sizeof(rdnss->nd_opt_rdnss_lifetime);
- tmp = opt = malloc(l);
- if (opt == NULL)
- continue;
- for (n = (size_t)ndo->nd_opt_len - 1; n > 1; n -= 2,
- op += sizeof(addr))
- {
- r = ipv6_printaddr(tmp, l, op,
- ifp->name);
- if (r != -1) {
- l -= ((size_t)r + 1);
- tmp += (size_t)r;
- *tmp++ = ' ';
- }
- }
- if (tmp != opt)
- (*--tmp) = '\0';
- else
- *opt = '\0';
- break;
-
- case ND_OPT_DNSSL:
- dnssl = (struct nd_opt_dnssl *)p;
- lifetime = ntohl(dnssl->nd_opt_dnssl_lifetime);
- op = p + offsetof(struct nd_opt_dnssl,
- nd_opt_dnssl_lifetime);
- op += sizeof(dnssl->nd_opt_dnssl_lifetime);
- n = (size_t)(dnssl->nd_opt_dnssl_len - 1) * 8;
- r = decode_rfc3397(NULL, 0, op, n);
- if (r < 1) {
- logger(ifp->ctx, new_data ? LOG_ERR : LOG_DEBUG,
- "%s: invalid DNSSL option",
- ifp->name);
- continue;
- } else {
- l = (size_t)r + 1;
- tmp = malloc(l);
- if (tmp) {
- decode_rfc3397(tmp, l, op, n);
- l -= 1;
- n = (size_t)print_string(NULL, 0,
- STRING | ARRAY | DOMAIN,
- (const uint8_t *)tmp, l);
- n++;
- opt = malloc(n);
- if (opt) {
- print_string(opt, n,
- STRING | ARRAY | DOMAIN,
- (const uint8_t *)tmp, l);
- } else
- logger(ifp->ctx, LOG_ERR,
- "%s: %m", __func__);
- free(tmp);
- }
- }
- break;
+ rdnss = (struct nd_opt_rdnss *)(void *)p;
+ if (rdnss->nd_opt_rdnss_lifetime &&
+ rdnss->nd_opt_rdnss_len > 1)
+ rap->hasdns = 1;
default:
continue;
}
+ }
- if (opt == NULL) {
- logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
- continue;
- }
-
- n = ndo->nd_opt_type;
-extra_opt:
- TAILQ_FOREACH(rao, &rap->options, next) {
- if (rao->type == n &&
- strcmp(rao->option, opt) == 0)
- break;
- }
- if (lifetime == 0 || *opt == '\0') {
- if (rao) {
- TAILQ_REMOVE(&rap->options, rao, next);
- free(rao->option);
- free(rao);
- }
- free(opt);
- free(opt2);
- continue;
- }
-
- if (rao == NULL) {
- rao = malloc(sizeof(*rao));
- if (rao == NULL) {
- logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
- continue;
- }
- rao->type = (uint16_t)n;
- rao->option = opt;
- TAILQ_INSERT_TAIL(&rap->options, rao, next);
- } else
- free(opt);
- if (lifetime == ~0U)
- timespecclear(&rao->expire);
- else {
- expire.tv_sec = (time_t)lifetime;
- expire.tv_nsec = 0;
- timespecadd(&rap->received, &expire, &rao->expire);
- }
- if (rao && rao->type == ND_OPT_PREFIX_INFORMATION && opt2) {
- n = _ND_OPT_PREFIX_ADDR;
- opt = opt2;
- opt2 = NULL;
- goto extra_opt;
+ for (i = 0, dho = dctx->nd_opts;
+ i < dctx->nd_opts_len;
+ i++, dho++)
+ {
+ if (has_option_mask(ifp->options->requiremasknd,
+ dho->option))
+ {
+ logger(ifp->ctx, LOG_WARNING,
+ "%s: reject RA (no option %s) from %s",
+ ifp->name, dho->var, ctx->sfrom);
+ if (new_rap)
+ ipv6nd_removefreedrop_ra(rap, 0, 0);
+ else
+ ipv6nd_free_ra(rap);
+ return;
}
}
if (new_rap)
add_router(ifp->ctx->ipv6, rap);
+
if (!ipv6nd_ra_has_public_addr(rap) &&
!(rap->iface->options->options & DHCPCD_IPV6RA_ACCEPT_NOPUBLIC) &&
(!(rap->flags & ND_RA_FLAG_MANAGED) ||
@@ -1191,7 +1109,7 @@ extra_opt:
}
ipv6_addaddrs(&rap->addrs);
#ifdef IPV6_MANAGETEMPADDR
- ipv6_addtempaddrs(ifp, &rap->received);
+ ipv6_addtempaddrs(ifp, &rap->acquired);
#endif
/* Find any freshly added routes, such as the subnet route.
@@ -1289,119 +1207,155 @@ ipv6nd_hasradhcp(const struct interface
return 0;
}
+static const uint8_t *
+ipv6nd_getoption(struct dhcpcd_ctx *ctx,
+ size_t *os, unsigned int *code, size_t *len,
+ const uint8_t *od, size_t ol, struct dhcp_opt **oopt)
+{
+ const struct nd_opt_hdr *o;
+ size_t i;
+ struct dhcp_opt *opt;
+
+ if (od) {
+ *os = sizeof(*o);
+ if (ol < *os) {
+ errno = EINVAL;
+ return NULL;
+ }
+ o = (const struct nd_opt_hdr *)od;
+ if (o->nd_opt_len > ol) {
+ errno = EINVAL;
+ return NULL;
+ }
+ *len = ND_OPTION_LEN(o);
+ *code = o->nd_opt_type;
+ } else
+ o = NULL;
+
+ for (i = 0, opt = ctx->nd_opts;
+ i < ctx->nd_opts_len; i++, opt++)
+ {
+ if (opt->option == *code) {
+ *oopt = opt;
+ break;
+ }
+ }
+
+ if (o)
+ return ND_COPTION_DATA(o);
+ return NULL;
+}
+
ssize_t
ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
{
- size_t i, l, len;
- const struct ra *rap;
- const struct ra_opt *rao;
- char buffer[32];
- const char *optn;
- char **pref, **addr, **mtu, **rdnss, **dnssl, ***var, *new;
+ size_t i, j, n, len;
+ struct ra *rap;
+ char ndprefix[32], abuf[24];
+ struct dhcp_opt *opt;
+ const struct nd_opt_hdr *o;
+ struct ipv6_addr *ia;
+ struct timespec now;
- i = l = 0;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ i = n = 0;
TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
if (rap->iface != ifp)
continue;
i++;
+ if (prefix != NULL)
+ snprintf(ndprefix, sizeof(ndprefix),
+ "%s_nd%zu", prefix, i);
+ else
+ snprintf(ndprefix, sizeof(ndprefix),
+ "nd%zu", i);
+ if (env)
+ setvar(rap->iface->ctx, &env[n], ndprefix,
+ "from", rap->sfrom);
+ n++;
+ if (env)
+ setvard(rap->iface->ctx, &env[n], ndprefix,
+ "acquired", (size_t)rap->acquired.tv_sec);
+ n++;
+ if (env)
+ setvard(rap->iface->ctx, &env[n], ndprefix,
+ "now", (size_t)now.tv_sec);
+ n++;
+
+ /* Zero our indexes */
if (env) {
- snprintf(buffer, sizeof(buffer),
- "ra%zu_from", i);
- setvar(ifp->ctx, &env, prefix, buffer, rap->sfrom);
- }
- l++;
-
- pref = addr = mtu = rdnss = dnssl = NULL;
- TAILQ_FOREACH(rao, &rap->options, next) {
- if (rao->option == NULL)
- continue;
- var = NULL;
- switch(rao->type) {
- case ND_OPT_PREFIX_INFORMATION:
- optn = "prefix";
- var = &pref;
- break;
- case _ND_OPT_PREFIX_ADDR:
- optn = "addr";
- var = &addr;
- break;
- case ND_OPT_MTU:
- optn = "mtu";
- var = &mtu;
- break;
- case ND_OPT_RDNSS:
- optn = "rdnss";
- var = &rdnss;
- break;
- case ND_OPT_DNSSL:
- optn = "dnssl";
- var = &dnssl;
+ for (j = 0, opt = rap->iface->ctx->nd_opts;
+ j < rap->iface->ctx->nd_opts_len;
+ j++, opt++)
+ dhcp_zero_index(opt);
+ for (j = 0, opt = rap->iface->options->nd_override;
+ j < rap->iface->options->nd_override_len;
+ j++, opt++)
+ dhcp_zero_index(opt);
+ }
+
+ /* Unlike DHCP, ND6 options *may* occur more than once.
+ * There is also no provision for option concatenation
+ * unlike DHCP. */
+ len = rap->data_len -
+ ((size_t)((const uint8_t *)ND_CFIRST_OPTION(rap) -
+ rap->data));
+
+ for (o = ND_CFIRST_OPTION(rap);
+ len >= (ssize_t)sizeof(*o);
+ o = ND_CNEXT_OPTION(o))
+ {
+ if ((size_t)o->nd_opt_len * 8 > len) {
+ errno = EINVAL;
break;
- default:
- continue;
}
- if (*var == NULL) {
- *var = env ? env : &new;
- l++;
- } else if (env) {
- /* With single only options, last one takes
- * precedence */
- if (rao->type == ND_OPT_MTU) {
- new = strchr(**var, '=');
- if (new == NULL) {
- logger(ifp->ctx, LOG_ERR,
- "new is null");
- continue;
- } else
- new++;
- len = (size_t)(new - **var) +
- strlen(rao->option) + 1;
- if (len > strlen(**var))
- new = realloc(**var, len);
- else
- new = **var;
- if (new) {
- **var = new;
- new = strchr(**var, '=');
- if (new) {
- len -=
- (size_t)
- (new - **var);
- strlcpy(new + 1,
- rao->option,
- len - 1);
- } else
- logger(ifp->ctx,
- LOG_ERR,
- "new is null");
- }
- continue;
- }
- len = strlen(rao->option) + 1;
- new = realloc(**var, strlen(**var) + 1 + len);
- if (new) {
- **var = new;
- new += strlen(new);
- *new++ = ' ';
- strlcpy(new, rao->option, len);
- } else
- logger(ifp->ctx, LOG_ERR,
- "%s: %m", __func__);
+ len -= (size_t)(o->nd_opt_len * 8);
+ if (has_option_mask(rap->iface->options->nomasknd,
+ o->nd_opt_type))
continue;
+ for (j = 0, opt = rap->iface->options->nd_override;
+ j < rap->iface->options->nd_override_len;
+ j++, opt++)
+ if (opt->option == o->nd_opt_type)
+ break;
+ if (j == rap->iface->options->nd_override_len) {
+ for (j = 0, opt = rap->iface->ctx->nd_opts;
+ j < rap->iface->ctx->nd_opts_len;
+ j++, opt++)
+ if (opt->option == o->nd_opt_type)
+ break;
+ if (j == rap->iface->ctx->nd_opts_len)
+ opt = NULL;
}
+ if (opt) {
+ n += dhcp_envoption(rap->iface->ctx,
+ env == NULL ? NULL : &env[n],
+ ndprefix, rap->iface->name,
+ opt, ipv6nd_getoption,
+ ND_COPTION_DATA(o), ND_OPTION_LEN(o));
+ }
+ }
+
+ /* We need to output the addresses we actually made
+ * from the prefix information options as well. */
+ j = 0;
+ TAILQ_FOREACH(ia, &rap->addrs, next) {
+ if (!(ia->flags & IPV6_AF_AUTOCONF)
+#ifdef IPV6_AF_TEMPORARY
+ || ia->flags & IPV6_AF_TEMPORARY
+#endif
+ )
+ continue;
+ j++;
if (env) {
- snprintf(buffer, sizeof(buffer),
- "ra%zu_%s", i, optn);
- setvar(ifp->ctx, &env,
- prefix, buffer, rao->option);
+ snprintf(abuf, sizeof(abuf), "addr%zu", j);
+ setvar(rap->iface->ctx, &env[n], ndprefix,
+ abuf, ia->saddr);
}
+ n++;
}
}
-
- if (env)
- setvard(ifp->ctx, &env, prefix, "ra_count", i);
- l++;
- return (ssize_t)l;
+ return (ssize_t)n;
}
void
@@ -1424,12 +1378,11 @@ ipv6nd_expirera(void *arg)
{
struct interface *ifp;
struct ra *rap, *ran;
- struct ra_opt *rao, *raon;
struct timespec now, lt, expire, next;
uint8_t expired, valid, validone;
ifp = arg;
- get_monotonic(&now);
+ clock_gettime(CLOCK_MONOTONIC, &now);
expired = 0;
timespecclear(&next);
@@ -1441,7 +1394,7 @@ ipv6nd_expirera(void *arg)
if (rap->lifetime) {
lt.tv_sec = (time_t)rap->lifetime;
lt.tv_nsec = 0;
- timespecadd(&rap->received, <, &expire);
+ timespecadd(&rap->acquired, <, &expire);
if (rap->lifetime == 0 || timespeccmp(&now, &expire, >))
{
if (!rap->expired) {
@@ -1460,43 +1413,10 @@ ipv6nd_expirera(void *arg)
}
}
- /* Addresses are expired in ipv6_addaddrs
- * so that DHCPv6 addresses can be removed also. */
- TAILQ_FOREACH_SAFE(rao, &rap->options, next, raon) {
- if (rap->expired) {
- switch(rao->type) {
- case ND_OPT_RDNSS: /* FALLTHROUGH */
- case ND_OPT_DNSSL:
- /* RFC6018 end of section 5.2 states
- * that if tha RA has a lifetime of 0
- * then we should expire these
- * options */
- TAILQ_REMOVE(&rap->options, rao, next);
- expired = 1;
- free(rao->option);
- free(rao);
- continue;
- }
- }
- if (!timespecisset(&rao->expire))
- continue;
- if (timespeccmp(&now, &rao->expire, >)) {
- /* Expired prefixes are logged above */
- if (rao->type != ND_OPT_PREFIX_INFORMATION)
- logger(ifp->ctx, LOG_WARNING,
- "%s: %s: expired option %d",
- ifp->name, rap->sfrom, rao->type);
- TAILQ_REMOVE(&rap->options, rao, next);
- expired = 1;
- free(rao->option);
- free(rao);
- continue;
- }
- valid = 1;
- timespecsub(&rao->expire, &now, <);
- if (!timespecisset(&next) || timespeccmp(&next, <, >))
- next = lt;
- }
+ /* XXX FixMe!
+ * We need to extract the lifetime from each option and check
+ * if that has expired or not.
+ * If it has, zero the option out in the returned data. */
/* No valid lifetimes are left on the RA, so we might
* as well punt it. */
@@ -1646,7 +1566,7 @@ ipv6nd_handledata(void *arg)
len = recvmsg(ctx->nd_fd, &ctx->rcvhdr, 0);
if (len == -1) {
logger(dctx, LOG_ERR, "recvmsg: %m");
- eloop_event_delete(dctx->eloop, ctx->nd_fd, 0);
+ eloop_event_delete(dctx->eloop, ctx->nd_fd);
close(ctx->nd_fd);
ctx->nd_fd = -1;
return;
Index: src/external/bsd/dhcpcd/dist/ipv4.c
diff -u src/external/bsd/dhcpcd/dist/ipv4.c:1.14 src/external/bsd/dhcpcd/dist/ipv4.c:1.15
--- src/external/bsd/dhcpcd/dist/ipv4.c:1.14 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/ipv4.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4.c,v 1.14 2015/05/02 15:18:37 roy Exp $");
+ __RCSID("$NetBSD: ipv4.c,v 1.15 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -35,6 +35,7 @@
#include <arpa/inet.h>
#include <net/route.h>
+#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
@@ -159,6 +160,15 @@ ipv4_findaddr(struct dhcpcd_ctx *ctx, co
}
int
+ipv4_ifaddrexists(const struct interface *ifp)
+{
+ const struct dhcp_state *state;
+
+ state = D_CSTATE(ifp);
+ return (state && state->addr.s_addr != INADDR_ANY);
+}
+
+int
ipv4_addrexists(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
{
struct interface *ifp;
@@ -744,6 +754,7 @@ ipv4_deladdr(struct interface *ifp,
int r;
struct ipv4_state *state;
struct ipv4_addr *ap;
+ struct arp_state *astate;
logger(ifp->ctx, LOG_DEBUG, "%s: deleting IP address %s/%d",
ifp->name, inet_ntoa(*addr), inet_ntocidr(*net));
@@ -753,14 +764,8 @@ ipv4_deladdr(struct interface *ifp,
errno != ENODEV)
logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
- dstate = D_STATE(ifp);
- if (dstate->addr.s_addr == addr->s_addr &&
- dstate->net.s_addr == net->s_addr)
- {
- dstate->added = 0;
- dstate->addr.s_addr = 0;
- dstate->net.s_addr = 0;
- }
+ if ((astate = arp_find(ifp, addr)) != NULL)
+ arp_free(astate);
state = IPV4_STATE(ifp);
TAILQ_FOREACH(ap, &state->addrs, next) {
@@ -772,6 +777,18 @@ ipv4_deladdr(struct interface *ifp,
break;
}
}
+
+ /* Have to do this last incase the function arguments
+ * were these very pointers. */
+ dstate = D_STATE(ifp);
+ if (dstate &&
+ dstate->addr.s_addr == addr->s_addr &&
+ dstate->net.s_addr == net->s_addr)
+ {
+ dstate->added = 0;
+ dstate->addr.s_addr = 0;
+ dstate->net.s_addr = 0;
+ }
return r;
}
@@ -815,6 +832,7 @@ ipv4_addaddr(struct interface *ifp, cons
{
struct ipv4_state *state;
struct ipv4_addr *ia;
+ struct dhcp_state *dstate;
if ((state = ipv4_getstate(ifp)) == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: ipv4_getstate: %m", __func__);
@@ -852,6 +870,17 @@ ipv4_addaddr(struct interface *ifp, cons
ia->addr_flags = IN_IFF_TENTATIVE;
#endif
TAILQ_INSERT_TAIL(&state->addrs, ia, next);
+
+ dstate = D_STATE(ifp);
+#ifdef IN_IFF_TENTATIVE
+ dstate->added |= STATE_ADDED;
+#else
+ dstate->added = STATE_ADDED;
+#endif
+ dstate->defend = 0;
+ dstate->addr.s_addr = lease->addr.s_addr;
+ dstate->net.s_addr = lease->net.s_addr;
+
return 0;
}
@@ -860,6 +889,8 @@ ipv4_finalisert(struct interface *ifp)
{
const struct dhcp_state *state = D_CSTATE(ifp);
+ assert(state != NULL);
+
/* Find any freshly added routes, such as the subnet route.
* We do this because we cannot rely on recieving the kernel
* notification right now via our link socket. */
@@ -884,13 +915,48 @@ ipv4_finaliseaddr(struct interface *ifp)
ipv4_iffindaddr(ifp, &lease->addr, NULL))
delete_address(ifp);
- state->added = STATE_ADDED;
- state->defend = 0;
- state->addr.s_addr = lease->addr.s_addr;
- state->net.s_addr = lease->net.s_addr;
+ state->added &= (uint8_t)~(STATE_FAKE | STATE_TENTATIVE);
ipv4_finalisert(ifp);
}
+int
+ipv4_preferanother(struct interface *ifp)
+{
+ struct dhcp_state *state = D_STATE(ifp), *nstate;
+ struct interface *ifn;
+ int preferred;
+
+ if (state == NULL)
+ return 0;
+
+ preferred = 0;
+ if (!state->added)
+ goto out;
+
+ TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
+ if (ifn == ifp || strcmp(ifn->name, ifp->name) == 0)
+ break; /* We are already the most preferred */
+ nstate = D_STATE(ifn);
+ if (nstate && !nstate->added &&
+ nstate->lease.addr.s_addr == state->addr.s_addr)
+ {
+ preferred = 1;
+ delete_address(ifp);
+ if (ifn->options->options & DHCPCD_ARP)
+ dhcp_bind(ifn, NULL);
+ else {
+ ipv4_addaddr(ifn, &nstate->lease);
+ nstate->added = STATE_ADDED;
+ }
+ break;
+ }
+ }
+
+out:
+ ipv4_buildroutes(ifp->ctx);
+ return preferred;
+}
+
void
ipv4_applyaddr(void *arg)
{
@@ -907,38 +973,15 @@ ipv4_applyaddr(void *arg)
dhcp = state->new;
lease = &state->lease;
+ if_sortinterfaces(ifp->ctx);
if (dhcp == NULL) {
if ((ifo->options & (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
(DHCPCD_EXITING | DHCPCD_PERSISTENT))
{
- if (state->added) {
- struct in_addr addr;
-
- addr = state->addr;
+ if (state->added && !ipv4_preferanother(ifp)) {
delete_address(ifp);
- TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
- if (ifn == ifp ||
- strcmp(ifn->name, ifp->name) == 0)
- continue;
- nstate = D_STATE(ifn);
- if (nstate && !nstate->added &&
- nstate->addr.s_addr == addr.s_addr)
- {
- if (ifn->options->options &
- DHCPCD_ARP)
- {
- dhcp_bind(ifn, NULL);
- } else {
- ipv4_addaddr(ifn,
- &nstate->lease);
- nstate->added =
- STATE_ADDED;
- }
- break;
- }
- }
+ ipv4_buildroutes(ifp->ctx);
}
- ipv4_buildroutes(ifp->ctx);
script_runreason(ifp, state->reason);
} else
ipv4_buildroutes(ifp->ctx);
@@ -946,29 +989,30 @@ ipv4_applyaddr(void *arg)
}
/* Ensure only one interface has the address */
+ r = 0;
TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
- if (ifn == ifp || strcmp(ifn->name, ifp->name) == 0)
+ if (ifn == ifp || strcmp(ifn->name, ifp->name) == 0) {
+ r = 1; /* past ourselves */
continue;
+ }
nstate = D_STATE(ifn);
if (nstate && nstate->added &&
nstate->addr.s_addr == lease->addr.s_addr)
{
- if (ifn->metric <= ifp->metric) {
+ if (r == 0) {
logger(ifp->ctx, LOG_INFO,
"%s: preferring %s on %s",
ifp->name,
inet_ntoa(lease->addr),
ifn->name);
- state->addr.s_addr = lease->addr.s_addr;
- state->net.s_addr = lease->net.s_addr;
- ipv4_finalisert(ifp);
+ state->added &= (uint8_t)~STATE_TENTATIVE;
+ return;
}
logger(ifp->ctx, LOG_INFO, "%s: preferring %s on %s",
ifn->name,
inet_ntoa(lease->addr),
ifp->name);
ipv4_deladdr(ifn, &nstate->addr, &nstate->net);
- nstate->added = 0;
break;
}
}
Index: src/external/bsd/dhcpcd/dist/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/ipv6.c:1.11 src/external/bsd/dhcpcd/dist/ipv6.c:1.12
--- src/external/bsd/dhcpcd/dist/ipv6.c:1.11 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/ipv6.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6.c,v 1.11 2015/05/02 15:18:37 roy Exp $");
+ __RCSID("$NetBSD: ipv6.c,v 1.12 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -38,19 +38,6 @@
#include <netinet/in.h>
#include <netinet/if_ether.h>
-#ifndef __linux__
-# ifndef __QNX__
-# include <sys/endian.h>
-# endif
-# include <net/if.h>
-# ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */
-# include <net/if_var.h>
-# endif
-# ifndef __sun
-# include <netinet6/in6_var.h>
-# endif
-#endif
-
#include <errno.h>
#include <ifaddrs.h>
#include <inttypes.h>
@@ -688,24 +675,36 @@ ipv6_addaddr(struct ipv6_addr *ap, const
struct timespec n;
if (now == NULL) {
- get_monotonic(&n);
+ clock_gettime(CLOCK_MONOTONIC, &n);
now = &n;
}
timespecsub(now, &ap->acquired, &n);
- if (ap->prefix_pltime != ND6_INFINITE_LIFETIME)
+ if (ap->prefix_pltime != ND6_INFINITE_LIFETIME) {
ap->prefix_pltime -= (uint32_t)n.tv_sec;
+ /* This can happen when confirming a
+ * deprecated but still valid lease. */
+ if (ap->prefix_pltime > pltime)
+ ap->prefix_pltime = 0;
+ }
if (ap->prefix_vltime != ND6_INFINITE_LIFETIME)
ap->prefix_vltime -= (uint32_t)n.tv_sec;
- }
- if (if_addaddress6(ap) == -1) {
- logger(ap->iface->ctx, LOG_ERR, "if_addaddress6: %m");
#if 0
logger(ap->iface->ctx, LOG_DEBUG,
+ "%s: acquired %lld.%.9ld, now %lld.%.9ld, diff %lld.%.9ld",
+ ap->iface->name,
+ (long long)ap->acquired.tv_sec, ap->acquired.tv_nsec,
+ (long long)now->tv_sec, now->tv_nsec,
+ (long long)n.tv_sec, n.tv_nsec);
+ logger(ap->iface->ctx, LOG_DEBUG,
"%s: adj pltime %"PRIu32" seconds, "
"vltime %"PRIu32" seconds",
ap->iface->name, ap->prefix_pltime, ap->prefix_vltime);
#endif
+ }
+
+ if (if_addaddress6(ap) == -1) {
+ logger(ap->iface->ctx, LOG_ERR, "if_addaddress6: %m");
/* Restore real pltime and vltime */
ap->prefix_pltime = pltime;
ap->prefix_vltime = vltime;
@@ -829,7 +828,7 @@ ipv6_addaddrs(struct ipv6_addrhead *addr
if (ap->flags & IPV6_AF_NEW)
i++;
if (!timespecisset(&now))
- get_monotonic(&now);
+ clock_gettime(CLOCK_MONOTONIC, &now);
ipv6_addaddr(ap, &now);
}
}
@@ -875,7 +874,7 @@ ipv6_freedrop_addrs(struct ipv6_addrhead
DHCPCD_EXITING) && apf)
{
if (!timespecisset(&now))
- get_monotonic(&now);
+ clock_gettime(CLOCK_MONOTONIC, &now);
ipv6_addaddr(apf, &now);
}
if (drop == 2)
@@ -1466,7 +1465,7 @@ ipv6_tempdadcallback(void *arg)
ia->iface->name);
return;
}
- get_monotonic(&tv);
+ clock_gettime(CLOCK_MONOTONIC, &tv);
if ((ia1 = ipv6_createtempaddr(ia, &tv)) == NULL)
logger(ia->iface->ctx, LOG_ERR,
"ipv6_createtempaddr: %m");
@@ -1571,9 +1570,7 @@ again:
cbp = inet_ntop(AF_INET6, &ia->addr, buf, sizeof(buf));
if (cbp)
snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
- cbp, ia->prefix_len);
- else
- ia->saddr[0] = '\0';
+ cbp, ia->prefix_len); else ia->saddr[0] = '\0';
TAILQ_INSERT_TAIL(&state->addrs, ia, next);
return ia;
@@ -1692,7 +1689,7 @@ ipv6_regentempaddr(void *arg)
logger(ia->iface->ctx, LOG_DEBUG, "%s: regen temp addr %s",
ia->iface->name, ia->saddr);
- get_monotonic(&tv);
+ clock_gettime(CLOCK_MONOTONIC, &tv);
ia1 = ipv6_createtempaddr(ia, &tv);
if (ia1)
ipv6_addaddr(ia1, &tv);
Index: src/external/bsd/dhcpcd/dist/ipv6nd.h
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.h:1.11 src/external/bsd/dhcpcd/dist/ipv6nd.h:1.12
--- src/external/bsd/dhcpcd/dist/ipv6nd.h:1.11 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/ipv6nd.h Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6nd.h,v 1.11 2015/05/02 15:18:37 roy Exp $ */
+/* $NetBSD: ipv6nd.h,v 1.12 2015/05/16 23:31:32 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -36,13 +36,6 @@
#include "dhcpcd.h"
#include "ipv6.h"
-struct ra_opt {
- TAILQ_ENTRY(ra_opt) next;
- uint16_t type;
- struct timespec expire;
- char *option;
-};
-
struct ra {
TAILQ_ENTRY(ra) next;
struct interface *iface;
@@ -50,14 +43,14 @@ struct ra {
char sfrom[INET6_ADDRSTRLEN];
unsigned char *data;
size_t data_len;
- struct timespec received;
+ struct timespec acquired;
unsigned char flags;
uint32_t lifetime;
uint32_t reachable;
uint32_t retrans;
uint32_t mtu;
struct ipv6_addrhead addrs;
- TAILQ_HEAD(, ra_opt) options;
+ uint8_t hasdns;
uint8_t expired;
uint8_t no_public_warned;
};
@@ -73,6 +66,17 @@ struct rs_state {
#define RS_STATE(a) ((struct rs_state *)(ifp)->if_data[IF_DATA_IPV6ND])
#define RS_STATE_RUNNING(a) (ipv6nd_hasra((a)) && ipv6nd_dadcompleted((a)))
+#define ND_CFIRST_OPTION(m) \
+ ((const struct nd_opt_hdr *) \
+ ((const uint8_t *)(m)->data + sizeof(struct nd_router_advert)))
+#define ND_OPTION_LEN(o) ((size_t)((o)->nd_opt_len * 8) - \
+ sizeof(struct nd_opt_hdr))
+#define ND_CNEXT_OPTION(o) \
+ ((const struct nd_opt_hdr *)((const uint8_t *)(o) + \
+ (size_t)((o)->nd_opt_len * 8)))
+#define ND_COPTION_DATA(o) \
+ ((const uint8_t *)(o) + sizeof(struct nd_opt_hdr))
+
#define MAX_RTR_SOLICITATION_DELAY 1 /* seconds */
#define MAX_UNICAST_SOLICIT 3 /* 3 transmissions */
#define RTR_SOLICITATION_INTERVAL 4 /* seconds */
@@ -93,6 +97,8 @@ struct rs_state {
#define IPV6ND_ROUTER (1 << 1)
#ifdef INET6
+void ipv6nd_printoptions(const struct dhcpcd_ctx *,
+ const struct dhcp_opt *, size_t);
void ipv6nd_startrs(struct interface *);
ssize_t ipv6nd_env(char **, const char *, const struct interface *);
struct ipv6_addr *ipv6nd_findaddr(struct dhcpcd_ctx *,
@@ -113,7 +119,6 @@ void ipv6nd_drop(struct interface *);
void ipv6nd_neighbour(struct dhcpcd_ctx *, struct in6_addr *, int);
#else
#define ipv6nd_startrs(a) {}
-#define ipv6nd_findaddr(a, b, c) (0)
#define ipv6nd_free(a) {}
#define ipv6nd_hasra(a) (0)
#define ipv6nd_dadcompleted(a) (0)
Index: src/external/bsd/dhcpcd/dist/script.c
diff -u src/external/bsd/dhcpcd/dist/script.c:1.19 src/external/bsd/dhcpcd/dist/script.c:1.20
--- src/external/bsd/dhcpcd/dist/script.c:1.19 Sat May 2 15:18:37 2015
+++ src/external/bsd/dhcpcd/dist/script.c Sat May 16 23:31:32 2015
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: script.c,v 1.19 2015/05/02 15:18:37 roy Exp $");
+ __RCSID("$NetBSD: script.c,v 1.20 2015/05/16 23:31:32 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -94,8 +94,9 @@ exec_script(const struct dhcpcd_ctx *ctx
{
pid_t pid;
posix_spawnattr_t attr;
- int i;
+ int r;
#ifdef USE_SIGNALS
+ size_t i;
short flags;
sigset_t defsigs;
#else
@@ -110,15 +111,15 @@ exec_script(const struct dhcpcd_ctx *ctx
flags = POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF;
posix_spawnattr_setflags(&attr, flags);
sigemptyset(&defsigs);
- for (i = 0; dhcpcd_handlesigs[i]; i++)
- sigaddset(&defsigs, dhcpcd_handlesigs[i]);
+ for (i = 0; i < dhcpcd_signals_len; i++)
+ sigaddset(&defsigs, dhcpcd_signals[i]);
posix_spawnattr_setsigdefault(&attr, &defsigs);
posix_spawnattr_setsigmask(&attr, &ctx->sigset);
#endif
errno = 0;
- i = posix_spawn(&pid, argv[0], NULL, &attr, argv, env);
- if (i) {
- errno = i;
+ r = posix_spawn(&pid, argv[0], NULL, &attr, argv, env);
+ if (r) {
+ errno = r;
return -1;
}
return pid;
@@ -287,7 +288,7 @@ make_env(const struct interface *ifp, co
if (ifp->ctx->options & DHCPCD_DUMPLEASE)
elen = 2;
else
- elen = 13;
+ elen = 12;
#define EMALLOC(i, l) if ((env[(i)] = malloc((l))) == NULL) goto eexit;
/* Make our env + space for profile, wireless and debug */
@@ -374,12 +375,6 @@ make_env(const struct interface *ifp, co
env[11] = strdup("if_oneup=false");
if (env[11] == NULL)
goto eexit;
- if (dhcpcd_ipwaited(ifp->ctx))
- env[12] = strdup("if_ipwaited=true");
- else
- env[12] = strdup("if_ipwaited=false");
- if (env[12] == NULL)
- goto eexit;
if (ifo->options & DHCPCD_DEBUG) {
e = strlen("syslog_debug=true") + 1;
EMALLOC(elen, e);
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.6 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.7
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.6 Fri Nov 7 20:51:03 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf Sat May 16 23:31:32 2015
@@ -1,4 +1,4 @@
-# $NetBSD: 20-resolv.conf,v 1.6 2014/11/07 20:51:03 roy Exp $
+# $NetBSD: 20-resolv.conf,v 1.7 2015/05/16 23:31:32 roy Exp $
# Generate /etc/resolv.conf
# Support resolvconf(8) if available
@@ -70,17 +70,54 @@ build_resolv_conf()
rm -f "$cf"
}
+# Extract any ND DNS options from the RA
+# For now, we ignore the lifetime of the DNS options unless they
+# are absent or zero.
+# In this case they are removed from consideration.
+# See draft-gont-6man-slaac-dns-config-issues-01 for issues
+# regarding DNS option lifetime in ND messages.
+eval_nd_dns()
+{
+
+ eval ltime=\$nd${i}_rdnss${j}_lifetime
+ if [ -z "$ltime" -o "$ltime" = 0 ]; then
+ rdnss=
+ else
+ eval rdnss=\$nd${i}_rdnss${j}_servers
+ fi
+ eval ltime=\$nd${i}_dnssl${j}_lifetime
+ if [ -z "$ltime" -o "$ltime" = 0 ]; then
+ dnssl=
+ else
+ eval dnssl=\$nd${i}_dnssl${j}_search
+ fi
+
+ [ -z "$rdnss" -a -z "$dnssl" ] && return 1
+
+ new_rdnss="$new_rdnss${new_rdnss:+ }$rdnss"
+ new_dnssl="$new_dnssl${new_dnssl:+ }$dnssl"
+ j=$(($j + 1))
+ return 0
+}
+
add_resolv_conf()
{
- local x= conf="$signature$NL" i=${ra_count:-0} ra= warn=true
+ local x= conf="$signature$NL" warn=true
+ local i j ltime rdnss dnssl new_rdnss new_dnssl
- while [ $i -ne 0 ]; do
- eval ra=\$ra${i}_rdnss
- new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$ra"
- eval ra=\$ra${i}_dnssl
- new_domain_search="$new_domain_search${new_domain_search:+ }$ra"
- i=$(($i - 1))
+ # Loop to extract the ND DNS options using our indexed shell values
+ i=1
+ j=1
+ while true; do
+ while true; do
+ eval_nd_dns || break
+ done
+ i=$(($i + 1))
+ j=1
+ eval_nd_dns || break
done
+ new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss"
+ new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl"
# If we don't have any configuration, remove it
if [ -z "$new_domain_name_servers" -a \