Re: [PATCH v4 bpf-next 11/11] bpf: Test BPF_SK_REUSEPORT_SELECT_OR_MIGRATE.
From: Martin KaFai Lau
Date: Wed May 05 2021 - 01:14:51 EST
On Tue, Apr 27, 2021 at 12:46:23PM +0900, Kuniyuki Iwashima wrote:
[ ... ]
> diff --git a/tools/testing/selftests/bpf/progs/test_migrate_reuseport.c b/tools/testing/selftests/bpf/progs/test_migrate_reuseport.c
> new file mode 100644
> index 000000000000..d7136dc29fa2
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/progs/test_migrate_reuseport.c
> @@ -0,0 +1,51 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Check if we can migrate child sockets.
> + *
> + * 1. If reuse_md->migrating_sk is NULL (SYN packet),
> + * return SK_PASS without selecting a listener.
> + * 2. If reuse_md->migrating_sk is not NULL (socket migration),
> + * select a listener (reuseport_map[migrate_map[cookie]])
> + *
> + * Author: Kuniyuki Iwashima <kuniyu@xxxxxxxxxxxx>
> + */
> +
> +#include <stddef.h>
> +#include <linux/bpf.h>
> +#include <bpf/bpf_helpers.h>
> +
> +struct {
> + __uint(type, BPF_MAP_TYPE_REUSEPORT_SOCKARRAY);
> + __uint(max_entries, 256);
> + __type(key, int);
> + __type(value, __u64);
> +} reuseport_map SEC(".maps");
> +
> +struct {
> + __uint(type, BPF_MAP_TYPE_HASH);
> + __uint(max_entries, 256);
> + __type(key, __u64);
> + __type(value, int);
> +} migrate_map SEC(".maps");
> +
> +SEC("sk_reuseport/migrate")
> +int prog_migrate_reuseport(struct sk_reuseport_md *reuse_md)
> +{
> + int *key, flags = 0;
> + __u64 cookie;
> +
> + if (!reuse_md->migrating_sk)
> + return SK_PASS;
> +
It will be useful to check if it is migrating a child sk or
a reqsk by testing the migrating_sk->state for TCP_ESTABLISHED
and TCP_NEW_SYN_RECV. skb can be further tested to check if it is
selecting for the final ACK. Global variables can then be
incremented and the user prog can check that, for example,
it is indeed testing the TCP_NEW_SYN_RECV code path...etc.
It will also become a good example for others on how migrating_sk
can be used.
> + cookie = bpf_get_socket_cookie(reuse_md->sk);
> +
> + key = bpf_map_lookup_elem(&migrate_map, &cookie);
> + if (!key)
> + return SK_DROP;
> +
> + bpf_sk_select_reuseport(reuse_md, &reuseport_map, key, flags);
> +
> + return SK_PASS;
> +}
> +
> +char _license[] SEC("license") = "GPL";
> --
> 2.30.2
>