From nobody Mon Feb 9 07:57:35 2026 Received: from mail-pj1-f44.google.com (mail-pj1-f44.google.com [209.85.216.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5E3702D3A72 for ; Wed, 12 Nov 2025 04:28:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921696; cv=none; b=JjuA2+CpYhEYI7atOqSCiA9KCpjliakd0u7Etgfu68mr4+iWCmjfhAmrqGDKB2xDRccto4WeIs4nITMuM2naWClpizXS1K/pFDITtsGf2IN/XgPPfTj31yABK42NAY6O5EnHrmJdlD6bUWOY3k4pX0+XsydBuyvHFq/SUfnq6to= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921696; c=relaxed/simple; bh=+jCGVmcm8MVpbEmr0Axn/mgty3ndsCdwYQUMd1UULmY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iwF1xPDJ576npcEPkZewVv219CLyPp+Megd56s0+rV8k3yQj0C4t/86cwJ74xW4vElaIKxNlYR3OEPTMIt5J2v/PpH1XavxvHxiCIvnP0DRnOvjqmk8Fj2FPiYGHaWI63m/d8EI0B+HbSaI8F2zqJ3C8hbGFNq1qEbDKjC04ZX0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=AXXWF5b3; arc=none smtp.client-ip=209.85.216.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="AXXWF5b3" Received: by mail-pj1-f44.google.com with SMTP id 98e67ed59e1d1-3437ea05540so412288a91.0 for ; Tue, 11 Nov 2025 20:28:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762921692; x=1763526492; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Tw8cOHbzhw9pNwhJI5NzaNsYq1VvyCsjiYozL/C9AsE=; b=AXXWF5b3O/UGSxSQyLs3S6Oyfqe6gfO1ifntoqumdkpnZYpVuTgsxM0og82dff92lJ HPoKh6Yde9IVXNOmHeAXGM4BwwV1r5Ft+6eP2LOpGlxrct2oq0/EiztzkOC2NddMqvnD LlSgQ6KS+km2ZC771nR7IqBzbKjgjTkPUzJi27YiKWwLcV54uOAOS68CbzcgJVEM2qpf QvEqoYa8NTTZRZSqbR2vHZbs3D+CmuqTsmwb+litI6q0cIs3p1zoVHwX9pn7v836Yd1O Axum4NEPp7zPiTPbF5cFcfS3uX7IOzHl1a7GazmjWjWnzzmdA5tljLWvVmgiasUbg9yw c9wQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762921692; x=1763526492; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Tw8cOHbzhw9pNwhJI5NzaNsYq1VvyCsjiYozL/C9AsE=; b=guwPsJNDUO/5pUpDtj5MbErFTZ4TS95lGbaaeGbvLLF8vTYbSO4qNzFV0GDtESD7WB oGl7yQNKCh7zkr3eG1CqOXQ84PTp/eJoJL0tuN73qNGE59OwhlF+aVU1z14/pJH3usqP sDFM6HfElcPS9RUnzGLSDKlaZJ+LjfvSoZ+NDuX6A36ykC+ZWPLHZ7D0XCbCQt50W+ZZ w1gyZYZXpqis16PPv7wozQRqZPa90OYuowW9VcXCR4pg+isw5V5wyVUUzwS0ygWamkvp MA+R2mCegnxzXEY71lmbhCrrvZTimE3CijbQp+UfL5cf4ANfBkviPjID3a03Kpf5OQqD czwg== X-Forwarded-Encrypted: i=1; AJvYcCX72duJexZW5gjLCqrEAOerfzLk6WghVxklviksmG4GHtu3tWp4PxPpQgeh+HqBosBJpbQQ/6WvSNXSNHY=@vger.kernel.org X-Gm-Message-State: AOJu0Yxb3aG7Ls0wPErIeDpBBE/rgQaQfnBPkst3w337sB/uARi25wcm E33f1XuWc7JoXbkfSOwrRy0YoziM9BJ7XC3tuV7orEiWsT0s0sYA3+xt X-Gm-Gg: ASbGnct2PA/IfBi59HidCE1AspCqpXnsuXEiyHdTIcM497piCNfRXbq9qFHrMOU+jPQ Bf4EhbvBEx9Od/rpTO2rc5o5Nswwy1+ujmg9FmdTMUD3j/uYoEOVtNa0UAY7IC8vLpbnY8hCPAO KxmCjaGZDyXxoxisOIp3TU+FqRFxKNoGxi8ZtFDyw2xc78B8u7u+230DhBa2JomILq5rvDnASR/ F3yNmFylG0EmX9icUrpdDtgIE1dJhPDP+oWyzmeLN5rFu+QDXZYZoQIpJfTWjy5wgyO2Y1QrpLW B+3d3F95BdBpYP/KiN2+PxF3UAJcDkL7pGmXqN70013uy/aq4iKGgupvIvImTOuGnnVJcceadcK n4f5DkdrX5JgswB5oLy/7KxaKnHbAHyR2a+j4oRacrSBGdWnfrRHnl3C32qaWC8cNqKaKGy/Xok m4BS3t8H0x0+9y7SueT3jIzSUAJGCVieIrcFhrNqCwS60BhAH4m5hgB411pFxBR85UIZrYnoqz/ x2Arp89Kw== X-Google-Smtp-Source: AGHT+IH4DTxJoV9qdn9141anhldPdY8NvxeKfjVGxu8WTSlRIvIvUku804PDVCCGbncSCn1vuCDFbg== X-Received: by 2002:a17:90b:3803:b0:340:b501:7b7d with SMTP id 98e67ed59e1d1-343dddfc5damr1978176a91.14.1762921692445; Tue, 11 Nov 2025 20:28:12 -0800 (PST) Received: from toolbx.alistair23.me (2403-580b-97e8-0-82ce-f179-8a79-69f4.ip6.aussiebb.net. [2403:580b:97e8:0:82ce:f179:8a79:69f4]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-343e06fbc0dsm854681a91.2.2025.11.11.20.28.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Nov 2025 20:28:12 -0800 (PST) From: alistair23@gmail.com X-Google-Original-From: alistair.francis@wdc.com To: chuck.lever@oracle.com, hare@kernel.org, kernel-tls-handshake@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nvme@lists.infradead.org, linux-nfs@vger.kernel.org Cc: kbusch@kernel.org, axboe@kernel.dk, hch@lst.de, sagi@grimberg.me, kch@nvidia.com, hare@suse.de, alistair23@gmail.com, Alistair Francis Subject: [PATCH v5 1/6] net/handshake: Store the key serial number on completion Date: Wed, 12 Nov 2025 14:27:15 +1000 Message-ID: <20251112042720.3695972-2-alistair.francis@wdc.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251112042720.3695972-1-alistair.francis@wdc.com> References: <20251112042720.3695972-1-alistair.francis@wdc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alistair Francis Allow userspace to include a key serial number when completing a handshake with the HANDSHAKE_CMD_DONE command. We then store this serial number and will provide it back to userspace in the future. This allows userspace to save data to the keyring and then restore that data later. This will be used to support the TLS KeyUpdate operation, as now userspace can resume information about a established session. Signed-off-by: Alistair Francis Reviewed-by: Hannes Reincke Reviewed-by: Chuck Lever Reviewed-by: Sagi Grimberg --- v5: - Change name to "handshake session ID" v4: - No change v3: - No change v2: - Change "key-serial" to "session-id" Documentation/netlink/specs/handshake.yaml | 4 ++++ Documentation/networking/tls-handshake.rst | 1 + drivers/nvme/host/tcp.c | 3 ++- drivers/nvme/target/tcp.c | 3 ++- include/net/handshake.h | 4 +++- include/uapi/linux/handshake.h | 1 + net/handshake/genl.c | 5 +++-- net/handshake/tlshd.c | 15 +++++++++++++-- net/sunrpc/svcsock.c | 4 +++- net/sunrpc/xprtsock.c | 4 +++- 10 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Documentation/netlink/specs/handshake.yaml b/Documentation/net= link/specs/handshake.yaml index 95c3fade7a8d..a273bc74d26f 100644 --- a/Documentation/netlink/specs/handshake.yaml +++ b/Documentation/netlink/specs/handshake.yaml @@ -87,6 +87,9 @@ attribute-sets: name: remote-auth type: u32 multi-attr: true + - + name: session-id + type: u32 =20 operations: list: @@ -123,6 +126,7 @@ operations: - status - sockfd - remote-auth + - session-id =20 mcast-groups: list: diff --git a/Documentation/networking/tls-handshake.rst b/Documentation/net= working/tls-handshake.rst index 6f5ea1646a47..0941b81dde5c 100644 --- a/Documentation/networking/tls-handshake.rst +++ b/Documentation/networking/tls-handshake.rst @@ -60,6 +60,7 @@ fills in a structure that contains the parameters of the = request: key_serial_t ta_my_privkey; unsigned int ta_num_peerids; key_serial_t ta_my_peerids[5]; + key_serial_t handshake_session_id; }; =20 The @ta_sock field references an open and connected socket. The consumer diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 9058ea64b89c..024d02248831 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -1694,7 +1694,8 @@ static void nvme_tcp_set_queue_io_cpu(struct nvme_tcp= _queue *queue) qid, queue->io_cpu); } =20 -static void nvme_tcp_tls_done(void *data, int status, key_serial_t pskid) +static void nvme_tcp_tls_done(void *data, int status, key_serial_t pskid, + key_serial_t handshake_session_id) { struct nvme_tcp_queue *queue =3D data; struct nvme_tcp_ctrl *ctrl =3D queue->ctrl; diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 470bf37e5a63..7f8516892359 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -1780,7 +1780,8 @@ static int nvmet_tcp_tls_key_lookup(struct nvmet_tcp_= queue *queue, } =20 static void nvmet_tcp_tls_handshake_done(void *data, int status, - key_serial_t peerid) + key_serial_t peerid, + key_serial_t handshake_session_id) { struct nvmet_tcp_queue *queue =3D data; =20 diff --git a/include/net/handshake.h b/include/net/handshake.h index 8ebd4f9ed26e..68d7f89e431a 100644 --- a/include/net/handshake.h +++ b/include/net/handshake.h @@ -18,7 +18,8 @@ enum { }; =20 typedef void (*tls_done_func_t)(void *data, int status, - key_serial_t peerid); + key_serial_t peerid, + key_serial_t handshake_session_id); =20 struct tls_handshake_args { struct socket *ta_sock; @@ -31,6 +32,7 @@ struct tls_handshake_args { key_serial_t ta_my_privkey; unsigned int ta_num_peerids; key_serial_t ta_my_peerids[5]; + key_serial_t handshake_session_id; }; =20 int tls_client_hello_anon(const struct tls_handshake_args *args, gfp_t fla= gs); diff --git a/include/uapi/linux/handshake.h b/include/uapi/linux/handshake.h index 662e7de46c54..b68ffbaa5f31 100644 --- a/include/uapi/linux/handshake.h +++ b/include/uapi/linux/handshake.h @@ -55,6 +55,7 @@ enum { HANDSHAKE_A_DONE_STATUS =3D 1, HANDSHAKE_A_DONE_SOCKFD, HANDSHAKE_A_DONE_REMOTE_AUTH, + HANDSHAKE_A_DONE_SESSION_ID, =20 __HANDSHAKE_A_DONE_MAX, HANDSHAKE_A_DONE_MAX =3D (__HANDSHAKE_A_DONE_MAX - 1) diff --git a/net/handshake/genl.c b/net/handshake/genl.c index f55d14d7b726..6cdce7e5dbc0 100644 --- a/net/handshake/genl.c +++ b/net/handshake/genl.c @@ -16,10 +16,11 @@ static const struct nla_policy handshake_accept_nl_poli= cy[HANDSHAKE_A_ACCEPT_HAN }; =20 /* HANDSHAKE_CMD_DONE - do */ -static const struct nla_policy handshake_done_nl_policy[HANDSHAKE_A_DONE_R= EMOTE_AUTH + 1] =3D { +static const struct nla_policy handshake_done_nl_policy[HANDSHAKE_A_DONE_S= ESSION_ID + 1] =3D { [HANDSHAKE_A_DONE_STATUS] =3D { .type =3D NLA_U32, }, [HANDSHAKE_A_DONE_SOCKFD] =3D { .type =3D NLA_S32, }, [HANDSHAKE_A_DONE_REMOTE_AUTH] =3D { .type =3D NLA_U32, }, + [HANDSHAKE_A_DONE_SESSION_ID] =3D { .type =3D NLA_U32, }, }; =20 /* Ops table for handshake */ @@ -35,7 +36,7 @@ static const struct genl_split_ops handshake_nl_ops[] =3D= { .cmd =3D HANDSHAKE_CMD_DONE, .doit =3D handshake_nl_done_doit, .policy =3D handshake_done_nl_policy, - .maxattr =3D HANDSHAKE_A_DONE_REMOTE_AUTH, + .maxattr =3D HANDSHAKE_A_DONE_SESSION_ID, .flags =3D GENL_CMD_CAP_DO, }, }; diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c index 081093dfd553..85c5fed690c0 100644 --- a/net/handshake/tlshd.c +++ b/net/handshake/tlshd.c @@ -26,7 +26,8 @@ =20 struct tls_handshake_req { void (*th_consumer_done)(void *data, int status, - key_serial_t peerid); + key_serial_t peerid, + key_serial_t handshake_session_id); void *th_consumer_data; =20 int th_type; @@ -39,6 +40,8 @@ struct tls_handshake_req { =20 unsigned int th_num_peerids; key_serial_t th_peerid[5]; + + key_serial_t handshake_session_id; }; =20 static struct tls_handshake_req * @@ -55,6 +58,7 @@ tls_handshake_req_init(struct handshake_req *req, treq->th_num_peerids =3D 0; treq->th_certificate =3D TLS_NO_CERT; treq->th_privkey =3D TLS_NO_PRIVKEY; + treq->handshake_session_id =3D TLS_NO_PRIVKEY; return treq; } =20 @@ -83,6 +87,13 @@ static void tls_handshake_remote_peerids(struct tls_hand= shake_req *treq, if (i >=3D treq->th_num_peerids) break; } + + nla_for_each_attr(nla, head, len, rem) { + if (nla_type(nla) =3D=3D HANDSHAKE_A_DONE_SESSION_ID) { + treq->handshake_session_id =3D nla_get_u32(nla); + break; + } + } } =20 /** @@ -105,7 +116,7 @@ static void tls_handshake_done(struct handshake_req *re= q, set_bit(HANDSHAKE_F_REQ_SESSION, &req->hr_flags); =20 treq->th_consumer_done(treq->th_consumer_data, -status, - treq->th_peerid[0]); + treq->th_peerid[0], treq->handshake_session_id); } =20 #if IS_ENABLED(CONFIG_KEYS) diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 7b90abc5cf0e..2401b4c757f6 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -444,13 +444,15 @@ static void svc_tcp_kill_temp_xprt(struct svc_xprt *x= prt) * @data: address of xprt to wake * @status: status of handshake * @peerid: serial number of key containing the remote peer's identity + * @handshake_session_id: serial number of the userspace session ID * * If a security policy is specified as an export option, we don't * have a specific export here to check. So we set a "TLS session * is present" flag on the xprt and let an upper layer enforce local * security policy. */ -static void svc_tcp_handshake_done(void *data, int status, key_serial_t pe= erid) +static void svc_tcp_handshake_done(void *data, int status, key_serial_t pe= erid, + key_serial_t handshake_session_id) { struct svc_xprt *xprt =3D data; struct svc_sock *svsk =3D container_of(xprt, struct svc_sock, sk_xprt); diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 3aa987e7f072..5c6e7543f293 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -2589,9 +2589,11 @@ static int xs_tcp_tls_finish_connecting(struct rpc_x= prt *lower_xprt, * @data: address of xprt to wake * @status: status of handshake * @peerid: serial number of key containing the remote's identity + * @handshake_session_id: serial number of the userspace session ID * */ -static void xs_tls_handshake_done(void *data, int status, key_serial_t pee= rid) +static void xs_tls_handshake_done(void *data, int status, key_serial_t pee= rid, + key_serial_t handshake_session_id) { struct rpc_xprt *lower_xprt =3D data; struct sock_xprt *lower_transport =3D --=20 2.51.1 From nobody Mon Feb 9 07:57:35 2026 Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 431822D9798 for ; Wed, 12 Nov 2025 04:28:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921700; cv=none; b=SGdp6ep7sO5YUqBC8JHgeRreRQLCSijb0wW7/JDUphAjHUtEuajUF86n3lHSZnnBMaoWxeVag76NsaSE7Y017x1lL4IclXgv8NbAgAC0TTnZKeh8y3cjni+hzqrq+3+vAj+MGxxDf38uhzH3M4sUepiIRFNMUo0TYn3uIv8nBAE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921700; c=relaxed/simple; bh=jaHChIsFwQccM67eVRPs/t3TxiMgA+k62NpjHrap2Rg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BF7zl94VsOzAFM/q82LMxlYdpTYhiRHumBRiL6xzw7CFOdEo+qwpT1LybgstRiAGoHGENr7Ji6+/Oi5/44xGIqwNaGQgzAd5GwwhVmViZWVadG3WdvcqV47HpE2qM1aip63OFVl7cpgphzBLPrWlikx5meguksWpzsettmg0vhk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=HoE6Xg4Y; arc=none smtp.client-ip=209.85.216.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HoE6Xg4Y" Received: by mail-pj1-f47.google.com with SMTP id 98e67ed59e1d1-343774bd9b4so362334a91.2 for ; Tue, 11 Nov 2025 20:28:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762921698; x=1763526498; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TfXE4RQsTo13oDtpS18/YqY50MP5ENyfIi78Z5opJm4=; b=HoE6Xg4YO3Umx5sJsEPhcNawAdjSYIbUpnrsed1+S0199rZk+FR1EoJ05G27zsSV1D UyShQv71scLUb6Vc9VZnQ4PA+aHxA8KOThr75eQAWCOfVsclvUyRnocbyLKQaION8e5i ugAw7DAisys+tRTUtRAZiFOWw2ebJSalNIYMUFgl81u9aMO6LnHJShoHh+a9MfKYhjNb /zq349rCkoAYeqx5jm4W1nZyNKhaMYEuIe7L9mjwiMWYNWT8VaTaLM5eeSDmk6ao3rHP 5x8STq0+j7NmQOMOcRQsO/2zHwuq4CKefPlQ9zoasrzvYbna+nSTVgE6ExVuc7KNb7cX xgCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762921698; x=1763526498; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=TfXE4RQsTo13oDtpS18/YqY50MP5ENyfIi78Z5opJm4=; b=Bk8uRcUz362MLiHpso69qcI1A1Z5HM5V86dQHYTlz0PI+Hy5C3RMis4YEhDUCQNheY AT/rRXL3J5WNXp5cXGMjDMWIIAoMI0w7lwAsp4GtE+lTpyPKkfdGvRNdr574hLREBViE orxKJEUTWgA8jixikyPxgEp8sCqe9BBPcNfNiJr4dOriKqsujil0u+5tX22JPSLyTIQv TpoSTWvF0egvbntr4xOaBUTJblypPVzYce4HXQZxfQ4Dc6wIVC6TZs0p+F+WlaplTZ9M 5Uo4uE1GhNkZigMMvq0D/sCf1eEwbcwQiLwHwDcVdqGdej53shophCxlkm7Uyt2rdBgr JwbA== X-Forwarded-Encrypted: i=1; AJvYcCVFXLHLAAlB3DxYoiv3grndG/HuW76xgWokBfniSXecvsjE4pMyEhkyQN/MO6yE2udgMBYgvT2ZT8CVpxA=@vger.kernel.org X-Gm-Message-State: AOJu0YzHBdE4mLeWXkuwt6u3RMkvzCLQu+N+u4XvZQCb6HHHC+13vsrE tKobCEUohxgAOdri77OilIYgcnOindqdBKGgA6ed33JMZdNObeyBWEuYREm3IA== X-Gm-Gg: ASbGncsdoSa7g0BRZTXIj5kP7rf7VHUNug2YIrwF9onjSU3TFFt8+EMllLf4rFpaNRZ AZy4UluMTLu7QUvp1sthvzi3nz23+O78lkbVDqF60IxsGvaA3Wuw0/mffvXVRmXpf/H567MaCSj wtdqKCaGpOlSVTm25MECv4rP3qy+bDyuKGY8s36EYy9Kg5+s0sQbi8I+7T6tfXpNr7D3kLZ29lZ 2xPqx+tmWJFsvEoIF/OyLjGgi5rOrxQGShiU5qWHkFrIF69NANd34g7/yA/EwYUzxHKQSr3G7xB 1w+ntjmaEBJIXVV7XeheORSisjjH9LagG40QfXTCrDxzjC0WRfxzK4shdkbY8yBQa8qDzS4cPmY v937Ww5wbRKSBkDPzb59BqA3PCyfdzSuwNG5d794Corm3zqB0xtrYrObVkwa9RTlgorKhUxIJZY 1De+BPKXYhmOEWVCFYA/CHuw50nb0W0EN7JYCnMQemHiWHXeswjWUd/EN1Cf1wyGDLTrAtXSGjx svIaWEzAA== X-Google-Smtp-Source: AGHT+IGasMEo2f3YSuRreEs/8zog7GQY45X0or6PmRJCkVtaVHjxXqWGnHYHC3SejrjGvw9vVcyiWQ== X-Received: by 2002:a17:90a:fc50:b0:343:a631:28a8 with SMTP id 98e67ed59e1d1-343dded5123mr2073086a91.37.1762921698484; Tue, 11 Nov 2025 20:28:18 -0800 (PST) Received: from toolbx.alistair23.me (2403-580b-97e8-0-82ce-f179-8a79-69f4.ip6.aussiebb.net. [2403:580b:97e8:0:82ce:f179:8a79:69f4]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-343e06fbc0dsm854681a91.2.2025.11.11.20.28.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Nov 2025 20:28:18 -0800 (PST) From: alistair23@gmail.com X-Google-Original-From: alistair.francis@wdc.com To: chuck.lever@oracle.com, hare@kernel.org, kernel-tls-handshake@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nvme@lists.infradead.org, linux-nfs@vger.kernel.org Cc: kbusch@kernel.org, axboe@kernel.dk, hch@lst.de, sagi@grimberg.me, kch@nvidia.com, hare@suse.de, alistair23@gmail.com, Alistair Francis Subject: [PATCH v5 2/6] net/handshake: Define handshake_sk_destruct_req Date: Wed, 12 Nov 2025 14:27:16 +1000 Message-ID: <20251112042720.3695972-3-alistair.francis@wdc.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251112042720.3695972-1-alistair.francis@wdc.com> References: <20251112042720.3695972-1-alistair.francis@wdc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alistair Francis Define a `handshake_sk_destruct_req()` function to allow the destruction of the handshake req. This is required to avoid hash conflicts when handshake_req_hash_add() is called as part of submitting the KeyUpdate request. Signed-off-by: Alistair Francis Reviewed-by: Hannes Reinecke --- v5: - No change v4: - No change v3: - New patch net/handshake/request.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/net/handshake/request.c b/net/handshake/request.c index 274d2c89b6b2..0d1c91c80478 100644 --- a/net/handshake/request.c +++ b/net/handshake/request.c @@ -98,6 +98,22 @@ static void handshake_sk_destruct(struct sock *sk) sk_destruct(sk); } =20 +/** + * handshake_sk_destruct_req - destroy an existing request + * @sk: socket on which there is an existing request + */ +static void handshake_sk_destruct_req(struct sock *sk) +{ + struct handshake_req *req; + + req =3D handshake_req_hash_lookup(sk); + if (!req) + return; + + trace_handshake_destruct(sock_net(sk), req, sk); + handshake_req_destroy(req); +} + /** * handshake_req_alloc - Allocate a handshake request * @proto: security protocol --=20 2.51.1 From nobody Mon Feb 9 07:57:35 2026 Received: from mail-pj1-f52.google.com (mail-pj1-f52.google.com [209.85.216.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23D672D7397 for ; Wed, 12 Nov 2025 04:28:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921706; cv=none; b=BH3p2WP+tJTgN94ldF+Fy6tBuUV6jKcWYHn//3uLVgdkTm3CZxBInRuTGAFdAv5WF4OhPQCh5sNebDecpfcVxWIJ9iDaYsEejR4sis/J05nSo+gKioU0qFDLPizZNoysITy2Enb/pm0UJX/utou5UU5BPJIVEZ4mihHmsc+U8i4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921706; c=relaxed/simple; bh=zP/NG7w1+KArs879n8cQJzWDunWwyIPS5O4paM2aWv4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VBplq8p6Utj/LleCXt58VQEjNYPMdD+1jzosXZE/qvDpj4G1cWgfC1tUvcf1PT/ksWV9slrPrP+qPJqyGNnndB74b2OvN70kKXxMUUHSS7KDBZmuf1xJCTANJasB7PQDIT6k+DebxdANqLpW3FMQgAjUi4GaXlSL50Kui3/9ATg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MnioBE+9; arc=none smtp.client-ip=209.85.216.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MnioBE+9" Received: by mail-pj1-f52.google.com with SMTP id 98e67ed59e1d1-3437af8444cso375143a91.2 for ; Tue, 11 Nov 2025 20:28:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762921704; x=1763526504; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zkGiIciWDidvQkbZlkaOibwVplEAw58SDT70kiDe31U=; b=MnioBE+9RluMS451pD6BCq/wgG9AjNRfLpn3OOC6f+TMcIvVk0/QKxcdwKXZ5j7RKz IXGk9ZbS6MQqb9+Q81yvkIDMcbyhlvmJ02GAISA3RgQEnsK2hwieOmHZ7PrHm69r2btP yXEfqYVr75TfX3tmLmgKCecYybtptcijEuAJSv6IqQht7VDsqfO3cRwzoepmlQOLABf+ +ZhOBP9Vh5VakngdMhP1UU/Cl7dkDRWmY30DOJNsNoaUSBYebRGgVB7iLLQL+hvtsYW0 sf+PRnXJpRZ5XKtr1Vcdchvbs4fQVAzOBCj13NbgEzR9m3buyp6iuyW2IJqEA2t/2e9Z Y5lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762921704; x=1763526504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=zkGiIciWDidvQkbZlkaOibwVplEAw58SDT70kiDe31U=; b=esLz07GMbM5mGhWevk2mCLdWuxRqNu4ZnqDhCmNdfwHOW0hfA16EE0oAWdTX1c/qmc hjUmnpIrrq9yR7X2g7txg3RU/zfvLe6zNeeEZSJoKkKhTDVMdUtreIcEXF7Sr1mRpeOL FBwleskBuGaz9tIBGPjLrzzKefEZxVE46/F7+LDUsl44Bn8jLibZCQ4UVaHPFQniHKg3 asT6/abl3dWvQQ3z7tPsHuXYwWc88QrWzO1hklraCzNXw71EV8nrChutThW/toymQ2SM 1LdZHDcyPapaLsiTVm5SJSw3j9hodH/JBQTwZZTJOmJ6RIN0dt+Eu+ss8Y7I7pONkHXM pr2Q== X-Forwarded-Encrypted: i=1; AJvYcCVDY9NGy40bXBegA7cXFvqtP6DPE4XOIr0GaGFGdg6FJNjlXutQE+ii6odFF9i92fnf6CcboxzqRjdyikM=@vger.kernel.org X-Gm-Message-State: AOJu0YyrCrxY52+DmBe06mvGzccWXivG+cuA99TRqHhWqdGOZWD5TnXe +eGHjhX+m7WqCfZ0CF+KPTyCpBjy3+qPPjBc7tjKfc2wXeOFqW7PJbL4 X-Gm-Gg: ASbGncvzOxVLxIlvY+yUh6KardpayDWua1urkXcJ72Bi32rEQgxteWMhbgjtrpl7tUJ 0zHARQ9i9p6EfZ1Zg1gShYWFNV8VZg56UUDHFQcUKD8e0pwd00V/uK40JEDuGPwFXQaaQwEmHxl EOJcckBzhmXgtkM9EDnoTFKqn+GiQ8is9EQTbz/uli0fC84KaId6PD+mNXh2eDis7k1HNR0oqAq yF78jeD5LaNNwNiO9DQTJ4PUMwaRUU7Urqc7JWRDQX2YPzlB0aBz9B6xqnIXlv4oLH/FIithprG rsEEMfz2qeCOR4PenbZqB04/rocR+iMqLbHwBvYLTsx2/W2h5Y8KnB2a0IGgBjjKnKxDqs6wN95 Bx0QY4zFIQT9LrFUkZQieNQ2NrS4lGaGDBbBLTvZZ5l7A7NS01X1NK31lTwbBPeOGyI13fXYgHL GLdCX+CLt/JvbnGY0lGeBSwxX37tlleN3kSoKh3sX69YltF7JlfEGPHM6/7F0Of9VxEmHmyxnyU vCfYumKXA== X-Google-Smtp-Source: AGHT+IFz599JMY+HbLZlN+Y4HCQji4lI/mnZmgyLfcZAZDfwLpsK/Yd65k0yw0c8AJv/WsCEFQFd3Q== X-Received: by 2002:a17:90b:4b89:b0:341:8b2b:43c with SMTP id 98e67ed59e1d1-343dde81845mr1915818a91.18.1762921704526; Tue, 11 Nov 2025 20:28:24 -0800 (PST) Received: from toolbx.alistair23.me (2403-580b-97e8-0-82ce-f179-8a79-69f4.ip6.aussiebb.net. [2403:580b:97e8:0:82ce:f179:8a79:69f4]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-343e06fbc0dsm854681a91.2.2025.11.11.20.28.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Nov 2025 20:28:24 -0800 (PST) From: alistair23@gmail.com X-Google-Original-From: alistair.francis@wdc.com To: chuck.lever@oracle.com, hare@kernel.org, kernel-tls-handshake@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nvme@lists.infradead.org, linux-nfs@vger.kernel.org Cc: kbusch@kernel.org, axboe@kernel.dk, hch@lst.de, sagi@grimberg.me, kch@nvidia.com, hare@suse.de, alistair23@gmail.com, Alistair Francis Subject: [PATCH v5 3/6] net/handshake: Ensure the request is destructed on completion Date: Wed, 12 Nov 2025 14:27:17 +1000 Message-ID: <20251112042720.3695972-4-alistair.francis@wdc.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251112042720.3695972-1-alistair.francis@wdc.com> References: <20251112042720.3695972-1-alistair.francis@wdc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alistair Francis To avoid future handshake_req_hash_add() calls failing with EEXIST when performing a KeyUpdate let's make sure the old request is destructed as part of the completion. Until now a handshake would only be destroyed on a failure or when a sock is freed (via the sk_destruct function pointer). handshake_complete() is only called on errors, not a successful handshake so it doesn't remove the request. Signed-off-by: Alistair Francis Reviewed-by: Hannes Reinecke --- v5: - No change v4: - Improve description in commit message v3: - New patch net/handshake/request.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/handshake/request.c b/net/handshake/request.c index 0d1c91c80478..194725a8aaca 100644 --- a/net/handshake/request.c +++ b/net/handshake/request.c @@ -311,6 +311,8 @@ void handshake_complete(struct handshake_req *req, unsi= gned int status, /* Handshake request is no longer pending */ sock_put(sk); } + + handshake_sk_destruct_req(sk); } EXPORT_SYMBOL_IF_KUNIT(handshake_complete); =20 --=20 2.51.1 From nobody Mon Feb 9 07:57:35 2026 Received: from mail-pj1-f48.google.com (mail-pj1-f48.google.com [209.85.216.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7FB282D7397 for ; Wed, 12 Nov 2025 04:28:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921714; cv=none; b=jHWs12sPLbyVr7MneGk6fqRTqq4M/fdrOxKZNkQM308JezvFYjCDjMccFtk6v0+GExmhzrgKxtfvuLU0zUAtbSwBmdnnppZOJDO92NsaqnnwFMnPcDN/SZBJT3m8YJSGhTXoavYTE4CShazImQsbWnoW2R/Zoy3DqCCTw9BpxDQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921714; c=relaxed/simple; bh=CSNpcjZHL9pVJrnk1JfX7pOti7wT8d8rdC2TqemtXqw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MsmbD9WEi1BE9j1kI1XY7veqll4J88krDXVRjo3mbX2y8bD73+SfKCoYnNyQGzKe3h/6D7sAGe/qvXn68tcdI3X/xzNVhBLDgHduETOIsNMP/MjW3A9G3wY3vukXQyf5YTPlZn3CvYKrY6r3wJ2JiD+jvs5ofR/ZsfnhGwZutSQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ASML86Vl; arc=none smtp.client-ip=209.85.216.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ASML86Vl" Received: by mail-pj1-f48.google.com with SMTP id 98e67ed59e1d1-340bcc92c7dso277939a91.0 for ; Tue, 11 Nov 2025 20:28:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762921711; x=1763526511; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GwMH/feAbYG5hMxYbw3J+YyHR7bCjVFZQaW7MKJUtGI=; b=ASML86VlMk+jcqJMvq+4BtpDseLiZazSvyliNHObeeNmpdLKOG3is1x5pMT9Tylcef hmYMrsOR0SA8mnKxECIahuDvFlD5HoPkeJPmWF/MkR42ZLKw1qsg5kJ9qcVO2PuHzS85 3oJIc5Xk2W76tmHQikY4hWim3bDObvOfl/hzm2LLBM5ll6WZoAUNuamkDS8+4MhkL1Cp KYqGyEv4x4LPgX3h+ufHRX+VYCTDCPkQEGTeOGX5W6CrVbyU4KQz5oh9PsImCiC8VJsL W+GgXxf+SN/oSd92kRs3LuP5CZ5exJ5IMVcCQ601m1HUGL4rjJcPJaBltPS41Fp4jSnk 6t2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762921711; x=1763526511; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=GwMH/feAbYG5hMxYbw3J+YyHR7bCjVFZQaW7MKJUtGI=; b=I3h8SPLle/znvaXxHORDiLdykFZcYdkgbUP7g3n0k0Fa9cJBVQ9zyoUcvrn45Q6wvL +X57tK7oXKdceEMNfUi6MpF8oNDwuVbu2gnhHIM6fjXPZQn/mpztKpYwUqoBXRJSEQOu nGO0BhxnA6zM1yfJVE7ZLLZ9lxcTPdufPPlQke6YUcpqGPUprW83xt9h4bsdbr1KR+wm 0aczuqKs2vrpVE6NsnSkbbCdRWET8voKzcc7q3UCDtQzHKDSicrUBgW8cl89KQ6fwbVS CLyBCQxS0wlbzvoNqGF9+5KtHsILHbc7urT3pRnnUIRNwGploHstt5Jbg9Lhmxh4Jx5t nBTA== X-Forwarded-Encrypted: i=1; AJvYcCUOn4GqXeaU3tPn8fkHhQUGU4+Sfwb9dZ47+SdNt9yRQ1BKghR8BqJBKayPBPd+gvnSdETnTtMtjLZxtL0=@vger.kernel.org X-Gm-Message-State: AOJu0YwrO5gA+7HA4ePKv168rMeKt/ci6zsGo5ciXLtd2O4e1vawPagl /Rnkme8XNAYOjhxuL2WgO1QoT2ehuNpzez3gaFpsbxfmgV2CQ9UStmZ2 X-Gm-Gg: ASbGncta1Wqoypxn9sr34HOWr6jKHJNTCSyrF3EgZT82Ls67MdTMF9ZB6fCKjTFpF6d A/uKjd0YTgFv8NSFGl8+2ogjN5zA4RRG+9MJMtZot5o6GkST2YyFGL27+JMq8LZofi59SxmtkSX 4HJkt2s3qFUo/QOL1VGRimt3NJjVAblnneWn3M1zHECbOp+SjG/qRcRrX7AZxTr2EzwB5003lVg 7pdBgVZV9R6BqUayRVgbL6GVjA8RLSeALXGpwru0wmOVitGi0qjnFn2vFu2inuJCHuWBW+oKz2Q hY6YG7V7QrbUR1/gw+Nti+c+ggP/tHHMuc3LB8Ax0WBKt51k0D+yYYh1Anh01WY+7kEOoh0Hmof 5+BTr57a2VkQ+rgYOa3TJN7egAUqXrwL29HseVwFCR44IuNBm5dXzGwOlv+srHGbmsigTI8Xozp vea9+M/yThxPqnsCXZ5AVFGBYGxdFyDf6bHJah01kpZh5IJM13jBsf/Mn1/w8fd0ybIRnKGQ8M9 7aocWIJ3Q== X-Google-Smtp-Source: AGHT+IHLsvrCYQlNmzagnHaIUAwzof2318bAn+2sz/wwmJG5Nv1JCItAUXzYrY+80FssVU6l5G3G/g== X-Received: by 2002:a17:90b:3943:b0:343:78ed:8d19 with SMTP id 98e67ed59e1d1-343bf0bd417mr7600541a91.7.1762921710572; Tue, 11 Nov 2025 20:28:30 -0800 (PST) Received: from toolbx.alistair23.me (2403-580b-97e8-0-82ce-f179-8a79-69f4.ip6.aussiebb.net. [2403:580b:97e8:0:82ce:f179:8a79:69f4]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-343e06fbc0dsm854681a91.2.2025.11.11.20.28.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Nov 2025 20:28:30 -0800 (PST) From: alistair23@gmail.com X-Google-Original-From: alistair.francis@wdc.com To: chuck.lever@oracle.com, hare@kernel.org, kernel-tls-handshake@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nvme@lists.infradead.org, linux-nfs@vger.kernel.org Cc: kbusch@kernel.org, axboe@kernel.dk, hch@lst.de, sagi@grimberg.me, kch@nvidia.com, hare@suse.de, alistair23@gmail.com, Alistair Francis Subject: [PATCH v5 4/6] net/handshake: Support KeyUpdate message types Date: Wed, 12 Nov 2025 14:27:18 +1000 Message-ID: <20251112042720.3695972-5-alistair.francis@wdc.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251112042720.3695972-1-alistair.francis@wdc.com> References: <20251112042720.3695972-1-alistair.francis@wdc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alistair Francis When reporting the msg-type to userspace let's also support reporting KeyUpdate events. This supports reporting a client/server event and if the other side requested a KeyUpdateRequest. Link: https://datatracker.ietf.org/doc/html/rfc8446#section-4.6.3 Signed-off-by: Alistair Francis Reviewed-by: Chuck Lever Reviewed-by: Hannes Reinecke --- v5: - Drop clientkeyupdaterequest and serverkeyupdaterequest v4: - Don't overload existing functions, instead create new ones v3: - Fixup yamllint and kernel-doc failures Documentation/netlink/specs/handshake.yaml | 16 ++++- drivers/nvme/host/tcp.c | 15 +++- drivers/nvme/target/tcp.c | 10 ++- include/net/handshake.h | 6 ++ include/uapi/linux/handshake.h | 11 +++ net/handshake/tlshd.c | 83 +++++++++++++++++++++- 6 files changed, 133 insertions(+), 8 deletions(-) diff --git a/Documentation/netlink/specs/handshake.yaml b/Documentation/net= link/specs/handshake.yaml index a273bc74d26f..2f77216c8ddf 100644 --- a/Documentation/netlink/specs/handshake.yaml +++ b/Documentation/netlink/specs/handshake.yaml @@ -21,12 +21,18 @@ definitions: type: enum name: msg-type value-start: 0 - entries: [unspec, clienthello, serverhello] + entries: [unspec, clienthello, serverhello, clientkeyupdate, + serverkeyupdate] - type: enum name: auth value-start: 0 entries: [unspec, unauth, psk, x509] + - + type: enum + name: key-update-type + value-start: 0 + entries: [unspec, send, received, received_request_update] =20 attribute-sets: - @@ -74,6 +80,13 @@ attribute-sets: - name: keyring type: u32 + - + name: key-update-request + type: u32 + enum: key-update-type + - + name: session-id + type: u32 - name: done attributes: @@ -116,6 +129,7 @@ operations: - certificate - peername - keyring + - session-id - name: done doc: Handler reports handshake completion diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 024d02248831..4797a4532b0d 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -20,6 +20,7 @@ #include #include #include +#include =20 #include "nvme.h" #include "fabrics.h" @@ -206,6 +207,10 @@ static struct workqueue_struct *nvme_tcp_wq; static const struct blk_mq_ops nvme_tcp_mq_ops; static const struct blk_mq_ops nvme_tcp_admin_mq_ops; static int nvme_tcp_try_send(struct nvme_tcp_queue *queue); +static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl, + struct nvme_tcp_queue *queue, + key_serial_t pskid, + enum handshake_key_update_type keyupdate); =20 static inline struct nvme_tcp_ctrl *to_tcp_ctrl(struct nvme_ctrl *ctrl) { @@ -1729,7 +1734,8 @@ static void nvme_tcp_tls_done(void *data, int status,= key_serial_t pskid, =20 static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl, struct nvme_tcp_queue *queue, - key_serial_t pskid) + key_serial_t pskid, + enum handshake_key_update_type keyupdate) { int qid =3D nvme_tcp_queue_id(queue); int ret; @@ -1751,7 +1757,10 @@ static int nvme_tcp_start_tls(struct nvme_ctrl *nctr= l, args.ta_timeout_ms =3D tls_handshake_timeout * 1000; queue->tls_err =3D -EOPNOTSUPP; init_completion(&queue->tls_complete); - ret =3D tls_client_hello_psk(&args, GFP_KERNEL); + if (keyupdate =3D=3D HANDSHAKE_KEY_UPDATE_TYPE_UNSPEC) + ret =3D tls_client_hello_psk(&args, GFP_KERNEL); + else + ret =3D tls_client_keyupdate_psk(&args, GFP_KERNEL, keyupdate); if (ret) { dev_err(nctrl->device, "queue %d: failed to start TLS: %d\n", qid, ret); @@ -1901,7 +1910,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nct= rl, int qid, =20 /* If PSKs are configured try to start TLS */ if (nvme_tcp_tls_configured(nctrl) && pskid) { - ret =3D nvme_tcp_start_tls(nctrl, queue, pskid); + ret =3D nvme_tcp_start_tls(nctrl, queue, pskid, HANDSHAKE_KEY_UPDATE_TYP= E_UNSPEC); if (ret) goto err_init_connect; } diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 7f8516892359..818efdeccef1 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -1833,7 +1833,8 @@ static void nvmet_tcp_tls_handshake_timeout(struct wo= rk_struct *w) kref_put(&queue->kref, nvmet_tcp_release_queue); } =20 -static int nvmet_tcp_tls_handshake(struct nvmet_tcp_queue *queue) +static int nvmet_tcp_tls_handshake(struct nvmet_tcp_queue *queue, + enum handshake_key_update_type keyupdate) { int ret =3D -EOPNOTSUPP; struct tls_handshake_args args; @@ -1852,7 +1853,10 @@ static int nvmet_tcp_tls_handshake(struct nvmet_tcp_= queue *queue) args.ta_keyring =3D key_serial(queue->port->nport->keyring); args.ta_timeout_ms =3D tls_handshake_timeout * 1000; =20 - ret =3D tls_server_hello_psk(&args, GFP_KERNEL); + if (keyupdate =3D=3D HANDSHAKE_KEY_UPDATE_TYPE_UNSPEC) + ret =3D tls_server_hello_psk(&args, GFP_KERNEL); + else + ret =3D tls_server_keyupdate_psk(&args, GFP_KERNEL, keyupdate); if (ret) { kref_put(&queue->kref, nvmet_tcp_release_queue); pr_err("failed to start TLS, err=3D%d\n", ret); @@ -1934,7 +1938,7 @@ static void nvmet_tcp_alloc_queue(struct nvmet_tcp_po= rt *port, sk->sk_data_ready =3D port->data_ready; write_unlock_bh(&sk->sk_callback_lock); if (!nvmet_tcp_try_peek_pdu(queue)) { - if (!nvmet_tcp_tls_handshake(queue)) + if (!nvmet_tcp_tls_handshake(queue, HANDSHAKE_KEY_UPDATE_TYPE_UNSPEC)) return; /* TLS handshake failed, terminate the connection */ goto out_destroy_sq; diff --git a/include/net/handshake.h b/include/net/handshake.h index 68d7f89e431a..f5a249327bf6 100644 --- a/include/net/handshake.h +++ b/include/net/handshake.h @@ -10,6 +10,8 @@ #ifndef _NET_HANDSHAKE_H #define _NET_HANDSHAKE_H =20 +#include + enum { TLS_NO_KEYRING =3D 0, TLS_NO_PEERID =3D 0, @@ -38,8 +40,12 @@ struct tls_handshake_args { int tls_client_hello_anon(const struct tls_handshake_args *args, gfp_t fla= gs); int tls_client_hello_x509(const struct tls_handshake_args *args, gfp_t fla= gs); int tls_client_hello_psk(const struct tls_handshake_args *args, gfp_t flag= s); +int tls_client_keyupdate_psk(const struct tls_handshake_args *args, gfp_t = flags, + enum handshake_key_update_type keyupdate); int tls_server_hello_x509(const struct tls_handshake_args *args, gfp_t fla= gs); int tls_server_hello_psk(const struct tls_handshake_args *args, gfp_t flag= s); +int tls_server_keyupdate_psk(const struct tls_handshake_args *args, gfp_t = flags, + enum handshake_key_update_type keyupdate); =20 bool tls_handshake_cancel(struct sock *sk); void tls_handshake_close(struct socket *sock); diff --git a/include/uapi/linux/handshake.h b/include/uapi/linux/handshake.h index b68ffbaa5f31..483815a064f0 100644 --- a/include/uapi/linux/handshake.h +++ b/include/uapi/linux/handshake.h @@ -19,6 +19,8 @@ enum handshake_msg_type { HANDSHAKE_MSG_TYPE_UNSPEC, HANDSHAKE_MSG_TYPE_CLIENTHELLO, HANDSHAKE_MSG_TYPE_SERVERHELLO, + HANDSHAKE_MSG_TYPE_CLIENTKEYUPDATE, + HANDSHAKE_MSG_TYPE_SERVERKEYUPDATE, }; =20 enum handshake_auth { @@ -28,6 +30,13 @@ enum handshake_auth { HANDSHAKE_AUTH_X509, }; =20 +enum handshake_key_update_type { + HANDSHAKE_KEY_UPDATE_TYPE_UNSPEC, + HANDSHAKE_KEY_UPDATE_TYPE_SEND, + HANDSHAKE_KEY_UPDATE_TYPE_RECEIVED, + HANDSHAKE_KEY_UPDATE_TYPE_RECEIVED_REQUEST_UPDATE, +}; + enum { HANDSHAKE_A_X509_CERT =3D 1, HANDSHAKE_A_X509_PRIVKEY, @@ -46,6 +55,8 @@ enum { HANDSHAKE_A_ACCEPT_CERTIFICATE, HANDSHAKE_A_ACCEPT_PEERNAME, HANDSHAKE_A_ACCEPT_KEYRING, + HANDSHAKE_A_ACCEPT_KEY_UPDATE_REQUEST, + HANDSHAKE_A_ACCEPT_SESSION_ID, =20 __HANDSHAKE_A_ACCEPT_MAX, HANDSHAKE_A_ACCEPT_MAX =3D (__HANDSHAKE_A_ACCEPT_MAX - 1) diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c index 85c5fed690c0..91d2bb515b7d 100644 --- a/net/handshake/tlshd.c +++ b/net/handshake/tlshd.c @@ -41,6 +41,7 @@ struct tls_handshake_req { unsigned int th_num_peerids; key_serial_t th_peerid[5]; =20 + unsigned int th_key_update_request; key_serial_t handshake_session_id; }; =20 @@ -58,7 +59,8 @@ tls_handshake_req_init(struct handshake_req *req, treq->th_num_peerids =3D 0; treq->th_certificate =3D TLS_NO_CERT; treq->th_privkey =3D TLS_NO_PRIVKEY; - treq->handshake_session_id =3D TLS_NO_PRIVKEY; + treq->handshake_session_id =3D args->handshake_session_id; + return treq; } =20 @@ -265,6 +267,16 @@ static int tls_handshake_accept(struct handshake_req *= req, break; } =20 + ret =3D nla_put_u32(msg, HANDSHAKE_A_ACCEPT_SESSION_ID, + treq->handshake_session_id); + if (ret < 0) + goto out_cancel; + + ret =3D nla_put_u32(msg, HANDSHAKE_A_ACCEPT_KEY_UPDATE_REQUEST, + treq->th_key_update_request); + if (ret < 0) + goto out_cancel; + genlmsg_end(msg, hdr); return genlmsg_reply(msg, info); =20 @@ -372,6 +384,44 @@ int tls_client_hello_psk(const struct tls_handshake_ar= gs *args, gfp_t flags) } EXPORT_SYMBOL(tls_client_hello_psk); =20 +/** + * tls_client_keyupdate_psk - request a PSK-based TLS handshake on a socket + * @args: socket and handshake parameters for this request + * @flags: memory allocation control flags + * @keyupdate: specifies the type of KeyUpdate operation + * + * Return values: + * %0: Handshake request enqueue; ->done will be called when complete + * %-EINVAL: Wrong number of local peer IDs + * %-ESRCH: No user agent is available + * %-ENOMEM: Memory allocation failed + */ +int tls_client_keyupdate_psk(const struct tls_handshake_args *args, gfp_t = flags, + enum handshake_key_update_type keyupdate) +{ + struct tls_handshake_req *treq; + struct handshake_req *req; + unsigned int i; + + if (!args->ta_num_peerids || + args->ta_num_peerids > ARRAY_SIZE(treq->th_peerid)) + return -EINVAL; + + req =3D handshake_req_alloc(&tls_handshake_proto, flags); + if (!req) + return -ENOMEM; + treq =3D tls_handshake_req_init(req, args); + treq->th_type =3D HANDSHAKE_MSG_TYPE_CLIENTKEYUPDATE; + treq->th_key_update_request =3D keyupdate; + treq->th_auth_mode =3D HANDSHAKE_AUTH_PSK; + treq->th_num_peerids =3D args->ta_num_peerids; + for (i =3D 0; i < args->ta_num_peerids; i++) + treq->th_peerid[i] =3D args->ta_my_peerids[i]; + + return handshake_req_submit(args->ta_sock, req, flags); +} +EXPORT_SYMBOL(tls_client_keyupdate_psk); + /** * tls_server_hello_x509 - request a server TLS handshake on a socket * @args: socket and handshake parameters for this request @@ -428,6 +478,37 @@ int tls_server_hello_psk(const struct tls_handshake_ar= gs *args, gfp_t flags) } EXPORT_SYMBOL(tls_server_hello_psk); =20 +/** + * tls_server_keyupdate_psk - request a server TLS KeyUpdate on a socket + * @args: socket and handshake parameters for this request + * @flags: memory allocation control flags + * @keyupdate: specifies the type of KeyUpdate operation + * + * Return values: + * %0: Handshake request enqueue; ->done will be called when complete + * %-ESRCH: No user agent is available + * %-ENOMEM: Memory allocation failed + */ +int tls_server_keyupdate_psk(const struct tls_handshake_args *args, gfp_t = flags, + enum handshake_key_update_type keyupdate) +{ + struct tls_handshake_req *treq; + struct handshake_req *req; + + req =3D handshake_req_alloc(&tls_handshake_proto, flags); + if (!req) + return -ENOMEM; + treq =3D tls_handshake_req_init(req, args); + treq->th_type =3D HANDSHAKE_MSG_TYPE_SERVERKEYUPDATE; + treq->th_key_update_request =3D keyupdate; + treq->th_auth_mode =3D HANDSHAKE_AUTH_PSK; + treq->th_num_peerids =3D 1; + treq->th_peerid[0] =3D args->ta_my_peerids[0]; + + return handshake_req_submit(args->ta_sock, req, flags); +} +EXPORT_SYMBOL(tls_server_keyupdate_psk); + /** * tls_handshake_cancel - cancel a pending handshake * @sk: socket on which there is an ongoing handshake --=20 2.51.1 From nobody Mon Feb 9 07:57:35 2026 Received: from mail-pj1-f42.google.com (mail-pj1-f42.google.com [209.85.216.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 438A72D8763 for ; Wed, 12 Nov 2025 04:28:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921719; cv=none; b=YSuvmNSsNjldSPfyxYNTTnAI/MGrlnRA2rQtiIrKsdJF1NhdJby+FnxdM3sFfTDWcAktY0sBrdT6Gt60zWIfJ22YwmbS6+TpI5IljxPpqDO6itWuAfqQOd9KlJgEm7LHfFBX5G1aqnKajPPq0+Tv+XiqI007MZQ5xLuhhSUWURg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921719; c=relaxed/simple; bh=WzzlpcIVvJDG08mn5WxWf9o+FOGQQrSDl+xHVjEaO58=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I5iyaPg33024x9zasWeWxV+87ZfCWLMn074gA+DVQa8I8iXo85PRLyZ7LqrjUcazl9DhGDH0v8uA6jPHYUKZL1htTLOAivAqcLnWx7Cf+jKFj0pIgMzYKHU2BeJmF8daw5LRBNVAbzK9On9cDjH6tR7zcuBDnpu/Yy13/mnV37c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=UnwK0ba/; arc=none smtp.client-ip=209.85.216.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UnwK0ba/" Received: by mail-pj1-f42.google.com with SMTP id 98e67ed59e1d1-3436a97f092so502171a91.3 for ; Tue, 11 Nov 2025 20:28:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762921717; x=1763526517; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=M80qUNZc1XHsNmFVJZkZr4sttr+ksd9CwMk6Xp4mOs8=; b=UnwK0ba/VuAiUssExLelCzLrUMui+9N3HcqmvUdEflLvmXcEuREhJ2XysvsyNSXi79 1eAlmtNOjOoBEOXLnVelxJPZKKzCjVMJpxTZjU/R5iYAK9EPPCvXF/6W3GBS2CH5uFfu xAl2gnpiEBl014IX21UmahMMGcb30jz03AWdBI60HZdYTZVoIZrX5GxqV8aHlQdUPIug PxJLOj83Jh0yLwz+GW8Vdg/y3uYCt7ZYdvn3QI0SM1+0uFw7RoSJivajxesbXT00JZPD FMhd7lS7KMIc7wtADd8O22qwRYIPMfy0MtwUoae5/d6Jcu/WcHW7OI5boUTT9TqjCj3v c6TA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762921717; x=1763526517; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=M80qUNZc1XHsNmFVJZkZr4sttr+ksd9CwMk6Xp4mOs8=; b=gVMLIuA0+hUOwPTOKWexxda3tupvDDzXtJa7YRNc8ZRoaAYkXGcp1U0lqcZJM7fksG y7EVRDsoYNG/3Q8IswrzyLRV30jCMFbZVRbRauR8ZNYjW3lFrK5Bhcar5KIU9oGzeGmH erjM6px/uaJRwMiAJ3tqMf6FmKDgEb+8KLADlP9jxJJhKuj4vVKGMjdP7e3fE70eNmNk 2PzAa4xTCk9AWoFMsX7ZC7Mw4k1+Z8qMpccV7HjvIBMVQKdeFLlZHXWU/kNQ4Gvh7d/N pqzYN4kX7MJwSB8BtE7RhoE3l4iRcltQFBmAAaRJDlTv9ELhStdND/pqNfeudVZRczMl a10w== X-Forwarded-Encrypted: i=1; AJvYcCVeRAKbHoyvOofkIQHKsZln49NUI7/CcROzCP+MTIepar/iSnwgSegsP8A1Y1kfg5PLsgJ/ztnzbAorsPE=@vger.kernel.org X-Gm-Message-State: AOJu0Yy8jclhen6oMdTa9xRn+sVTnaT0a61F6LLNsEBBPaoOfwWA+v6Y xKfeYN0bHQWKc4o1hvvJ0Ff3dWP2xJn2a+pEYmwiWN1gjt2XR60pNiUG X-Gm-Gg: ASbGncveVdIkupGMwupiJrIMQFlAPtShL4GoTosCk7Fn73Ru8tAnDWRglivIgHSJs+j lbTrwEU01eIWllT9pBPswpeasR5X+6mPXHtkDswVBBNGbq3TUN7OHM7IZNN0KzQfxHErmCpR56A 5uDy71zqZ1ZFCbbBNdKf7Qg5kjuh+ee1YhoUTNEsmck8bRZs/ti3A6cserwQo9Xi4ikv57JZ88R OPDMNJguDBz1f2s9bJtb5uIq8X9+fjcUUUuAxUKOYVFcjDV4VdzAr9DlWyKc7HyfY5KQnjWrXCO 7Grtayljo4AHyaqdorILMyzgEXsS3/HxCZlvHB4BSDsdUHsj83YKBKVt5UwQmhuvN59x3WY7QBT RGhnLMF/nrqF87qopbggWEevgXx2+XEr/A0MuHy8jd2ZU5mlPYJQgsmTHioaIO0APzw/IIDEr+q AqV0+3B+aUGcqhrLBsBBsvVrftg+Zs0HlTSEdCkhoXt6Qs9gMfI28rxQS9I27Cq8yczyA3ntza8 1Myh8RYvRN8PSmFigZV X-Google-Smtp-Source: AGHT+IH+yGIMkP+5jLWuv7dmVXtMrTOjJ9if6zSq3lOjXH0ncDd2BGvxBgxvOWF7qaIpKkGatI+aRA== X-Received: by 2002:a17:90b:4c44:b0:32b:65e6:ec48 with SMTP id 98e67ed59e1d1-343dde0d055mr2061728a91.8.1762921716677; Tue, 11 Nov 2025 20:28:36 -0800 (PST) Received: from toolbx.alistair23.me (2403-580b-97e8-0-82ce-f179-8a79-69f4.ip6.aussiebb.net. [2403:580b:97e8:0:82ce:f179:8a79:69f4]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-343e06fbc0dsm854681a91.2.2025.11.11.20.28.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Nov 2025 20:28:36 -0800 (PST) From: alistair23@gmail.com X-Google-Original-From: alistair.francis@wdc.com To: chuck.lever@oracle.com, hare@kernel.org, kernel-tls-handshake@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nvme@lists.infradead.org, linux-nfs@vger.kernel.org Cc: kbusch@kernel.org, axboe@kernel.dk, hch@lst.de, sagi@grimberg.me, kch@nvidia.com, hare@suse.de, alistair23@gmail.com, Alistair Francis Subject: [PATCH v5 5/6] nvme-tcp: Support KeyUpdate Date: Wed, 12 Nov 2025 14:27:19 +1000 Message-ID: <20251112042720.3695972-6-alistair.francis@wdc.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251112042720.3695972-1-alistair.francis@wdc.com> References: <20251112042720.3695972-1-alistair.francis@wdc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alistair Francis If the nvme_tcp_try_send() or nvme_tcp_try_recv() functions return EKEYEXPIRED then the underlying TLS keys need to be updated. This occurs on an KeyUpdate event as described in RFC8446 https://datatracker.ietf.org/doc/html/rfc8446#section-4.6.3. If the NVMe Target (TLS server) initiates a KeyUpdate this patch will allow the NVMe layer to process the KeyUpdate request and forward the request to userspace. Userspace must then update the key to keep the connection alive. This patch allows us to handle the NVMe target sending a KeyUpdate request without aborting the connection. At this time we don't support initiating a KeyUpdate. Signed-off-by: Alistair Francis Reviewed-by: Hannes Reinecke --- v5: - Cleanup code flow - Check for MSG_CTRUNC in the msg_flags return from recvmsg and use that to determine if it's a control message v4: - Remove all support for initiating KeyUpdate - Don't call cancel_work() when updating keys v3: - Don't cancel existing handshake requests v2: - Don't change the state - Use a helper function for KeyUpdates - Continue sending in nvme_tcp_send_all() after a KeyUpdate - Remove command message using recvmsg drivers/nvme/host/tcp.c | 85 +++++++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 15 deletions(-) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 4797a4532b0d..5cec5a974bbf 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -172,6 +172,7 @@ struct nvme_tcp_queue { bool tls_enabled; u32 rcv_crc; u32 snd_crc; + key_serial_t handshake_session_id; __le32 exp_ddgst; __le32 recv_ddgst; struct completion tls_complete; @@ -858,7 +859,10 @@ static void nvme_tcp_handle_c2h_term(struct nvme_tcp_q= ueue *queue, static int nvme_tcp_recvmsg_pdu(struct nvme_tcp_queue *queue) { char *pdu =3D queue->pdu; + char cbuf[CMSG_LEN(sizeof(char))] =3D {}; struct msghdr msg =3D { + .msg_control =3D cbuf, + .msg_controllen =3D sizeof(cbuf), .msg_flags =3D MSG_DONTWAIT, }; struct kvec iov =3D { @@ -873,12 +877,17 @@ static int nvme_tcp_recvmsg_pdu(struct nvme_tcp_queue= *queue) if (ret <=3D 0) return ret; =20 + hdr =3D queue->pdu; + if (hdr->type =3D=3D TLS_HANDSHAKE_KEYUPDATE) { + dev_err(queue->ctrl->ctrl.device, "KeyUpdate message\n"); + return 1; + } + queue->pdu_remaining -=3D ret; queue->pdu_offset +=3D ret; if (queue->pdu_remaining) return 0; =20 - hdr =3D queue->pdu; if (unlikely(hdr->hlen !=3D sizeof(struct nvme_tcp_rsp_pdu))) { if (!nvme_tcp_recv_pdu_supported(hdr->type)) goto unsupported_pdu; @@ -944,6 +953,7 @@ static int nvme_tcp_recvmsg_data(struct nvme_tcp_queue = *queue) struct request *rq =3D nvme_cid_to_rq(nvme_tcp_tagset(queue), pdu->command_id); struct nvme_tcp_request *req =3D blk_mq_rq_to_pdu(rq); + char cbuf[CMSG_LEN(sizeof(char))] =3D {}; =20 if (nvme_tcp_recv_state(queue) !=3D NVME_TCP_RECV_DATA) return 0; @@ -976,10 +986,26 @@ static int nvme_tcp_recvmsg_data(struct nvme_tcp_queu= e *queue) =20 ret =3D sock_recvmsg(queue->sock, &msg, msg.msg_flags); if (ret < 0) { - dev_err(queue->ctrl->ctrl.device, - "queue %d failed to receive request %#x data", - nvme_tcp_queue_id(queue), rq->tag); - return ret; + /* If MSG_CTRUNC is set, it's a control message, + * so let's read the control message. + */ + if (msg.msg_flags & MSG_CTRUNC) { + memset(&msg, 0, sizeof(msg)); + msg.msg_flags =3D MSG_DONTWAIT; + msg.msg_control =3D cbuf; + msg.msg_controllen =3D sizeof(cbuf); + + ret =3D sock_recvmsg(queue->sock, &msg, msg.msg_flags); + } + + if (ret < 0) { + dev_dbg(queue->ctrl->ctrl.device, + "queue %d failed to receive request %#x data, %d", + nvme_tcp_queue_id(queue), rq->tag, ret); + return ret; + } + + return 0; } if (queue->data_digest) nvme_tcp_ddgst_calc(req, &queue->rcv_crc, ret); @@ -1384,15 +1410,39 @@ static int nvme_tcp_try_recvmsg(struct nvme_tcp_que= ue *queue) } } while (result >=3D 0); =20 - if (result < 0 && result !=3D -EAGAIN) { - dev_err(queue->ctrl->ctrl.device, - "receive failed: %d\n", result); - queue->rd_enabled =3D false; - nvme_tcp_error_recovery(&queue->ctrl->ctrl); - } else if (result =3D=3D -EAGAIN) - result =3D 0; + if (result < 0) { + if (result !=3D -EKEYEXPIRED && result !=3D -EAGAIN) { + dev_err(queue->ctrl->ctrl.device, + "receive failed: %d\n", result); + queue->rd_enabled =3D false; + nvme_tcp_error_recovery(&queue->ctrl->ctrl); + } + return result; + } + + queue->nr_cqe =3D nr_cqe; + return nr_cqe; +} + +static void update_tls_keys(struct nvme_tcp_queue *queue) +{ + int qid =3D nvme_tcp_queue_id(queue); + int ret; + + dev_dbg(queue->ctrl->ctrl.device, + "updating key for queue %d\n", qid); =20 - return result < 0 ? result : (queue->nr_cqe =3D nr_cqe); + flush_work(&(queue->ctrl->ctrl).async_event_work); + + ret =3D nvme_tcp_start_tls(&(queue->ctrl->ctrl), + queue, queue->ctrl->ctrl.tls_pskid, + HANDSHAKE_KEY_UPDATE_TYPE_RECEIVED); + + if (ret < 0) { + dev_err(queue->ctrl->ctrl.device, + "failed to update the keys %d\n", ret); + nvme_tcp_fail_request(queue->request); + } } =20 static void nvme_tcp_io_work(struct work_struct *w) @@ -1417,8 +1467,11 @@ static void nvme_tcp_io_work(struct work_struct *w) result =3D nvme_tcp_try_recvmsg(queue); if (result > 0) pending =3D true; - else if (unlikely(result < 0)) - return; + else if (unlikely(result < 0)) { + if (result =3D=3D -EKEYEXPIRED) + update_tls_keys(queue); + break; + } =20 /* did we get some space after spending time in recv? */ if (nvme_tcp_queue_has_pending(queue) && @@ -1726,6 +1779,7 @@ static void nvme_tcp_tls_done(void *data, int status,= key_serial_t pskid, ctrl->ctrl.tls_pskid =3D key_serial(tls_key); key_put(tls_key); queue->tls_err =3D 0; + queue->handshake_session_id =3D handshake_session_id; } =20 out_complete: @@ -1755,6 +1809,7 @@ static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl, keyring =3D key_serial(nctrl->opts->keyring); args.ta_keyring =3D keyring; args.ta_timeout_ms =3D tls_handshake_timeout * 1000; + args.handshake_session_id =3D queue->handshake_session_id; queue->tls_err =3D -EOPNOTSUPP; init_completion(&queue->tls_complete); if (keyupdate =3D=3D HANDSHAKE_KEY_UPDATE_TYPE_UNSPEC) --=20 2.51.1 From nobody Mon Feb 9 07:57:35 2026 Received: from mail-pj1-f48.google.com (mail-pj1-f48.google.com [209.85.216.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7B9B42E613A for ; Wed, 12 Nov 2025 04:28:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921725; cv=none; b=ibqOGHJWgnpx46+t6jE7IIZS5vWvCPHcGum9GfMkkeUySPT9szaupjrN8NtMJORPh/CQPT/9/ln/Z2Mkh7+Wjdbck0/HRoRbXIvtLRUD8NE2VPJYdTXp6YgAg4KVeOHax8CXNmWnVS/iZS7Rl2hqy5bIikQ8GXY/F7Mx36A/R8M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762921725; c=relaxed/simple; bh=jCDpx8M8k0FKY4eSBRvHYTTF69BLGw4kLu44e9Ryamc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UZIq3AnzJsrQOlvCV/h5by+hneuEJKF8HnCP8EfXkY1DUcAkNspcZw/DzBFb7LlbHh0V9k5a3jdiRr1AbItm2sEslTKTia+2L4w7w/TjZ8EDJWw9/O1d3kJk1E+se7yVueEsEUHaG1GhVYidlQgv2+VuPmkJUHVdzmZg9wwXar0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=nEKSnbU2; arc=none smtp.client-ip=209.85.216.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nEKSnbU2" Received: by mail-pj1-f48.google.com with SMTP id 98e67ed59e1d1-3436a97f092so502264a91.3 for ; Tue, 11 Nov 2025 20:28:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762921723; x=1763526523; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=bypbKJSNdfzMIo5PJqXm9z2sZhPniVXZs5eZRTP+WOQ=; b=nEKSnbU2JVPJe8mg2mQEPIZJlETYi07y8OyyipoUX8RXUqjupW0KuGMInnX0H44kVL WFw3fK4ti9RSjJedsu/bA7G0X/q/mkrmsF/4OQ1fWJ+ZmoMN+m8gdcPkWf2t3FuUEmP8 X8jAl0keiTZOnkgu50MI1mATgeef0a5r56GlEwi5V6sN5ELNB2OVtGUyW8Q+9g430eLG NZfDtjC7nfKXioqIUeLE8B81wr6JCGkVippy5PNSq4HzC9aKPKy/yao3fAwAs6QtyJNz 0TcSi1H+die+YJFFt3X9GMeiIcJM66VhYLjeQ1nkUCr7qOweRSuiw7zdXEOWmJZOuloO B6/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762921723; x=1763526523; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=bypbKJSNdfzMIo5PJqXm9z2sZhPniVXZs5eZRTP+WOQ=; b=cnYXmIOm2HvocO5yPqmt8mkeLWHTXzFQb18p01YmJ5KGzg+uls/wFamtvJKQ3Wdc6M mRmqbq7O47ka6FpmVcbzmii7ZqqZzJOJ+L5YCtd1EXs8ZvJditfgMlZyhCNFbLb2RFAE mRadA3paQxh9C+dBNJ3jePvzmufiGMMmo33xVFw03rCxkLbP+CxNiHkEeap9XhoM/YJW TOdbYsvqR83Wk8dpLEf7V1UkLlAn174YDVC7dEpi5KDlmAmQ2GNUUALqPoMdaVefJitk 2VUyZLodKO+qyhuYvxl6ZfyIWy1CsxQNZIp7uyPbnFP2Ly/mXqtypzW0IfvL5XLDNada +gFA== X-Forwarded-Encrypted: i=1; AJvYcCXDvsr5ZKgx1Tz6C+g+qBWersVGZhMODW3e9bmLfg35e2HC17aLpvGMRBvbWqnI+tw71tE5oO6OBrSUIy0=@vger.kernel.org X-Gm-Message-State: AOJu0YzwRI/0ZseOepBJmE4NtI0TJN2zXX/ytoFnpVv5HBAK03xzPN6r yd4iuMB2K6D5/MeUkb4DCojORC94txw0v9DxqiocPzEgWzFLC6fHGPMh X-Gm-Gg: ASbGncvTrnTxWpbtreN8OXacurLmpohxJEMZbkGxkit8He8VKCfRKZMwvUNoiGA1bRU FIP/PsdwIy+6PANXMx/ScWF/zak4kBDiVSy/BcK0czDIPRDuV35tLSBi1hMZlPqsZYmo2GmXpyk GwWIQE//KHvFSdvcmd6GFu591R6uLHvrJs14IQdnqvBDY9VuthZjOiYQlmXX8+O77NlvxGDvIq1 na+U+J+WcVr+lyv2AKTe1YQGnhHOh/kQAe0U4oHQrPQ0t2lo/O/DNgVWUwHmfaNeQ8DU0cIeGPH MS60VaTtsCuRXIaAUzbR+mo/ooIDkq1N/XINrPlbaTPPdsFWjYKTGYUufw57SRYdtfL8m5vDRut clswVMthNrQusxWnRNzFHxVHeENRBKvwVY5Hh3sQTGY8aK0bNBbU3p5J5kuMcKMHoXw8Eja8Vka ksNjRAYHbbkw70fk3pf20SfKVwhnP59CYZNoRO0XLZsB9Z+PhXN6jdQI4rUlqUxXR96KAcGyyzB SdK8wbH+A== X-Google-Smtp-Source: AGHT+IEk3fmOmPuZqt1xGOcbomb+tiqKdW76DJidL9Gpiy8ngxFNpe36IzIVYCCq1TjDctRIbXHwUg== X-Received: by 2002:a17:90b:1dce:b0:341:d326:7354 with SMTP id 98e67ed59e1d1-343ddeff608mr2144322a91.37.1762921722670; Tue, 11 Nov 2025 20:28:42 -0800 (PST) Received: from toolbx.alistair23.me (2403-580b-97e8-0-82ce-f179-8a79-69f4.ip6.aussiebb.net. [2403:580b:97e8:0:82ce:f179:8a79:69f4]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-343e06fbc0dsm854681a91.2.2025.11.11.20.28.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Nov 2025 20:28:42 -0800 (PST) From: alistair23@gmail.com X-Google-Original-From: alistair.francis@wdc.com To: chuck.lever@oracle.com, hare@kernel.org, kernel-tls-handshake@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nvme@lists.infradead.org, linux-nfs@vger.kernel.org Cc: kbusch@kernel.org, axboe@kernel.dk, hch@lst.de, sagi@grimberg.me, kch@nvidia.com, hare@suse.de, alistair23@gmail.com, Alistair Francis Subject: [PATCH v5 6/6] nvmet-tcp: Support KeyUpdate Date: Wed, 12 Nov 2025 14:27:20 +1000 Message-ID: <20251112042720.3695972-7-alistair.francis@wdc.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251112042720.3695972-1-alistair.francis@wdc.com> References: <20251112042720.3695972-1-alistair.francis@wdc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alistair Francis If the nvmet_tcp_try_recv() function return EKEYEXPIRED or if we receive a KeyUpdate handshake type then the underlying TLS keys need to be updated. If the NVMe Host (TLS client) initiates a KeyUpdate this patch will allow the NVMe layer to process the KeyUpdate request and forward the request to userspace. Userspace must then update the key to keep the connection alive. This patch allows us to handle the NVMe host sending a KeyUpdate request without aborting the connection. At this time we don't support initiating a KeyUpdate. Link: https://datatracker.ietf.org/doc/html/rfc8446#section-4.6.3 Signed-off-by: Alistair Francis Reviewed-by: Hannes Reinecke --- v5: - No change v4: - Restructure code to avoid #ifdefs and forward declarations - Use a helper function for checking -EKEYEXPIRED - Remove all support for initiating KeyUpdate - Use helper function for restoring callbacks v3: - Use a write lock for sk_user_data - Fix build with CONFIG_NVME_TARGET_TCP_TLS disabled - Remove unused variable v2: - Use a helper function for KeyUpdates - Ensure keep alive timer is stopped - Wait for TLS KeyUpdate to complete drivers/nvme/target/tcp.c | 203 ++++++++++++++++++++++++++------------ 1 file changed, 142 insertions(+), 61 deletions(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 818efdeccef1..486ea7bb0056 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -175,6 +175,7 @@ struct nvmet_tcp_queue { =20 /* TLS state */ key_serial_t tls_pskid; + key_serial_t handshake_session_id; struct delayed_work tls_handshake_tmo_work; =20 unsigned long poll_end; @@ -186,6 +187,8 @@ struct nvmet_tcp_queue { struct sockaddr_storage sockaddr_peer; struct work_struct release_work; =20 + struct completion tls_complete; + int idx; struct list_head queue_list; =20 @@ -214,6 +217,10 @@ static struct workqueue_struct *nvmet_tcp_wq; static const struct nvmet_fabrics_ops nvmet_tcp_ops; static void nvmet_tcp_free_cmd(struct nvmet_tcp_cmd *c); static void nvmet_tcp_free_cmd_buffers(struct nvmet_tcp_cmd *cmd); +#ifdef CONFIG_NVME_TARGET_TCP_TLS +static int nvmet_tcp_tls_handshake(struct nvmet_tcp_queue *queue, + enum handshake_key_update_type keyupdate); +#endif =20 static inline u16 nvmet_tcp_cmd_tag(struct nvmet_tcp_queue *queue, struct nvmet_tcp_cmd *cmd) @@ -832,6 +839,23 @@ static int nvmet_tcp_try_send_one(struct nvmet_tcp_que= ue *queue, return 1; } =20 +#ifdef CONFIG_NVME_TARGET_TCP_TLS +static bool nvmet_tls_key_expired(struct nvmet_tcp_queue *queue, int ret) +{ + if (ret =3D=3D -EKEYEXPIRED && + queue->state !=3D NVMET_TCP_Q_DISCONNECTING && + queue->state !=3D NVMET_TCP_Q_TLS_HANDSHAKE) + return true; + + return false; +} +#else +static bool nvmet_tls_key_expired(struct nvmet_tcp_queue *queue, int ret) +{ + return false; +} +#endif + static int nvmet_tcp_try_send(struct nvmet_tcp_queue *queue, int budget, int *sends) { @@ -1106,6 +1130,103 @@ static inline bool nvmet_tcp_pdu_valid(u8 type) return false; } =20 +static void nvmet_tcp_release_queue(struct kref *kref) +{ + struct nvmet_tcp_queue *queue =3D + container_of(kref, struct nvmet_tcp_queue, kref); + + WARN_ON(queue->state !=3D NVMET_TCP_Q_DISCONNECTING); + queue_work(nvmet_wq, &queue->release_work); +} + +static void nvmet_tcp_schedule_release_queue(struct nvmet_tcp_queue *queue) +{ + spin_lock_bh(&queue->state_lock); + if (queue->state =3D=3D NVMET_TCP_Q_TLS_HANDSHAKE) { + /* Socket closed during handshake */ + tls_handshake_cancel(queue->sock->sk); + } + if (queue->state !=3D NVMET_TCP_Q_DISCONNECTING) { + queue->state =3D NVMET_TCP_Q_DISCONNECTING; + kref_put(&queue->kref, nvmet_tcp_release_queue); + } + spin_unlock_bh(&queue->state_lock); +} + +static void nvmet_tcp_restore_socket_callbacks(struct nvmet_tcp_queue *que= ue) +{ + struct socket *sock =3D queue->sock; + + if (!queue->state_change) + return; + + write_lock_bh(&sock->sk->sk_callback_lock); + sock->sk->sk_data_ready =3D queue->data_ready; + sock->sk->sk_state_change =3D queue->state_change; + sock->sk->sk_write_space =3D queue->write_space; + sock->sk->sk_user_data =3D NULL; + write_unlock_bh(&sock->sk->sk_callback_lock); +} + +#ifdef CONFIG_NVME_TARGET_TCP_TLS +static void nvmet_tcp_tls_handshake_timeout(struct work_struct *w) +{ + struct nvmet_tcp_queue *queue =3D container_of(to_delayed_work(w), + struct nvmet_tcp_queue, tls_handshake_tmo_work); + + pr_warn("queue %d: TLS handshake timeout\n", queue->idx); + /* + * If tls_handshake_cancel() fails we've lost the race with + * nvmet_tcp_tls_handshake_done() */ + if (!tls_handshake_cancel(queue->sock->sk)) + return; + spin_lock_bh(&queue->state_lock); + if (WARN_ON(queue->state !=3D NVMET_TCP_Q_TLS_HANDSHAKE)) { + spin_unlock_bh(&queue->state_lock); + return; + } + queue->state =3D NVMET_TCP_Q_FAILED; + spin_unlock_bh(&queue->state_lock); + nvmet_tcp_schedule_release_queue(queue); + kref_put(&queue->kref, nvmet_tcp_release_queue); +} + +static int update_tls_keys(struct nvmet_tcp_queue *queue) +{ + int ret; + + cancel_work(&queue->io_work); + queue->state =3D NVMET_TCP_Q_TLS_HANDSHAKE; + + nvmet_tcp_restore_socket_callbacks(queue); + + INIT_DELAYED_WORK(&queue->tls_handshake_tmo_work, + nvmet_tcp_tls_handshake_timeout); + + ret =3D nvmet_tcp_tls_handshake(queue, HANDSHAKE_KEY_UPDATE_TYPE_RECEIVED= ); + + if (ret < 0) + return ret; + + ret =3D wait_for_completion_interruptible_timeout(&queue->tls_complete, + 10 * HZ); + + if (ret <=3D 0) { + tls_handshake_cancel(queue->sock->sk); + return ret; + } + + queue->state =3D NVMET_TCP_Q_LIVE; + + return 0; +} +#else +static int update_tls_keys(struct nvmet_tcp_queue *queue) +{ + return -EPFNOSUPPORT; +} +#endif + static int nvmet_tcp_tls_record_ok(struct nvmet_tcp_queue *queue, struct msghdr *msg, char *cbuf) { @@ -1131,6 +1252,9 @@ static int nvmet_tcp_tls_record_ok(struct nvmet_tcp_q= ueue *queue, ret =3D -EAGAIN; } break; + case TLS_RECORD_TYPE_HANDSHAKE: + ret =3D -EAGAIN; + break; default: /* discard this record type */ pr_err("queue %d: TLS record %d unhandled\n", @@ -1340,6 +1464,8 @@ static int nvmet_tcp_try_recv(struct nvmet_tcp_queue = *queue, for (i =3D 0; i < budget; i++) { ret =3D nvmet_tcp_try_recv_one(queue); if (unlikely(ret < 0)) { + if (nvmet_tls_key_expired(queue, ret)) + goto done; nvmet_tcp_socket_error(queue, ret); goto done; } else if (ret =3D=3D 0) { @@ -1351,29 +1477,6 @@ static int nvmet_tcp_try_recv(struct nvmet_tcp_queue= *queue, return ret; } =20 -static void nvmet_tcp_release_queue(struct kref *kref) -{ - struct nvmet_tcp_queue *queue =3D - container_of(kref, struct nvmet_tcp_queue, kref); - - WARN_ON(queue->state !=3D NVMET_TCP_Q_DISCONNECTING); - queue_work(nvmet_wq, &queue->release_work); -} - -static void nvmet_tcp_schedule_release_queue(struct nvmet_tcp_queue *queue) -{ - spin_lock_bh(&queue->state_lock); - if (queue->state =3D=3D NVMET_TCP_Q_TLS_HANDSHAKE) { - /* Socket closed during handshake */ - tls_handshake_cancel(queue->sock->sk); - } - if (queue->state !=3D NVMET_TCP_Q_DISCONNECTING) { - queue->state =3D NVMET_TCP_Q_DISCONNECTING; - kref_put(&queue->kref, nvmet_tcp_release_queue); - } - spin_unlock_bh(&queue->state_lock); -} - static inline void nvmet_tcp_arm_queue_deadline(struct nvmet_tcp_queue *qu= eue) { queue->poll_end =3D jiffies + usecs_to_jiffies(idle_poll_period_usecs); @@ -1404,8 +1507,12 @@ static void nvmet_tcp_io_work(struct work_struct *w) ret =3D nvmet_tcp_try_recv(queue, NVMET_TCP_RECV_BUDGET, &ops); if (ret > 0) pending =3D true; - else if (ret < 0) + else if (ret < 0) { + if (ret =3D=3D -EKEYEXPIRED) + break; + return; + } =20 ret =3D nvmet_tcp_try_send(queue, NVMET_TCP_SEND_BUDGET, &ops); if (ret > 0) @@ -1415,6 +1522,11 @@ static void nvmet_tcp_io_work(struct work_struct *w) =20 } while (pending && ops < NVMET_TCP_IO_WORK_BUDGET); =20 + if (ret =3D=3D -EKEYEXPIRED) { + update_tls_keys(queue); + pending =3D true; + } + /* * Requeue the worker if idle deadline period is in progress or any * ops activity was recorded during the do-while loop above. @@ -1517,21 +1629,6 @@ static void nvmet_tcp_free_cmds(struct nvmet_tcp_que= ue *queue) kfree(cmds); } =20 -static void nvmet_tcp_restore_socket_callbacks(struct nvmet_tcp_queue *que= ue) -{ - struct socket *sock =3D queue->sock; - - if (!queue->state_change) - return; - - write_lock_bh(&sock->sk->sk_callback_lock); - sock->sk->sk_data_ready =3D queue->data_ready; - sock->sk->sk_state_change =3D queue->state_change; - sock->sk->sk_write_space =3D queue->write_space; - sock->sk->sk_user_data =3D NULL; - write_unlock_bh(&sock->sk->sk_callback_lock); -} - static void nvmet_tcp_uninit_data_in_cmds(struct nvmet_tcp_queue *queue) { struct nvmet_tcp_cmd *cmd =3D queue->cmds; @@ -1794,6 +1891,7 @@ static void nvmet_tcp_tls_handshake_done(void *data, = int status, } if (!status) { queue->tls_pskid =3D peerid; + queue->handshake_session_id =3D handshake_session_id; queue->state =3D NVMET_TCP_Q_CONNECTING; } else queue->state =3D NVMET_TCP_Q_FAILED; @@ -1809,28 +1907,7 @@ static void nvmet_tcp_tls_handshake_done(void *data,= int status, else nvmet_tcp_set_queue_sock(queue); kref_put(&queue->kref, nvmet_tcp_release_queue); -} - -static void nvmet_tcp_tls_handshake_timeout(struct work_struct *w) -{ - struct nvmet_tcp_queue *queue =3D container_of(to_delayed_work(w), - struct nvmet_tcp_queue, tls_handshake_tmo_work); - - pr_warn("queue %d: TLS handshake timeout\n", queue->idx); - /* - * If tls_handshake_cancel() fails we've lost the race with - * nvmet_tcp_tls_handshake_done() */ - if (!tls_handshake_cancel(queue->sock->sk)) - return; - spin_lock_bh(&queue->state_lock); - if (WARN_ON(queue->state !=3D NVMET_TCP_Q_TLS_HANDSHAKE)) { - spin_unlock_bh(&queue->state_lock); - return; - } - queue->state =3D NVMET_TCP_Q_FAILED; - spin_unlock_bh(&queue->state_lock); - nvmet_tcp_schedule_release_queue(queue); - kref_put(&queue->kref, nvmet_tcp_release_queue); + complete(&queue->tls_complete); } =20 static int nvmet_tcp_tls_handshake(struct nvmet_tcp_queue *queue, @@ -1852,11 +1929,15 @@ static int nvmet_tcp_tls_handshake(struct nvmet_tcp= _queue *queue, args.ta_data =3D queue; args.ta_keyring =3D key_serial(queue->port->nport->keyring); args.ta_timeout_ms =3D tls_handshake_timeout * 1000; + args.handshake_session_id =3D queue->handshake_session_id; + + init_completion(&queue->tls_complete); =20 if (keyupdate =3D=3D HANDSHAKE_KEY_UPDATE_TYPE_UNSPEC) ret =3D tls_server_hello_psk(&args, GFP_KERNEL); else ret =3D tls_server_keyupdate_psk(&args, GFP_KERNEL, keyupdate); + if (ret) { kref_put(&queue->kref, nvmet_tcp_release_queue); pr_err("failed to start TLS, err=3D%d\n", ret); --=20 2.51.1