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 Sync



details:   https://anonhg.NetBSD.org/src/rev/0747b4055c5c
branches:  trunk
changeset: 966033:0747b4055c5c
user:      roy <roy%NetBSD.org@localhost>
date:      Fri Oct 11 11:03:59 2019 +0000

description:
Sync

diffstat:

 external/bsd/dhcpcd/dist/src/bpf.c        |   81 +--------
 external/bsd/dhcpcd/dist/src/dhcp.c       |  243 ++++++++++++++++-------------
 external/bsd/dhcpcd/dist/src/dhcp6.c      |   76 +++-----
 external/bsd/dhcpcd/dist/src/dhcpcd.8.in  |   11 +-
 external/bsd/dhcpcd/dist/src/dhcpcd.c     |    7 +-
 external/bsd/dhcpcd/dist/src/if-bsd.c     |   63 +++++++
 external/bsd/dhcpcd/dist/src/if-options.c |   17 +-
 7 files changed, 264 insertions(+), 234 deletions(-)

diffs (truncated from 945 to 300 lines):

diff -r b4d690dfcce3 -r 0747b4055c5c external/bsd/dhcpcd/dist/src/bpf.c
--- a/external/bsd/dhcpcd/dist/src/bpf.c        Fri Oct 11 11:00:49 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/bpf.c        Fri Oct 11 11:03:59 2019 +0000
@@ -410,13 +410,7 @@
 #endif
 
 #ifdef ARP
-
 static const struct bpf_insn bpf_arp_ether [] = {
-       /* Ensure packet is at least correct size. */
-       BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0),
-       BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ether_arp), 1, 0),
-       BPF_STMT(BPF_RET + BPF_K, 0),
-
        /* Check this is an ARP packet. */
        BPF_STMT(BPF_LD + BPF_H + BPF_ABS,
                 offsetof(struct ether_header, ether_type)),
@@ -552,17 +546,8 @@
 }
 #endif
 
-#define        BPF_M_FHLEN     0
-#define        BPF_M_IPHLEN    1
-#define        BPF_M_IPLEN     2
-#define        BPF_M_UDP       3
-#define        BPF_M_UDPLEN    4
-
 #ifdef ARPHRD_NONE
 static const struct bpf_insn bpf_bootp_none[] = {
-       /* Set the frame header length to zero. */
-       BPF_STMT(BPF_LD + BPF_IMM, 0),
-       BPF_STMT(BPF_ST, BPF_M_FHLEN),
 };
 #define BPF_BOOTP_NONE_LEN     __arraycount(bpf_bootp_none)
 #endif
@@ -574,13 +559,14 @@
        BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 1, 0),
        BPF_STMT(BPF_RET + BPF_K, 0),
 
-       /* Load frame header length into X. */
-       BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, sizeof(struct ether_header)),
-       /* Copy frame header length to memory */
-       BPF_STMT(BPF_STX, BPF_M_FHLEN),
+       /* Advance to the IP header. */
+       BPF_STMT(BPF_LDX + BPF_K, sizeof(struct ether_header)),
 };
 #define BPF_BOOTP_ETHER_LEN    __arraycount(bpf_bootp_ether)
 
+#define BOOTP_MIN_SIZE         sizeof(struct ip) + sizeof(struct udphdr) + \
+                               sizeof(struct bootp)
+
 static const struct bpf_insn bpf_bootp_filter[] = {
        /* Make sure it's an IPv4 packet. */
        BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0),
@@ -588,15 +574,6 @@
        BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x40, 1, 0),
        BPF_STMT(BPF_RET + BPF_K, 0),
 
-       /* Ensure IP header length is big enough and
-        * store the IP header length in memory. */
-       BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0),
-       BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x0f),
-       BPF_STMT(BPF_ALU + BPF_MUL + BPF_K, 4),
-       BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ip), 1, 0),
-       BPF_STMT(BPF_RET + BPF_K, 0),
-       BPF_STMT(BPF_ST, BPF_M_IPHLEN),
-
        /* Make sure it's a UDP packet. */
        BPF_STMT(BPF_LD + BPF_B + BPF_IND, offsetof(struct ip, ip_p)),
        BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0),
@@ -607,49 +584,17 @@
        BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 0, 1),
        BPF_STMT(BPF_RET + BPF_K, 0),
 
-       /* Store IP length. */
-       BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct ip, ip_len)),
-       BPF_STMT(BPF_ST, BPF_M_IPLEN),
-
        /* Advance to the UDP header. */
-       BPF_STMT(BPF_LD + BPF_MEM, BPF_M_IPHLEN),
+       BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0),
+       BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x0f),
+       BPF_STMT(BPF_ALU + BPF_MUL + BPF_K, 4),
        BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0),
        BPF_STMT(BPF_MISC + BPF_TAX, 0),
 
