[PATCH mptcp-next v11 1/9] bpf: Add bpf_mptcp_send_info_to_ssk

Geliang Tang posted 9 patches 1 week, 4 days ago
[PATCH mptcp-next v11 1/9] bpf: Add bpf_mptcp_send_info_to_ssk
Posted by Geliang Tang 1 week, 4 days ago
From: Geliang Tang <tanggeliang@kylinos.cn>

Burst scheduler needs to allocate an array of struct subflow_send_info
on the stack and then select a subflow to send data. In order to implement
burst scheduler in BPF, this patch adds a new bpf_mptcp_send_info_to_ssk()
helper to get ssk from subflow_send_info and sets its parameter type as
ARG_PTR_TO_STACK.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 include/uapi/linux/bpf.h       |  7 +++++++
 net/mptcp/bpf.c                | 22 ++++++++++++++++++++++
 net/mptcp/protocol.c           |  5 -----
 net/mptcp/protocol.h           |  5 +++++
 tools/include/uapi/linux/bpf.h |  7 +++++++
 5 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 4162afc6b5d0..0d7a5846bd77 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -5795,6 +5795,12 @@ union bpf_attr {
  *		0 on success.
  *
  *		**-ENOENT** if the bpf_local_storage cannot be found.
+ *
+ * void *bpf_mptcp_send_info_to_ssk(void *info)
+ *	Description
+ *		Dynamically cast a *info* pointer to a *sock* pointer.
+ *	Return
+ *		*info* if casting is valid, or **NULL** otherwise.
  */
 #define ___BPF_FUNC_MAPPER(FN, ctx...)			\
 	FN(unspec, 0, ##ctx)				\
@@ -6009,6 +6015,7 @@ union bpf_attr {
 	FN(user_ringbuf_drain, 209, ##ctx)		\
 	FN(cgrp_storage_get, 210, ##ctx)		\
 	FN(cgrp_storage_delete, 211, ##ctx)		\
+	FN(mptcp_send_info_to_ssk, 212, ##ctx)			\
 	/* */
 
 /* backwards-compatibility macros for users of __BPF_FUNC_MAPPER that don't
diff --git a/net/mptcp/bpf.c b/net/mptcp/bpf.c
index e9db856972cb..10d3db6323dc 100644
--- a/net/mptcp/bpf.c
+++ b/net/mptcp/bpf.c
@@ -21,6 +21,26 @@ static struct bpf_struct_ops bpf_mptcp_sched_ops;
 static const struct btf_type *mptcp_sock_type, *mptcp_subflow_type __read_mostly;
 static u32 mptcp_sock_id, mptcp_subflow_id;
 
+BPF_CALL_1(bpf_mptcp_send_info_to_ssk, struct subflow_send_info *, info)
+{
+	BTF_TYPE_EMIT(struct sock);
+
+	if (info && info->ssk && sk_fullsock(info->ssk) &&
+	    info->ssk->sk_protocol == IPPROTO_TCP &&
+	    sk_is_mptcp(info->ssk))
+		return (unsigned long)info->ssk;
+
+	return (unsigned long)NULL;
+}
+
+static const struct bpf_func_proto bpf_mptcp_send_info_to_ssk_proto = {
+	.func		= bpf_mptcp_send_info_to_ssk,
+	.gpl_only	= false,
+	.ret_type	= RET_PTR_TO_BTF_ID_OR_NULL,
+	.arg1_type	= ARG_PTR_TO_STACK,
+	.ret_btf_id	= &btf_sock_ids[BTF_SOCK_TYPE_SOCK],
+};
+
 static const struct bpf_func_proto *
 bpf_mptcp_sched_get_func_proto(enum bpf_func_id func_id,
 			       const struct bpf_prog *prog)
@@ -34,6 +54,8 @@ bpf_mptcp_sched_get_func_proto(enum bpf_func_id func_id,
 		return &bpf_skc_to_tcp6_sock_proto;
 	case BPF_FUNC_skc_to_tcp_sock:
 		return &bpf_skc_to_tcp_sock_proto;
+	case BPF_FUNC_mptcp_send_info_to_ssk:
+		return &bpf_mptcp_send_info_to_ssk_proto;
 	default:
 		return bpf_base_func_proto(func_id, prog);
 	}
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index f768aa4473fb..791c1c0149ee 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1387,11 +1387,6 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
 					 sizeof(struct ipv6hdr) - \
 					 sizeof(struct frag_hdr))
 
-struct subflow_send_info {
-	struct sock *ssk;
-	u64 linger_time;
-};
-
 void mptcp_subflow_set_active(struct mptcp_subflow_context *subflow)
 {
 	if (!subflow->stale)
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 19a811220621..78a7cfb84c69 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -598,6 +598,11 @@ mptcp_subflow_ctx_reset(struct mptcp_subflow_context *subflow)
 	WRITE_ONCE(subflow->local_id, -1);
 }
 
+struct subflow_send_info {
+	struct sock *ssk;
+	u64 linger_time;
+};
+
 /* Convert reset reasons in MPTCP to enum sk_rst_reason type */
 static inline enum sk_rst_reason
 sk_rst_convert_mptcp_reason(u32 reason)
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 4162afc6b5d0..0d7a5846bd77 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -5795,6 +5795,12 @@ union bpf_attr {
  *		0 on success.
  *
  *		**-ENOENT** if the bpf_local_storage cannot be found.
+ *
+ * void *bpf_mptcp_send_info_to_ssk(void *info)
+ *	Description
+ *		Dynamically cast a *info* pointer to a *sock* pointer.
+ *	Return
+ *		*info* if casting is valid, or **NULL** otherwise.
  */
 #define ___BPF_FUNC_MAPPER(FN, ctx...)			\
 	FN(unspec, 0, ##ctx)				\
@@ -6009,6 +6015,7 @@ union bpf_attr {
 	FN(user_ringbuf_drain, 209, ##ctx)		\
 	FN(cgrp_storage_get, 210, ##ctx)		\
 	FN(cgrp_storage_delete, 211, ##ctx)		\
+	FN(mptcp_send_info_to_ssk, 212, ##ctx)			\
 	/* */
 
 /* backwards-compatibility macros for users of __BPF_FUNC_MAPPER that don't
-- 
2.45.2