On Wed, Mar 31, 2021 at 04:32 AM CEST, Cong Wang wrote: > From: Cong Wang <cong.wang@xxxxxxxxxxxxx> > > Currently sockmap calls into each protocol to update the struct > proto and replace it. This certainly won't work when the protocol > is implemented as a module, for example, AF_UNIX. > > Introduce a new ops sk->sk_prot->psock_update_sk_prot(), so each > protocol can implement its own way to replace the struct proto. > This also helps get rid of symbol dependencies on CONFIG_INET. > > Cc: John Fastabend <john.fastabend@xxxxxxxxx> > Cc: Daniel Borkmann <daniel@xxxxxxxxxxxxx> > Cc: Jakub Sitnicki <jakub@xxxxxxxxxxxxxx> > Cc: Lorenz Bauer <lmb@xxxxxxxxxxxxxx> > Signed-off-by: Cong Wang <cong.wang@xxxxxxxxxxxxx> > --- [...] > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > index 4a0478b17243..38952aaee3a1 100644 > --- a/net/ipv4/udp.c > +++ b/net/ipv4/udp.c > @@ -2849,6 +2849,9 @@ struct proto udp_prot = { > .unhash = udp_lib_unhash, > .rehash = udp_v4_rehash, > .get_port = udp_v4_get_port, > +#ifdef CONFIG_BPF_SYSCALL > + .psock_update_sk_prot = udp_bpf_update_proto, > +#endif > .memory_allocated = &udp_memory_allocated, > .sysctl_mem = sysctl_udp_mem, > .sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min), > diff --git a/net/ipv4/udp_bpf.c b/net/ipv4/udp_bpf.c > index 7a94791efc1a..6001f93cd3a0 100644 > --- a/net/ipv4/udp_bpf.c > +++ b/net/ipv4/udp_bpf.c > @@ -41,12 +41,23 @@ static int __init udp_bpf_v4_build_proto(void) > } > core_initcall(udp_bpf_v4_build_proto); > > -struct proto *udp_bpf_get_proto(struct sock *sk, struct sk_psock *psock) > +int udp_bpf_update_proto(struct sock *sk, bool restore) > { > int family = sk->sk_family == AF_INET ? UDP_BPF_IPV4 : UDP_BPF_IPV6; > + struct sk_psock *psock = sk_psock(sk); > + > + if (restore) { > + sk->sk_write_space = psock->saved_write_space; > + /* Pairs with lockless read in sk_clone_lock() */ Just to clarify. UDP sockets don't get cloned, so the above comment apply. > + WRITE_ONCE(sk->sk_prot, psock->sk_proto); > + return 0; > + } > > if (sk->sk_family == AF_INET6) > udp_bpf_check_v6_needs_rebuild(psock->sk_proto); > > - return &udp_bpf_prots[family]; > + /* Pairs with lockless read in sk_clone_lock() */ > + WRITE_ONCE(sk->sk_prot, &udp_bpf_prots[family]); > + return 0; > } > +EXPORT_SYMBOL_GPL(udp_bpf_update_proto); [...]