Commit 6503b9f2 authored by Manu Bretelle's avatar Manu Bretelle Committed by Daniel Borkmann

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

Augment the current set of options that are accessible via
bpf_{g,s}etsockopt to also support SO_REUSEPORT.
Signed-off-by: default avatarManu Bretelle <chantra@fb.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarMartin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20210310182305.1910312-1-chantra@fb.com
parent 1211f4e9
...@@ -4729,6 +4729,9 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname, ...@@ -4729,6 +4729,9 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname,
sk->sk_prot->keepalive(sk, valbool); sk->sk_prot->keepalive(sk, valbool);
sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool); sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool);
break; break;
case SO_REUSEPORT:
sk->sk_reuseport = valbool;
break;
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
...@@ -4898,6 +4901,9 @@ static int _bpf_getsockopt(struct sock *sk, int level, int optname, ...@@ -4898,6 +4901,9 @@ static int _bpf_getsockopt(struct sock *sk, int level, int optname,
case SO_BINDTOIFINDEX: case SO_BINDTOIFINDEX:
*((int *)optval) = sk->sk_bound_dev_if; *((int *)optval) = sk->sk_bound_dev_if;
break; break;
case SO_REUSEPORT:
*((int *)optval) = sk->sk_reuseport;
break;
default: default:
goto err_clear; goto err_clear;
} }
......
...@@ -57,6 +57,27 @@ static __inline int bind_to_device(struct bpf_sock_addr *ctx) ...@@ -57,6 +57,27 @@ static __inline int bind_to_device(struct bpf_sock_addr *ctx)
return 0; 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) static __inline int misc_opts(struct bpf_sock_addr *ctx, int opt)
{ {
int old, tmp, new = 0xeb9f; int old, tmp, new = 0xeb9f;
...@@ -127,6 +148,10 @@ int bind_v4_prog(struct bpf_sock_addr *ctx) ...@@ -127,6 +148,10 @@ int bind_v4_prog(struct bpf_sock_addr *ctx)
if (misc_opts(ctx, SO_MARK) || misc_opts(ctx, SO_PRIORITY)) if (misc_opts(ctx, SO_MARK) || misc_opts(ctx, SO_PRIORITY))
return 0; return 0;
/* Set reuseport and unset */
if (bind_reuseport(ctx))
return 0;
ctx->user_ip4 = bpf_htonl(SERV4_REWRITE_IP); ctx->user_ip4 = bpf_htonl(SERV4_REWRITE_IP);
ctx->user_port = bpf_htons(SERV4_REWRITE_PORT); ctx->user_port = bpf_htons(SERV4_REWRITE_PORT);
......
...@@ -63,6 +63,27 @@ static __inline int bind_to_device(struct bpf_sock_addr *ctx) ...@@ -63,6 +63,27 @@ static __inline int bind_to_device(struct bpf_sock_addr *ctx)
return 0; 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) static __inline int misc_opts(struct bpf_sock_addr *ctx, int opt)
{ {
int old, tmp, new = 0xeb9f; int old, tmp, new = 0xeb9f;
...@@ -141,6 +162,10 @@ int bind_v6_prog(struct bpf_sock_addr *ctx) ...@@ -141,6 +162,10 @@ int bind_v6_prog(struct bpf_sock_addr *ctx)
if (misc_opts(ctx, SO_MARK) || misc_opts(ctx, SO_PRIORITY)) if (misc_opts(ctx, SO_MARK) || misc_opts(ctx, SO_PRIORITY))
return 0; 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[0] = bpf_htonl(SERV6_REWRITE_IP_0);
ctx->user_ip6[1] = bpf_htonl(SERV6_REWRITE_IP_1); ctx->user_ip6[1] = bpf_htonl(SERV6_REWRITE_IP_1);
ctx->user_ip6[2] = bpf_htonl(SERV6_REWRITE_IP_2); ctx->user_ip6[2] = bpf_htonl(SERV6_REWRITE_IP_2);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment