]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
BPF: Start with the EOF marker set
authorRoy Marples <roy@marples.name>
Sun, 9 Mar 2025 19:56:40 +0000 (19:56 +0000)
committerRoy Marples <roy@marples.name>
Sun, 9 Mar 2025 19:56:40 +0000 (19:56 +0000)
This will allow us to abort any BPF read loop if it's reset.
While here, delay restarting DHCP slightly to allow privsep builds
to recover the same error.

Fixes #481.

src/bpf.c
src/dhcp.c
src/if-linux.c

index 47375a3da08ff787edfa06704b85f35dede42741..7c52126187a1a855ff94e7532e4b49eb6fc47330 100644 (file)
--- a/src/bpf.c
+++ b/src/bpf.c
@@ -170,6 +170,7 @@ bpf_open(const struct interface *ifp,
        if (bpf == NULL)
                return NULL;
        bpf->bpf_ifp = ifp;
+       bpf->bpf_flags = BPF_EOF;
 
        /* /dev/bpf is a cloner on modern kernels */
        bpf->bpf_fd = open("/dev/bpf", BPF_OPEN_FLAGS);
@@ -218,10 +219,12 @@ bpf_open(const struct interface *ifp,
        /* Get the required BPF buffer length from the kernel. */
        if (ioctl(bpf->bpf_fd, BIOCGBLEN, &ibuf_len) == -1)
                goto eexit;
+
        bpf->bpf_size = (size_t)ibuf_len;
        bpf->bpf_buffer = malloc(bpf->bpf_size);
        if (bpf->bpf_buffer == NULL)
                goto eexit;
+
        return bpf;
 
 eexit:
index f6db1a7c213b9cecf476925cd347e5eb411da188..436399cb017d33e1d87c47db7644d203adca2599 100644 (file)
@@ -2236,12 +2236,18 @@ dhcp_arp_defend_failed(struct arp_state *astate)
 {
        struct interface *ifp = astate->iface;
        struct dhcp_state *state = D_STATE(ifp);
+       unsigned int delay;
 
        if (!(ifp->options->options & (DHCPCD_INFORM | DHCPCD_STATIC)))
                dhcp_decline(ifp);
        dhcp_drop(ifp, "EXPIRED");
        dhcp_unlink(ifp->ctx, state->leasefile);
-       dhcp_start1(ifp);
+
+       // Delay restarting to give time for the BPF ARP process to exit
+       // as we may spawn a new one with a different filter fairly quickly
+       delay = MSEC_PER_SEC +
+               (arc4random_uniform(MSEC_PER_SEC * 2) - MSEC_PER_SEC);
+       eloop_timeout_add_msec(ifp->ctx->eloop, delay, dhcp_start1, ifp);
 }
 #endif
 
index 2e519f2a22d01e139bb19825030e83f27a65407d..b9082505a5453c6600e75f68a48ad552204e2b2d 100644 (file)
@@ -1850,6 +1850,7 @@ bpf_open(const struct interface *ifp,
        if (bpf == NULL)
                return NULL;
        bpf->bpf_ifp = ifp;
+       bpf->bpf_flags = BPF_EOF;
 
        /* Allocate a suitably large buffer for a single packet. */
        bpf->bpf_size = ETH_FRAME_LEN;