tcpdump mailing list archives

Re: What's the correct new API to request pcap_linux to not open an eventfd


From: Guy Harris via tcpdump-workers <tcpdump-workers () lists tcpdump org>
Date: Fri, 20 May 2022 12:36:01 -0700

--- Begin Message --- From: Guy Harris <gharris () sonic net>
Date: Fri, 20 May 2022 12:36:01 -0700
On May 20, 2022, at 10:56 AM, Bill Fenner via tcpdump-workers <tcpdump-workers () lists tcpdump org> wrote:

I'm helping to debug a system that uses many many pcap handles, and never
calls pcap_loop - only ever pcap_next.

Both pcap_loop() and pcap_next() ultimately go to the same place.

Note, BTW, that pcap_next() sucks; it's impossible to know whether it returns NULL because of an error or because the 
timeout expired and no packets had arrived during that time.  pcap_next_ex() doesn't have that problem.  (On Linux, the 
turbopacket timer doesn't expire if no packets have arrived, so, *on Linux*, NULL should, as far as I know, be returned 
only on errors.)

We've found that each pcap handle has an associated eventfd, which is used to make sure to wake up when
pcap_breakloop() is called.  Since this code doesn't call pcap_loop or
pcap_breakloop, the eventfd is unneeded.

If it called pcap_breakloop(), the eventfd would still be needed; otherwise, a call could remain indefinitely stuck in 
pcap_next() until a packet finally arrives.  Only the lack of a pcap_breakloop() call renders the eventfd unnecessary.

So how is this system handling those pcap handles?

If it's putting them in non-blocking mode, and using some select/poll/epoll/etc. mechanism in a single event loop, then 
the right name for the API is pcap_setnonblock().  There's no need for an eventfd to wake up the blocking poll() if 
there *is* no blocking poll(), so:

        if non-blocking mode is on before pcap_activate() is called, no eventfd should be opened, and poll_breakloop_fd 
should be set to -1;

        if non-blocking mode is turned on after pcap_activate() is called, the eventfd should be closed, and 
poll_breakloop_fd should be set to -1;

        if non-blocking mode is turned *off* afterwards, an eventfd should be opened, and poll_breakloop_fd should be 
set to it;

        if poll_breakloop_fd is -1, the poll() should only wait on the socket FD;

so this can be handled without API changes.

If it's doing something else, e.g. using multiple threads, then:

I'm willing to write and test the code that skips creating the breakloop_fd
- but, I wanted to discuss what the API should be.  Should there be a
pcap.c "pcap_breakloop_not_needed( pcap_t * )" that dispatches to the
implementation, or should there be a linux-specific
"pcap_linux_dont_create_eventfd( pcap_t * )"?

...it should be called pcap_breakloop_not_needed() (or something such as that), with a per-type implementation, and a 
*default* implementation that does nothing, so only implementations that need to do something different would need to 
do so.

--- End Message ---
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers () lists tcpdump org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers

Current thread: