summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2022-03-18 15:46:59 +0100
committerDaniel Borkmann <daniel@iogearbox.net>2022-03-18 15:47:04 +0100
commit63cc8e20b384d5ea10a4df330d8b9cf2f14eb64c (patch)
tree0c5f7fffe2b308ba022fd0263a5cb412a88c0e09 /tools
parentMerge branch 'Subskeleton support for BPF librariesThread-Topic: [PATCH bpf-n... (diff)
parentselftests/bpf: Fix test for 4-byte load from dst_port on big-endian (diff)
downloadlinux-63cc8e20b384d5ea10a4df330d8b9cf2f14eb64c.tar.xz
linux-63cc8e20b384d5ea10a4df330d8b9cf2f14eb64c.zip
Merge branch 'bpf-fix-sock-field-tests'
Jakub Sitnicki says: ==================== I think we have reached a consensus [1] on how the test for the 4-byte load from bpf_sock->dst_port and bpf_sk_lookup->remote_port should look, so here goes v3. I will submit a separate set of patches for bpf_sk_lookup->remote_port tests. This series has been tested on x86_64 and s390 on top of recent bpf-next - ad13baf45691 ("selftests/bpf: Test subprog jit when toggle bpf_jit_harden repeatedly"). [1] https://lore.kernel.org/bpf/87k0cwxkzs.fsf@cloudflare.com/ v2 -> v3: - Split what was previously patch 2 which was doing two things - Use BPF_TCP_* constants (Martin) - Treat the result of 4-byte load from dst_port as a 16-bit value (Martin) - Typo fixup and some rewording in patch 4 description v1 -> v2: - Limit read_sk_dst_port only to client traffic (patch 2) - Make read_sk_dst_port pass on litte- and big-endian (patch 3) v1: https://lore.kernel.org/bpf/20220225184130.483208-1-jakub@cloudflare.com/ v2: https://lore.kernel.org/bpf/20220227202757.519015-1-jakub@cloudflare.com/ ==================== Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/bpf/progs/test_sock_fields.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/tools/testing/selftests/bpf/progs/test_sock_fields.c b/tools/testing/selftests/bpf/progs/test_sock_fields.c
index 246f1f001813..9f4b8f9f1181 100644
--- a/tools/testing/selftests/bpf/progs/test_sock_fields.c
+++ b/tools/testing/selftests/bpf/progs/test_sock_fields.c
@@ -114,7 +114,7 @@ static void tpcpy(struct bpf_tcp_sock *dst,
#define RET_LOG() ({ \
linum = __LINE__; \
- bpf_map_update_elem(&linum_map, &linum_idx, &linum, BPF_NOEXIST); \
+ bpf_map_update_elem(&linum_map, &linum_idx, &linum, BPF_ANY); \
return CG_OK; \
})
@@ -134,11 +134,11 @@ int egress_read_sock_fields(struct __sk_buff *skb)
if (!sk)
RET_LOG();
- /* Not the testing egress traffic or
- * TCP_LISTEN (10) socket will be copied at the ingress side.
+ /* Not testing the egress traffic or the listening socket,
+ * which are covered by the cgroup_skb/ingress test program.
*/
if (sk->family != AF_INET6 || !is_loopback6(sk->src_ip6) ||
- sk->state == 10)
+ sk->state == BPF_TCP_LISTEN)
return CG_OK;
if (sk->src_port == bpf_ntohs(srv_sa6.sin6_port)) {
@@ -232,8 +232,8 @@ int ingress_read_sock_fields(struct __sk_buff *skb)
sk->src_port != bpf_ntohs(srv_sa6.sin6_port))
return CG_OK;
- /* Only interested in TCP_LISTEN */
- if (sk->state != 10)
+ /* Only interested in the listening socket */
+ if (sk->state != BPF_TCP_LISTEN)
return CG_OK;
/* It must be a fullsock for cgroup_skb/ingress prog */
@@ -251,10 +251,16 @@ int ingress_read_sock_fields(struct __sk_buff *skb)
return CG_OK;
}
+/*
+ * NOTE: 4-byte load from bpf_sock at dst_port offset is quirky. It
+ * gets rewritten by the access converter to a 2-byte load for
+ * backward compatibility. Treating the load result as a be16 value
+ * makes the code portable across little- and big-endian platforms.
+ */
static __noinline bool sk_dst_port__load_word(struct bpf_sock *sk)
{
__u32 *word = (__u32 *)&sk->dst_port;
- return word[0] == bpf_htonl(0xcafe0000);
+ return word[0] == bpf_htons(0xcafe);
}
static __noinline bool sk_dst_port__load_half(struct bpf_sock *sk)
@@ -281,6 +287,10 @@ int read_sk_dst_port(struct __sk_buff *skb)
if (!sk)
RET_LOG();
+ /* Ignore everything but the SYN from the client socket */
+ if (sk->state != BPF_TCP_SYN_SENT)
+ return CG_OK;
+
if (!sk_dst_port__load_word(sk))
RET_LOG();
if (!sk_dst_port__load_half(sk))