From: Hannes Reinecke <hare@suse.de>
To: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagi@grimberg.me>, Keith Busch <kbusch@kernel.org>,
linux-nvme@lists.infradead.org, Jakub Kicinski <kuba@kernel.org>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>,
netdev@vger.kernel.org, Hannes Reinecke <hare@suse.de>
Subject: [PATCH 17/17] nvmet-tcp: peek icreq before starting TLS
Date: Mon, 14 Aug 2023 13:19:43 +0200 [thread overview]
Message-ID: <20230814111943.68325-18-hare@suse.de> (raw)
In-Reply-To: <20230814111943.68325-1-hare@suse.de>
Incoming connection might be either 'normal' NVMe-TCP connections
starting with icreq or TLS handshakes. To ensure that 'normal'
connections can still be handled we need to peek the first packet
and only start TLS handshake if it's not an icreq.
With that we can lift the restriction to always set TREQ to
'required' when TLS1.3 is enabled.
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
drivers/nvme/target/configfs.c | 17 ----------
drivers/nvme/target/nvmet.h | 10 ++++++
drivers/nvme/target/tcp.c | 61 +++++++++++++++++++++++++++++++---
3 files changed, 66 insertions(+), 22 deletions(-)
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index ad1fb32c7387..56ed6ce4d4d5 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -175,11 +175,6 @@ static ssize_t nvmet_addr_treq_show(struct config_item *item, char *page)
return snprintf(page, PAGE_SIZE, "\n");
}
-static inline u8 nvmet_port_disc_addr_treq_mask(struct nvmet_port *port)
-{
- return (port->disc_addr.treq & ~NVME_TREQ_SECURE_CHANNEL_MASK);
-}
-
static ssize_t nvmet_addr_treq_store(struct config_item *item,
const char *page, size_t count)
{
@@ -377,7 +372,6 @@ static ssize_t nvmet_addr_tsas_store(struct config_item *item,
const char *page, size_t count)
{
struct nvmet_port *port = to_nvmet_port(item);
- u8 treq = nvmet_port_disc_addr_treq_mask(port);
u8 sectype;
int i;
@@ -410,17 +404,6 @@ static ssize_t nvmet_addr_tsas_store(struct config_item *item,
}
nvmet_port_init_tsas_tcp(port, sectype);
- /*
- * The TLS implementation currently does not support
- * secure concatenation, so TREQ is always set to 'required'
- * if TLS is enabled.
- */
- if (sectype == NVMF_TCP_SECTYPE_TLS13) {
- treq |= NVMF_TREQ_REQUIRED;
- } else {
- treq |= NVMF_TREQ_NOT_SPECIFIED;
- }
- port->disc_addr.treq = treq;
return count;
}
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 7f9ae53c1df5..c47bab3281e0 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -179,6 +179,16 @@ static inline struct nvmet_port *ana_groups_to_port(
ana_groups_group);
}
+static inline u8 nvmet_port_disc_addr_treq_mask(struct nvmet_port *port)
+{
+ return (port->disc_addr.treq & ~NVME_TREQ_SECURE_CHANNEL_MASK);
+}
+
+static inline bool nvmet_port_secure_channel_required(struct nvmet_port *port)
+{
+ return nvmet_port_disc_addr_treq_mask(port) == NVMF_TREQ_REQUIRED;
+}
+
struct nvmet_ctrl {
struct nvmet_subsys *subsys;
struct nvmet_sq **sqs;
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index ded985efdb66..2b60e6f23cc9 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -1156,6 +1156,54 @@ static int nvmet_tcp_tls_record_ok(struct nvmet_tcp_queue *queue,
return ret;
}
+static int nvmet_tcp_try_peek_pdu(struct nvmet_tcp_queue *queue)
+{
+ struct nvme_tcp_hdr *hdr = &queue->pdu.cmd.hdr;
+ int len, ret;
+ struct kvec iov = {
+ .iov_base = (u8 *)&queue->pdu + queue->offset,
+ .iov_len = sizeof(struct nvme_tcp_hdr),
+ };
+ char cbuf[CMSG_LEN(sizeof(char))] = {};
+ struct msghdr msg = {
+ .msg_control = cbuf,
+ .msg_controllen = sizeof(cbuf),
+ .msg_flags = MSG_PEEK,
+ };
+
+ if (nvmet_port_secure_channel_required(queue->port->nport))
+ return 0;
+
+ len = kernel_recvmsg(queue->sock, &msg, &iov, 1,
+ iov.iov_len, msg.msg_flags);
+ if (unlikely(len < 0)) {
+ pr_debug("queue %d: peek error %d\n",
+ queue->idx, len);
+ return len;
+ }
+
+ ret = nvmet_tcp_tls_record_ok(queue, &msg, cbuf);
+ if (ret < 0)
+ return ret;
+
+ if (len < sizeof(struct nvme_tcp_hdr)) {
+ pr_debug("queue %d: short read, %d bytes missing\n",
+ queue->idx, (int)iov.iov_len - len);
+ return -EAGAIN;
+ }
+ pr_debug("queue %d: hdr type %d hlen %d plen %d size %d\n",
+ queue->idx, hdr->type, hdr->hlen, hdr->plen,
+ (int)sizeof(struct nvme_tcp_icreq_pdu));
+ if (hdr->type == nvme_tcp_icreq &&
+ hdr->hlen == sizeof(struct nvme_tcp_icreq_pdu) &&
+ hdr->plen == sizeof(struct nvme_tcp_icreq_pdu)) {
+ pr_debug("queue %d: icreq detected\n",
+ queue->idx);
+ return len;
+ }
+ return 0;
+}
+
static int nvmet_tcp_try_recv_pdu(struct nvmet_tcp_queue *queue)
{
struct nvme_tcp_hdr *hdr = &queue->pdu.cmd.hdr;
@@ -1868,11 +1916,14 @@ static void nvmet_tcp_alloc_queue(struct nvmet_tcp_port *port,
sk->sk_user_data = NULL;
sk->sk_data_ready = port->data_ready;
read_unlock_bh(&sk->sk_callback_lock);
- if (!nvmet_tcp_tls_handshake(queue))
- return;
-
- /* TLS handshake failed, terminate the connection */
- goto out_destroy_sq;
+ if (!nvmet_tcp_try_peek_pdu(queue)) {
+ if (!nvmet_tcp_tls_handshake(queue))
+ return;
+ /* TLS handshake failed, terminate the connection */
+ goto out_destroy_sq;
+ }
+ /* Not a TLS connection, continue with normal processing */
+ queue->state = NVMET_TCP_Q_CONNECTING;
}
#endif
--
2.35.3
next prev parent reply other threads:[~2023-08-14 11:19 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-14 11:19 [PATCHv8 00/17] nvme: In-kernel TLS support for TCP Hannes Reinecke
2023-08-14 11:19 ` [PATCH 01/17] nvme-keyring: register '.nvme' keyring Hannes Reinecke
2023-08-14 11:19 ` [PATCH 02/17] nvme-keyring: define a 'psk' keytype Hannes Reinecke
2023-08-14 11:19 ` [PATCH 03/17] nvme: add TCP TSAS definitions Hannes Reinecke
2023-08-14 11:19 ` [PATCH 04/17] nvme-tcp: add definitions for TLS cipher suites Hannes Reinecke
2023-08-14 11:19 ` [PATCH 05/17] nvme-keyring: implement nvme_tls_psk_default() Hannes Reinecke
2023-08-14 11:19 ` [PATCH 06/17] security/keys: export key_lookup() Hannes Reinecke
2023-08-14 11:19 ` [PATCH 07/17] nvme-tcp: allocate socket file Hannes Reinecke
2023-08-14 11:19 ` [PATCH 08/17] nvme-tcp: enable TLS handshake upcall Hannes Reinecke
2023-08-14 11:19 ` [PATCH 09/17] nvme-tcp: control message handling for recvmsg() Hannes Reinecke
2023-08-14 11:19 ` [PATCH 10/17] nvme-fabrics: parse options 'keyring' and 'tls_key' Hannes Reinecke
2023-08-14 12:07 ` Sagi Grimberg
2023-08-14 11:19 ` [PATCH 11/17] nvmet: make TCP sectype settable via configfs Hannes Reinecke
2023-08-14 11:19 ` [PATCH 12/17] nvmet-tcp: make nvmet_tcp_alloc_queue() a void function Hannes Reinecke
2023-08-14 11:19 ` [PATCH 13/17] nvmet-tcp: allocate socket file Hannes Reinecke
2023-08-14 11:19 ` [PATCH 14/17] nvmet: Set 'TREQ' to 'required' when TLS is enabled Hannes Reinecke
2023-08-14 11:19 ` [PATCH 15/17] nvmet-tcp: enable TLS handshake upcall Hannes Reinecke
2023-08-14 12:48 ` Sagi Grimberg
2023-08-14 14:03 ` Hannes Reinecke
2023-08-14 19:12 ` Sagi Grimberg
2023-08-15 6:29 ` Hannes Reinecke
2023-08-15 7:01 ` Sagi Grimberg
2023-08-15 7:20 ` Hannes Reinecke
2023-08-15 13:34 ` Sagi Grimberg
2023-08-15 15:04 ` Hannes Reinecke
2023-08-14 11:19 ` [PATCH 16/17] nvmet-tcp: control messages for recvmsg() Hannes Reinecke
2023-08-14 12:08 ` Sagi Grimberg
2023-08-14 11:19 ` Hannes Reinecke [this message]
2023-08-14 12:11 ` [PATCH 17/17] nvmet-tcp: peek icreq before starting TLS Sagi Grimberg
2023-08-14 13:18 ` Hannes Reinecke
2023-08-14 19:05 ` Sagi Grimberg
2023-08-15 6:20 ` Hannes Reinecke
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230814111943.68325-18-hare@suse.de \
--to=hare@suse.de \
--cc=edumazet@google.com \
--cc=hch@lst.de \
--cc=kbusch@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sagi@grimberg.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).