-       /* Store UDP location */
-       BPF_STMT(BPF_STX, BPF_M_UDP),
-
        /* Make sure it's from and to the right port. */
        BPF_STMT(BPF_LD + BPF_W + BPF_IND, 0),
        BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (BOOTPS << 16) + BOOTPC, 1, 0),
        BPF_STMT(BPF_RET + BPF_K, 0),
-
-       /* Store UDP length. */
-       BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct udphdr, uh_ulen)),
-       BPF_STMT(BPF_ST, BPF_M_UDPLEN),
-
-       /* Ensure that UDP length + IP header length == IP length */
-       /* Copy IP header length to X. */
-       BPF_STMT(BPF_LDX + BPF_MEM, BPF_M_IPHLEN),
-       /* Add UDP length (A) to IP header length (X). */
-       BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0),
-       /* Store result in X. */
-       BPF_STMT(BPF_MISC + BPF_TAX, 0),
-       /* Copy IP length to A. */
-       BPF_STMT(BPF_LD + BPF_MEM, BPF_M_IPLEN),
-       /* Ensure X == A. */
-       BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 1, 0),
-       BPF_STMT(BPF_RET + BPF_K, 0),
-
-       /* Advance to the BOOTP packet. */
-       BPF_STMT(BPF_LD + BPF_MEM, BPF_M_UDP),
-       BPF_STMT(BPF_ALU + BPF_ADD + BPF_K, sizeof(struct udphdr)),
-       BPF_STMT(BPF_MISC + BPF_TAX, 0),
-
-       /* Make sure it's BOOTREPLY. */
-       BPF_STMT(BPF_LD + BPF_B + BPF_IND, offsetof(struct bootp, op)),
-       BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTREPLY, 1, 0),
-       BPF_STMT(BPF_RET + BPF_K, 0),
 };
 
 #define BPF_BOOTP_FILTER_LEN   __arraycount(bpf_bootp_filter)
@@ -729,14 +674,8 @@
        }
 #endif
 
-       /* All passed, return the packet - frame length + ip length */
-       BPF_SET_STMT(bp, BPF_LD + BPF_MEM, BPF_M_FHLEN);
-       bp++;
-       BPF_SET_STMT(bp, BPF_LDX + BPF_MEM, BPF_M_IPLEN);
-       bp++;
-       BPF_SET_STMT(bp, BPF_ALU + BPF_ADD + BPF_X, 0);
-       bp++;
-       BPF_SET_STMT(bp, BPF_RET + BPF_A, 0);
+       /* All passed, return the packet. */
+       BPF_SET_STMT(bp, BPF_RET + BPF_K, BPF_WHOLEPACKET);
        bp++;
 
        return bpf_attach(fd, bpf, (unsigned int)(bp - bpf));
diff -r b4d690dfcce3 -r 0747b4055c5c external/bsd/dhcpcd/dist/src/dhcp.c
--- a/external/bsd/dhcpcd/dist/src/dhcp.c       Fri Oct 11 11:00:49 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcp.c       Fri Oct 11 11:03:59 2019 +0000
@@ -988,7 +988,8 @@
 
 #ifdef AUTH
                if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) !=
