Module Name:    src
Committed By:   martin
Date:           Thu Jun  7 18:34:03 UTC 2018

Modified Files:
        src/doc [netbsd-8]: 3RDPARTY
        src/external/bsd/dhcpcd/dist [netbsd-8]: Makefile
        src/external/bsd/dhcpcd/dist/src [netbsd-8]: arp.c auth.c auth.h bpf.c
            defs.h dhcp.c dhcp.h dhcp6.c dhcp6.h dhcpcd-definitions.conf
            dhcpcd.8.in dhcpcd.c dhcpcd.conf.5.in if-bsd.c if-linux.c
            if-options.c ipv4ll.h ipv6.c ipv6.h ipv6nd.c ipv6nd.h route.c

Log Message:
Catch up to current in src/external/bsd/dhcpcd/dist, requested
by roy in ticket #849:

external/bsd/dhcpcd/dist/Makefile               up to 1.1.1.5
external/bsd/dhcpcd/dist/src/arp.c              up to 1.1.1.7
external/bsd/dhcpcd/dist/src/auth.c             up to 1.1.1.5
external/bsd/dhcpcd/dist/src/auth.h             up to 1.1.1.3
external/bsd/dhcpcd/dist/src/bpf.c              up to 1.7
external/bsd/dhcpcd/dist/src/defs.h             up to 1.1.1.13
external/bsd/dhcpcd/dist/src/dhcp.c             up to 1.11
external/bsd/dhcpcd/dist/src/dhcp.h             up to 1.1.1.6
external/bsd/dhcpcd/dist/src/dhcp6.c            up to 1.1.1.12
external/bsd/dhcpcd/dist/src/dhcp6.h            up to 1.1.1.6
external/bsd/dhcpcd/dist/src/dhcpcd-definitions.conf up to 1.1.1.2
external/bsd/dhcpcd/dist/src/dhcpcd.8.in        up to 1.1.1.9
external/bsd/dhcpcd/dist/src/dhcpcd.c           up to 1.12
external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in   up to 1.1.1.9
external/bsd/dhcpcd/dist/src/if-bsd.c           up to 1.1.1.8
external/bsd/dhcpcd/dist/src/if-linux.c         up to 1.1.1.9
external/bsd/dhcpcd/dist/src/if-options.c       up to 1.10
external/bsd/dhcpcd/dist/src/ipv4ll.h           up to 1.1.1.4
external/bsd/dhcpcd/dist/src/ipv6.c             up to 1.1.1.10
external/bsd/dhcpcd/dist/src/ipv6.h             up to 1.1.1.7
external/bsd/dhcpcd/dist/src/ipv6nd.c           up to 1.1.1.8
external/bsd/dhcpcd/dist/src/ipv6nd.h           up to 1.1.1.6
external/bsd/dhcpcd/dist/src/route.c            up to 1.1.1.7
doc/3RDPARTY                                    (manually modified)

Import dhcpcd 7.0.5b.

Changes:
 * Routing: Fix case when cloning route changes but needs to be replaced
 * DHCP6: Transpose DHCP userclass option into DHCP6
 * DHCP6: Fix sending custom vendor class option
 * Auth: Allow zero value replay detection data
 * Auth: Allow different tokens for send and receive
 * ND6: Warn if router lifetime is set to zero
 * DHCP6: Softwire Address and Port-Mapped Clients, RFC7598
 *  dhcp: Clarified some checksumming code, style and commentary
    (thanks to Maxime Villard)
 *  dhcp6: IAID is now unique per IA type rather than global
 *  ip6: if an IA callback causes a fork, exit earlier


To generate a diff of this commit:
cvs rdiff -u -r1.1444.2.11 -r1.1444.2.12 src/doc/3RDPARTY
cvs rdiff -u -r1.1.1.4 -r1.1.1.4.2.1 src/external/bsd/dhcpcd/dist/Makefile
cvs rdiff -u -r1.1.1.2.8.2 -r1.1.1.2.8.3 \
    src/external/bsd/dhcpcd/dist/src/arp.c \
    src/external/bsd/dhcpcd/dist/src/ipv6nd.c
cvs rdiff -u -r1.1.1.1.8.1 -r1.1.1.1.8.2 \
    src/external/bsd/dhcpcd/dist/src/auth.c \
    src/external/bsd/dhcpcd/dist/src/auth.h
cvs rdiff -u -r1.3.8.1 -r1.3.8.2 src/external/bsd/dhcpcd/dist/src/bpf.c
cvs rdiff -u -r1.1.1.4.2.2 -r1.1.1.4.2.3 \
    src/external/bsd/dhcpcd/dist/src/defs.h \
    src/external/bsd/dhcpcd/dist/src/dhcp6.c \
    src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in \
    src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in
cvs rdiff -u -r1.1.1.3.8.3 -r1.1.1.3.8.4 \
    src/external/bsd/dhcpcd/dist/src/dhcp.c
cvs rdiff -u -r1.1.1.1.8.2 -r1.1.1.1.8.3 \
    src/external/bsd/dhcpcd/dist/src/dhcp.h \
    src/external/bsd/dhcpcd/dist/src/dhcp6.h \
    src/external/bsd/dhcpcd/dist/src/ipv6nd.h
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.8.1 \
    src/external/bsd/dhcpcd/dist/src/dhcpcd-definitions.conf
cvs rdiff -u -r1.4.2.2 -r1.4.2.3 src/external/bsd/dhcpcd/dist/src/dhcpcd.c \
    src/external/bsd/dhcpcd/dist/src/if-options.c
cvs rdiff -u -r1.1.1.3.2.2 -r1.1.1.3.2.3 \
    src/external/bsd/dhcpcd/dist/src/if-bsd.c \
    src/external/bsd/dhcpcd/dist/src/if-linux.c \
    src/external/bsd/dhcpcd/dist/src/ipv6.c \
    src/external/bsd/dhcpcd/dist/src/route.c
cvs rdiff -u -r1.1.1.2.8.1 -r1.1.1.2.8.2 \
    src/external/bsd/dhcpcd/dist/src/ipv4ll.h
cvs rdiff -u -r1.1.1.2.2.2 -r1.1.1.2.2.3 \
    src/external/bsd/dhcpcd/dist/src/ipv6.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/doc/3RDPARTY
diff -u src/doc/3RDPARTY:1.1444.2.11 src/doc/3RDPARTY:1.1444.2.12
--- src/doc/3RDPARTY:1.1444.2.11	Sun May  6 09:42:38 2018
+++ src/doc/3RDPARTY	Thu Jun  7 18:34:03 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: 3RDPARTY,v 1.1444.2.11 2018/05/06 09:42:38 martin Exp $
+#	$NetBSD: 3RDPARTY,v 1.1444.2.12 2018/06/07 18:34:03 martin Exp $
 #
 # This file contains a list of the software that has been integrated into
 # NetBSD where we are not the primary maintainer.
@@ -334,8 +334,8 @@ Notes:
 Use the dhcp2netbsd script.
 
 Package:	dhcpcd
-Version:	7.0.0
-Current Vers:	7.0.0
+Version:	7.0.5b
+Current Vers:	7.0.5b
 Maintainer:	roy
 Archive Site:	ftp://roy.marples.name/pub/dhcpcd/
 Home Page:	http://roy.marples.name/projects/dhcpcd/

Index: src/external/bsd/dhcpcd/dist/Makefile
diff -u src/external/bsd/dhcpcd/dist/Makefile:1.1.1.4 src/external/bsd/dhcpcd/dist/Makefile:1.1.1.4.2.1
--- src/external/bsd/dhcpcd/dist/Makefile:1.1.1.4	Wed May 10 11:00:37 2017
+++ src/external/bsd/dhcpcd/dist/Makefile	Thu Jun  7 18:34:03 2018
@@ -8,7 +8,8 @@ DIST!=		if test -f .fslckout; then echo 
 FOSSILID?=	current
 GITREF?=	HEAD
 
