diff mbox series

bpf: Add getter and setter for SO_REUSEPORT through bpf_{g,s}etsockopt

Message ID 20210310182305.1910312-1-chantra@fb.com (mailing list archive)
State Accepted
Delegated to: BPF
Headers show
Series bpf: Add getter and setter for SO_REUSEPORT through bpf_{g,s}etsockopt | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Manu Bretelle March 10, 2021, 6:23 p.m. UTC
Augment the current set of options that are accessible via
bpf_{g,s}etsockopt to also support SO_REUSEPORT.

Signed-off-by: Manu Bretelle <chantra@fb.com>
---
 net/core/filter.c                             |  6 +++++
 .../testing/selftests/bpf/progs/bind4_prog.c  | 27 +++++++++++++++++++
 .../testing/selftests/bpf/progs/bind6_prog.c  | 27 +++++++++++++++++++
 3 files changed, 60 insertions(+)

Comments

Martin KaFai Lau March 11, 2021, 5:56 a.m. UTC | #1
On Wed, Mar 10, 2021 at 10:23:05AM -0800, Manu Bretelle wrote:
> Augment the current set of options that are accessible via
> bpf_{g,s}etsockopt to also support SO_REUSEPORT.
Thanks for the patch.

It is for bpf-next.  Please tag the subject line with "bpf-next" in the
future.  Details in Documentation/bpf/bpf_devel_QA.rst.

Acked-by: Martin KaFai Lau <kafai@fb.com>
Daniel Borkmann March 15, 2021, 4:25 p.m. UTC | #2
On 3/10/21 7:23 PM, Manu Bretelle wrote:
> Augment the current set of options that are accessible via
> bpf_{g,s}etsockopt to also support SO_REUSEPORT.
> 
> Signed-off-by: Manu Bretelle <chantra@fb.com>

Applied, thanks! I fixed up the 4 extra newlines:

> diff --git a/tools/testing/selftests/bpf/progs/bind4_prog.c b/tools/testing/selftests/bpf/progs/bind4_prog.c
> index 115a3b0ad984..b65a5e2481e6 100644
> --- a/tools/testing/selftests/bpf/progs/bind4_prog.c
> +++ b/tools/testing/selftests/bpf/progs/bind4_prog.c
> @@ -57,6 +57,29 @@ static __inline int bind_to_device(struct bpf_sock_addr *ctx)
>   	return 0;
>   }
>   
> +static __inline int bind_reuseport(struct bpf_sock_addr *ctx)
> +{
> +

^^^ here

> +	int val = 1;
> +
> +	if (bpf_setsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
> +			   &val, sizeof(val)))
> +		return 1;
> +	if (bpf_getsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
> +			   &val, sizeof(val)) || !val)
> +		return 1;
> +	val = 0;
> +	if (bpf_setsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
> +			   &val, sizeof(val)))
> +		return 1;
> +	if (bpf_getsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
> +			   &val, sizeof(val)) || val)
> +		return 1;
> +
> +

^^^ here

> +	return 0;
> +}
> +
>   static __inline int misc_opts(struct bpf_sock_addr *ctx, int opt)
>   {
[...]
> diff --git a/tools/testing/selftests/bpf/progs/bind6_prog.c b/tools/testing/selftests/bpf/progs/bind6_prog.c
> index 4c0d348034b9..68e7ede67b6d 100644
> --- a/tools/testing/selftests/bpf/progs/bind6_prog.c
> +++ b/tools/testing/selftests/bpf/progs/bind6_prog.c
> @@ -63,6 +63,29 @@ static __inline int bind_to_device(struct bpf_sock_addr *ctx)
>   	return 0;
>   }
>   
> +static __inline int bind_reuseport(struct bpf_sock_addr *ctx)
> +{
> +

^^^ here

> +	int val = 1;
> +
> +	if (bpf_setsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
> +			   &val, sizeof(val)))
> +		return 1;
> +	if (bpf_getsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
> +			   &val, sizeof(val)) || !val)
> +		return 1;
> +	val = 0;
> +	if (bpf_setsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
> +			   &val, sizeof(val)))
> +		return 1;
> +	if (bpf_getsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
> +			   &val, sizeof(val)) || val)
> +		return 1;
> +
> +

^^^ here

