From: Gang Yan <yangang@kylinos.cn>
This patch adds a helper named 'mptcp_call_bpf' like tcp_call_bpf.
Invoke the new helper from mptcp_connect() with
BPF_SOCK_OPS_TCP_CONNECT_CB, placed after the subflow lock is acquired
and before tcp_connect(). At this point the msk lock is held by
__inet_stream_connect(), mirroring the placement of TCP_CONNECT_CB in
tcp_v4_connect()/tcp_v6_connect().
'bpf_sock_ops_cb_flags_set' can be called via msk, so using sk_is_tcp()
to avoid this issue.
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
net/core/filter.c | 3 +++
net/mptcp/protocol.c | 6 ++++++
net/mptcp/protocol.h | 29 +++++++++++++++++++++++++++++
3 files changed, 38 insertions(+)
diff --git a/net/core/filter.c b/net/core/filter.c
index 18e650bf7393..2f9778181279 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -6097,6 +6097,9 @@ BPF_CALL_2(bpf_sock_ops_cb_flags_set, struct bpf_sock_ops_kern *, bpf_sock,
if (!IS_ENABLED(CONFIG_INET) || !sk_fullsock(sk))
return -EINVAL;
+ if (!sk_is_tcp(sk))
+ return -EOPNOTSUPP;
+
tcp_sk(sk)->bpf_sock_ops_cb_flags = val;
return argval & (~BPF_SOCK_OPS_ALL_CB_FLAGS);
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index ffcf5a1788f6..837bb76e5c2d 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -4149,6 +4149,12 @@ static int mptcp_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
if (!msk->fastopening)
lock_sock(ssk);
+ /* Notify cgroup BPF on the msk before initiating the subflow connect.
+ * Mirrors BPF_SOCK_OPS_TCP_CONNECT_CB; msk lock is held by the
+ * caller (__inet_stream_connect) and ssk is held before.
+ */
+ mptcp_call_bpf(sk, BPF_SOCK_OPS_TCP_CONNECT_CB, 0, NULL);
+
/* the following mirrors closely a very small chunk of code from
* __inet_stream_connect()
*/
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index da40c6f3705f..e862310b2f81 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1374,4 +1374,33 @@ mptcp_token_join_cookie_init_state(struct mptcp_subflow_request_sock *subflow_re
static inline void mptcp_join_cookie_init(void) {}
#endif
+#ifdef CONFIG_BPF_JIT
+static inline int mptcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
+{
+ struct bpf_sock_ops_kern sock_ops;
+ int ret;
+
+ memset(&sock_ops, 0, offsetof(struct bpf_sock_ops_kern, temp));
+
+ if (sk_fullsock(sk)) {
+ sock_ops.is_fullsock = 1;
+ sock_owned_by_me(sk);
+ }
+
+ 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);
+ return ret == 0 ? sock_ops.reply : -1;
+}
+#else
+static inline int mptcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
+{
+ return -1;
+}
+#endif
+
#endif /* __MPTCP_PROTOCOL_H */
--
2.43.0