From nobody Mon Feb 9 19:53:06 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 095DB2D239B; Mon, 27 Oct 2025 14:52:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761576745; cv=none; b=Ps4940nYGHBvSW4jZ5jQHbYRxjTX08pALGczrccITE6IGQE10GjqwaUTcINn9Oe8PPMpw8AW6oq3dZ0LfYA/suigHOaCAkjgFsDQDPsKtxiPr+OkHDYtcN36YFHZx2HDUalq2xRTLRblp460Ug7LSuX2i5qgv4E2avqhbt+BC0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761576745; c=relaxed/simple; bh=iu0P+vaJ5O5gG5TpEvT8FAfiBsTiYmaG1u8QZ7crA7U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jVEY5eAYpmhIyV3gwXa/Oucb6z0P2I5utaJTBhsNIIDkq4oZYBFk8o1VNQXby04vBLhkh60HkhbFZ5+gdE44Jq0uTRE6zjryF3KthnDUL7PjXqztjZLkJI7jWGEgLNwbEub5EJNrSyTxkH7grQkcDA8j2XH1htfstAaHXG/tFTo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=nGSXk3vx; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="nGSXk3vx" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 6B0CE1A16DC; Mon, 27 Oct 2025 14:52:21 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 40D2F6062C; Mon, 27 Oct 2025 14:52:21 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E8C9B102F2507; Mon, 27 Oct 2025 15:52:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1761576739; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=xWiMo9ST793ACRe8WuzUy6BUXSEaZtsfUnqCbu+HGBM=; b=nGSXk3vxvzdLIp+HioYECMUtWbatJK9t5sTgqD6zFhQ33FcB939EeQURj1XIrQdJ5/S+Pw 9l9n/SPKCZMnQyt2ef2PXNFKcYxO/09W+txMfPIzZZz7mt2sNzhNiyVa6zWeV1aoRlYIsg GXBBWL2Ek4MXmzwHJkRzg809OQxKfaszdD8Ru9tiVdXxL+R2rf9HsZ+g/t/F+9R6m57nKl oesmojRAnY12i3hbqrEbqgPsri1CWuSdrGgN9dn4m4h9JJCCSdiMRMraUsD99Yt8yNb2/B hB7QgCGfwb7/vwKvbKUpUg/tn1pYj8USrsjsSskA/JiW8sMwpLrlBHmFbn1Bnw== From: =?utf-8?q?Alexis_Lothor=C3=A9_=28eBPF_Foundation=29?= Date: Mon, 27 Oct 2025 15:51:54 +0100 Subject: [PATCH bpf-next v3 2/4] selftests/bpf: make test_tc_tunnel.bpf.c compatible with big endian platforms Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251027-tc_tunnel-v3-2-505c12019f9d@bootlin.com> References: <20251027-tc_tunnel-v3-0-505c12019f9d@bootlin.com> In-Reply-To: <20251027-tc_tunnel-v3-0-505c12019f9d@bootlin.com> To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan Cc: ebpf@linuxfoundation.org, Thomas Petazzoni , Bastien Curutchet , bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Alexis_Lothor=C3=A9_=28eBPF_Foundation=29?= X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 When trying to run bpf-based encapsulation in a s390x environment, some parts of test_tc_tunnel.bpf.o do not encapsulate correctly the traffic, leading to tests failures. Adding some logs shows for example that packets about to be sent on an interface with the ip6vxlan_eth program attached do not have the expected value 5 in the ip header ihl field, and so are ignored by the program. This phenomenon appears when trying to cross-compile the selftests, rather than compiling it from a virtualized host: the selftests build system may then wrongly pick some host headers. If ends up being picked on the host (and if the host has a endianness different from the target one), it will then expose wrong endianness defines (e.g __LITTLE_ENDIAN_BITFIELD instead of __BIT_ENDIAN_BITFIELD), and it will for example mess up the iphdr structure layout used in the ebpf program. To prevent this, directly use the vmlinux.h header generated by the selftests build system rather than including directly specific kernel headers. As a consequence, add some missing definitions that are not exposed by vmlinux.h, and adapt the bitfield manipulations to allow building and using the program on both types of platforms. Signed-off-by: Alexis Lothor=C3=A9 (eBPF Foundation) --- Changes in v2: - use bpf_tracing_net.h to get some existing definitions --- tools/testing/selftests/bpf/progs/test_tc_tunnel.c | 57 +++++++++---------= ---- 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/tools/testing/selftests/bpf/progs/test_tc_tunnel.c b/tools/tes= ting/selftests/bpf/progs/test_tc_tunnel.c index 404124a93892..b509e4c99648 100644 --- a/tools/testing/selftests/bpf/progs/test_tc_tunnel.c +++ b/tools/testing/selftests/bpf/progs/test_tc_tunnel.c @@ -2,23 +2,11 @@ =20 /* In-place tunneling */ =20 -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include =20 -#include #include +#include +#include "bpf_tracing_net.h" #include "bpf_compiler.h" =20 #pragma GCC diagnostic ignored "-Waddress-of-packed-member" @@ -27,6 +15,14 @@ static const int cfg_port =3D 8000; =20 static const int cfg_udp_src =3D 20000; =20 +#define ETH_P_MPLS_UC 0x8847 +#define ETH_P_TEB 0x6558 + +#define MPLS_LS_S_MASK 0x00000100 +#define BPF_F_ADJ_ROOM_ENCAP_L2(len) \ + (((__u64)len & BPF_ADJ_ROOM_ENCAP_L2_MASK) \ + << BPF_ADJ_ROOM_ENCAP_L2_SHIFT) + #define L2_PAD_SZ (sizeof(struct vxlanhdr) + ETH_HLEN) =20 #define UDP_PORT 5555 @@ -36,10 +32,9 @@ static const int cfg_udp_src =3D 20000; =20 #define EXTPROTO_VXLAN 0x1 =20 -#define VXLAN_N_VID (1u << 24) -#define VXLAN_VNI_MASK bpf_htonl((VXLAN_N_VID - 1) << 8) -#define VXLAN_FLAGS 0x8 -#define VXLAN_VNI 1 +#define VXLAN_FLAGS bpf_htonl(1<<27) +#define VNI_ID 1 +#define VXLAN_VNI bpf_htonl(VNI_ID << 8) =20 #ifndef NEXTHDR_DEST #define NEXTHDR_DEST 60 @@ -48,12 +43,6 @@ static const int cfg_udp_src =3D 20000; /* MPLS label 1000 with S bit (last label) set and ttl of 255. */ static const __u32 mpls_label =3D __bpf_constant_htonl(1000 << 12 | MPLS_LS_S_MASK | 0xff); - -struct vxlanhdr { - __be32 vx_flags; - __be32 vx_vni; -} __attribute__((packed)); - struct gre_hdr { __be16 flags; __be16 protocol; @@ -94,8 +83,8 @@ static __always_inline void set_ipv4_csum(struct iphdr *i= ph) static __always_inline int __encap_ipv4(struct __sk_buff *skb, __u8 encap_= proto, __u16 l2_proto, __u16 ext_proto) { + struct iphdr iph_inner =3D {0}; __u16 udp_dst =3D UDP_PORT; - struct iphdr iph_inner; struct v4hdr h_outer; struct tcphdr tcph; int olen, l2_len; @@ -122,7 +111,6 @@ static __always_inline int __encap_ipv4(struct __sk_buf= f *skb, __u8 encap_proto, return TC_ACT_OK; =20 /* Derive the IPv4 header fields from the IPv6 header */ - memset(&iph_inner, 0, sizeof(iph_inner)); iph_inner.version =3D 4; iph_inner.ihl =3D 5; iph_inner.tot_len =3D bpf_htons(sizeof(iph6_inner) + @@ -210,7 +198,7 @@ static __always_inline int __encap_ipv4(struct __sk_buf= f *skb, __u8 encap_proto, struct vxlanhdr *vxlan_hdr =3D (struct vxlanhdr *)l2_hdr; =20 vxlan_hdr->vx_flags =3D VXLAN_FLAGS; - vxlan_hdr->vx_vni =3D bpf_htonl((VXLAN_VNI & VXLAN_VNI_MASK) << 8); + vxlan_hdr->vx_vni =3D VXLAN_VNI; =20 l2_hdr +=3D sizeof(struct vxlanhdr); } @@ -340,7 +328,7 @@ static __always_inline int __encap_ipv6(struct __sk_buf= f *skb, __u8 encap_proto, struct vxlanhdr *vxlan_hdr =3D (struct vxlanhdr *)l2_hdr; =20 vxlan_hdr->vx_flags =3D VXLAN_FLAGS; - vxlan_hdr->vx_vni =3D bpf_htonl((VXLAN_VNI & VXLAN_VNI_MASK) << 8); + vxlan_hdr->vx_vni =3D VXLAN_VNI; =20 l2_hdr +=3D sizeof(struct vxlanhdr); } @@ -372,8 +360,8 @@ static __always_inline int __encap_ipv6(struct __sk_buf= f *skb, __u8 encap_proto, =20 static int encap_ipv6_ipip6(struct __sk_buff *skb) { + struct v6hdr h_outer =3D {0}; struct iphdr iph_inner; - struct v6hdr h_outer; struct tcphdr tcph; struct ethhdr eth; __u64 flags; @@ -400,13 +388,12 @@ static int encap_ipv6_ipip6(struct __sk_buff *skb) return TC_ACT_SHOT; =20 /* prepare new outer network header */ - memset(&h_outer.ip, 0, sizeof(h_outer.ip)); h_outer.ip.version =3D 6; h_outer.ip.hop_limit =3D iph_inner.ttl; - h_outer.ip.saddr.s6_addr[1] =3D 0xfd; - h_outer.ip.saddr.s6_addr[15] =3D 1; - h_outer.ip.daddr.s6_addr[1] =3D 0xfd; - h_outer.ip.daddr.s6_addr[15] =3D 2; + h_outer.ip.saddr.in6_u.u6_addr8[1] =3D 0xfd; + h_outer.ip.saddr.in6_u.u6_addr8[15] =3D 1; + h_outer.ip.daddr.in6_u.u6_addr8[1] =3D 0xfd; + h_outer.ip.daddr.in6_u.u6_addr8[15] =3D 2; h_outer.ip.payload_len =3D iph_inner.tot_len; h_outer.ip.nexthdr =3D IPPROTO_IPIP; =20 --=20 2.51.1.dirty