build: finish fixing Linux TX_RING support after #1043 - #1045
Merged
Conversation
#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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #1044.
#1043 (thanks @plusky) fixed a typo in
src/common/txring.h's include guard -__GLIBC_MINORinstead of__GLIBC_MINOR__always evaluates false, so the#elsebranch (missing the TX_RING API entirely) was taken unconditionally on every glibc system - and switched to<linux/if_packet.h>, the header that actually definesstruct 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.acandcmake/ConfigureChecks.cmake'sHAVE_TX_RINGprobe test programs independently included<netpacket/packet.h>alongside<linux/if_packet.h>. The two cannot be included together before C23 - both definestruct 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=gnu17system). So the probe itself failed to compile, meaningHAVE_TX_RINGwas 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_RINGhad literally never been true in any build before this chain of fixes, this code path had never been exercised:src/common/sendpacket.handsendpacket.ceach unconditionally include<netpacket/packet.h>forstruct sockaddr_llwheneverHAVE_PF_PACKETis set (insendpacket.c, also wheneverHAVE_LIBURINGis set) - both commonly true alongsideHAVE_TX_RINGon a modern Linux system - which then collided withtxring.h's<linux/if_packet.h>. Made those three includes conditional on!HAVE_TX_RING, sincetxring.halready providesstruct sockaddr_llvia<linux/if_packet.h>in that case.Test plan
Linux TX_RING: yescorrectly detected (wasnobefore this PR,yesin 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 testpassesHAVE_TX_RINGsucceeds, full build succeeds with zero errorstcpreplay --versionreportsInjection method: PF_PACKET / TX_RING; actually replayed packets through it (179/179 successful, 0 failed), throughput ~13x over plainPF_PACKET send()grepthat 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 fixAlso updates
docs/CHANGELOGanddocs/CREDITto credit @plusky for #1043.🤖 Generated with Claude Code