Skip to content

build: finish fixing Linux TX_RING support after #1043 - #1045

Merged
fklassen merged 1 commit into
4.6.0-beta1from
fix-txring-probe-header-collision
Jul 20, 2026
Merged

build: finish fixing Linux TX_RING support after #1043#1045
fklassen merged 1 commit into
4.6.0-beta1from
fix-txring-probe-header-collision

Conversation

@fklassen

Copy link
Copy Markdown
Member

Summary

Fixes #1044.

#1043 (thanks @plusky) fixed a typo in src/common/txring.h's include guard - __GLIBC_MINOR instead of __GLIBC_MINOR__ always evaluates false, so the #else branch (missing the TX_RING API entirely) was taken unconditionally on every glibc system - and switched to <linux/if_packet.h>, the header that actually defines struct tpacket_hdr/tpacket_req/TPACKET_HDRLEN.

That fix alone wasn't enough to actually enable TX_RING. This PR finishes the job with three more fixes surfaced by actually verifying it end-to-end (build + sudo make test, not just "does it compile in isolation"):

1. Both build systems' TX_RING probes had the same header collision

configure.ac and cmake/ConfigureChecks.cmake's HAVE_TX_RING probe test programs independently included <netpacket/packet.h> alongside <linux/if_packet.h>. The two cannot be included together before C23 - both define struct sockaddr_ll/packet_mreq, and the __UAPI_DEF_* de-duplication guards don't apply pre-C23 (verified directly - reproduces the identical redefinition errors on a real -std=gnu17 system). So the probe itself failed to compile, meaning HAVE_TX_RING was never defined in the first place on affected systems (the openSUSE/Fedora-style "older language level" case #1043 called out) - txring.h's now-correct code was never even reached. Dropped the redundant <netpacket/packet.h> from both probes; it supplies nothing they use.

2. Fixing the probes surfaced a third instance of the same collision

Since HAVE_TX_RING had literally never been true in any build before this chain of fixes, this code path had never been exercised: src/common/sendpacket.h and sendpacket.c each unconditionally include <netpacket/packet.h> for struct sockaddr_ll whenever HAVE_PF_PACKET is set (in sendpacket.c, also whenever HAVE_LIBURING is set) - both commonly true alongside HAVE_TX_RING on a modern Linux system - which then collided with txring.h's <linux/if_packet.h>. Made those three includes conditional on !HAVE_TX_RING, since txring.h already provides struct sockaddr_ll via <linux/if_packet.h> in that case.

Test plan

  • Fresh clone, autotools: Linux TX_RING: yes correctly detected (was no before this PR, yes in the probe but build failures if only txring: fix __GLIBC_MINOR typo and include the header that defines the TX_RING API #1043's fix were applied), full build succeeds with zero errors, sudo make test passes
  • Fresh clone, CMake: same - HAVE_TX_RING succeeds, full build succeeds with zero errors
  • Runtime: tcpreplay --version reports Injection method: PF_PACKET / TX_RING; actually replayed packets through it (179/179 successful, 0 failed), throughput ~13x over plain PF_PACKET send()
  • Confirmed via grep that no other file in the tree includes both <netpacket/packet.h> and <linux/if_packet.h> (or has an unguarded include of one that could still collide) after this fix

Also updates docs/CHANGELOG and docs/CREDIT to credit @plusky for #1043.

🤖 Generated with Claude Code

#1043 (thanks @plusky) fixed a typo in src/common/txring.h's include
guard - '__GLIBC_MINOR' instead of '__GLIBC_MINOR__' always evaluates
false, so the #else branch (missing the TX_RING API entirely) was
taken unconditionally on every glibc system - and switched to
<linux/if_packet.h>, the header that actually defines struct
tpacket_hdr/tpacket_req/TPACKET_HDRLEN.

That fix alone wasn't enough to actually enable TX_RING:

1. Both build systems' own TX_RING feature probes (configure.ac,
   cmake/ConfigureChecks.cmake) independently included
   <netpacket/packet.h> alongside <linux/if_packet.h>. The two cannot
   be included together before C23 - both define struct
   sockaddr_ll/packet_mreq, and the __UAPI_DEF_* de-duplication guards
   don't apply pre-C23 - so the probe itself failed to compile under
   -std=gnu11/-std=gnu17 (verified directly, reproduces the identical
   redefinition errors), meaning HAVE_TX_RING was never defined in the
   first place on affected systems (the openSUSE/Fedora-style "older
   language level" case #1043 called out) and txring.h's now-correct
   code was never reached. Dropped the redundant
   <netpacket/packet.h> from both probes - it supplies nothing they
   use, only TP_STATUS_WRONG_FORMAT from <linux/if_packet.h>.

2. Fixing the probes surfaced a third instance of the exact same
   collision, hit for the first time ever since TX_RING had literally
   never compiled before: src/common/sendpacket.h and sendpacket.c
   each unconditionally include <netpacket/packet.h> for struct
   sockaddr_ll whenever HAVE_PF_PACKET is set (in sendpacket.c, also
   whenever HAVE_LIBURING is set) - both commonly true alongside
   HAVE_TX_RING on a modern Linux system - which then collided with
   txring.h's <linux/if_packet.h>. Made those three includes
   conditional on !HAVE_TX_RING, since txring.h already provides
   struct sockaddr_ll via <linux/if_packet.h> in that case.

Verified end-to-end, not just that it compiles: with all four fixes
applied, 'Linux TX_RING: yes' is correctly detected by both autotools
and CMake on a real glibc/-std=gnu17 system (GCC 14), tcpreplay
reports 'Injection method: PF_PACKET / TX_RING' at runtime, and
packets are actually sent successfully through it (179/179, 0
failed, throughput up ~13x over plain PF_PACKET send()). sudo make
test passes with both build systems.

Also updates docs/CHANGELOG and docs/CREDIT for #1043.

Fixes #1044.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@fklassen
fklassen merged commit 82c6ff9 into 4.6.0-beta1 Jul 20, 2026
5 checks passed
@fklassen
fklassen deleted the fix-txring-probe-header-collision branch July 20, 2026 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants