From: Geliang Tang <[email protected]> To support MPTCP on the target side, the listen socket needs to pass IPPROTO_MPTCP to sock_create() for MPTCP ports, and use MPTCP-specific setsockopt functions.
This patch adds struct nvmet_tcp_proto_ops to hold listen socket protocol operations (protocol, set_reuseaddr, set_nodelay, set_priority). A TCP version is defined and used for TCP ports. v2: - use trtype instead of tsas (Hannes). v3: - check mptcp protocol from disc_addr.trtype instead of passing a parameter (Hannes). v4: - check CONFIG_MPTCP. v5: - define nvmet_tcp_proto struct. - add a pointer to this structure in nvmet_tcp_port. v6: - split nvmet_tcp_proto struct into two structs, nvmet_tcp_proto and nvmet_tcp_proto_ops, one for the accept socket, the other for the liston socket. - add a pointer to nvmet_tcp_proto struct in nvmet_tcp_queue. 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 | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 16f153a9772b..83fe001fc619 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -2087,8 +2087,23 @@ static void nvmet_tcp_listen_data_ready(struct sock *sk) read_unlock_bh(&sk->sk_callback_lock); } +struct nvmet_tcp_proto_ops { + int protocol; + void (*set_reuseaddr)(struct sock *sk); + void (*set_nodelay)(struct sock *sk); + void (*set_priority)(struct sock *sk, u32 priority); +}; + +static const struct nvmet_tcp_proto_ops nvmet_tcp_proto_ops = { + .protocol = IPPROTO_TCP, + .set_reuseaddr = sock_set_reuseaddr, + .set_nodelay = tcp_sock_set_nodelay, + .set_priority = sock_set_priority, +}; + static int nvmet_tcp_add_port(struct nvmet_port *nport) { + const struct nvmet_tcp_proto_ops *ops; struct nvmet_tcp_port *port; __kernel_sa_family_t af; int ret; @@ -2111,6 +2126,13 @@ static int nvmet_tcp_add_port(struct nvmet_port *nport) goto err_port; } + if (nport->disc_addr.trtype == NVMF_TRTYPE_TCP) { + ops = &nvmet_tcp_proto_ops; + } else { + ret = -EINVAL; + goto err_port; + } + ret = inet_pton_with_scope(&init_net, af, nport->disc_addr.traddr, nport->disc_addr.trsvcid, &port->addr); if (ret) { @@ -2125,7 +2147,7 @@ static int nvmet_tcp_add_port(struct nvmet_port *nport) port->nport->inline_data_size = NVMET_TCP_DEF_INLINE_DATA_SIZE; ret = sock_create(port->addr.ss_family, SOCK_STREAM, - IPPROTO_TCP, &port->sock); + ops->protocol, &port->sock); if (ret) { pr_err("failed to create a socket\n"); goto err_port; @@ -2134,10 +2156,10 @@ static int nvmet_tcp_add_port(struct nvmet_port *nport) port->sock->sk->sk_user_data = port; port->data_ready = port->sock->sk->sk_data_ready; port->sock->sk->sk_data_ready = nvmet_tcp_listen_data_ready; - sock_set_reuseaddr(port->sock->sk); - tcp_sock_set_nodelay(port->sock->sk); + ops->set_reuseaddr(port->sock->sk); + ops->set_nodelay(port->sock->sk); if (so_priority > 0) - sock_set_priority(port->sock->sk, so_priority); + ops->set_priority(port->sock->sk, so_priority); ret = kernel_bind(port->sock, (struct sockaddr_unsized *)&port->addr, sizeof(port->addr)); -- 2.53.0
