From: Geliang Tang <[email protected]> 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 <[email protected]> Cc: John Meneghini <[email protected]> Cc: Randy Jennings <[email protected]> Cc: Nilay Shroff <[email protected]> Co-developed-by: zhenwei pi <[email protected]> Signed-off-by: zhenwei pi <[email protected]> Co-developed-by: Hui Zhu <[email protected]> Signed-off-by: Hui Zhu <[email protected]> Co-developed-by: Gang Yan <[email protected]> Signed-off-by: Gang Yan <[email protected]> Signed-off-by: Geliang Tang <[email protected]> --- 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
