diff --git a/external/bsd/dhcpcd/dist/control.c b/external/bsd/dhcpcd/dist/control.c index 67854fa906de..43404d1a29ff 100644 --- a/external/bsd/dhcpcd/dist/control.c +++ b/external/bsd/dhcpcd/dist/control.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: control.c,v 1.9 2015/05/16 23:31:32 roy Exp $"); + __RCSID("$NetBSD: control.c,v 1.10 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -46,6 +46,7 @@ #include "dhcpcd.h" #include "control.h" #include "eloop.h" +#include "if.h" #ifndef SUN_LEN #define SUN_LEN(su) \ @@ -210,28 +211,8 @@ make_sock(struct sockaddr_un *sa, const char *ifname, int unpriv) { int fd; -#ifdef SOCK_CLOEXEC - if ((fd = socket(AF_UNIX, - SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) == -1) + if ((fd = xsocket(AF_UNIX, SOCK_STREAM, 0, O_NONBLOCK|O_CLOEXEC)) == -1) return -1; -#else - int flags; - - if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) - return -1; - if ((flags = fcntl(fd, F_GETFD, 0)) == -1 || - fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) - { - close(fd); - return -1; - } - if ((flags = fcntl(fd, F_GETFL, 0)) == -1 || - fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) - { - close(fd); - return -1; - } -#endif memset(sa, 0, sizeof(*sa)); sa->sun_family = AF_UNIX; if (unpriv) diff --git a/external/bsd/dhcpcd/dist/defs.h b/external/bsd/dhcpcd/dist/defs.h index a023f91f99d6..ec84fb5984a4 100644 --- a/external/bsd/dhcpcd/dist/defs.h +++ b/external/bsd/dhcpcd/dist/defs.h @@ -1,4 +1,4 @@ -/* $NetBSD: defs.h,v 1.19 2015/07/09 10:15:34 roy Exp $ */ +/* $NetBSD: defs.h,v 1.20 2015/08/21 10:39:00 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -30,7 +30,7 @@ #define CONFIG_H #define PACKAGE "dhcpcd" -#define VERSION "6.9.1" +#define VERSION "6.9.2" #ifndef CONFIG # define CONFIG SYSCONFDIR "/" PACKAGE ".conf" diff --git a/external/bsd/dhcpcd/dist/dhcp.c b/external/bsd/dhcpcd/dist/dhcp.c index e110a087935c..ab00301098f4 100644 --- a/external/bsd/dhcpcd/dist/dhcp.c +++ b/external/bsd/dhcpcd/dist/dhcp.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: dhcp.c,v 1.32 2015/07/09 10:15:34 roy Exp $"); + __RCSID("$NetBSD: dhcp.c,v 1.33 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -278,6 +278,23 @@ get_option_uint32(struct dhcpcd_ctx *ctx, return 0; } +static int +get_option_uint16(struct dhcpcd_ctx *ctx, + uint16_t *i, const struct dhcp_message *dhcp, uint8_t option) +{ + const uint8_t *p; + size_t len; + uint16_t d; + + p = get_option(ctx, dhcp, option, &len); + if (!p || len < (ssize_t)sizeof(d)) + return -1; + memcpy(&d, p, sizeof(d)); + if (i) + *i = ntohs(d); + return 0; +} + static int get_option_uint8(struct dhcpcd_ctx *ctx, uint8_t *i, const struct dhcp_message *dhcp, uint8_t option) @@ -586,7 +603,7 @@ route_netmask(uint32_t ip_in) /* We need to obey routing options. * If we have a CSR then we only use that. * Otherwise we add static routes and then routers. */ -struct rt_head * +static struct rt_head * get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp) { struct if_options *ifo = ifp->options; @@ -692,6 +709,40 @@ get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp) return routes; } +uint16_t +dhcp_get_mtu(const struct interface *ifp) +{ + const struct dhcp_message *dhcp; + uint16_t mtu; + + if ((dhcp = D_CSTATE(ifp)->new) == NULL || + has_option_mask(ifp->options->nomask, DHO_MTU) || + get_option_uint16(ifp->ctx, &mtu, dhcp, DHO_MTU) == -1) + return 0; + return mtu; +} + +/* Grab our routers from the DHCP message and apply any MTU value + * the message contains */ +struct rt_head * +dhcp_get_routes(struct interface *ifp) +{ + struct rt_head *routes; + uint16_t mtu; + const struct dhcp_message *dhcp; + + dhcp = D_CSTATE(ifp)->new; + routes = get_option_routes(ifp, dhcp); + if ((mtu = dhcp_get_mtu(ifp)) != 0) { + struct rt *rt; + + TAILQ_FOREACH(rt, routes, next) { + rt->mtu = mtu; + } + } + return routes; +} + #define PUTADDR(_type, _val) \ { \ *p++ = _type; \ @@ -852,21 +903,27 @@ make_message(struct dhcp_message **message, if (!(ifo->options & DHCPCD_BOOTP)) { int mtu; - *p++ = DHO_MAXMESSAGESIZE; - *p++ = 2; - mtu = if_getmtu(ifp->name); - if (mtu < MTU_MIN) { - if (if_setmtu(ifp->name, MTU_MIN) == 0) - sz = MTU_MIN; + if ((mtu = if_getmtu(ifp)) == -1) + logger(ifp->ctx, LOG_ERR, + "%s: if_getmtu: %m", ifp->name); + else if (mtu < MTU_MIN) { + if (if_setmtu(ifp, MTU_MIN) == -1) + logger(ifp->ctx, LOG_ERR, + "%s: if_setmtu: %m", ifp->name); + mtu = MTU_MIN; } else if (mtu > MTU_MAX) { /* Even though our MTU could be greater than * MTU_MAX (1500) dhcpcd does not presently * handle DHCP packets any bigger. */ mtu = MTU_MAX; } - sz = htons((uint16_t)mtu); - memcpy(p, &sz, 2); - p += 2; + if (mtu != -1) { + *p++ = DHO_MAXMESSAGESIZE; + *p++ = 2; + sz = htons((uint16_t)mtu); + memcpy(p, &sz, 2); + p += 2; + } } if (ifo->userclass[0]) { @@ -1184,6 +1241,13 @@ read_lease(struct interface *ifp) else logger(ifp->ctx, LOG_DEBUG, "%s: accepted reconfigure key", ifp->name); + } else if ((ifp->options->auth.options & DHCPCD_AUTH_SENDREQUIRE) == + DHCPCD_AUTH_SENDREQUIRE) + { + logger(ifp->ctx, LOG_ERR, + "%s: authentication now required", ifp->name); + free(dhcp); + return NULL; } return dhcp; @@ -1483,19 +1547,8 @@ dhcp_openudp(struct interface *ifp) char *p; #endif -#ifdef SOCK_CLOEXEC - if ((s = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP)) == -1) + if ((s = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP, O_CLOEXEC)) == -1) return -1; -#else - if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) - return -1; - if ((n = fcntl(s, F_GETFD, 0)) == -1 || - fcntl(s, F_SETFD, n | FD_CLOEXEC) == -1) - { - close(s); - return -1; - } -#endif n = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1) @@ -2325,6 +2378,8 @@ dhcp_drop(struct interface *ifp, const char *reason) dhcp_auth_reset(&state->auth); dhcp_close(ifp); + free(state->offer); + state->offer = NULL; free(state->old); state->old = state->new; state->new = NULL; @@ -2481,12 +2536,15 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp, else logger(ifp->ctx, LOG_DEBUG, "%s: accepted reconfigure key", ifp->name); - } else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) { - log_dhcp1(LOG_ERR, "no authentication", ifp, dhcp, from, 0); - return; - } else if (ifo->auth.options & DHCPCD_AUTH_SEND) + } else if (ifo->auth.options & DHCPCD_AUTH_SEND) { + if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) { + log_dhcp1(LOG_ERR, "no authentication", + ifp, dhcp, from, 0); + return; + } log_dhcp1(LOG_WARNING, "no authentication", ifp, dhcp, from, 0); + } /* RFC 3203 */ if (type == DHCP_FORCERENEW) { @@ -2500,7 +2558,8 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp, if (auth == NULL) { log_dhcp(LOG_ERR, "unauthenticated Force Renew", ifp, dhcp, from); - return; + if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) + return; } if (state->state != DHS_BOUND && state->state != DHS_INFORM) { log_dhcp(LOG_DEBUG, "not bound, ignoring Force Renew", @@ -3203,7 +3262,7 @@ dhcp_start1(void *arg) } /* We don't want to read the old lease if we NAK an old test */ nolease = state->offer && ifp->ctx->options & DHCPCD_TEST; - if (!nolease) { + if (!nolease && ifo->options & DHCPCD_DHCP) { state->offer = read_lease(ifp); /* Check the saved lease matches the type we want */ if (state->offer) { @@ -3294,13 +3353,8 @@ dhcp_start1(void *arg) } if (!(ifo->options & DHCPCD_DHCP)) { - if (ifo->options & DHCPCD_IPV4LL) { - if (state->offer && state->offer->cookie != 0) { - free(state->offer); - state->offer = NULL; - } + if (ifo->options & DHCPCD_IPV4LL) ipv4ll_start(ifp); - } return; } @@ -3337,6 +3391,13 @@ dhcp_start(struct interface *ifp) eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcp_start1, ifp); } +void +dhcp_abort(struct interface *ifp) +{ + + eloop_timeout_delete(ifp->ctx->eloop, dhcp_start1, ifp); +} + void dhcp_handleifa(int cmd, struct interface *ifp, const struct in_addr *addr, diff --git a/external/bsd/dhcpcd/dist/dhcp.h b/external/bsd/dhcpcd/dist/dhcp.h index 9831c484437a..616a19766772 100644 --- a/external/bsd/dhcpcd/dist/dhcp.h +++ b/external/bsd/dhcpcd/dist/dhcp.h @@ -1,4 +1,4 @@ -/* $NetBSD: dhcp.h,v 1.10 2015/07/09 10:15:34 roy Exp $ */ +/* $NetBSD: dhcp.h,v 1.11 2015/08/21 10:39:00 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -247,8 +247,8 @@ int get_option_addr(struct dhcpcd_ctx *,struct in_addr *, const struct dhcp_message *, uint8_t); #define IS_BOOTP(i, m) ((m) != NULL && \ get_option_uint8((i)->ctx, NULL, (m), DHO_MESSAGETYPE) == -1) -struct rt_head *get_option_routes(struct interface *, - const struct dhcp_message *); +uint16_t dhcp_get_mtu(const struct interface *); +struct rt_head *dhcp_get_routes(struct interface *); ssize_t dhcp_env(char **, const char *, const struct dhcp_message *, const struct interface *); @@ -266,7 +266,7 @@ void dhcp_handleifa(int, struct interface *, void dhcp_drop(struct interface *, const char *); void dhcp_start(struct interface *); -void dhcp_stop(struct interface *); +void dhcp_abort(struct interface *); void dhcp_discover(void *); void dhcp_inform(struct interface *); void dhcp_bind(struct interface *); @@ -277,6 +277,7 @@ int dhcp_dump(struct interface *); #else #define dhcp_drop(a, b) {} #define dhcp_start(a) {} +#define dhcp_abort(a) {} #define dhcp_reboot(a, b) (b = b) #define dhcp_reboot_newopts(a, b) (b = b) #define dhcp_close(a) {} diff --git a/external/bsd/dhcpcd/dist/dhcp6.c b/external/bsd/dhcpcd/dist/dhcp6.c index bd600818bab2..892b57edccaa 100644 --- a/external/bsd/dhcpcd/dist/dhcp6.c +++ b/external/bsd/dhcpcd/dist/dhcp6.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: dhcp6.c,v 1.14 2015/07/09 10:15:34 roy Exp $"); + __RCSID("$NetBSD: dhcp6.c,v 1.15 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -43,6 +43,7 @@ #include #include #include +#include #define ELOOP_QUEUE 4 #include "config.h" @@ -2247,7 +2248,9 @@ auth: else logger(ifp->ctx, LOG_DEBUG, "%s: accepted reconfigure key", ifp->name); - } else if (ifp->options->auth.options & DHCPCD_AUTH_REQUIRE) { + } else if ((ifp->options->auth.options & DHCPCD_AUTH_SENDREQUIRE) == + DHCPCD_AUTH_SENDREQUIRE) + { logger(ifp->ctx, LOG_ERR, "%s: authentication now required", ifp->name); goto ex; @@ -2753,13 +2756,16 @@ dhcp6_handledata(void *arg) else logger(ifp->ctx, LOG_DEBUG, "%s: accepted reconfigure key", ifp->name); - } else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) { - logger(ifp->ctx, LOG_ERR, - "%s: no authentication from %s", ifp->name, ctx->sfrom); - return; - } else if (ifo->auth.options & DHCPCD_AUTH_SEND) + } else if (ifo->auth.options & DHCPCD_AUTH_SEND) { + if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) { + logger(ifp->ctx, LOG_ERR, + "%s: no authentication from %s", + ifp->name, ctx->sfrom); + return; + } logger(ifp->ctx, LOG_WARNING, "%s: no authentication from %s", ifp->name, ctx->sfrom); + } op = dhcp6_get_op(r->type); switch(r->type) { @@ -2863,7 +2869,8 @@ dhcp6_handledata(void *arg) logger(ifp->ctx, LOG_ERR, "%s: unauthenticated %s from %s", ifp->name, op, ctx->sfrom); - return; + if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) + return; } logger(ifp->ctx, LOG_INFO, "%s: %s from %s", ifp->name, op, ctx->sfrom); @@ -3073,30 +3080,10 @@ dhcp6_open(struct dhcpcd_ctx *dctx) #endif ctx = dctx->ipv6; -#ifdef SOCK_CLOEXEC - ctx->dhcp_fd = socket(PF_INET6, - SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, - IPPROTO_UDP); + ctx->dhcp_fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, + O_NONBLOCK|O_CLOEXEC); if (ctx->dhcp_fd == -1) return -1; -#else - if ((ctx->dhcp_fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1) - return -1; - if ((n = fcntl(ctx->dhcp_fd, F_GETFD, 0)) == -1 || - fcntl(ctx->dhcp_fd, F_SETFD, n | FD_CLOEXEC) == -1) - { - close(ctx->dhcp_fd); - ctx->dhcp_fd = -1; - return -1; - } - if ((n = fcntl(ctx->dhcp_fd, F_GETFL, 0)) == -1 || - fcntl(ctx->dhcp_fd, F_SETFL, n | O_NONBLOCK) == -1) - { - close(ctx->dhcp_fd); - ctx->dhcp_fd = -1; - return -1; - } -#endif n = 1; if (setsockopt(ctx->dhcp_fd, SOL_SOCKET, SO_REUSEADDR, @@ -3143,8 +3130,8 @@ dhcp6_start1(void *arg) const struct dhcp_compat *dhc; state = D6_STATE(ifp); - /* Match any DHCPv4 opton to DHCPv6 options if given for easy - * configuration */ + /* If no DHCPv6 options are configured, + match configured DHCPv4 options to DHCPv6 equivalents. */ for (i = 0; i < sizeof(ifo->requestmask6); i++) { if (ifo->requestmask6[i] != '\0') break; @@ -3160,7 +3147,7 @@ dhcp6_start1(void *arg) add_option_mask(ifo->requestmask6, D6_OPTION_FQDN); } - /* Rapid commit won't wor with Prefix Delegation Exclusion */ + /* Rapid commit won't work with Prefix Delegation Exclusion */ if (dhcp6_findselfsla(ifp, NULL)) del_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT); diff --git a/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-mtu b/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-mtu deleted file mode 100644 index 26d1a0c21395..000000000000 --- a/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-mtu +++ /dev/null @@ -1,40 +0,0 @@ -# $NetBSD: 10-mtu,v 1.6 2014/11/07 20:51:03 roy Exp $ - -# Configure the MTU for the interface - -mtu_dir="$state_dir/mtu" - -set_mtu() -{ - local mtu=$1 - - if [ -w /sys/class/net/$interface/mtu ]; then - echo "$mtu" >/sys/class/net/$interface/mtu - else - ifconfig "$interface" mtu "$mtu" - fi -} - -if [ "$reason" = PREINIT -a -e "$mtu_dir/$interface" ]; then - rm "$mtu_dir/$interface" -elif [ -n "$new_interface_mtu" ] && $if_up; then - # The smalled MTU dhcpcd can work with is 576 - if [ "$new_interface_mtu" -ge 576 ]; then - if set_mtu "$new_interface_mtu"; then - syslog info "MTU set to $new_interface_mtu" - # Save the MTU so we can restore it later - if [ ! -e "$mtu_dir/$interface" ]; then - mkdir -p "$mtu_dir" - echo "$ifmtu" > "$mtu_dir/$interface" - fi - fi - fi -elif [ -e "$mtu_dir/$interface" ]; then - if $if_up || $if_down; then - # No MTU in this state, so restore the prior MTU - mtu=$(cat "$mtu_dir/$interface") - syslog info "MTU restored to $mtu" - set_mtu "$mtu" - rm "$mtu_dir/$interface" - fi -fi diff --git a/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf b/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf index 027fa1b62282..e3a64821225a 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf +++ b/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf @@ -1,4 +1,4 @@ -# $NetBSD: 20-resolv.conf,v 1.7 2015/05/16 23:31:32 roy Exp $ +# $NetBSD: 20-resolv.conf,v 1.8 2015/08/21 10:39:00 roy Exp $ # Generate /etc/resolv.conf # Support resolvconf(8) if available @@ -119,14 +119,6 @@ add_resolv_conf() new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss" new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl" - # If we don't have any configuration, remove it - if [ -z "$new_domain_name_servers" -a \ - -z "$new_domain_name" -a \ - -z "$new_domain_search" ]; then - remove_resolv_conf - return $? - fi - # Derive a new domain from our various hostname options if [ -z "$new_domain_name" ]; then if [ "$new_dhcp6_fqdn" != "${new_dhcp6_fqdn#*.}" ]; then @@ -138,6 +130,14 @@ add_resolv_conf() fi fi + # If we don't have any configuration, remove it + if [ -z "$new_domain_name_servers" -a \ + -z "$new_domain_name" -a \ + -z "$new_domain_search" ]; then + remove_resolv_conf + return $? + fi + if [ -n "$new_domain_name" ]; then set -- $new_domain_name if valid_domainname "$1"; then diff --git a/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname b/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname index c4068ac1d889..e0f0400f0413 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname +++ b/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname @@ -1,4 +1,4 @@ -# $NetBSD: 30-hostname,v 1.6 2014/11/07 20:51:03 roy Exp $ +# $NetBSD: 30-hostname,v 1.7 2015/08/21 10:39:00 roy Exp $ # Set the hostname from DHCP data if required @@ -148,6 +148,7 @@ set_hostname() case "$reason" in BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6) new_fqdn="$new_dhcp6_fqdn" + old_fqdn="$old_dhcp6_fqdn" ;; esac diff --git a/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in b/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in index 4d159c974da6..8fe9a5007c13 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in +++ b/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in @@ -1,5 +1,5 @@ #!/bin/sh -# $NetBSD: dhcpcd-run-hooks.in,v 1.10 2015/07/09 10:15:34 roy Exp $ +# $NetBSD: dhcpcd-run-hooks.in,v 1.11 2015/08/21 10:39:00 roy Exp $ # dhcpcd client configuration script @@ -120,8 +120,7 @@ remove_markers() comp_file() { - [ -e "$1" ] || return 1 - [ -e "$2" ] || return 1 + [ -e "$1" -a -e "$2" ] || return 1 if type cmp >/dev/null 2>&1; then cmp -s "$1" "$2" diff --git a/external/bsd/dhcpcd/dist/dhcpcd.8.in b/external/bsd/dhcpcd/dist/dhcpcd.8.in index f1942356e048..9d148d446bb3 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd.8.in +++ b/external/bsd/dhcpcd/dist/dhcpcd.8.in @@ -1,4 +1,4 @@ -.\" $NetBSD: dhcpcd.8.in,v 1.43 2015/07/09 10:15:34 roy Exp $ +.\" $NetBSD: dhcpcd.8.in,v 1.44 2015/08/21 10:39:00 roy Exp $ .\" Copyright (c) 2006-2015 Roy Marples .\" All rights reserved .\" @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 3, 2015 +.Dd August 21, 2015 .Dt DHCPCD 8 .Os .Sh NAME @@ -204,7 +204,7 @@ This script runs each script found in in a lexical order. The default installation supplies the scripts .Pa 01-test , -.Pa 10-mtu , +.Pa 02-dump , .Pa 10-wpa_supplicant , .Pa 15-timezone , .Pa 20-resolv.conf @@ -552,8 +552,8 @@ Matches full name, or prefixed with 2 numbers optionally ending with .Pp So to stop .Nm -from touching your DNS or MTU settings you would do:- -.D1 dhcpcd -C resolv.conf -C mtu eth0 +from touching your DNS settings you would do:- +.D1 dhcpcd -C resolv.conf eth0 .It Fl G , Fl Fl nogateway Don't set any default routes. .It Fl H , Fl Fl xidhwaddr diff --git a/external/bsd/dhcpcd/dist/dhcpcd.c b/external/bsd/dhcpcd/dist/dhcpcd.c index 4007a9bc4b7d..9210e0ce396d 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd.c +++ b/external/bsd/dhcpcd/dist/dhcpcd.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: dhcpcd.c,v 1.26 2015/07/09 10:15:34 roy Exp $"); + __RCSID("$NetBSD: dhcpcd.c,v 1.27 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -575,10 +575,6 @@ configure_interface1(struct interface *ifp) } } #endif - - /* If we are not sending an authentication option, don't require it */ - if (!(ifo->auth.options & DHCPCD_AUTH_SEND)) - ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE; } int @@ -703,6 +699,7 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags, script_runreason(ifp, "NOCARRIER"); #ifdef NOCARRIER_PRESERVE_IP arp_close(ifp); + dhcp_abort(ifp); if_sortinterfaces(ctx); ipv4_preferanother(ifp); ipv6nd_expire(ifp, 0); @@ -907,7 +904,9 @@ dhcpcd_prestartinterface(void *arg) struct interface *ifp = arg; pre_start(ifp); - if (if_up(ifp) == -1) + if ((!(ifp->ctx->options & DHCPCD_MASTER) || + ifp->options->options & DHCPCD_IF_UP) && + if_up(ifp) == -1) logger(ifp->ctx, LOG_ERR, "%s: if_up: %m", ifp->name); if (ifp->options->options & DHCPCD_LINK && @@ -1395,6 +1394,14 @@ main(int argc, char **argv) ifo = NULL; ctx.cffile = CONFIG; ctx.pid_fd = ctx.control_fd = ctx.control_unpriv_fd = ctx.link_fd = -1; + ctx.pf_inet_fd = -1; +#if defined(INET6) && defined(BSD) + ctx.pf_inet6_fd = -1; +#endif +#ifdef IFLR_ACTIVE + ctx.pf_link_fd = -1; +#endif + TAILQ_INIT(&ctx.control_fds); #ifdef PLUGIN_DEV ctx.dev_fd = -1; @@ -1760,17 +1767,12 @@ main(int argc, char **argv) if (ctx.ifc == 1 && !(ctx.options & DHCPCD_BACKGROUND)) ctx.options |= DHCPCD_WAITIP; - /* RTM_NEWADDR goes through the link socket as well which we - * need for IPv6 DAD, so we check for DHCPCD_LINK in - * dhcpcd_handlecarrier instead. - * We also need to open this before checking for interfaces below - * so that we pickup any new addresses during the discover phase. */ - ctx.link_fd = if_openlinksocket(); - if (ctx.link_fd == -1) - logger(&ctx, LOG_ERR, "open_link_socket: %m"); - else - eloop_event_add(ctx.eloop, ctx.link_fd, - handle_link, &ctx, NULL, NULL); + /* Open our persistent sockets. */ + if (if_opensockets(&ctx) == -1) { + logger(&ctx, LOG_ERR, "if_opensockets: %m"); + goto exit_failure; + } + eloop_event_add(ctx.eloop, ctx.link_fd, handle_link, &ctx, NULL, NULL); /* Start any dev listening plugin which may want to * change the interface name provided by the kernel */ @@ -1875,6 +1877,17 @@ exit1: eloop_event_delete(ctx.eloop, ctx.link_fd); close(ctx.link_fd); } + if (ctx.pf_inet_fd != -1) + close(ctx.pf_inet_fd); +#if defined(INET6) && defined(BSD) + if (ctx.pf_inet6_fd != -1) + close(ctx.pf_inet6_fd); +#endif +#ifdef IFLR_ACTIVE + if (ctx.pf_link_fd != -1) + close(ctx.pf_link_fd); +#endif + free_options(ifo); free_globals(&ctx); diff --git a/external/bsd/dhcpcd/dist/dhcpcd.conf b/external/bsd/dhcpcd/dist/dhcpcd.conf index d12aa11da316..786f647e4a59 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd.conf +++ b/external/bsd/dhcpcd/dist/dhcpcd.conf @@ -1,4 +1,4 @@ -# $NetBSD: dhcpcd.conf,v 1.16 2015/03/26 10:26:37 roy Exp $ +# $NetBSD: dhcpcd.conf,v 1.17 2015/08/21 10:39:00 roy Exp $ # A sample configuration for dhcpcd. # See dhcpcd.conf(5) for details. @@ -30,9 +30,8 @@ option domain_name_servers, domain_name, domain_search, host_name option classless_static_routes # Most distributions have NTP support. option ntp_servers -# Respect the network MTU. -# Some interface drivers reset when changing the MTU so disabled by default. -#option interface_mtu +# Respect the network MTU. This is applied to DHCP routes. +option interface_mtu # A ServerID is required by RFC2131. require dhcp_server_identifier diff --git a/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in b/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in index d3a5089b6a34..8827f03b1745 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in +++ b/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in @@ -1,4 +1,4 @@ -.\" $NetBSD: dhcpcd.conf.5.in,v 1.22 2015/07/09 10:15:34 roy Exp $ +.\" $NetBSD: dhcpcd.conf.5.in,v 1.23 2015/08/21 10:39:00 roy Exp $ .\" Copyright (c) 2006-2015 Roy Marples .\" All rights reserved .\" @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 9, 2015 +.Dd August 1, 2015 .Dt DHCPCD.CONF 5 .Os .Sh NAME @@ -408,6 +408,7 @@ Don't send any ARP requests. This also disables IPv4LL. .It Ic noauthrequired Don't require authentication even though we requested it. +Also allows FORCERENEW and RECONFIGURE messages without authentication. .It Ic nodelay Don't delay for an initial randomised time when starting protocols. .It Ic nodev @@ -431,8 +432,8 @@ Matches full name, or prefixed with 2 numbers optionally ending with .Pp So to stop .Nm dhcpcd -from touching your DNS or MTU settings you would do:- -.D1 nohook resolv.conf, mtu +from touching your DNS settings or starting wpa_supplicant you would do:- +.D1 nohook resolv.conf, wpa_supplicant .It Ic noipv4 Don't attempt to configure an IPv4 address. .It Ic noipv4ll @@ -448,6 +449,14 @@ Disable solicitation and receipt of IPv6 Router Advertisements. .It Ic nolink Don't receive link messages about carrier status. You should only set this for buggy interface drivers. +.It Ic noup +Don't bring the interface up when in master mode. +If +.Nm +cannot determine the carrier state, +.Nm +will enter a tight polling loop until the interface is marked up and running +or a valid carrier state is reported. .It Ic option Ar option Requests the .Ar option @@ -464,7 +473,8 @@ lines. Prepend dhcp6_ to .Ar option to request a DHCPv6 option. -DHCPv4 options are mapped to DHCPv6 where applicable. +If no DHCPv6 options are configured, +then DHCPv4 options are mapped to equivalent DHCPv6 options. .Pp Prepend nd_ to .Ar option diff --git a/external/bsd/dhcpcd/dist/dhcpcd.h b/external/bsd/dhcpcd/dist/dhcpcd.h index 587322d76120..2c8037fe25d8 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd.h +++ b/external/bsd/dhcpcd/dist/dhcpcd.h @@ -1,4 +1,4 @@ -/* $NetBSD: dhcpcd.h,v 1.12 2015/07/09 10:15:34 roy Exp $ */ +/* $NetBSD: dhcpcd.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -64,6 +64,11 @@ * dhcpcd can poll it for the relevant flags periodically */ #define IF_POLL_UP 100 /* milliseconds */ +#ifdef __QNX__ +/* QNX carries defines for, but does not actually support PF_LINK */ +#undef IFLR_ACTIVE +#endif + struct interface { struct dhcpcd_ctx *ctx; TAILQ_ENTRY(interface) next; @@ -107,9 +112,17 @@ struct dhcpcd_ctx { char **ifcv; /* configured interfaces */ unsigned char *duid; size_t duid_len; - int link_fd; struct if_head *ifaces; + int pf_inet_fd; +#if defined(INET6) && defined(BSD) + int pf_inet6_fd; +#endif +#ifdef IFLR_ACTIVE + int pf_link_fd; +#endif + int link_fd; + #ifdef USE_SIGNALS sigset_t sigset; #endif @@ -125,6 +138,8 @@ struct dhcpcd_ctx { struct dhcp_opt *vivso; size_t vivso_len; + char *randomstate; /* original state */ + #ifdef INET struct dhcp_opt *dhcp_opts; size_t dhcp_opts_len; diff --git a/external/bsd/dhcpcd/dist/if-bsd.c b/external/bsd/dhcpcd/dist/if-bsd.c index d51bb2be65bc..6581764335ce 100644 --- a/external/bsd/dhcpcd/dist/if-bsd.c +++ b/external/bsd/dhcpcd/dist/if-bsd.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: if-bsd.c,v 1.22 2015/07/09 10:15:34 roy Exp $"); + __RCSID("$NetBSD: if-bsd.c,v 1.23 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -84,6 +84,7 @@ #include "if.h" #include "if-options.h" #include "ipv4.h" +#include "ipv4ll.h" #include "ipv6.h" #include "ipv6nd.h" @@ -127,27 +128,7 @@ int if_openlinksocket(void) { -#ifdef SOCK_CLOEXEC - return socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); -#else - int s, flags; - - if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1) - return -1; - if ((flags = fcntl(s, F_GETFD, 0)) == -1 || - fcntl(s, F_SETFD, flags | FD_CLOEXEC) == -1) - { - close(s); - return -1; - } - if ((flags = fcntl(s, F_GETFL, 0)) == -1 || - fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) - { - close(s); - return -1; - } - return s; -#endif + return xsocket(PF_ROUTE, SOCK_RAW, 0, O_NONBLOCK|O_CLOEXEC); } #if defined(INET) || defined(INET6) @@ -164,9 +145,9 @@ if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp) #endif static int -if_getssid1(const char *ifname, uint8_t *ssid) +if_getssid1(int s, const char *ifname, uint8_t *ssid) { - int s, retval = -1; + int retval = -1; #if defined(SIOCG80211NWID) struct ifreq ifr; struct ieee80211_nwid nwid; @@ -175,9 +156,6 @@ if_getssid1(const char *ifname, uint8_t *ssid) char nwid[IEEE80211_NWID_LEN + 1]; #endif - if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) - return -1; - #if defined(SIOCG80211NWID) /* NetBSD */ memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); @@ -216,7 +194,6 @@ if_getssid1(const char *ifname, uint8_t *ssid) } #endif - close(s); return retval; } @@ -225,7 +202,7 @@ if_getssid(struct interface *ifp) { int r; - r = if_getssid1(ifp->name, ifp->ssid); + r = if_getssid1(ifp->ctx->pf_inet_fd, ifp->name, ifp->ssid); if (r != -1) ifp->ssid_len = (unsigned int)r; return r; @@ -239,23 +216,20 @@ if_getssid(struct interface *ifp) * returning the SSID gives an error. */ int -if_vimaster(const char *ifname) +if_vimaster(const struct dhcpcd_ctx *ctx, const char *ifname) { - int s, r; + int r; struct ifmediareq ifmr; - if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) - return -1; memset(&ifmr, 0, sizeof(ifmr)); strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); - r = ioctl(s, SIOCGIFMEDIA, &ifmr); - close(s); + r = ioctl(ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr); if (r == -1) return -1; if (ifmr.ifm_status & IFM_AVALID && IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211) { - if (if_getssid1(ifname, NULL) == -1) + if (if_getssid1(ctx->pf_inet_fd, ifname, NULL) == -1) return 1; } return 0; @@ -450,12 +424,9 @@ if_address(const struct interface *ifp, const struct in_addr *address, const struct in_addr *netmask, const struct in_addr *broadcast, int action) { - int s, r; + int r; struct in_aliasreq ifra; - if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) - return -1; - memset(&ifra, 0, sizeof(ifra)); strlcpy(ifra.ifra_name, ifp->name, sizeof(ifra.ifra_name)); @@ -470,9 +441,8 @@ if_address(const struct interface *ifp, const struct in_addr *address, ADDADDR(&ifra.ifra_broadaddr, broadcast); #undef ADDADDR - r = ioctl(s, + r = ioctl(ifp->ctx->pf_inet_fd, action < 0 ? SIOCDIFADDR : SIOCAIFADDR, &ifra); - close(s); return r; } @@ -503,6 +473,7 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm) get_addrs(rtm->rtm_addrs, cp, 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]); @@ -511,6 +482,9 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm) COPYOUT(rt->gate, rti_info[RTAX_GATEWAY]); COPYOUT(rt->src, rti_info[RTAX_IFA]); + if (rtm->rtm_inits & RTV_MTU) + rt->mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu; + if (rtm->rtm_index) rt->iface = if_findindex(ctx->ifaces, rtm->rtm_index); else if (rtm->rtm_addrs & RTA_IFP) { @@ -519,6 +493,7 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm) sdl = (struct sockaddr_dl *)(void *)rti_info[RTAX_IFP]; rt->iface = if_findsdl(ctx, sdl); } + /* If we don't have an interface and it's a host route, it maybe * to a local ip via the loopback interface. */ if (rt->iface == NULL && @@ -537,6 +512,7 @@ int if_route(unsigned char cmd, const struct rt *rt) { const struct dhcp_state *state; + const struct ipv4ll_state *istate; union sockunion { struct sockaddr sa; struct sockaddr_in sin; @@ -549,10 +525,6 @@ if_route(unsigned char cmd, const struct rt *rt) } rtm; char *bp = rtm.buffer; size_t l; - int s, retval; - - if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1) - return -1; #define ADDSU { \ l = RT_ROUNDUP(su.sa.sa_len); \ @@ -563,14 +535,18 @@ if_route(unsigned char cmd, const struct rt *rt) memset(&su, 0, sizeof(su)); \ su.sin.sin_family = AF_INET; \ su.sin.sin_len = sizeof(su.sin); \ - (&su.sin)->sin_addr = *addr; \ + (&su.sin)->sin_addr = *(addr); \ ADDSU; \ } - if (cmd != RTM_DELETE) + if (cmd != RTM_DELETE) { state = D_CSTATE(rt->iface); - else /* appease GCC */ + istate = IPV4LL_CSTATE(rt->iface); + } else { + /* appease GCC */ state = NULL; + istate = NULL; + } memset(&rtm, 0, sizeof(rtm)); rtm.hdr.rtm_version = RTM_VERSION; rtm.hdr.rtm_seq = 1; @@ -587,9 +563,14 @@ if_route(unsigned char cmd, const struct rt *rt) if (cmd != RTM_DELETE) { rtm.hdr.rtm_addrs |= RTA_IFA | RTA_IFP; /* None interface subnet routes are static. */ - if (rt->gate.s_addr != INADDR_ANY || + if ((rt->gate.s_addr != INADDR_ANY || rt->net.s_addr != state->net.s_addr || - rt->dest.s_addr != (state->addr.s_addr & state->net.s_addr)) + rt->dest.s_addr != + (state->addr.s_addr & state->net.s_addr)) && + (istate == NULL || + rt->dest.s_addr != + (istate->addr.s_addr & inaddr_llmask.s_addr) || + rt->net.s_addr != inaddr_llmask.s_addr)) rtm.hdr.rtm_flags |= RTF_STATIC; else { #ifdef RTF_CLONING @@ -660,16 +641,20 @@ if_route(unsigned char cmd, const struct rt *rt) } if (rtm.hdr.rtm_addrs & RTA_IFA) - ADDADDR(&state->addr); + ADDADDR(istate == NULL ? &state->addr : &istate->addr); + + if (rt->mtu) { + rtm.hdr.rtm_inits |= RTV_MTU; + rtm.hdr.rtm_rmx.rmx_mtu = rt->mtu; + } } #undef ADDADDR #undef ADDSU rtm.hdr.rtm_msglen = (unsigned short)(bp - (char *)&rtm); - retval = write(s, &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0; - close(s); - return retval; + return write(rt->iface->ctx->link_fd, + &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0; } int @@ -713,23 +698,17 @@ if_initrt(struct interface *ifp) int if_addrflags(const struct in_addr *addr, const struct interface *ifp) { - int s, flags; struct ifreq ifr; struct sockaddr_in *sin; - s = socket(PF_INET, SOCK_DGRAM, 0); - flags = -1; - if (s != -1) { - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); - sin = (struct sockaddr_in *)(void *)&ifr.ifr_addr; - sin->sin_family = AF_INET; - sin->sin_addr = *addr; - if (ioctl(s, SIOCGIFAFLAG_IN, &ifr) != -1) - flags = ifr.ifr_addrflags; - close(s); - } - return flags; + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); + sin = (struct sockaddr_in *)(void *)&ifr.ifr_addr; + sin->sin_family = AF_INET; + sin->sin_addr = *addr; + if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1) + return -1; + return ifr.ifr_addrflags; } #else int @@ -775,17 +754,13 @@ ifa_scope(struct sockaddr_in6 *sin, unsigned int ifindex) #endif int -if_address6(const struct ipv6_addr *a, int action) +if_address6(const struct ipv6_addr *ia, int action) { - int s, r; struct in6_aliasreq ifa; struct in6_addr mask; - if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) == -1) - return -1; - memset(&ifa, 0, sizeof(ifa)); - strlcpy(ifa.ifra_name, a->iface->name, sizeof(ifa.ifra_name)); + strlcpy(ifa.ifra_name, ia->iface->name, sizeof(ifa.ifra_name)); /* * We should not set IN6_IFF_TENTATIVE as the kernel should be * able to work out if it's a new address or not. @@ -795,31 +770,30 @@ if_address6(const struct ipv6_addr *a, int action) * either. */ #if 0 - if (a->autoconf) + if (ia->autoconf) ifa.ifra_flags |= IN6_IFF_AUTOCONF; #endif #ifdef IPV6_MANGETEMPADDR - if (a->flags & IPV6_AF_TEMPORARY) + if (ia->flags & IPV6_AF_TEMPORARY) ifa.ifra_flags |= IN6_IFF_TEMPORARY; #endif #define ADDADDR(v, addr) { \ (v)->sin6_family = AF_INET6; \ (v)->sin6_len = sizeof(*v); \ - (v)->sin6_addr = *addr; \ + (v)->sin6_addr = *(addr); \ } - ADDADDR(&ifa.ifra_addr, &a->addr); - ifa_scope(&ifa.ifra_addr, a->iface->index); - ipv6_mask(&mask, a->prefix_len); + ADDADDR(&ifa.ifra_addr, &ia->addr); + ifa_scope(&ifa.ifra_addr, ia->iface->index); + ipv6_mask(&mask, ia->prefix_len); ADDADDR(&ifa.ifra_prefixmask, &mask); - ifa.ifra_lifetime.ia6t_vltime = a->prefix_vltime; - ifa.ifra_lifetime.ia6t_pltime = a->prefix_pltime; + ifa.ifra_lifetime.ia6t_vltime = ia->prefix_vltime; + ifa.ifra_lifetime.ia6t_pltime = ia->prefix_pltime; #undef ADDADDR - r = ioctl(s, action < 0 ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa); - close(s); - return r; + return ioctl(ia->iface->ctx->pf_inet6_fd, + action < 0 ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa); } @@ -900,6 +874,9 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struct rt6 *rt, struct rt_msghdr *rtm) ipv6_mask(&rt->net, 128); COPYOUT6(rt->gate, rti_info[RTAX_GATEWAY]); + if (rtm->rtm_inits & RTV_MTU) + rt->mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu; + if (rtm->rtm_index) rt->iface = if_findindex(ctx->ifaces, rtm->rtm_index); else if (rtm->rtm_addrs & RTA_IFP) { @@ -937,10 +914,6 @@ if_route6(unsigned char cmd, const struct rt6 *rt) } rtm; char *bp = rtm.buffer; size_t l; - int s, retval; - - if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1) - return -1; #define ADDSU { \ l = RT_ROUNDUP(su.sa.sa_len); \ @@ -1025,9 +998,8 @@ if_route6(unsigned char cmd, const struct rt6 *rt) #undef ADDSU rtm.hdr.rtm_msglen = (unsigned short)(bp - (char *)&rtm); - retval = write(s, &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0; - close(s); - return retval; + return write(rt->iface->ctx->link_fd, + &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0; } int @@ -1070,67 +1042,56 @@ if_initrt6(struct interface *ifp) int if_addrflags6(const struct in6_addr *addr, const struct interface *ifp) { - int s, flags; + int flags; struct in6_ifreq ifr6; - s = socket(PF_INET6, SOCK_DGRAM, 0); - flags = -1; - if (s != -1) { - memset(&ifr6, 0, sizeof(ifr6)); - strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name)); - ifr6.ifr_addr.sin6_family = AF_INET6; - ifr6.ifr_addr.sin6_addr = *addr; - ifa_scope(&ifr6.ifr_addr, ifp->index); - if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) != -1) - flags = ifr6.ifr_ifru.ifru_flags6; - close(s); - } + memset(&ifr6, 0, sizeof(ifr6)); + strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name)); + ifr6.ifr_addr.sin6_family = AF_INET6; + ifr6.ifr_addr.sin6_addr = *addr; + ifa_scope(&ifr6.ifr_addr, ifp->index); + if (ioctl(ifp->ctx->pf_inet6_fd, SIOCGIFAFLAG_IN6, &ifr6) != -1) + flags = ifr6.ifr_ifru.ifru_flags6; + else + flags = -1; return flags; } int if_getlifetime6(struct ipv6_addr *ia) { - int s, r; + int r; struct in6_ifreq ifr6; + time_t t; + struct in6_addrlifetime *lifetime; - s = socket(PF_INET6, SOCK_DGRAM, 0); r = -1; - if (s != -1) { - memset(&ifr6, 0, sizeof(ifr6)); - strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name)); - ifr6.ifr_addr.sin6_family = AF_INET6; - ifr6.ifr_addr.sin6_addr = ia->addr; - ifa_scope(&ifr6.ifr_addr, ia->iface->index); - if (ioctl(s, SIOCGIFALIFETIME_IN6, &ifr6) != -1) { - time_t t; - struct in6_addrlifetime *lifetime; + memset(&ifr6, 0, sizeof(ifr6)); + strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name)); + ifr6.ifr_addr.sin6_family = AF_INET6; + ifr6.ifr_addr.sin6_addr = ia->addr; + ifa_scope(&ifr6.ifr_addr, ia->iface->index); + if (ioctl(ia->iface->ctx->pf_inet6_fd, + SIOCGIFALIFETIME_IN6, &ifr6) == -1) + return -1; - t = time(NULL); - lifetime = &ifr6.ifr_ifru.ifru_lifetime; + t = time(NULL); + lifetime = &ifr6.ifr_ifru.ifru_lifetime; - if (lifetime->ia6t_preferred) - ia->prefix_pltime = - (uint32_t)(lifetime->ia6t_preferred - - MIN(t, lifetime->ia6t_preferred)); - else - ia->prefix_pltime = ND6_INFINITE_LIFETIME; - if (lifetime->ia6t_expire) { - ia->prefix_vltime = - (uint32_t)(lifetime->ia6t_expire - - MIN(t, lifetime->ia6t_expire)); - /* Calculate the created time */ - clock_gettime(CLOCK_MONOTONIC, &ia->created); - ia->created.tv_sec -= - lifetime->ia6t_vltime - ia->prefix_vltime; - } else - ia->prefix_vltime = ND6_INFINITE_LIFETIME; - - r = 0; - } - close(s); - } - return r; + if (lifetime->ia6t_preferred) + ia->prefix_pltime = (uint32_t)(lifetime->ia6t_preferred - + MIN(t, lifetime->ia6t_preferred)); + else + ia->prefix_pltime = ND6_INFINITE_LIFETIME; + if (lifetime->ia6t_expire) { + ia->prefix_vltime = (uint32_t)(lifetime->ia6t_expire - + MIN(t, lifetime->ia6t_expire)); + /* Calculate the created time */ + clock_gettime(CLOCK_MONOTONIC, &ia->created); + ia->created.tv_sec -= lifetime->ia6t_vltime - ia->prefix_vltime; + } else + ia->prefix_vltime = ND6_INFINITE_LIFETIME; + return 0; } #endif @@ -1670,12 +1631,7 @@ _if_checkipv6(int s, struct dhcpcd_ctx *ctx, int if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own) { - int s, r; - if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) == -1) - return -1; - r = _if_checkipv6(s, ctx, ifp, own); - close(s); - return r; + return _if_checkipv6(ctx->pf_inet6_fd, ctx, ifp, own); } #endif diff --git a/external/bsd/dhcpcd/dist/if-options.c b/external/bsd/dhcpcd/dist/if-options.c index 67f4a055cfad..393b04d84d59 100644 --- a/external/bsd/dhcpcd/dist/if-options.c +++ b/external/bsd/dhcpcd/dist/if-options.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: if-options.c,v 1.25 2015/07/09 10:15:34 roy Exp $"); + __RCSID("$NetBSD: if-options.c,v 1.26 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -97,7 +97,7 @@ #define O_CONTROLGRP O_BASE + 34 #define O_SLAAC O_BASE + 35 #define O_GATEWAY O_BASE + 36 -// unassigned O_BASE + 37 +#define O_NOUP O_BASE + 37 #define O_IPV6RA_AUTOCONF O_BASE + 38 #define O_IPV6RA_NOAUTOCONF O_BASE + 39 #define O_REJECT O_BASE + 40 @@ -199,6 +199,7 @@ const struct option cf_options[] = { {"reject", required_argument, NULL, O_REJECT}, {"bootp", no_argument, NULL, O_BOOTP}, {"nodelay", no_argument, NULL, O_NODELAY}, + {"noup", no_argument, NULL, O_NOUP}, {NULL, 0, NULL, '\0'} }; @@ -2006,6 +2007,9 @@ err_sla: case O_GATEWAY: ifo->options |= DHCPCD_GATEWAY; break; + case O_NOUP: + ifo->options &= ~DHCPCD_IF_UP; + break; case O_SLAAC: if (strcmp(arg, "private") == 0 || strcmp(arg, "stableprivate") == 0 || @@ -2120,6 +2124,7 @@ read_config(struct dhcpcd_ctx *ctx, return NULL; } ifo->options |= DHCPCD_DAEMONISE | DHCPCD_LINK | DHCPCD_INITIAL_DELAY; + ifo->options |= DHCPCD_IF_UP; #ifdef PLUGIN_DEV ifo->options |= DHCPCD_DEV; #endif diff --git a/external/bsd/dhcpcd/dist/if-options.h b/external/bsd/dhcpcd/dist/if-options.h index 946b741aaf3c..482b60d24f26 100644 --- a/external/bsd/dhcpcd/dist/if-options.h +++ b/external/bsd/dhcpcd/dist/if-options.h @@ -1,4 +1,4 @@ -/* $NetBSD: if-options.h,v 1.12 2015/07/09 10:15:34 roy Exp $ */ +/* $NetBSD: if-options.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -106,7 +106,7 @@ #define DHCPCD_IAID (1ULL << 48) #define DHCPCD_DHCP (1ULL << 49) #define DHCPCD_DHCP6 (1ULL << 50) -// unassigned (1ULL << 51) +#define DHCPCD_IF_UP (1ULL << 51) // unassigned (1ULL << 52) // unassinged (1ULL << 53) #define DHCPCD_IPV6RA_AUTOCONF (1ULL << 54) diff --git a/external/bsd/dhcpcd/dist/if.c b/external/bsd/dhcpcd/dist/if.c index 71e2744389ab..7be94a12d28b 100644 --- a/external/bsd/dhcpcd/dist/if.c +++ b/external/bsd/dhcpcd/dist/if.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: if.c,v 1.14 2015/07/09 10:15:34 roy Exp $"); + __RCSID("$NetBSD: if.c,v 1.15 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -61,6 +61,7 @@ #include #include #include +#include #include "config.h" #include "common.h" @@ -73,11 +74,6 @@ #include "ipv4ll.h" #include "ipv6nd.h" -#ifdef __QNX__ -/* QNX carries defines for, but does not actually support PF_LINK */ -#undef IFLR_ACTIVE -#endif - void if_free(struct interface *ifp) { @@ -95,28 +91,50 @@ if_free(struct interface *ifp) } int -if_carrier(struct interface *iface) +if_opensockets(struct dhcpcd_ctx *ctx) { - int s, r; + + if ((ctx->link_fd = if_openlinksocket()) == -1) + return -1; + + ctx->pf_inet_fd = xsocket(PF_INET, SOCK_DGRAM, 0, O_CLOEXEC); + if (ctx->pf_inet_fd == -1) + return -1; + +#if defined(INET6) && defined(BSD) + ctx->pf_inet6_fd = xsocket(PF_INET6, SOCK_DGRAM, 0, O_CLOEXEC); + if (ctx->pf_inet6_fd == -1) + return -1; +#endif + +#ifdef IFLR_ACTIVE + ctx->pf_link_fd = xsocket(PF_LINK, SOCK_DGRAM, 0, O_CLOEXEC); + if (ctx->pf_link_fd == -1) + return -1; +#endif + + return 0; +} + +int +if_carrier(struct interface *ifp) +{ + int r; struct ifreq ifr; #ifdef SIOCGIFMEDIA struct ifmediareq ifmr; #endif - if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) - return LINK_UNKNOWN; memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) { - close(s); + strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); + if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == -1) return LINK_UNKNOWN; - } - iface->flags = (unsigned int)ifr.ifr_flags; + ifp->flags = (unsigned int)ifr.ifr_flags; #ifdef SIOCGIFMEDIA memset(&ifmr, 0, sizeof(ifmr)); - strlcpy(ifmr.ifm_name, iface->name, sizeof(ifmr.ifm_name)); - if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1 && + strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name)); + if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) != -1 && ifmr.ifm_status & IFM_AVALID) r = (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN; else @@ -124,7 +142,6 @@ if_carrier(struct interface *iface) #else r = ifr.ifr_flags & IFF_RUNNING ? LINK_UP : LINK_DOWN; #endif - close(s); return r; } @@ -132,24 +149,21 @@ int if_setflag(struct interface *ifp, short flag) { struct ifreq ifr; - int s, r; + int r; - if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) - return -1; memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); r = -1; - if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) { + if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == 0) { if (flag == 0 || (ifr.ifr_flags & flag) == flag) r = 0; else { ifr.ifr_flags |= flag; - if (ioctl(s, SIOCSIFFLAGS, &ifr) == 0) + if (ioctl(ifp->ctx->pf_inet_fd, SIOCSIFFLAGS, &ifr) ==0) r = 0; } ifp->flags = (unsigned int)ifr.ifr_flags; } - close(s); return r; } @@ -241,24 +255,12 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) const struct sockaddr_dl *sdl; #ifdef SIOCGIFPRIORITY struct ifreq ifr; - int s_inet; #endif #ifdef IFLR_ACTIVE struct if_laddrreq iflr; - int s_link; #endif -#ifdef SIOCGIFPRIORITY - if ((s_inet = socket(PF_INET, SOCK_DGRAM, 0)) == -1) - return NULL; -#endif #ifdef IFLR_ACTIVE - if ((s_link = socket(PF_LINK, SOCK_DGRAM, 0)) == -1) { -#ifdef SIOCGIFPRIORITY - close(s_inet); -#endif - return NULL; - } memset(&iflr, 0, sizeof(iflr)); #endif #elif AF_PACKET @@ -343,7 +345,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) continue; } - if (if_vimaster(p) == 1) { + if (if_vimaster(ctx, p) == 1) { logger(ctx, argc ? LOG_ERR : LOG_DEBUG, "%s: is a Virtual Interface Master, skipping", p); continue; @@ -376,7 +378,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) MIN(ifa->ifa_addr->sa_len, sizeof(iflr.addr))); iflr.flags = IFLR_PREFIX; iflr.prefixlen = (unsigned int)sdl->sdl_alen * NBBY; - if (ioctl(s_link, SIOCGLIFADDR, &iflr) == -1 || + if (ioctl(ctx->pf_link_fd, SIOCGLIFADDR, &iflr) == -1 || !(iflr.flags & IFLR_ACTIVE)) { if_free(ifp); @@ -497,27 +499,30 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) } } - /* Handle any platform init for the interface */ - if (if_init(ifp) == -1) { - logger(ifp->ctx, LOG_ERR, "%s: if_init: %m", p); - if_free(ifp); - continue; - } + if (!(ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))) { + /* Handle any platform init for the interface */ + if (if_init(ifp) == -1) { + logger(ifp->ctx, LOG_ERR, "%s: if_init: %m", p); + if_free(ifp); + continue; + } - /* Ensure that the MTU is big enough for DHCP */ - if (if_getmtu(ifp->name) < MTU_MIN && - if_setmtu(ifp->name, MTU_MIN) == -1) - { - logger(ifp->ctx, LOG_ERR, "%s: set_mtu: %m", p); - if_free(ifp); - continue; + /* Ensure that the MTU is big enough for DHCP */ + if (if_getmtu(ifp) < MTU_MIN && + if_setmtu(ifp, MTU_MIN) == -1) + { + logger(ifp->ctx, LOG_ERR, + "%s: if_setmtu: %m", p); + if_free(ifp); + continue; + } } #ifdef SIOCGIFPRIORITY /* Respect the interface priority */ memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); - if (ioctl(s_inet, SIOCGIFPRIORITY, &ifr) == 0) + if (ioctl(ctx->pf_inet_fd, SIOCGIFPRIORITY, &ifr) == 0) ifp->metric = ifr.ifr_metric; #else /* We reserve the 100 range for virtual interfaces, if and when @@ -535,13 +540,6 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) if_learnaddrs1(ctx, ifs, ifaddrs); freeifaddrs(ifaddrs); -#ifdef SIOCGIFPRIORITY - close(s_inet); -#endif -#ifdef IFLR_ACTIVE - close(s_link); -#endif - return ifs; } @@ -581,18 +579,15 @@ if_findindex(struct if_head *ifaces, unsigned int idx) } int -if_domtu(const char *ifname, short int mtu) +if_domtu(const struct interface *ifp, short int mtu) { - int s, r; + int r; struct ifreq ifr; - if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) - return -1; memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); ifr.ifr_mtu = mtu; - r = ioctl(s, mtu ? SIOCSIFMTU : SIOCGIFMTU, &ifr); - close(s); + r = ioctl(ifp->ctx->pf_inet_fd, mtu ? SIOCSIFMTU : SIOCGIFMTU, &ifr); if (r == -1) return -1; return ifr.ifr_mtu; @@ -667,3 +662,31 @@ if_sortinterfaces(struct dhcpcd_ctx *ctx) } TAILQ_CONCAT(ctx->ifaces, &sorted, next); } + +int +xsocket(int domain, int type, int protocol, int flags) +{ +#ifdef SOCK_CLOEXEC + if (flags & O_CLOEXEC) + type |= SOCK_CLOEXEC; + if (flags & O_NONBLOCK) + type |= SOCK_NONBLOCK; + + return socket(domain, type, protocol); +#else + int s, xflags; + + if ((s = socket(domain, type, protocol)) == -1) + return -1; + if ((flags & O_CLOEXEC) && (xflags = fcntl(s, F_GETFD, 0)) == -1 || + fcntl(s, F_SETFD, xlags | FD_CLOEXEC) == -1) + goto out; + if ((flags & O_NONBLOCK) && (xflags = fcntl(s, F_GETFL, 0)) == -1 || + fcntl(s, F_SETFL, xflags | O_NONBLOCK) == -1) + goto out; + return s; +out: + close(s); + return -1; +#endif +} diff --git a/external/bsd/dhcpcd/dist/if.h b/external/bsd/dhcpcd/dist/if.h index c312d30f9ac0..bbec012026a6 100644 --- a/external/bsd/dhcpcd/dist/if.h +++ b/external/bsd/dhcpcd/dist/if.h @@ -1,4 +1,4 @@ -/* $NetBSD: if.h,v 1.11 2015/07/09 10:15:34 roy Exp $ */ +/* $NetBSD: if.h,v 1.12 2015/08/21 10:39:00 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -95,16 +95,17 @@ struct interface *if_find(struct if_head *, const char *); struct interface *if_findindex(struct if_head *, unsigned int); void if_sortinterfaces(struct dhcpcd_ctx *); void if_free(struct interface *); -int if_domtu(const char *, short int); -#define if_getmtu(iface) if_domtu(iface, 0) -#define if_setmtu(iface, mtu) if_domtu(iface, mtu) +int if_domtu(const struct interface *, short int); +#define if_getmtu(ifp) if_domtu((ifp), 0) +#define if_setmtu(ifp, mtu) if_domtu((ifp), (mtu)) int if_carrier(struct interface *); /* The below functions are provided by if-KERNEL.c */ int if_conf(struct interface *); int if_init(struct interface *); int if_getssid(struct interface *); -int if_vimaster(const char *); +int if_vimaster(const struct dhcpcd_ctx *ctx, const char *); +int if_opensockets(struct dhcpcd_ctx *); int if_openlinksocket(void); int if_managelink(struct dhcpcd_ctx *); @@ -163,4 +164,5 @@ int if_initrt6(struct interface *); #endif int if_machinearch(char *, size_t); +int xsocket(int, int, int, int); #endif diff --git a/external/bsd/dhcpcd/dist/ipv4.c b/external/bsd/dhcpcd/dist/ipv4.c index c2842cec20e0..83cb2e0c17d4 100644 --- a/external/bsd/dhcpcd/dist/ipv4.c +++ b/external/bsd/dhcpcd/dist/ipv4.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: ipv4.c,v 1.16 2015/07/09 10:15:34 roy Exp $"); + __RCSID("$NetBSD: ipv4.c,v 1.17 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -296,6 +296,11 @@ desc_route(const char *cmd, const struct rt *rt) else if (rt->net.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->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)); @@ -383,6 +388,7 @@ ipv4_handlert(struct dhcpcd_ctx *ctx, int cmd, struct rt *rt) static int nc_route(struct rt *ort, struct rt *nrt) { + int change; /* Don't set default routes if not asked to */ if (nrt->dest.s_addr == 0 && @@ -392,6 +398,7 @@ nc_route(struct rt *ort, struct rt *nrt) desc_route(ort == NULL ? "adding" : "changing", nrt); + change = 0; if (ort == NULL) { ort = ipv4_findrt(nrt->iface->ctx, nrt, 0); if (ort && @@ -401,8 +408,12 @@ nc_route(struct rt *ort, struct rt *nrt) ort->metric == nrt->metric && #endif ort->gate.s_addr == nrt->gate.s_addr))) - return 0; - } else if (ort->flags & STATE_FAKE && !(nrt->flags & STATE_FAKE) && + { + if (ort->mtu == nrt->mtu) + return 0; + change = 1; + } + } else if (ort->state & STATE_FAKE && !(nrt->state & STATE_FAKE) && ort->iface == nrt->iface && #ifdef HAVE_ROUTE_METRIC ort->metric == nrt->metric && @@ -410,12 +421,32 @@ nc_route(struct rt *ort, struct rt *nrt) ort->dest.s_addr == nrt->dest.s_addr && ort->net.s_addr == nrt->net.s_addr && ort->gate.s_addr == nrt->gate.s_addr) - return 0; + { + if (ort->mtu == nrt->mtu) + return 0; + change = 1; + } + +#ifdef RTF_CLONING + /* BSD can set routes to be cloning routes. + * Cloned routes inherit the parent flags. + * As such, we need to delete and re-add the route to flush children + * to correct the flags. */ + if (change && ort != NULL && ort->flags & RTF_CLONING) + change = 0; +#endif + + if (change) { + if (if_route(RTM_CHANGE, nrt) == 0) + return 0; + if (errno != ESRCH) + logger(nrt->iface->ctx, LOG_ERR, "if_route (CHG): %m"); + } #ifdef HAVE_ROUTE_METRIC /* With route metrics, we can safely add the new route before * deleting the old route. */ - if (if_route(RTM_ADD, nrt) == 0) { + if (if_route(RTM_ADD, nrt) == 0) { if (ort && if_route(RTM_DELETE, ort) == -1 && errno != ESRCH) logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m"); return 0; @@ -472,7 +503,7 @@ add_subnet_route(struct rt_head *rt, const struct interface *ifp) return rt; #endif - if ((r = malloc(sizeof(*r))) == NULL) { + if ((r = calloc(1, sizeof(*r))) == NULL) { logger(ifp->ctx, LOG_ERR, "%s: %m", __func__); ipv4_freeroutes(rt); return NULL; @@ -480,6 +511,7 @@ add_subnet_route(struct rt_head *rt, const struct interface *ifp) r->dest.s_addr = s->addr.s_addr & s->net.s_addr; r->net.s_addr = s->net.s_addr; r->gate.s_addr = INADDR_ANY; + r->mtu = dhcp_get_mtu(ifp); r->src = s->addr; TAILQ_INSERT_HEAD(rt, r, next); @@ -500,8 +532,7 @@ add_loopback_route(struct rt_head *rt, const struct interface *ifp) if (s->addr.s_addr == INADDR_ANY) return rt; - r = malloc(sizeof(*r)); - if (r == NULL) { + if ((r = calloc(1, sizeof(*r))) == NULL) { logger(ifp->ctx, LOG_ERR, "%s: %m", __func__); ipv4_freeroutes(rt); return NULL; @@ -509,6 +540,7 @@ add_loopback_route(struct rt_head *rt, const struct interface *ifp) r->dest = s->addr; r->net.s_addr = INADDR_BROADCAST; r->gate.s_addr = htonl(INADDR_LOOPBACK); + r->mtu = dhcp_get_mtu(ifp); r->src = s->addr; TAILQ_INSERT_HEAD(rt, r, next); return rt; @@ -529,8 +561,7 @@ get_routes(struct interface *ifp) TAILQ_FOREACH(rt, ifp->options->routes, next) { if (rt->gate.s_addr == 0) break; - r = malloc(sizeof(*r)); - if (r == NULL) { + if ((r = calloc(1, sizeof(*r))) == NULL) { logger(ifp->ctx, LOG_ERR, "%s: %m", __func__); ipv4_freeroutes(nrt); return NULL; @@ -539,7 +570,7 @@ get_routes(struct interface *ifp) TAILQ_INSERT_TAIL(nrt, r, next); } } else - nrt = get_option_routes(ifp, D_STATE(ifp)->new); + nrt = dhcp_get_routes(ifp); /* Copy our address as the source address */ if (nrt) { @@ -564,8 +595,7 @@ add_destination_route(struct rt_head *rt, const struct interface *ifp) (state = D_CSTATE(ifp)) == NULL) return rt; - r = malloc(sizeof(*r)); - if (r == NULL) { + if ((r = calloc(1, sizeof(*r))) == NULL) { logger(ifp->ctx, LOG_ERR, "%s: %m", __func__); ipv4_freeroutes(rt); return NULL; @@ -573,6 +603,8 @@ add_destination_route(struct rt_head *rt, const struct interface *ifp) r->dest.s_addr = INADDR_ANY; r->net.s_addr = INADDR_ANY; r->gate.s_addr = state->dst.s_addr; + r->mtu = dhcp_get_mtu(ifp); + r->src = state->addr; TAILQ_INSERT_HEAD(rt, r, next); return rt; } @@ -637,8 +669,7 @@ add_router_host_route(struct rt_head *rt, const struct interface *ifp) "%s: router %s requires a host route", ifp->name, inet_ntoa(rtp->gate)); } - rtn = malloc(sizeof(*rtn)); - if (rtn == NULL) { + if ((rtn = calloc(1, sizeof(*rtn))) == NULL) { logger(ifp->ctx, LOG_ERR, "%s: %m", __func__); ipv4_freeroutes(rt); return NULL; @@ -646,18 +677,72 @@ add_router_host_route(struct rt_head *rt, const struct interface *ifp) rtn->dest.s_addr = rtp->gate.s_addr; rtn->net.s_addr = htonl(INADDR_BROADCAST); rtn->gate.s_addr = htonl(INADDR_ANY); + rtn->mtu = dhcp_get_mtu(ifp); + rtn->src = state->addr; TAILQ_INSERT_BEFORE(rtp, rtn, next); } return rt; } +static int +ipv4_doroute(struct rt *rt, struct rt_head *nrs) +{ + const struct dhcp_state *state; + struct rt *or; + + state = D_CSTATE(rt->iface); + rt->state = state->added & STATE_FAKE; +#ifdef HAVE_ROUTE_METRIC + rt->metric = rt->iface->metric; +#endif + /* Is this route already in our table? */ + if ((find_route(nrs, rt, NULL)) != NULL) + return 0; + /* Do we already manage it? */ + if ((or = find_route(rt->iface->ctx->ipv4_routes, rt, NULL))) { + if (state->added & STATE_FAKE) + return 0; + if (or->state & STATE_FAKE || + or->iface != rt->iface || +#ifdef HAVE_ROUTE_METRIC + rt->metric != or->metric || +#endif + rt->src.s_addr != or->src.s_addr || + rt->gate.s_addr != or->gate.s_addr || + rt->mtu != or->mtu) + { + if (c_route(or, rt) != 0) + return 0; + } + TAILQ_REMOVE(rt->iface->ctx->ipv4_routes, or, next); + free(or); + } else { + if (state->added & STATE_FAKE) { + if ((or = ipv4_findrt(rt->iface->ctx, rt, 1)) == NULL) + return 0; + rt->iface = or->iface; + rt->gate.s_addr = or->gate.s_addr; +#ifdef HAVE_ROUTE_METRIC + rt->metric = or->metric; +#endif + rt->mtu = or->mtu; + rt->flags = or->flags; + } else { + if (n_route(rt) != 0) + return 0; + } + } + return 1; +} + void ipv4_buildroutes(struct dhcpcd_ctx *ctx) { struct rt_head *nrs, *dnr; - struct rt *or, *rt, *rtn; + struct rt *rt, *rtn; struct interface *ifp; const struct dhcp_state *state; + int has_default; /* We need to have the interfaces in the correct order to ensure * our routes are managed correctly. */ @@ -669,6 +754,7 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx) } TAILQ_INIT(nrs); + has_default = 0; TAILQ_FOREACH(ifp, ctx->ifaces, next) { state = D_CSTATE(ifp); if (state != NULL && state->new != NULL && state->added) { @@ -700,48 +786,29 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx) continue; TAILQ_FOREACH_SAFE(rt, dnr, next, rtn) { rt->iface = ifp; -#ifdef HAVE_ROUTE_METRIC - rt->metric = ifp->metric; -#endif - rt->flags = state->added & STATE_FAKE; - /* Is this route already in our table? */ - if ((find_route(nrs, rt, NULL)) != NULL) - continue; - /* Do we already manage it? */ - if ((or = find_route(ctx->ipv4_routes, rt, NULL))) { - if (state->added & STATE_FAKE) - continue; - if (or->flags & STATE_FAKE || - or->iface != ifp || -#ifdef HAVE_ROUTE_METRIC - rt->metric != or->metric || -#endif - rt->src.s_addr != or->src.s_addr || - rt->gate.s_addr != or->gate.s_addr) - { - if (c_route(or, rt) != 0) - continue; - } - TAILQ_REMOVE(ctx->ipv4_routes, or, next); - free(or); - } else { - if (state->added & STATE_FAKE) { - or = ipv4_findrt(ctx, rt, 1); - if (or == NULL || - or->gate.s_addr != rt->gate.s_addr) - continue; - } else { - if (n_route(rt) != 0) - continue; - } + if (ipv4_doroute(rt, nrs) == 1) { + TAILQ_REMOVE(dnr, rt, next); + TAILQ_INSERT_TAIL(nrs, rt, next); + if (rt->dest.s_addr == INADDR_ANY) + has_default = 1; } - rt->flags |= STATE_ADDED; - TAILQ_REMOVE(dnr, rt, next); - TAILQ_INSERT_TAIL(nrs, rt, next); } ipv4_freeroutes(dnr); } + /* If we don't manage a default route, grab one without a + * gateway for any IPv4LL enabled interfaces. */ + if (!has_default) { + TAILQ_FOREACH(ifp, ctx->ifaces, next) { + if ((rt = ipv4ll_default_route(ifp)) != NULL) { + if (ipv4_doroute(rt, nrs) == 1) + TAILQ_INSERT_TAIL(nrs, rt, next); + else + free(rt); + } + } + } + /* Remove old routes we used to manage */ if (ctx->ipv4_routes) { TAILQ_FOREACH(rt, ctx->ipv4_routes, next) { diff --git a/external/bsd/dhcpcd/dist/ipv4.h b/external/bsd/dhcpcd/dist/ipv4.h index 47680c542f87..8373f0cbfaa2 100644 --- a/external/bsd/dhcpcd/dist/ipv4.h +++ b/external/bsd/dhcpcd/dist/ipv4.h @@ -1,4 +1,4 @@ -/* $NetBSD: ipv4.h,v 1.12 2015/07/09 10:15:34 roy Exp $ */ +/* $NetBSD: ipv4.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -63,8 +63,10 @@ struct rt { #ifdef HAVE_ROUTE_METRIC unsigned int metric; #endif + unsigned int mtu; struct in_addr src; unsigned int flags; + unsigned int state; }; TAILQ_HEAD(rt_head, rt); diff --git a/external/bsd/dhcpcd/dist/ipv4ll.c b/external/bsd/dhcpcd/dist/ipv4ll.c index 0d0a08d66376..caa6c9c32284 100644 --- a/external/bsd/dhcpcd/dist/ipv4ll.c +++ b/external/bsd/dhcpcd/dist/ipv4ll.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: ipv4ll.c,v 1.11 2015/07/09 10:15:34 roy Exp $"); + __RCSID("$NetBSD: ipv4ll.c,v 1.12 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -48,13 +48,17 @@ #include "ipv4ll.h" #include "script.h" -static const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) }; -static const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BRDC) }; +const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) }; +const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BRDC) }; static in_addr_t ipv4ll_pick_addr(const struct arp_state *astate) { struct in_addr addr; + struct ipv4ll_state *istate; + + istate = IPV4LL_STATE(astate->iface); + setstate(istate->randomstate); do { /* RFC 3927 Section 2.1 states that the first 256 and @@ -69,6 +73,9 @@ ipv4ll_pick_addr(const struct arp_state *astate) /* Ensure we don't have the address on another interface */ } while (ipv4_findaddr(astate->iface->ctx, &addr) != NULL); + /* Restore the original random state */ + setstate(astate->iface->ctx->randomstate); + return addr.s_addr; } @@ -83,7 +90,7 @@ ipv4ll_subnet_route(const struct interface *ifp) state->addr.s_addr == INADDR_ANY) return NULL; - if ((rt = malloc(sizeof(*rt))) == NULL) { + if ((rt = calloc(1, sizeof(*rt))) == NULL) { logger(ifp->ctx, LOG_ERR, "%s: malloc: %m", __func__); return NULL; } @@ -95,6 +102,29 @@ ipv4ll_subnet_route(const struct interface *ifp) return rt; } +struct rt * +ipv4ll_default_route(const struct interface *ifp) +{ + const struct ipv4ll_state *state; + struct rt *rt; + + assert(ifp != NULL); + if ((state = IPV4LL_CSTATE(ifp)) == NULL || + state->addr.s_addr == INADDR_ANY) + return NULL; + + if ((rt = calloc(1, sizeof(*rt))) == NULL) { + logger(ifp->ctx, LOG_ERR, "%s: malloc: %m", __func__); + return NULL; + } + rt->iface = ifp; + rt->dest.s_addr = INADDR_ANY; + rt->net.s_addr = INADDR_ANY; + rt->gate.s_addr = INADDR_ANY; + rt->src = state->addr; + return rt; +} + ssize_t ipv4ll_env(char **env, const char *prefix, const struct interface *ifp) { @@ -162,6 +192,7 @@ ipv4ll_probed(struct arp_state *astate) #endif state->addr = astate->addr; timespecclear(&state->defend); + if_initrt(ifp); ipv4_buildroutes(ifp->ctx); arp_announce(astate); script_runreason(ifp, "IPV4LL"); @@ -295,6 +326,7 @@ ipv4ll_start(void *arg) * the same address without persistent storage. */ if (state->conflicts == 0) { unsigned int seed; + char *orig; if (sizeof(seed) > ifp->hwlen) { seed = 0; @@ -302,7 +334,15 @@ ipv4ll_start(void *arg) } else memcpy(&seed, ifp->hwaddr + ifp->hwlen - sizeof(seed), sizeof(seed)); - initstate(seed, state->randomstate, sizeof(state->randomstate)); + orig = initstate(seed, + state->randomstate, sizeof(state->randomstate)); + + /* Save the original state. */ + if (ifp->ctx->randomstate == NULL) + ifp->ctx->randomstate = orig; + + /* Set back the original state until we need the seeded one. */ + setstate(ifp->ctx->randomstate); } if ((astate = arp_new(ifp, NULL)) == NULL) @@ -338,7 +378,6 @@ ipv4ll_start(void *arg) return; } - setstate(state->randomstate); logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address", ifp->name); astate->addr.s_addr = ipv4ll_pick_addr(astate); @@ -353,9 +392,11 @@ void ipv4ll_freedrop(struct interface *ifp, int drop) { struct ipv4ll_state *state; + int dropped; assert(ifp != NULL); state = IPV4LL_STATE(ifp); + dropped = 0; /* Free ARP state first because ipv4_deladdr might also ... */ if (state && state->arp) { @@ -370,6 +411,7 @@ ipv4ll_freedrop(struct interface *ifp, int drop) if (state && state->addr.s_addr != INADDR_ANY) { ipv4_deladdr(ifp, &state->addr, &inaddr_llmask, 1); state->addr.s_addr = INADDR_ANY; + dropped = 1; } /* Free any other link local addresses that might exist. */ @@ -377,18 +419,22 @@ ipv4ll_freedrop(struct interface *ifp, int drop) struct ipv4_addr *ia, *ian; TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) { - if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) + if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) { ipv4_deladdr(ifp, &ia->addr, &ia->net, 0); + dropped = 1; + } } } - script_runreason(ifp, "IPV4LL"); } if (state) { free(state); ifp->if_data[IF_DATA_IPV4LL] = NULL; - ipv4_buildroutes(ifp->ctx); + if (dropped) { + ipv4_buildroutes(ifp->ctx); + script_runreason(ifp, "IPV4LL"); + } } } diff --git a/external/bsd/dhcpcd/dist/ipv4ll.h b/external/bsd/dhcpcd/dist/ipv4ll.h index 4212d5b10153..c038222e7d77 100644 --- a/external/bsd/dhcpcd/dist/ipv4ll.h +++ b/external/bsd/dhcpcd/dist/ipv4ll.h @@ -1,4 +1,4 @@ -/* $NetBSD: ipv4ll.h,v 1.9 2015/07/09 10:15:34 roy Exp $ */ +/* $NetBSD: ipv4ll.h,v 1.10 2015/08/21 10:39:00 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -32,6 +32,9 @@ #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) @@ -58,6 +61,7 @@ struct ipv4ll_state { IN_LINKLOCAL(ntohl(IPV4LL_CSTATE((ifp))->addr.s_addr))) struct rt* ipv4ll_subnet_route(const struct interface *); +struct rt* ipv4ll_default_route(const struct interface *); ssize_t ipv4ll_env(char **, const char *, const struct interface *); void ipv4ll_start(void *); void ipv4ll_claimed(void *); diff --git a/external/bsd/dhcpcd/dist/ipv6.c b/external/bsd/dhcpcd/dist/ipv6.c index a8d497dc8497..434bf546838e 100644 --- a/external/bsd/dhcpcd/dist/ipv6.c +++ b/external/bsd/dhcpcd/dist/ipv6.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: ipv6.c,v 1.13 2015/07/09 10:15:34 roy Exp $"); + __RCSID("$NetBSD: ipv6.c,v 1.14 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -647,7 +647,13 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timespec *now) ap->flags |= IPV6_AF_DADCOMPLETED; logger(ap->iface->ctx, ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG, - "%s: adding address %s", ap->iface->name, ap->saddr); + "%s: adding %saddress %s", ap->iface->name, +#ifdef IPV6_AF_TEMPORARY + ap->flags & IPV6_AF_TEMPORARY ? "temporary " : "", +#else + "", +#endif + ap->saddr); if (ap->prefix_pltime == ND6_INFINITE_LIFETIME && ap->prefix_vltime == ND6_INFINITE_LIFETIME) logger(ap->iface->ctx, LOG_DEBUG, @@ -881,17 +887,22 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop, { if (drop == 2) TAILQ_REMOVE(addrs, ap, next); - /* Find the same address somewhere else */ - apf = ipv6_findaddr(ap->iface->ctx, &ap->addr, 0); - if (apf == NULL || - (apf->iface != ap->iface)) - ipv6_deleteaddr(ap); - if (!(ap->iface->options->options & - DHCPCD_EXITING) && apf) - { - if (!timespecisset(&now)) - clock_gettime(CLOCK_MONOTONIC, &now); - ipv6_addaddr(apf, &now); + /* Don't drop link-local addresses. */ + if (!IN6_IS_ADDR_LINKLOCAL(&ap->addr)) { + /* Find the same address somewhere else */ + apf = ipv6_findaddr(ap->iface->ctx, &ap->addr, + 0); + if ((apf == NULL || + (apf->iface != ap->iface))) + ipv6_deleteaddr(ap); + if (!(ap->iface->options->options & + DHCPCD_EXITING) && apf) + { + if (!timespecisset(&now)) + clock_gettime(CLOCK_MONOTONIC, + &now); + ipv6_addaddr(apf, &now); + } } if (drop == 2) ipv6_freeaddr(ap); @@ -1850,6 +1861,7 @@ ipv6_handlert(struct dhcpcd_ctx *ctx, int cmd, struct rt6 *rt) static int nc_route(struct rt6 *ort, struct rt6 *nrt) { + int change; /* Don't set default routes if not asked to */ if (IN6_IS_ADDR_UNSPECIFIED(&nrt->dest) && @@ -1859,6 +1871,7 @@ nc_route(struct rt6 *ort, struct rt6 *nrt) desc_route(ort == NULL ? "adding" : "changing", nrt); + change = 0; if (ort == NULL) { ort = ipv6_findrt(nrt->iface->ctx, nrt, 0); if (ort && @@ -1868,7 +1881,27 @@ nc_route(struct rt6 *ort, struct rt6 *nrt) ort->metric == nrt->metric && #endif IN6_ARE_ADDR_EQUAL(&ort->gate, &nrt->gate)))) + { + if (ort->mtu == nrt->mtu) + return 0; + change = 1; + } + } + +#ifdef RTF_CLONING + /* BSD can set routes to be cloning routes. + * Cloned routes inherit the parent flags. + * As such, we need to delete and re-add the route to flush children + * to correct the flags. */ + if (change && ort != NULL && ort->flags & RTF_CLONING) + change = 0; +#endif + + if (change) { + if (if_route6(RTM_CHANGE, nrt) == 0) return 0; + if (errno != ESRCH) + logger(nrt->iface->ctx, LOG_ERR, "if_route6 (CHG): %m"); } #ifdef HAVE_ROUTE_METRIC diff --git a/external/bsd/dhcpcd/dist/ipv6nd.c b/external/bsd/dhcpcd/dist/ipv6nd.c index 5d787ebf07bc..6dac8d6f55e0 100644 --- a/external/bsd/dhcpcd/dist/ipv6nd.c +++ b/external/bsd/dhcpcd/dist/ipv6nd.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: ipv6nd.c,v 1.25 2015/07/09 10:15:34 roy Exp $"); + __RCSID("$NetBSD: ipv6nd.c,v 1.26 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -192,29 +192,10 @@ ipv6nd_open(struct dhcpcd_ctx *dctx) ctx = dctx->ipv6; if (ctx->nd_fd != -1) return ctx->nd_fd; -#ifdef SOCK_CLOEXEC - ctx->nd_fd = socket(PF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, - IPPROTO_ICMPV6); + ctx->nd_fd = xsocket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, + O_NONBLOCK|O_CLOEXEC); if (ctx->nd_fd == -1) return -1; -#else - if ((ctx->nd_fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1) - return -1; - if ((on = fcntl(ctx->nd_fd, F_GETFD, 0)) == -1 || - fcntl(ctx->nd_fd, F_SETFD, on | FD_CLOEXEC) == -1) - { - close(ctx->nd_fd); - ctx->nd_fd = -1; - return -1; - } - if ((on = fcntl(ctx->nd_fd, F_GETFL, 0)) == -1 || - fcntl(ctx->nd_fd, F_SETFL, on | O_NONBLOCK) == -1) - { - close(ctx->nd_fd); - ctx->nd_fd = -1; - return -1; - } -#endif /* RFC4861 4.1 */ on = 255; @@ -735,14 +716,19 @@ try_script: } static int -ipv6nd_ra_has_public_addr(const struct ra *rap) +ipv6nd_has_public_addr(const struct interface *ifp) { + const struct ra *rap; const struct ipv6_addr *ia; - TAILQ_FOREACH(ia, &rap->addrs, next) { - if (ia->flags & IPV6_AF_AUTOCONF && - ipv6_publicaddr(ia)) - return 1; + TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) { + if (rap->iface == ifp) { + TAILQ_FOREACH(ia, &rap->addrs, next) { + if (ia->flags & IPV6_AF_AUTOCONF && + ipv6_publicaddr(ia)) + return 1; + } + } } return 0; } @@ -1109,7 +1095,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp, if (new_rap) add_router(ifp->ctx->ipv6, rap); - if (!ipv6nd_ra_has_public_addr(rap) && + if (!ipv6nd_has_public_addr(rap->iface) && !(rap->iface->options->options & DHCPCD_IPV6RA_ACCEPT_NOPUBLIC) && (!(rap->flags & ND_RA_FLAG_MANAGED) || !dhcp6_has_public_addr(rap->iface))) diff --git a/external/bsd/dhcpcd/dist/script.c b/external/bsd/dhcpcd/dist/script.c index cdf19ae987f8..25c190c77fef 100644 --- a/external/bsd/dhcpcd/dist/script.c +++ b/external/bsd/dhcpcd/dist/script.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: script.c,v 1.21 2015/07/09 10:15:34 roy Exp $"); + __RCSID("$NetBSD: script.c,v 1.22 2015/08/21 10:39:00 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -325,7 +325,7 @@ make_env(const struct interface *ifp, const char *reason, char ***argv) EMALLOC(6, e); snprintf(env[6], e, "ifflags=%u", ifp->flags); EMALLOC(7, e); - snprintf(env[7], e, "ifmtu=%d", if_getmtu(ifp->name)); + snprintf(env[7], e, "ifmtu=%d", if_getmtu(ifp)); l = e = strlen("interface_order="); TAILQ_FOREACH(ifp2, ifp->ctx->ifaces, next) { e += strlen(ifp2->name) + 1;