xdp-tools: avoid struct ethhdr redefinition on musl

musl's <netinet/if_ether.h> and the kernel's raw <linux/if_ether.h>
both define struct ethhdr, and only avoid colliding if
<netinet/if_ether.h> (or something that pulls it in) is processed
first. lib/util/params.{c,h} and xdpsock.c, xdp-filter.c and
xdp-dump/xdpdump.c all got this backwards in various ways; fix the
include order/choice in each.

AI-Generated: Uses Claude Code

Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
This commit is contained in:
Khem Raj committed 2026-09-29 09:57:23 -07:00
1 parent 41bb6138a8
commit 8558f0f363
3 files changed
+140

No files matched your search

@@ -0,0 +1,81 @@
From: Khem Raj <khem.raj@oss.qualcomm.com>
Date: Tue, 29 Sep 2026 02:14:39 +0000
Subject: [PATCH] lib/util: avoid struct ethhdr redefinition on musl
lib/util/params.h and lib/util/params.c only need ETH_ALEN from
<linux/if_ether.h>, but including that raw kernel uapi header can
collide with musl's own <netinet/if_ether.h>: musl only skips its own
struct ethhdr (via __UAPI_DEF_ETHHDR) once its own header has already
been processed, so pulling in <linux/if_ether.h> first, or from a
translation unit that later also includes <net/ethernet.h>, defines
struct ethhdr twice and fails to build. Switch both files to use
<netinet/if_ether.h> directly instead of the uapi header.
lib/util/xdpsock.c already includes <netinet/ether.h> (which pulls in
musl's <netinet/if_ether.h>) after also including <linux/if_ether.h>
earlier in the file, i.e. in the wrong order for musl's
__UAPI_DEF_ETHHDR guard to take effect. Move the <linux/if_ether.h>
include to after <netinet/ether.h> so the guard suppresses the uapi
header's struct ethhdr as intended.
Upstream-Status: Pending
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
---
diff --git a/lib/util/params.c b/lib/util/params.c
index 5a5ee11..f4b143c 100644
--- a/lib/util/params.c
+++ b/lib/util/params.c
@@ -10,7 +10,9 @@
#include <errno.h>
#include <net/if.h>
-#include <linux/if_ether.h>
+/* ETH_ALEN only; see params.h for why this uses the libc header instead of
+ * the raw <linux/if_ether.h> uapi one. */
+#include <netinet/if_ether.h>
#include <linux/if_link.h> /* XDP_FLAGS_* depend on kernel-headers installed */
#include <linux/if_xdp.h>
#include <arpa/inet.h>
diff --git a/lib/util/params.h b/lib/util/params.h
index ab0ee4a..b50c259 100644
--- a/lib/util/params.h
+++ b/lib/util/params.h
@@ -8,7 +8,12 @@
#include <stdlib.h>
#include <linux/in.h>
#include <linux/in6.h>
-#include <linux/if_ether.h>
+/* Only ETH_ALEN is needed here; use the libc's own header (rather than the
+ * raw kernel uapi one) so we don't end up defining struct ethhdr twice when
+ * a translation unit also includes <net/ethernet.h>/<netinet/ether.h> (musl
+ * only suppresses <linux/if_ether.h>'s struct ethhdr via __UAPI_DEF_ETHHDR
+ * when its own netinet/if_ether.h was included first). */
+#include <netinet/if_ether.h>
#include <bpf/libbpf.h>
enum option_type {
diff --git a/lib/util/xdpsock.c b/lib/util/xdpsock.c
index a893728..46379dc 100644
--- a/lib/util/xdpsock.c
+++ b/lib/util/xdpsock.c
@@ -9,7 +9,6 @@
#include <linux/err.h>
#include <linux/if_link.h>
#include <linux/if_xdp.h>
-#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/limits.h>
#include <linux/udp.h>
@@ -17,6 +16,12 @@
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
+/* <linux/if_ether.h> must come after <netinet/ether.h> above: musl's
+ * <netinet/if_ether.h> (pulled in by netinet/ether.h) defines its own
+ * struct ethhdr and then sets __UAPI_DEF_ETHHDR=0, which this header
+ * checks before defining struct ethhdr itself. Included the other way
+ * around, both structs get defined and the second one is a hard error. */
+#include <linux/if_ether.h>
#include <net/if.h>
#include <poll.h>
#include <pthread.h>
@@ -0,0 +1,57 @@
From: Khem Raj <khem.raj@oss.qualcomm.com>
Date: Tue, 29 Sep 2026 02:14:39 +0000
Subject: [PATCH] xdp-filter, xdp-dump: avoid struct ethhdr redefinition on
musl
0003-lib-util-avoid-struct-ethhdr-redefinition-on-musl.patch made
lib/util/params.h include musl's <netinet/if_ether.h> (rather than the
raw <linux/if_ether.h> uapi header) so that struct ethhdr is only
defined once. That only works if <netinet/if_ether.h> (or something
that pulls it in) is processed before any raw <linux/if_ether.h>
inclusion sets __UAPI_DEF_ETHHDR=1 as a side effect of defining its
own struct ethhdr.
Two translation units still get this backwards:
- xdp-filter.c directly includes <linux/if_ether.h> before "params.h",
even though it doesn't use anything from that header itself (ETH_ALEN
already comes via params.h). Just drop the redundant include.
- xdpdump.c includes <linux/ethtool.h> (which itself pulls in
<linux/if_ether.h> for struct ethhdr) before "params.h" is reached
further down the file. Include musl's <netinet/if_ether.h> ahead of
<linux/ethtool.h> so the guard is already set when ethtool.h's
transitive <linux/if_ether.h> is processed.
Upstream-Status: Pending
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
---
diff --git a/xdp-dump/xdpdump.c b/xdp-dump/xdpdump.c
index fa3aeb3..395226c 100644
--- a/xdp-dump/xdpdump.c
+++ b/xdp-dump/xdpdump.c
@@ -21,6 +21,11 @@
#include <bpf/libbpf.h>
#include <linux/err.h>
+/* <linux/ethtool.h> pulls in <linux/if_ether.h>, which defines its own
+ * struct ethhdr unless __UAPI_DEF_ETHHDR is already 0. Include musl's
+ * <netinet/if_ether.h> first (it defines struct ethhdr and sets that
+ * guard) so <linux/ethtool.h> doesn't try to define it a second time. */
+#include <netinet/if_ether.h>
#include <linux/ethtool.h>
#include <linux/perf_event.h>
#include <linux/sockios.h>
diff --git a/xdp-filter/xdp-filter.c b/xdp-filter/xdp-filter.c
index 8e9d344..89286fc 100644
--- a/xdp-filter/xdp-filter.c
+++ b/xdp-filter/xdp-filter.c
@@ -14,8 +14,6 @@
#include <xdp/libxdp.h>
#include <arpa/inet.h>
-#include <linux/if_ether.h>
-
#include "params.h"
#include "logging.h"
#include "util.h"
@@ -16,6 +16,8 @@ SRC_URI = " \
git://github.com/xdp-project/xdp-tools.git;tag=v${PV};nobranch=1;protocol=https \
file://0001-configure-correctly-handle-CC-when-validating-requir.patch \
file://0002-lib-libxdp-Makefile-use-cp-fRd-to-preserve-symlinks-.patch \
file://0003-lib-util-avoid-struct-ethhdr-redefinition-on-musl.patch \
file://0004-xdp-filter-xdp-dump-avoid-struct-ethhdr-redefinitio.patch \
"
SRCREV = "8fbad9f0af621a22aa87ff2520b3735915b1f0fd"