Module Name: src
Committed By: roy
Date: Fri Mar 14 11:31:11 UTC 2014
Modified Files:
src/external/bsd/dhcpcd/dist: dhcp.c dhcpcd.8.in dhcpcd.c if-bsd.c
if-options.c ipv6nd.c net.c
Log Message:
Sync
To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/dhcp.c
cvs rdiff -u -r1.26 -r1.27 src/external/bsd/dhcpcd/dist/dhcpcd.8.in
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/dhcpcd/dist/dhcpcd.c
cvs rdiff -u -r1.4 -r1.5 src/external/bsd/dhcpcd/dist/if-bsd.c
cvs rdiff -u -r1.7 -r1.8 src/external/bsd/dhcpcd/dist/if-options.c
cvs rdiff -u -r1.6 -r1.7 src/external/bsd/dhcpcd/dist/ipv6nd.c
cvs rdiff -u -r1.5 -r1.6 src/external/bsd/dhcpcd/dist/net.c
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/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.11 src/external/bsd/dhcpcd/dist/dhcp.c:1.12
--- src/external/bsd/dhcpcd/dist/dhcp.c:1.11 Sat Mar 1 11:04:21 2014
+++ src/external/bsd/dhcpcd/dist/dhcp.c Fri Mar 14 11:31:11 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp.c,v 1.11 2014/03/01 11:04:21 roy Exp $");
+ __RCSID("$NetBSD: dhcp.c,v 1.12 2014/03/14 11:31:11 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -1064,8 +1064,12 @@ read_lease(struct interface *ifp)
free(dhcp);
return NULL;
}
- syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
- ifp->name, state->auth.token->secretid);
+ if (state->auth.token)
+ syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
+ ifp->name, state->auth.token->secretid);
+ else
+ syslog(LOG_DEBUG, "%s: accepted reconfigure key",
+ ifp->name);
}
return dhcp;
@@ -1347,7 +1351,7 @@ dhcp_close(struct interface *ifp)
state->raw_fd = -1;
}
if (state->udp_fd != -1) {
- /* we don't listen to events on the udp */
+ eloop_event_delete(ifp->ctx->eloop, state->udp_fd);
close(state->udp_fd);
state->udp_fd = -1;
}
@@ -2200,8 +2204,12 @@ dhcp_handledhcp(struct interface *iface,
iface, dhcp, from, 0);
return;
}
- syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
- iface->name, state->auth.token->secretid);
+ if (state->auth.token)
+ syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
+ iface->name, state->auth.token->secretid);
+ else
+ syslog(LOG_DEBUG, "%s: accepted reconfigure key",
+ iface->name);
} else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
log_dhcp1(LOG_ERR, "no authentication", iface, dhcp, from, 0);
return;
@@ -2614,7 +2622,7 @@ dhcp_handleudp(void *arg)
/* Just read what's in the UDP fd and discard it as we always read
* from the raw fd */
- read(ctx->udp_fd, buffer, sizeof(buffer));
+ (void)read(ctx->udp_fd, buffer, sizeof(buffer));
}
static void
@@ -2629,7 +2637,7 @@ dhcp_handleifudp(void *arg)
/* Just read what's in the UDP fd and discard it as we always read
* from the raw fd */
- read(state->udp_fd, buffer, sizeof(buffer));
+ (void)read(state->udp_fd, buffer, sizeof(buffer));
}
static int
@@ -2673,25 +2681,23 @@ dhcp_open(struct interface *ifp)
}
int
-dhcp_dump(const char *ifname)
+dhcp_dump(struct dhcpcd_ctx *ctx, const char *ifname)
{
- struct dhcpcd_ctx ctx;
struct interface *ifp;
struct dhcp_state *state;
- int r;
- ifp = NULL;
+ if (ctx->ifaces == NULL) {
+ ctx->ifaces = malloc(sizeof(*ctx->ifaces));
+ if (ctx->ifaces == NULL)
+ return -1;
+ TAILQ_INIT(ctx->ifaces);
+ }
state = NULL;
- memset(&ctx, 0, sizeof(ctx));
- ctx.ifaces = malloc(sizeof(*ctx.ifaces));
- if (ctx.ifaces == NULL)
- goto eexit;
- TAILQ_INIT(ctx.ifaces);
ifp = calloc(1, sizeof(*ifp));
if (ifp == NULL)
goto eexit;
- ifp->ctx = &ctx;
- TAILQ_INSERT_HEAD(ctx.ifaces, ifp, next);
+ ifp->ctx = ctx;
+ TAILQ_INSERT_HEAD(ctx->ifaces, ifp, next);
ifp->if_data[IF_DATA_DHCP] = state = calloc(1, sizeof(*state));
if (state == NULL)
goto eexit;
@@ -2701,7 +2707,6 @@ dhcp_dump(const char *ifname)
strlcpy(ifp->name, ifname, sizeof(ifp->name));
snprintf(state->leasefile, sizeof(state->leasefile),
LEASEFILE, ifp->name);
- strlcpy(ifp->options->script, SCRIPT, sizeof(ifp->options->script));
state->new = read_lease(ifp);
if (state->new == NULL && errno == ENOENT) {
strlcpy(state->leasefile, ifname, sizeof(state->leasefile));
@@ -2710,28 +2715,14 @@ dhcp_dump(const char *ifname)
if (state->new == NULL) {
if (errno == ENOENT)
syslog(LOG_ERR, "%s: no lease to dump", ifname);
- r = -1;
- goto cexit;
+ return -1;
}
state->reason = "DUMP";
- r = script_runreason(ifp, state->reason);
- goto cexit;
+ return script_runreason(ifp, state->reason);
eexit:
syslog(LOG_ERR, "%s: %m", __func__);
- r = -1;
-
-cexit:
- if (state) {
- free(state->new);
- free(state);
- }
- if (ifp) {
- free(ifp->options);
- free(ifp);
- }
- free(ctx.ifaces);
- return r;
+ return -1;
}
void
Index: src/external/bsd/dhcpcd/dist/dhcpcd.8.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.26 src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.27
--- src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.26 Tue Feb 25 13:20:23 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.8.in Fri Mar 14 11:31:11 2014
@@ -1,4 +1,4 @@
-.\" $NetBSD: dhcpcd.8.in,v 1.26 2014/02/25 13:20:23 roy Exp $
+.\" $NetBSD: dhcpcd.8.in,v 1.27 2014/03/14 11:31:11 roy Exp $
.\" Copyright (c) 2006-2014 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 February 25, 2014
+.Dd March 7, 2014
.Dt DHCPCD 8
.Os
.Sh NAME
@@ -31,7 +31,7 @@
.Nd a DHCP client
.Sh SYNOPSIS
.Nm
-.Op Fl 46ABbDdEGgHJKLpqTV
+.Op Fl 46ABbDdEGgHJKLMpqTV
.Op Fl C , Fl Fl nohook Ar hook
.Op Fl c , Fl Fl script Ar script
.Op Fl e , Fl Fl env Ar value
@@ -327,6 +327,10 @@ By default
.Nm
does not request any lease time and leaves it in the hands of the
DHCP server.
+.It Fl M , Fl Fl master
+Start
+.Nm
+in master mode even if only one interface specified on the command line.
.It Fl m , Fl Fl metric Ar metric
Metrics are used to prefer an interface over another one, lowest wins.
.Nm
@@ -639,11 +643,11 @@ lease and use the files mtime as when it
Stores the monotonic counter used in the
.Ar replay
field in Authentication Options.
-.It Pa @[email protected]
+.It Pa @RUNDIR@/dhcpcd.pid
Stores the PID of
.Nm
running on all interfaces.
-.It Pa @RUNDIR@dhcpcd\- Ns Ar interface Ns .pid
+.It Pa @RUNDIR@/dhcpcd\- Ns Ar interface Ns .pid
Stores the PID of
.Nm
running on the
Index: src/external/bsd/dhcpcd/dist/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.c:1.3 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.4
--- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.3 Sat Mar 1 11:04:21 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.c Fri Mar 14 11:31:11 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd.c,v 1.3 2014/03/01 11:04:21 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd.c,v 1.4 2014/03/14 11:31:11 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -300,9 +300,11 @@ find_interface(struct dhcpcd_ctx *ctx, c
{
struct interface *ifp;
- TAILQ_FOREACH(ifp, ctx->ifaces, next) {
- if (strcmp(ifp->name, ifname) == 0)
- return ifp;
+ if (ctx != NULL && ctx->ifaces != NULL) {
+ TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+ if (strcmp(ifp->name, ifname) == 0)
+ return ifp;
+ }
}
return NULL;
}
@@ -522,7 +524,8 @@ handle_carrier(struct dhcpcd_ctx *ctx, i
* them as some OS's will remove, mark tentative or
* do nothing. */
ipv6_free_ll_callbacks(ifp);
- dhcp_drop(ifp, "NOCARRIER");
+ dhcp_drop(ifp, "EXPIRE");
+ script_runreason(ifp, "NOCARRIER");
}
} else if (carrier == LINK_UP && ifp->flags & IFF_UP) {
if (ifp->carrier != LINK_UP) {
@@ -578,7 +581,8 @@ start_interface(void *arg)
size_t i;
char buf[DUID_LEN * 3];
- handle_carrier(ifp->ctx, LINK_UNKNOWN, 0, ifp->name);
+ if (ifp->carrier == LINK_UNKNOWN)
+ handle_carrier(ifp->ctx, LINK_UNKNOWN, 0, ifp->name);
if (ifp->carrier == LINK_DOWN) {
syslog(LOG_INFO, "%s: waiting for carrier", ifp->name);
return;
@@ -852,6 +856,7 @@ struct dhcpcd_siginfo {
pid_t pid;
} dhcpcd_siginfo;
+#define sigmsg "received signal %s from PID %d, %s"
static void
handle_signal1(void *arg)
{
@@ -866,17 +871,17 @@ handle_signal1(void *arg)
do_release = 0;
switch (si->signo) {
case SIGINT:
- syslog(LOG_INFO, "received SIGINT from PID %d, stopping",
- (int)si->pid);
+ syslog(LOG_INFO, sigmsg, "INT", (int)si->pid, "stopping");
break;
case SIGTERM:
- syslog(LOG_INFO, "received SIGTERM from PID %d, stopping",
- (int)si->pid);
+ syslog(LOG_INFO, sigmsg, "TERM", (int)si->pid, "stopping");
break;
case SIGALRM:
- syslog(LOG_INFO, "received SIGALRM from PID %d, rebinding",
- (int)si->pid);
-
+ syslog(LOG_INFO, sigmsg, "ALRM", (int)si->pid, "releasing");
+ do_release = 1;
+ break;
+ case SIGHUP:
+ syslog(LOG_INFO, sigmsg, "HUP", (int)si->pid, "rebinding");
free_globals(ctx);
ifo = read_config(ctx, NULL, NULL, NULL);
add_options(ctx, NULL, ifo, ctx->argc, ctx->argv);
@@ -892,20 +897,14 @@ handle_signal1(void *arg)
reconf_reboot(ctx, 1, ctx->argc, ctx->argv,
ctx->argc - ctx->ifc);
return;
- case SIGHUP:
- syslog(LOG_INFO, "received SIGHUP from PID %d, releasing",
- (int)si->pid);
- do_release = 1;
- break;
case SIGUSR1:
- syslog(LOG_INFO, "received SIGUSR from PID %d, reconfiguring",
- (int)si->pid);
+ syslog(LOG_INFO, sigmsg, "USR1", (int)si->pid, "reconfiguring");
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
ipv4_applyaddr(ifp);
}
return;
case SIGPIPE:
- syslog(LOG_WARNING, "received SIGPIPE");
+ syslog(LOG_WARNING, "received signal PIPE");
return;
default:
syslog(LOG_ERR,
@@ -921,14 +920,14 @@ handle_signal1(void *arg)
}
static void
-handle_signal(__unused int sig, siginfo_t *siginfo, __unused void *context)
+handle_signal(int sig, 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 = siginfo->si_signo;
- dhcpcd_siginfo.pid = siginfo->si_pid;
+ dhcpcd_siginfo.signo = sig;
+ dhcpcd_siginfo.pid = siginfo ? siginfo->si_pid : 0;
eloop_timeout_add_now(dhcpcd_ctx->eloop,
handle_signal1, &dhcpcd_siginfo);
}
@@ -1118,6 +1117,7 @@ main(int argc, char **argv)
#endif
#ifdef USE_SIGNALS
int sig;
+ const char *siga;
#endif
struct timespec ts;
@@ -1125,6 +1125,7 @@ main(int argc, char **argv)
#ifdef USE_SIGNALS
dhcpcd_ctx = &ctx;
sig = 0;
+ siga = NULL;
#endif
closefrom(3);
openlog(PACKAGE, LOG_PERROR | LOG_PID, LOG_DAEMON);
@@ -1166,15 +1167,19 @@ main(int argc, char **argv)
#ifdef USE_SIGNALS
case 'g':
sig = SIGUSR1;
+ siga = "USR1";
break;
case 'k':
- sig = SIGHUP;
+ sig = SIGALRM;
+ siga = "ARLM";
break;
case 'n':
- sig = SIGALRM;
+ sig = SIGHUP;
+ siga = "HUP";
break;
case 'x':
sig = SIGTERM;
+ siga = "TERM";;
break;
#endif
case 'T':
@@ -1194,6 +1199,9 @@ main(int argc, char **argv)
ctx.argv = argv;
ctx.argc = argc;
+ ctx.ifc = argc - optind;
+ ctx.ifv = argv + optind;
+
ifo = read_config(&ctx, NULL, NULL, NULL);
opt = add_options(&ctx, NULL, ifo, argc, argv);
if (opt != 1) {
@@ -1247,7 +1255,7 @@ main(int argc, char **argv)
if (!(ctx.options & (DHCPCD_TEST | DHCPCD_DUMPLEASE))) {
/* If we have any other args, we should run as a single dhcpcd
* instance for that interface. */
- if (optind == argc - 1) {
+ if (optind == argc - 1 && !(ctx.options & DHCPCD_MASTER)) {
if (strlen(argv[optind]) > IF_NAMESIZE) {
syslog(LOG_ERR, "%s: interface name too long",
argv[optind]);
@@ -1270,13 +1278,15 @@ main(int argc, char **argv)
syslog(LOG_ERR, "dumplease requires an interface");
goto exit_failure;
}
- if (dhcp_dump(argv[optind]) == -1)
+ if (dhcp_dump(&ctx, argv[optind]) == -1)
goto exit_failure;
goto exit_success;
}
#ifdef USE_SIGNALS
- if (!(ctx.options & (DHCPCD_MASTER | DHCPCD_TEST))) {
+ if (!(ctx.options & DHCPCD_TEST) &&
+ (sig == 0 || ctx.ifc != 0))
+ {
#endif
if (ctx.options & DHCPCD_MASTER)
i = -1;
@@ -1318,20 +1328,20 @@ main(int argc, char **argv)
if (sig != 0) {
pid = read_pid(pidfile);
if (pid != 0)
- syslog(LOG_INFO, "sending signal %d to pid %d",
- sig, pid);
+ syslog(LOG_INFO, "sending signal %s to pid %d",
+ siga, pid);
if (pid == 0 || kill(pid, sig) != 0) {
- if (sig != SIGALRM && errno != EPERM)
+ if (sig != SIGHUP && errno != EPERM)
syslog(LOG_ERR, ""PACKAGE" not running");
if (pid != 0 && errno != ESRCH) {
syslog(LOG_ERR, "kill: %m");
goto exit_failure;
}
unlink(pidfile);
- if (sig != SIGALRM)
+ if (sig != SIGHUP)
goto exit_failure;
} else {
- if (sig == SIGALRM || sig == SIGUSR1)
+ if (sig == SIGHUP || sig == SIGUSR1)
goto exit_success;
/* Spin until it exits */
syslog(LOG_INFO, "waiting for pid %d to exit", pid);
@@ -1405,8 +1415,10 @@ main(int argc, char **argv)
}
#endif
- ctx.ifc = argc - optind;
- ctx.ifv = argv + optind;
+#ifdef __FreeBSD__
+ syslog(LOG_WARNING, "FreeBSD errors that are worked around:");
+ syslog(LOG_WARNING, "IPv4 subnet routes cannot be deleted");
+#endif
/* When running dhcpcd against a single interface, we need to retain
* the old behaviour of waiting for an IP address */
Index: src/external/bsd/dhcpcd/dist/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.4 src/external/bsd/dhcpcd/dist/if-bsd.c:1.5
--- src/external/bsd/dhcpcd/dist/if-bsd.c:1.4 Tue Feb 25 13:20:23 2014
+++ src/external/bsd/dhcpcd/dist/if-bsd.c Fri Mar 14 11:31:11 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: if-bsd.c,v 1.4 2014/02/25 13:20:23 roy Exp $");
+ __RCSID("$NetBSD: if-bsd.c,v 1.5 2014/03/14 11:31:11 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -50,6 +50,7 @@
#elif __APPLE__
/* FIXME: Add apple includes so we can work out SSID */
#else
+# include <net80211/ieee80211.h>
# include <net80211/ieee80211_ioctl.h>
#endif
@@ -285,19 +286,24 @@ if_route(const struct rt *rt, int action
memset(&rtm, 0, sizeof(rtm));
rtm.hdr.rtm_version = RTM_VERSION;
rtm.hdr.rtm_seq = 1;
+ rtm.hdr.rtm_addrs = RTA_DST;
if (action == 0)
rtm.hdr.rtm_type = RTM_CHANGE;
- else if (action > 0)
+ else if (action > 0) {
rtm.hdr.rtm_type = RTM_ADD;
- else
+ rtm.hdr.rtm_addrs |= RTA_GATEWAY;
+ } else
rtm.hdr.rtm_type = RTM_DELETE;
rtm.hdr.rtm_flags = RTF_UP;
+#ifdef SIOCGIFPRIORITY
+ rtm.hdr.rtm_priority = rt->metric;
+#endif
+
/* None interface subnet routes are static. */
if (rt->gate.s_addr != INADDR_ANY ||
rt->net.s_addr != state->net.s_addr ||
rt->dest.s_addr != (state->addr.s_addr & state->net.s_addr))
rtm.hdr.rtm_flags |= RTF_STATIC;
- rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
if (rt->dest.s_addr == rt->gate.s_addr &&
rt->net.s_addr == INADDR_BROADCAST)
rtm.hdr.rtm_flags |= RTF_HOST;
@@ -313,17 +319,19 @@ if_route(const struct rt *rt, int action
}
ADDADDR(&rt->dest);
- if ((rtm.hdr.rtm_flags & RTF_HOST &&
- rt->gate.s_addr != htonl(INADDR_LOOPBACK)) ||
- !(rtm.hdr.rtm_flags & RTF_STATIC))
- {
- /* Make us a link layer socket for the host gateway */
- memset(&su, 0, sizeof(su));
- su.sdl.sdl_len = sizeof(struct sockaddr_dl);
- link_addr(rt->iface->name, &su.sdl);
- ADDSU;
- } else
- ADDADDR(&rt->gate);
+ if (rtm.hdr.rtm_addrs & RTA_GATEWAY) {
+ if ((rtm.hdr.rtm_flags & RTF_HOST &&
+ rt->gate.s_addr != htonl(INADDR_LOOPBACK)) ||
+ !(rtm.hdr.rtm_flags & RTF_STATIC))
+ {
+ /* Make us a link layer socket for the host gateway */
+ memset(&su, 0, sizeof(su));
+ su.sdl.sdl_len = sizeof(struct sockaddr_dl);
+ link_addr(rt->iface->name, &su.sdl);
+ ADDSU;
+ } else
+ ADDADDR(&rt->gate);
+ }
if (rtm.hdr.rtm_addrs & RTA_NETMASK)
ADDADDR(&rt->net);
@@ -411,7 +419,7 @@ if_route6(const struct rt6 *rt, int acti
char *bp = rtm.buffer;
size_t l;
int s, retval;
- const struct ipv6_addr_l *lla;
+ const struct ipv6_addr *lla;
if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
return -1;
@@ -456,8 +464,11 @@ if_route6(const struct rt6 *rt, int acti
rtm.hdr.rtm_type = RTM_ADD;
else
rtm.hdr.rtm_type = RTM_DELETE;
-
rtm.hdr.rtm_flags = RTF_UP;
+ rtm.hdr.rtm_addrs = RTA_DST | RTA_NETMASK;
+#ifdef SIOCGIFPRIORITY
+ rtm.hdr.rtm_priority = rt->metric;
+#endif
/* None interface subnet routes are static. */
if (IN6_IS_ADDR_UNSPECIFIED(&rt->dest) &&
IN6_IS_ADDR_UNSPECIFIED(&rt->net))
@@ -467,19 +478,21 @@ if_route6(const struct rt6 *rt, int acti
rtm.hdr.rtm_flags |= RTF_CLONING;
#endif
- rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
if (action >= 0)
- rtm.hdr.rtm_addrs |= RTA_IFP | RTA_IFA;
+ rtm.hdr.rtm_addrs |= RTA_GATEWAY | RTA_IFP | RTA_IFA;
ADDADDR(&rt->dest);
- if (!(rtm.hdr.rtm_flags & RTF_GATEWAY)) {
- lla = ipv6_linklocal(rt->iface);
- if (lla == NULL) /* unlikely as we need a LL to get here */
- return -1;
- ADDADDRS(&lla->addr, rt->iface->index);
- } else {
- lla = NULL;
- ADDADDRS(&rt->gate, rt->iface->index);
+ lla = NULL;
+ if (rtm.hdr.rtm_addrs & RTA_GATEWAY) {
+ if (!(rtm.hdr.rtm_flags & RTF_GATEWAY)) {
+ lla = ipv6_linklocal(rt->iface);
+ if (lla == NULL) /* unlikely */
+ return -1;
+ ADDADDRS(&lla->addr, rt->iface->index);
+ } else {
+ lla = NULL;
+ ADDADDRS(&rt->gate, rt->iface->index);
+ }
}
if (rtm.hdr.rtm_addrs & RTA_NETMASK) {
@@ -582,7 +595,7 @@ manage_link(struct dhcpcd_ctx *ctx)
#ifdef INET
struct rt rt;
#endif
-#if defined(INET6) && !defined(LISTEN_DAD)
+#ifdef INET6
struct in6_addr ia6;
struct sockaddr_in6 *sin6;
int ifa_flags;
@@ -701,7 +714,7 @@ manage_link(struct dhcpcd_ctx *ctx)
&rt.dest, &rt.net, &rt.gate);
break;
#endif
-#if defined(INET6) && !defined(LISTEN_DAD)
+#ifdef INET6
case AF_INET6:
sin6 = (struct sockaddr_in6*)(void *)
rti_info[RTAX_IFA];
Index: src/external/bsd/dhcpcd/dist/if-options.c
diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.7 src/external/bsd/dhcpcd/dist/if-options.c:1.8
--- src/external/bsd/dhcpcd/dist/if-options.c:1.7 Sat Mar 1 11:04:21 2014
+++ src/external/bsd/dhcpcd/dist/if-options.c Fri Mar 14 11:31:11 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: if-options.c,v 1.7 2014/03/01 11:04:21 roy Exp $");
+ __RCSID("$NetBSD: if-options.c,v 1.8 2014/03/14 11:31:11 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -127,6 +127,7 @@ const struct option cf_options[] = {
{"broadcast", no_argument, NULL, 'J'},
{"nolink", no_argument, NULL, 'K'},
{"noipv4ll", no_argument, NULL, 'L'},
+ {"master", no_argument, NULL, 'M'},
{"nooption", optional_argument, NULL, 'O'},
{"require", required_argument, NULL, 'Q'},
{"static", required_argument, NULL, 'S'},
@@ -929,6 +930,9 @@ parse_option(struct dhcpcd_ctx *ctx, con
case 'L':
ifo->options &= ~DHCPCD_IPV4LL;
break;
+ case 'M':
+ ifo->options |= DHCPCD_MASTER;
+ break;
case 'O':
arg = set_option_space(ctx, arg, &d, &dl, ifo,
&request, &require, &no);
Index: src/external/bsd/dhcpcd/dist/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.6 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.7
--- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.6 Sat Mar 1 11:04:21 2014
+++ src/external/bsd/dhcpcd/dist/ipv6nd.c Fri Mar 14 11:31:11 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6nd.c,v 1.6 2014/03/01 11:04:21 roy Exp $");
+ __RCSID("$NetBSD: ipv6nd.c,v 1.7 2014/03/14 11:31:11 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -49,14 +49,6 @@
#include <syslog.h>
#include <unistd.h>
-/* Currently, no known kernel allows us to send from the unspecified address
- * which is required for DAD to work. This isn't that much of a problem as
- * the kernel will do DAD for us correctly, however we don't know the exact
- * randomness the kernel applies to the timeouts. So we just follow the same
- * logic and have a little faith.
- * This define is purely for completeness */
-// #define IPV6_SEND_DAD
-
#define ELOOP_QUEUE 2
#include "common.h"
#include "dhcpcd.h"
@@ -66,11 +58,6 @@
#include "ipv6nd.h"
#include "script.h"
-#if defined(LISTEN_DAD) && defined(INET6)
-# warning kernel does not report DAD results to userland
-# warning listening to duplicated addresses on the wire
-#endif
-
/* Debugging Router Solicitations is a lot of spam, so disable it */
//#define DEBUG_RS
@@ -172,16 +159,10 @@ ipv6nd_open(struct dhcpcd_ctx *dctx)
struct ipv6_ctx *ctx;
int on;
struct icmp6_filter filt;
-#ifdef IPV6_SEND_DAD
- union {
- struct sockaddr sa;
- struct sockaddr_in6 sin;
- } su;
-#endif
ctx = dctx->ipv6;
if (ctx->nd_fd != -1)
- goto unspec;
+ return ctx->nd_fd;
#ifdef SOCK_CLOEXEC
ctx->nd_fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
IPPROTO_ICMPV6);
@@ -206,6 +187,12 @@ ipv6nd_open(struct dhcpcd_ctx *dctx)
}
#endif
+ /* RFC4861 4.1 */
+ on = 255;
+ if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+ &on, sizeof(on)) == -1)
+ goto eexit;
+
on = 1;
if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
&on, sizeof(on)) == -1)
@@ -224,62 +211,6 @@ ipv6nd_open(struct dhcpcd_ctx *dctx)
goto eexit;
eloop_event_add(dctx->eloop, ctx->nd_fd, ipv6nd_handledata, dctx);
-
-unspec:
-#ifdef IPV6_SEND_DAD
- if (ctx->unspec_fd != -1)
- return ctx->nd_fd;
-
- ICMP6_FILTER_SETBLOCKALL(&filt);
-
- /* We send DAD requests from the unspecified address. */
-#ifdef SOCK_CLOEXEC
- ctx->unspec_fd = socket(AF_INET6,
- SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
- IPPROTO_ICMPV6);
- if (ctx->unspec_fd == -1)
- return -1;
-#else
- if ((ctx->unspec_fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1)
- return -1;
- if ((on = fcntl(ctx->unspec_fd, F_GETFD, 0)) == -1 ||
- fcntl(ctx->unspec_fd, F_SETFD, on | FD_CLOEXEC) == -1)
- {
- close(ctx->unspec_fd);
- ctx->unspec_fd = -1;
- return -1;
- }
- if ((on = fcntl(ctx->unspec_fd, F_GETFL, 0)) == -1 ||
- fcntl(ctx->unspec_fd, F_SETFL, on | O_NONBLOCK) == -1)
- {
- close(ctx->unspec_fd);
- ctx->unspec_fd = -1;
- return -1;
- }
-#endif
-
- if (setsockopt(ctx->unspec_fd, IPPROTO_ICMPV6, ICMP6_FILTER,
- &filt, sizeof(filt)) == -1)
- goto eexit;
- memset(&su, 0, sizeof(su));
- su.sin.sin6_family = AF_INET6;
-#ifdef SIN6_LEN
- su.sin.sin6_len = sizeof(su.sin);
-#endif
- if (bind(ctx->unspec_fd, &su.sa, sizeof(su.sin)) == -1)
- goto eexit;
-#endif
-
-#ifdef LISTEN_DAD
- if (!ctx->dad_warned) {
- syslog(LOG_WARNING,
- "kernel does not report DAD results to userland");
- syslog(LOG_WARNING,
- "warning listening to duplicated addresses on the wire");
- ctx->dad_warned = 1;
- }
-#endif
-
return ctx->nd_fd;
eexit:
@@ -288,12 +219,6 @@ eexit:
close(ctx->nd_fd);
ctx->nd_fd = -1;
}
-#ifdef IPV6_SEND_DAD
- if (ctx->unpsec_fd != -1) {
- close(ctx->unspec_fd);
- ctx->unspec_fd = -1;
- }
-#endif
return -1;
}
@@ -331,7 +256,6 @@ ipv6nd_sendrsprobe(void *arg)
struct sockaddr_in6 dst;
struct cmsghdr *cm;
struct in6_pktinfo pi;
- int hoplimit = HOPLIMIT;
if (ipv6_linklocal(ifp) == NULL) {
syslog(LOG_DEBUG,
@@ -369,15 +293,6 @@ ipv6nd_sendrsprobe(void *arg)
pi.ipi6_ifindex = ifp->index;
memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
- /* Hop limit */
- cm = CMSG_NXTHDR(&ctx->sndhdr, cm);
- if (cm == NULL) /* unlikely */
- return;
- cm->cmsg_level = IPPROTO_IPV6;
- cm->cmsg_type = IPV6_HOPLIMIT;
- cm->cmsg_len = CMSG_LEN(sizeof(hoplimit));
- memcpy(CMSG_DATA(cm), &hoplimit, sizeof(hoplimit));
-
syslog(LOG_DEBUG, "%s: sending Router Solicitation", ifp->name);
if (sendmsg(ctx->nd_fd, &ctx->sndhdr, 0) == -1) {
syslog(LOG_ERR, "%s: %s: sendmsg: %m", ifp->name, __func__);
@@ -581,16 +496,11 @@ ipv6nd_dadcallback(void *arg)
int wascompleted, found;
wascompleted = (ap->flags & IPV6_AF_DADCOMPLETED);
- ipv6nd_cancelprobeaddr(ap);
ap->flags |= IPV6_AF_DADCOMPLETED;
if (ap->flags & IPV6_AF_DUPLICATED)
/* No idea what how to try and make another address :( */
syslog(LOG_WARNING, "%s: DAD detected %s",
ap->iface->name, ap->saddr);
-#ifdef IPV6_SEND_DAD
- else
- ipv6_addaddr(ap);
-#endif
if (!wascompleted) {
ifp = ap->iface;
@@ -611,7 +521,7 @@ ipv6nd_dadcallback(void *arg)
found = 1;
}
- if (wascompleted && found && rap->lifetime) {
+ if (wascompleted && found) {
syslog(LOG_DEBUG,
"%s: Router Advertisement DAD completed",
rap->iface->name);
@@ -687,11 +597,6 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
}
nd_ra = (struct nd_router_advert *)icp;
- /* Don't bother doing anything if we don't know about a router
- * expiring */
- if ((rap == NULL || rap->lifetime == 0)
- && nd_ra->nd_ra_router_lifetime == 0)
- return;
/* We don't want to spam the log with the fact we got an RA every
* 30 seconds or so, so only spam the log if it's different. */
@@ -860,13 +765,13 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
ntohl(pi->nd_opt_pi_preferred_time);
ap->nsprobes = 0;
if (opt) {
- l = strlen(opt);
- tmp = realloc(opt,
- l + strlen(ap->saddr) + 2);
+ l = strlen(opt) + 1;
+ m = strlen(ap->saddr) + 1;
+ tmp = realloc(opt, l + m);
if (tmp) {
opt = tmp;
- opt[l] = ' ';
- strcpy(opt + l + 1, ap->saddr);
+ opt[l - 1] = ' ';
+ strlcpy(opt + l, ap->saddr, m);
}
} else
opt = strdup(ap->saddr);
@@ -1001,14 +906,10 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
script_runreason(ifp, "TEST");
goto handle_flag;
}
- ipv6nd_probeaddrs(&rap->addrs);
+ ipv6_addaddrs(&rap->addrs);
ipv6_buildroutes(ifp->ctx);
-
- /* We will get run by the expire function */
- if (rap->lifetime) {
- if (ipv6nd_scriptrun(rap))
- return;
- }
+ if (ipv6nd_scriptrun(rap))
+ return;
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
eloop_timeout_delete(ifp->ctx->eloop, NULL, rap); /* reachable timer */
@@ -1025,15 +926,13 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
handle_flag:
if (rap->flags & ND_RA_FLAG_MANAGED) {
- if (rap->lifetime && new_data &&
- dhcp6_start(ifp, DH6S_INIT) == -1)
+ if (new_data && dhcp6_start(ifp, DH6S_INIT) == -1)
syslog(LOG_ERR, "dhcp6_start: %s: %m", ifp->name);
} else if (rap->flags & ND_RA_FLAG_OTHER) {
- if (rap->lifetime && new_data &&
- dhcp6_start(ifp, DH6S_INFORM) == -1)
+ if (new_data && dhcp6_start(ifp, DH6S_INFORM) == -1)
syslog(LOG_ERR, "dhcp6_start: %s: %m", ifp->name);
} else {
- if (rap->lifetime && new_data)
+ if (new_data)
syslog(LOG_DEBUG, "%s: No DHCPv6 instruction in RA",
ifp->name);
if (ifp->ctx->options & DHCPCD_TEST) {
@@ -1132,24 +1031,25 @@ ipv6nd_env(char **env, const char *prefi
if (new) {
**var = new;
new = strchr(**var, '=');
- if (new)
- strcpy(new + 1,
- rao->option);
- else
+ if (new) {
+ len -= (new - **var);
+ strlcpy(new + 1,
+ rao->option,
+ len - 1);
+ } else
syslog(LOG_ERR,
"new is null");
}
continue;
}
- new = realloc(**var,
- strlen(**var) + 1 +
- strlen(rao->option) + 1);
+ len = strlen(rao->option) + 1;
+ new = realloc(**var, strlen(**var) + 1 + len);
if (new == NULL)
return -1;
**var = new;
new += strlen(new);
*new++ = ' ';
- strcpy(new, rao->option);
+ strlcpy(new, rao->option, len);
continue;
}
if (env) {
@@ -1202,26 +1102,29 @@ ipv6nd_expirera(void *arg)
TAILQ_FOREACH_SAFE(rap, ifp->ctx->ipv6->ra_routers, next, ran) {
if (rap->iface != ifp)
continue;
- lt.tv_sec = rap->lifetime;
- lt.tv_usec = 0;
- timeradd(&rap->received, <, &expire);
- if (rap->lifetime == 0 || timercmp(&now, &expire, >)) {
- valid = 0;
- if (!rap->expired) {
- syslog(LOG_WARNING,
- "%s: %s: router expired",
- ifp->name, rap->sfrom);
- rap->expired = expired = 1;
- ipv6nd_cancelproberouter(rap);
+ valid = 0;
+ if (rap->lifetime) {
+ lt.tv_sec = rap->lifetime;
+ lt.tv_usec = 0;
+ timeradd(&rap->received, <, &expire);
+ if (rap->lifetime == 0 || timercmp(&now, &expire, >)) {
+ if (!rap->expired) {
+ syslog(LOG_WARNING,
+ "%s: %s: router expired",
+ ifp->name, rap->sfrom);
+ rap->expired = expired = 1;
+ ipv6nd_cancelproberouter(rap);
+ }
+ } else {
+ valid = 1;
+ timersub(&expire, &now, <);
+ if (!timerisset(&next) ||
+ timercmp(&next, <, >))
+ next = lt;
}
- } else {
- valid = 1;
- timersub(&expire, &now, <);
- if (!timerisset(&next) || timercmp(&next, <, >))
- next = lt;
}
- /* Addresses are expired in ipv6ns_probeaddrs
+ /* 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) {
@@ -1332,201 +1235,6 @@ ipv6nd_unreachable(void *arg)
&tv, ipv6nd_proberouter, rap);
}
-#ifdef LISTEN_DAD
-void
-ipv6nd_cancelprobeaddr(struct ipv6_addr *ap)
-{
-
- eloop_timeout_delete(ap->iface->ctx->eloop, ipv6nd_probeaddr, ap);
- if (ap->dadcallback)
- eloop_timeout_delete(ap->iface->ctx->eloop, ap->dadcallback,ap);
-}
-#endif
-
-void
-ipv6nd_probeaddr(void *arg)
-{
- struct ipv6_addr *ap = arg;
-#ifdef IPV6_SEND_DAD
- struct nd_neighbor_solicit *ns;
- struct nd_opt_hdr *nd;
- struct sockaddr_in6 dst;
- struct cmsghdr *cm;
- struct in6_pktinfo pi;
- int hoplimit = HOPLIMIT;
-#else
-#ifdef LISTEN_DAD
- struct timeval tv, rtv;
- struct timeval mtv;
- int i;
-#endif
-#endif
-
- if (ap->dadcallback &&
- ((ap->flags & IPV6_AF_NEW) == 0 ||
- ap->nsprobes >= ap->iface->options->dadtransmits))
- {
-#ifdef IPV6_SEND_DAD
- ap->dadcallback(ap);
-#else
- if (!(ap->flags & IPV6_AF_AUTOCONF) ||
- ap->iface->options->options & DHCPCD_IPV6RA_OWN)
- ipv6_addaddr(ap);
-#endif
- return;
- }
-
- if (ipv6nd_open(ap->iface->ctx) == -1) {
- syslog(LOG_ERR, "%s: ipv6nd_open: %m", __func__);
- return;
- }
-
- ap->flags &= ~IPV6_AF_DADCOMPLETED;
-
-#ifdef IPV6_SEND_DAD
- if (!ap->ns) {
- ap->nslen = sizeof(*ns) + ROUNDUP8(ap->iface->hwlen + 2);
- ap->ns = calloc(1, ap->nslen);
- if (ap->ns == NULL) {
- syslog(LOG_ERR, "%s: %m", __func__);
- return;
- }
- ns = (struct nd_neighbor_solicit *)(void *)ap->ns;
- ns->nd_ns_type = ND_NEIGHBOR_SOLICIT;
- //ns->nd_ns_cksum = 0;
- //ns->nd_ns_code = 0;
- //ns->nd_ns_reserved = 0;
- ns->nd_ns_target = ap->addr;
- nd = (struct nd_opt_hdr *)(ap->ns + sizeof(*ns));
- nd->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
- nd->nd_opt_len = (ROUNDUP8(ap->iface->hwlen + 2)) >> 3;
- memcpy(nd + 1, ap->iface->hwaddr, ap->iface->hwlen);
- }
-
- memset(&dst, 0, sizeof(dst));
- dst.sin6_family = AF_INET6;
-#ifdef SIN6_LEN
- dst.sin6_len = sizeof(dst);
-#endif
- dst.sin6_addr.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
- dst.sin6_addr.s6_addr16[1] = 0;
- dst.sin6_addr.s6_addr32[1] = 0;
- dst.sin6_addr.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
- dst.sin6_addr.s6_addr32[3] = ap->addr.s6_addr32[3];
- dst.sin6_addr.s6_addr[12] = 0xff;
-
- //memcpy(&dst.sin6_addr, &ap->addr, sizeof(dst.sin6_addr));
- dst.sin6_scope_id = ap->iface->index;
-
- ctx = ap->iface->ctx->ipv6;
- ctx->sndhdr.msg_name = (caddr_t)&dst;
- ctx->sndhdr.msg_iov[0].iov_base = ap->ns;
- ctx->sndhdr.msg_iov[0].iov_len = ap->nslen;
-
- /* Set the outbound interface */
- cm = CMSG_FIRSTHDR(&ctx->sndhdr);
- if (cm == NULL) /* unlikely */
- return;
- cm->cmsg_level = IPPROTO_IPV6;
- cm->cmsg_type = IPV6_PKTINFO;
- cm->cmsg_len = CMSG_LEN(sizeof(pi));
- memset(&pi, 0, sizeof(pi));
- pi.ipi6_ifindex = ap->iface->index;
- memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
-
- /* Hop limit */
- cm = CMSG_NXTHDR(&sndhdr, cm);
- if (cm == NULL) /* unlikely */
- return;
- cm->cmsg_level = IPPROTO_IPV6;
- cm->cmsg_type = IPV6_HOPLIMIT;
- cm->cmsg_len = CMSG_LEN(sizeof(hoplimit));
- memcpy(CMSG_DATA(cm), &hoplimit, sizeof(hoplimit));
-
-#ifdef DEBUG_NS
- syslog(LOG_INFO, "%s: sending IPv6 NS for %s",
- ap->iface->name, ap->saddr);
- if (ap->dadcallback == NULL)
- syslog(LOG_WARNING, "%s: no callback!", ap->iface->name);
-#endif
- if (sendmsg(unspec_sock, &sndhdr, 0) == -1) {
- syslog(LOG_ERR, "%s: %s: sendmsg: %m",
- ap->iface->name, __func__);
- return;
- }
-
- if (ap->dadcallback) {
- ms_to_tv(&tv, RETRANS_TIMER);
- ms_to_tv(&rtv, MIN_RANDOM_FACTOR);
- timeradd(&tv, &rtv, &tv);
- rtv.tv_sec = 0;
- rtv.tv_usec = arc4random() %
- (MAX_RANDOM_FACTOR_U - MIN_RANDOM_FACTOR_U);
- timeradd(&tv, &rtv, &tv);
-
- eloop_timeout_add_tv(ap->iface->ctx->eloop, &tv,
- ++(ap->nsprobes) < ap->iface->options->dadtransmits ?
- ipv6nd_probeaddr : ap->dadcallback,
- ap);
- }
-#else /* IPV6_SEND_DAD */
-
- if (!(ap->flags & IPV6_AF_AUTOCONF) ||
- ap->iface->options->options & DHCPCD_IPV6RA_OWN)
- ipv6_addaddr(ap);
-
-#ifdef LISTEN_DAD
- /* Let the kernel handle DAD.
- * We don't know the timings, so just wait for the max */
- if (ap->dadcallback) {
- mtv.tv_sec = 0;
- mtv.tv_usec = 0;
- for (i = 0; i < ap->iface->options->dadtransmits; i++) {
- ms_to_tv(&tv, RETRANS_TIMER);
- ms_to_tv(&rtv, MAX_RANDOM_FACTOR);
- timeradd(&tv, &rtv, &tv);
- timeradd(&mtv, &tv, &mtv);
- }
- eloop_timeout_add_tv(ap->iface->ctx->eloop,
- &mtv, ap->dadcallback, ap);
- }
-#endif
-#endif /* IPV6_SEND_DAD */
-}
-
-ssize_t
-ipv6nd_probeaddrs(struct ipv6_addrhead *addrs)
-{
- struct ipv6_addr *ap, *apn;
- ssize_t i;
-
- i = 0;
- TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
- if (ap->prefix_vltime == 0) {
- TAILQ_REMOVE(addrs, ap, next);
- if (ap->flags & IPV6_AF_ADDED) {
- syslog(LOG_INFO, "%s: deleting address %s",
- ap->iface->name, ap->saddr);
- i++;
- if (!IN6_IS_ADDR_UNSPECIFIED(&ap->addr) &&
- del_address6(ap) == -1 &&
- errno != EADDRNOTAVAIL && errno != ENXIO)
- syslog(LOG_ERR, "del_address6 %m");
- }
- if (ap->dadcallback)
- eloop_q_timeout_delete(ap->iface->ctx->eloop,
- 0, NULL, ap->dadcallback);
- free(ap);
- } else if (!IN6_IS_ADDR_UNSPECIFIED(&ap->addr)) {
- ipv6nd_probeaddr(ap);
- if (ap->flags & IPV6_AF_NEW)
- i++;
- }
- }
-
- return i;
-}
-
void
ipv6nd_proberouter(void *arg)
{
@@ -1536,7 +1244,6 @@ ipv6nd_proberouter(void *arg)
struct sockaddr_in6 dst;
struct cmsghdr *cm;
struct in6_pktinfo pi;
- int hoplimit = HOPLIMIT;
struct timeval tv, rtv;
struct ipv6_ctx *ctx;
@@ -1588,15 +1295,6 @@ ipv6nd_proberouter(void *arg)
pi.ipi6_ifindex = rap->iface->index;
memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
- /* Hop limit */
- cm = CMSG_NXTHDR(&ctx->sndhdr, cm);
- if (cm == NULL) /* unlikely */
- return;
- cm->cmsg_level = IPPROTO_IPV6;
- cm->cmsg_type = IPV6_HOPLIMIT;
- cm->cmsg_len = CMSG_LEN(sizeof(hoplimit));
- memcpy(CMSG_DATA(cm), &hoplimit, sizeof(hoplimit));
-
#ifdef DEBUG_NS
syslog(LOG_INFO, "%s: sending IPv6 NS for %s",
rap->iface->name, rap->sfrom);
@@ -1636,16 +1334,8 @@ ipv6nd_handlena(struct ipv6_ctx *ctx, st
struct nd_neighbor_advert *nd_na;
struct ra *rap;
int is_router, is_solicited;
-#ifdef DEBUG_NS
- int found;
-#endif
struct timeval tv;
-#ifdef LISTEN_DAD
- struct dhcp6_state *d6state;
- struct ipv6_addr *ap;
-#endif
-
if ((size_t)len < sizeof(struct nd_neighbor_advert)) {
syslog(LOG_ERR, "IPv6 NA packet too short from %s", ctx->sfrom);
return;
@@ -1669,55 +1359,16 @@ ipv6nd_handlena(struct ipv6_ctx *ctx, st
return;
}
-#ifdef DEBUG_NS
- found = 0;
-#endif
TAILQ_FOREACH(rap, ctx->ra_routers, next) {
- if (rap->iface != ifp)
- continue;
- if (memcmp(rap->from.s6_addr, nd_na->nd_na_target.s6_addr,
+ if (rap->iface == ifp &&
+ memcmp(rap->from.s6_addr, nd_na->nd_na_target.s6_addr,
sizeof(rap->from.s6_addr)) == 0)
break;
-#ifdef LISTEN_DAD
- TAILQ_FOREACH(ap, &rap->addrs, next) {
- if (memcmp(ap->addr.s6_addr,
- nd_na->nd_na_target.s6_addr,
- sizeof(ap->addr.s6_addr)) == 0)
- {
- ap->flags |= IPV6_AF_DUPLICATED;
- if (ap->dadcallback)
- ap->dadcallback(ap);
-#ifdef DEBUG_NS
- found++;
-#endif
- }
- }
-#endif
}
if (rap == NULL) {
-#ifdef LISTEN_DAD
- d6state = D6_STATE(ifp);
- if (d6state) {
- TAILQ_FOREACH(ap, &d6state->addrs, next) {
- if (memcmp(ap->addr.s6_addr,
- nd_na->nd_na_target.s6_addr,
- sizeof(ap->addr.s6_addr)) == 0)
- {
- ap->flags |= IPV6_AF_DUPLICATED;
- if (ap->dadcallback)
- ap->dadcallback(ap);
-#ifdef DEBUG_NS
- found++;
-#endif
- }
- }
- }
-#endif
-
#ifdef DEBUG_NS
- if (found == 0)
- syslog(LOG_DEBUG, "%s: unexpected NA from %s",
- ifp->name, ctx->sfrom);
+ syslog(LOG_DEBUG, "%s: unexpected NA from s",
+ ifp->name, ctx->sfrom);
#endif
return;
}
@@ -1774,6 +1425,8 @@ ipv6nd_handledata(void *arg)
dhcpcd_ctx = arg;
ctx = dhcpcd_ctx->ipv6;
+ ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
+ CMSG_SPACE(sizeof(int));
len = recvmsg(ctx->nd_fd, &ctx->rcvhdr, 0);
if (len == -1) {
syslog(LOG_ERR, "recvmsg: %m");
Index: src/external/bsd/dhcpcd/dist/net.c
diff -u src/external/bsd/dhcpcd/dist/net.c:1.5 src/external/bsd/dhcpcd/dist/net.c:1.6
--- src/external/bsd/dhcpcd/dist/net.c:1.5 Tue Feb 25 13:20:23 2014
+++ src/external/bsd/dhcpcd/dist/net.c Fri Mar 14 11:31:11 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: net.c,v 1.5 2014/02/25 13:20:23 roy Exp $");
+ __RCSID("$NetBSD: net.c,v 1.6 2014/03/14 11:31:11 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -253,13 +253,26 @@ discover_interfaces(struct dhcpcd_ctx *c
#endif
#ifdef AF_LINK
const struct sockaddr_dl *sdl;
+#ifdef SIOCGIFPRIORITY
+ struct ifreq ifr;
+ int s_inet;
+#endif
#ifdef IFLR_ACTIVE
struct if_laddrreq iflr;
- int socket_aflink;
+ int s_link;
+#endif
- socket_aflink = socket(AF_LINK, SOCK_DGRAM, 0);
- if (socket_aflink == -1)
+#ifdef SIOCGIFPRIORITY
+ if ((s_inet = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ return NULL;
+#endif
+#ifdef IFLR_ACTIVE
+ if ((s_link = socket(AF_LINK, SOCK_DGRAM, 0)) == -1) {
+#ifdef SIOCGIFPRIORITY
+ close(s_inet);
+#endif
return NULL;
+ }
memset(&iflr, 0, sizeof(iflr));
#endif
#elif AF_PACKET
@@ -268,7 +281,6 @@ discover_interfaces(struct dhcpcd_ctx *c
if (getifaddrs(&ifaddrs) == -1)
return NULL;
-
ifs = malloc(sizeof(*ifs));
if (ifs == NULL)
return NULL;
@@ -342,8 +354,10 @@ discover_interfaces(struct dhcpcd_ctx *c
}
ifp = calloc(1, sizeof(*ifp));
- if (ifp == NULL)
- return NULL;
+ if (ifp == NULL) {
+ syslog(LOG_ERR, "%s: %m", __func__);
+ break;
+ }
ifp->ctx = ctx;
strlcpy(ifp->name, p, sizeof(ifp->name));
ifp->flags = ifa->ifa_flags;
@@ -381,7 +395,7 @@ discover_interfaces(struct dhcpcd_ctx *c
MIN(ifa->ifa_addr->sa_len, sizeof(iflr.addr)));
iflr.flags = IFLR_PREFIX;
iflr.prefixlen = sdl->sdl_alen * NBBY;
- if (ioctl(socket_aflink, SIOCGLIFADDR, &iflr) == -1 ||
+ if (ioctl(s_link, SIOCGLIFADDR, &iflr) == -1 ||
!(iflr.flags & IFLR_ACTIVE))
{
free_interface(ifp);
@@ -466,6 +480,13 @@ discover_interfaces(struct dhcpcd_ctx *c
continue;
}
+#ifdef SIOCGIFPRIORITY
+ /* Respect the interface priority */
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+ if (ioctl(s_inet, SIOCGIFPRIORITY, &ifr) == 0)
+ ifp->metric = ifr.ifr_metric;
+#else
/* We reserve the 100 range for virtual interfaces, if and when
* we can work them out. */
ifp->metric = 200 + ifp->index;
@@ -473,6 +494,7 @@ discover_interfaces(struct dhcpcd_ctx *c
ifp->wireless = 1;
ifp->metric += 100;
}
+#endif
TAILQ_INSERT_TAIL(ifs, ifp, next);
}
@@ -515,8 +537,11 @@ discover_interfaces(struct dhcpcd_ctx *c
freeifaddrs(ifaddrs);
+#ifdef SIOCGIFPRIORITY
+ close(s_inet);
+#endif
#ifdef IFLR_ACTIVE
- close(socket_aflink);
+ close(s_link);
#endif
return ifs;