> +	return 0;
> +}
> +
>   static __inline int misc_opts(struct bpf_sock_addr *ctx, int opt)
>   {
>   	int old, tmp, new = 0xeb9f;
diff mbox series

Patch

diff --git a/net/core/filter.c b/net/core/filter.c
index 588b19ba0da8..ac67495af585 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -4786,6 +4786,9 @@  static int _bpf_setsockopt(struct sock *sk, int level, int optname,
 				sk->sk_prot->keepalive(sk, valbool);
 			sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool);
 			break;
+		case SO_REUSEPORT:
+			sk->sk_reuseport = valbool;
+			break;
 		default:
 			ret = -EINVAL;
 		}
@@ -4955,6 +4958,9 @@  static int _bpf_getsockopt(struct sock *sk, int level, int optname,
 		case SO_BINDTOIFINDEX:
 			*((int *)optval) = sk->sk_bound_dev_if;
 			break;
+		case SO_REUSEPORT:
+			*((int *)optval) = sk->sk_reuseport;
+			break;
 		default:
 			goto err_clear;
 		}
diff --git a/tools/testing/selftests/bpf/progs/bind4_prog.c b/tools/testing/selftests/bpf/progs/bind4_prog.c
index 115a3b0ad984..b65a5e2481e6 100644
--- a/tools/testing/selftests/bpf/progs/bind4_prog.c
+++ b/tools/testing/selftests/bpf/progs/bind4_prog.c
@@ -57,6 +57,29 @@  static __inline int bind_to_device(struct bpf_sock_addr *ctx)
 	return 0;
 }
 
+static __inline int bind_reuseport(struct bpf_sock_addr *ctx)
+{
+
+	int val = 1;
+
+	if (bpf_setsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
+			   &val, sizeof(val)))
+		return 1;
+	if (bpf_getsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
+			   &val, sizeof(val)) || !val)
+		return 1;
+	val = 0;
+	if (bpf_setsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
+			   &val, sizeof(val)))
+		return 1;
+	if (bpf_getsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
+			   &val, sizeof(val)) || val)
+		return 1;
+
+
+	return 0;
+}
+
 static __inline int misc_opts(struct bpf_sock_addr *ctx, int opt)
 {
 	int old, tmp, new = 0xeb9f;
@@ -127,6 +150,10 @@  int bind_v4_prog(struct bpf_sock_addr *ctx)
 	if (misc_opts(ctx, SO_MARK) || misc_opts(ctx, SO_PRIORITY))
 		return 0;
 
+	/* Set reuseport and unset */
+	if (bind_reuseport(ctx))
+		return 0;
+
 	ctx->user_ip4 = bpf_htonl(SERV4_REWRITE_IP);
 	ctx->user_port = bpf_htons(SERV4_REWRITE_PORT);
 
diff --git a/tools/testing/selftests/bpf/progs/bind6_prog.c b/tools/testing/selftests/bpf/progs/bind6_prog.c
index 4c0d348034b9..68e7ede67b6d 100644
--- a/tools/testing/selftests/bpf/progs/bind6_prog.c
+++ b/tools/testing/selftests/bpf/progs/bind6_prog.c
@@ -63,6 +63,29 @@  static __inline int bind_to_device(struct bpf_sock_addr *ctx)
 	return 0;
 }
 
+static __inline int bind_reuseport(struct bpf_sock_addr *ctx)
+{
+
+	int val = 1;
+
+	if (bpf_setsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
+			   &val, sizeof(val)))
+		return 1;
+	if (bpf_getsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
+			   &val, sizeof(val)) || !val)
+		return 1;
+	val = 0;
+	if (bpf_setsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
+			   &val, sizeof(val)))
+		return 1;
+	if (bpf_getsockopt(ctx, SOL_SOCKET, SO_REUSEPORT,
+			   &val, sizeof(val)) || val)
+		return 1;
+
+
+	return 0;
+}
+
 static __inline int misc_opts(struct bpf_sock_addr *ctx, int opt)
 {
 	int old, tmp, new = 0xeb9f;
@@ -141,6 +164,10 @@  int bind_v6_prog(struct bpf_sock_addr *ctx)
 	if (misc_opts(ctx, SO_MARK) || misc_opts(ctx, SO_PRIORITY))
 		return 0;
 
+	/* Set reuseport and unset */
+	if (bind_reuseport(ctx))
+		return 0;
+
 	ctx->user_ip6[0] = bpf_htonl(SERV6_REWRITE_IP_0);
 	ctx->user_ip6[1] = bpf_htonl(SERV6_REWRITE_IP_1);
 	ctx->user_ip6[2] = bpf_htonl(SERV6_REWRITE_IP_2);