{"id":2229681,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2229681/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-cifs-client/patch/20260428154604.222551-6-henrique.carvalho@suse.com/","project":{"id":12,"url":"http://patchwork.ozlabs.org/api/1.1/projects/12/?format=json","name":"Linux CIFS Client","link_name":"linux-cifs-client","list_id":"linux-cifs.vger.kernel.org","list_email":"linux-cifs@vger.kernel.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260428154604.222551-6-henrique.carvalho@suse.com>","date":"2026-04-28T15:46:01","name":"[03/11] smb: client: add QUIC mount and transport setup","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"2d90ff985f87ed9ad11e57bbf0bc3cb0a81da173","submitter":{"id":89563,"url":"http://patchwork.ozlabs.org/api/1.1/people/89563/?format=json","name":"Henrique Carvalho","email":"henrique.carvalho@suse.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-cifs-client/patch/20260428154604.222551-6-henrique.carvalho@suse.com/mbox/","series":[{"id":501882,"url":"http://patchwork.ozlabs.org/api/1.1/series/501882/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-cifs-client/list/?series=501882","date":"2026-04-28T15:45:56","name":"smb: implement SMB over QUIC","version":1,"mbox":"http://patchwork.ozlabs.org/series/501882/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2229681/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2229681/checks/","tags":{},"headers":{"Return-Path":"\n <linux-cifs+bounces-11225-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-cifs@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=suse.com header.i=@suse.com header.a=rsa-sha256\n header.s=google header.b=NH+I9IM7;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-cifs+bounces-11225-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com\n header.b=\"NH+I9IM7\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=209.85.221.42","smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=suse.com","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=suse.com"],"Received":["from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g4lFx0mmjz1xvV\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 Apr 2026 01:48:21 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id E2428306C7FB\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 15:47:01 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id BA688322C6D;\n\tTue, 28 Apr 2026 15:46:55 +0000 (UTC)","from mail-wr1-f42.google.com (mail-wr1-f42.google.com\n [209.85.221.42])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id E1B803C3BF3\n\tfor <linux-cifs@vger.kernel.org>; Tue, 28 Apr 2026 15:46:52 +0000 (UTC)","by mail-wr1-f42.google.com with SMTP id\n ffacd0b85a97d-43d77f6092eso8107093f8f.2\n        for <linux-cifs@vger.kernel.org>;\n Tue, 28 Apr 2026 08:46:52 -0700 (PDT)","from precision ([2a01:4b00:c007:bb00:be9d:a3c4:18b1:4a25])\n        by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-4463d4fa52bsm7725384f8f.15.2026.04.28.08.46.50\n        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n        Tue, 28 Apr 2026 08:46:50 -0700 (PDT)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777391215; cv=none;\n b=qWzsD3PV/F8ZNcQUqPd8ZOdIRRNKbednugKsLivWmcRBB7a6SD3M2+q1eEatDHb/vM2c72vDfy1ig6Ex7WFkJGPSyZ+x6sZ7CcZwfLDcOPCdQG+n/gTDsI9K/VPyTHC3OCG8+nQSP9gjBnOg/eRMDo3ZiFRF08UYFqewAMBC8YI=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777391215; c=relaxed/simple;\n\tbh=2DiCheTPcsUxqeXUgGMUKQ6AKOFGY0LGdU9YabS+w7k=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=LBpPg7V4jlhALZ+hRBpzfgXRP0uUwsSb3nQD9BKFjgGv7BMXfeqVIoFl+NaJ9lvMJnxP9CantAVjUCA9wCn4G9NPXSHVe6miV/RP5/BCWEeUkAYXtVRILaESuzx2lmyZsNK0E9g+jp1cuTZJareqk5XQAsRrC2WA2aqW6C/096U=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=suse.com;\n spf=pass smtp.mailfrom=suse.com;\n dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com\n header.b=NH+I9IM7; arc=none smtp.client-ip=209.85.221.42","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=suse.com; s=google; t=1777391211; x=1777996011;\n darn=vger.kernel.org;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n         :message-id:reply-to;\n        bh=XZJsQEUrX44rAyCg1faVBNcmLKBSPLK+aWneKpC1/A4=;\n        b=NH+I9IM7RilflMKdM9os2Hrw4OvjujVub/8Q34dONI7WrQkXKNeXlY752KJS/E96Y1\n         tteSsnzesnD/fpI7iq+6EzNfUOupnbfvA+J0ymTmuEvdfrJ+KHMepvzE2Sl9u6ajWzeL\n         Kmn66HKBGCiWoKkI+xcJMx74KO1ppZwFpD8MhWei7WfkMJOFSVdbaWLD6+M5b4OIm8aL\n         Zx/mfTdbu7SHT0wDH8xiX5e5QsbsUA9IvOOy5SYr0zJeqDFM73clc93+XSOLiuK28PIq\n         zxmqgXdrrxDrGgLeTqz84nicna6zlVjrmnLhT1sAwWBoojiJuXTU+nV6UKfinB74LaLn\n         HULA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=1e100.net; s=20251104; t=1777391211; x=1777996011;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n         :to:cc:subject:date:message-id:reply-to;\n        bh=XZJsQEUrX44rAyCg1faVBNcmLKBSPLK+aWneKpC1/A4=;\n        b=bZmuYYN8WJ0l3wzQmZukfGfpSnps5y+33S/IeL+VORt7J71OClzhJFN+V7RfR2utpQ\n         OPrSFI3zS8GnEiC1uzsVrrk5AVsm8ntdjsoHgsETtmEPaIEhCT2c5Hu01lD4KiMBnSg1\n         LrBjx8HAjYQA1dmxW7XVGqeb1hb1yCDZHOFfW1TxIltfATrLrXLzIzWh8g0ilZu2k5L5\n         t0wyAwpJbbtXcyAa1TErh0r8uhI9Rfrc1YVE6dBOhDLqQHVtPMeFlUDHt0SCF19jAs0Y\n         SAeJuEgCMn7Ge5yx966ExQnGbcMraQQBvTCPL/LFSfoHW/wD3v9fVLZwdOFjEZciM81K\n         QGGQ==","X-Gm-Message-State":"AOJu0Yw+sh3OVpcbmVHlZAo67PRbHdZr8ie4f4wDeSmCNASI0ugETKlR\n\t+r9ENMheHlfy756Gi4lOL/bigc/WmdpLQ/OOYX+Ut2O2nDq83k9yZ52ba7HP7foOl09VWJOAHf0\n\tJMSx6I/kKMA==","X-Gm-Gg":"AeBDietm3dpi/xBMY/AZ/NT1uz1Uj5raHna15LEKesJdX2M7fzjf2bFfGK7I96arr6y\n\tdk735sFa0PzvJfOHR8VxZUoklVoY7UjIGliAaWLXdPztOasE05F95WIDnfgvHGDXEB4fwpNgZfR\n\tYMyRvnlb8yGuwq5m4R/cGotQQd64xFCktvtVsjN6EzuZaBUc8Xs8N66K7xcE1REI4JTa2vTel5n\n\tu9E1tdG6oqX/XvsIcpkbtp/YnA+6/FIq3RxXCm43wj+z3Wilc8xDy31SOKGAezgJRkLoztpRy/T\n\tqsrAkG7tzuGkjdM2ZzZzEcANO/rE9A9rXXTWaN3SyEAtPgv+aDU65R+wRDbuP69XkoCDOm8hRrz\n\t8w5j7JAYl4PhS51HbZnCsA9QQ+6P6sCgLMtM2bh2igx3mLNM4Pf269Cmo50bovp3IFnlM5fZyK1\n\t+LjpeOQOEi03CUD9Q2PeG37OBT+rnl7fgm0anblY0LnRTx","X-Received":"by 2002:a05:6000:2f88:b0:43d:77a8:3baf with SMTP id\n ffacd0b85a97d-4464b1b8620mr6854069f8f.32.1777391210850;\n        Tue, 28 Apr 2026 08:46:50 -0700 (PDT)","From":"Henrique Carvalho <henrique.carvalho@suse.com>","To":"linux-cifs@vger.kernel.org","Cc":"sfrench@samba.org,\n\tlinkinjeon@kernel.org,\n\tmetze@samba.org,\n\tpc@manguebit.com,\n\tronniesahlberg@gmail.com,\n\tsprasad@microsoft.com,\n\ttom@talpey.com,\n\tbharathsm@microsoft.com,\n\tematsumiya@suse.de,\n\tHenrique Carvalho <henrique.carvalho@suse.com>","Subject":"[PATCH 03/11] smb: client: add QUIC mount and transport setup","Date":"Tue, 28 Apr 2026 12:46:01 -0300","Message-ID":"<20260428154604.222551-6-henrique.carvalho@suse.com>","X-Mailer":"git-send-email 2.53.0","In-Reply-To":"<20260428154604.222551-1-henrique.carvalho@suse.com>","References":"<20260428154604.222551-1-henrique.carvalho@suse.com>","Precedence":"bulk","X-Mailing-List":"linux-cifs@vger.kernel.org","List-Id":"<linux-cifs.vger.kernel.org>","List-Subscribe":"<mailto:linux-cifs+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-cifs+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit"},"content":"Introduce new mount options used to drive SMB over QUIC: `quic` and\n`mtls`. Introduce per-server state needed to drive the QUIC transport.\nIntroduce transport functions for smb quic tls handshake setup and\ninitial quic transport setup. Include SMB2_TRANSPORT_CAPABILITIES\nnegotiate context for QUIC.\n\nSigned-off-by: Henrique Carvalho <henrique.carvalho@suse.com>\n---\n fs/smb/client/cifsglob.h   |  19 +++-\n fs/smb/client/connect.c    | 184 +++++++++++++++++++++++++++++++++++--\n fs/smb/client/fs_context.c |  27 ++++++\n fs/smb/client/fs_context.h |   4 +\n fs/smb/client/smb2pdu.c    |  27 ++++++\n fs/smb/client/transport.c  |  40 ++++----\n 6 files changed, 274 insertions(+), 27 deletions(-)","diff":"diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h\nindex 58be72377c7d..f56d3732bfa8 100644\n--- a/fs/smb/client/cifsglob.h\n+++ b/fs/smb/client/cifsglob.h\n@@ -35,6 +35,7 @@\n #define CIFS_PORT 445\n #define RFC1001_PORT 139\n #define SMBD_IWARP_PORT 5445\n+#define SMB_QUIC_PORT 443\n \n /*\n  * The sizes of various internal tables and strings\n@@ -759,8 +760,10 @@ struct TCP_Server_Info {\n \tbool\tsec_mskerberos;\t\t/* supports legacy MS Kerberos */\n \tbool\tsec_iakerb;\t\t/* supports pass-through auth for Kerberos (krb5 proxy) */\n \tbool\tlarge_buf;\t\t/* is current buffer large? */\n-\tint\tipproto; /* IPPROTO_TCP or IPOROTO_SMBDIRECT */\n+\tint\tipproto; /* IPPROTO_TCP, IPOROTO_SMBDIRECT or IPPROTO_QUIC */\n #define cifs_rdma_enabled(__server)\t((__server)->ipproto == IPPROTO_SMBDIRECT)\n+\t/* point to the SMBD connection if RDMA is used instead of socket */\n+\tstruct smbd_connection *smbd_conn;\n \tstruct delayed_work\techo; /* echo ping workqueue job */\n \tchar\t*smallbuf;\t/* pointer to current \"small\" buffer */\n \tchar\t*bigbuf;\t/* pointer to current \"big\" buffer */\n@@ -832,6 +835,14 @@ struct TCP_Server_Info {\n \tchar *leaf_fullpath;\n \tbool dfs_conn:1;\n \tchar dns_dom[CIFS_MAX_DOMAINNAME_LEN + 1];\n+\n+\tstruct {\n+\t\tbool need_smb_seal; /* if unset, smb encryption is disabled over QUIC\n+\t\t\t\t     * transport, and QUIC security (i.e. TLS 1.3) is\n+\t\t\t\t     * the one used\n+\t\t\t\t     */\n+\t\tbool mtls;\n+\t} quic_conn;\n };\n \n static inline bool is_smb1(const struct TCP_Server_Info *server)\n@@ -855,6 +866,12 @@ static inline void cifs_server_unlock(struct TCP_Server_Info *server)\n \tmemalloc_nofs_restore(nofs_flag);\n }\n \n+static inline bool\n+cifs_quic_enabled(struct TCP_Server_Info *server)\n+{\n+\treturn server->ipproto == IPPROTO_QUIC;\n+}\n+\n struct cifs_credits {\n \tunsigned int value;\n \tunsigned int instance;\ndiff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c\nindex 33d619007905..bfe949b14db2 100644\n--- a/fs/smb/client/connect.c\n+++ b/fs/smb/client/connect.c\n@@ -25,11 +25,14 @@\n #include <linux/namei.h>\n #include <linux/uuid.h>\n #include <linux/uaccess.h>\n+#include <linux/quic.h>\n #include <asm/processor.h>\n #include <linux/inet.h>\n #include <linux/module.h>\n #include <keys/user-type.h>\n #include <net/ipv6.h>\n+#include <net/handshake.h>\n+#include <keys/asymmetric-type.h>\n #include <linux/parser.h>\n #include <linux/bvec.h>\n #include \"cifsglob.h\"\n@@ -70,7 +73,11 @@ static void mchan_mount_work_fn(struct work_struct *work);\n \n static void smb_sock_release(struct TCP_Server_Info *server)\n {\n-\tsock_release(server->ssocket);\n+\t/* ->ssocket will be released by fput() */\n+\tif (cifs_quic_enabled(server) && server->ssocket->file)\n+\t\tfput(server->ssocket->file);\n+\telse if (server->ssocket)\n+\t\tsock_release(server->ssocket);\n \tserver->ssocket = NULL;\n }\n \n@@ -1643,6 +1650,9 @@ static int match_server(struct TCP_Server_Info *server,\n \tif (cifs_rdma_enabled(server) != ctx->rdma)\n \t\treturn 0;\n \n+\tif (cifs_quic_enabled(server) != ctx->quic)\n+\t\treturn 0;\n+\n \tif (server->ignore_signature != ctx->ignore_signature)\n \t\treturn 0;\n \n@@ -1784,7 +1794,10 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,\n \ttcp_ses->tcp_nodelay = ctx->sockopt_tcp_nodelay;\n \tif (ctx->rdma)\n \t\ttcp_ses->ipproto = IPPROTO_SMBDIRECT;\n-\telse\n+\telse if (ctx->quic) {\n+\t\ttcp_ses->ipproto = IPPROTO_QUIC;\n+\t\ttcp_ses->quic_conn.mtls = ctx->mtls;\n+\t} else\n \t\ttcp_ses->ipproto = IPPROTO_TCP;\n \n \ttcp_ses->in_flight = 0;\n@@ -3304,6 +3317,145 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)\n \treturn 0;\n }\n \n+static void\n+smb_tls_handshake_done(void *data, int status, key_serial_t peerid)\n+{\n+\tstruct smb_tls *smb_tls = (struct smb_tls *)data;\n+\n+\tsmb_tls->status = status;\n+\tsmb_tls->peerid = peerid;\n+\n+\tcomplete(&smb_tls->handshake_done);\n+}\n+\n+static inline struct smb_tls *\n+smb_tls_init(struct TCP_Server_Info *server)\n+{\n+\tstruct smb_tls *tls;\n+\n+\ttls = kzalloc_obj(*tls, GFP_KERNEL);\n+\tif (!tls)\n+\t\treturn ERR_PTR(-ENOMEM);\n+\n+\ttls->status = 0;\n+\n+\ttls->args.ta_sock = server->ssocket;\n+\ttls->args.ta_done = smb_tls_handshake_done;\n+\ttls->args.ta_data = tls;\n+\ttls->args.ta_peername = kstrdup(server->hostname, GFP_KERNEL); /* do I need kstrdup ? */\n+\ttls->args.ta_timeout_ms = SMB_TLS_TIMEOUT_MS;\n+\ttls->args.ta_keyring = TLS_NO_KEYRING;\n+\n+\tinit_completion(&tls->handshake_done);\n+\n+\treturn tls;\n+}\n+\n+static void smb_tls_free(struct smb_tls **tls)\n+{\n+\tkfree((*tls)->args.ta_peername);\n+\tkfree_sensitive(*tls);\n+\t*tls = NULL;\n+}\n+\n+static inline void\n+smb_tls_debug(int rc)\n+{\n+\tswitch (rc) {\n+\tcase 0:\n+\t\tcifs_dbg(VFS, \"smb tls: Handshake successful\");\n+\t\treturn;\n+\tcase -ERESTARTSYS:\n+\t\tcifs_dbg(VFS, \"smb tls: Handshake interrupted\");\n+\t\treturn;\n+\tcase -ETIMEDOUT:\n+\t\tcifs_dbg(VFS, \"smb tls: Handshake timed out\");\n+\t\treturn;\n+\tcase -EINVAL:\n+\t\tcifs_dbg(VFS, \"smb tls: Consumer provided an invalid argument\");\n+\t\treturn;\n+\tcase -ENOKEY:\n+\t\tcifs_dbg(VFS, \"smb tls: Missing authentication material\");\n+\t\treturn;\n+\tcase -EIO:\n+\t\tcifs_dbg(VFS, \"smb tls: An unexpected fault occurred\");\n+\t\treturn;\n+\tdefault:\n+\t\tcifs_dbg(VFS, \"smb tls: Error: %d\", -rc);\n+\t\treturn;\n+\t}\n+}\n+\n+static int\n+smb_tls_handshake(struct TCP_Server_Info *server)\n+{\n+\tint rc;\n+\tstruct smb_tls *tls;\n+\n+\tcifs_dbg(FYI, \"smb tls: starting TLS handshake\");\n+\n+\ttls = smb_tls_init(server);\n+\tif (IS_ERR(tls))\n+\t\treturn PTR_ERR(tls);\n+\n+\tif (server->quic_conn.mtls)\n+\t\trc = tls_client_hello_x509(&tls->args, GFP_KERNEL);\n+\telse\n+\t\trc = tls_client_hello_anon(&tls->args, GFP_KERNEL);\n+\n+\tif (rc < 0)\n+\t\tgoto free;\n+\n+\trc = wait_for_completion_interruptible(&tls->handshake_done);\n+\tif (rc < 0)\n+\t\ttls_handshake_cancel(server->ssocket->sk);\n+\telse\n+\t\trc = tls->status;\n+\n+free:\n+\tsmb_tls_free(&tls);\n+\n+\tsmb_tls_debug(rc);\n+\n+\treturn rc;\n+}\n+\n+static int\n+smb_quic_tls(struct TCP_Server_Info *server)\n+{\n+\tint rc;\n+\tsize_t sinfolen;\n+\tstruct quic_stream_info sinfo;\n+\tstruct socket *socket = server->ssocket;\n+\n+\trc = smb_tls_handshake(server);\n+\tif (rc < 0)\n+\t\treturn rc;\n+\n+\t/* open a new stream after handshake, default to stream id == 0 */\n+\tsinfo.stream_id = -1;\n+\tsinfolen = sizeof(sinfo);\n+\trc = quic_do_getsockopt(socket->sk, QUIC_SOCKOPT_STREAM_OPEN,\n+\t\t\t\tKERNEL_SOCKPTR(&sinfo), KERNEL_SOCKPTR(&sinfolen));\n+\n+\treturn rc;\n+}\n+\n+static int\n+smb_quic_prepare_socket(struct TCP_Server_Info *server)\n+{\n+\tint flags = 0;\n+\tstruct file *filp;\n+\tstruct socket *socket = server->ssocket;\n+\n+\tfilp = sock_alloc_file(socket, flags, NULL);\n+\tif (IS_ERR(filp))\n+\t\treturn PTR_ERR(filp);\n+\n+\treturn quic_do_setsockopt(socket->sk, QUIC_SOCKOPT_ALPN,\n+\t\t\t\t  KERNEL_SOCKPTR(\"smb\"), 3);\n+}\n+\n static inline const char *\n get_protocol_name(struct TCP_Server_Info *server)\n {\n@@ -3350,8 +3502,6 @@ generic_ip_connect(struct TCP_Server_Info *server)\n \t\t\t __func__, pname, &ipv4->sin_addr, ntohs(sport));\n \t}\n \n-\tsmb_sock_release(server);\n-\n \t{\n \t\tstruct net *net = cifs_net_ns(server);\n \t\tstruct sock *sk;\n@@ -3380,8 +3530,8 @@ generic_ip_connect(struct TCP_Server_Info *server)\n \n \trc = bind_socket(server);\n \tif (rc < 0) {\n-\t\tcifs_dbg(FYI, \"Error %d bind_socket() %s\\n\", rc, pname);\n-\t\tgoto close_socket;\n+\t\tcifs_dbg(VFS, \"Error %d bind_socket() %s\\n\", rc, pname);\n+\t\treturn rc;\n \t}\n \n \t/*\n@@ -3406,10 +3556,16 @@ generic_ip_connect(struct TCP_Server_Info *server)\n \tif (cifs_rdma_enabled(server)) {\n \t\trc = smbd_prepare_socket(server, ntohs(sport));\n \t\tif (rc < 0) {\n-\t\t\tcifs_dbg(FYI, \"Error %d from smbd_prepare_socket(port=%u)\\n\",\n+\t\t\tcifs_dbg(VFS, \"Error %d from smbd_prepare_socket(port=%u)\\n\",\n \t\t\t\t rc, ntohs(sport));\n \t\t\tgoto close_socket;\n \t\t}\n+\t} else if (cifs_quic_enabled(server)) {\n+\t\trc = smb_quic_prepare_socket(server);\n+\t\tif (rc < 0) {\n+\t\t\tcifs_dbg(VFS, \"Error %d from smb_quic_prepare_socket()\\n\", rc);\n+\t\t\tgoto close_socket;\n+\t\t}\n \t}\n \n \tcifs_dbg(FYI, \"sndbuf %d rcvbuf %d rcvtimeo 0x%lx\\n\",\n@@ -3426,9 +3582,18 @@ generic_ip_connect(struct TCP_Server_Info *server)\n \tif (server->noblockcnt && rc == -EINPROGRESS)\n \t\trc = 0;\n \tif (rc < 0) {\n-\t\tcifs_dbg(FYI, \"Error %d connecting with %s to server\\n\", rc, pname);\n+\t\tcifs_dbg(VFS, \"Error %d connecting with %s to server\\n\", rc, pname);\n \t\tgoto close_socket;\n \t}\n+\n+\tif (cifs_quic_enabled(server)) {\n+\t\trc = smb_quic_tls(server);\n+\t\tif (rc < 0) {\n+\t\t\tcifs_dbg(VFS, \"Error %d from smb_quic_tls()\\n\", rc);\n+\t\t\tgoto close_socket;\n+\t\t}\n+\t}\n+\n \ttrace_smb3_connect_done(server->hostname, server->conn_id, &server->dstaddr);\n \n \t/*\n@@ -3467,6 +3632,9 @@ ip_connect(struct TCP_Server_Info *server)\n \tif (cifs_rdma_enabled(server)) {\n \t\tport1 = SMBD_IWARP_PORT;\n \t\tport2 = CIFS_PORT;\n+\t} else if (cifs_quic_enabled(server)) {\n+\t\tport1 = SMB_QUIC_PORT;\n+\t\tport2 = 0;\n \t}\n \n \tif (server->dstaddr.ss_family == AF_INET6)\ndiff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c\nindex 54090739535f..3a0c66cf3c2c 100644\n--- a/fs/smb/client/fs_context.c\n+++ b/fs/smb/client/fs_context.c\n@@ -127,6 +127,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {\n \tfsparam_flag(\"nosparse\", Opt_nosparse),\n \tfsparam_flag(\"domainauto\", Opt_domainauto),\n \tfsparam_flag(\"rdma\", Opt_rdma),\n+\tfsparam_flag(\"quic\", Opt_quic),\n \tfsparam_flag(\"modesid\", Opt_modesid),\n \tfsparam_flag(\"modefromsid\", Opt_modesid),\n \tfsparam_flag(\"rootfs\", Opt_rootfs),\n@@ -135,6 +136,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {\n \tfsparam_flag_no(\"nativesocket\", Opt_nativesocket),\n \tfsparam_flag_no(\"unicode\", Opt_unicode),\n \tfsparam_flag_no(\"nbsessinit\", Opt_nbsessinit),\n+\tfsparam_flag(\"mtls\", Opt_mtls),\n \n \t/* Mount options which take uid or gid */\n \tfsparam_uid(\"backupuid\", Opt_backupuid),\n@@ -840,6 +842,19 @@ static int smb3_fs_context_validate(struct fs_context *fc)\n \t\treturn -EOPNOTSUPP;\n \t}\n \n+\tif (ctx->rdma && ctx->quic) {\n+\t\tcifs_errorf(fc, \"SMB Direct and QUIC transport are mutually exclusive\\n\");\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\tif (ctx->quic) {\n+\t\tpr_err(\"%x\", ctx->vals->protocol_id);\n+\t\tif (ctx->vals->protocol_id < SMB311_PROT_ID) {\n+\t\t\tcifs_errorf(fc, \"SMB over QUIC requires Version >=3.1.1\\n\");\n+\t\t\treturn -EOPNOTSUPP;\n+\t\t}\n+\t}\n+\n #ifndef CONFIG_KEYS\n \t/* Muliuser mounts require CONFIG_KEYS support */\n \tif (ctx->multiuser) {\n@@ -1011,6 +1026,7 @@ static int smb3_verify_reconfigure_ctx(struct fs_context *fc,\n \t\tcifs_errorf(fc, \"can not change nbsessinit during remount\\n\");\n \t\treturn -EINVAL;\n \t}\n+\t/* XXX(QUIC): support remount ? */\n \n \treturn 0;\n }\n@@ -1871,6 +1887,13 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,\n \tcase Opt_rdma:\n \t\tctx->rdma = true;\n \t\tbreak;\n+\tcase Opt_quic:\n+#if !IS_ENABLED(CONFIG_IP_QUIC)\n+\t\tcifs_dbg(VFS, \"CONFIG_IP_QUIC is not enabled\\n\");\n+\t\tgoto cifs_parse_mount_err;\n+#endif\n+\t\tctx->quic = true;\n+\t\tbreak;\n \tcase Opt_reparse:\n \t\tif (parse_reparse_flavor(fc, param->string, ctx))\n \t\t\tgoto cifs_parse_mount_err;\n@@ -1896,7 +1919,11 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,\n \t\tctx->symlinkroot = param->string;\n \t\tparam->string = NULL;\n \t\tbreak;\n+\tcase Opt_mtls:\n+\t\tctx->mtls = true;\n+\t\tbreak;\n \t}\n+\n \t/* case Opt_ignore: - is ignored as expected ... */\n \n \tif (ctx->multiuser && ctx->upcall_target == UPTARGET_MOUNT) {\ndiff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h\nindex 0b64fcb5d302..e9b85c1c1937 100644\n--- a/fs/smb/client/fs_context.h\n+++ b/fs/smb/client/fs_context.h\n@@ -143,6 +143,7 @@ enum cifs_param {\n \tOpt_tcp_nodelay,\n \tOpt_domainauto,\n \tOpt_rdma,\n+\tOpt_quic,\n \tOpt_modesid,\n \tOpt_rootfs,\n \tOpt_multichannel,\n@@ -199,6 +200,7 @@ enum cifs_param {\n \tOpt_nativesocket,\n \tOpt_symlink,\n \tOpt_symlinkroot,\n+\tOpt_mtls,\n \n \t/* Mount options to be ignored */\n \tOpt_ignore,\n@@ -293,6 +295,8 @@ struct smb3_fs_context {\n \tbool resilient:1; /* noresilient not required since not fored for CA */\n \tbool domainauto:1;\n \tbool rdma:1;\n+\tbool quic:1;\n+\tbool mtls:1;\n \tbool multichannel:1;\n \tbool multichannel_specified:1; /* true if user specified multichannel or nomultichannel */\n \tbool max_channels_specified:1; /* true if user specified max_channels */\ndiff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c\nindex bac88a612d5d..848f9137f01d 100644\n--- a/fs/smb/client/smb2pdu.c\n+++ b/fs/smb/client/smb2pdu.c\n@@ -732,6 +732,16 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)\n \treturn smb2_neg_context_len(pneg_ctxt);\n }\n \n+static unsigned int\n+build_transport_ctxt(struct smb2_transport_capabilities_context *pneg_ctxt)\n+{\n+\tpneg_ctxt->ContextType = SMB2_TRANSPORT_CAPABILITIES;\n+\tpneg_ctxt->DataLength = cpu_to_le16(sizeof(struct smb2_transport_capabilities_context) -\n+\t\t\t\t\t    sizeof(struct smb2_neg_context));\n+\tpneg_ctxt->Flags = cpu_to_le32(SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY);\n+\treturn smb2_neg_context_len(pneg_ctxt);\n+}\n+\n struct neg_ctx {\n \tchar *pos;\n \tunsigned int len;\n@@ -801,6 +811,11 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,\n \tif (enable_negotiate_signing)\n \t\tadd_context(&nc, build_signing_ctxt((struct smb2_signing_capabilities *)nc.pos));\n \n+\tif (cifs_quic_enabled(server) && server->quic_conn.need_smb_seal)\n+\t\tadd_context(&nc,\n+\t\t\t    build_transport_ctxt(\n+\t\t\t\t    (struct smb2_transport_capabilities_context *)nc.pos));\n+\n \t/* check for and add transport_capabilities and signing capabilities */\n \treq->NegotiateContextCount = cpu_to_le16(nc.cnt);\n \n@@ -945,6 +960,15 @@ static void decode_signing_ctx(struct TCP_Server_Info *server,\n \t\t     server->signing_algorithm);\n }\n \n+static void\n+decode_transport_ctx(struct TCP_Server_Info *server,\n+\t\t     struct smb2_transport_capabilities_context *pctxt)\n+{\n+\tif (pctxt->Flags == cpu_to_le32(SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY))\n+\t\tserver->quic_conn.need_smb_seal = false;\n+\telse\n+\t\tserver->quic_conn.need_smb_seal = true;\n+}\n \n static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp,\n \t\t\t\t     struct TCP_Server_Info *server,\n@@ -997,6 +1021,9 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp,\n \t\telse if (pctx->ContextType == SMB2_SIGNING_CAPABILITIES)\n \t\t\tdecode_signing_ctx(server,\n \t\t\t\t(struct smb2_signing_capabilities *)pctx);\n+\t\telse if (pctx->ContextType == SMB2_TRANSPORT_CAPABILITIES)\n+\t\t\tdecode_transport_ctx(server,\n+\t\t\t\t(struct smb2_transport_capabilities_context *)pctx);\n \t\telse\n \t\t\tcifs_server_dbg(VFS, \"unknown negcontext of type %d ignored\\n\",\n \t\t\t\tle16_to_cpu(pctx->ContextType));\ndiff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c\nindex e64becee928f..46a67c7eba54 100644\n--- a/fs/smb/client/transport.c\n+++ b/fs/smb/client/transport.c\n@@ -23,6 +23,7 @@\n #include <linux/sched/signal.h>\n #include <linux/task_io_accounting_ops.h>\n #include <linux/task_work.h>\n+#include <linux/quic.h>\n #include \"cifsglob.h\"\n #include \"cifsproto.h\"\n #include \"cifs_debug.h\"\n@@ -148,10 +149,12 @@ smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,\n \n \t*sent = 0;\n \n-\tif (server->noblocksnd)\n-\t\tsmb_msg->msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;\n-\telse\n-\t\tsmb_msg->msg_flags = MSG_NOSIGNAL;\n+\tif (cifs_quic_enabled(server)) {\n+\t\tif (server->noblocksnd)\n+\t\t\tsmb_msg->msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;\n+\t\telse\n+\t\t\tsmb_msg->msg_flags = MSG_NOSIGNAL;\n+\t}\n \n \twhile (msg_data_left(smb_msg)) {\n \t\t/*\n@@ -270,7 +273,8 @@ int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,\n \n \trc = 0;\n \t/* cork the socket */\n-\ttcp_sock_set_cork(ssocket->sk, true);\n+\tif (!cifs_quic_enabled(server))\n+\t\ttcp_sock_set_cork(ssocket->sk, true);\n \n \tfor (j = 0; j < num_rqst; j++)\n \t\tsend_length += smb_rqst_len(server, &rqst[j]);\n@@ -287,19 +291,17 @@ int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,\n \tsigprocmask(SIG_BLOCK, &mask, &oldmask);\n \n \t/* Generate a rfc1002 marker */\n-\t{\n-\t\tstruct kvec hiov = {\n-\t\t\t.iov_base = &rfc1002_marker,\n-\t\t\t.iov_len  = 4\n-\t\t};\n-\t\tiov_iter_kvec(&smb_msg.msg_iter, ITER_SOURCE, &hiov, 1, 4);\n-\t\trc = smb_send_kvec(server, &smb_msg, &sent);\n-\t\tif (rc < 0)\n-\t\t\tgoto unmask;\n+\tstruct kvec hiov = {\n+\t\t.iov_base = &rfc1002_marker,\n+\t\t.iov_len  = 4\n+\t};\n+\tiov_iter_kvec(&smb_msg.msg_iter, ITER_SOURCE, &hiov, 1, 4);\n+\trc = smb_send_kvec(server, &smb_msg, &sent);\n+\tif (rc < 0)\n+\t\tgoto unmask;\n \n-\t\ttotal_len += sent;\n-\t\tsend_length += 4;\n-\t}\n+\ttotal_len += sent;\n+\tsend_length += 4;\n \n \tcifs_dbg(FYI, \"Sending smb: smb_len=%u\\n\", send_length);\n \n@@ -350,7 +352,9 @@ int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,\n \t}\n \n \t/* uncork it */\n-\ttcp_sock_set_cork(ssocket->sk, false);\n+\n+\tif (!cifs_quic_enabled(server))\n+\t\ttcp_sock_set_cork(ssocket->sk, false);\n \n \tif ((total_len > 0) && (total_len != send_length)) {\n \t\tcifs_dbg(FYI, \"partial send (wanted=%u sent=%zu): terminating session\\n\",\n","prefixes":["03/11"]}