On 10/13/25 23:53, Samuel Thibault wrote:
In this patch, my approach is to make the data pass through a pipe,
which read end is going to be the selectable_fd for dhcpcd. When capture
starts, a new thread reads packets from gnumach bpf and pushes them to
the pipe. When the pipe has data, dhcpcd is signaled and it will call
the read function, which I modified to read from the pipe and return data
to dhcpcd. This is working fine in my local tests, but I'd appreciate a
review.
That doesn't look like an efficient way :)
But for gnumach devices, we don't really have another way to get it
through poll(), so it's actually the most efficient way (more than using
some separate translator on /dev/eth0).
How difficult would be implementing such a thing? a selectable fd that
would be signaled by gnumach when there is data in the bpf filter?
#include "pcap-int.h"
@@ -26,6 +28,9 @@ struct pcap_hurd {
device_t mach_dev;
mach_port_t rcv_port;
int filtering_in_kernel;
+ pthread_t pipe_thread_id;
+ int pipefd[2];
+ volatile int thread_should_stop;
thread_should_stop doesn't seem used? Usually you want to avoid volatile
variables anyway, they're so easy to get completely wrong.
Oops!, that was an old test I forgot to remove.
+ ret = read(rpipe, &msg->msg_hdr, p->bufsize);
+ if (ret < 0) {
+ /* Only write to errbuf if this is an error,
+ * not during termination */
+ if (errno != EBADF) {
Does EBADF happen? That's worrying, we shouldn't be getting it if we
properly manage fds.
This is also because of my tests on how to ensure the thread is
terminated. One of the first approaches was to close the pipe and the
rcv_port from the cleanup function while the thread was still working,
to make mach_msg, read or write fail and terminate the thread gracefully.
If the write end is closed while blocking on read(), it returns EBADF.
Same with write when the read end is closed.
The ifs were there to not log the EBADF error, since it was expected in
that approach.
I decided to leave them like "just in case" but theoretically EBADF
should never happen with the final implementation when the thread is
cancelled by pthread_cancel() before closing the pipe.
+ /* Close the pipe ends */
+ if (ph->pipefd[1] != 0) {
+ close(ph->pipefd[1]);
+ ph->pipefd[1] = 0;
Better make it -1, since 0 is a valid fd.
Yeah, in fact, libpcap initialize them to 0, so I'll ensure they are
initialized to -1 as well.