Skip to content

txring: fix __GLIBC_MINOR typo and include the header that defines the TX_RING API - #1043

Merged
fklassen merged 2 commits into
appneta:4.6.0-beta1from
plusky:fix-txring-glibc-minor-includes
Jul 20, 2026
Merged

txring: fix __GLIBC_MINOR typo and include the header that defines the TX_RING API#1043
fklassen merged 2 commits into
appneta:4.6.0-beta1from
plusky:fix-txring-glibc-minor-includes

Conversation

@plusky

@plusky plusky commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

The include guard in src/common/txring.h reads

#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1

but the macro is spelled __GLIBC_MINOR__. __GLIBC_MINOR is not defined by any header, so the preprocessor substitutes 0 and the condition is always false — the #else branch has been taken unconditionally on every glibc system since this check was added.

That accident is the only reason the file has ever compiled.

Why fixing the typo alone is not enough

<netpacket/packet.h>, the glibc header the "true" branch selects, defines only struct sockaddr_ll and struct packet_mreq. It has never provided the PACKET_TX_RING API. struct tpacket_hdr, struct tpacket_req and TPACKET_HDRLEN — all used by txring.h and txring.c — come only from <linux/if_packet.h>, which is in the #else branch. Correcting just the macro name gives:

error: storage size of 'h' isn't known        (struct tpacket_hdr)
error: 'TPACKET_HDRLEN' undeclared

So this PR fixes the include as well: use <linux/if_packet.h> in both branches and drop <netpacket/packet.h>, which supplies nothing this header needs.

A second bug this fixes

Before C23, <netpacket/packet.h> and <linux/if_packet.h> cannot be included together — both define struct sockaddr_ll and struct packet_mreq, and the __UAPI_DEF_* de-duplication does not apply:

linux/if_packet.h:14:8: error: redefinition of 'struct sockaddr_ll'
linux/if_packet.h:297:8: error: redefinition of 'struct packet_mreq'

configure's TX_RING probe includes both headers, so this collision makes the probe fail whenever tcpreplay is built with -std=gnu11 or -std=gnu17, silently disabling HAVE_TX_RING and falling back to the slower PF_PACKET send() path. Distributions that pin an older language level for the bundled (non-C23-clean) libopts hit exactly this — openSUSE has been shipping tcpreplay without TX_RING for this reason, and Fedora carries a partial patch for the typo that does not address the header problem.

After this change txring.h compiles under -std=gnu11, -std=gnu17 and -std=gnu23 alike.

Verification

Built on Linux/aarch64 with HAVE_TX_RING enabled (configure reports Linux TX_RING: yes), and run-tested: replayed frames were captured on a veth peer, 3/3 successful, 0 failed.

fklassen and others added 2 commits July 19, 2026 11:05
…e TX_RING API

txring.h guards its includes with

    #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1

but the macro is spelled __GLIBC_MINOR__. __GLIBC_MINOR is not defined
by any header, so the preprocessor substitutes 0 and the condition is
always false: the #else branch has been taken unconditionally on every
glibc system since this check was added.

That accident is the only reason the file has ever compiled. The glibc
header selected by the "true" branch, <netpacket/packet.h>, defines only
struct sockaddr_ll and struct packet_mreq -- it has never provided the
PACKET_TX_RING API. struct tpacket_hdr, struct tpacket_req and
TPACKET_HDRLEN, all used by txring.h and txring.c, come only from
<linux/if_packet.h>, which the #else branch includes. Correcting just
the macro name makes the true branch fail to build:

    error: storage size of 'h' isn't known        (struct tpacket_hdr)
    error: 'TPACKET_HDRLEN' undeclared

so fix the include too: use <linux/if_packet.h> in both branches and drop
<netpacket/packet.h>, which supplies nothing this header needs.

Dropping it also fixes a second problem. Before C23, <netpacket/packet.h>
and <linux/if_packet.h> cannot be included together -- both define struct
sockaddr_ll and struct packet_mreq, and the __UAPI_DEF_* de-duplication
does not apply:

    linux/if_packet.h:14:8: error: redefinition of 'struct sockaddr_ll'
    linux/if_packet.h:297:8: error: redefinition of 'struct packet_mreq'

configure's TX_RING probe includes both headers, so that collision makes
the probe fail whenever tcpreplay is built with -std=gnu11 or -std=gnu17,
silently disabling HAVE_TX_RING and falling back to the slower PF_PACKET
send() path. Distributions that pin an older language level for the
bundled libopts hit exactly this. After this change txring.h compiles
under -std=gnu11, -std=gnu17 and -std=gnu23 alike.

Verified on Linux/aarch64 with HAVE_TX_RING enabled: tcpreplay builds
clean and replayed frames were captured on a veth peer (3/3 sent, 0
failed).

Signed-off-by: Martin Pluskal <mpluskal@suse.com>
@fklassen
fklassen changed the base branch from master to 4.6.0-beta1 July 20, 2026 20:34
@fklassen
fklassen merged commit 7807638 into appneta:4.6.0-beta1 Jul 20, 2026
3 checks passed
fklassen added a commit that referenced this pull request Jul 20, 2026
build: finish fixing Linux TX_RING support after #1043.

#1043 (thanks @plusky) fixed a typo in src/common/txring.h's include
guard but that 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 - so the probe itself failed to
   compile under -std=gnu11/-std=gnu17, meaning HAVE_TX_RING was never
   defined in the first place on affected systems. Dropped the
   redundant <netpacket/packet.h> from both probes.

2. Fixing the probes surfaced a third instance of the same collision,
   hit for the first time ever since TX_RING had never actually
   compiled before: src/common/sendpacket.h and sendpacket.c each
   unconditionally include <netpacket/packet.h> whenever HAVE_PF_PACKET
   (and in sendpacket.c, HAVE_LIBURING) is set, colliding with
   txring.h's <linux/if_packet.h>. Made those includes conditional on
   !HAVE_TX_RING.

Verified end-to-end: 'Linux TX_RING: yes' correctly detected by both
build systems, tcpreplay reports 'Injection method: PF_PACKET /
TX_RING', packets actually sent successfully through it, sudo make
test passes.

Fixes #1044.
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