OSDN Git Service

bpf: net: Add SO_DETACH_REUSEPORT_BPF
authorMartin KaFai Lau <kafai@fb.com>
Thu, 13 Jun 2019 22:00:01 +0000 (15:00 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 14 Jun 2019 23:21:19 +0000 (01:21 +0200)
There is SO_ATTACH_REUSEPORT_[CE]BPF but there is no DETACH.
This patch adds SO_DETACH_REUSEPORT_BPF sockopt.  The same
sockopt can be used to undo both SO_ATTACH_REUSEPORT_[CE]BPF.

reseport_detach_prog() is added and it is mostly a mirror
of the existing reuseport_attach_prog().  The differences are,
it does not call reuseport_alloc() and returns -ENOENT when
there is no old prog.

Cc: Craig Gallek <kraig@google.com>
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Reviewed-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
arch/alpha/include/uapi/asm/socket.h
arch/mips/include/uapi/asm/socket.h
arch/parisc/include/uapi/asm/socket.h
arch/sparc/include/uapi/asm/socket.h
include/net/sock_reuseport.h
include/uapi/asm-generic/socket.h
net/core/sock.c
net/core/sock_reuseport.c

index 976e89b..de6c4df 100644 (file)
 #define SO_RCVTIMEO_NEW         66
 #define SO_SNDTIMEO_NEW         67
 
+#define SO_DETACH_REUSEPORT_BPF 68
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
index d41765c..d0a9ed2 100644 (file)
 #define SO_RCVTIMEO_NEW         66
 #define SO_SNDTIMEO_NEW         67
 
+#define SO_DETACH_REUSEPORT_BPF 68
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
index 66c5dd2..10173c3 100644 (file)
 #define SO_RCVTIMEO_NEW         0x4040
 #define SO_SNDTIMEO_NEW         0x4041
 
+#define SO_DETACH_REUSEPORT_BPF 0x4042
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
index 9265a9e..8029b68 100644 (file)
 #define SO_RCVTIMEO_NEW          0x0044
 #define SO_SNDTIMEO_NEW          0x0045
 
+#define SO_DETACH_REUSEPORT_BPF  0x0047
+
 #if !defined(__KERNEL__)
 
 
index 8a5f70c..d9112de 100644 (file)
@@ -35,6 +35,8 @@ extern struct sock *reuseport_select_sock(struct sock *sk,
                                          struct sk_buff *skb,
                                          int hdr_len);
 extern int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog);
+extern int reuseport_detach_prog(struct sock *sk);
+
 int reuseport_get_id(struct sock_reuseport *reuse);
 
 #endif  /* _SOCK_REUSEPORT_H */
index 8c1391c..77f7c16 100644 (file)
 #define SO_RCVTIMEO_NEW         66
 #define SO_SNDTIMEO_NEW         67
 
+#define SO_DETACH_REUSEPORT_BPF 68
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
index 75b1c95..06be307 100644 (file)
@@ -1045,6 +1045,10 @@ set_rcvbuf:
                }
                break;
 
+       case SO_DETACH_REUSEPORT_BPF:
+               ret = reuseport_detach_prog(sk);
+               break;
+
        case SO_DETACH_FILTER:
                ret = sk_detach_filter(sk);
                break;
index dc4aefd..9408f92 100644 (file)
@@ -332,3 +332,27 @@ int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog)
        return 0;
 }
 EXPORT_SYMBOL(reuseport_attach_prog);
+
+int reuseport_detach_prog(struct sock *sk)
+{
+       struct sock_reuseport *reuse;
+       struct bpf_prog *old_prog;
+
+       if (!rcu_access_pointer(sk->sk_reuseport_cb))
+               return sk->sk_reuseport ? -ENOENT : -EINVAL;
+
+       old_prog = NULL;
+       spin_lock_bh(&reuseport_lock);
+       reuse = rcu_dereference_protected(sk->sk_reuseport_cb,
+                                         lockdep_is_held(&reuseport_lock));
+       rcu_swap_protected(reuse->prog, old_prog,
+                          lockdep_is_held(&reuseport_lock));
+       spin_unlock_bh(&reuseport_lock);
+
+       if (!old_prog)
+               return -ENOENT;
+
+       sk_reuseport_prog_free(old_prog);
+       return 0;
+}
+EXPORT_SYMBOL(reuseport_detach_prog);