-DISTPREFIX?=	dhcpcd-${VERSION}
+DISTSUFFIX=
+DISTPREFIX?=	dhcpcd-${VERSION}${DISTSUFFIX}
 DISTFILEGZ?=	${DISTPREFIX}.tar.gz
 DISTFILE?=	${DISTPREFIX}.tar.xz
 DISTINFO=	${DISTFILE}.distinfo

Index: src/external/bsd/dhcpcd/dist/src/arp.c
diff -u src/external/bsd/dhcpcd/dist/src/arp.c:1.1.1.2.8.2 src/external/bsd/dhcpcd/dist/src/arp.c:1.1.1.2.8.3
--- src/external/bsd/dhcpcd/dist/src/arp.c:1.1.1.2.8.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/arp.c	Thu Jun  7 18:34:03 2018
@@ -128,13 +128,16 @@ arp_packet(struct interface *ifp, uint8_
 	/* Protocol must be IP. */
 	if (ar.ar_pro != htons(ETHERTYPE_IP))
 		continue;
-	/* Only these types are recognised */
-	if (ar.ar_op != htons(ARPOP_REPLY) &&
-	    ar.ar_op != htons(ARPOP_REQUEST))
+	/* lladdr length matches */
+	if (ar.ar_hln != ifp->hwlen)
 		continue;
 	/* Protocol length must match in_addr_t */
 	if (ar.ar_pln != sizeof(arm.sip.s_addr))
 		return;
+	/* Only these types are recognised */
+	if (ar.ar_op != htons(ARPOP_REPLY) &&
+	    ar.ar_op != htons(ARPOP_REQUEST))
+		continue;
 #endif
 
 	/* Get pointers to the hardware addresses */
Index: src/external/bsd/dhcpcd/dist/src/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.1.1.2.8.2 src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.1.1.2.8.3
--- src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.1.1.2.8.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/ipv6nd.c	Thu Jun  7 18:34:03 2018
@@ -749,7 +749,8 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, 
 	struct in6_addr pi_prefix;
 	struct ipv6_addr *ap;
 	struct dhcp_opt *dho;
-	uint8_t new_rap, new_data;
+	bool new_rap, new_data;
+	uint32_t old_lifetime;
 	__printflike(1, 2) void (*logfunc)(const char *, ...);
 #ifdef IPV6_MANAGETEMPADDR
 	uint8_t new_ap;
@@ -764,25 +765,25 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, 
 	}
 
 	if (len < sizeof(struct nd_router_advert)) {
-		logerr("IPv6 RA packet too short from %s", ctx->sfrom);
+		logerrx("IPv6 RA packet too short from %s", ctx->sfrom);
 		return;
 	}
 
 	/* RFC 4861 7.1.2 */
 	if (hoplimit != 255) {
-		logerr("invalid hoplimit(%d) in RA from %s",
+		logerrx("invalid hoplimit(%d) in RA from %s",
 		    hoplimit, ctx->sfrom);
 		return;
 	}
 
 	if (!IN6_IS_ADDR_LINKLOCAL(&ctx->from.sin6_addr)) {
-		logerr("RA from non local address %s", ctx->sfrom);
+		logerrx("RA from non local address %s", ctx->sfrom);
 		return;
 	}
 
 	if (!(ifp->options->options & DHCPCD_IPV6RS)) {
 #ifdef DEBUG_RS
-		logerr("%s: unexpected RA from %s",
+		logerrx("%s: unexpected RA from %s",
 		    ifp->name, ctx->sfrom);
 #endif
 		return;
@@ -820,9 +821,9 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, 
 			free(rap->data);
 			rap->data_len = 0;
 		}
-		new_data = 1;
+		new_data = true;
 	} else
-		new_data = 0;
+		new_data = false;
 	if (rap == NULL) {
 		rap = calloc(1, sizeof(*rap));
 		if (rap == NULL) {
@@ -833,9 +834,9 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, 
 		rap->from = ctx->from.sin6_addr;
 		strlcpy(rap->sfrom, ctx->sfrom, sizeof(rap->sfrom));
 		TAILQ_INIT(&rap->addrs);
-		new_rap = 1;
+		new_rap = true;
 	} else
-		new_rap = 0;
+		new_rap = false;
 	if (rap->data_len == 0) {
 		rap->data = malloc(len);
 		if (rap->data == NULL) {
@@ -858,7 +859,11 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, 
 
 	clock_gettime(CLOCK_MONOTONIC, &rap->acquired);
 	rap->flags = nd_ra->nd_ra_flags_reserved;
+	old_lifetime = rap->lifetime;
 	rap->lifetime = ntohs(nd_ra->nd_ra_router_lifetime);
+	if (!new_rap && rap->lifetime == 0 && old_lifetime != 0)
+		logwarnx("%s: %s: no longer a default router",
+		    ifp->name, rap->sfrom);
 	if (nd_ra->nd_ra_reachable) {
 		rap->reachable = ntohl(nd_ra->nd_ra_reachable);
 		if (rap->reachable > MAX_REACHABLE_TIME)
@@ -1529,9 +1534,6 @@ ipv6nd_handledata(void *arg)
 	len = recvmsg_realloc(ctx->nd_fd, &ctx->rcvhdr, 0);
 	if (len == -1) {
 		logerr(__func__);
-		eloop_event_delete(ctx->eloop, ctx->nd_fd);
-		close(ctx->nd_fd);
-		ctx->nd_fd = -1;
 		return;
 	}
 	ctx->sfrom = inet_ntop(AF_INET6, &ctx->from.sin6_addr,

Index: src/external/bsd/dhcpcd/dist/src/auth.c
diff -u src/external/bsd/dhcpcd/dist/src/auth.c:1.1.1.1.8.1 src/external/bsd/dhcpcd/dist/src/auth.c:1.1.1.1.8.2
--- src/external/bsd/dhcpcd/dist/src/auth.c:1.1.1.1.8.1	Sat Jan 13 21:35:30 2018
+++ src/external/bsd/dhcpcd/dist/src/auth.c	Thu Jun  7 18:34:03 2018
@@ -151,7 +151,24 @@ dhcp_auth_validate(struct authstate *sta
 
 	memcpy(&replay, d, sizeof(replay));
 	replay = ntohll(replay);
-	if (state->token) {
+	/*
+	 * Test for a replay attack.
+	 *
+	 * NOTE: Some servers always send a replay data value of zero.
+	 * This is strictly compliant with RFC 3315 and 3318 which say:
+	 * "If the RDM field contains 0x00, the replay detection field MUST be
+	 *    set to the value of a monotonically increasing counter."
+	 * An example of a monotonically increasing sequence is:
+	 * 1, 2, 2, 2, 2, 2, 2
+	 * Errata 3474 updates RFC 3318 to say:
+	 * "If the RDM field contains 0x00, the replay detection field MUST be
+	 *    set to the value of a strictly increasing counter."
+	 *
+	 * Taking the above into account, dhcpcd will only test for
+	 * strictly speaking replay attacks if it receives any non zero
+	 * replay data to validate against.
+	 */
+	if (state->token && state->replay != 0) {
 		if (state->replay == (replay ^ 0x8000000000000000ULL)) {
 			/* We don't know if the singular point is increasing
 			 * or decreasing. */
@@ -174,7 +191,7 @@ dhcp_auth_validate(struct authstate *sta
 	 * Rest of data is MAC. */
 	switch (protocol) {
 	case AUTH_PROTO_TOKEN:
-		secretid = 0;
+		secretid = auth->token_rcv_secretid;
 		break;
 	case AUTH_PROTO_DELAYED:
 		if (dlen < sizeof(secretid) + sizeof(hmac_code)) {
@@ -182,6 +199,7 @@ dhcp_auth_validate(struct authstate *sta
 			return NULL;
 		}
 		memcpy(&secretid, d, sizeof(secretid));
+		secretid = ntohl(secretid);
 		d += sizeof(secretid);
 		dlen -= sizeof(secretid);
 		break;
@@ -197,6 +215,7 @@ dhcp_auth_validate(struct authstate *sta
 			dlen -= realm_len;
 		}
 		memcpy(&secretid, d, sizeof(secretid));
+		secretid = ntohl(secretid);
 		d += sizeof(secretid);
 		dlen -= sizeof(secretid);
 		break;
@@ -266,7 +285,6 @@ dhcp_auth_validate(struct authstate *sta
 	}
 
 	/* Find a token for the realm and secret */
-	secretid = ntohl(secretid);
 	TAILQ_FOREACH(t, &auth->tokens, next) {
 		if (t->secretid == secretid &&
 		    t->realm_len == realm_len &&
@@ -478,14 +496,16 @@ dhcp_auth_encode(struct auth *auth, cons
 	uint64_t rdm;
 	uint8_t hmac_code[HMAC_LENGTH];
 	time_t now;
-	uint8_t hops, *p, info, *m, *data;
+	uint8_t hops, *p, *m, *data;
 	uint32_t giaddr, secretid;
+	bool auth_info;
 
-	if (auth->protocol == 0 && t == NULL) {
+	/* Ignore the token argument given to us - always send using the
+	 * configured token. */
+	if (auth->protocol == AUTH_PROTO_TOKEN) {
 		TAILQ_FOREACH(t, &auth->tokens, next) {
-			if (t->secretid == 0 &&
-			    t->realm_len == 0)
-			break;
+			if (t->secretid == auth->token_snd_secretid)
+				break;
 		}
 		if (t == NULL) {
 			errno = EINVAL;
@@ -532,9 +552,9 @@ dhcp_auth_encode(struct auth *auth, cons
 	/* DISCOVER or INFORM messages don't write auth info */
 	if ((mp == 4 && (mt == DHCP_DISCOVER || mt == DHCP_INFORM)) ||
 	    (mp == 6 && (mt == DHCP6_SOLICIT || mt == DHCP6_INFORMATION_REQ)))
-		info = 0;
+		auth_info = false;
 	else
-		info = 1;
+		auth_info = true;
 
 	/* Work out the auth area size.
 	 * We only need to do this for DISCOVER messages */
@@ -545,11 +565,11 @@ dhcp_auth_encode(struct auth *auth, cons
 			dlen += t->key_len;
 			break;
 		case AUTH_PROTO_DELAYEDREALM:
-			if (info && t)
+			if (auth_info && t)
 				dlen += t->realm_len;
 			/* FALLTHROUGH */
 		case AUTH_PROTO_DELAYED:
-			if (info && t)
+			if (auth_info && t)
 				dlen += sizeof(t->secretid) + sizeof(hmac_code);
 			break;
 		}
@@ -572,18 +592,32 @@ dhcp_auth_encode(struct auth *auth, cons
 	/* Write out our option */
 	*data++ = auth->protocol;
 	*data++ = auth->algorithm;
-	*data++ = auth->rdm;
-	switch (auth->rdm) {
-	case AUTH_RDM_MONOTONIC:
-		rdm = get_next_rdm_monotonic(auth);
-		break;
-	default:
-		/* This block appeases gcc, clang doesn't need it */
-		rdm = get_next_rdm_monotonic(auth);
-		break;
+	/*
+	 * RFC 3315 21.4.4.1 says that SOLICIT in DELAYED authentication
+	 * should not set RDM or it's data.
+	 * An expired draft draft-ietf-dhc-dhcpv6-clarify-auth-01 suggets
+	 * this should not be set for INFORMATION REQ messages as well,
+	 * which is probably a good idea because both states start from zero.
+	 */
+	if (auth_info ||
+	    !(auth->protocol & (AUTH_PROTO_DELAYED | AUTH_PROTO_DELAYEDREALM)))
+	{
+		*data++ = auth->rdm;
+		switch (auth->rdm) {
+		case AUTH_RDM_MONOTONIC:
+			rdm = get_next_rdm_monotonic(auth);
+			break;
+		default:
+			/* This block appeases gcc, clang doesn't need it */
+			rdm = get_next_rdm_monotonic(auth);
+			break;
+		}
+		rdm = htonll(rdm);
+		memcpy(data, &rdm, 8);
+	} else {
+		*data++ = 0;		/* rdm */
+		memset(data, 0, 8);	/* replay detection data */
 	}
-	rdm = htonll(rdm);
-	memcpy(data, &rdm, 8);
 	data += 8;
 	dlen -= 1 + 1 + 1 + 8;
 
@@ -603,7 +637,7 @@ dhcp_auth_encode(struct auth *auth, cons
 	}
 
 	/* DISCOVER or INFORM messages don't write auth info */
-	if (!info)
+	if (!auth_info)
 		return (ssize_t)dlen;
 
 	/* Loading a saved lease without an authentication option */
Index: src/external/bsd/dhcpcd/dist/src/auth.h
diff -u src/external/bsd/dhcpcd/dist/src/auth.h:1.1.1.1.8.1 src/external/bsd/dhcpcd/dist/src/auth.h:1.1.1.1.8.2
--- src/external/bsd/dhcpcd/dist/src/auth.h:1.1.1.1.8.1	Sat Jan 13 21:35:30 2018
+++ src/external/bsd/dhcpcd/dist/src/auth.h	Thu Jun  7 18:34:03 2018
@@ -71,6 +71,8 @@ struct auth {
 	uint64_t last_replay;
 	uint8_t last_replay_set;
 	struct token_head tokens;
+	uint32_t token_snd_secretid;
+	uint32_t token_rcv_secretid;
 #endif
 };
 

Index: src/external/bsd/dhcpcd/dist/src/bpf.c
diff -u src/external/bsd/dhcpcd/dist/src/bpf.c:1.3.8.1 src/external/bsd/dhcpcd/dist/src/bpf.c:1.3.8.2
--- src/external/bsd/dhcpcd/dist/src/bpf.c:1.3.8.1	Sat Jan 13 21:35:30 2018
+++ src/external/bsd/dhcpcd/dist/src/bpf.c	Thu Jun  7 18:34:03 2018
@@ -108,7 +108,7 @@ bpf_open(struct interface *ifp, int (*fi
 	size_t buf_len;
 	struct bpf_version pv;
 #ifdef BIOCIMMEDIATE
-	int flags;
+	unsigned int flags;
 #endif
 #ifndef O_CLOEXEC
 	int fd_opts;
@@ -411,7 +411,7 @@ static const struct bpf_insn bpf_arp_eth
 	/* Make sure the hardware length matches. */
 	BPF_STMT(BPF_LD + BPF_B + BPF_IND, offsetof(struct arphdr, ar_hln)),
 	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
-	         sizeof((struct ether_arp *)0)->arp_sha, 1, 0),
+	         sizeof(((struct ether_arp *)0)->arp_sha), 1, 0),
 	BPF_STMT(BPF_RET + BPF_K, 0),
 };
 #define bpf_arp_ether_len	__arraycount(bpf_arp_ether)
@@ -540,7 +540,7 @@ static const struct bpf_insn bpf_bootp_e
 #define BPF_BOOTP_ETHER_LEN	__arraycount(bpf_bootp_ether)
 
 static const struct bpf_insn bpf_bootp_filter[] = {
-	/* Make sure it's an IPv4 packet. */
+	/* Make sure it's an optionless IPv4 packet. */
 	BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0),
 	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x45, 1, 0),
 	BPF_STMT(BPF_RET + BPF_K, 0),

Index: src/external/bsd/dhcpcd/dist/src/defs.h
diff -u src/external/bsd/dhcpcd/dist/src/defs.h:1.1.1.4.2.2 src/external/bsd/dhcpcd/dist/src/defs.h:1.1.1.4.2.3
--- src/external/bsd/dhcpcd/dist/src/defs.h:1.1.1.4.2.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/defs.h	Thu Jun  7 18:34:03 2018
@@ -28,7 +28,7 @@
 #define CONFIG_H
 
 #define PACKAGE			"dhcpcd"
-#define VERSION			"7.0.3"
+#define VERSION			"7.0.5"
 
 #ifndef CONFIG
 # define CONFIG			SYSCONFDIR "/" PACKAGE ".conf"
Index: src/external/bsd/dhcpcd/dist/src/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.1.1.4.2.2 src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.1.1.4.2.3
--- src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.1.1.4.2.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/dhcp6.c	Thu Jun  7 18:34:03 2018
@@ -98,6 +98,11 @@ struct dhcp6_ia_na {
 };
 __CTASSERT(sizeof(struct dhcp6_ia_na) == 12);
 
+struct dhcp6_ia_ta {
+	uint8_t iaid[4];
+};
+__CTASSERT(sizeof(struct dhcp6_ia_ta) == 4);
+
 struct dhcp6_ia_addr {
 	struct in6_addr addr;
 	uint32_t pltime;
@@ -194,6 +199,48 @@ dhcp6_printoptions(const struct dhcpcd_c
 }
 
 static size_t
+dhcp6_makeuser(void *data, const struct interface *ifp)
+{
+	const struct if_options *ifo = ifp->options;
+	struct dhcp6_option o;
+	uint8_t *p;
+	const uint8_t *up, *ue;
+	uint16_t ulen, unlen;
+	size_t olen;
+
+	/* Convert the DHCPv4 user class option to DHCPv6 */
+	up = ifo->userclass;
+	ulen = *up++;
+	if (ulen == 0)
+		return 0;
+
+	p = data;
+	olen = 0;
+	if (p != NULL)
+		p += sizeof(o);
+
+	ue = up + ulen;
+	for (; up < ue; up += ulen) {
+		ulen = *up++;
+		olen += sizeof(ulen) + ulen;
+		if (data == NULL)
+			continue;
+		unlen = htons(ulen);
+		memcpy(p, &unlen, sizeof(unlen));
+		p += sizeof(unlen);
+		memcpy(p, up, ulen);
+		p += ulen;
+	}
+	if (data != NULL) {
+		o.code = htons(D6_OPTION_USER_CLASS);
+		o.len = htons((uint16_t)olen);
+		memcpy(data, &o, sizeof(o));
+	}
+
+	return sizeof(o) + olen;
+}
+
+static size_t
 dhcp6_makevendor(void *data, const struct interface *ifp)
 {
 	const struct if_options *ifo;
@@ -245,7 +292,7 @@ dhcp6_makevendor(void *data, const struc
 			{
 				hvlen = htons((uint16_t)vivco->len);
 				memcpy(p, &hvlen, sizeof(hvlen));
-				p += sizeof(len);
+				p += sizeof(hvlen);
 				memcpy(p, vivco->data, vivco->len);
 				p += vivco->len;
 			}
@@ -437,20 +484,18 @@ again:
 
 #ifndef SMALL
 static const struct if_sla *
-dhcp6_findselfsla(struct interface *ifp, const uint8_t *iaid)
+dhcp6_findselfsla(struct interface *ifp)
 {
 	size_t i, j;
+	struct if_ia *ia;
 
 	for (i = 0; i < ifp->options->ia_len; i++) {
-		if (iaid == NULL ||
-		    memcmp(&ifp->options->ia[i].iaid, iaid,
-		    sizeof(ifp->options->ia[i].iaid)) == 0)
-		{
-			for (j = 0; j < ifp->options->ia[i].sla_len; j++) {
-				if (strcmp(ifp->options->ia[i].sla[j].ifname,
-				    ifp->name) == 0)
-					return &ifp->options->ia[i].sla[j];
-			}
+		ia = &ifp->options->ia[i];
+		if (ia->ia_type != D6_OPTION_IA_PD)
+			continue;
+		for (j = 0; j < ia->sla_len; j++) {
+			if (strcmp(ia->sla[j].ifname, ifp->name) == 0)
+				return &ia->sla[j];
 		}
 	}
 	return NULL;
@@ -587,6 +632,7 @@ dhcp6_makemessage(struct interface *ifp)
 	int fqdn;
 	struct dhcp6_ia_na ia_na;
 	uint16_t ia_na_len;
+	struct if_ia *ifia;
 #ifdef AUTH
 	uint16_t auth_len;
 #endif
@@ -651,7 +697,7 @@ dhcp6_makemessage(struct interface *ifp)
 				len += sizeof(o.len);
 			}
 		}
-		if (dhcp6_findselfsla(ifp, NULL)) {
+		if (dhcp6_findselfsla(ifp)) {
 			n_options++;
 			len += sizeof(o.len);
 		}
@@ -677,6 +723,8 @@ dhcp6_makemessage(struct interface *ifp)
 	len += sizeof(*state->send);
 	len += sizeof(o) + ifp->ctx->duid_len;
 	len += sizeof(o) + sizeof(uint16_t); /* elapsed */
+	if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS))
+		len += dhcp6_makeuser(NULL, ifp);
 	if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
 		len += dhcp6_makevendor(NULL, ifp);
 
@@ -728,7 +776,13 @@ dhcp6_makemessage(struct interface *ifp)
 		}
 		/* FALLTHROUGH */
 	case DH6S_INIT:
-		len += ifo->ia_len * (sizeof(o) + (sizeof(uint32_t) * 3));
+		for (l = 0; l < ifo->ia_len; l++) {
+			ifia = &ifo->ia[l];
+			len += sizeof(o) + sizeof(uint32_t); /* IAID */
+			/* IA_TA does not have T1 or T2 timers */
+			if (ifo->ia[l].ia_type != D6_OPTION_IA_TA)
+				len += sizeof(uint32_t) + sizeof(uint32_t);
+		}
 		IA = 1;
 		break;
 	default:
@@ -844,6 +898,8 @@ dhcp6_makemessage(struct interface *ifp)
 	si_len = 0;
 	COPYIN(D6_OPTION_ELAPSED, &si_len, sizeof(si_len));
 
+	if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS))
+		p += dhcp6_makeuser(p, ifp);
 	if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
 		p += dhcp6_makevendor(p, ifp);
 
@@ -853,19 +909,29 @@ dhcp6_makemessage(struct interface *ifp)
 		COPYIN1(D6_OPTION_RAPID_COMMIT, 0);
 
 	for (l = 0; IA && l < ifo->ia_len; l++) {
+		ifia = &ifo->ia[l];
 		o_lenp = NEXTLEN;
-		ia_na_len = sizeof(ia_na);
-		memcpy(ia_na.iaid, ifo->ia[l].iaid, sizeof(ia_na.iaid));
+		/* TA structure is the same as the others,
+		 * it just lacks the T1 and T2 timers.
+		 * These happen to be at the end of the struct,
+		 * so we just don't copy them in. */
+		if (ifia->ia_type == D6_OPTION_IA_TA)
+			ia_na_len = sizeof(struct dhcp6_ia_ta);
+		else
+			ia_na_len = sizeof(ia_na);
+		memcpy(ia_na.iaid, ifia->iaid, sizeof(ia_na.iaid));
 		ia_na.t1 = 0;
 		ia_na.t2 = 0;
-		COPYIN(ifo->ia[l].ia_type, &ia_na, sizeof(ia_na));
+		COPYIN(ifia->ia_type, &ia_na, ia_na_len);
 		TAILQ_FOREACH(ap, &state->addrs, next) {
 			if (ap->flags & IPV6_AF_STALE)
 				continue;
 			if (ap->prefix_vltime == 0 &&
 			    !(ap->flags & IPV6_AF_REQUEST))
 				continue;
-			if (memcmp(ifo->ia[l].iaid, ap->iaid, sizeof(uint32_t)))
+			if (ap->ia_type != ifia->ia_type)
+				continue;
+			if (memcmp(ap->iaid, ifia->iaid, sizeof(ap->iaid)))
 				continue;
 			if (ap->ia_type == D6_OPTION_IA_PD) {
 #ifndef SMALL
@@ -1008,7 +1074,7 @@ dhcp6_makemessage(struct interface *ifp)
 					    (o.len + sizeof(o.code));
 				}
 			}
-			if (dhcp6_findselfsla(ifp, NULL)) {
+			if (dhcp6_findselfsla(ifp)) {
 				o.code = htons(D6_OPTION_PD_EXCLUDE);
 				memcpy(p, &o.code, sizeof(o.code));
 				p += sizeof(o.code);
@@ -2149,6 +2215,7 @@ dhcp6_findia(struct interface *ifp, stru
 	uint8_t iaid[4];
 	char buf[sizeof(iaid) * 3];
 	struct ipv6_addr *ap;
+	struct if_ia *ifia;
 
 	if (l < sizeof(*m)) {
 		/* Should be impossible with guards at packet in
@@ -2202,8 +2269,9 @@ dhcp6_findia(struct interface *ifp, stru
 		o.len = (uint16_t)(o.len - nl);
 
 		for (j = 0; j < ifo->ia_len; j++) {
-			if (memcmp(&ifo->ia[j].iaid, ia.iaid,
-			    sizeof(ia.iaid)) == 0)
+			ifia = &ifo->ia[j];
+			if (ifia->ia_type == o.code &&
+			    memcmp(ifia->iaid, ia.iaid, sizeof(ia.iaid)) == 0)
 				break;
 		}
 		if (j == ifo->ia_len &&
@@ -2215,13 +2283,6 @@ dhcp6_findia(struct interface *ifp, stru
 			    buf, sizeof(buf)));
 			continue;
 		}
-		if ( j < ifo->ia_len && ifo->ia[j].ia_type != o.code) {
-			logerrx("%s: IAID %s: option type mismatch",
-			    ifp->name,
-			    hwaddr_ntoa(ia.iaid, sizeof(ia.iaid),
-			    buf, sizeof(buf)));
-			continue;
-		}
 
 		if (o.code != D6_OPTION_IA_TA) {
 			ia.t1 = ntohl(ia.t1);
@@ -2727,6 +2788,8 @@ dhcp6_delegate_prefix(struct interface *
 			}
 			for (i = 0; i < ifo->ia_len; i++) {
 				ia = &ifo->ia[i];
+				if (ia->ia_type != D6_OPTION_IA_PD)
+					continue;
 				if (memcmp(ia->iaid, ap->iaid,
 				    sizeof(ia->iaid)))
 					continue;
@@ -2823,6 +2886,8 @@ dhcp6_find_delegates(struct interface *i
 				continue;
 			for (i = 0; i < ifo->ia_len; i++) {
 				ia = &ifo->ia[i];
+				if (ia->ia_type != D6_OPTION_IA_PD)
+					continue;
 				if (memcmp(ia->iaid, ap->iaid,
 				    sizeof(ia->iaid)))
 					continue;
@@ -3410,13 +3475,6 @@ dhcp6_recv(struct dhcpcd_ctx *ctx, struc
 	bytes = recvmsg_realloc(s, &ctx->rcvhdr, 0);
 	if (bytes == -1) {
 		logerr("%s: recvmsg_realloc", __func__);
-		close(s);
-		eloop_event_delete(ctx->eloop, s);
-		if (ia != NULL)
-			ia->dhcp6_fd = -1;
-		else
-			ctx->dhcp6_fd = -1;
-		eloop_exit(ctx->eloop, 1);
 		return;
 	}
 	len = (size_t)bytes;
@@ -3607,6 +3665,8 @@ dhcp6_activateinterfaces(struct interfac
 
 	for (i = 0; i < ifp->options->ia_len; i++) {
 		ia = &ifp->options->ia[i];
+		if (ia->ia_type != D6_OPTION_IA_PD)
+			continue;
 		for (j = 0; j < ia->sla_len; j++) {
 			sla = &ia->sla[j];
 			ifd = if_find(ifp->ctx->ifaces, sla->ifname);
@@ -3663,7 +3723,7 @@ dhcp6_start1(void *arg)
 
 #ifndef SMALL
 	/* Rapid commit won't work with Prefix Delegation Exclusion */
-	if (dhcp6_findselfsla(ifp, NULL))
+	if (dhcp6_findselfsla(ifp))
 		del_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT);
 #endif
 
Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.1.1.4.2.2 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.1.1.4.2.3
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.1.1.4.2.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in	Thu Jun  7 18:34:03 2018
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd January 8, 2018
+.Dd April 29, 2018
 .Dt DHCPCD 8
 .Os
 .Sh NAME
@@ -753,6 +753,17 @@ to rebind, reconfigure or exit need to i
 so that
 .Nm
 knows which process to signal.
+.Pp
+Some DHCP servers implement ClientID filtering.
+If
+.Nm
+is replacing an in-use DHCP client then you might need to adjust the clientid
+option
+.Nm
+sends to match.
+If using a DUID in place of the ClientID, edit
+.Pa @DBDIR@/duid
+accordingly.
 .Sh FILES
 .Bl -ohang
 .It Pa @SYSCONFDIR@/dhcpcd.conf
Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in:1.1.1.4.2.2 src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in:1.1.1.4.2.3
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in:1.1.1.4.2.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in	Thu Jun  7 18:34:03 2018
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd February 2, 2018
+.Dd May 3, 2018
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -74,9 +74,16 @@ Example:
 .D1 # A generic 192.168.0.1 network
 .D1 profile 192.168.0.1
 .D1 static ip_address=192.168.0.98/24
-.It Ic authprotocol Ar protocol Ar algorithm Ar rdm
+.It Ic authprotocol Ar protocol Op Ar algorithm Op Ar rdm
 Authenticate DHCP messages.
 See the Supported Authentication Protocols section.
+If
+.Ar protocol
+is
+.Ar token
+then
+.Ar algorithm is
+snd_secretid/rcv_secretid so you can send and recieve different tokens.
 .It Ic authtoken Ar secretid Ar realm Ar expire Ar key
 Define a shared key for use in authentication.
 .Ar realm
@@ -378,7 +385,8 @@ interface eth0
 Only configure IPv4.
 .It Ic ipv6only
 Only configure IPv6.
-.It Ic fqdn Op disable | ptr | both
+.It Ic fqdn Op disable | none | ptr | both
+none will not ask the DHCP server to update DNS.
 ptr just asks the DHCP server to update the PTR
 record of the host in DNS whereas both also updates the A record.
 disable will disable the FQDN option.
@@ -863,7 +871,11 @@ References an option from the global def
 .Ss Supported Authentication Protocols
 .Bl -tag -width -indent
 .It Ic token
-Sends and expects the token with the secretid 0 and realm of "" in each message.
+Sends a plain text token the server expects and matches a token sent by
+the server.
+The tokens to not have to be the same.
+If unspecified, the token with secretid of 0 will be used in sending messages
+and validating received messages.
 .It Ic delayedrealm
 Delayed Authentication.
 .Nm dhcpcd

Index: src/external/bsd/dhcpcd/dist/src/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcp.c:1.1.1.3.8.3 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.1.1.3.8.4
--- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.1.1.3.8.3	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/dhcp.c	Thu Jun  7 18:34:03 2018
@@ -2101,8 +2101,10 @@ dhcp_arp_probed(struct arp_state *astate
 	if (ifp->ctx->options & DHCPCD_FORKED)
 		return;
 
+#ifdef IPV4LL
 	/* Stop IPv4LL now we have a working DHCP address */
 	ipv4ll_drop(ifp);
+#endif
 
 	if (ifo->options & DHCPCD_INFORM)
 		dhcp_inform(ifp);
@@ -3276,7 +3278,7 @@ valid_udp_packet(void *data, size_t data
 	struct bootp_pkt *p;
 	uint16_t bytes;
 
-	if (data_len < sizeof(p->ip) + sizeof(p->udp)) {
+	if (data_len < sizeof(p->ip)) {
 		if (from)
 			from->s_addr = INADDR_ANY;
 		errno = ERANGE;
@@ -3291,6 +3293,12 @@ valid_udp_packet(void *data, size_t data
 	}
 
 	bytes = ntohs(p->ip.ip_len);
+	/* Check we have a payload */
+	if (bytes <= sizeof(p->ip) + sizeof(p->udp)) {
+		errno = ERANGE;
+		return -1;
+	}
+	/* Check we don't go beyond the payload */
 	if (bytes > data_len) {
 		errno = ENOBUFS;
 		return -1;
@@ -3334,7 +3342,7 @@ dhcp_handlepacket(struct interface *ifp,
 			     state->bpf_flags & RAW_PARTIALCSUM) == -1)
 	{
 		if (errno == EINVAL)
-			logerrx("%s: UDP checksum failure from %s",
+			logerrx("%s: checksum failure from %s",
 			  ifp->name, inet_ntoa(from));
 		else
 			logerr("%s: invalid UDP packet from %s",

Index: src/external/bsd/dhcpcd/dist/src/dhcp.h
diff -u src/external/bsd/dhcpcd/dist/src/dhcp.h:1.1.1.1.8.2 src/external/bsd/dhcpcd/dist/src/dhcp.h:1.1.1.1.8.3
--- src/external/bsd/dhcpcd/dist/src/dhcp.h:1.1.1.1.8.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/dhcp.h	Thu Jun  7 18:34:03 2018
@@ -267,7 +267,6 @@ void dhcp_close(struct interface *);
 void dhcp_free(struct interface *);
 int dhcp_dump(struct interface *);
 #else
-#define dhcp_drop(a, b) {}
 #define dhcp_start(a) {}
 #define dhcp_abort(a) {}
 #define dhcp_renew(a) {}
Index: src/external/bsd/dhcpcd/dist/src/dhcp6.h
diff -u src/external/bsd/dhcpcd/dist/src/dhcp6.h:1.1.1.1.8.2 src/external/bsd/dhcpcd/dist/src/dhcp6.h:1.1.1.1.8.3
--- src/external/bsd/dhcpcd/dist/src/dhcp6.h:1.1.1.1.8.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/dhcp6.h	Thu Jun  7 18:34:03 2018
@@ -67,6 +67,7 @@
 #define D6_OPTION_UNICAST		12
 #define D6_OPTION_STATUS_CODE		13
 #define D6_OPTION_RAPID_COMMIT		14
+#define D6_OPTION_USER_CLASS		15
 #define D6_OPTION_VENDOR_CLASS		16
 #define D6_OPTION_VENDOR_OPTS		17
 #define D6_OPTION_INTERFACE_ID		18
@@ -244,7 +245,6 @@ int dhcp6_dump(struct interface *);
 #define dhcp6_renew(a) {}
 #define dhcp6_env(a, b, c, d, e) (0)
 #define dhcp6_free(a) {}
-#define dhcp6_handleifa(a, b) {}
 #define dhcp6_dadcompleted(a) (0)
 #define dhcp6_drop(a, b) {}
 #define dhcp6_dropnondelegates(a) {}
Index: src/external/bsd/dhcpcd/dist/src/ipv6nd.h
diff -u src/external/bsd/dhcpcd/dist/src/ipv6nd.h:1.1.1.1.8.2 src/external/bsd/dhcpcd/dist/src/ipv6nd.h:1.1.1.1.8.3
--- src/external/bsd/dhcpcd/dist/src/ipv6nd.h:1.1.1.1.8.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/ipv6nd.h	Thu Jun  7 18:34:03 2018
@@ -107,7 +107,6 @@ void ipv6nd_neighbour(struct dhcpcd_ctx 
 #define ipv6nd_free(a) {}
 #define ipv6nd_hasra(a) (0)
 #define ipv6nd_dadcompleted(a) (0)
-#define ipv6nd_drop(a) {}
 #define ipv6nd_expire(a, b) {}
 #endif
 

Index: src/external/bsd/dhcpcd/dist/src/dhcpcd-definitions.conf
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd-definitions.conf:1.1.1.1 src/external/bsd/dhcpcd/dist/src/dhcpcd-definitions.conf:1.1.1.1.8.1
--- src/external/bsd/dhcpcd/dist/src/dhcpcd-definitions.conf:1.1.1.1	Fri Mar 31 20:51:15 2017
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd-definitions.conf	Thu Jun  7 18:34:03 2018
@@ -579,6 +579,37 @@ define6 80	ip6address		link_address
 define6 82	request uint32		sol_max_rt
 define6	83	request uint32		inf_max_rt
 
+# DHCPv6 Softwire Address and Port-Mapped Clients, RFC7598
+define6	89	embed			s46_rule
+embed		bitflags=0000000F	flags
+embed		byte			ea_len
+embed		byte			prefix4_len
+embed		ipaddress		ipv4_prefix
+embed		ip6address		ipv6_prefix
+define6	90	ip6address		s64_br
+define6	91	embed			s46_dmr
+embed		byte			prefix_len
+embed		binhex			prefix
+define6	92	embed			s46_v4v6bind
+embed		ipaddress		ipv4_address
+embed		byte			ipv6_prefix_len
+embed		binhex			ipv6_prefix_and_options
+# Cannot decode options after variable length address ...
+#encap	93	option
+define6	93	embed			s46_portparams
+embed		byte			offset
+embed		byte			psid_len
+embed		uint16			psid
+define6	94	embed			s46_cont_mape
+encap	89	option
+encap	90	option
+define6	95	embed			s46_cont_mapt
+encap	89	option
+encap	91	option
+define6	96	embed			s46_cont_lw
+encap	90	option
+encap	92	option
+
 # DHCPv6 Address Selection Policy
 # Currently not supported
 

Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.4.2.2 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.4.2.3
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.4.2.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c	Thu Jun  7 18:34:03 2018
@@ -363,14 +363,25 @@ static void
 dhcpcd_drop(struct interface *ifp, int stop)
 {
 
+#ifdef DHCP6
 	dhcp6_drop(ifp, stop ? NULL : "EXPIRE6");
+#endif
+#ifdef INET6
 	ipv6nd_drop(ifp);
 	ipv6_drop(ifp);
+#endif
+#ifdef IPV4LL
 	ipv4ll_drop(ifp);
+#endif
+#ifdef DHCP
 	dhcp_drop(ifp, stop ? "STOP" : "EXPIRE");
+#endif
 #ifdef ARP
 	arp_drop(ifp);
 #endif
+#if !defined(DHCP6) && !defined(DHCP)
+	UNUSED(stop);
+#endif
 }
 
 static void
@@ -770,22 +781,29 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *
 }
 
 static void
-warn_iaid_conflict(struct interface *ifp, uint8_t *iaid)
+warn_iaid_conflict(struct interface *ifp, uint16_t ia_type, uint8_t *iaid)
 {
 	struct interface *ifn;
+#ifdef INET6
 	size_t i;
+	struct if_ia *ia;
+#endif
 
 	TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
 		if (ifn == ifp || !ifn->active)
 			continue;
-		if (memcmp(ifn->options->iaid, iaid,
+		if (ia_type == 0 &&
+		    memcmp(ifn->options->iaid, iaid,
 		    sizeof(ifn->options->iaid)) == 0)
 			break;
+#ifdef INET6
 		for (i = 0; i < ifn->options->ia_len; i++) {
-			if (memcmp(&ifn->options->ia[i].iaid, iaid,
-			    sizeof(ifn->options->ia[i].iaid)) == 0)
+			ia = &ifn->options->ia[i];
+			if (ia->ia_type == ia_type &&
+			    memcmp(ia->iaid, iaid, sizeof(ia->iaid)) == 0)
 				break;
 		}
+#endif
 	}
 
 	/* This is only a problem if the interfaces are on the same network. */
@@ -799,7 +817,6 @@ dhcpcd_startinterface(void *arg)
 {
 	struct interface *ifp = arg;
 	struct if_options *ifo = ifp->options;
-	size_t i;
 	char buf[DUID_LEN * 3];
 	int carrier;
 	struct timespec tv;
@@ -839,22 +856,28 @@ dhcpcd_startinterface(void *arg)
 	}
 
 	if (ifo->options & (DHCPCD_DUID | DHCPCD_IPV6)) {
+#ifdef INET6
+		size_t i;
+		struct if_ia *ia;
+#endif
+
 		/* Report IAIDs */
 		loginfox("%s: IAID %s", ifp->name,
 		    hwaddr_ntoa(ifo->iaid, sizeof(ifo->iaid),
 		    buf, sizeof(buf)));
-		warn_iaid_conflict(ifp, ifo->iaid);
+		warn_iaid_conflict(ifp, 0, ifo->iaid);
+#ifdef INET6
 		for (i = 0; i < ifo->ia_len; i++) {
-			if (memcmp(ifo->iaid, ifo->ia[i].iaid,
-			    sizeof(ifo->iaid)))
-			{
-				loginfox("%s: IAID %s",
-				    ifp->name, hwaddr_ntoa(ifo->ia[i].iaid,
-				    sizeof(ifo->ia[i].iaid),
+			ia = &ifo->ia[i];
+			if (memcmp(ifo->iaid, ia->iaid, sizeof(ifo->iaid))) {
+				loginfox("%s: IA type %u IAID %s",
+				    ifp->name, ia->ia_type,
+				    hwaddr_ntoa(ia->iaid, sizeof(ia->iaid),
 				    buf, sizeof(buf)));
-				warn_iaid_conflict(ifp, ifo->ia[i].iaid);
+				warn_iaid_conflict(ifp, ia->ia_type, ia->iaid);
 			}
 		}
+#endif
 	}
 
 	if (ifo->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) {
Index: src/external/bsd/dhcpcd/dist/src/if-options.c
diff -u src/external/bsd/dhcpcd/dist/src/if-options.c:1.4.2.2 src/external/bsd/dhcpcd/dist/src/if-options.c:1.4.2.3
--- src/external/bsd/dhcpcd/dist/src/if-options.c:1.4.2.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/if-options.c	Thu Jun  7 18:34:03 2018
@@ -1360,6 +1360,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
 		for (sl = 0; sl < ifo->ia_len; sl++) {
 			if ((arg == NULL && !ifo->ia[sl].iaid_set) ||
 			    (arg != NULL && ifo->ia[sl].iaid_set &&
+			    ifo->ia[sl].ia_type == (uint16_t)i &&
 			    ifo->ia[sl].iaid[0] == iaid[0] &&
 			    ifo->ia[sl].iaid[1] == iaid[1] &&
 			    ifo->ia[sl].iaid[2] == iaid[2] &&
@@ -1369,10 +1370,6 @@ parse_option(struct dhcpcd_ctx *ctx, con
 				break;
 			}
 		}
-		if (ia && ia->ia_type != (uint16_t)i) {
-			logerrx("Cannot mix IA for the same IAID");
-			break;
-		}
 		if (ia == NULL) {
 			ia = reallocarray(ifo->ia,
 			    ifo->ia_len + 1, sizeof(*ifo->ia));
@@ -1850,6 +1847,7 @@ err_sla:
 			logerrx("invalid code: %s", arg);
 			return -1;
 		}
+		fp = strskipwhite(fp);
 		if (fp) {
 			s = parse_string(NULL, 0, fp);
 			if (s == -1) {
@@ -1912,12 +1910,32 @@ err_sla:
 		}
 		if (fp)
 			*fp++ = '\0';
-		if (strcasecmp(arg, "hmacmd5") == 0 ||
-		    strcasecmp(arg, "hmac-md5") == 0)
-			ifo->auth.algorithm = AUTH_ALG_HMAC_MD5;
-		else {
-			logerrx("%s: unsupported algorithm", arg);
-			return 1;
+		if (ifo->auth.protocol == AUTH_PROTO_TOKEN) {
+			np = strchr(arg, '/');
+			if (np) {
+				if (fp == NULL || np < fp)
+					*np++ = '\0';
+				else
+					np = NULL;
+			}
+			if (parse_uint32(&ifo->auth.token_snd_secretid,
+			    arg) == -1)
+				logerrx("%s: not a number", arg);
+			else
+				ifo->auth.token_rcv_secretid =
+				    ifo->auth.token_snd_secretid;
+			if (np &&
+			    parse_uint32(&ifo->auth.token_rcv_secretid,
+			    np) == -1)
+				logerrx("%s: not a number", arg);
+		} else {
+			if (strcasecmp(arg, "hmacmd5") == 0 ||
+			    strcasecmp(arg, "hmac-md5") == 0)
+				ifo->auth.algorithm = AUTH_ALG_HMAC_MD5;
+			else {
+				logerrx("%s: unsupported algorithm", arg);
+				return 1;
+			}
 		}
 		arg = fp;
 		if (arg == NULL) {

Index: src/external/bsd/dhcpcd/dist/src/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.1.1.3.2.2 src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.1.1.3.2.3
--- src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.1.1.3.2.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/if-bsd.c	Thu Jun  7 18:34:03 2018
@@ -496,13 +496,12 @@ if_route(unsigned char cmd, const struct
 
 		rtm->rtm_flags |= RTF_UP;
 		rtm->rtm_addrs |= RTA_GATEWAY;
-#ifdef RTA_LABEL
-		rtm->rtm_addrs |= RTA_LABEL;
-#endif
 		if (!(rtm->rtm_flags & RTF_REJECT) &&
 		    !sa_is_loopback(&rt->rt_gateway))
 		{
-			rtm->rtm_addrs |= RTA_IFP;
+			rtm->rtm_index = (unsigned short)rt->rt_ifp->index;
+			if (!gateway_unspec)
+				rtm->rtm_addrs |= RTA_IFP;
 			if (!sa_is_unspecified(&rt->rt_ifa))
 				rtm->rtm_addrs |= RTA_IFA;
 		}
@@ -574,10 +573,8 @@ if_route(unsigned char cmd, const struct
 	if (rtm->rtm_addrs & RTA_NETMASK)
 		ADDSA(&rt->rt_netmask);
 
-	if (rtm->rtm_addrs & RTA_IFP) {
-		rtm->rtm_index = (unsigned short)rt->rt_ifp->index;
+	if (rtm->rtm_addrs & RTA_IFP)
 		ADDSA((struct sockaddr *)&sdl);
-	}
 
 	if (rtm->rtm_addrs & RTA_IFA)
 		ADDSA(&rt->rt_ifa);
Index: src/external/bsd/dhcpcd/dist/src/if-linux.c
diff -u src/external/bsd/dhcpcd/dist/src/if-linux.c:1.1.1.3.2.2 src/external/bsd/dhcpcd/dist/src/if-linux.c:1.1.1.3.2.3
--- src/external/bsd/dhcpcd/dist/src/if-linux.c:1.1.1.3.2.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/if-linux.c	Thu Jun  7 18:34:03 2018
@@ -652,23 +652,6 @@ l2addr_len(unsigned short if_type)
 	return 0;
 }
 
-static int
-handle_rename(struct dhcpcd_ctx *ctx, unsigned int ifindex, const char *ifname)
-{
-	struct interface *ifp;
-
-	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-		if (ifp->index == ifindex && strcmp(ifp->name, ifname)) {
-			dhcpcd_handleinterface(ctx, -1, ifp->name);
-			/* Let dev announce the interface for renaming */
-			if (!dev_listening(ctx))
-				dhcpcd_handleinterface(ctx, 1, ifname);
-			return 1;
-		}
-	}
-	return 0;
-}
-
 #ifdef INET6
 static int
 link_neigh(struct dhcpcd_ctx *ctx, __unused struct interface *ifp,
@@ -770,7 +753,10 @@ link_netlink(struct dhcpcd_ctx *ctx, str
 	}
 
 	if (nlm->nlmsg_type == RTM_DELLINK) {
-		dhcpcd_handleinterface(ctx, -1, ifn);
+		/* If are listening to a dev manager, let that remove
+		 * the interface rather than the kernel. */
+		if (dev_listening(ctx) < 1)
+			dhcpcd_handleinterface(ctx, -1, ifn);
 		return 0;
 	}
 
@@ -783,12 +769,9 @@ link_netlink(struct dhcpcd_ctx *ctx, str
 		return 0;
 	}
 
-	/* Check for interface name change */
-	if (handle_rename(ctx, (unsigned int)ifi->ifi_index, ifn))
-		return 0;
-
 	/* Check for a new interface */
-	if ((ifp = if_find(ctx->ifaces, ifn)) == NULL) {
+	ifp = if_findindex(ctx->ifaces, (unsigned int)ifi->ifi_index);
+	if (ifp == NULL) {
 		/* If are listening to a dev manager, let that announce
 		 * the interface rather than the kernel. */
 		if (dev_listening(ctx) < 1)
@@ -796,6 +779,13 @@ link_netlink(struct dhcpcd_ctx *ctx, str
 		return 0;
 	}
 
+	/* Handle interface being renamed */
+	if (strcmp(ifp->name, ifn) != 0) {
+		dhcpcd_handleinterface(ctx, -1, ifn);
+		dhcpcd_handleinterface(ctx, 1, ifn);
+		return 0;
+	}
+
 	/* Re-read hardware address and friends */
 	if (!(ifi->ifi_flags & IFF_UP) && hwaddr) {
 		uint8_t l;
Index: src/external/bsd/dhcpcd/dist/src/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/src/ipv6.c:1.1.1.3.2.2 src/external/bsd/dhcpcd/dist/src/ipv6.c:1.1.1.3.2.3
--- src/external/bsd/dhcpcd/dist/src/ipv6.c:1.1.1.3.2.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/ipv6.c	Thu Jun  7 18:34:03 2018
@@ -1152,8 +1152,11 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
 			}
 #endif
 
-			if (ia->dadcallback)
+			if (ia->dadcallback) {
 				ia->dadcallback(ia);
+				if (ctx->options & DHCPCD_FORKED)
+					goto out;
+			}
 
 			if (IN6_IS_ADDR_LINKLOCAL(&ia->addr) &&
 			    !(ia->addr_flags & IN6_IFF_NOTUSEABLE))
@@ -1168,20 +1171,26 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
 					    cb, next);
 					cb->callback(cb->arg);
 					free(cb);
+					if (ctx->options & DHCPCD_FORKED)
+						goto out;
 				}
 			}
 		}
 		break;
 	}
 
-	if (ia != NULL) {
-		ipv6nd_handleifa(cmd, ia, pid);
-		dhcp6_handleifa(cmd, ia, pid);
+	if (ia == NULL)
+		return;
 
-		/* Done with the ia now, so free it. */
-		if (cmd == RTM_DELADDR)
-			ipv6_freeaddr(ia);
-	}
+	ipv6nd_handleifa(cmd, ia, pid);
+#ifdef DHCP6
+	dhcp6_handleifa(cmd, ia, pid);
+#endif
+
+out:
+	/* Done with the ia now, so free it. */
+	if (cmd == RTM_DELADDR)
+		ipv6_freeaddr(ia);
 }
 
 int
Index: src/external/bsd/dhcpcd/dist/src/route.c
diff -u src/external/bsd/dhcpcd/dist/src/route.c:1.1.1.3.2.2 src/external/bsd/dhcpcd/dist/src/route.c:1.1.1.3.2.3
--- src/external/bsd/dhcpcd/dist/src/route.c:1.1.1.3.2.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/route.c	Thu Jun  7 18:34:03 2018
@@ -359,7 +359,7 @@ rt_add(struct rt *nrt, struct rt *ort)
 	 * As such, we need to delete and re-add the route to flush children
 	 * to correct the flags. */
 	if (change && ort != NULL && ort->rt_flags & RTF_CLONING)
-		change = true;
+		change = false;
 #endif
 
 	if (change) {

Index: src/external/bsd/dhcpcd/dist/src/ipv4ll.h
diff -u src/external/bsd/dhcpcd/dist/src/ipv4ll.h:1.1.1.2.8.1 src/external/bsd/dhcpcd/dist/src/ipv4ll.h:1.1.1.2.8.2
--- src/external/bsd/dhcpcd/dist/src/ipv4ll.h:1.1.1.2.8.1	Sat Jan 13 21:35:30 2018
+++ src/external/bsd/dhcpcd/dist/src/ipv4ll.h	Thu Jun  7 18:34:03 2018
@@ -75,7 +75,6 @@ void ipv4ll_freedrop(struct interface *,
 #define	ipv4ll_defaultroute(route, ifp)	(0)
 #define	ipv4ll_handlert(a, b, c)	(0)
 #define	ipv4ll_free(a)			{}
-#define	ipv4ll_drop(a)			{}
 #endif
 
 #endif

Index: src/external/bsd/dhcpcd/dist/src/ipv6.h
diff -u src/external/bsd/dhcpcd/dist/src/ipv6.h:1.1.1.2.2.2 src/external/bsd/dhcpcd/dist/src/ipv6.h:1.1.1.2.2.3
--- src/external/bsd/dhcpcd/dist/src/ipv6.h:1.1.1.2.2.2	Mon Apr  9 16:46:34 2018
+++ src/external/bsd/dhcpcd/dist/src/ipv6.h	Thu Jun  7 18:34:03 2018
@@ -285,7 +285,6 @@ bool inet6_getroutes(struct dhcpcd_ctx *
 #define ipv6_hasaddr(a) (0)
 #define ipv6_free_ll_callbacks(a) {}
 #define ipv6_free(a) {}
-#define ipv6_drop(a) {}
 #define ipv6_ctxfree(a) {}
 #define ipv6_gentempifid(a) {}
 #endif

Reply via email to