Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de525be2 authored by Lawrence Brakmo's avatar Lawrence Brakmo Committed by Alexei Starovoitov
Browse files

bpf: Support passing args to sock_ops bpf function



Adds support for passing up to 4 arguments to sock_ops bpf functions. It
reusues the reply union, so the bpf_sock_ops structures are not
increased in size.

Signed-off-by: default avatarLawrence Brakmo <brakmo@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent b73042b8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1003,6 +1003,7 @@ struct bpf_sock_ops_kern {
	struct	sock *sk;
	u32	op;
	union {
		u32 args[4];
		u32 reply;
		u32 replylong[4];
	};
+35 −5
Original line number Diff line number Diff line
@@ -2006,7 +2006,7 @@ void tcp_cleanup_ulp(struct sock *sk);
 * program loaded).
 */
#ifdef CONFIG_BPF
static inline int tcp_call_bpf(struct sock *sk, int op)
static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
{
	struct bpf_sock_ops_kern sock_ops;
	int ret;
@@ -2019,6 +2019,8 @@ static inline int tcp_call_bpf(struct sock *sk, int op)

	sock_ops.sk = sk;
	sock_ops.op = op;
	if (nargs > 0)
		memcpy(sock_ops.args, args, nargs * sizeof(*args));

	ret = BPF_CGROUP_RUN_PROG_SOCK_OPS(&sock_ops);
	if (ret == 0)
@@ -2027,18 +2029,46 @@ static inline int tcp_call_bpf(struct sock *sk, int op)
		ret = -1;
	return ret;
}

static inline int tcp_call_bpf_2arg(struct sock *sk, int op, u32 arg1, u32 arg2)
{
	u32 args[2] = {arg1, arg2};

	return tcp_call_bpf(sk, op, 2, args);
}

static inline int tcp_call_bpf_3arg(struct sock *sk, int op, u32 arg1, u32 arg2,
				    u32 arg3)
{
	u32 args[3] = {arg1, arg2, arg3};

	return tcp_call_bpf(sk, op, 3, args);
}

#else
static inline int tcp_call_bpf(struct sock *sk, int op)
static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
{
	return -EPERM;
}

static inline int tcp_call_bpf_2arg(struct sock *sk, int op, u32 arg1, u32 arg2)
{
	return -EPERM;
}

static inline int tcp_call_bpf_3arg(struct sock *sk, int op, u32 arg1, u32 arg2,
				    u32 arg3)
{
	return -EPERM;
}

#endif

static inline u32 tcp_timeout_init(struct sock *sk)
{
	int timeout;

	timeout = tcp_call_bpf(sk, BPF_SOCK_OPS_TIMEOUT_INIT);
	timeout = tcp_call_bpf(sk, BPF_SOCK_OPS_TIMEOUT_INIT, 0, NULL);

	if (timeout <= 0)
		timeout = TCP_TIMEOUT_INIT;
@@ -2049,7 +2079,7 @@ static inline u32 tcp_rwnd_init_bpf(struct sock *sk)
{
	int rwnd;

	rwnd = tcp_call_bpf(sk, BPF_SOCK_OPS_RWND_INIT);
	rwnd = tcp_call_bpf(sk, BPF_SOCK_OPS_RWND_INIT, 0, NULL);

	if (rwnd < 0)
		rwnd = 0;
@@ -2058,7 +2088,7 @@ static inline u32 tcp_rwnd_init_bpf(struct sock *sk)

static inline bool tcp_bpf_ca_needs_ecn(struct sock *sk)
{
	return (tcp_call_bpf(sk, BPF_SOCK_OPS_NEEDS_ECN) == 1);
	return (tcp_call_bpf(sk, BPF_SOCK_OPS_NEEDS_ECN, 0, NULL) == 1);
}

#if IS_ENABLED(CONFIG_SMC)
+3 −2
Original line number Diff line number Diff line
@@ -952,8 +952,9 @@ struct bpf_map_info {
struct bpf_sock_ops {
	__u32 op;
	union {
		__u32 reply;
		__u32 replylong[4];
		__u32 args[4];		/* Optionally passed to bpf program */
		__u32 reply;		/* Returned by bpf program	    */
		__u32 replylong[4];	/* Optionally returned by bpf prog  */
	};
	__u32 family;
	__u32 remote_ip4;	/* Stored in network byte order */
+1 −1
Original line number Diff line number Diff line
@@ -463,7 +463,7 @@ void tcp_init_transfer(struct sock *sk, int bpf_op)
	tcp_mtup_init(sk);
	icsk->icsk_af_ops->rebuild_header(sk);
	tcp_init_metrics(sk);
	tcp_call_bpf(sk, bpf_op);
	tcp_call_bpf(sk, bpf_op, 0, NULL);
	tcp_init_congestion_control(sk);
	tcp_init_buffer_space(sk);
}
+1 −1
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ static void tcpnv_init(struct sock *sk)
	 * within a datacenter, where we have reasonable estimates of
	 * RTTs
	 */
	base_rtt = tcp_call_bpf(sk, BPF_SOCK_OPS_BASE_RTT);
	base_rtt = tcp_call_bpf(sk, BPF_SOCK_OPS_BASE_RTT, 0, NULL);
	if (base_rtt > 0) {
		ca->nv_base_rtt = base_rtt;
		ca->nv_lower_bound_rtt = (base_rtt * 205) >> 8; /* 80% */
Loading