aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/include/uapi/asm/socket.h2
-rw-r--r--arch/mips/include/uapi/asm/socket.h2
-rw-r--r--arch/parisc/include/uapi/asm/socket.h2
-rw-r--r--arch/sparc/include/uapi/asm/socket.h2
-rw-r--r--include/net/sock_reuseport.h2
-rw-r--r--include/uapi/asm-generic/socket.h2
-rw-r--r--net/core/sock.c4
-rw-r--r--net/core/sock_reuseport.c24
8 files changed, 40 insertions, 0 deletions
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
index 976e89b116e5..de6c4df61082 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -122,6 +122,8 @@
122#define SO_RCVTIMEO_NEW 66 122#define SO_RCVTIMEO_NEW 66
123#define SO_SNDTIMEO_NEW 67 123#define SO_SNDTIMEO_NEW 67
124 124
125#define SO_DETACH_REUSEPORT_BPF 68
126
125#if !defined(__KERNEL__) 127#if !defined(__KERNEL__)
126 128
127#if __BITS_PER_LONG == 64 129#if __BITS_PER_LONG == 64
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
index d41765cfbc6e..d0a9ed2ca2d6 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -133,6 +133,8 @@
133#define SO_RCVTIMEO_NEW 66 133#define SO_RCVTIMEO_NEW 66
134#define SO_SNDTIMEO_NEW 67 134#define SO_SNDTIMEO_NEW 67
135 135
136#define SO_DETACH_REUSEPORT_BPF 68
137
136#if !defined(__KERNEL__) 138#if !defined(__KERNEL__)
137 139
138#if __BITS_PER_LONG == 64 140#if __BITS_PER_LONG == 64
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
index 66c5dd245ac7..10173c32195e 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -114,6 +114,8 @@
114#define SO_RCVTIMEO_NEW 0x4040 114#define SO_RCVTIMEO_NEW 0x4040
115#define SO_SNDTIMEO_NEW 0x4041 115#define SO_SNDTIMEO_NEW 0x4041
116 116
117#define SO_DETACH_REUSEPORT_BPF 0x4042
118
117#if !defined(__KERNEL__) 119#if !defined(__KERNEL__)
118 120
119#if __BITS_PER_LONG == 64 121#if __BITS_PER_LONG == 64
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
index 9265a9eece15..8029b681fc7c 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -115,6 +115,8 @@
115#define SO_RCVTIMEO_NEW 0x0044 115#define SO_RCVTIMEO_NEW 0x0044
116#define SO_SNDTIMEO_NEW 0x0045 116#define SO_SNDTIMEO_NEW 0x0045
117 117
118#define SO_DETACH_REUSEPORT_BPF 0x0047
119
118#if !defined(__KERNEL__) 120#if !defined(__KERNEL__)
119 121
120 122
diff --git a/include/net/sock_reuseport.h b/include/net/sock_reuseport.h
index 8a5f70c7cdf2..d9112de85261 100644
--- a/include/net/sock_reuseport.h
+++ b/include/net/sock_reuseport.h
@@ -35,6 +35,8 @@ extern struct sock *reuseport_select_sock(struct sock *sk,
35 struct sk_buff *skb, 35 struct sk_buff *skb,
36 int hdr_len); 36 int hdr_len);
37extern int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog); 37extern int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog);
38extern int reuseport_detach_prog(struct sock *sk);
39
38int reuseport_get_id(struct sock_reuseport *reuse); 40int reuseport_get_id(struct sock_reuseport *reuse);
39 41
40#endif /* _SOCK_REUSEPORT_H */ 42#endif /* _SOCK_REUSEPORT_H */
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index 8c1391c89171..77f7c1638eb1 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -117,6 +117,8 @@
117#define SO_RCVTIMEO_NEW 66 117#define SO_RCVTIMEO_NEW 66
118#define SO_SNDTIMEO_NEW 67 118#define SO_SNDTIMEO_NEW 67
119 119
120#define SO_DETACH_REUSEPORT_BPF 68
121
120#if !defined(__KERNEL__) 122#if !defined(__KERNEL__)
121 123
122#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__)) 124#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
diff --git a/net/core/sock.c b/net/core/sock.c
index 75b1c950b49f..06be30737b69 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1045,6 +1045,10 @@ set_rcvbuf:
1045 } 1045 }
1046 break; 1046 break;
1047 1047
1048 case SO_DETACH_REUSEPORT_BPF:
1049 ret = reuseport_detach_prog(sk);
1050 break;
1051
1048 case SO_DETACH_FILTER: 1052 case SO_DETACH_FILTER:
1049 ret = sk_detach_filter(sk); 1053 ret = sk_detach_filter(sk);
1050 break; 1054 break;
diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
index dc4aefdf2a08..9408f9264d05 100644
--- a/net/core/sock_reuseport.c
+++ b/net/core/sock_reuseport.c
@@ -332,3 +332,27 @@ int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog)
332 return 0; 332 return 0;
333} 333}
334EXPORT_SYMBOL(reuseport_attach_prog); 334EXPORT_SYMBOL(reuseport_attach_prog);
335
336int reuseport_detach_prog(struct sock *sk)
337{
338 struct sock_reuseport *reuse;
339 struct bpf_prog *old_prog;
340
341 if (!rcu_access_pointer(sk->sk_reuseport_cb))
342 return sk->sk_reuseport ? -ENOENT : -EINVAL;
343
344 old_prog = NULL;
345 spin_lock_bh(&reuseport_lock);
346 reuse = rcu_dereference_protected(sk->sk_reuseport_cb,
347 lockdep_is_held(&reuseport_lock));
348 rcu_swap_protected(reuse->prog, old_prog,
349 lockdep_is_held(&reuseport_lock));
350 spin_unlock_bh(&reuseport_lock);
351
352 if (!old_prog)
353 return -ENOENT;
354
355 sk_reuseport_prog_free(old_prog);
356 return 0;
357}
358EXPORT_SYMBOL(reuseport_detach_prog);