mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
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 -
ad13baf456
("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>
This commit is contained in:
commit
63cc8e20b3
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user