[PATCH 05/11] nvmet-tcp: implement mptcp listen socket ops
Geliang Tang
geliang at kernel.org
Wed May 27 20:10:39 PDT 2026
From: Geliang Tang <tanggeliang at kylinos.cn>
An MPTCP-specific version of struct nvmet_tcp_proto_ops is implemented
for listen sockets. It is assigned to port->proto_ops when the transport
type is MPTCP.
Dedicated MPTCP helpers are introduced for setting listen socket options.
The set_nodelay and set_priority helpers set the values on all existing
subflows using mptcp_for_each_subflow(). The set_reuseaddr helper only
applies to the first subflow. The values are then synchronized to other
newly created subflows in sync_socket_options().
Cc: Hannes Reinecke <hare at suse.de>
Cc: John Meneghini <jmeneghi at redhat.com>
Cc: Randy Jennings <randyj at purestorage.com>
Cc: Nilay Shroff <nilay at linux.ibm.com>
Co-developed-by: zhenwei pi <zhenwei.pi at linux.dev>
Signed-off-by: zhenwei pi <zhenwei.pi at linux.dev>
Co-developed-by: Hui Zhu <zhuhui at kylinos.cn>
Signed-off-by: Hui Zhu <zhuhui at kylinos.cn>
Co-developed-by: Gang Yan <yangang at kylinos.cn>
Signed-off-by: Gang Yan <yangang at kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang at kylinos.cn>
---
drivers/nvme/target/tcp.c | 13 ++++++++++++
include/net/mptcp.h | 8 ++++++++
net/mptcp/sockopt.c | 42 +++++++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+)
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index e2f3de364c2b..8c2dc4bcbcd3 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -2101,6 +2101,15 @@ static const struct nvmet_tcp_proto_ops nvmet_tcp_proto_ops = {
.set_priority = sock_set_priority,
};
+#ifdef CONFIG_MPTCP
+static const struct nvmet_tcp_proto_ops nvmet_mptcp_proto_ops = {
+ .protocol = IPPROTO_MPTCP,
+ .set_reuseaddr = mptcp_sock_set_reuseaddr,
+ .set_nodelay = mptcp_sock_set_nodelay,
+ .set_priority = mptcp_sock_set_priority,
+};
+#endif
+
static int nvmet_tcp_add_port(struct nvmet_port *nport)
{
const struct nvmet_tcp_proto_ops *ops;
@@ -2128,6 +2137,10 @@ static int nvmet_tcp_add_port(struct nvmet_port *nport)
if (nport->disc_addr.trtype == NVMF_TRTYPE_TCP) {
ops = &nvmet_tcp_proto_ops;
+#ifdef CONFIG_MPTCP
+ } else if (nport->disc_addr.trtype == NVMF_TRTYPE_MPTCP) {
+ ops = &nvmet_mptcp_proto_ops;
+#endif
} else {
ret = -EINVAL;
goto err_port;
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index bf74dedc578d..b8ab214a7890 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -239,6 +239,10 @@ void mptcp_sock_no_linger(struct sock *sk);
void mptcp_sock_set_priority(struct sock *sk, u32 priority);
void mptcp_sock_set_tos(struct sock *sk);
+
+void mptcp_sock_set_reuseaddr(struct sock *sk);
+
+void mptcp_sock_set_nodelay(struct sock *sk);
#else
static inline void mptcp_init(void)
@@ -331,6 +335,10 @@ static inline void mptcp_sock_no_linger(struct sock *sk) { }
static inline void mptcp_sock_set_priority(struct sock *sk, u32 priority) { }
static inline void mptcp_sock_set_tos(struct sock *sk) { }
+
+static inline void mptcp_sock_set_reuseaddr(struct sock *sk) { }
+
+static inline void mptcp_sock_set_nodelay(struct sock *sk) { }
#endif /* CONFIG_MPTCP */
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 359b1eb2d0a9..0adbbe568f6e 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -1596,6 +1596,8 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
inet_assign_bit(FREEBIND, ssk, inet_test_bit(FREEBIND, sk));
inet_assign_bit(BIND_ADDRESS_NO_PORT, ssk, inet_test_bit(BIND_ADDRESS_NO_PORT, sk));
WRITE_ONCE(inet_sk(ssk)->local_port_range, READ_ONCE(inet_sk(sk)->local_port_range));
+
+ ssk->sk_reuse = sk->sk_reuse;
}
void mptcp_sockopt_sync_locked(struct mptcp_sock *msk, struct sock *ssk)
@@ -1741,3 +1743,43 @@ void mptcp_sock_set_tos(struct sock *sk)
__mptcp_sock_set_tos(sk, val);
}
EXPORT_SYMBOL(mptcp_sock_set_tos);
+
+void mptcp_sock_set_reuseaddr(struct sock *sk)
+{
+ struct mptcp_sock *msk = mptcp_sk(sk);
+ struct sock *ssk;
+
+ lock_sock(sk);
+ sockopt_seq_inc(msk);
+ sk->sk_reuse = SK_CAN_REUSE;
+ ssk = __mptcp_nmpc_sk(msk);
+ if (IS_ERR(ssk))
+ goto unlock;
+ lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
+ ssk->sk_reuse = SK_CAN_REUSE;
+ release_sock(ssk);
+unlock:
+ release_sock(sk);
+}
+EXPORT_SYMBOL(mptcp_sock_set_reuseaddr);
+
+void mptcp_sock_set_nodelay(struct sock *sk)
+{
+ struct mptcp_sock *msk = mptcp_sk(sk);
+ struct mptcp_subflow_context *subflow;
+ struct sock *ssk;
+
+ lock_sock(sk);
+ sockopt_seq_inc(msk);
+ msk->nodelay = true;
+ mptcp_for_each_subflow(msk, subflow) {
+ ssk = mptcp_subflow_tcp_sock(subflow);
+ if (ssk) {
+ lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
+ __tcp_sock_set_nodelay(ssk, true);
+ release_sock(ssk);
+ }
+ }
+ release_sock(sk);
+}
+EXPORT_SYMBOL(mptcp_sock_set_nodelay);
--
2.53.0
More information about the Linux-nvme
mailing list