-                   DHCPCD_AUTH_SENDREQUIRE)
+                   DHCPCD_AUTH_SENDREQUIRE &&
+                   !has_option_mask(ifo->nomask, DHO_FORCERENEW_NONCE))
                {
                        /* We support HMAC-MD5 */
                        AREA_CHECK(1);
@@ -1032,10 +1033,7 @@
                    i < ifp->ctx->dhcp_opts_len;
                    i++, opt++)
                {
-                       if (!(opt->type & OT_REQUEST ||
-                           has_option_mask(ifo->requestmask, opt->option)))
-                               continue;
-                       if (opt->type & OT_NOREQ)
+                       if (!DHC_REQOPT(opt, ifo->requestmask, ifo->nomask))
                                continue;
                        if (type == DHCP_INFORM &&
                            (opt->option == DHO_RENEWALTIME ||
@@ -1054,10 +1052,7 @@
                                        break;
                        if (lp < p)
                                continue;
-                       if (!(opt->type & OT_REQUEST ||
-                           has_option_mask(ifo->requestmask, opt->option)))
-                               continue;
-                       if (opt->type & OT_NOREQ)
+                       if (!DHC_REQOPT(opt, ifo->requestmask, ifo->nomask))
                                continue;
                        if (type == DHCP_INFORM &&
                            (opt->option == DHO_RENEWALTIME ||
@@ -1738,15 +1733,32 @@
        if (r == -1)
                goto fail;
        len = (size_t)r;
-       from.s_addr = bootp->ciaddr;
-       if (from.s_addr != INADDR_ANY)
+
+       if (ipv4_iffindaddr(ifp, &state->lease.addr, NULL) != NULL)
+               from.s_addr = state->lease.addr.s_addr;
+       else
+               from.s_addr = INADDR_ANY;
+       if (from.s_addr != INADDR_ANY &&
+           state->lease.server.s_addr != INADDR_ANY)
                to.s_addr = state->lease.server.s_addr;
        else
-               to.s_addr = INADDR_ANY;
-
-       /* If unicasting, try and avoid sending by BPF so we don't
-        * use a L2 broadcast. */
-       if (to.s_addr != INADDR_ANY && to.s_addr != INADDR_BROADCAST) {
+               to.s_addr = INADDR_BROADCAST;
+
+       /*
+        * If not listening on the unspecified address we can
+        * only receive broadcast messages via BPF.
+        * Sockets bound to an address cannot receive broadcast messages
+        * even if they are setup to send them.
+        * Broadcasting from UDP is only an optimisation for rebinding
+        * and on BSD, at least, is reliant on the subnet route being
+        * correctly configured to recieve the unicast reply.
+        * As such, we always broadcast and receive the reply to it via BPF.
+        * This also guarantees we have a DHCP server attached to the
+        * interface we want to configure because we can't dictate the
+        * interface via IP_PKTINFO unlike for IPv6.
+        */
+       if (to.s_addr != INADDR_BROADCAST)
+       {
                if (dhcp_sendudp(ifp, &to, bootp, len) != -1)
                        goto out;
                logerr("%s: dhcp_sendudp", ifp->name);
@@ -2001,30 +2013,44 @@
 }
 
 
-static void
+static bool
 dhcp_addr_duplicated(struct interface *ifp, struct in_addr *ia)
 {
        struct dhcp_state *state = D_STATE(ifp);
+       unsigned long long opts = ifp->options->options;
+       struct dhcpcd_ctx *ctx = ifp->ctx;
+       bool deleted = false;
 #ifdef IN_IFF_DUPLICATED
        struct ipv4_addr *iap;
 #endif
 
        if ((state->offer == NULL || state->offer->yiaddr != ia->s_addr) &&
            !IN_ARE_ADDR_EQUAL(ia, &state->lease.addr))
-               return;
+               return deleted;
 
        /* RFC 2131 3.1.5, Client-server interaction */
        logerrx("%s: DAD detected %s", ifp->name, inet_ntoa(*ia));
        unlink(state->leasefile);
-       if (!(ifp->options->options & DHCPCD_STATIC) && !state->lease.frominfo)
+       if (!(opts & DHCPCD_STATIC) && !state->lease.frominfo)
                dhcp_decline(ifp);
 #ifdef IN_IFF_DUPLICATED
-       if ((iap = ipv4_iffindaddr(ifp, ia, NULL)) != NULL)
+       if ((iap = ipv4_iffindaddr(ifp, ia, NULL)) != NULL) {
                ipv4_deladdr(iap, 0);
+               deleted = true;
+       }
 #endif
-       eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
+       eloop_timeout_delete(ctx->eloop, NULL, ifp);
+       if (opts & (DHCPCD_STATIC | DHCPCD_INFORM)) {
+               state->reason = "EXPIRE";
+               script_runreason(ifp, state->reason);
+#define NOT_ONLY_SELF (DHCPCD_MASTER | DHCPCD_IPV6RS | DHCPCD_DHCP6)
+               if (!(ctx->options & NOT_ONLY_SELF))
+                       eloop_exit(ifp->ctx->eloop, EXIT_FAILURE);
+               return deleted;
+       }
        eloop_timeout_add_sec(ifp->ctx->eloop,
            DHCP_RAND_MAX, dhcp_discover, ifp);
+       return deleted;
 }
 #endif
 
@@ -2362,7 +2388,9 @@
                        /* Add the address now, let the kernel handle DAD. */
                        ipv4_addaddr(ifp, &l.addr, &l.mask, &l.brd,
                            l.leasetime, l.rebindtime);
-               } else
+               } else if (ia->addr_flags & IN_IFF_DUPLICATED)
+                       dhcp_addr_duplicated(ifp, &ia->addr);
+               else
                        loginfox("%s: waiting for DAD on %s",
                            ifp->name, inet_ntoa(addr));
                return 0;
@@ -2841,14 +2869,18 @@
 #define LOGDHCP(l, m) \
        log_dhcp((l), (m), ifp, bootp, bootp_len, from, 1)
 
+#define IS_STATE_ACTIVE(s) ((s)-state != DHS_NONE && \
+       (s)->state != DHS_INIT && (s)->state != DHS_BOUND)
+
        if (bootp->op != BOOTREPLY) {
-               logdebugx("%s: op (%d) is not BOOTREPLY",
-                   ifp->name, bootp->op);
+               if (IS_STATE_ACTIVE(state))
+                       logdebugx("%s: op (%d) is not BOOTREPLY",
+                           ifp->name, bootp->op);
                return;
        }
 
        if (state->xid != ntohl(bootp->xid)) {
-               if (state->state != DHS_BOUND && state->state != DHS_NONE)
+               if (IS_STATE_ACTIVE(state))
                        logdebugx("%s: wrong xid 0x%x (expecting 0x%x) from %s",
                            ifp->name, ntohl(bootp->xid), state->xid,
                            inet_ntoa(*from));



Home | Main Index | Thread Index | Old Index