Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/bsd/dhcpcd/dist/src Import dhcpcd-8.1.0 with the fo...



details:   https://anonhg.NetBSD.org/src/rev/cdd69c660b50
branches:  trunk
changeset: 455233:cdd69c660b50
user:      roy <roy%NetBSD.org@localhost>
date:      Fri Oct 11 11:00:49 2019 +0000

description:
Import dhcpcd-8.1.0 with the following changes:

 * Fix carrier status after a route socket overflow
 * Allow domain spaced options
 * DHCP: Allow not sending Force Renew Nonce or Reconf Accept
 * IPv4LL: Now passes Apple Bonjour test versions 1.4 and 1.5
 * ARP: Fix a typo and remove pragma (thus working with old gcc)
 * DHCP6: Fix a cosmetic issue with infinite leases
 * DHCP6: SLA 0 and Prefix Len 0 will now add a delegatd /64 address
 * Ignore some virtual interfaces such as Tap and Bridge by default
 * BPF: Move validation logic out of BPF and back into dhcpcd

diffstat:

 external/bsd/dhcpcd/dist/src/arp.c         |  95 ++++++++++++++++++-----------
 external/bsd/dhcpcd/dist/src/bpf.h         |  19 ++++++
 external/bsd/dhcpcd/dist/src/control.h     |   2 +
 external/bsd/dhcpcd/dist/src/defs.h        |   2 +-
 external/bsd/dhcpcd/dist/src/dhcp-common.c |   4 +
 external/bsd/dhcpcd/dist/src/dhcp-common.h |   5 +
 external/bsd/dhcpcd/dist/src/dhcp.h        |   2 +-
 external/bsd/dhcpcd/dist/src/if.c          |  45 ++++++-------
 external/bsd/dhcpcd/dist/src/if.h          |   1 +
 external/bsd/dhcpcd/dist/src/ipv4.c        |  23 +++---
 external/bsd/dhcpcd/dist/src/ipv4.h        |   1 +
 external/bsd/dhcpcd/dist/src/ipv4ll.c      |  45 ++++++++++----
 external/bsd/dhcpcd/dist/src/ipv4ll.h      |   2 +-
 external/bsd/dhcpcd/dist/src/route.c       |   4 +-
 14 files changed, 161 insertions(+), 89 deletions(-)

diffs (truncated from 613 to 300 lines):

diff -r 5d5c611a37eb -r cdd69c660b50 external/bsd/dhcpcd/dist/src/arp.c
--- a/external/bsd/dhcpcd/dist/src/arp.c        Fri Oct 11 09:31:52 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/arp.c        Fri Oct 11 11:00:49 2019 +0000
@@ -129,12 +129,11 @@
            inet_ntoa(astate->addr));
 }
 
