new file mode 100644
@@ -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>
new file mode 100644
@@ -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"
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> --- ...d-struct-ethhdr-redefinition-on-musl.patch | 81 +++++++++++++++++++ ...dump-avoid-struct-ethhdr-redefinitio.patch | 57 +++++++++++++ .../xdp-tools/xdp-tools_1.6.3.bb | 2 + 3 files changed, 140 insertions(+) create mode 100644 meta-oe/recipes-support/xdp-tools/files/0003-lib-util-avoid-struct-ethhdr-redefinition-on-musl.patch create mode 100644 meta-oe/recipes-support/xdp-tools/files/0004-xdp-filter-xdp-dump-avoid-struct-ethhdr-redefinitio.patch