Module Name: src
Committed By: roy
Date: Tue Jul 30 10:25:03 UTC 2019
Modified Files:
src/external/bsd/dhcpcd/dist/src: bpf.c dhcp.c dhcp6.c dhcpcd.c
if-bsd.c if-options.c ipv6.c ipv6.h ipv6nd.c
Log Message:
Sync
To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/src/bpf.c \
src/external/bsd/dhcpcd/dist/src/dhcp6.c
cvs rdiff -u -r1.22 -r1.23 src/external/bsd/dhcpcd/dist/src/dhcp.c \
src/external/bsd/dhcpcd/dist/src/dhcpcd.c
cvs rdiff -u -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/src/if-bsd.c \
src/external/bsd/dhcpcd/dist/src/ipv6nd.c
cvs rdiff -u -r1.15 -r1.16 src/external/bsd/dhcpcd/dist/src/if-options.c
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/dhcpcd/dist/src/ipv6.c \
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/external/bsd/dhcpcd/dist/src/bpf.c
diff -u src/external/bsd/dhcpcd/dist/src/bpf.c:1.10 src/external/bsd/dhcpcd/dist/src/bpf.c:1.11
--- src/external/bsd/dhcpcd/dist/src/bpf.c:1.10 Wed Jul 24 09:57:43 2019
+++ src/external/bsd/dhcpcd/dist/src/bpf.c Tue Jul 30 10:25:03 2019
@@ -93,7 +93,7 @@ bpf_frame_header_len(const struct interf
}
}
-static const uint8_t etherbroadcastaddr[] =
+static const uint8_t etherbcastaddr[] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
int
@@ -104,7 +104,7 @@ bpf_frame_bcast(const struct interface *
case ARPHRD_ETHER:
return memcmp(frame +
offsetof(struct ether_header, ether_dhost),
- etherbroadcastaddr, sizeof(etherbroadcastaddr));
+ etherbcastaddr, sizeof(etherbcastaddr));
default:
return -1;
}
@@ -552,6 +552,12 @@ bpf_arp(struct interface *ifp, int fd)
}
#endif
+#define BPF_M_FHLEN 0
+#define BPF_M_IPHLEN 1
+#define BPF_M_IPLEN 2
+#define BPF_M_UDP 3
+#define BPF_M_UDPLEN 4
+
static const struct bpf_insn bpf_bootp_ether[] = {
/* Make sure this is an IP packet. */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS,
@@ -561,16 +567,26 @@ static const struct bpf_insn bpf_bootp_e
/* Load frame header length into X. */
BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, sizeof(struct ether_header)),
- /* Copy to M0. */
- BPF_STMT(BPF_STX, 0),
+ /* Copy frame header length to memory */
+ BPF_STMT(BPF_STX, BPF_M_FHLEN),
};
#define BPF_BOOTP_ETHER_LEN __arraycount(bpf_bootp_ether)
static const struct bpf_insn bpf_bootp_filter[] = {
- /* Make sure it's an optionless IPv4 packet. */
+ /* Make sure it's an IPv4 packet. */
+ BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0),
+ BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0xf0),
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x40, 1, 0),
+ BPF_STMT(BPF_RET + BPF_K, 0),
+
+ /* Ensure IP header length is big enough and
+ * store the IP header length in memory. */
BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0),
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x45, 1, 0),
+ BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x0f),
+ BPF_STMT(BPF_ALU + BPF_MUL + BPF_K, 4),
+ BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ip), 1, 0),
BPF_STMT(BPF_RET + BPF_K, 0),
+ BPF_STMT(BPF_ST, BPF_M_IPHLEN),
/* Make sure it's a UDP packet. */
BPF_STMT(BPF_LD + BPF_B + BPF_IND, offsetof(struct ip, ip_p)),
@@ -582,39 +598,42 @@ static const struct bpf_insn bpf_bootp_f
BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 0, 1),
BPF_STMT(BPF_RET + BPF_K, 0),
- /* Store IP location in M1. */
+ /* Store IP length. */
BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct ip, ip_len)),
- BPF_STMT(BPF_ST, 1),
-
- /* Store IP length in M2. */
- BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct ip, ip_len)),
- BPF_STMT(BPF_ST, 2),
+ BPF_STMT(BPF_ST, BPF_M_IPLEN),
/* Advance to the UDP header. */
- BPF_STMT(BPF_MISC + BPF_TXA, 0),
- BPF_STMT(BPF_ALU + BPF_ADD + BPF_K, sizeof(struct ip)),
+ BPF_STMT(BPF_LD + BPF_MEM, BPF_M_IPHLEN),
+ BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0),
BPF_STMT(BPF_MISC + BPF_TAX, 0),
- /* Store X in M3. */
- BPF_STMT(BPF_STX, 3),
+ /* Store UDP location */
+ BPF_STMT(BPF_STX, BPF_M_UDP),
/* Make sure it's from and to the right port. */
BPF_STMT(BPF_LD + BPF_W + BPF_IND, 0),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (BOOTPS << 16) + BOOTPC, 1, 0),
BPF_STMT(BPF_RET + BPF_K, 0),
- /* Store UDP length in X. */
+ /* Store UDP length. */
BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct udphdr, uh_ulen)),
+ BPF_STMT(BPF_ST, BPF_M_UDPLEN),
+
+ /* Ensure that UDP length + IP header length == IP length */
+ /* Copy IP header length to X. */
+ BPF_STMT(BPF_LDX + BPF_MEM, BPF_M_IPHLEN),
+ /* Add UDP length (A) to IP header length (X). */
+ BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0),
+ /* Store result in X. */
BPF_STMT(BPF_MISC + BPF_TAX, 0),
- /* Copy IP length in M2 to A. */
- BPF_STMT(BPF_LD + BPF_MEM, 2),
- /* Ensure IP length - IP header size == UDP length. */
- BPF_STMT(BPF_ALU + BPF_SUB + BPF_K, sizeof(struct ip)),
+ /* Copy IP length to A. */
+ BPF_STMT(BPF_LD + BPF_MEM, BPF_M_IPLEN),
+ /* Ensure X == A. */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 1, 0),
BPF_STMT(BPF_RET + BPF_K, 0),
- /* Advance to the BOOTP packet (UDP X is in M3). */
- BPF_STMT(BPF_LD + BPF_MEM, 3),
+ /* Advance to the BOOTP packet. */
+ BPF_STMT(BPF_LD + BPF_MEM, BPF_M_UDP),
BPF_STMT(BPF_ALU + BPF_ADD + BPF_K, sizeof(struct udphdr)),
BPF_STMT(BPF_MISC + BPF_TAX, 0),
@@ -695,11 +714,10 @@ bpf_bootp(struct interface *ifp, int fd)
}
#endif
- /* All passed, return the packet
- * (Frame length in M0, IP length in M2). */
- BPF_SET_STMT(bp, BPF_LD + BPF_MEM, 0);
+ /* All passed, return the packet - frame length + ip length */
+ BPF_SET_STMT(bp, BPF_LD + BPF_MEM, BPF_M_FHLEN);
bp++;
- BPF_SET_STMT(bp, BPF_LDX + BPF_MEM, 2);
+ BPF_SET_STMT(bp, BPF_LDX + BPF_MEM, BPF_M_IPLEN);
bp++;
BPF_SET_STMT(bp, BPF_ALU + BPF_ADD + BPF_X, 0);
bp++;
Index: src/external/bsd/dhcpcd/dist/src/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.10 src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.11
--- src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.10 Fri Jul 26 10:53:45 2019
+++ src/external/bsd/dhcpcd/dist/src/dhcp6.c Tue Jul 30 10:25:03 2019
@@ -1938,6 +1938,7 @@ dhcp6_checkstatusok(const struct interfa
if ((opt = f(farg, len, D6_OPTION_STATUS_CODE, &opt_len)) == NULL) {
//logdebugx("%s: no status", ifp->name);
state->lerror = 0;
+ errno = ESRCH;
return 0;
}
@@ -1949,7 +1950,8 @@ dhcp6_checkstatusok(const struct interfa
code = ntohs(code);
if (code == D6_STATUS_OK) {
state->lerror = 0;
- return 1;
+ errno = 0;
+ return 0;
}
/* Anything after the code is a message. */
@@ -1980,7 +1982,8 @@ dhcp6_checkstatusok(const struct interfa
logfunc("%s: DHCPv6 REPLY: %s", ifp->name, status);
free(sbuf);
state->lerror = code;
- return -1;
+ errno = 0;
+ return (int)code;
}
const struct ipv6_addr *
@@ -2227,7 +2230,7 @@ dhcp6_findia(struct interface *ifp, stru
struct dhcp6_option o;
uint8_t *d, *p;
struct dhcp6_ia_na ia;
- int i, e;
+ int i, e, error;
size_t j;
uint16_t nl;
uint8_t iaid[4];
@@ -2316,7 +2319,9 @@ dhcp6_findia(struct interface *ifp, stru
}
} else
ia.t1 = ia.t2 = 0; /* appease gcc */
- if (dhcp6_checkstatusok(ifp, NULL, p, o.len) == -1) {
+ if ((error = dhcp6_checkstatusok(ifp, NULL, p, o.len)) != 0) {
+ if (error == D6_STATUS_NOBINDING)
+ state->has_no_binding = true;
e = 1;
continue;
}
@@ -2417,7 +2422,7 @@ dhcp6_validatelease(struct interface *if
const char *sfrom, const struct timespec *acquired)
{
struct dhcp6_state *state;
- int ok, nia;
+ int nia, ok_errno;
struct timespec aq;
if (len <= sizeof(*m)) {
@@ -2426,8 +2431,10 @@ dhcp6_validatelease(struct interface *if
}
state = D6_STATE(ifp);
- if ((ok = dhcp6_checkstatusok(ifp, m, NULL, len) == -1))
+ errno = 0;
+ if (dhcp6_checkstatusok(ifp, m, NULL, len) != 0)
return -1;
+ ok_errno = errno;
state->renew = state->rebind = state->expire = 0;
state->lowpl = ND6_INFINITE_LIFETIME;
@@ -2435,9 +2442,10 @@ dhcp6_validatelease(struct interface *if
clock_gettime(CLOCK_MONOTONIC, &aq);
acquired = &aq;
}
+ state->has_no_binding = false;
nia = dhcp6_findia(ifp, m, len, sfrom, acquired);
if (nia == 0) {
- if (state->state != DH6S_CONFIRM && ok != 1) {
+ if (state->state != DH6S_CONFIRM && ok_errno != 0) {
logerrx("%s: no useable IA found in lease", ifp->name);
return -1;
}
@@ -2447,6 +2455,7 @@ dhcp6_validatelease(struct interface *if
* IA's must have existed here otherwise we would
* have rejected it earlier. */
assert(state->new != NULL && state->new_len != 0);
+ state->has_no_binding = false;
nia = dhcp6_findia(ifp, state->new, state->new_len,
sfrom, acquired);
}
@@ -3269,7 +3278,7 @@ dhcp6_recvif(struct interface *ifp, cons
case DHCP6_REPLY:
switch(state->state) {
case DH6S_INFORM:
- if (dhcp6_checkstatusok(ifp, r, NULL, len) == -1)
+ if (dhcp6_checkstatusok(ifp, r, NULL, len) != 0)
return;
break;
case DH6S_CONFIRM:
@@ -3317,6 +3326,14 @@ dhcp6_recvif(struct interface *ifp, cons
dhcp6_startdiscover(ifp);
return;
}
+ /* RFC8415 18.2.10.1 */
+ if ((state->state == DH6S_RENEW ||
+ state->state == DH6S_REBIND) &&
+ state->has_no_binding)
+ {
+ dhcp6_startrequest(ifp);
+ return;
+ }
if (state->state == DH6S_DISCOVER)
state->state = DH6S_REQUEST;
break;
Index: src/external/bsd/dhcpcd/dist/src/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcp.c:1.22 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.23
--- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.22 Fri Jul 26 10:47:29 2019
+++ src/external/bsd/dhcpcd/dist/src/dhcp.c Tue Jul 30 10:25:03 2019
@@ -3220,70 +3220,80 @@ rapidcommit:
}
static void *
-get_udp_data(void *udp, size_t *len)
+get_udp_data(void *packet, size_t *len)
{
- struct bootp_pkt *p;
-
- p = (struct bootp_pkt *)udp;
- *len = (size_t)ntohs(p->ip.ip_len) - sizeof(p->ip) - sizeof(p->udp);
- return (char *)udp + offsetof(struct bootp_pkt, bootp);
+ const struct ip *ip = packet;
+ size_t ip_hl = (size_t)ip->ip_hl * 4;
+ char *p = packet;
+
+ p += ip_hl + sizeof(struct udphdr);
+ *len = (size_t)ntohs(ip->ip_len) - sizeof(struct udphdr) - ip_hl;
+ return p;
}
static int
-valid_udp_packet(void *data, size_t data_len, struct in_addr *from,
- int noudpcsum)
+valid_udp_packet(void *packet, size_t plen, struct in_addr *from,
+ unsigned int flags)
{
- struct bootp_pkt *p;
- uint16_t bytes;
+ struct ip *ip = packet;
+ char ip_hlv = *(char *)ip;
+ size_t ip_hlen;
+ uint16_t ip_len, uh_sum;
+ struct udphdr *udp;
- if (data_len < sizeof(p->ip)) {
- if (from)
+ if (plen < sizeof(*ip)) {
+ if (from != NULL)
from->s_addr = INADDR_ANY;
errno = ERANGE;
return -1;
}
- p = (struct bootp_pkt *)data;
- if (from)
- from->s_addr = p->ip.ip_src.s_addr;
- if (checksum(&p->ip, sizeof(p->ip)) != 0) {
+
+ if (from != NULL)
+ from->s_addr = ip->ip_src.s_addr;
+
+ ip_hlen = (size_t)ip->ip_hl * 4;
+ if (checksum(ip, ip_hlen) != 0) {
errno = EINVAL;
return -1;
}
- bytes = ntohs(p->ip.ip_len);
+ ip_len = ntohs(ip->ip_len);
/* Check we have a payload */
- if (bytes <= sizeof(p->ip) + sizeof(p->udp)) {
+ if (ip_len <= ip_hlen + sizeof(*udp)) {
errno = ERANGE;
return -1;
}
/* Check we don't go beyond the payload */
- if (bytes > data_len) {
+ if (ip_len > plen) {
errno = ENOBUFS;
return -1;
}
- if (noudpcsum == 0) {
- uint16_t udpsum, iplen;
+ if (flags & BPF_PARTIALCSUM)
+ return 0;
+
+ udp = (struct udphdr *)((char *)ip + ip_hlen);
+ if (udp->uh_sum == 0)
+ return 0;
+ uh_sum = udp->uh_sum;
- /* This does scribble on the packet, but at this point
- * we don't care to keep it. */
- iplen = p->ip.ip_len;
- udpsum = p->udp.uh_sum;
- p->udp.uh_sum = 0;
- p->ip.ip_hl = 0;
- p->ip.ip_v = 0;
- p->ip.ip_tos = 0;
- p->ip.ip_len = p->udp.uh_ulen;
- p->ip.ip_id = 0;
- p->ip.ip_off = 0;
- p->ip.ip_ttl = 0;
- p->ip.ip_sum = 0;
- if (udpsum && checksum(p, bytes) != udpsum) {
- errno = EINVAL;
- return -1;
- }
- p->ip.ip_len = iplen;
+ /* This does scribble on the packet, but at this point
+ * we don't care to keep it. */
+ udp->uh_sum = 0;
+ ip->ip_hl = 0;
+ ip->ip_v = 0;
+ ip->ip_tos = 0;
+ ip->ip_len = udp->uh_ulen;
+ ip->ip_id = 0;
+ ip->ip_off = 0;
+ ip->ip_ttl = 0;
+ ip->ip_sum = 0;
+ if (checksum(packet, ip_len) != uh_sum) {
+ errno = EINVAL;
+ return -1;
}
+ *(char *)ip = ip_hlv;
+ ip->ip_len = htons(ip_len);
return 0;
}
@@ -3320,9 +3330,7 @@ dhcp_handlepacket(struct interface *ifp,
size_t udp_len;
const struct dhcp_state *state = D_CSTATE(ifp);
- if (valid_udp_packet(data, len, &from,
- state->bpf_flags & RAW_PARTIALCSUM) == -1)
- {
+ if (valid_udp_packet(data, len, &from, state->bpf_flags) == -1) {
if (errno == EINVAL)
logerrx("%s: checksum failure from %s",
ifp->name, inet_ntoa(from));
@@ -3384,6 +3392,7 @@ dhcp_readpacket(void *arg)
static void
dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp)
{
+ const struct dhcp_state *state;
struct sockaddr_in from;
unsigned char buf[10 * 1024]; /* Maximum MTU */
struct iovec iov = {
@@ -3405,8 +3414,7 @@ dhcp_readudp(struct dhcpcd_ctx *ctx, str
ssize_t bytes;
if (ifp != NULL) {
- const struct dhcp_state *state = D_CSTATE(ifp);
-
+ state = D_CSTATE(ifp);
s = state->udp_fd;
} else
s = ctx->udp_fd;
@@ -3426,13 +3434,19 @@ dhcp_readudp(struct dhcpcd_ctx *ctx, str
logerr(__func__);
return;
}
- if (D_CSTATE(ifp) == NULL) {
+ state = D_CSTATE(ifp);
+ if (state == NULL) {
logdebugx("%s: received BOOTP for inactive interface",
ifp->name);
return;
}
}
+ if (state->bpf_fd != -1) {
+ /* Avoid a duplicate read if BPF is open for the interface. */
+ return;
+ }
+
dhcp_handlebootp(ifp, (struct bootp *)(void *)buf, (size_t)bytes,
&from.sin_addr);
#endif
Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.22 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.23
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.22 Thu Jul 25 08:55:18 2019
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c Tue Jul 30 10:25:03 2019
@@ -2125,13 +2125,13 @@ exit1:
}
free(ctx.ifaces);
}
+ free_options(&ctx, ifo);
#ifdef HAVE_OPEN_MEMSTREAM
if (ctx.script_fp)
fclose(ctx.script_fp);
#endif
free(ctx.script_buf);
free(ctx.script_env);
- free_options(&ctx, ifo);
rt_dispose(&ctx);
free(ctx.duid);
if (ctx.link_fd != -1) {
Index: src/external/bsd/dhcpcd/dist/src/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.9 src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.10
--- src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.9 Wed Jul 24 09:57:43 2019
+++ src/external/bsd/dhcpcd/dist/src/if-bsd.c Tue Jul 30 10:25:03 2019
@@ -51,6 +51,8 @@
#include <netinet6/nd6.h>
#ifdef __NetBSD__
#include <net/if_vlanvar.h> /* Needs netinet/if_ether.h */
+#elif defined(__DragonFly__)
+#include <net/vlan/if_vlan_var.h>
#else
#include <net/if_vlan_var.h>
#endif
@@ -541,7 +543,7 @@ if_route(unsigned char cmd, const struct
* try to encourage someone to fix that by logging a waring during compile.
*/
#if defined(__FreeBSD__) || defined(__OpenBSD__)
-#warning OS does not allow IPv6 address sharing
+#warning kernel does not allow IPv6 address sharing
if (!gateway_unspec || rt->rt_dest.sa_family!=AF_INET6)
#endif
rtm->rtm_addrs |= RTA_IFP;
Index: src/external/bsd/dhcpcd/dist/src/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.9 src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.10
--- src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.9 Fri Jul 26 10:53:45 2019
+++ src/external/bsd/dhcpcd/dist/src/ipv6nd.c Tue Jul 30 10:25:03 2019
@@ -434,13 +434,7 @@ ipv6nd_sendadvertisement(void *arg)
s = ctx->nd_fd;
#endif
if (sendmsg(s, &msg, 0) == -1)
-#ifdef __OpenBSD__
-/* This isn't too critical as they don't support IPv6 address sharing */
-#warning Cannot send NA messages on OpenBSD
- logdebug(__func__);
-#else
logerr(__func__);
-#endif
if (++ia->na_count < MAX_NEIGHBOR_ADVERTISEMENT) {
eloop_timeout_add_sec(ctx->eloop,
@@ -527,6 +521,8 @@ ipv6nd_advertise(struct ipv6_addr *ia)
eloop_timeout_delete(ctx->eloop, ipv6nd_sendadvertisement, iaf);
ipv6nd_sendadvertisement(iaf);
}
+#elif !defined(SMALL)
+#warning kernel does not support userland sending ND6 advertisements
#endif /* ND6_ADVERTISE */
static void
Index: src/external/bsd/dhcpcd/dist/src/if-options.c
diff -u src/external/bsd/dhcpcd/dist/src/if-options.c:1.15 src/external/bsd/dhcpcd/dist/src/if-options.c:1.16
--- src/external/bsd/dhcpcd/dist/src/if-options.c:1.15 Wed Jul 24 09:57:43 2019
+++ src/external/bsd/dhcpcd/dist/src/if-options.c Tue Jul 30 10:25:03 2019
@@ -2611,73 +2611,92 @@ void
free_options(struct dhcpcd_ctx *ctx, struct if_options *ifo)
{
size_t i;
+#ifdef RT_FREE_ROUTE_TABLE
+ struct interface *ifp;
+ struct rt *rt;
+#endif
struct dhcp_opt *opt;
struct vivco *vo;
#ifdef AUTH
struct token *token;
#endif
- if (ifo) {
- if (ifo->environ) {
- i = 0;
- while (ifo->environ[i])
- free(ifo->environ[i++]);
- free(ifo->environ);
- }
- if (ifo->config) {
- i = 0;
- while (ifo->config[i])
- free(ifo->config[i++]);
- free(ifo->config);
+ if (ifo == NULL)
+ return;
+
+ if (ifo->environ) {
+ i = 0;
+ while (ifo->environ[i])
+ free(ifo->environ[i++]);
+ free(ifo->environ);
+ }
+ if (ifo->config) {
+ i = 0;
+ while (ifo->config[i])
+ free(ifo->config[i++]);
+ free(ifo->config);
+ }
+
+#ifdef RT_FREE_ROUTE_TABLE
+ /* Stupidly, we don't know the interface when creating the options.
+ * As such, make sure each route has one so they can goto the
+ * free list. */
+ ifp = ctx->ifaces != NULL ? TAILQ_FIRST(ctx->ifaces) : NULL;
+ if (ifp != NULL) {
+ RB_TREE_FOREACH(rt, &ifo->routes) {
+ if (rt->rt_ifp == NULL)
+ rt->rt_ifp = ifp;
}
- rt_headclear0(ctx, &ifo->routes, AF_UNSPEC);
- if (ifo->script != default_script)
- free(ifo->script);
- free(ifo->arping);
- free(ifo->blacklist);
- free(ifo->fallback);
-
- for (opt = ifo->dhcp_override;
- ifo->dhcp_override_len > 0;
- 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--)
- free_dhcp_opt_embenc(opt);
- free(ifo->dhcp6_override);
- for (vo = ifo->vivco;
- ifo->vivco_len > 0;
- vo++, ifo->vivco_len--)
- free(vo->data);
- free(ifo->vivco);
- for (opt = ifo->vivso_override;
- ifo->vivso_override_len > 0;
- opt++, ifo->vivso_override_len--)
- free_dhcp_opt_embenc(opt);
- free(ifo->vivso_override);
+ }
+#endif
+ rt_headclear0(ctx, &ifo->routes, AF_UNSPEC);
+
+ if (ifo->script != default_script)
+ free(ifo->script);
+ free(ifo->arping);
+ free(ifo->blacklist);
+ free(ifo->fallback);
+
+ for (opt = ifo->dhcp_override;
+ ifo->dhcp_override_len > 0;
+ 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--)
+ free_dhcp_opt_embenc(opt);
+ free(ifo->dhcp6_override);
+ for (vo = ifo->vivco;
+ ifo->vivco_len > 0;
+ vo++, ifo->vivco_len--)
+ free(vo->data);
+ free(ifo->vivco);
+ for (opt = ifo->vivso_override;
+ ifo->vivso_override_len > 0;
+ opt++, ifo->vivso_override_len--)
+ free_dhcp_opt_embenc(opt);
+ free(ifo->vivso_override);
#if defined(INET6) && !defined(SMALL)
- for (; ifo->ia_len > 0; ifo->ia_len--)
- free(ifo->ia[ifo->ia_len - 1].sla);
+ for (; ifo->ia_len > 0; ifo->ia_len--)
+ free(ifo->ia[ifo->ia_len - 1].sla);
#endif
- free(ifo->ia);
+ free(ifo->ia);
#ifdef AUTH
- while ((token = TAILQ_FIRST(&ifo->auth.tokens))) {
- TAILQ_REMOVE(&ifo->auth.tokens, token, next);
- if (token->realm_len)
- free(token->realm);
- free(token->key);
- free(token);
- }
-#endif
- free(ifo);
+ while ((token = TAILQ_FIRST(&ifo->auth.tokens))) {
+ TAILQ_REMOVE(&ifo->auth.tokens, token, next);
+ if (token->realm_len)
+ free(token->realm);
+ free(token->key);
+ free(token);
}
+#endif
+ free(ifo);
}
Index: src/external/bsd/dhcpcd/dist/src/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/src/ipv6.c:1.2 src/external/bsd/dhcpcd/dist/src/ipv6.c:1.3
--- src/external/bsd/dhcpcd/dist/src/ipv6.c:1.2 Fri Jul 26 10:53:45 2019
+++ src/external/bsd/dhcpcd/dist/src/ipv6.c Tue Jul 30 10:25:03 2019
@@ -634,6 +634,15 @@ ipv6_addaddr1(struct ipv6_addr *ia, cons
#ifdef __sun
struct ipv6_state *state;
struct ipv6_addr *ia2;
+
+ /* If we re-add then address on Solaris then the prefix
+ * route will be scrubbed and re-added. Something might
+ * be using it, so let's avoid it. */
+ if (ia->flags & IPV6_AF_DADCOMPLETED) {
+ logdebugx("%s: IP address %s already exists",
+ ia->iface->name, ia->saddr);
+ return 0;
+ }
#endif
/* Remember the interface of the address. */
@@ -1187,6 +1196,8 @@ out:
/* Done with the ia now, so free it. */
if (cmd == RTM_DELADDR)
ipv6_freeaddr(ia);
+ else if (!(ia->addr_flags & IN6_IFF_NOTUSEABLE))
+ ia->flags |= IPV6_AF_DADCOMPLETED;
}
int
@@ -1465,8 +1476,10 @@ ipv6_newaddr(struct interface *ifp, cons
goto err;
ia->iface = ifp;
- ia->flags = IPV6_AF_NEW | flags;
ia->addr_flags = addr_flags;
+ ia->flags = IPV6_AF_NEW | flags;
+ if (!(ia->addr_flags & IN6_IFF_NOTUSEABLE))
+ ia->flags |= IPV6_AF_DADCOMPLETED;
ia->prefix_len = prefix_len;
ia->dhcp6_fd = -1;
Index: src/external/bsd/dhcpcd/dist/src/ipv6.h
diff -u src/external/bsd/dhcpcd/dist/src/ipv6.h:1.2 src/external/bsd/dhcpcd/dist/src/ipv6.h:1.3
--- src/external/bsd/dhcpcd/dist/src/ipv6.h:1.2 Fri Jul 26 10:53:45 2019
+++ src/external/bsd/dhcpcd/dist/src/ipv6.h Tue Jul 30 10:25:03 2019
@@ -149,7 +149,13 @@
# define IN6_IFF_DETACHED 0
#endif
-#ifndef SMALL
+/*
+ * ND6 Advertising is only used for IP address sharing to prefer
+ * the address on a specific interface.
+ * This just fails to work on OpenBSD and causes erroneous duplicate
+ * address messages on BSD's other then NetBSD.
+ */
+#if !defined(SMALL) && (defined(__NetBSD__) || defined(__linux__))
# define ND6_ADVERTISE
#endif