-
 static void
 arp_found(struct arp_state *astate, const struct arp_msg *amsg)
 {
        struct interface *ifp;
-       struct ivp4_addr *ia;
+       struct ipv4_addr *ia;
 #ifndef KERNEL_RFC5227
        struct timespec now, defend;
 #endif
@@ -142,11 +141,8 @@
        arp_report_conflicted(astate, amsg);
        ifp = astate->iface;
 
-#pragma GCC diagnostic push /* GCC is clearly wrong about this warning. */
-#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
        /* If we haven't added the address we're doing a probe. */
        ia = ipv4_iffindaddr(ifp, &astate->addr, NULL);
-#pragma GCC diagnostic pop
        if (ia == NULL) {
                if (astate->found_cb != NULL)
                        astate->found_cb(astate, amsg);
@@ -182,6 +178,35 @@
                astate->defend_failed_cb(astate);
 }
 
+static bool
+arp_validate(const struct interface *ifp, struct arphdr *arp)
+{
+
+       /* Families must match */
+       if (arp->ar_hrd != htons(ifp->family))
+               return false;
+
+       /* Protocol must be IP. */
+       if (arp->ar_pro != htons(ETHERTYPE_IP))
+               return false;
+
+       /* lladdr length matches */
+       if (arp->ar_hln != ifp->hwlen)
+               return false;
+
+       /* Protocol length must match in_addr_t */
+       if (arp->ar_pln != sizeof(in_addr_t))
+               return false;
+
+       /* Only these types are recognised */
+       if (arp->ar_op != htons(ARPOP_REPLY) &&
+           arp->ar_op != htons(ARPOP_REQUEST))
+               return false;
+
+       return true;
+}
+
+
 static void
 arp_packet(struct interface *ifp, uint8_t *data, size_t len)
 {
@@ -197,25 +222,12 @@
                return;
        memcpy(&ar, data, sizeof(ar));
 
-       /* These checks are enforced in the BPF filter. */
-#if 0
-       /* Families must match */
-       if (ar.ar_hrd != htons(ifp->family))
+       if (!arp_validate(ifp, &ar)) {
+#ifdef BPF_DEBUG
+               logerrx("%s: ARP BPF validation failure", ifp->name);
+#endif
                return;
-       /* Protocol must be IP. */
-       if (ar.ar_pro != htons(ETHERTYPE_IP))
-               continue;
-       /* lladdr length matches */
-       if (ar.ar_hln != ifp->hwlen)
-               continue;
-       /* Protocol length must match in_addr_t */
-       if (ar.ar_pln != sizeof(arm.sip.s_addr))
-               return;
-       /* Only these types are recognised */
-       if (ar.ar_op != htons(ARPOP_REPLY) &&
-           ar.ar_op != htons(ARPOP_REQUEST))
-               continue;
-#endif
+       }
 
        /* Get pointers to the hardware addresses */
        hw_s = data + sizeof(ar);
@@ -329,10 +341,8 @@
        state = ARP_STATE(ifp);
        if (state->bpf_fd == -1) {
                state->bpf_fd = bpf_open(ifp, bpf_arp);
-               if (state->bpf_fd == -1) {
-                       logerr("%s: %s", __func__, ifp->name);
+               if (state->bpf_fd == -1)
                        return -1;
-               }
                eloop_event_add(ifp->ctx->eloop, state->bpf_fd, arp_read, ifp);
        }
        return state->bpf_fd;
@@ -428,6 +438,7 @@
 {
        struct arp_state *astate = arg;
        struct interface *ifp = astate->iface;
+       struct ipv4_addr *ia;
 
        if (++astate->claims < ANNOUNCE_NUM)
                logdebugx("%s: ARP announcing %s (%d of %d), "
@@ -438,24 +449,31 @@
                logdebugx("%s: ARP announcing %s (%d of %d)",
                    ifp->name, inet_ntoa(astate->addr),
                    astate->claims, ANNOUNCE_NUM);
+
+       /* The kernel will send a Gratuitous ARP for newly added addresses.
+        * So we can avoid sending the same.
+        * Linux is special and doesn't send one. */
+       ia = ipv4_iffindaddr(ifp, &astate->addr, NULL);
+#ifndef __linux__
+       if (astate->claims == 1 && ia != NULL && ia->flags & IPV4_AF_NEW)
+               goto skip_request;
+#endif
+
        if (arp_request(ifp, &astate->addr, &astate->addr) == -1)
                logerr(__func__);
+
+#ifndef __linux__
+skip_request:
+#endif
+       /* No longer a new address. */
+       if (ia != NULL)
+               ia->flags |= ~IPV4_AF_NEW;
+
        eloop_timeout_add_sec(ifp->ctx->eloop, ANNOUNCE_WAIT,
            astate->claims < ANNOUNCE_NUM ? arp_announce1 : arp_announced,
            astate);
 }
 
-/*
- * XXX FIXME
- * Kernels supporting RFC5227 will announce the address when it's
- * added.
- * dhcpcd should not announce when this happens, nor need to open
- * a BPF socket for it.
- * Also, an address might be added to a non preferred inteface when
- * the same address exists on a preferred one so we need to instruct
- * the kernel not to announce the address somehow.
- */
-
 void
 arp_announce(struct arp_state *astate)
 {
@@ -501,6 +519,9 @@
 {
        struct arp_state *astate;
 
+       if (ifp->flags & IFF_NOARP)
+               return;
+
        astate = arp_find(ifp, ia);
        if (astate == NULL) {
                astate = arp_new(ifp, ia);
diff -r 5d5c611a37eb -r cdd69c660b50 external/bsd/dhcpcd/dist/src/bpf.h
--- a/external/bsd/dhcpcd/dist/src/bpf.h        Fri Oct 11 09:31:52 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/bpf.h        Fri Oct 11 11:00:49 2019 +0000
@@ -34,6 +34,25 @@
 #define        BPF_PARTIALCSUM         (1U << 2)
 #define        BPF_BCAST               (1U << 3)
 
+/*
+ * Even though we program the BPF filter should we trust it?
+ * On Linux at least there is a window between opening the socket,
+ * binding the interface and setting the filter where we receive data.
+ * This data is NOT checked OR flushed and IS returned when reading.
+ * We have no way of flushing it other than reading these packets!
+ * But we don't know if they passed the filter or not ..... so we need
+ * to validate each and every packet that comes through ourselves as well.
+ * Even if Linux does fix this sorry state, who is to say other kernels
+ * don't have bugs causing a similar effect?
+ *
+ * As such, let's strive to keep the filters just for pattern matching
+ * to avoid waking dhcpcd up.
+ *
+ * If you want to be notified of any packet failing the BPF filter,
+ * define BPF_DEBUG below.
+ */
+//#define      BPF_DEBUG
+
 #include "dhcpcd.h"
 
 extern const char *bpf_name;
diff -r 5d5c611a37eb -r cdd69c660b50 external/bsd/dhcpcd/dist/src/control.h
--- a/external/bsd/dhcpcd/dist/src/control.h    Fri Oct 11 09:31:52 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/control.h    Fri Oct 11 11:00:49 2019 +0000
@@ -29,6 +29,8 @@
 #ifndef CONTROL_H
 #define CONTROL_H
 
+#include <stdbool.h>
+
 #include "dhcpcd.h"
 
 #if !defined(CTL_FREE_LIST)
diff -r 5d5c611a37eb -r cdd69c660b50 external/bsd/dhcpcd/dist/src/defs.h
--- a/external/bsd/dhcpcd/dist/src/defs.h       Fri Oct 11 09:31:52 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/defs.h       Fri Oct 11 11:00:49 2019 +0000
@@ -29,7 +29,7 @@
 #define CONFIG_H
 
 #define PACKAGE                        "dhcpcd"
-#define VERSION                        "8.0.6"
+#define VERSION                        "8.1.0"
 
 #ifndef CONFIG
 # define CONFIG                        SYSCONFDIR "/" PACKAGE ".conf"
diff -r 5d5c611a37eb -r cdd69c660b50 external/bsd/dhcpcd/dist/src/dhcp-common.c
--- a/external/bsd/dhcpcd/dist/src/dhcp-common.c        Fri Oct 11 09:31:52 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcp-common.c        Fri Oct 11 11:00:49 2019 +0000
@@ -200,6 +200,10 @@
        while ((token = strsep(&p, ", "))) {
                if (*token == '\0')
                        continue;
+               if (strncmp(token, "dhcp6_", 6) == 0)
+                       token += 6;
+               if (strncmp(token, "nd6_", 4) == 0)
+                       token += 4;
                match = 0;
                for (i = 0, opt = odopts; i < odopts_len; i++, opt++) {
                        if (opt->var == NULL || opt->option == 0)
diff -r 5d5c611a37eb -r cdd69c660b50 external/bsd/dhcpcd/dist/src/dhcp-common.h
--- a/external/bsd/dhcpcd/dist/src/dhcp-common.h        Fri Oct 11 09:31:52 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcp-common.h        Fri Oct 11 11:00:49 2019 +0000
@@ -81,6 +81,11 @@
 #define        OT_BITFLAG              (1 << 27)
 #define        OT_RESERVED             (1 << 28)
 
+#define DHC_REQOPT(o, r, n)                                              \
+       (!((o)->type & OT_NOREQ) &&                                       \
+        ((o)->type & OT_REQUEST || has_option_mask((r), (o)->option)) && \
+         !has_option_mask((n), (o)->option))
+
 struct dhcp_opt {
        uint32_t option; /* Also used for IANA Enterpise Number */
        int type;
diff -r 5d5c611a37eb -r cdd69c660b50 external/bsd/dhcpcd/dist/src/dhcp.h
--- a/external/bsd/dhcpcd/dist/src/dhcp.h       Fri Oct 11 09:31:52 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcp.h       Fri Oct 11 11:00:49 2019 +0000
@@ -260,7 +260,7 @@
 ssize_t dhcp_env(FILE *, const char *, const struct interface *,
     const struct bootp *, size_t);
 
-void dhcp_handleifa(int, struct ipv4_addr *, pid_t pid);
+struct ipv4_addr *dhcp_handleifa(int, struct ipv4_addr *, pid_t pid);
 void dhcp_drop(struct interface *, const char *);
 void dhcp_start(struct interface *);
 void dhcp_abort(struct interface *);
diff -r 5d5c611a37eb -r cdd69c660b50 external/bsd/dhcpcd/dist/src/if.c
--- a/external/bsd/dhcpcd/dist/src/if.c Fri Oct 11 09:31:52 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/if.c Fri Oct 11 11:00:49 2019 +0000
@@ -312,6 +312,7 @@
        struct if_head *ifs;
        struct interface *ifp;
        struct if_spec spec;
+       bool if_noconf;
 #ifdef AF_LINK
        const struct sockaddr_dl *sdl;
 #ifdef IFLR_ACTIVE
@@ -405,13 +406,6 @@
                        continue;
 #endif
 
-               /* Don't allow loopback or pointopoint unless explicit */
-               if (ifa->ifa_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) {
-                       if ((argc == 0 || argc == -1) &&
-                           ctx->ifac == 0 && !if_hasconf(ctx, spec.devname))
-                               active = IF_INACTIVE;
-               }
-
                if (if_vimaster(ctx, spec.devname) == 1) {
                        logfunc_t *logfunc = argc != 0 ? logerrx : logdebugx;
                        logfunc("%s: is a Virtual Interface Master, skipping",
@@ -419,6 +413,17 @@
                        continue;
                }
 
+               if_noconf = ((argc == 0 || argc == -1) && ctx->ifac == 0 &&
+                   !if_hasconf(ctx, spec.devname));
+
+               /* Don't allow loopback or pointopoint unless explicit.
+                * Don't allow some reserved interface names unless explicit. */
+               if (if_noconf) {
+                       if (ifa->ifa_flags & (IFF_LOOPBACK | IFF_POINTOPOINT) ||
+                           if_ignore(ctx, spec.devname))



Home | Main Index | Thread Index | Old Index