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 >