Module Name: src Committed By: roy Date: Fri Jun 17 19:42:32 UTC 2016
Modified Files: src/external/bsd/dhcpcd/dist: arp.c arp.h bpf-filter.h defs.h dhcp-common.c dhcp.c dhcp.h dhcp6.c dhcp6.h dhcpcd.c dhcpcd.conf.5.in dhcpcd.h if-bsd.c if-options.c if.c if.h ipv4.c ipv4.h ipv4ll.c ipv4ll.h ipv6.c ipv6.h ipv6nd.c script.c src/external/bsd/dhcpcd/dist/dhcpcd-hooks: 20-resolv.conf 30-hostname Log Message: Sync To generate a diff of this commit: cvs rdiff -u -r1.19 -r1.20 src/external/bsd/dhcpcd/dist/arp.c cvs rdiff -u -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/arp.h \ src/external/bsd/dhcpcd/dist/dhcp6.h cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/bpf-filter.h cvs rdiff -u -r1.27 -r1.28 src/external/bsd/dhcpcd/dist/defs.h \ src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in cvs rdiff -u -r1.17 -r1.18 src/external/bsd/dhcpcd/dist/dhcp-common.c \ src/external/bsd/dhcpcd/dist/dhcpcd.h src/external/bsd/dhcpcd/dist/ipv4.h cvs rdiff -u -r1.42 -r1.43 src/external/bsd/dhcpcd/dist/dhcp.c cvs rdiff -u -r1.16 -r1.17 src/external/bsd/dhcpcd/dist/dhcp.h \ src/external/bsd/dhcpcd/dist/if.h src/external/bsd/dhcpcd/dist/ipv4ll.c cvs rdiff -u -r1.21 -r1.22 src/external/bsd/dhcpcd/dist/dhcp6.c \ src/external/bsd/dhcpcd/dist/if.c cvs rdiff -u -r1.34 -r1.35 src/external/bsd/dhcpcd/dist/dhcpcd.c cvs rdiff -u -r1.30 -r1.31 src/external/bsd/dhcpcd/dist/if-bsd.c cvs rdiff -u -r1.33 -r1.34 src/external/bsd/dhcpcd/dist/if-options.c cvs rdiff -u -r1.22 -r1.23 src/external/bsd/dhcpcd/dist/ipv4.c cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/ipv4ll.h cvs rdiff -u -r1.18 -r1.19 src/external/bsd/dhcpcd/dist/ipv6.c \ src/external/bsd/dhcpcd/dist/ipv6.h cvs rdiff -u -r1.29 -r1.30 src/external/bsd/dhcpcd/dist/ipv6nd.c cvs rdiff -u -r1.26 -r1.27 src/external/bsd/dhcpcd/dist/script.c cvs rdiff -u -r1.8 -r1.9 \ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf cvs rdiff -u -r1.7 -r1.8 \ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/bsd/dhcpcd/dist/arp.c diff -u src/external/bsd/dhcpcd/dist/arp.c:1.19 src/external/bsd/dhcpcd/dist/arp.c:1.20 --- src/external/bsd/dhcpcd/dist/arp.c:1.19 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/arp.c Fri Jun 17 19:42:31 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: arp.c,v 1.19 2016/05/09 10:15:59 roy Exp $"); + __RCSID("$NetBSD: arp.c,v 1.20 2016/06/17 19:42:31 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -65,6 +65,7 @@ arp_request(const struct interface *ifp, struct arphdr ar; size_t len; uint8_t *p; + const struct iarp_state *state; ar.ar_hrd = htons(ifp->family); ar.ar_pro = htons(ETHERTYPE_IP); @@ -91,7 +92,9 @@ arp_request(const struct interface *ifp, APPEND(&sip, sizeof(sip)); ZERO(ifp->hwlen); APPEND(&tip, sizeof(tip)); - return if_sendrawpacket(ifp, ETHERTYPE_ARP, arp_buffer, len); + + state = ARP_CSTATE(ifp); + return if_sendraw(ifp, state->fd, ETHERTYPE_ARP, arp_buffer, len); eexit: errno = ENOBUFS; @@ -123,7 +126,7 @@ arp_packet(void *arg) { struct interface *ifp = arg; const struct interface *ifn; - uint8_t arp_buffer[ARP_LEN]; + uint8_t buf[ARP_LEN]; struct arphdr ar; struct arp_msg arm; ssize_t bytes; @@ -134,65 +137,62 @@ arp_packet(void *arg) state = ARP_STATE(ifp); flags = 0; - while (!(flags & RAW_EOF)) { - bytes = if_readrawpacket(ifp, ETHERTYPE_ARP, - arp_buffer, sizeof(arp_buffer), &flags); - if (bytes == -1) { - logger(ifp->ctx, LOG_ERR, - "%s: arp if_readrawpacket: %m", ifp->name); - arp_close(ifp); - return; - } - /* We must have a full ARP header */ - if ((size_t)bytes < sizeof(ar)) - continue; - memcpy(&ar, arp_buffer, sizeof(ar)); - /* Families must match */ - if (ar.ar_hrd != htons(ifp->family)) - continue; + bytes = if_readraw(ifp, state->fd, buf, sizeof(buf), &flags); + if (bytes == -1) { + logger(ifp->ctx, LOG_ERR, + "%s: arp if_readrawpacket: %m", ifp->name); + arp_close(ifp); + return; + } + /* We must have a full ARP header */ + if ((size_t)bytes < sizeof(ar)) + return; + memcpy(&ar, buf, sizeof(ar)); + /* Families must match */ + if (ar.ar_hrd != htons(ifp->family)) + return; #if 0 - /* These checks are enforced in the BPF filter. */ - /* 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)) - continue; + /* These checks are enforced in the BPF filter. */ + /* 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)) + continue; #endif - if (ar.ar_pln != sizeof(arm.sip.s_addr)) - continue; + if (ar.ar_pln != sizeof(arm.sip.s_addr)) + return; - /* Get pointers to the hardware addreses */ - hw_s = arp_buffer + sizeof(ar); - hw_t = hw_s + ar.ar_hln + ar.ar_pln; - /* Ensure we got all the data */ - if ((hw_t + ar.ar_hln + ar.ar_pln) - arp_buffer > bytes) - continue; - /* Ignore messages from ourself */ - TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) { - if (ar.ar_hln == ifn->hwlen && - memcmp(hw_s, ifn->hwaddr, ifn->hwlen) == 0) - break; - } - if (ifn) { + /* Get pointers to the hardware addreses */ + hw_s = buf + sizeof(ar); + hw_t = hw_s + ar.ar_hln + ar.ar_pln; + /* Ensure we got all the data */ + if ((hw_t + ar.ar_hln + ar.ar_pln) - buf > bytes) + return; + /* Ignore messages from ourself */ + TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) { + if (ar.ar_hln == ifn->hwlen && + memcmp(hw_s, ifn->hwaddr, ifn->hwlen) == 0) + break; + } + if (ifn) { #if 0 - logger(ifp->ctx, LOG_DEBUG, - "%s: ignoring ARP from self", ifp->name); + logger(ifp->ctx, LOG_DEBUG, + "%s: ignoring ARP from self", ifp->name); #endif - continue; - } - /* Copy out the HW and IP addresses */ - memcpy(&arm.sha, hw_s, ar.ar_hln); - memcpy(&arm.sip.s_addr, hw_s + ar.ar_hln, ar.ar_pln); - memcpy(&arm.tha, hw_t, ar.ar_hln); - memcpy(&arm.tip.s_addr, hw_t + ar.ar_hln, ar.ar_pln); - - /* Run the conflicts */ - TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, astaten) { - if (astate->conflicted_cb) - astate->conflicted_cb(astate, &arm); - } + return; + } + /* Copy out the HW and IP addresses */ + memcpy(&arm.sha, hw_s, ar.ar_hln); + memcpy(&arm.sip.s_addr, hw_s + ar.ar_hln, ar.ar_pln); + memcpy(&arm.tha, hw_t, ar.ar_hln); + memcpy(&arm.tip.s_addr, hw_t + ar.ar_hln, ar.ar_pln); + + /* Run the conflicts */ + TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, astaten) { + if (astate->conflicted_cb) + astate->conflicted_cb(astate, &arm); } } @@ -203,7 +203,7 @@ arp_open(struct interface *ifp) state = ARP_STATE(ifp); if (state->fd == -1) { - state->fd = if_openrawsocket(ifp, ETHERTYPE_ARP); + state->fd = if_openraw(ifp, ETHERTYPE_ARP); if (state->fd == -1) { logger(ifp->ctx, LOG_ERR, "%s: %s: %m", __func__, ifp->name); @@ -391,7 +391,7 @@ arp_free(struct arp_state *astate) TAILQ_FIRST(&state->arp_states) == NULL) { eloop_event_delete(ifp->ctx->eloop, state->fd); - close(state->fd); + if_closeraw(ifp, state->fd); free(state); ifp->if_data[IF_DATA_ARP] = NULL; } @@ -428,22 +428,21 @@ arp_close(struct interface *ifp) } void -arp_handleifa(int cmd, struct interface *ifp, const struct in_addr *addr, - int flags) +arp_handleifa(int cmd, struct ipv4_addr *addr) { #ifdef IN_IFF_DUPLICATED struct iarp_state *state; struct arp_state *astate, *asn; - if (cmd != RTM_NEWADDR || (state = ARP_STATE(ifp)) == NULL) + if (cmd != RTM_NEWADDR || (state = ARP_STATE(addr->iface)) == NULL) return; TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, asn) { - if (astate->addr.s_addr == addr->s_addr) { - if (flags & IN_IFF_DUPLICATED) { + if (astate->addr.s_addr == addr->addr.s_addr) { + if (addr->addr_flags & IN_IFF_DUPLICATED) { if (astate->conflicted_cb) astate->conflicted_cb(astate, NULL); - } else if (!(flags & IN_IFF_NOTUSEABLE)) { + } else if (!(addr->addr_flags & IN_IFF_NOTUSEABLE)) { if (astate->probed_cb) astate->probed_cb(astate); } @@ -451,8 +450,6 @@ arp_handleifa(int cmd, struct interface } #else UNUSED(cmd); - UNUSED(ifp); UNUSED(addr); - UNUSED(flags); #endif } Index: src/external/bsd/dhcpcd/dist/arp.h diff -u src/external/bsd/dhcpcd/dist/arp.h:1.13 src/external/bsd/dhcpcd/dist/arp.h:1.14 --- src/external/bsd/dhcpcd/dist/arp.h:1.13 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/arp.h Fri Jun 17 19:42:31 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: arp.h,v 1.13 2016/05/09 10:15:59 roy Exp $ */ +/* $NetBSD: arp.h,v 1.14 2016/06/17 19:42:31 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -43,6 +43,7 @@ #define DEFEND_INTERVAL 10 #include "dhcpcd.h" +#include "if.h" struct arp_msg { uint16_t op; @@ -91,7 +92,7 @@ void arp_free_but(struct arp_state *); struct arp_state *arp_find(struct interface *, const struct in_addr *); void arp_close(struct interface *); -void arp_handleifa(int, struct interface *, const struct in_addr *, int); +void arp_handleifa(int, struct ipv4_addr *); #else #define arp_close(a) {} #endif Index: src/external/bsd/dhcpcd/dist/dhcp6.h diff -u src/external/bsd/dhcpcd/dist/dhcp6.h:1.13 src/external/bsd/dhcpcd/dist/dhcp6.h:1.14 --- src/external/bsd/dhcpcd/dist/dhcp6.h:1.13 Sun Apr 10 21:00:53 2016 +++ src/external/bsd/dhcpcd/dist/dhcp6.h Fri Jun 17 19:42:31 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: dhcp6.h,v 1.13 2016/04/10 21:00:53 roy Exp $ */ +/* $NetBSD: dhcp6.h,v 1.14 2016/06/17 19:42:31 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -250,6 +250,7 @@ void dhcp6_handleifa(struct dhcpcd_ctx * const struct in6_addr *addr, int); int dhcp6_dadcompleted(const struct interface *); void dhcp6_drop(struct interface *, const char *); +void dhcp6_dropnondelegates(struct interface *ifp); int dhcp6_dump(struct interface *); #else #define dhcp6_find_delegates(a) {} Index: src/external/bsd/dhcpcd/dist/bpf-filter.h diff -u src/external/bsd/dhcpcd/dist/bpf-filter.h:1.10 src/external/bsd/dhcpcd/dist/bpf-filter.h:1.11 --- src/external/bsd/dhcpcd/dist/bpf-filter.h:1.10 Thu Jan 7 20:09:43 2016 +++ src/external/bsd/dhcpcd/dist/bpf-filter.h Fri Jun 17 19:42:31 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: bpf-filter.h,v 1.10 2016/01/07 20:09:43 roy Exp $ */ +/* $NetBSD: bpf-filter.h,v 1.11 2016/06/17 19:42:31 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -51,7 +51,7 @@ static const struct bpf_insn arp_bpf_fil /* Otherwise, drop it. */ BPF_STMT(BPF_RET + BPF_K, 0), }; -#define arp_bpf_filter_len sizeof(arp_bpf_filter) / sizeof(arp_bpf_filter[0]) +#define arp_bpf_filter_len __arraycount(arp_bpf_filter) /* dhcp_bpf_filter taken from bpf.c in dhcp-3.1.0 @@ -78,7 +78,7 @@ static const struct bpf_insn arp_bpf_fil * http://www.isc.org/ */ -static const struct bpf_insn dhcp_bpf_filter [] = { +static const struct bpf_insn bootp_bpf_filter [] = { #ifndef BPF_SKIPTYPE /* Make sure this is an IP packet... */ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12), @@ -94,10 +94,10 @@ static const struct bpf_insn dhcp_bpf_fi BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14 + BPF_ETHCOOK), /* Make sure it's to the right port... */ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16 + BPF_ETHCOOK), - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_CLIENT_PORT, 0, 1), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTPC, 0, 1), /* If we passed all the tests, ask for the whole packet. */ BPF_STMT(BPF_RET + BPF_K, BPF_WHOLEPACKET), /* Otherwise, drop it. */ BPF_STMT(BPF_RET + BPF_K, 0), }; -#define dhcp_bpf_filter_len sizeof(dhcp_bpf_filter) / sizeof(dhcp_bpf_filter[0]) +#define bootp_bpf_filter_len __arraycount(bootp_bpf_filter) Index: src/external/bsd/dhcpcd/dist/defs.h diff -u src/external/bsd/dhcpcd/dist/defs.h:1.27 src/external/bsd/dhcpcd/dist/defs.h:1.28 --- src/external/bsd/dhcpcd/dist/defs.h:1.27 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/defs.h Fri Jun 17 19:42:31 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: defs.h,v 1.27 2016/05/09 10:15:59 roy Exp $ */ +/* $NetBSD: defs.h,v 1.28 2016/06/17 19:42:31 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -30,7 +30,7 @@ #define CONFIG_H #define PACKAGE "dhcpcd" -#define VERSION "6.11.0" +#define VERSION "6.11.1" #ifndef CONFIG # define CONFIG SYSCONFDIR "/" PACKAGE ".conf" Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.27 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.28 --- src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.27 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in Fri Jun 17 19:42:31 2016 @@ -1,4 +1,4 @@ -.\" $NetBSD: dhcpcd.conf.5.in,v 1.27 2016/05/09 10:15:59 roy Exp $ +.\" $NetBSD: dhcpcd.conf.5.in,v 1.28 2016/06/17 19:42:31 roy Exp $ .\" Copyright (c) 2006-2016 Roy Marples .\" All rights reserved .\" @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 21, 2016 +.Dd June 14, 2016 .Dt DHCPCD.CONF 5 .Os .Sh NAME @@ -156,7 +156,7 @@ should use with .Ic env .Va wpa_supplicant_driver=nl80211 .Pp -If the hostname is set, will be will set to the FQDN if possible as per +If the hostname is set, it will be will set to the FQDN if possible as per RFC 4702 section 3.1. If the FQDN option is missing, .Nm dhcpcd @@ -262,14 +262,14 @@ You can use this option to stop this fro Fallback to using this profile if DHCP fails. This allows you to configure a static profile instead of using ZeroConf. .It Ic hostname Ar name -Sends -.Ar hostname +Sends the hostname +.Ar name to the DHCP server so it can be registered in DNS. If -.Ar hostname +.Ar name is an empty string then the current system hostname is sent. If -.Ar hostname +.Ar name is a FQDN (ie, contains a .) then it will be encoded as such. .It Ic hostname_short Sends the short hostname to the DHCP server instead of the FQDN. @@ -523,6 +523,12 @@ to handle ND options, but this only work and .Ic require options. +.Pp +To see a list of options you can use, call +.Nm dhcpcd +with the +.Fl V , Fl Fl variables +argument. .It Ic nooption Ar option Remove the option from the message before it's processed. .It Ic require Ar option Index: src/external/bsd/dhcpcd/dist/dhcp-common.c diff -u src/external/bsd/dhcpcd/dist/dhcp-common.c:1.17 src/external/bsd/dhcpcd/dist/dhcp-common.c:1.18 --- src/external/bsd/dhcpcd/dist/dhcp-common.c:1.17 Wed Jun 8 01:33:08 2016 +++ src/external/bsd/dhcpcd/dist/dhcp-common.c Fri Jun 17 19:42:31 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: dhcp-common.c,v 1.17 2016/06/08 01:33:08 christos Exp $"); + __RCSID("$NetBSD: dhcp-common.c,v 1.18 2016/06/17 19:42:31 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -833,7 +833,7 @@ int dhcp_set_leasefile(char *leasefile, size_t len, int family, const struct interface *ifp) { - char ssid[1 + (IF_SSIDLEN * 4) + 1]; + char ssid[1 + (IF_SSIDLEN * 4) + 1]; /* - prefix and NUL terminated. */ if (ifp->name[0] == '\0') { strlcpy(leasefile, ifp->ctx->pidfile, len); Index: src/external/bsd/dhcpcd/dist/dhcpcd.h diff -u src/external/bsd/dhcpcd/dist/dhcpcd.h:1.17 src/external/bsd/dhcpcd/dist/dhcpcd.h:1.18 --- src/external/bsd/dhcpcd/dist/dhcpcd.h:1.17 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/dhcpcd.h Fri Jun 17 19:42:31 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: dhcpcd.h,v 1.17 2016/05/09 10:15:59 roy Exp $ */ +/* $NetBSD: dhcpcd.h,v 1.18 2016/06/17 19:42:31 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -200,7 +200,7 @@ int dhcpcd_handleargs(struct dhcpcd_ctx void dhcpcd_handlecarrier(struct dhcpcd_ctx *, int, unsigned int, const char *); int dhcpcd_handleinterface(void *, int, const char *); void dhcpcd_handlehwaddr(struct dhcpcd_ctx *, const char *, - const unsigned char *, uint8_t); + const void *, uint8_t); void dhcpcd_dropinterface(struct interface *, const char *); int dhcpcd_selectprofile(struct interface *, const char *); Index: src/external/bsd/dhcpcd/dist/ipv4.h diff -u src/external/bsd/dhcpcd/dist/ipv4.h:1.17 src/external/bsd/dhcpcd/dist/ipv4.h:1.18 --- src/external/bsd/dhcpcd/dist/ipv4.h:1.17 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/ipv4.h Fri Jun 17 19:42:32 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: ipv4.h,v 1.17 2016/05/09 10:15:59 roy Exp $ */ +/* $NetBSD: ipv4.h,v 1.18 2016/06/17 19:42:32 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -57,7 +57,7 @@ struct rt { TAILQ_ENTRY(rt) next; struct in_addr dest; - struct in_addr net; + struct in_addr mask; struct in_addr gate; const struct interface *iface; #ifdef HAVE_ROUTE_METRIC @@ -73,13 +73,20 @@ TAILQ_HEAD(rt_head, rt); struct ipv4_addr { TAILQ_ENTRY(ipv4_addr) next; struct in_addr addr; - struct in_addr net; + struct in_addr mask; struct in_addr brd; struct interface *iface; int addr_flags; + char saddr[INET_ADDRSTRLEN + 3]; }; TAILQ_HEAD(ipv4_addrhead, ipv4_addr); +#define IPV4_ADDR_EQ(a1, a2) ((a1) && (a1)->addr.s_addr == (a2)->addr.s_addr) +#define IPV4_MASK1_EQ(a1, a2) ((a1) && (a1)->mask.s_addr == (a2)->mask.s_addr) +#define IPV4_MASK_EQ(a1, a2) (IPV4_ADDR_EQ(a1, a2) && IPV4_MASK1_EQ(a1, a2)) +#define IPV4_BRD1_EQ(a1, a2) ((a1) && (a1)->brd.s_addr == (a2)->brd.s_addr) +#define IPV4_BRD_EQ(a1, a2) (IPV4_MASK_EQ(a1, a2) && IPV4_BRD1_EQ(a1, a2)) + struct ipv4_state { struct ipv4_addrhead addrs; struct rt_head routes; @@ -87,7 +94,7 @@ struct ipv4_state { #ifdef BSD /* Buffer for BPF */ size_t buffer_size, buffer_len, buffer_pos; - uint8_t *buffer; + char *buffer; #endif }; @@ -99,7 +106,6 @@ struct ipv4_state { #ifdef INET struct ipv4_state *ipv4_getstate(struct interface *); int ipv4_init(struct dhcpcd_ctx *); -int ipv4_protocol_fd(const struct interface *, uint16_t); int ipv4_ifcmp(const struct interface *, const struct interface *); uint8_t inet_ntocidr(struct in_addr); int inet_cidrtoaddr(int, struct in_addr *); @@ -110,8 +116,7 @@ int ipv4_hasaddr(const struct interface #define STATE_FAKE 0x02 void ipv4_buildroutes(struct dhcpcd_ctx *); -int ipv4_deladdr(struct interface *, const struct in_addr *, - const struct in_addr *, int); +int ipv4_deladdr(struct ipv4_addr *, int); int ipv4_preferanother(struct interface *); struct ipv4_addr *ipv4_addaddr(struct interface *, const struct in_addr *, const struct in_addr *, const struct in_addr *); Index: src/external/bsd/dhcpcd/dist/dhcp.c diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.42 src/external/bsd/dhcpcd/dist/dhcp.c:1.43 --- src/external/bsd/dhcpcd/dist/dhcp.c:1.42 Thu May 26 09:09:47 2016 +++ src/external/bsd/dhcpcd/dist/dhcp.c Fri Jun 17 19:42:31 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: dhcp.c,v 1.42 2016/05/26 09:09:47 prlw1 Exp $"); + __RCSID("$NetBSD: dhcp.c,v 1.43 2016/06/17 19:42:31 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -434,7 +434,7 @@ decode_rfc3442_rt(struct dhcpcd_ctx *ctx if (ocets > 0) { memcpy(&rt->dest.s_addr, p, ocets); p += ocets; - rt->net.s_addr = htonl(~0U << (32 - cidr)); + rt->mask.s_addr = htonl(~0U << (32 - cidr)); } /* Finally, snag the router */ @@ -629,9 +629,9 @@ get_option_routes(struct interface *ifp, route->gate.s_addr == bootp->yiaddr) { route->gate.s_addr = htonl(INADDR_ANY); - route->net.s_addr = htonl(INADDR_BROADCAST); + route->mask.s_addr = htonl(INADDR_BROADCAST); } else - route->net.s_addr = + route->mask.s_addr = route_netmask(route->dest.s_addr); TAILQ_INSERT_TAIL(routes, route, next); } @@ -671,7 +671,7 @@ dhcp_get_mtu(const struct interface *ifp if ((state = D_CSTATE(ifp)) == NULL || has_option_mask(ifp->options->nomask, DHO_MTU) || get_option_uint16(ifp->ctx, &mtu, - state->new, state->new_len, DHO_MTU) == -1) + state->new, state->new_len, DHO_MTU) == -1) return 0; return mtu; } @@ -763,18 +763,14 @@ make_message(struct bootp **bootpm, cons return -1; *bootpm = bootp; - if ((type == DHCP_INFORM || type == DHCP_RELEASE || - (type == DHCP_REQUEST && state->net.s_addr == lease->net.s_addr && + if (state->addr != NULL && + (type == DHCP_INFORM || type == DHCP_RELEASE || + (type == DHCP_REQUEST && + state->addr->mask.s_addr == lease->mask.s_addr && (state->new == NULL || IS_DHCP(state->new))))) - { - /* In-case we haven't actually configured the address yet */ - if (type == DHCP_INFORM && state->addr.s_addr == 0) - bootp->ciaddr = lease->addr.s_addr; - else - bootp->ciaddr = state->addr.s_addr; - } + bootp->ciaddr = state->addr->addr.s_addr; - bootp->op = DHCP_BOOTREQUEST; + bootp->op = BOOTREQUEST; bootp->htype = (uint8_t)ifp->family; switch (ifp->family) { case ARPHRD_ETHER: @@ -789,7 +785,7 @@ make_message(struct bootp **bootpm, cons type != DHCP_DECLINE && type != DHCP_RELEASE) bootp->flags = htons(BROADCAST_FLAG); -#if 0 + if (type != DHCP_DECLINE && type != DHCP_RELEASE) { struct timespec tv; @@ -800,7 +796,7 @@ make_message(struct bootp **bootpm, cons else bootp->secs = htons((uint16_t)tv.tv_sec); } -#endif + bootp->xid = htonl(state->xid); if (ifo->options & DHCPCD_BOOTP) @@ -838,7 +834,8 @@ make_message(struct bootp **bootpm, cons if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) { if (type == DHCP_DECLINE || (type == DHCP_REQUEST && - lease->addr.s_addr != state->addr.s_addr)) + (state->addr == NULL || + lease->addr.s_addr != state->addr->addr.s_addr))) { PUT_ADDR(DHO_IPADDRESS, &lease->addr); if (lease->server.s_addr) @@ -1171,7 +1168,12 @@ read_lease(struct interface *ifp, struct return 0; } - if (bytes < sizeof(**bootp)) { + /* Ensure the packet is at lease BOOTP sized + * with a vendor area of 4 octets + * (it should be more, and our read packet enforces this so this + * code should not be needed, but of course people could + * scribble whatever in the stored lease file. */ + if (bytes < offsetof(struct bootp, vend) + 4) { free(lease); logger(ifp->ctx, LOG_ERR, "%s: truncated lease", __func__); return 0; @@ -1429,19 +1431,40 @@ dhcp_env(char **env, const char *prefix, } static void -get_lease(struct dhcpcd_ctx *ctx, +get_lease(struct interface *ifp, struct dhcp_lease *lease, const struct bootp *bootp, size_t len) { + struct dhcpcd_ctx *ctx; assert(bootp != NULL); memcpy(&lease->cookie, bootp->vend, sizeof(lease->cookie)); /* BOOTP does not set yiaddr for replies when ciaddr is set. */ lease->addr.s_addr = bootp->yiaddr ? bootp->yiaddr : bootp->ciaddr; - if (get_option_addr(ctx, &lease->net, bootp, len, DHO_SUBNETMASK) == -1) - lease->net.s_addr = ipv4_getnetmask(lease->addr.s_addr); - if (get_option_addr(ctx, &lease->brd, bootp, len, DHO_BROADCAST) == -1) - lease->brd.s_addr = lease->addr.s_addr | ~lease->net.s_addr; + ctx = ifp->ctx; + if (ifp->options->options & (DHCPCD_STATIC | DHCPCD_INFORM)) { + if (ifp->options->req_addr.s_addr != INADDR_ANY) { + lease->mask = ifp->options->req_mask; + lease->brd.s_addr = + lease->addr.s_addr | ~lease->mask.s_addr; + } else { + const struct ipv4_addr *ia; + + ia = ipv4_iffindaddr(ifp, &lease->addr, NULL); + assert(ia != NULL); + lease->mask = ia->mask; + lease->brd = ia->brd; + } + } else { + if (get_option_addr(ctx, &lease->mask, bootp, len, + DHO_SUBNETMASK) == -1) + lease->mask.s_addr = + ipv4_getnetmask(lease->addr.s_addr); + if (get_option_addr(ctx, &lease->brd, bootp, len, + DHO_BROADCAST) == -1) + lease->brd.s_addr = + lease->addr.s_addr | ~lease->mask.s_addr; + } if (get_option_uint32(ctx, &lease->leasetime, bootp, len, DHO_LEASETIME) != 0) lease->leasetime = ~0U; /* Default to infinite lease */ @@ -1502,7 +1525,7 @@ dhcp_close(struct interface *ifp) if (state->raw_fd != -1) { eloop_event_delete(ifp->ctx->eloop, state->raw_fd); - close(state->raw_fd); + if_closeraw(ifp, state->raw_fd); state->raw_fd = -1; } @@ -1542,12 +1565,12 @@ dhcp_openudp(struct interface *ifp) #endif memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; - sin.sin_port = htons(DHCP_CLIENT_PORT); + sin.sin_port = htons(BOOTPC); if (ifp) { state = D_STATE(ifp); - sin.sin_addr.s_addr = state->addr.s_addr; - } else - state = NULL; /* appease gcc */ + if (state->addr) + sin.sin_addr.s_addr = state->addr->addr.s_addr; + } if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) goto eexit; @@ -1610,8 +1633,8 @@ dhcp_makeudppacket(size_t *sz, const uin else ip->ip_dst.s_addr = dest.s_addr; - udp->uh_sport = htons(DHCP_CLIENT_PORT); - udp->uh_dport = htons(DHCP_SERVER_PORT); + udp->uh_sport = htons(BOOTPC); + udp->uh_dport = htons(BOOTPS); udp->uh_ulen = htons((uint16_t)(sizeof(*udp) + length)); ip->ip_len = udp->uh_ulen; udp->uh_sum = checksum(udpp, sizeof(*ip) + sizeof(*udp) + length); @@ -1638,7 +1661,7 @@ send_message(struct interface *ifp, uint size_t len; ssize_t r; struct in_addr from, to; - in_addr_t a = INADDR_ANY; + struct ipv4_addr *iap; struct timespec tv; int s; #ifdef IN_IFF_NOTUSEABLE @@ -1681,11 +1704,11 @@ send_message(struct interface *ifp, uint if (dhcp_open(ifp) == -1) return; + iap = state->addr; if (state->added && !(state->added & STATE_FAKE) && - state->addr.s_addr != INADDR_ANY && - state->new != NULL && + state->addr != NULL && state->new != NULL && #ifdef IN_IFF_NOTUSEABLE - ((ia = ipv4_iffindaddr(ifp, &state->addr, NULL)) && + ((ia = ipv4_iffindaddr(ifp, &state->addr->addr, NULL)) && !(ia->addr_flags & IN_IFF_NOTUSEABLE)) && #endif (state->lease.server.s_addr || @@ -1698,14 +1721,12 @@ send_message(struct interface *ifp, uint logger(ifp->ctx, LOG_ERR, "%s: dhcp_openudp: %m", ifp->name); /* We cannot renew */ - a = state->addr.s_addr; - state->addr.s_addr = INADDR_ANY; + state->addr = NULL; } } r = make_message(&bootp, ifp, type); - if (a != INADDR_ANY) - state->addr.s_addr = a; + state->addr = iap; if (r == -1) goto fail; len = (size_t)r; @@ -1720,7 +1741,7 @@ send_message(struct interface *ifp, uint memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = to.s_addr; - sin.sin_port = htons(DHCP_SERVER_PORT); + sin.sin_port = htons(BOOTPS); r = sendto(s, (uint8_t *)bootp, len, 0, (struct sockaddr *)&sin, sizeof(sin)); if (r == -1) @@ -1730,12 +1751,12 @@ send_message(struct interface *ifp, uint size_t ulen; r = 0; - udp = dhcp_makeudppacket(&ulen, (uint8_t *)bootp, len, from, to); + udp = dhcp_makeudppacket(&ulen, (uint8_t *)bootp, len, from,to); if (udp == NULL) { logger(ifp->ctx, LOG_ERR, "dhcp_makeudppacket: %m"); } else { - r = if_sendrawpacket(ifp, ETHERTYPE_IP, - (uint8_t *)udp, ulen); + r = if_sendraw(ifp, state->raw_fd, + ETHERTYPE_IP, (uint8_t *)udp, ulen); free(udp); } /* If we failed to send a raw packet this normally means @@ -1745,7 +1766,7 @@ send_message(struct interface *ifp, uint * stopping the interface. */ if (r == -1) { logger(ifp->ctx, LOG_ERR, - "%s: if_sendrawpacket: %m", ifp->name); + "%s: if_sendraw: %m", ifp->name); switch(errno) { case ENETDOWN: case ENETRESET: @@ -1994,7 +2015,7 @@ dhcp_arp_probed(struct arp_state *astate len = state->new_len; state->new = state->offer; state->new_len = state->offer_len; - get_lease(astate->iface->ctx, &state->lease, + get_lease(astate->iface, &state->lease, state->new, state->new_len); ipv4_applyaddr(astate->iface); state->new = bootp; @@ -2073,9 +2094,8 @@ dhcp_arp_conflicted(struct arp_state *as !state->lease.frominfo) dhcp_decline(ifp); #ifdef IN_IFF_DUPLICATED - ia = ipv4_iffindaddr(ifp, &astate->addr, NULL); - if (ia) - ipv4_deladdr(ifp, &ia->addr, &ia->net, 1); + if ((ia = ipv4_iffindaddr(ifp, &astate->addr, NULL)) != NULL) + ipv4_deladdr(ia, 1); #endif arp_free(astate); eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); @@ -2085,11 +2105,12 @@ dhcp_arp_conflicted(struct arp_state *as } /* Bound address */ - if (amsg && - (amsg->sip.s_addr == state->addr.s_addr || - (amsg->sip.s_addr == 0 && amsg->tip.s_addr == state->addr.s_addr))) + if (amsg && state->addr && + (amsg->sip.s_addr == state->addr->addr.s_addr || + (amsg->sip.s_addr == 0 && + amsg->tip.s_addr == state->addr->addr.s_addr))) { - astate->failed = state->addr; + astate->failed = state->addr->addr; arp_report_conflicted(astate, amsg); if (state->state == DHS_BOUND) { /* For now, just report the duplicated address */ @@ -2120,11 +2141,11 @@ dhcp_bind(struct interface *ifp) state->offer = NULL; state->offer_len = 0; } - get_lease(ifp->ctx, lease, state->new, state->new_len); + get_lease(ifp, lease, state->new, state->new_len); if (ifo->options & DHCPCD_STATIC) { logger(ifp->ctx, LOG_INFO, "%s: using static address %s/%d", ifp->name, inet_ntoa(lease->addr), - inet_ntocidr(lease->net)); + inet_ntocidr(lease->mask)); lease->leasetime = ~0U; state->reason = "STATIC"; } else if (ifo->options & DHCPCD_INFORM) { @@ -2171,7 +2192,8 @@ dhcp_bind(struct interface *ifp) ifp->name, lease->renewaltime); } logger(ifp->ctx, - lease->addr.s_addr == state->addr.s_addr && + state->addr && + lease->addr.s_addr == state->addr->addr.s_addr && !(state->added & STATE_FAKE) ? LOG_DEBUG : LOG_INFO, "%s: leased %s for %"PRIu32" seconds", ifp->name, @@ -2227,6 +2249,9 @@ dhcp_lastlease(void *arg) struct interface *ifp = arg; struct dhcp_state *state = D_STATE(ifp); + logger(ifp->ctx, LOG_INFO, + "%s: timed out contacting a DHCP server, using last lease", + ifp->name); dhcp_bind(ifp); /* If we forked, stop here. */ if (ifp->ctx->options & DHCPCD_FORKED) @@ -2256,10 +2281,10 @@ dhcp_message_new(struct bootp **bootp, p = (*bootp)->vend; cookie = htonl(MAGIC_COOKIE); - memcpy(&cookie, p, sizeof(cookie)); + memcpy(p, &cookie, sizeof(cookie)); p += sizeof(cookie); - if (mask && mask->s_addr != INADDR_ANY) { + if (mask->s_addr != INADDR_ANY) { *p++ = DHO_SUBNETMASK; *p++ = sizeof(mask->s_addr); memcpy(p, &mask->s_addr, sizeof(mask->s_addr)); @@ -2297,9 +2322,9 @@ dhcp_arp_address(struct interface *ifp) if (ia == NULL) { struct dhcp_lease l; - get_lease(ifp->ctx, &l, state->offer, state->offer_len); + get_lease(ifp, &l, state->offer, state->offer_len); /* Add the address now, let the kernel handle DAD. */ - ipv4_addaddr(ifp, &l.addr, &l.net, &l.brd); + ipv4_addaddr(ifp, &l.addr, &l.mask, &l.brd); } else logger(ifp->ctx, LOG_INFO, "%s: waiting for DAD on %s", ifp->name, inet_ntoa(addr)); @@ -2309,9 +2334,9 @@ dhcp_arp_address(struct interface *ifp) if (ifp->options->options & DHCPCD_ARP && ia == NULL) { struct dhcp_lease l; - get_lease(ifp->ctx, &l, state->offer, state->offer_len); + get_lease(ifp, &l, state->offer, state->offer_len); logger(ifp->ctx, LOG_INFO, "%s: probing address %s/%d", - ifp->name, inet_ntoa(l.addr), inet_ntocidr(l.net)); + ifp->name, inet_ntoa(l.addr), inet_ntocidr(l.mask)); if ((astate = arp_new(ifp, &addr)) != NULL) { astate->probed_cb = dhcp_arp_probed; astate->conflicted_cb = dhcp_arp_conflicted; @@ -2358,7 +2383,7 @@ dhcp_static(struct interface *ifp) state->offer_len = dhcp_message_new(&state->offer, ia ? &ia->addr : &ifo->req_addr, - ia ? &ia->net : &ifo->req_mask); + ia ? &ia->mask : &ifo->req_mask); if (state->offer_len) dhcp_arp_bind(ifp); } @@ -2398,6 +2423,10 @@ dhcp_inform(struct interface *ifp) ifp->name); return; } + ia = ipv4_iffindaddr(ifp, &ifo->req_addr, NULL); + if (ia != NULL) + /* Netmask must be different, delete it. */ + ipv4_deladdr(ia, 1); state->offer_len = dhcp_message_new(&state->offer, &ifo->req_addr, &ifo->req_mask); if (dhcp_arp_address(ifp) == 0) @@ -2408,11 +2437,12 @@ dhcp_inform(struct interface *ifp) } } - state->offer_len = dhcp_message_new(&state->offer, &ia->addr, &ia->net); + state->addr = ia; + state->offer_len = dhcp_message_new(&state->offer, + &ia->addr, &ia->mask); if (state->offer_len) { state->xid = dhcp_xid(ifp); - get_lease(ifp->ctx, &state->lease, - state->offer, state->offer_len); + get_lease(ifp, &state->lease, state->offer, state->offer_len); send_inform(ifp); } } @@ -2427,7 +2457,8 @@ dhcp_reboot_newopts(struct interface *if return; ifo = ifp->options; if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) && - state->addr.s_addr != ifo->req_addr.s_addr) || + (state->addr == NULL || + state->addr->addr.s_addr != ifo->req_addr.s_addr)) || (oldopts & (DHCPCD_INFORM | DHCPCD_STATIC) && !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)))) { @@ -2672,6 +2703,12 @@ dhcp_handledhcp(struct interface *ifp, s #define LOGDHCP(l, m) \ log_dhcp((l), (m), ifp, bootp, bootp_len, from, 1) + if (bootp->op != BOOTREPLY) { + logger(ifp->ctx, LOG_DEBUG, "%s: op (%d) is not BOOTREPLY", + ifp->name, bootp->op); + return; + } + /* Ensure packet is for us */ if (ifp->hwlen <= sizeof(bootp->chaddr) && memcmp(bootp->chaddr, ifp->hwaddr, ifp->hwlen)) @@ -2901,7 +2938,7 @@ dhcp_handledhcp(struct interface *ifp, s LOGDHCP(LOG_WARNING, "declined duplicate address"); if (type) dhcp_decline(ifp); - ipv4_deladdr(ifp, &ia->addr, &ia->net, 0); + ipv4_deladdr(ia, 0); eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); eloop_timeout_add_sec(ifp->ctx->eloop, DHCP_RAND_MAX, dhcp_discover, ifp); @@ -3103,69 +3140,59 @@ dhcp_handlepacket(void *arg) /* Need this API due to BPF */ flags = 0; bootp = NULL; - while (!(flags & RAW_EOF)) { - bytes = (size_t)if_readrawpacket(ifp, ETHERTYPE_IP, - buf, sizeof(buf), &flags); - if ((ssize_t)bytes == -1) { - logger(ifp->ctx, LOG_ERR, - "%s: dhcp if_readrawpacket: %m", ifp->name); - dhcp_close(ifp); - arp_close(ifp); - break; - } - if (valid_udp_packet(buf, bytes, - &from, flags & RAW_PARTIALCSUM) == -1) - { - logger(ifp->ctx, LOG_ERR, - "%s: invalid UDP packet from %s", - ifp->name, inet_ntoa(from)); - continue; - } - i = whitelisted_ip(ifp->options, from.s_addr); - if (i == 0) { - logger(ifp->ctx, LOG_WARNING, - "%s: non whitelisted DHCP packet from %s", - ifp->name, inet_ntoa(from)); - continue; - } else if (i != 1 && - blacklisted_ip(ifp->options, from.s_addr) == 1) - { - logger(ifp->ctx, LOG_WARNING, - "%s: blacklisted DHCP packet from %s", - ifp->name, inet_ntoa(from)); - continue; - } - if (ifp->flags & IFF_POINTOPOINT && - state->brd.s_addr != from.s_addr) - { - logger(ifp->ctx, LOG_WARNING, - "%s: server %s is not destination", - ifp->name, inet_ntoa(from)); - } - /* - * DHCP has a variable option area rather than a fixed - * vendor area. - * Because DHCP uses the BOOTP protocol it should - * still send BOOTP sized packets to be RFC compliant. - * However some servers send a truncated vendor area. - * dhcpcd can work fine without the vendor area being sent. - */ - bytes = get_udp_data(&bootp, buf); - if (bytes < offsetof(struct bootp, vend)) { - logger(ifp->ctx, LOG_ERR, - "%s: truncated packet (%zu) from %s", - ifp->name, bytes, inet_ntoa(from)); - continue; - } - /* But to make our IS_DHCP macro easy, ensure the vendor - * area has at least 4 octets. */ - while (bytes < offsetof(struct bootp, vend) + 4) - bootp[bytes++] = '\0'; - - dhcp_handledhcp(ifp, (struct bootp *)bootp, bytes, &from); - if (state->raw_fd == -1) - break; + bytes = (size_t)if_readraw(ifp, state->raw_fd,buf, sizeof(buf), &flags); + if ((ssize_t)bytes == -1) { + logger(ifp->ctx, LOG_ERR, + "%s: dhcp if_readrawpacket: %m", ifp->name); + dhcp_close(ifp); + arp_close(ifp); + return; + } + if (valid_udp_packet(buf, bytes, &from, flags & RAW_PARTIALCSUM) == -1) + { + logger(ifp->ctx, LOG_ERR, "%s: invalid UDP packet from %s", + ifp->name, inet_ntoa(from)); + return; + } + i = whitelisted_ip(ifp->options, from.s_addr); + if (i == 0) { + logger(ifp->ctx, LOG_WARNING, + "%s: non whitelisted DHCP packet from %s", + ifp->name, inet_ntoa(from)); + return; + } else if (i != 1 && blacklisted_ip(ifp->options, from.s_addr) == 1) { + logger(ifp->ctx, LOG_WARNING, + "%s: blacklisted DHCP packet from %s", + ifp->name, inet_ntoa(from)); + return; + } + if (ifp->flags & IFF_POINTOPOINT && + (state->addr == NULL || state->addr->brd.s_addr != from.s_addr)) + { + logger(ifp->ctx, LOG_WARNING, + "%s: server %s is not destination", + ifp->name, inet_ntoa(from)); + } + /* + * DHCP has a variable option area rather than a fixed vendor area. + * Because DHCP uses the BOOTP protocol it should still send BOOTP + * sized packets to be RFC compliant. + * However some servers send a truncated vendor area. + * dhcpcd can work fine without the vendor area being sent. + */ + bytes = get_udp_data(&bootp, buf); + if (bytes < offsetof(struct bootp, vend)) { + logger(ifp->ctx, LOG_ERR, + "%s: truncated packet (%zu) from %s", + ifp->name, bytes, inet_ntoa(from)); + return; } + /* But to make our IS_DHCP macro easy, ensure the vendor + * area has at least 4 octets. */ + while (bytes < offsetof(struct bootp, vend) + 4) + bootp[bytes++] = '\0'; + + dhcp_handledhcp(ifp, (struct bootp *)bootp, bytes, &from); } static void @@ -3193,7 +3220,7 @@ dhcp_open(struct interface *ifp) state = D_STATE(ifp); if (state->raw_fd == -1) { - state->raw_fd = if_openrawsocket(ifp, ETHERTYPE_IP); + state->raw_fd = if_openraw(ifp, ETHERTYPE_IP); if (state->raw_fd == -1) { if (errno == ENOENT) { logger(ifp->ctx, LOG_ERR, @@ -3293,7 +3320,7 @@ dhcp_init(struct interface *ifp) state->raw_fd = -1; /* Now is a good time to find IPv4 routes */ - if_initrt(ifp); + if_initrt(ifp->ctx); } state->state = DHS_INIT; @@ -3455,11 +3482,13 @@ dhcp_start1(void *arg) } } if (state->offer) { - get_lease(ifp->ctx, &state->lease, - state->offer, state->offer_len); + struct ipv4_addr *ia; + + get_lease(ifp, &state->lease, state->offer, state->offer_len); state->lease.frominfo = 1; if (state->new == NULL && - ipv4_iffindaddr(ifp, &state->lease.addr, &state->lease.net)) + (ia = ipv4_iffindaddr(ifp, + &state->lease.addr, &state->lease.mask)) != NULL) { /* We still have the IP address from the last lease. * Fake add the address and routes from it so the lease @@ -3468,19 +3497,17 @@ dhcp_start1(void *arg) if (state->new) { memcpy(state->new, state->offer, state->offer_len); - state->addr = state->lease.addr; - state->net = state->lease.net; + state->new_len = state->offer_len; + state->addr = ia; state->added |= STATE_ADDED | STATE_FAKE; ipv4_buildroutes(ifp->ctx); } else logger(ifp->ctx, LOG_ERR, "%s: %m", __func__); } if (!IS_DHCP(state->offer)) { - if (state->offer->yiaddr == state->addr.s_addr) { - free(state->offer); - state->offer = NULL; - state->offer_len = 0; - } + free(state->offer); + state->offer = NULL; + state->offer_len = 0; } else if (!(ifo->options & DHCPCD_LASTLEASE_EXTEND) && state->lease.leasetime != ~0U && stat(state->leasefile, &st) == 0) @@ -3543,6 +3570,13 @@ dhcp_start(struct interface *ifp) if (!(ifp->options->options & DHCPCD_IPV4)) return; + /* If we haven't been given a netmask for our requested address, + * set it now. */ + if (ifp->options->req_addr.s_addr != INADDR_ANY && + ifp->options->req_mask.s_addr == INADDR_ANY) + ifp->options->req_mask.s_addr = + ipv4_getnetmask(ifp->options->req_addr.s_addr); + /* If we haven't specified a ClientID and our hardware address * length is greater than BOOTP CHADDR then we enforce a ClientID * of the hardware address family and the hardware address. @@ -3594,29 +3628,22 @@ dhcp_abort(struct interface *ifp) } void -dhcp_handleifa(int cmd, struct interface *ifp, - const struct in_addr *addr, - const struct in_addr *net, - const struct in_addr *brd, - int flags) +dhcp_handleifa(int cmd, struct ipv4_addr *ia) { + struct interface *ifp; struct dhcp_state *state; struct if_options *ifo; uint8_t i; + ifp = ia->iface; state = D_STATE(ifp); if (state == NULL) return; if (cmd == RTM_DELADDR) { - if (state->addr.s_addr == addr->s_addr && - state->net.s_addr == net->s_addr && - state->brd.s_addr == brd->s_addr) - { + if (IPV4_BRD_EQ(state->addr, ia)) { logger(ifp->ctx, LOG_INFO, - "%s: removing IP address %s/%d", - ifp->name, inet_ntoa(state->addr), - inet_ntocidr(state->net)); + "%s: removing IP address %s", ifp->name, ia->saddr); dhcp_drop(ifp, "EXPIRE"); } return; @@ -3626,10 +3653,8 @@ dhcp_handleifa(int cmd, struct interface return; #ifdef IN_IFF_NOTUSEABLE - if (flags & IN_IFF_NOTUSEABLE) + if (ia->addr_flags & IN_IFF_NOTUSEABLE) return; -#else - UNUSED(flags); #endif ifo = ifp->options; @@ -3646,14 +3671,13 @@ dhcp_handleifa(int cmd, struct interface free(state->old); state->old = state->new; - state->new_len = dhcp_message_new(&state->new, addr, net); + state->new_len = dhcp_message_new(&state->new, &ia->addr, &ia->mask); if (state->new == NULL) return; - state->brd = *brd; if (ifp->flags & IFF_POINTOPOINT) { for (i = 1; i < 255; i++) if (i != DHO_ROUTER && has_option_mask(ifo->dstmask,i)) - dhcp_message_add_addr(state->new, i, *brd); + dhcp_message_add_addr(state->new, i, ia->brd); } state->reason = "STATIC"; ipv4_buildroutes(ifp->ctx); @@ -3661,9 +3685,8 @@ dhcp_handleifa(int cmd, struct interface if (ifo->options & DHCPCD_INFORM) { state->state = DHS_INFORM; state->xid = dhcp_xid(ifp); - state->lease.server = *brd; - state->addr = *addr; - state->net = *net; + state->lease.server.s_addr = INADDR_ANY; + state->addr = ia; dhcp_inform(ifp); } } Index: src/external/bsd/dhcpcd/dist/dhcp.h diff -u src/external/bsd/dhcpcd/dist/dhcp.h:1.16 src/external/bsd/dhcpcd/dist/dhcp.h:1.17 --- src/external/bsd/dhcpcd/dist/dhcp.h:1.16 Thu May 26 09:09:47 2016 +++ src/external/bsd/dhcpcd/dist/dhcp.h Fri Jun 17 19:42:31 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: dhcp.h,v 1.16 2016/05/26 09:09:47 prlw1 Exp $ */ +/* $NetBSD: dhcp.h,v 1.17 2016/06/17 19:42:31 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -40,27 +40,27 @@ #include "auth.h" #include "dhcp-common.h" -/* UDP port numbers for DHCP */ -#define DHCP_SERVER_PORT 67 -#define DHCP_CLIENT_PORT 68 - -#define MAGIC_COOKIE 0x63825363 -#define BROADCAST_FLAG 0x8000 - -/* DHCP message OP code */ -#define DHCP_BOOTREQUEST 1 -#define DHCP_BOOTREPLY 2 +/* UDP port numbers for BOOTP */ +#define BOOTPS 67 +#define BOOTPC 68 + +#define MAGIC_COOKIE 0x63825363 +#define BROADCAST_FLAG 0x8000 + +/* BOOTP message OP code */ +#define BOOTREQUEST 1 +#define BOOTREPLY 2 /* DHCP message type */ -#define DHCP_DISCOVER 1 -#define DHCP_OFFER 2 -#define DHCP_REQUEST 3 -#define DHCP_DECLINE 4 -#define DHCP_ACK 5 -#define DHCP_NAK 6 -#define DHCP_RELEASE 7 -#define DHCP_INFORM 8 -#define DHCP_FORCERENEW 9 +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 +#define DHCP_FORCERENEW 9 /* Constants taken from RFC 2131. */ #define T1 0.5 @@ -173,7 +173,7 @@ struct bootp { struct dhcp_lease { struct in_addr addr; - struct in_addr net; + struct in_addr mask; struct in_addr brd; uint32_t leasetime; uint32_t renewaltime; @@ -215,9 +215,7 @@ struct dhcp_state { int socket; int raw_fd; - struct in_addr addr; - struct in_addr net; - struct in_addr brd; + struct ipv4_addr *addr; uint8_t added; char leasefile[sizeof(LEASEFILE) + IF_NAMESIZE + (IF_SSIDLEN * 4)]; @@ -253,10 +251,7 @@ struct rt_head *dhcp_get_routes(struct i ssize_t dhcp_env(char **, const char *, const struct bootp *, size_t, const struct interface *); -void dhcp_handleifa(int, struct interface *, - const struct in_addr *, const struct in_addr *, const struct in_addr *, - int); - +void dhcp_handleifa(int, struct ipv4_addr *); void dhcp_drop(struct interface *, const char *); void dhcp_start(struct interface *); void dhcp_abort(struct interface *); Index: src/external/bsd/dhcpcd/dist/if.h diff -u src/external/bsd/dhcpcd/dist/if.h:1.16 src/external/bsd/dhcpcd/dist/if.h:1.17 --- src/external/bsd/dhcpcd/dist/if.h:1.16 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/if.h Fri Jun 17 19:42:32 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: if.h,v 1.16 2016/05/09 10:15:59 roy Exp $ */ +/* $NetBSD: if.h,v 1.17 2016/06/17 19:42:32 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -82,13 +82,14 @@ ((addr & IN_CLASSB_NET) == 0xc0a80000)) #endif -#define RAW_EOF 1 << 0 -#define RAW_PARTIALCSUM 2 << 0 +#define RAW_PARTIALCSUM 1 << 0 #ifdef __sun -/* platform does not supply AF_LINK with getifaddrs. */ +/* Solaris getifaddrs is very un-suitable for dhcpcd. + * See if-sun.c for details why. */ struct ifaddrs; int if_getifaddrs(struct ifaddrs **); +#define getifaddrs if_getifaddrs #else #define GETIFADDRS_AFLINK #endif @@ -114,7 +115,7 @@ int if_opensockets(struct dhcpcd_ctx *); int if_opensockets_os(struct dhcpcd_ctx *); void if_closesockets(struct dhcpcd_ctx *); void if_closesockets_os(struct dhcpcd_ctx *); -int if_managelink(struct dhcpcd_ctx *); +int if_handlelink(struct dhcpcd_ctx *); /* dhcpcd uses the same routing flags as BSD. * If the platform doesn't use these flags, @@ -141,23 +142,17 @@ int if_managelink(struct dhcpcd_ctx *); #ifdef INET extern const char *if_pfname; -int if_openrawsocket(struct interface *, uint16_t); -ssize_t if_sendrawpacket(const struct interface *, - uint16_t, const void *, size_t); -ssize_t if_readrawpacket(struct interface *, uint16_t, void *, size_t, int *); - -int if_address(const struct interface *, - const struct in_addr *, const struct in_addr *, - const struct in_addr *, int); -#define if_addaddress(ifp, addr, net, brd) \ - if_address(ifp, addr, net, brd, 1) -#define if_deladdress(ifp, addr, net) \ - if_address(ifp, addr, net, NULL, -1) +int if_openraw(struct interface *, uint16_t); +ssize_t if_sendraw(const struct interface *, int, uint16_t, + const void *, size_t); +ssize_t if_readraw(struct interface *, int, void *, size_t, int *); +void if_closeraw(struct interface *, int); +int if_address(unsigned char, const struct ipv4_addr *); int if_addrflags(const struct in_addr *, const struct interface *); int if_route(unsigned char, const struct rt *rt); -int if_initrt(struct interface *); +int if_initrt(struct dhcpcd_ctx *); #endif #ifdef INET6 @@ -170,15 +165,12 @@ int ip6_temp_valid_lifetime(const char * #define ip6_use_tempaddr(a) (0) #endif -int if_address6(const struct ipv6_addr *, int); -#define if_addaddress6(a) if_address6(a, 1) -#define if_deladdress6(a) if_address6(a, -1) - +int if_address6(unsigned char, const struct ipv6_addr *); int if_addrflags6(const struct in6_addr *, const struct interface *); int if_getlifetime6(struct ipv6_addr *); int if_route6(unsigned char, const struct rt6 *rt); -int if_initrt6(struct interface *); +int if_initrt6(struct dhcpcd_ctx *); #else #define if_checkipv6(a, b, c) (-1) #endif Index: src/external/bsd/dhcpcd/dist/ipv4ll.c diff -u src/external/bsd/dhcpcd/dist/ipv4ll.c:1.16 src/external/bsd/dhcpcd/dist/ipv4ll.c:1.17 --- src/external/bsd/dhcpcd/dist/ipv4ll.c:1.16 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/ipv4ll.c Fri Jun 17 19:42:32 2016 @@ -1,9 +1,9 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: ipv4ll.c,v 1.16 2016/05/09 10:15:59 roy Exp $"); + __RCSID("$NetBSD: ipv4ll.c,v 1.17 2016/06/17 19:42:32 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> + * Copyright (c) 2006-2016 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -48,11 +48,15 @@ #include "ipv4ll.h" #include "script.h" -const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) }; -const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BRDC) }; +static const struct in_addr inaddr_llmask = { + .s_addr = HTONL(LINKLOCAL_MASK) +}; +static const struct in_addr inaddr_llbcast = { + .s_addr = HTONL(LINKLOCAL_BCAST) +}; static in_addr_t -ipv4ll_pick_addr(const struct arp_state *astate) +ipv4ll_pickaddr(struct arp_state *astate) { struct in_addr addr; struct ipv4ll_state *istate; @@ -78,8 +82,7 @@ ipv4ll_pick_addr(const struct arp_state } while (ipv4_findaddr(astate->iface->ctx, &addr) != NULL); /* Restore the original random state */ - setstate(astate->iface->ctx->randomstate); - + setstate(istate->arp->iface->ctx->randomstate); return addr.s_addr; } @@ -91,7 +94,7 @@ ipv4ll_subnet_route(const struct interfa assert(ifp != NULL); if ((state = IPV4LL_CSTATE(ifp)) == NULL || - state->addr.s_addr == INADDR_ANY) + state->addr == NULL) return NULL; if ((rt = calloc(1, sizeof(*rt))) == NULL) { @@ -99,10 +102,10 @@ ipv4ll_subnet_route(const struct interfa return NULL; } rt->iface = ifp; - rt->dest.s_addr = state->addr.s_addr & inaddr_llmask.s_addr; - rt->net = inaddr_llmask; + rt->dest.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr; + rt->mask.s_addr = state->addr->mask.s_addr; rt->gate.s_addr = INADDR_ANY; - rt->src = state->addr; + rt->src = state->addr->addr; return rt; } @@ -114,7 +117,7 @@ ipv4ll_default_route(const struct interf assert(ifp != NULL); if ((state = IPV4LL_CSTATE(ifp)) == NULL || - state->addr.s_addr == INADDR_ANY) + state->addr == NULL) return NULL; if ((rt = calloc(1, sizeof(*rt))) == NULL) { @@ -123,9 +126,9 @@ ipv4ll_default_route(const struct interf } rt->iface = ifp; rt->dest.s_addr = INADDR_ANY; - rt->net.s_addr = INADDR_ANY; + rt->mask.s_addr = INADDR_ANY; rt->gate.s_addr = INADDR_ANY; - rt->src = state->addr; + rt->src = state->addr->addr; return rt; } @@ -145,18 +148,18 @@ ipv4ll_env(char **env, const char *prefi /* Emulate a DHCP environment */ if (asprintf(&env[0], "%s%sip_address=%s", - prefix, pf, inet_ntoa(state->addr)) == -1) + prefix, pf, inet_ntoa(state->addr->addr)) == -1) return -1; if (asprintf(&env[1], "%s%ssubnet_mask=%s", - prefix, pf, inet_ntoa(inaddr_llmask)) == -1) + prefix, pf, inet_ntoa(state->addr->mask)) == -1) return -1; if (asprintf(&env[2], "%s%ssubnet_cidr=%d", - prefix, pf, inet_ntocidr(inaddr_llmask)) == -1) + prefix, pf, inet_ntocidr(state->addr->mask)) == -1) return -1; if (asprintf(&env[3], "%s%sbroadcast_address=%s", - prefix, pf, inet_ntoa(inaddr_llbcast)) == -1) + prefix, pf, inet_ntoa(state->addr->brd)) == -1) return -1; - netnum.s_addr = state->addr.s_addr & inaddr_llmask.s_addr; + netnum.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr; if (asprintf(&env[4], "%s%snetwork_number=%s", prefix, pf, inet_ntoa(netnum)) == -1) return -1; @@ -198,14 +201,14 @@ ipv4ll_probed(struct arp_state *astate) ifp->name, inet_ntoa(astate->addr)); #endif test: - state->addr = astate->addr; + state->addr = ia; if (ifp->ctx->options & DHCPCD_TEST) { script_runreason(ifp, "TEST"); eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS); return; } timespecclear(&state->defend); - if_initrt(ifp); + if_initrt(ifp->ctx); ipv4_buildroutes(ifp->ctx); arp_announce(astate); script_runreason(ifp, "IPV4LL"); @@ -244,6 +247,7 @@ ipv4ll_conflicted(struct arp_state *asta ifp = astate->iface; state = IPV4LL_STATE(ifp); assert(state != NULL); + assert(state->addr != NULL); fail = 0; /* RFC 3927 2.2.1, Probe Conflict Detection */ @@ -253,9 +257,9 @@ ipv4ll_conflicted(struct arp_state *asta fail = astate->addr.s_addr; /* RFC 3927 2.5, Conflict Defense */ - if (IN_LINKLOCAL(ntohl(state->addr.s_addr)) && - amsg && amsg->sip.s_addr == state->addr.s_addr) - fail = state->addr.s_addr; + if (IN_LINKLOCAL(ntohl(state->addr->addr.s_addr)) && + amsg && amsg->sip.s_addr == state->addr->addr.s_addr) + fail = state->addr->addr.s_addr; if (fail == 0) return; @@ -263,7 +267,7 @@ ipv4ll_conflicted(struct arp_state *asta astate->failed.s_addr = fail; arp_report_conflicted(astate, amsg); - if (astate->failed.s_addr == state->addr.s_addr) { + if (astate->failed.s_addr == state->addr->addr.s_addr) { struct timespec now, defend; /* RFC 3927 Section 2.5 says a defence should @@ -280,24 +284,23 @@ ipv4ll_conflicted(struct arp_state *asta if (timespeccmp(&defend, &now, >)) logger(ifp->ctx, LOG_WARNING, "%s: IPv4LL %d second defence failed for %s", - ifp->name, DEFEND_INTERVAL, - inet_ntoa(state->addr)); + ifp->name, DEFEND_INTERVAL, state->addr->saddr); else if (arp_request(ifp, - state->addr.s_addr, state->addr.s_addr) == -1) + state->addr->addr.s_addr, state->addr->addr.s_addr) == -1) logger(ifp->ctx, LOG_ERR, "%s: arp_request: %m", __func__); else { logger(ifp->ctx, LOG_DEBUG, "%s: defended IPv4LL address %s", - ifp->name, inet_ntoa(state->addr)); + ifp->name, state->addr->saddr); state->defend = now; return; } - ipv4_deladdr(ifp, &state->addr, &inaddr_llmask, 1); + ipv4_deladdr(state->addr, 1); state->down = 1; + state->addr = NULL; script_runreason(ifp, "IPV4LL"); - state->addr.s_addr = INADDR_ANY; } arp_cancel(astate); @@ -305,7 +308,7 @@ ipv4ll_conflicted(struct arp_state *asta logger(ifp->ctx, LOG_ERR, "%s: failed to acquire an IPv4LL address", ifp->name); - astate->addr.s_addr = ipv4ll_pick_addr(astate); + astate->addr.s_addr = ipv4ll_pickaddr(astate); eloop_timeout_add_sec(ifp->ctx->eloop, state->conflicts >= MAX_CONFLICTS ? RATE_LIMIT_INTERVAL : PROBE_WAIT, @@ -338,8 +341,6 @@ ipv4ll_start(void *arg) syslog(LOG_ERR, "%s: calloc %m", __func__); return; } - - state->addr.s_addr = INADDR_ANY; } if (state->arp != NULL) @@ -384,7 +385,7 @@ ipv4ll_start(void *arg) ia = ipv4_iffindlladdr(ifp); #ifdef IN_IFF_TENTATIVE if (ia != NULL && ia->addr_flags & IN_IFF_DUPLICATED) { - ipv4_deladdr(ifp, &ia->addr, &ia->net, 0); + ipv4_deladdr(ia, 0); ia = NULL; } #endif @@ -398,7 +399,7 @@ ipv4ll_start(void *arg) return; } logger(ifp->ctx, LOG_INFO, "%s: using IPv4LL address %s", - ifp->name, inet_ntoa(astate->addr)); + ifp->name, ia->saddr); #endif ipv4ll_probed(astate); return; @@ -406,7 +407,7 @@ ipv4ll_start(void *arg) logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address", ifp->name); - astate->addr.s_addr = ipv4ll_pick_addr(astate); + astate->addr.s_addr = ipv4ll_pickaddr(astate); #ifdef IN_IFF_TENTATIVE ipv4ll_probed(astate); #else @@ -434,9 +435,9 @@ ipv4ll_freedrop(struct interface *ifp, i if (drop && (ifp->options->options & DHCPCD_NODROP) != DHCPCD_NODROP) { struct ipv4_state *istate; - if (state && state->addr.s_addr != INADDR_ANY) { - ipv4_deladdr(ifp, &state->addr, &inaddr_llmask, 1); - state->addr.s_addr = INADDR_ANY; + if (state && state->addr != NULL) { + ipv4_deladdr(state->addr, 1); + state->addr = NULL; dropped = 1; } @@ -446,8 +447,7 @@ ipv4ll_freedrop(struct interface *ifp, i TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) { if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) { - ipv4_deladdr(ifp, &ia->addr, - &ia->net, 0); + ipv4_deladdr(ia, 0); dropped = 1; } } @@ -479,12 +479,11 @@ ipv4ll_handlert(struct dhcpcd_ctx *ctx, /* If any interface is running IPv4LL, rebuild our routing table. */ TAILQ_FOREACH(ifp, ctx->ifaces, next) { - if (IPV4LL_STATE_RUNNING(ifp)) + if (IPV4LL_STATE_RUNNING(ifp)) { + if_initrt(ifp->ctx); + ipv4_buildroutes(ifp->ctx); break; - } - if (ifp != NULL) { - if_initrt(ifp); - ipv4_buildroutes(ctx); + } } return 0; Index: src/external/bsd/dhcpcd/dist/dhcp6.c diff -u src/external/bsd/dhcpcd/dist/dhcp6.c:1.21 src/external/bsd/dhcpcd/dist/dhcp6.c:1.22 --- src/external/bsd/dhcpcd/dist/dhcp6.c:1.21 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/dhcp6.c Fri Jun 17 19:42:31 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: dhcp6.c,v 1.21 2016/05/09 10:15:59 roy Exp $"); + __RCSID("$NetBSD: dhcp6.c,v 1.22 2016/06/17 19:42:31 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -64,10 +64,6 @@ #include "compat/bitops.h" #endif -#ifndef __UNCONST -#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) -#endif - /* DHCPCD Project has been assigned an IANA PEN of 40712 */ #define DHCPCD_IANA_PEN 40712 @@ -320,7 +316,7 @@ dhcp6_updateelapsed(struct interface *if if (co == NULL) return -1; - o = __UNCONST(co); + o = UNCONST(co); state = D6_STATE(ifp); clock_gettime(CLOCK_MONOTONIC, &tv); if (state->RTC == 0) { @@ -408,14 +404,29 @@ dhcp6_delegateaddr(struct in6_addr *addr } if (sla == NULL || sla->sla_set == 0) { + /* No SLA set, so make an assumption of + * desired SLA and prefix length. */ asla.sla = ifp->index; asla.prefix_len = 0; + asla.sla_set = 0; + sla = &asla; + } else if (sla->sla == 0 && sla->prefix_len == 0) { + /* An SLA of 0 was set with no prefix length specified. + * This means we delegate the whole prefix. */ + asla.sla = sla->sla; + asla.prefix_len = prefix->prefix_len; + asla.sla_set = 0; sla = &asla; } else if (sla->prefix_len == 0) { + /* An SLA was given, but prefix length was not. + * We need to work out a suitable prefix length for + * potentially more than one interface. */ asla.sla = sla->sla; asla.prefix_len = 0; + asla.sla_set = 0; sla = &asla; } + if (sla->prefix_len == 0) { uint32_t sla_max; int bits; @@ -954,7 +965,7 @@ dhcp6_update_auth(struct interface *ifp, if (co == NULL) return -1; - o = __UNCONST(co); + o = UNCONST(co); state = D6_STATE(ifp); return dhcp_auth_encode(&ifp->options->auth, state->auth.token, @@ -2393,7 +2404,7 @@ dhcp6_ifdelegateaddr(struct interface *i ia->flags = IPV6_AF_NEW | IPV6_AF_ONLINK; ia->dadcallback = dhcp6_dadcallback; memcpy(&ia->iaid, &prefix->iaid, sizeof(ia->iaid)); - ia->created = ia->acquired = prefix->acquired; + ia->created = prefix->acquired; ia->addr = daddr; TAILQ_INSERT_TAIL(&state->addrs, ia, next); @@ -2402,6 +2413,7 @@ dhcp6_ifdelegateaddr(struct interface *i ia->delegating_prefix = prefix; ia->prefix = addr; ia->prefix_len = (uint8_t)pfxlen; + ia->acquired = prefix->acquired; ia->prefix_pltime = prefix->prefix_pltime; ia->prefix_vltime = prefix->prefix_vltime; @@ -2468,6 +2480,11 @@ dhcp6_delegate_prefix(struct interface * ifo = ifp->options; state = D6_STATE(ifp); + /* Clear the logged flag. */ + TAILQ_FOREACH(ap, &state->addrs, next) { + ap->flags &= ~IPV6_AF_DELEGATEDLOG; + } + TAILQ_FOREACH(ifd, ifp->ctx->ifaces, next) { if (!ifd->active) continue; @@ -2476,11 +2493,15 @@ dhcp6_delegate_prefix(struct interface * TAILQ_FOREACH(ap, &state->addrs, next) { if (!(ap->flags & IPV6_AF_DELEGATEDPFX)) continue; - if (ap->flags & IPV6_AF_NEW) { - ap->flags &= ~IPV6_AF_NEW; - logger(ifp->ctx, LOG_DEBUG, + if (!(ap->flags & IPV6_AF_DELEGATEDLOG)) { + /* We only want to log this the once as we loop + * through many interfaces first. */ + ap->flags |= IPV6_AF_DELEGATEDLOG; + logger(ifp->ctx, + ap->flags & IPV6_AF_NEW ?LOG_INFO:LOG_DEBUG, "%s: delegated prefix %s", ifp->name, ap->saddr); + ap->flags &= ~IPV6_AF_NEW; } for (i = 0; i < ifo->ia_len; i++) { ia = &ifo->ia[i]; @@ -2527,7 +2548,7 @@ dhcp6_delegate_prefix(struct interface * if (k && !carrier_warned) { ifd_state = D6_STATE(ifd); ipv6_addaddrs(&ifd_state->addrs); - if_initrt6(ifd); + if_initrt6(ifd->ctx); ipv6_buildroutes(ifd->ctx); dhcp6_script_try_run(ifd, 1); } @@ -2594,7 +2615,7 @@ dhcp6_find_delegates(struct interface *i state = D6_STATE(ifp); state->state = DH6S_DELEGATED; ipv6_addaddrs(&state->addrs); - if_initrt6(ifp); + if_initrt6(ifp->ctx); ipv6_buildroutes(ifp->ctx); dhcp6_script_try_run(ifp, 1); } @@ -2955,7 +2976,12 @@ dhcp6_handledata(void *arg) case DHCP6_ADVERTISE: if (state->state == DH6S_REQUEST) /* rapid commit */ break; - ap = TAILQ_FIRST(&state->addrs); + TAILQ_FOREACH(ap, &state->addrs, next) { + if (!(ap->flags & IPV6_AF_REQUEST)) + break; + } + if (ap == NULL) + ap = TAILQ_FIRST(&state->addrs); logger(ifp->ctx, LOG_INFO, "%s: ADV %s from %s", ifp->name, ap->saddr, ctx->sfrom); if (ifp->ctx->options & DHCPCD_TEST) @@ -3095,7 +3121,7 @@ recv: else if (state->expire == 0) logger(ifp->ctx, has_new ? LOG_INFO : LOG_DEBUG, "%s: will expire", ifp->name); - if_initrt6(ifp); + if_initrt6(ifp->ctx); ipv6_buildroutes(ifp->ctx); dhcp6_writelease(ifp); dhcp6_delegate_prefix(ifp); @@ -3426,6 +3452,20 @@ dhcp6_free(struct interface *ifp) dhcp6_freedrop(ifp, 0, NULL); } +void dhcp6_dropnondelegates(struct interface *ifp) +{ + struct dhcp6_state *state; + struct ipv6_addr *ia; + + if ((state = D6_STATE(ifp)) == NULL) + return; + TAILQ_FOREACH(ia, &state->addrs, next) { + if (ia->flags & (IPV6_AF_DELEGATED | IPV6_AF_DELEGATEDPFX)) + return; + } + dhcp6_drop(ifp, "EXPIRE6"); +} + void dhcp6_handleifa(struct dhcpcd_ctx *ctx, int cmd, const char *ifname, const struct in6_addr *addr, int flags) Index: src/external/bsd/dhcpcd/dist/if.c diff -u src/external/bsd/dhcpcd/dist/if.c:1.21 src/external/bsd/dhcpcd/dist/if.c:1.22 --- src/external/bsd/dhcpcd/dist/if.c:1.21 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/if.c Fri Jun 17 19:42:31 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: if.c,v 1.21 2016/05/09 10:15:59 roy Exp $"); + __RCSID("$NetBSD: if.c,v 1.22 2016/06/17 19:42:31 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -214,14 +214,13 @@ static void if_learnaddrs(struct dhcpcd_ addr = (void *)ifa->ifa_addr; net = (void *)ifa->ifa_netmask; if (ifa->ifa_flags & IFF_POINTOPOINT) - brd = (const struct sockaddr_in *) - (void *)ifa->ifa_dstaddr; + brd = (void *)ifa->ifa_dstaddr; else brd = (void *)ifa->ifa_broadaddr; ifa_flags = if_addrflags(&addr->sin_addr, ifp); ipv4_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name, - &addr->sin_addr, &net->sin_addr, &brd->sin_addr, - ifa_flags); + &addr->sin_addr, &net->sin_addr, + brd ? &brd->sin_addr : NULL, ifa_flags); break; #endif #ifdef INET6 @@ -274,16 +273,11 @@ if_discover(struct dhcpcd_ctx *ctx, int const struct sockaddr_ll *sll; #endif -#ifdef GETIFADDRS_AFLINK if (getifaddrs(&ifaddrs) == -1) return NULL; -#else - if (if_getifaddrs(&ifaddrs) == -1) - return NULL; -#endif - ifs = malloc(sizeof(*ifs)); - if (ifs == NULL) - return NULL; + + if ((ifs = malloc(sizeof(*ifs))) == NULL) + goto failed; TAILQ_INIT(ifs); for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { @@ -469,7 +463,7 @@ if_discover(struct dhcpcd_ctx *ctx, int } ifp->hwlen = sdl->sdl_alen; #ifndef CLLADDR -# define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen)) +# define CLLADDR(s) (const void *)((s)->sdl_data + (s)->sdl_nlen) #endif memcpy(ifp->hwaddr, CLLADDR(sdl), ifp->hwlen); #elif AF_PACKET @@ -557,16 +551,9 @@ if_discover(struct dhcpcd_ctx *ctx, int TAILQ_INSERT_TAIL(ifs, ifp, next); } -#ifdef GETIFADDRS_AFLINK - { -#else + if_learnaddrs(ctx, ifs, ifaddrs); +failed: freeifaddrs(ifaddrs); - if (getifaddrs(&ifaddrs) != -1) { -#endif - if_learnaddrs(ctx, ifs, ifaddrs); - freeifaddrs(ifaddrs); - } - return ifs; } Index: src/external/bsd/dhcpcd/dist/dhcpcd.c diff -u src/external/bsd/dhcpcd/dist/dhcpcd.c:1.34 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.35 --- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.34 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/dhcpcd.c Fri Jun 17 19:42:31 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: dhcpcd.c,v 1.34 2016/05/09 10:15:59 roy Exp $"); + __RCSID("$NetBSD: dhcpcd.c,v 1.35 2016/06/17 19:42:31 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -423,14 +423,17 @@ configure_interface1(struct interface *i if (ifo->options & DHCPCD_RELEASE) ifo->options &= ~DHCPCD_PERSISTENT; - if (ifp->flags & IFF_POINTOPOINT && !(ifo->options & DHCPCD_INFORM)) - ifo->options |= DHCPCD_STATIC; + if (ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) { + ifo->options &= ~DHCPCD_ARP; + if (!(ifp->flags & IFF_MULTICAST)) + ifo->options &= ~DHCPCD_IPV6RS; + if (!(ifo->options & DHCPCD_INFORM)) + ifo->options |= DHCPCD_STATIC; + } if (ifp->flags & IFF_NOARP || + !(ifo->options & DHCPCD_ARP) || ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)) ifo->options &= ~DHCPCD_IPV4LL; - if (ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK) || - !(ifp->flags & IFF_MULTICAST)) - ifo->options &= ~DHCPCD_IPV6RS; if (ifo->metric != -1) ifp->metric = (unsigned int)ifo->metric; @@ -989,13 +992,13 @@ dhcpcd_activateinterface(struct interfac } static void -handle_link(void *arg) +dhcpcd_handlelink(void *arg) { struct dhcpcd_ctx *ctx; ctx = arg; - if (if_managelink(ctx) == -1) { - logger(ctx, LOG_ERR, "if_managelink: %m"); + if (if_handlelink(ctx) == -1) { + logger(ctx, LOG_ERR, "if_handlelink: %m"); eloop_event_delete(ctx->eloop, ctx->link_fd); close(ctx->link_fd); ctx->link_fd = -1; @@ -1089,7 +1092,7 @@ dhcpcd_handleinterface(void *arg, int ac void dhcpcd_handlehwaddr(struct dhcpcd_ctx *ctx, const char *ifname, - const uint8_t *hwaddr, uint8_t hwlen) + const void *hwaddr, uint8_t hwlen) { struct interface *ifp; char buf[sizeof(ifp->hwaddr) * 3]; @@ -1831,7 +1834,7 @@ printpidfile: /* Start handling kernel messages for interfaces, addreses and * routes. */ - eloop_event_add(ctx.eloop, ctx.link_fd, handle_link, &ctx); + eloop_event_add(ctx.eloop, ctx.link_fd, dhcpcd_handlelink, &ctx); /* Start any dev listening plugin which may want to * change the interface name provided by the kernel */ Index: src/external/bsd/dhcpcd/dist/if-bsd.c diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.30 src/external/bsd/dhcpcd/dist/if-bsd.c:1.31 --- src/external/bsd/dhcpcd/dist/if-bsd.c:1.30 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/if-bsd.c Fri Jun 17 19:42:31 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: if-bsd.c,v 1.30 2016/05/09 10:15:59 roy Exp $"); + __RCSID("$NetBSD: if-bsd.c,v 1.31 2016/06/17 19:42:31 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -96,16 +96,18 @@ #define COPYOUT(sin, sa) do { \ if ((sa) && ((sa)->sa_family == AF_INET || (sa)->sa_family == 255)) \ - (sin) = ((struct sockaddr_in *)(void *)(sa))->sin_addr; \ + (sin) = ((const struct sockaddr_in *)(const void *) \ + (sa))->sin_addr; \ } while (0) #define COPYOUT6(sin, sa) do { \ if ((sa) && ((sa)->sa_family == AF_INET6 || (sa)->sa_family == 255)) \ - (sin) = ((struct sockaddr_in6 *)(void *)(sa))->sin6_addr; \ + (sin) = ((const struct sockaddr_in6 *)(const void *) \ + (sa))->sin6_addr; \ } while (0) #ifndef CLLADDR -# define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen)) +# define CLLADDR(s) (const void *)((s)->sdl_data + (s)->sdl_nlen) #endif struct priv { @@ -145,7 +147,7 @@ if_opensockets_os(struct dhcpcd_ctx *ctx #endif #define SOCK_FLAGS (SOCK_CLOEXEC | SOCK_NONBLOCK) - ctx->link_fd = xsocket(PF_ROUTE, SOCK_RAW | SOCK_FLAGS, 0); + ctx->link_fd = xsocket(PF_ROUTE, SOCK_RAW | SOCK_FLAGS, AF_UNSPEC); #undef SOCK_FLAGS return ctx->link_fd == -1 ? -1 : 0; } @@ -174,7 +176,7 @@ if_linkaddr(struct sockaddr_dl *sdl, con #endif static int -if_getssid1(int s, const char *ifname, uint8_t *ssid) +if_getssid1(int s, const char *ifname, void *ssid) { int retval = -1; #if defined(SIOCG80211NWID) @@ -266,13 +268,15 @@ if_vimaster(const struct dhcpcd_ctx *ctx } static void -get_addrs(int type, char *cp, struct sockaddr **sa) +get_addrs(int type, const void *data, const struct sockaddr **sa) { + const char *cp; int i; + cp = data; for (i = 0; i < RTAX_MAX; i++) { if (type & (1 << i)) { - sa[i] = (struct sockaddr *)cp; + sa[i] = (const struct sockaddr *)cp; RT_ADVANCE(cp, sa[i]); } else sa[i] = NULL; @@ -362,8 +366,15 @@ if_findsa(struct dhcpcd_ctx *ctx, const #ifdef INET const char *if_pfname = "Berkley Packet Filter"; +void +if_closeraw(__unused struct interface *ifp, int fd) +{ + + close(fd); +} + int -if_openrawsocket(struct interface *ifp, uint16_t protocol) +if_openraw(struct interface *ifp, uint16_t protocol) { struct ipv4_state *state; int fd = -1; @@ -443,14 +454,14 @@ if_openrawsocket(struct interface *ifp, goto eexit; #endif - /* Install the DHCP filter */ + /* Install the filter. */ memset(&pf, 0, sizeof(pf)); if (protocol == ETHERTYPE_ARP) { pf.bf_insns = UNCONST(arp_bpf_filter); pf.bf_len = arp_bpf_filter_len; } else { - pf.bf_insns = UNCONST(dhcp_bpf_filter); - pf.bf_len = dhcp_bpf_filter_len; + pf.bf_insns = UNCONST(bootp_bpf_filter); + pf.bf_len = bootp_bpf_filter_len; } if (ioctl(fd, BIOCSETF, &pf) == -1) goto eexit; @@ -465,12 +476,11 @@ eexit: } ssize_t -if_sendrawpacket(const struct interface *ifp, uint16_t protocol, +if_sendraw(__unused const struct interface *ifp, int fd, uint16_t protocol, const void *data, size_t len) { struct iovec iov[2]; struct ether_header hw; - int fd; memset(&hw, 0, ETHER_HDR_LEN); memset(&hw.ether_dhost, 0xff, ETHER_ADDR_LEN); @@ -479,25 +489,20 @@ if_sendrawpacket(const struct interface iov[0].iov_len = ETHER_HDR_LEN; iov[1].iov_base = UNCONST(data); iov[1].iov_len = len; - fd = ipv4_protocol_fd(ifp, protocol); return writev(fd, iov, 2); } /* BPF requires that we read the entire buffer. * So we pass the buffer in the API so we can loop on >1 packet. */ ssize_t -if_readrawpacket(struct interface *ifp, uint16_t protocol, - void *data, size_t len, int *flags) +if_readraw(struct interface *ifp, int fd, void *data, size_t len, int *flags) { - int fd; struct bpf_hdr packet; ssize_t bytes; - const unsigned char *payload; + const char *payload; struct ipv4_state *state; state = IPV4_STATE(ifp); - fd = ipv4_protocol_fd(ifp, protocol); - *flags = 0; for (;;) { if (state->buffer_len == 0) { @@ -524,10 +529,8 @@ if_readrawpacket(struct interface *ifp, next: state->buffer_pos += BPF_WORDALIGN(packet.bh_hdrlen + packet.bh_caplen); - if (state->buffer_pos >= state->buffer_len) { + if (state->buffer_pos >= state->buffer_len) state->buffer_len = state->buffer_pos = 0; - *flags |= RAW_EOF; - } if (bytes != -1) return bytes; } @@ -535,40 +538,36 @@ next: int -if_address(const struct interface *ifp, const struct in_addr *address, - const struct in_addr *netmask, const struct in_addr *broadcast, - int action) +if_address(unsigned char cmd, const struct ipv4_addr *ia) { int r; struct in_aliasreq ifra; memset(&ifra, 0, sizeof(ifra)); - strlcpy(ifra.ifra_name, ifp->name, sizeof(ifra.ifra_name)); + strlcpy(ifra.ifra_name, ia->iface->name, sizeof(ifra.ifra_name)); #define ADDADDR(var, addr) do { \ (var)->sin_family = AF_INET; \ (var)->sin_len = sizeof(*(var)); \ (var)->sin_addr = *(addr); \ } while (/*CONSTCOND*/0) - ADDADDR(&ifra.ifra_addr, address); - ADDADDR(&ifra.ifra_mask, netmask); - if (action >= 0 && broadcast) - ADDADDR(&ifra.ifra_broadaddr, broadcast); + ADDADDR(&ifra.ifra_addr, &ia->addr); + ADDADDR(&ifra.ifra_mask, &ia->mask); + if (cmd == RTM_NEWADDR && ia->brd.s_addr != INADDR_ANY) + ADDADDR(&ifra.ifra_broadaddr, &ia->brd); #undef ADDADDR - r = ioctl(ifp->ctx->pf_inet_fd, - action < 0 ? SIOCDIFADDR : SIOCAIFADDR, &ifra); + r = ioctl(ia->iface->ctx->pf_inet_fd, + cmd == RTM_DELADDR ? SIOCDIFADDR : SIOCAIFADDR, &ifra); return r; } static int -if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm) +if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm) { - char *cp; - struct sockaddr *sa, *rti_info[RTAX_MAX]; + const struct sockaddr *sa, *rti_info[RTAX_MAX]; - cp = (void *)(rtm + 1); - sa = (void *)cp; + sa = (const void *)(rtm + 1); if (sa->sa_family != AF_INET) return -1; if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) @@ -586,14 +585,14 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct return -1; #endif - get_addrs(rtm->rtm_addrs, cp, rti_info); + get_addrs(rtm->rtm_addrs, sa, rti_info); memset(rt, 0, sizeof(*rt)); rt->flags = (unsigned int)rtm->rtm_flags; COPYOUT(rt->dest, rti_info[RTAX_DST]); if (rtm->rtm_addrs & RTA_NETMASK) - COPYOUT(rt->net, rti_info[RTAX_NETMASK]); + COPYOUT(rt->mask, rti_info[RTAX_NETMASK]); else - rt->net.s_addr = INADDR_BROADCAST; + rt->mask.s_addr = INADDR_BROADCAST; COPYOUT(rt->gate, rti_info[RTAX_GATEWAY]); COPYOUT(rt->src, rti_info[RTAX_IFA]); rt->mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu; @@ -692,7 +691,7 @@ if_route(unsigned char cmd, const struct if (subnet == -1) /* unikely */ rtm.hdr.rtm_addrs &= ~RTA_IFA; } - if (rt->net.s_addr == htonl(INADDR_BROADCAST) && + if (rt->mask.s_addr == htonl(INADDR_BROADCAST) && rt->gate.s_addr == htonl(INADDR_ANY)) { #ifdef RTF_CLONING @@ -708,7 +707,7 @@ if_route(unsigned char cmd, const struct rtm.hdr.rtm_flags |= RTF_HOST; #endif } else if (rt->gate.s_addr == htonl(INADDR_LOOPBACK) && - rt->net.s_addr == htonl(INADDR_BROADCAST)) + rt->mask.s_addr == htonl(INADDR_BROADCAST)) { rtm.hdr.rtm_flags |= RTF_HOST | RTF_GATEWAY; /* Going via lo0 so remove the interface flags */ @@ -718,7 +717,7 @@ if_route(unsigned char cmd, const struct rtm.hdr.rtm_addrs |= RTA_NETMASK; if (rtm.hdr.rtm_flags & RTF_STATIC) rtm.hdr.rtm_flags |= RTF_GATEWAY; - if (rt->net.s_addr == htonl(INADDR_BROADCAST)) + if (rt->mask.s_addr == htonl(INADDR_BROADCAST)) rtm.hdr.rtm_flags |= RTF_HOST; } if ((cmd == RTM_ADD || cmd == RTM_CHANGE) && @@ -744,7 +743,7 @@ if_route(unsigned char cmd, const struct } if (rtm.hdr.rtm_addrs & RTA_NETMASK) - ADDADDR(&rt->net); + ADDADDR(&rt->mask); if ((cmd == RTM_ADD || cmd == RTM_CHANGE) && (rtm.hdr.rtm_addrs & (RTA_IFP | RTA_IFA))) @@ -775,7 +774,7 @@ if_route(unsigned char cmd, const struct } int -if_initrt(struct interface *ifp) +if_initrt(struct dhcpcd_ctx *ctx) { struct rt_msghdr *rtm; int mib[6]; @@ -783,7 +782,7 @@ if_initrt(struct interface *ifp) char *buf, *p, *end; struct rt rt; - ipv4_freerts(ifp->ctx->ipv4_kroutes); + ipv4_freerts(ctx->ipv4_kroutes); mib[0] = CTL_NET; mib[1] = PF_ROUTE; @@ -806,17 +805,17 @@ if_initrt(struct interface *ifp) end = buf + needed; for (p = buf; p < end; p += rtm->rtm_msglen) { rtm = (void *)p; - if (if_copyrt(ifp->ctx, &rt, rtm) == 0) - ipv4_handlert(ifp->ctx, RTM_ADD, &rt, 1); + if (if_copyrt(ctx, &rt, rtm) == 0) + ipv4_handlert(ctx, RTM_ADD, &rt, 1); } free(buf); return 0; } -#ifdef SIOCGIFAFLAG_IN int if_addrflags(const struct in_addr *addr, const struct interface *ifp) { +#ifdef SIOCGIFAFLAG_IN struct ifreq ifr; struct sockaddr_in *sin; @@ -828,17 +827,12 @@ if_addrflags(const struct in_addr *addr, if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1) return -1; return ifr.ifr_addrflags; -} #else -int -if_addrflags(__unused const struct in_addr *addr, - __unused const struct interface *ifp) -{ - - errno = ENOTSUP; + UNUSED(addr); + UNUSED(ifp); return 0; -} #endif +} #endif /* INET */ #ifdef INET6 @@ -873,7 +867,7 @@ ifa_scope(struct sockaddr_in6 *sin, unsi #endif int -if_address6(const struct ipv6_addr *ia, int action) +if_address6(unsigned char cmd, const struct ipv6_addr *ia) { struct in6_aliasreq ifa; struct in6_addr mask; @@ -914,18 +908,15 @@ if_address6(const struct ipv6_addr *ia, priv = (struct priv *)ia->iface->ctx->priv; return ioctl(priv->pf_inet6_fd, - action < 0 ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa); + cmd == RTM_DELADDR ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa); } - static int -if_copyrt6(struct dhcpcd_ctx *ctx, struct rt6 *rt, struct rt_msghdr *rtm) +if_copyrt6(struct dhcpcd_ctx *ctx, struct rt6 *rt, const struct rt_msghdr *rtm) { - char *cp; - struct sockaddr *sa, *rti_info[RTAX_MAX]; + const struct sockaddr *sa, *rti_info[RTAX_MAX]; - cp = (void *)(rtm + 1); - sa = (void *)cp; + sa = (const void *)(rtm + 1); if (sa->sa_family != AF_INET6) return -1; if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) @@ -942,7 +933,7 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struc return -1; #endif - get_addrs(rtm->rtm_addrs, cp, rti_info); + get_addrs(rtm->rtm_addrs, sa, rti_info); memset(rt, 0, sizeof(*rt)); rt->flags = (unsigned int)rtm->rtm_flags; COPYOUT6(rt->dest, rti_info[RTAX_DST]); @@ -955,12 +946,12 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struc * a kernel bug or actually used for something. * Either way it needs to be zeroed out. */ - struct sockaddr_in6 *sin6; + const struct sockaddr_in6 *sin6; size_t e, i, final = 0, illegal = 0; const unsigned char *p; - sin6 = (void *)rti_info[RTAX_NETMASK]; - rt->net = sin6->sin6_addr; + sin6 = (const void *)rti_info[RTAX_NETMASK]; + rt->mask = sin6->sin6_addr; e = sin6->sin6_len - offsetof(struct sockaddr_in6, sin6_addr); if (e > sizeof(struct in6_addr)) e = sizeof(struct in6_addr); @@ -970,7 +961,7 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struc { if (final && *p) { illegal = 1; - rt->net.s6_addr[i++] = 0x00; + rt->mask.s6_addr[i++] = 0x00; continue; } switch (*p & 0xff) { @@ -991,14 +982,14 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struc break; } if (!illegal) - rt->net.s6_addr[i++] &= *p; + rt->mask.s6_addr[i++] &= *p; else - rt->net.s6_addr[i++] = 0x00; + rt->mask.s6_addr[i++] = 0x00; } - while (i < sizeof(rt->net.s6_addr)) - rt->net.s6_addr[i++] = 0x00; + while (i < sizeof(rt->mask.s6_addr)) + rt->mask.s6_addr[i++] = 0x00; } else - ipv6_mask(&rt->net, 128); + ipv6_mask(&rt->mask, 128); COPYOUT6(rt->gate, rti_info[RTAX_GATEWAY]); DESCOPE(&rt->gate); rt->mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu; @@ -1107,7 +1098,7 @@ if_route6(unsigned char cmd, const struc } if (rtm.hdr.rtm_addrs & RTA_NETMASK) - ADDADDR(&rt->net); + ADDADDR(&rt->mask); if (rtm.hdr.rtm_addrs & (RTA_IFP | RTA_IFA)) { rtm.hdr.rtm_index = (unsigned short)rt->iface->index; @@ -1142,7 +1133,7 @@ if_route6(unsigned char cmd, const struc } int -if_initrt6(struct interface *ifp) +if_initrt6(struct dhcpcd_ctx *ctx) { struct rt_msghdr *rtm; int mib[6]; @@ -1150,7 +1141,7 @@ if_initrt6(struct interface *ifp) char *buf, *p, *end; struct rt6 rt; - ipv6_freerts(&ifp->ctx->ipv6->kroutes); + ipv6_freerts(&ctx->ipv6->kroutes); mib[0] = CTL_NET; mib[1] = PF_ROUTE; @@ -1173,8 +1164,8 @@ if_initrt6(struct interface *ifp) end = buf + needed; for (p = buf; p < end; p += rtm->rtm_msglen) { rtm = (void *)p; - if (if_copyrt6(ifp->ctx, &rt, rtm) == 0) - ipv6_handlert(ifp->ctx, RTM_ADD, &rt); + if (if_copyrt6(ctx, &rt, rtm) == 0) + ipv6_handlert(ctx, RTM_ADD, &rt); } free(buf); return 0; @@ -1237,215 +1228,252 @@ if_getlifetime6(struct ipv6_addr *ia) } #endif -int -if_managelink(struct dhcpcd_ctx *ctx) +static void +if_announce(struct dhcpcd_ctx *ctx, const struct if_announcemsghdr *ifan) +{ + + switch(ifan->ifan_what) { + case IFAN_ARRIVAL: + dhcpcd_handleinterface(ctx, 1, ifan->ifan_name); + break; + case IFAN_DEPARTURE: + dhcpcd_handleinterface(ctx, -1, ifan->ifan_name); + break; + } +} + +static void +if_ifinfo(struct dhcpcd_ctx *ctx, const struct if_msghdr *ifm) { - /* route and ifwatchd like a msg buf size of 2048 */ - char msg[2048], *p, *e, *cp; - ssize_t bytes; - struct rt_msghdr *rtm; - struct if_announcemsghdr *ifan; - struct if_msghdr *ifm; - struct ifa_msghdr *ifam; - struct sockaddr *sa, *rti_info[RTAX_MAX]; - int len; - struct sockaddr_dl sdl; struct interface *ifp; + int state; + + if ((ifp = if_findindex(ctx->ifaces, ifm->ifm_index)) == NULL) + return; + switch (ifm->ifm_data.ifi_link_state) { + case LINK_STATE_DOWN: + state = LINK_DOWN; + break; + case LINK_STATE_UP: + state = LINK_UP; + break; + default: + /* handle_carrier will re-load the interface flags and check for + * IFF_RUNNING as some drivers that don't handle link state also + * don't set IFF_RUNNING when this routing message is generated. + * As such, it is a race ...*/ + state = LINK_UNKNOWN; + break; + } + dhcpcd_handlecarrier(ctx, state, + (unsigned int)ifm->ifm_flags, ifp->name); +} + +static void +if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm) +{ + const struct sockaddr *sa; + + /* Ignore messages generated by us */ + if (rtm->rtm_pid == getpid()) { + ctx->options &= ~DHCPCD_RTM_PPID; + return; + } + + /* Ignore messages sent by the parent after forking */ + if ((ctx->options & + (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED)) == + (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED) && + rtm->rtm_pid == ctx->ppid) + { + /* If this is the last successful message sent, + * clear the check flag as it's possible another + * process could re-use the same pid and also + * manipulate therouting table. */ + if (rtm->rtm_seq == ctx->pseq) + ctx->options &= ~DHCPCD_RTM_PPID; + return; + } + + sa = (const void *)(rtm + 1); + switch (sa->sa_family) { #ifdef INET - struct rt rt; + case AF_INET: + { + struct rt rt; + + if (if_copyrt(ctx, &rt, rtm) == 0) + ipv4_handlert(ctx, rtm->rtm_type, &rt, 0); + break; + } #endif #ifdef INET6 - struct rt6 rt6; - struct in6_addr ia6, net6; - struct sockaddr_in6 *sin6; -#endif -#if (defined(INET) && defined(IN_IFF_TENTATIVE)) || defined(INET6) - int ifa_flags; -#endif + case AF_INET6: + { + struct rt6 rt6; - if ((bytes = read(ctx->link_fd, msg, sizeof(msg))) == -1) - return -1; - e = msg + bytes; - for (p = msg; p < e; p += rtm->rtm_msglen) { - rtm = (void *)p; - switch(rtm->rtm_type) { -#ifdef RTM_IFANNOUNCE - case RTM_IFANNOUNCE: - ifan = (void *)p; - switch(ifan->ifan_what) { - case IFAN_ARRIVAL: - dhcpcd_handleinterface(ctx, 1, - ifan->ifan_name); - break; - case IFAN_DEPARTURE: - dhcpcd_handleinterface(ctx, -1, - ifan->ifan_name); - break; - } + if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) break; -#endif - case RTM_IFINFO: - ifm = (void *)p; - ifp = if_findindex(ctx->ifaces, ifm->ifm_index); - if (ifp == NULL) - break; - switch (ifm->ifm_data.ifi_link_state) { - case LINK_STATE_DOWN: - len = LINK_DOWN; - break; - case LINK_STATE_UP: - len = LINK_UP; - break; - default: - /* handle_carrier will re-load - * the interface flags and check for - * IFF_RUNNING as some drivers that - * don't handle link state also don't - * set IFF_RUNNING when this routing - * message is generated. - * As such, it is a race ...*/ - len = LINK_UNKNOWN; - break; - } - dhcpcd_handlecarrier(ctx, len, - (unsigned int)ifm->ifm_flags, ifp->name); + /* + * BSD announces host routes. + * As such, we should be notified of reachability by its + * existance with a hardware address. + */ + if (rtm->rtm_flags & (RTF_HOST)) { + const struct sockaddr *rti_info[RTAX_MAX]; + struct in6_addr dst6; + struct sockaddr_dl sdl; + + get_addrs(rtm->rtm_addrs, rtm + 1, rti_info); + COPYOUT6(dst6, rti_info[RTAX_DST]); + DESCOPE(&dst6); + if (rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) + memcpy(&sdl, rti_info[RTAX_GATEWAY], + sizeof(sdl)); + else + sdl.sdl_alen = 0; + ipv6nd_neighbour(ctx, &dst6, + rtm->rtm_type != RTM_DELETE && sdl.sdl_alen ? + IPV6ND_REACHABLE : 0); break; - case RTM_ADD: - case RTM_CHANGE: - case RTM_DELETE: - /* Ignore messages generated by us */ - if (rtm->rtm_pid == getpid()) { - ctx->options &= ~DHCPCD_RTM_PPID; - continue; - } - /* Ignore messages sent by the parent after forking */ - if ((ctx->options & - (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED)) == - (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED) && - rtm->rtm_pid == ctx->ppid) - { - /* If this is the last successful message sent, - * clear the check flag as it's possible another - * process could re-use the same pid and also - * manipulate therouting table. */ - if (rtm->rtm_seq == ctx->pseq) - ctx->options &= ~DHCPCD_RTM_PPID; - continue; - } - cp = (void *)(rtm + 1); - sa = (void *)cp; - switch (sa->sa_family) { -#ifdef INET - case AF_INET: - if (if_copyrt(ctx, &rt, rtm) == 0) - ipv4_handlert(ctx, rtm->rtm_type,&rt,0); - break; -#endif -#ifdef INET6 - case AF_INET6: - if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) - break; - /* - * BSD caches host routes in the - * routing table. - * As such, we should be notified of - * reachability by its existance - * with a hardware address - */ - if (rtm->rtm_flags & (RTF_HOST)) { - get_addrs(rtm->rtm_addrs, cp, rti_info); - COPYOUT6(ia6, rti_info[RTAX_DST]); - DESCOPE(&ia6); - if (rti_info[RTAX_GATEWAY]->sa_family - == AF_LINK) - memcpy(&sdl, - rti_info[RTAX_GATEWAY], - sizeof(sdl)); - else - sdl.sdl_alen = 0; - ipv6nd_neighbour(ctx, &ia6, - rtm->rtm_type != RTM_DELETE && - sdl.sdl_alen ? - IPV6ND_REACHABLE : 0); - break; - } + } - if (if_copyrt6(ctx, &rt6, rtm) == 0) - ipv6_handlert(ctx, rtm->rtm_type, &rt6); - break; -#endif - } - break; -#ifdef RTM_CHGADDR - case RTM_CHGADDR: /* FALLTHROUGH */ + if (if_copyrt6(ctx, &rt6, rtm) == 0) + ipv6_handlert(ctx, rtm->rtm_type, &rt6); + break; + } #endif - case RTM_DELADDR: /* FALLTHROUGH */ - case RTM_NEWADDR: - /* XXX We have no way of knowing who generated these - * messages wich truely sucks because we want to - * avoid listening to our own delete messages. */ - ifam = (void *)p; - ifp = if_findindex(ctx->ifaces, ifam->ifam_index); - if (ifp == NULL) - break; - cp = (void *)(ifam + 1); - get_addrs(ifam->ifam_addrs, cp, rti_info); - if (rti_info[RTAX_IFA] == NULL) - break; - switch (rti_info[RTAX_IFA]->sa_family) { - case AF_LINK: + } +} + +static void +if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam) +{ + struct interface *ifp; + const struct sockaddr *rti_info[RTAX_MAX]; + + /* XXX We have no way of knowing who generated these + * messages wich truely sucks because we want to + * avoid listening to our own delete messages. */ + if ((ifp = if_findindex(ctx->ifaces, ifam->ifam_index)) == NULL) + return; + get_addrs(ifam->ifam_addrs, ifam + 1, rti_info); + if (rti_info[RTAX_IFA] == NULL) + return; + switch (rti_info[RTAX_IFA]->sa_family) { + case AF_LINK: + { + struct sockaddr_dl sdl; + #ifdef RTM_CHGADDR - if (rtm->rtm_type != RTM_CHGADDR) - break; + if (ifam->ifam_type != RTM_CHGADDR) + break; #else - if (rtm->rtm_type != RTM_NEWADDR) - break; + if (ifam->ifam_type != RTM_NEWADDR) + break; #endif - memcpy(&sdl, rti_info[RTAX_IFA], - rti_info[RTAX_IFA]->sa_len); - dhcpcd_handlehwaddr(ctx, ifp->name, - (const unsigned char*)CLLADDR(&sdl), - sdl.sdl_alen); - break; + memcpy(&sdl, rti_info[RTAX_IFA], rti_info[RTAX_IFA]->sa_len); + dhcpcd_handlehwaddr(ctx, ifp->name, CLLADDR(&sdl),sdl.sdl_alen); + break; + } #ifdef INET - case AF_INET: - case 255: /* FIXME: Why 255? */ - COPYOUT(rt.dest, rti_info[RTAX_IFA]); - COPYOUT(rt.net, rti_info[RTAX_NETMASK]); - COPYOUT(rt.gate, rti_info[RTAX_BRD]); - if (rtm->rtm_type == RTM_NEWADDR) { - ifa_flags = if_addrflags(&rt.dest, ifp); - if (ifa_flags == -1) - break; - } else - ifa_flags = 0; - ipv4_handleifa(ctx, rtm->rtm_type, - NULL, ifp->name, - &rt.dest, &rt.net, &rt.gate, ifa_flags); + case AF_INET: + case 255: /* FIXME: Why 255? */ + { + const struct sockaddr_in *sin; + struct in_addr addr, mask, bcast; + int flags; + + sin = (const void *)rti_info[RTAX_IFA]; + addr.s_addr = sin != NULL && sin->sin_family == AF_INET ? + sin->sin_addr.s_addr : INADDR_ANY; + sin = (const void *)rti_info[RTAX_NETMASK]; + mask.s_addr = sin != NULL && sin->sin_family == AF_INET ? + sin->sin_addr.s_addr : INADDR_ANY; + sin = (const void *)rti_info[RTAX_BRD]; + bcast.s_addr = sin != NULL && sin->sin_family == AF_INET ? + sin->sin_addr.s_addr : INADDR_ANY; + if (ifam->ifam_type == RTM_NEWADDR) { + if ((flags = if_addrflags(&addr, ifp)) == -1) break; + } else + flags = 0; + ipv4_handleifa(ctx, ifam->ifam_type, NULL, ifp->name, + &addr, &mask, &bcast, flags); + break; + } #endif #ifdef INET6 - case AF_INET6: - sin6 = (void *)rti_info[RTAX_IFA]; - ia6 = sin6->sin6_addr; - DESCOPE(&ia6); - sin6 = (void *)rti_info[RTAX_NETMASK]; - net6 = sin6->sin6_addr; - DESCOPE(&net6); - if (rtm->rtm_type == RTM_NEWADDR) { - ifa_flags = if_addrflags6(&ia6, ifp); - if (ifa_flags == -1) - break; - } else - ifa_flags = 0; - ipv6_handleifa(ctx, rtm->rtm_type, NULL, - ifp->name, &ia6, ipv6_prefixlen(&net6), - ifa_flags); + case AF_INET6: + { + struct in6_addr addr6, mask6; + const struct sockaddr_in6 *sin6; + int flags; + + sin6 = (const void *)rti_info[RTAX_IFA]; + addr6 = sin6->sin6_addr; + DESCOPE(&addr6); + sin6 = (const void *)rti_info[RTAX_NETMASK]; + mask6 = sin6->sin6_addr; + DESCOPE(&mask6); + if (ifam->ifam_type == RTM_NEWADDR) { + if ((flags = if_addrflags6(&addr6, ifp)) == -1) break; + } else + flags = 0; + ipv6_handleifa(ctx, ifam->ifam_type, NULL, + ifp->name, &addr6, ipv6_prefixlen(&mask6), flags); + break; + } #endif - } - break; - } + } +} + +static void +if_dispatch(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm) +{ + + switch(rtm->rtm_type) { +#ifdef RTM_IFANNOUNCE + case RTM_IFANNOUNCE: + if_announce(ctx, (const void *)rtm); + break; +#endif + case RTM_IFINFO: + if_ifinfo(ctx, (const void *)rtm); + break; + case RTM_ADD: /* FALLTHROUGH */ + case RTM_CHANGE: /* FALLTHROUGH */ + case RTM_DELETE: + if_rtm(ctx, (const void *)rtm); + break; +#ifdef RTM_CHGADDR + case RTM_CHGADDR: /* FALLTHROUGH */ +#endif + case RTM_DELADDR: /* FALLTHROUGH */ + case RTM_NEWADDR: + if_ifa(ctx, (const void *)rtm); + break; + } +} + +int +if_handlelink(struct dhcpcd_ctx *ctx) +{ + /* route and ifwatchd like a msg buf size of 2048 */ + char buf[2048]; + const char *p, *e; + size_t msglen; + ssize_t bytes; + const struct rt_msghdr *rtm; + + if ((bytes = read(ctx->link_fd, buf, sizeof(buf))) == -1) + return -1; + e = buf + bytes; + for (p = buf; p < e; p += msglen) { + rtm = (const void *)p; + msglen = rtm->rtm_msglen; + if_dispatch(ctx, rtm); } return 0; } Index: src/external/bsd/dhcpcd/dist/if-options.c diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.33 src/external/bsd/dhcpcd/dist/if-options.c:1.34 --- src/external/bsd/dhcpcd/dist/if-options.c:1.33 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/if-options.c Fri Jun 17 19:42:31 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: if-options.c,v 1.33 2016/05/09 10:15:59 roy Exp $"); + __RCSID("$NetBSD: if-options.c,v 1.34 2016/06/17 19:42:31 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -1093,7 +1093,7 @@ parse_option(struct dhcpcd_ctx *ctx, con *fp = ' '; return -1; } - if (parse_addr(ctx, &rt->dest, &rt->net, p) == -1 || + if (parse_addr(ctx, &rt->dest, &rt->mask, p) == -1 || parse_addr(ctx, &rt->gate, NULL, np) == -1) { free(rt); @@ -1118,7 +1118,7 @@ parse_option(struct dhcpcd_ctx *ctx, con return -1; } rt->dest.s_addr = INADDR_ANY; - rt->net.s_addr = INADDR_ANY; + rt->mask.s_addr = INADDR_ANY; if (parse_addr(ctx, &rt->gate, NULL, p) == -1) { free(rt); return -1; Index: src/external/bsd/dhcpcd/dist/ipv4.c diff -u src/external/bsd/dhcpcd/dist/ipv4.c:1.22 src/external/bsd/dhcpcd/dist/ipv4.c:1.23 --- src/external/bsd/dhcpcd/dist/ipv4.c:1.22 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/ipv4.c Fri Jun 17 19:42:32 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: ipv4.c,v 1.22 2016/05/09 10:15:59 roy Exp $"); + __RCSID("$NetBSD: ipv4.c,v 1.23 2016/06/17 19:42:32 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -116,7 +116,7 @@ ipv4_getnetmask(uint32_t addr) struct ipv4_addr * ipv4_iffindaddr(struct interface *ifp, - const struct in_addr *addr, const struct in_addr *net) + const struct in_addr *addr, const struct in_addr *mask) { struct ipv4_state *state; struct ipv4_addr *ap; @@ -125,7 +125,7 @@ ipv4_iffindaddr(struct interface *ifp, if (state) { TAILQ_FOREACH(ap, &state->addrs, next) { if ((addr == NULL || ap->addr.s_addr == addr->s_addr) && - (net == NULL || ap->net.s_addr == net->s_addr)) + (mask == NULL || ap->mask.s_addr == mask->s_addr)) return ap; } } @@ -157,8 +157,8 @@ ipv4_iffindmaskaddr(struct interface *if state = IPV4_STATE(ifp); if (state) { TAILQ_FOREACH (ap, &state->addrs, next) { - if ((ap->addr.s_addr & ap->net.s_addr) == - (addr->s_addr & ap->net.s_addr)) + if ((ap->addr.s_addr & ap->mask.s_addr) == + (addr->s_addr & ap->mask.s_addr)) return ap; } } @@ -206,31 +206,33 @@ ipv4_srcaddr(const struct rt *rt, struct /* Prefer DHCP source address if matching */ dstate = D_CSTATE(rt->iface); - if (dstate && - rt->net.s_addr == dstate->net.s_addr && - rt->dest.s_addr == (dstate->addr.s_addr & dstate->net.s_addr)) + if (dstate && dstate->addr && + rt->mask.s_addr == dstate->addr->mask.s_addr && + rt->dest.s_addr == + (dstate->addr->addr.s_addr & dstate->addr->mask.s_addr)) { - *addr = dstate->addr; + *addr = dstate->addr->addr; return 1; } /* Then IPv4LL source address if matching */ istate = IPV4LL_CSTATE(rt->iface); - if (istate && - rt->net.s_addr == inaddr_llmask.s_addr && - rt->dest.s_addr == (istate->addr.s_addr & inaddr_llmask.s_addr)) + if (istate && istate->addr && + rt->mask.s_addr == istate->addr->mask.s_addr && + rt->dest.s_addr == + (istate->addr->addr.s_addr & istate->addr->mask.s_addr)) { - *addr = istate->addr; + *addr = istate->addr->addr; return 1; } /* If neither match, return DHCP then IPv4LL */ - if (dstate) { - *addr = dstate->addr; + if (dstate && dstate->addr) { + *addr = dstate->addr->addr; return 0; } - if (istate) { - *addr = istate->addr; + if (istate && istate->addr) { + *addr = istate->addr->addr; return 0; } @@ -248,8 +250,8 @@ ipv4_hasaddr(const struct interface *ifp istate = IPV4LL_CSTATE(ifp); return ((dstate && dstate->added == STATE_ADDED && - dstate->addr.s_addr != INADDR_ANY) || - (istate && istate->addr.s_addr != INADDR_ANY)); + dstate->addr != NULL) || + (istate && istate->addr)); } void @@ -281,25 +283,6 @@ ipv4_init(struct dhcpcd_ctx *ctx) return 0; } -int -ipv4_protocol_fd(const struct interface *ifp, uint16_t protocol) -{ - - if (protocol == ETHERTYPE_ARP) { - const struct iarp_state *istate; - - istate = ARP_CSTATE(ifp); - assert(istate != NULL); - return istate->fd; - } else { - const struct dhcp_state *dstate; - - dstate = D_CSTATE(ifp); - assert(dstate != NULL); - return dstate->raw_fd; - } -} - /* Interface comparer for working out ordering. */ int ipv4_ifcmp(const struct interface *si, const struct interface *ti) @@ -349,7 +332,7 @@ find_route(struct rt_head *rts, const st rt->iface->metric == r->iface->metric)) && #endif (!srt || srt != rt) && - rt->net.s_addr == r->net.s_addr) + rt->mask.s_addr == r->mask.s_addr) return rt; } return NULL; @@ -363,28 +346,28 @@ desc_route(const char *cmd, const struct const char *ifname = rt->iface ? rt->iface->name : NULL; strlcpy(addr, inet_ntoa(rt->dest), sizeof(addr)); - if (rt->net.s_addr == htonl(INADDR_BROADCAST) && + if (rt->mask.s_addr == htonl(INADDR_BROADCAST) && rt->gate.s_addr == htonl(INADDR_ANY)) logger(ctx, LOG_INFO, "%s: %s host route to %s", ifname, cmd, addr); - else if (rt->net.s_addr == htonl(INADDR_BROADCAST)) + else if (rt->mask.s_addr == htonl(INADDR_BROADCAST)) logger(ctx, LOG_INFO, "%s: %s host route to %s via %s", ifname, cmd, addr, inet_ntoa(rt->gate)); else if (rt->dest.s_addr == htonl(INADDR_ANY) && - rt->net.s_addr == htonl(INADDR_ANY) && + rt->mask.s_addr == htonl(INADDR_ANY) && rt->gate.s_addr == htonl(INADDR_ANY)) logger(ctx, LOG_INFO, "%s: %s default route", ifname, cmd); else if (rt->gate.s_addr == htonl(INADDR_ANY)) logger(ctx, LOG_INFO, "%s: %s route to %s/%d", - ifname, cmd, addr, inet_ntocidr(rt->net)); + ifname, cmd, addr, inet_ntocidr(rt->mask)); else if (rt->dest.s_addr == htonl(INADDR_ANY) && - rt->net.s_addr == htonl(INADDR_ANY)) + rt->mask.s_addr == htonl(INADDR_ANY)) logger(ctx, LOG_INFO, "%s: %s default route via %s", ifname, cmd, inet_ntoa(rt->gate)); else logger(ctx, LOG_INFO, "%s: %s route to %s/%d via %s", - ifname, cmd, addr, inet_ntocidr(rt->net), + ifname, cmd, addr, inet_ntocidr(rt->mask), inet_ntoa(rt->gate)); } @@ -403,7 +386,7 @@ ipv4_findrt(struct dhcpcd_ctx *ctx, cons #else (!flags || rt->iface == r->iface) && #endif - rt->net.s_addr == r->net.s_addr) + rt->mask.s_addr == r->mask.s_addr) return r; } return NULL; @@ -467,7 +450,7 @@ nc_route(struct rt *ort, struct rt *nrt) /* Don't set default routes if not asked to */ if (nrt->dest.s_addr == 0 && - nrt->net.s_addr == 0 && + nrt->mask.s_addr == 0 && !(nrt->iface->options->options & DHCPCD_GATEWAY)) return -1; @@ -494,7 +477,7 @@ nc_route(struct rt *ort, struct rt *nrt) ort->metric == nrt->metric && #endif ort->dest.s_addr == nrt->dest.s_addr && - ort->net.s_addr == nrt->net.s_addr && + ort->mask.s_addr == nrt->mask.s_addr && ort->gate.s_addr == nrt->gate.s_addr) { if (ort->mtu == nrt->mtu) @@ -562,19 +545,23 @@ d_route(struct rt *rt) static struct rt_head * add_subnet_route(struct rt_head *rt, const struct interface *ifp) { - const struct dhcp_state *s; + const struct dhcp_state *state; struct rt *r; if (rt == NULL) /* earlier malloc failed */ return NULL; - s = D_CSTATE(ifp); + /* P2P interfaces don't have subnet routes as such. */ + if (ifp->flags & IFF_POINTOPOINT) + return rt; + + state = D_CSTATE(ifp); /* Don't create a subnet route for these addresses */ - if (s->net.s_addr == INADDR_ANY) + if (state->addr->mask.s_addr == INADDR_ANY) return rt; #ifndef BSD /* BSD adds a route in this instance */ - if (s->net.s_addr == INADDR_BROADCAST) + if (state->addr->mask.s_addr == INADDR_BROADCAST) return rt; #endif @@ -583,11 +570,11 @@ add_subnet_route(struct rt_head *rt, con ipv4_freeroutes(rt); return NULL; } - r->dest.s_addr = s->addr.s_addr & s->net.s_addr; - r->net.s_addr = s->net.s_addr; + r->dest.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr; + r->mask.s_addr = state->addr->mask.s_addr; r->gate.s_addr = INADDR_ANY; r->mtu = dhcp_get_mtu(ifp); - r->src = s->addr; + r->src = state->addr->addr; TAILQ_INSERT_HEAD(rt, r, next); return rt; @@ -598,13 +585,13 @@ static struct rt_head * add_loopback_route(struct rt_head *rt, const struct interface *ifp) { struct rt *r; - const struct dhcp_state *s; + const struct dhcp_state *state; if (rt == NULL) /* earlier malloc failed */ return NULL; - s = D_CSTATE(ifp); - if (s->addr.s_addr == INADDR_ANY) + state = D_CSTATE(ifp); + if (state->addr == NULL) return rt; if ((r = calloc(1, sizeof(*r))) == NULL) { @@ -612,11 +599,11 @@ add_loopback_route(struct rt_head *rt, c ipv4_freeroutes(rt); return NULL; } - r->dest = s->addr; - r->net.s_addr = INADDR_BROADCAST; + r->dest = state->addr->addr; + r->mask.s_addr = INADDR_BROADCAST; r->gate.s_addr = htonl(INADDR_LOOPBACK); r->mtu = dhcp_get_mtu(ifp); - r->src = s->addr; + r->src = state->addr->addr; TAILQ_INSERT_HEAD(rt, r, next); return rt; } @@ -651,7 +638,7 @@ get_routes(struct interface *ifp) if (nrt) { state = D_CSTATE(ifp); TAILQ_FOREACH(rt, nrt, next) { - rt->src = state->addr; + rt->src = state->addr->addr; } } @@ -676,10 +663,10 @@ add_destination_route(struct rt_head *rt return NULL; } r->dest.s_addr = INADDR_ANY; - r->net.s_addr = INADDR_ANY; - r->gate.s_addr = state->brd.s_addr; + r->mask.s_addr = INADDR_ANY; + r->gate = state->addr->brd; r->mtu = dhcp_get_mtu(ifp); - r->src = state->addr; + r->src = state->addr->addr; TAILQ_INSERT_HEAD(rt, r, next); return rt; } @@ -697,6 +684,10 @@ add_router_host_route(struct rt_head *rt if (rt == NULL) /* earlier malloc failed */ return NULL; + /* Don't add a host route for these interfaces. */ + if (ifp->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) + return rt; + TAILQ_FOREACH(rtp, rt, next) { if (rtp->dest.s_addr != INADDR_ANY) continue; @@ -710,8 +701,8 @@ add_router_host_route(struct rt_head *rt /* match subnet */ cp = (const char *)&rtp->gate.s_addr; cp2 = (const char *)&rtn->dest.s_addr; - cp3 = (const char *)&rtn->net.s_addr; - cplim = cp3 + sizeof(rtn->net.s_addr); + cp3 = (const char *)&rtn->mask.s_addr; + cplim = cp3 + sizeof(rtn->mask.s_addr); while (cp3 < cplim) { if ((*cp++ ^ *cp2++) & *cp3++) break; @@ -750,10 +741,10 @@ add_router_host_route(struct rt_head *rt return NULL; } rtn->dest.s_addr = rtp->gate.s_addr; - rtn->net.s_addr = htonl(INADDR_BROADCAST); + rtn->mask.s_addr = htonl(INADDR_BROADCAST); rtn->gate.s_addr = htonl(INADDR_ANY); rtn->mtu = dhcp_get_mtu(ifp); - rtn->src = state->addr; + rtn->src = state->addr->addr; TAILQ_INSERT_BEFORE(rtp, rtn, next); } return rt; @@ -906,49 +897,42 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx) } int -ipv4_deladdr(struct interface *ifp, - const struct in_addr *addr, const struct in_addr *net, int keeparp) +ipv4_deladdr(struct ipv4_addr *addr, int keeparp) { - struct dhcp_state *dstate; int r; struct ipv4_state *state; struct ipv4_addr *ap; struct arp_state *astate; - uint32_t a, n; - logger(ifp->ctx, LOG_DEBUG, - "%s: deleting IP address %s/%d", - ifp->name, inet_ntoa(*addr), inet_ntocidr(*net)); + logger(addr->iface->ctx, LOG_DEBUG, + "%s: deleting IP address %s", addr->iface->name, addr->saddr); - r = if_deladdress(ifp, addr, net); + r = if_address(RTM_DELADDR, addr); if (r == -1 && errno != EADDRNOTAVAIL && errno != ENXIO && errno != ENODEV) - logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__); + logger(addr->iface->ctx, LOG_ERR, "%s: %s: %m", + addr->iface->name, __func__); - if (!keeparp && (astate = arp_find(ifp, addr)) != NULL) + if (!keeparp && (astate = arp_find(addr->iface, &addr->addr)) != NULL) arp_free(astate); - a = addr->s_addr; - n = net->s_addr; - state = IPV4_STATE(ifp); + state = IPV4_STATE(addr->iface); TAILQ_FOREACH(ap, &state->addrs, next) { - if (ap->addr.s_addr == addr->s_addr && - ap->net.s_addr == net->s_addr) - { + if (IPV4_MASK_EQ(ap, addr)) { + struct dhcp_state *dstate; + + dstate = D_STATE(ap->iface); TAILQ_REMOVE(&state->addrs, ap, next); free(ap); + + if (dstate && dstate->addr == ap) { + dstate->added = 0; + dstate->addr = NULL; + } break; } } - /* Have to do this last incase the function arguments - * were these very pointers. */ - dstate = D_STATE(ifp); - if (dstate && dstate->addr.s_addr == a && dstate->net.s_addr == n) { - dstate->added = 0; - dstate->addr.s_addr = 0; - dstate->net.s_addr = 0; - } return r; } @@ -964,7 +948,7 @@ delete_address(struct interface *ifp) if (ifo->options & DHCPCD_INFORM || (ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0)) return 0; - r = ipv4_deladdr(ifp, &state->addr, &state->net, 0); + r = ipv4_deladdr(state->addr, 0); return r; } @@ -997,7 +981,6 @@ ipv4_addaddr(struct interface *ifp, cons { struct ipv4_state *state; struct ipv4_addr *ia; - char bcast_str[INET_ADDRSTRLEN]; if ((state = ipv4_getstate(ifp)) == NULL) { logger(ifp->ctx, LOG_ERR, "%s: ipv4_getstate: %m", __func__); @@ -1008,7 +991,7 @@ ipv4_addaddr(struct interface *ifp, cons TAILQ_FOREACH_SAFE(ia, &state->addrs, next, ian) { if (ia->addr.s_addr != addr->s_addr) - ipv4_deladdr(ifp, &ia->addr, &ia->net, 0); + ipv4_deladdr(ia, 0); } } @@ -1017,10 +1000,18 @@ ipv4_addaddr(struct interface *ifp, cons return NULL; } - strlcpy(bcast_str, inet_ntoa(*bcast), sizeof(bcast_str)); - logger(ifp->ctx, LOG_DEBUG, "%s: adding IP address %s/%d broadcast %s", - ifp->name, inet_ntoa(*addr), inet_ntocidr(*mask), bcast_str); - if (if_addaddress(ifp, addr, mask, bcast) == -1) { + ia->iface = ifp; + ia->addr = *addr; + ia->mask = *mask; + ia->brd = *bcast; +#ifdef IN_IFF_TENTATIVE + ia->addr_flags = IN_IFF_TENTATIVE; +#endif + snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d", + inet_ntoa(*addr), inet_ntocidr(*mask)); + logger(ifp->ctx, LOG_DEBUG, "%s: adding IP address %s broadcast %s", + ifp->name, ia->saddr, inet_ntoa(*bcast)); + if (if_address(RTM_NEWADDR, ia) == -1) { if (errno != EEXIST) logger(ifp->ctx, LOG_ERR, "%s: if_addaddress: %m", __func__); @@ -1028,13 +1019,6 @@ ipv4_addaddr(struct interface *ifp, cons return NULL; } - ia->iface = ifp; - ia->addr = *addr; - ia->net = *mask; - ia->brd = *bcast; -#ifdef IN_IFF_TENTATIVE - ia->addr_flags = IN_IFF_TENTATIVE; -#endif TAILQ_INSERT_TAIL(&state->addrs, ia, next); return ia; } @@ -1043,16 +1027,15 @@ static int ipv4_daddaddr(struct interface *ifp, const struct dhcp_lease *lease) { struct dhcp_state *state; + struct ipv4_addr *ia; - if (ipv4_addaddr(ifp, &lease->addr, &lease->net, &lease->brd) == NULL) + ia = ipv4_addaddr(ifp, &lease->addr, &lease->mask, &lease->brd); + if (ia == NULL) return -1; state = D_STATE(ifp); state->added = STATE_ADDED; - - state->addr.s_addr = lease->addr.s_addr; - state->net.s_addr = lease->net.s_addr; - + state->addr = ia; return 0; } @@ -1075,7 +1058,8 @@ ipv4_preferanother(struct interface *ifp break; /* We are already the most preferred */ nstate = D_STATE(ifn); if (nstate && !nstate->added && - nstate->lease.addr.s_addr == state->addr.s_addr) + state->addr != NULL && + nstate->lease.addr.s_addr == state->addr->addr.s_addr) { preferred = 1; delete_address(ifp); @@ -1101,7 +1085,7 @@ ipv4_applyaddr(void *arg) struct dhcp_state *state = D_STATE(ifp), *nstate; struct dhcp_lease *lease; struct if_options *ifo = ifp->options; - struct ipv4_addr *ap; + struct ipv4_addr *ia; int r; if (state == NULL) @@ -1133,7 +1117,8 @@ ipv4_applyaddr(void *arg) } nstate = D_STATE(ifn); if (nstate && nstate->added && - nstate->addr.s_addr == lease->addr.s_addr) + nstate->addr && + nstate->addr->addr.s_addr == lease->addr.s_addr) { if (r == 0) { logger(ifp->ctx, LOG_INFO, @@ -1147,7 +1132,7 @@ ipv4_applyaddr(void *arg) ifn->name, inet_ntoa(lease->addr), ifp->name); - ipv4_deladdr(ifn, &nstate->addr, &nstate->net, 0); + ipv4_deladdr(nstate->addr, 0); break; } } @@ -1157,64 +1142,63 @@ ipv4_applyaddr(void *arg) TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) { if (ifn == ifp) continue; - ap = ipv4_iffindaddr(ifn, &lease->addr, NULL); - if (ap) - ipv4_deladdr(ifn, &ap->addr, &ap->net, 0); + ia = ipv4_iffindaddr(ifn, &lease->addr, NULL); + if (ia != NULL) + ipv4_deladdr(ia, 0); } } /* If the netmask or broadcast is different, re-add the addresss */ - ap = ipv4_iffindaddr(ifp, &lease->addr, NULL); - if (ap && - ap->net.s_addr == lease->net.s_addr && - ap->brd.s_addr == lease->brd.s_addr) + ia = ipv4_iffindaddr(ifp, &lease->addr, NULL); + if (ia && + ia->mask.s_addr == lease->mask.s_addr && + ia->brd.s_addr == lease->brd.s_addr) logger(ifp->ctx, LOG_DEBUG, - "%s: IP address %s/%d already exists", - ifp->name, inet_ntoa(lease->addr), - inet_ntocidr(lease->net)); + "%s: IP address %s already exists", + ifp->name, ia->saddr); else { #if __linux__ /* Linux does not change netmask/broadcast address * for re-added addresses, so we need to delete the old one * first. */ - if (ap != NULL) - ipv4_deladdr(ifp, &ap->addr, &ap->net, 0); + if (ia != NULL) + ipv4_deladdr(ia, 0); #endif r = ipv4_daddaddr(ifp, lease); if (r == -1 && errno != EEXIST) return; } -#ifdef IN_IFF_NOTUSEABLE - ap = ipv4_iffindaddr(ifp, &lease->addr, NULL); - if (ap == NULL) { + ia = ipv4_iffindaddr(ifp, &lease->addr, NULL); + if (ia == NULL) { logger(ifp->ctx, LOG_ERR, "%s: added address vanished", ifp->name); return; - } else if (ap->addr_flags & IN_IFF_NOTUSEABLE) + } +#ifdef IN_IFF_NOTUSEABLE + if (ia->addr_flags & IN_IFF_NOTUSEABLE) return; #endif /* Delete the old address if different */ - if (state->addr.s_addr != lease->addr.s_addr && - state->addr.s_addr != 0 && + if (state->addr && + state->addr->addr.s_addr != lease->addr.s_addr && ipv4_iffindaddr(ifp, &lease->addr, NULL)) delete_address(ifp); + state->addr = ia; state->added = STATE_ADDED; - state->addr.s_addr = lease->addr.s_addr; - state->net.s_addr = lease->net.s_addr; /* Find any freshly added routes, such as the subnet route. * We do this because we cannot rely on recieving the kernel * notification right now via our link socket. */ - if_initrt(ifp); + if_initrt(ifp->ctx); ipv4_buildroutes(ifp->ctx); /* Announce the address */ if (ifo->options & DHCPCD_ARP) { struct arp_state *astate; - if ((astate = arp_new(ifp, &state->addr)) != NULL) + if ((astate = arp_new(ifp, &state->addr->addr)) != NULL) arp_announce(astate); } if (state->state == DHS_BOUND) { @@ -1226,12 +1210,12 @@ ipv4_applyaddr(void *arg) void ipv4_handleifa(struct dhcpcd_ctx *ctx, int cmd, struct if_head *ifs, const char *ifname, - const struct in_addr *addr, const struct in_addr *net, + const struct in_addr *addr, const struct in_addr *mask, const struct in_addr *brd, int flags) { struct interface *ifp; struct ipv4_state *state; - struct ipv4_addr *ap; + struct ipv4_addr *ia; if (ifs == NULL) ifs = ctx->ifaces; @@ -1239,10 +1223,6 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx, errno = ESRCH; return; } - if (addr->s_addr == INADDR_ANY) { - errno = EINVAL; - return; - } if ((ifp = if_find(ifs, ifname)) == NULL) return; if ((state = ipv4_getstate(ifp)) == NULL) { @@ -1250,43 +1230,58 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx, return; } - ap = ipv4_iffindaddr(ifp, addr, NULL); - if (cmd == RTM_NEWADDR) { - if (ap == NULL) { - if ((ap = malloc(sizeof(*ap))) == NULL) { + ia = ipv4_iffindaddr(ifp, addr, NULL); + switch (cmd) { + case RTM_NEWADDR: + if (ia == NULL) { + if ((ia = malloc(sizeof(*ia))) == NULL) { logger(ifp->ctx, LOG_ERR, "%s: %m", __func__); return; } - ap->iface = ifp; - ap->addr = *addr; - TAILQ_INSERT_TAIL(&state->addrs, ap, next); - } - ap->net = *net; - ap->brd = *brd; - ap->addr_flags = flags; - } else if (cmd == RTM_DELADDR) { - if (ap) { - TAILQ_REMOVE(&state->addrs, ap, next); - free(ap); - } + ia->iface = ifp; + ia->addr = *addr; + TAILQ_INSERT_TAIL(&state->addrs, ia, next); + } + /* Mask could have changed */ + ia->mask = *mask; + snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d", + inet_ntoa(*addr), inet_ntocidr(*mask)); + if (brd != NULL) + ia->brd = *brd; + else + ia->brd.s_addr = INADDR_ANY; + ia->addr_flags = flags; + break; + case RTM_DELADDR: + if (ia == NULL) + return; + TAILQ_REMOVE(&state->addrs, ia, next); + break; + default: + return; } - arp_handleifa(cmd, ifp, addr, flags); - dhcp_handleifa(cmd, ifp, addr, net, brd, flags); + if (addr->s_addr != INADDR_ANY && addr->s_addr != INADDR_BROADCAST) { + arp_handleifa(cmd, ia); + dhcp_handleifa(cmd, ia); + } + + if (cmd == RTM_DELADDR) + free(ia); } void ipv4_free(struct interface *ifp) { struct ipv4_state *state; - struct ipv4_addr *addr; + struct ipv4_addr *ia; if (ifp) { state = IPV4_STATE(ifp); if (state) { - while ((addr = TAILQ_FIRST(&state->addrs))) { - TAILQ_REMOVE(&state->addrs, addr, next); - free(addr); + while ((ia = TAILQ_FIRST(&state->addrs))) { + TAILQ_REMOVE(&state->addrs, ia, next); + free(ia); } ipv4_freerts(&state->routes); #ifdef BSD Index: src/external/bsd/dhcpcd/dist/ipv4ll.h diff -u src/external/bsd/dhcpcd/dist/ipv4ll.h:1.11 src/external/bsd/dhcpcd/dist/ipv4ll.h:1.12 --- src/external/bsd/dhcpcd/dist/ipv4ll.h:1.11 Sun Apr 10 21:00:53 2016 +++ src/external/bsd/dhcpcd/dist/ipv4ll.h Fri Jun 17 19:42:32 2016 @@ -1,8 +1,8 @@ -/* $NetBSD: ipv4ll.h,v 1.11 2016/04/10 21:00:53 roy Exp $ */ +/* $NetBSD: ipv4ll.h,v 1.12 2016/06/17 19:42:32 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2015 Roy Marples <r...@marples.name> + * Copyright (c) 2006-2016 Roy Marples <r...@marples.name> * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -33,19 +33,16 @@ #ifdef INET #include "arp.h" -extern const struct in_addr inaddr_llmask; -extern const struct in_addr inaddr_llbcast; - #define LINKLOCAL_ADDR 0xa9fe0000 #define LINKLOCAL_MASK IN_CLASSB_NET -#define LINKLOCAL_BRDC (LINKLOCAL_ADDR | ~LINKLOCAL_MASK) +#define LINKLOCAL_BCAST (LINKLOCAL_ADDR | ~LINKLOCAL_MASK) #ifndef IN_LINKLOCAL # define IN_LINKLOCAL(addr) ((addr & IN_CLASSB_NET) == LINKLOCAL_ADDR) #endif struct ipv4ll_state { - struct in_addr addr; + struct ipv4_addr *addr; struct arp_state *arp; unsigned int conflicts; struct timespec defend; @@ -58,8 +55,8 @@ struct ipv4ll_state { #define IPV4LL_CSTATE(ifp) \ ((const struct ipv4ll_state *)(ifp)->if_data[IF_DATA_IPV4LL]) #define IPV4LL_STATE_RUNNING(ifp) \ - (IPV4LL_CSTATE((ifp)) && !IPV4LL_CSTATE((ifp))->down && \ - IN_LINKLOCAL(ntohl(IPV4LL_CSTATE((ifp))->addr.s_addr))) + (IPV4LL_CSTATE((ifp)) && !IPV4LL_CSTATE((ifp))->down && \ + (IPV4LL_CSTATE((ifp))->addr != NULL)) struct rt* ipv4ll_subnet_route(const struct interface *); struct rt* ipv4ll_default_route(const struct interface *); Index: src/external/bsd/dhcpcd/dist/ipv6.c diff -u src/external/bsd/dhcpcd/dist/ipv6.c:1.18 src/external/bsd/dhcpcd/dist/ipv6.c:1.19 --- src/external/bsd/dhcpcd/dist/ipv6.c:1.18 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/ipv6.c Fri Jun 17 19:42:32 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: ipv6.c,v 1.18 2016/05/09 10:15:59 roy Exp $"); + __RCSID("$NetBSD: ipv6.c,v 1.19 2016/06/17 19:42:32 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -592,9 +592,9 @@ ipv6_deleteaddr(struct ipv6_addr *ia) logger(ia->iface->ctx, LOG_INFO, "%s: deleting address %s", ia->iface->name, ia->saddr); - if (if_deladdress6(ia) == -1 && + if (if_address6(RTM_DELADDR, ia) == -1 && errno != EADDRNOTAVAIL && errno != ENXIO && errno != ENODEV) - logger(ia->iface->ctx, LOG_ERR, "if_deladdress6: :%m"); + logger(ia->iface->ctx, LOG_ERR, "if_address6: :%m"); /* NOREJECT is set if we delegated exactly the prefix to another * address. @@ -704,7 +704,7 @@ ipv6_addaddr(struct ipv6_addr *ap, const #endif } - if (if_addaddress6(ap) == -1) { + if (if_address6(RTM_NEWADDR, ap) == -1) { logger(ap->iface->ctx, LOG_ERR, "if_addaddress6: %m"); /* Restore real pltime and vltime */ ap->prefix_pltime = pltime; @@ -827,10 +827,10 @@ ipv6_addaddrs(struct ipv6_addrhead *addr apf->iface->name, ap->saddr, ap->iface->name); - if (if_deladdress6(apf) == -1 && + if (if_address6(RTM_DELADDR, apf) == -1 && errno != EADDRNOTAVAIL && errno != ENXIO) logger(apf->iface->ctx, LOG_ERR, - "if_deladdress6: %m"); + "if_address6: %m"); apf->flags &= ~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED); } else if (apf) @@ -1453,7 +1453,7 @@ ipv6_startstatic(struct interface *ifp) ia->prefix_pltime = ND6_INFINITE_LIFETIME; ia->dadcallback = ipv6_staticdadcallback; ipv6_addaddr(ia, NULL); - if_initrt6(ifp); + if_initrt6(ifp->ctx); ipv6_buildroutes(ifp->ctx); if (run_script) script_runreason(ifp, "STATIC6"); @@ -1476,7 +1476,7 @@ ipv6_start(struct interface *ifp) } /* Load existing routes */ - if_initrt6(ifp); + if_initrt6(ifp->ctx); if (!IN6_IS_ADDR_UNSPECIFIED(&ifp->options->req_addr6)) ipv6_buildroutes(ifp->ctx); return 0; @@ -1497,7 +1497,7 @@ ipv6_freedrop(struct interface *ifp, int ipv6_freedrop_addrs(&state->addrs, drop ? 2 : 0, NULL); if (drop) { if (ifp->ctx->ipv6 != NULL) { - if_initrt6(ifp); + if_initrt6(ifp->ctx); ipv6_buildroutes(ifp->ctx); } } else { @@ -1955,7 +1955,7 @@ find_route6(struct rt6_head *rts, const (r->iface == NULL || rt->iface == NULL || rt->iface->metric == r->iface->metric) && #endif - IN6_ARE_ADDR_EQUAL(&rt->net, &r->net)) + IN6_ARE_ADDR_EQUAL(&rt->mask, &r->mask)) return rt; } return NULL; @@ -1975,16 +1975,16 @@ desc_route(const char *cmd, const struct gate = inet_ntop(AF_INET6, &rt->gate, gatebuf, INET6_ADDRSTRLEN); if (IN6_ARE_ADDR_EQUAL(&rt->gate, &in6addr_any)) logger(ctx, LOG_INFO, "%s: %s route to %s/%d", - ifname, cmd, dest, ipv6_prefixlen(&rt->net)); + ifname, cmd, dest, ipv6_prefixlen(&rt->mask)); else if (IN6_ARE_ADDR_EQUAL(&rt->dest, &in6addr_any) && - IN6_ARE_ADDR_EQUAL(&rt->net, &in6addr_any)) + IN6_ARE_ADDR_EQUAL(&rt->mask, &in6addr_any)) logger(ctx, LOG_INFO, "%s: %s default route via %s", ifname, cmd, gate); else logger(ctx, LOG_INFO, "%s: %s%s route to %s/%d via %s", ifname, cmd, rt->flags & RTF_REJECT ? " reject" : "", - dest, ipv6_prefixlen(&rt->net), gate); + dest, ipv6_prefixlen(&rt->mask), gate); } static struct rt6* @@ -2002,7 +2002,7 @@ ipv6_findrt(struct dhcpcd_ctx *ctx, cons (!flags || rt->iface == r->iface || (rt->flags & RTF_REJECT && r->flags & RTF_REJECT)) && #endif - IN6_ARE_ADDR_EQUAL(&rt->net, &r->net)) + IN6_ARE_ADDR_EQUAL(&rt->mask, &r->mask)) return r; } return NULL; @@ -2064,7 +2064,7 @@ nc_route(struct rt6 *ort, struct rt6 *nr /* Don't set default routes if not asked to */ if (IN6_IS_ADDR_UNSPECIFIED(&nrt->dest) && - IN6_IS_ADDR_UNSPECIFIED(&nrt->net) && + IN6_IS_ADDR_UNSPECIFIED(&nrt->mask) && !(nrt->iface->options->options & DHCPCD_GATEWAY)) return -1; @@ -2208,7 +2208,7 @@ make_prefix(const struct interface *ifp, if (r == NULL) return NULL; r->dest = addr->prefix; - ipv6_mask(&r->net, addr->prefix_len); + ipv6_mask(&r->mask, addr->prefix_len); if (addr->flags & IPV6_AF_DELEGATEDPFX) { r->flags |= RTF_REJECT; r->gate = in6addr_loopback; @@ -2226,14 +2226,14 @@ make_router(const struct ra *rap) if (r == NULL) return NULL; r->dest = in6addr_any; - r->net = in6addr_any; + r->mask = in6addr_any; r->gate = rap->from; return r; } #define RT_IS_DEFAULT(rtp) \ (IN6_ARE_ADDR_EQUAL(&((rtp)->dest), &in6addr_any) && \ - IN6_ARE_ADDR_EQUAL(&((rtp)->net), &in6addr_any)) + IN6_ARE_ADDR_EQUAL(&((rtp)->mask), &in6addr_any)) static void ipv6_build_static_routes(struct dhcpcd_ctx *ctx, struct rt6_head *dnr) Index: src/external/bsd/dhcpcd/dist/ipv6.h diff -u src/external/bsd/dhcpcd/dist/ipv6.h:1.18 src/external/bsd/dhcpcd/dist/ipv6.h:1.19 --- src/external/bsd/dhcpcd/dist/ipv6.h:1.18 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/ipv6.h Fri Jun 17 19:42:32 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: ipv6.h,v 1.18 2016/05/09 10:15:59 roy Exp $ */ +/* $NetBSD: ipv6.h,v 1.19 2016/06/17 19:42:32 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -183,14 +183,15 @@ struct ipv6_addr { #define IPV6_AF_NOREJECT 0x0200 #define IPV6_AF_REQUEST 0x0400 #define IPV6_AF_STATIC 0x0800 +#define IPV6_AF_DELEGATEDLOG 0x1000 #ifdef IPV6_MANAGETEMPADDR -#define IPV6_AF_TEMPORARY 0X1000 +#define IPV6_AF_TEMPORARY 0X2000 #endif struct rt6 { TAILQ_ENTRY(rt6) next; struct in6_addr dest; - struct in6_addr net; + struct in6_addr mask; struct in6_addr gate; const struct interface *iface; unsigned int flags; Index: src/external/bsd/dhcpcd/dist/ipv6nd.c diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.29 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.30 --- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.29 Wed Apr 20 08:53:01 2016 +++ src/external/bsd/dhcpcd/dist/ipv6nd.c Fri Jun 17 19:42:32 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: ipv6nd.c,v 1.29 2016/04/20 08:53:01 roy Exp $"); + __RCSID("$NetBSD: ipv6nd.c,v 1.30 2016/06/17 19:42:32 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -258,15 +258,6 @@ ipv6nd_makersprobe(struct interface *ifp return 0; } -static void ipv6nd_dropdhcp6(struct interface *ifp) -{ - const struct dhcp6_state *d6; - - /* Don't drop DHCP6 if the interface is delegated to. */ - if ((d6 = D6_CSTATE(ifp)) != NULL && d6->state != DH6S_DELEGATED) - dhcp6_drop(ifp, "EXPIRE6"); -} - static void ipv6nd_sendrsprobe(void *arg) { @@ -330,7 +321,7 @@ ipv6nd_sendrsprobe(void *arg) logger(ifp->ctx, LOG_WARNING, "%s: no IPv6 Routers available", ifp->name); ipv6nd_drop(ifp); - ipv6nd_dropdhcp6(ifp); + dhcp6_dropnondelegates(ifp); } } @@ -660,9 +651,9 @@ ipv6nd_dadcallback(void *arg) } logger(ifp->ctx, LOG_INFO, "%s: deleting address %s", ifp->name, ap->saddr); - if (if_deladdress6(ap) == -1 && + if (if_address6(RTM_DELADDR, ap) == -1 && errno != EADDRNOTAVAIL && errno != ENXIO) - logger(ifp->ctx, LOG_ERR, "if_deladdress6: %m"); + logger(ifp->ctx, LOG_ERR, "if_address6: %m"); dadcounter = ap->dadcounter; if (ipv6_makestableprivate(&ap->addr, &ap->prefix, ap->prefix_len, @@ -1102,7 +1093,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx, /* Find any freshly added routes, such as the subnet route. * We do this because we cannot rely on recieving the kernel * notification right now via our link socket. */ - if_initrt6(ifp); + if_initrt6(ifp->ctx); ipv6_buildroutes(ifp->ctx); if (ipv6nd_scriptrun(rap)) @@ -1395,7 +1386,7 @@ ipv6nd_expirera(void *arg) /* No valid routers? Kill any DHCPv6. */ if (!validone) - ipv6nd_dropdhcp6(ifp); + dhcp6_dropnondelegates(ifp); } void Index: src/external/bsd/dhcpcd/dist/script.c diff -u src/external/bsd/dhcpcd/dist/script.c:1.26 src/external/bsd/dhcpcd/dist/script.c:1.27 --- src/external/bsd/dhcpcd/dist/script.c:1.26 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/script.c Fri Jun 17 19:42:32 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: script.c,v 1.26 2016/05/09 10:15:59 roy Exp $"); + __RCSID("$NetBSD: script.c,v 1.27 2016/06/17 19:42:32 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -264,7 +264,7 @@ make_env(const struct interface *ifp, co ra = 1; #endif #ifdef INET - else if (istate && istate->addr.s_addr != INADDR_ANY) + else if (istate && istate->addr != NULL) ipv4ll = 1; else dhcp = 1; Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.8 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.9 --- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.8 Fri Aug 21 10:39:00 2015 +++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf Fri Jun 17 19:42:32 2016 @@ -1,4 +1,4 @@ -# $NetBSD: 20-resolv.conf,v 1.8 2015/08/21 10:39:00 roy Exp $ +# $NetBSD: 20-resolv.conf,v 1.9 2016/06/17 19:42:32 roy Exp $ # Generate /etc/resolv.conf # Support resolvconf(8) if available @@ -94,8 +94,8 @@ eval_nd_dns() [ -z "$rdnss" -a -z "$dnssl" ] && return 1 - new_rdnss="$new_rdnss${new_rdnss:+ }$rdnss" - new_dnssl="$new_dnssl${new_dnssl:+ }$dnssl" + [ -n "$rdnss" ] && new_rdnss="$new_rdnss${new_rdnss:+ }$rdnss" + [ -n "$dnssl" ] && new_dnssl="$new_dnssl${new_dnssl:+ }$dnssl" j=$(($j + 1)) return 0 } @@ -116,8 +116,10 @@ add_resolv_conf() j=1 eval_nd_dns || break done - new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss" - new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl" + [ -n "$new_rdnss" ] && \ + new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss" + [ -n "$new_dnssl" ] && \ + new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl" # Derive a new domain from our various hostname options if [ -z "$new_domain_name" ]; then Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.7 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.8 --- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.7 Fri Aug 21 10:39:00 2015 +++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname Fri Jun 17 19:42:32 2016 @@ -1,4 +1,4 @@ -# $NetBSD: 30-hostname,v 1.7 2015/08/21 10:39:00 roy Exp $ +# $NetBSD: 30-hostname,v 1.8 2016/06/17 19:42:32 roy Exp $ # Set the hostname from DHCP data if required @@ -68,7 +68,7 @@ need_hostname() case "$hostname_fqdn" in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) hfqdn=true;; - [Ss][Ee][Rr][Vv][Ee][Rr]) ;; + ""|[Ss][Ee][Rr][Vv][Ee][Rr]) ;; *) hshort=true;; esac @@ -117,7 +117,7 @@ set_hostname() case "$hostname_fqdn" in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) hfqdn=true;; - "") ;; + ""|[Ss][Ee][Rr][Vv][Ee][Rr]) ;; *) hshort=true;; esac