public inbox for linux-cifs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] cifs: implementation id context as negotiate context
@ 2026-03-04 12:27 nspmangalore
  2026-03-04 12:34 ` Shyam Prasad N
  2026-03-09 16:19 ` Ralph Boehme
  0 siblings, 2 replies; 15+ messages in thread
From: nspmangalore @ 2026-03-04 12:27 UTC (permalink / raw)
  To: linux-cifs, smfrench, pc, bharathsm, dhowells; +Cc: Shyam Prasad N

From: Shyam Prasad N <sprasad@microsoft.com>

MS-SMB2 does not allow any fields for the client to communicate
the client version details to the server. This change is a
proof-of-concept to add client details in a new negotiate context.

Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
---
 fs/smb/client/smb2pdu.c | 78 +++++++++++++++++++++++++++++++++++++++++
 fs/smb/common/smb2pdu.h | 32 +++++++++++++++++
 2 files changed, 110 insertions(+)

diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index ef655acf673df..9c89f6b4a6709 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -24,6 +24,7 @@
 #include <linux/pagemap.h>
 #include <linux/xattr.h>
 #include <linux/netfs.h>
+#include <linux/utsname.h>
 #include <trace/events/netfs.h>
 #include "cifsglob.h"
 #include "cifsproto.h"
@@ -45,6 +46,7 @@
 #include "cached_dir.h"
 #include "compress.h"
 #include "fs_context.h"
+#include "cifsfs.h"
 
 /*
  *  The following table defines the expected "StructureSize" of SMB2 requests
@@ -724,6 +726,75 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
 	pneg_ctxt->Name[15] = 0x7C;
 }
 
+static unsigned int
+build_implementation_id_ctxt(struct smb2_implementation_id_context *pneg_ctxt)
+{
+	struct nls_table *cp = load_nls_default();
+	struct new_utsname *uts = utsname();
+	const char *impl_domain = "kernel.org";
+	const char *impl_name = "fs/smb/client";
+	const char *os_name = "Linux";
+	unsigned int data_len = 0;
+	__u8 *data_ptr;
+	int len;
+
+	pneg_ctxt->ContextType = SMB2_IMPLEMENTATION_ID_CONTEXT_ID;
+	data_ptr = pneg_ctxt->Data;
+
+	/* ImplDomain */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, impl_domain,
+			      SMB2_IMPL_ID_MAX_DOMAIN_LEN, cp);
+	pneg_ctxt->ImplDomainLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* ImplName */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, impl_name,
+			      SMB2_IMPL_ID_MAX_NAME_LEN, cp);
+	pneg_ctxt->ImplNameLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* ImplVersion - CIFS_VERSION from cifsfs.h */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, CIFS_VERSION,
+			      SMB2_IMPL_ID_MAX_VERSION_LEN, cp);
+	pneg_ctxt->ImplVersionLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* HostName - from utsname()->nodename */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, uts->nodename,
+			      SMB2_IMPL_ID_MAX_HOSTNAME_LEN, cp);
+	pneg_ctxt->HostNameLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* OSName */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, os_name,
+			      SMB2_IMPL_ID_MAX_OS_NAME_LEN, cp);
+	pneg_ctxt->OSNameLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* OSVersion - from utsname()->release */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, uts->release,
+			      SMB2_IMPL_ID_MAX_OS_VERSION_LEN, cp);
+	pneg_ctxt->OSVersionLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* Arch - from utsname()->machine */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, uts->machine,
+			      SMB2_IMPL_ID_MAX_ARCH_LEN, cp);
+	pneg_ctxt->ArchLength = cpu_to_le16(len * 2);
+	data_len += len * 2;
+
+	pneg_ctxt->Reserved2 = 0;
+	pneg_ctxt->DataLength = cpu_to_le16(data_len + 14); /* 14 = 7 length fields * 2 bytes */
+	/* Context size is DataLength + minimal smb2_neg_context, aligned to 8 */
+	return ALIGN(le16_to_cpu(pneg_ctxt->DataLength) + sizeof(struct smb2_neg_context), 8);
+}
+
 static void
 assemble_neg_contexts(struct smb2_negotiate_req *req,
 		      struct TCP_Server_Info *server, unsigned int *total_len)
@@ -797,6 +868,13 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
 		neg_context_count++;
 	}
 
+	/* Add implementation ID context */
+	ctxt_len = build_implementation_id_ctxt((struct smb2_implementation_id_context *)
+				pneg_ctxt);
+	*total_len += ctxt_len;
+	pneg_ctxt += ctxt_len;
+	neg_context_count++;
+
 	/* check for and add transport_capabilities and signing capabilities */
 	req->NegotiateContextCount = cpu_to_le16(neg_context_count);
 
diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
index e482c86ceb00d..1ad7b57ce2952 100644
--- a/fs/smb/common/smb2pdu.h
+++ b/fs/smb/common/smb2pdu.h
@@ -457,6 +457,7 @@ struct smb2_tree_disconnect_rsp {
 #define SMB2_TRANSPORT_CAPABILITIES		cpu_to_le16(6)
 #define SMB2_RDMA_TRANSFORM_CAPABILITIES	cpu_to_le16(7)
 #define SMB2_SIGNING_CAPABILITIES		cpu_to_le16(8)
+#define SMB2_IMPLEMENTATION_ID_CONTEXT_ID	cpu_to_le16(0xF100)
 #define SMB2_POSIX_EXTENSIONS_AVAILABLE		cpu_to_le16(0x100)
 
 struct smb2_neg_context {
@@ -596,6 +597,37 @@ struct smb2_signing_capabilities {
 	/*  Followed by padding to 8 byte boundary (required by some servers) */
 } __packed;
 
+/*
+ * For implementation ID context see MS-SMB2 2.2.3.1.8
+ * Maximum string lengths per specification
+ */
+#define SMB2_IMPL_ID_MAX_DOMAIN_LEN	128
+#define SMB2_IMPL_ID_MAX_NAME_LEN	260
+#define SMB2_IMPL_ID_MAX_VERSION_LEN	260
+#define SMB2_IMPL_ID_MAX_HOSTNAME_LEN	64
+#define SMB2_IMPL_ID_MAX_OS_NAME_LEN	64
+#define SMB2_IMPL_ID_MAX_OS_VERSION_LEN	64
+#define SMB2_IMPL_ID_MAX_ARCH_LEN	64
+
+struct smb2_implementation_id_context {
+	__le16	ContextType; /* 9 */
+	__le16	DataLength;
+	__le32	Reserved;
+	__le16	ImplDomainLength;
+	__le16	ImplNameLength;
+	__le16	ImplVersionLength;
+	__le16	HostNameLength;
+	__le16	OSNameLength;
+	__le16	OSVersionLength;
+	__le16	ArchLength;
+	__le16	Reserved2;
+	/* Followed by variable length UTF-16 strings:
+	 * ImplDomain, ImplName, ImplVersion, HostName,
+	 * OSName, OSVersion, Arch
+	 */
+	__u8	Data[];
+} __packed;
+
 #define POSIX_CTXT_DATA_LEN	16
 struct smb2_posix_neg_context {
 	__le16	ContextType; /* 0x100 */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-04 12:27 [PATCH] cifs: implementation id context as negotiate context nspmangalore
@ 2026-03-04 12:34 ` Shyam Prasad N
  2026-03-06 22:45   ` Henrique Carvalho
  2026-03-09 16:19 ` Ralph Boehme
  1 sibling, 1 reply; 15+ messages in thread
From: Shyam Prasad N @ 2026-03-04 12:34 UTC (permalink / raw)
  To: linux-cifs, smfrench, pc, bharathsm, dhowells; +Cc: Shyam Prasad N

[-- Attachment #1: Type: text/plain, Size: 7181 bytes --]

On Wed, Mar 4, 2026 at 5:59 PM <nspmangalore@gmail.com> wrote:
>
> From: Shyam Prasad N <sprasad@microsoft.com>
>
> MS-SMB2 does not allow any fields for the client to communicate
> the client version details to the server. This change is a
> proof-of-concept to add client details in a new negotiate context.
>
> Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
> ---
>  fs/smb/client/smb2pdu.c | 78 +++++++++++++++++++++++++++++++++++++++++
>  fs/smb/common/smb2pdu.h | 32 +++++++++++++++++
>  2 files changed, 110 insertions(+)
>
> diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
> index ef655acf673df..9c89f6b4a6709 100644
> --- a/fs/smb/client/smb2pdu.c
> +++ b/fs/smb/client/smb2pdu.c
> @@ -24,6 +24,7 @@
>  #include <linux/pagemap.h>
>  #include <linux/xattr.h>
>  #include <linux/netfs.h>
> +#include <linux/utsname.h>
>  #include <trace/events/netfs.h>
>  #include "cifsglob.h"
>  #include "cifsproto.h"
> @@ -45,6 +46,7 @@
>  #include "cached_dir.h"
>  #include "compress.h"
>  #include "fs_context.h"
> +#include "cifsfs.h"
>
>  /*
>   *  The following table defines the expected "StructureSize" of SMB2 requests
> @@ -724,6 +726,75 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
>         pneg_ctxt->Name[15] = 0x7C;
>  }
>
> +static unsigned int
> +build_implementation_id_ctxt(struct smb2_implementation_id_context *pneg_ctxt)
> +{
> +       struct nls_table *cp = load_nls_default();
> +       struct new_utsname *uts = utsname();
> +       const char *impl_domain = "kernel.org";
> +       const char *impl_name = "fs/smb/client";
> +       const char *os_name = "Linux";
> +       unsigned int data_len = 0;
> +       __u8 *data_ptr;
> +       int len;
> +
> +       pneg_ctxt->ContextType = SMB2_IMPLEMENTATION_ID_CONTEXT_ID;
> +       data_ptr = pneg_ctxt->Data;
> +
> +       /* ImplDomain */
> +       len = cifs_strtoUTF16((__le16 *)data_ptr, impl_domain,
> +                             SMB2_IMPL_ID_MAX_DOMAIN_LEN, cp);
> +       pneg_ctxt->ImplDomainLength = cpu_to_le16(len * 2);
> +       data_ptr += len * 2;
> +       data_len += len * 2;
> +
> +       /* ImplName */
> +       len = cifs_strtoUTF16((__le16 *)data_ptr, impl_name,
> +                             SMB2_IMPL_ID_MAX_NAME_LEN, cp);
> +       pneg_ctxt->ImplNameLength = cpu_to_le16(len * 2);
> +       data_ptr += len * 2;
> +       data_len += len * 2;
> +
> +       /* ImplVersion - CIFS_VERSION from cifsfs.h */
> +       len = cifs_strtoUTF16((__le16 *)data_ptr, CIFS_VERSION,
> +                             SMB2_IMPL_ID_MAX_VERSION_LEN, cp);
> +       pneg_ctxt->ImplVersionLength = cpu_to_le16(len * 2);
> +       data_ptr += len * 2;
> +       data_len += len * 2;
> +
> +       /* HostName - from utsname()->nodename */
> +       len = cifs_strtoUTF16((__le16 *)data_ptr, uts->nodename,
> +                             SMB2_IMPL_ID_MAX_HOSTNAME_LEN, cp);
> +       pneg_ctxt->HostNameLength = cpu_to_le16(len * 2);
> +       data_ptr += len * 2;
> +       data_len += len * 2;
> +
> +       /* OSName */
> +       len = cifs_strtoUTF16((__le16 *)data_ptr, os_name,
> +                             SMB2_IMPL_ID_MAX_OS_NAME_LEN, cp);
> +       pneg_ctxt->OSNameLength = cpu_to_le16(len * 2);
> +       data_ptr += len * 2;
> +       data_len += len * 2;
> +
> +       /* OSVersion - from utsname()->release */
> +       len = cifs_strtoUTF16((__le16 *)data_ptr, uts->release,
> +                             SMB2_IMPL_ID_MAX_OS_VERSION_LEN, cp);
> +       pneg_ctxt->OSVersionLength = cpu_to_le16(len * 2);
> +       data_ptr += len * 2;
> +       data_len += len * 2;
> +
> +       /* Arch - from utsname()->machine */
> +       len = cifs_strtoUTF16((__le16 *)data_ptr, uts->machine,
> +                             SMB2_IMPL_ID_MAX_ARCH_LEN, cp);
> +       pneg_ctxt->ArchLength = cpu_to_le16(len * 2);
> +       data_len += len * 2;
> +
> +       pneg_ctxt->Reserved2 = 0;
> +       pneg_ctxt->DataLength = cpu_to_le16(data_len + 14); /* 14 = 7 length fields * 2 bytes */
> +       /* Context size is DataLength + minimal smb2_neg_context, aligned to 8 */
> +       return ALIGN(le16_to_cpu(pneg_ctxt->DataLength) + sizeof(struct smb2_neg_context), 8);
> +}
> +
>  static void
>  assemble_neg_contexts(struct smb2_negotiate_req *req,
>                       struct TCP_Server_Info *server, unsigned int *total_len)
> @@ -797,6 +868,13 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
>                 neg_context_count++;
>         }
>
> +       /* Add implementation ID context */
> +       ctxt_len = build_implementation_id_ctxt((struct smb2_implementation_id_context *)
> +                               pneg_ctxt);
> +       *total_len += ctxt_len;
> +       pneg_ctxt += ctxt_len;
> +       neg_context_count++;
> +
>         /* check for and add transport_capabilities and signing capabilities */
>         req->NegotiateContextCount = cpu_to_le16(neg_context_count);
>
> diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
> index e482c86ceb00d..1ad7b57ce2952 100644
> --- a/fs/smb/common/smb2pdu.h
> +++ b/fs/smb/common/smb2pdu.h
> @@ -457,6 +457,7 @@ struct smb2_tree_disconnect_rsp {
>  #define SMB2_TRANSPORT_CAPABILITIES            cpu_to_le16(6)
>  #define SMB2_RDMA_TRANSFORM_CAPABILITIES       cpu_to_le16(7)
>  #define SMB2_SIGNING_CAPABILITIES              cpu_to_le16(8)
> +#define SMB2_IMPLEMENTATION_ID_CONTEXT_ID      cpu_to_le16(0xF100)
>  #define SMB2_POSIX_EXTENSIONS_AVAILABLE                cpu_to_le16(0x100)
>
>  struct smb2_neg_context {
> @@ -596,6 +597,37 @@ struct smb2_signing_capabilities {
>         /*  Followed by padding to 8 byte boundary (required by some servers) */
>  } __packed;
>
> +/*
> + * For implementation ID context see MS-SMB2 2.2.3.1.8
> + * Maximum string lengths per specification
> + */
> +#define SMB2_IMPL_ID_MAX_DOMAIN_LEN    128
> +#define SMB2_IMPL_ID_MAX_NAME_LEN      260
> +#define SMB2_IMPL_ID_MAX_VERSION_LEN   260
> +#define SMB2_IMPL_ID_MAX_HOSTNAME_LEN  64
> +#define SMB2_IMPL_ID_MAX_OS_NAME_LEN   64
> +#define SMB2_IMPL_ID_MAX_OS_VERSION_LEN        64
> +#define SMB2_IMPL_ID_MAX_ARCH_LEN      64
> +
> +struct smb2_implementation_id_context {
> +       __le16  ContextType; /* 9 */
> +       __le16  DataLength;
> +       __le32  Reserved;
> +       __le16  ImplDomainLength;
> +       __le16  ImplNameLength;
> +       __le16  ImplVersionLength;
> +       __le16  HostNameLength;
> +       __le16  OSNameLength;
> +       __le16  OSVersionLength;
> +       __le16  ArchLength;
> +       __le16  Reserved2;
> +       /* Followed by variable length UTF-16 strings:
> +        * ImplDomain, ImplName, ImplVersion, HostName,
> +        * OSName, OSVersion, Arch
> +        */
> +       __u8    Data[];
> +} __packed;
> +
>  #define POSIX_CTXT_DATA_LEN    16
>  struct smb2_posix_neg_context {
>         __le16  ContextType; /* 0x100 */
> --
> 2.43.0
>

A proof-of-concept based on this draft from Bharath.
Looking for comments on how to improve.

-- 
Regards,
Shyam

[-- Attachment #2: SMB2_IMPL_ID_Design.pdf --]
[-- Type: application/pdf, Size: 372482 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-04 12:34 ` Shyam Prasad N
@ 2026-03-06 22:45   ` Henrique Carvalho
  2026-03-06 23:04     ` Steve French
  0 siblings, 1 reply; 15+ messages in thread
From: Henrique Carvalho @ 2026-03-06 22:45 UTC (permalink / raw)
  To: Shyam Prasad N
  Cc: linux-cifs, smfrench, pc, bharathsm, dhowells, Shyam Prasad N

On Wed, Mar 04, 2026 at 06:04:05PM +0530, Shyam Prasad N wrote: > On Wed, Mar 4, 2026 at 5:59 PM <nspmangalore@gmail.com> wrote: From: Shyam Prasad N <sprasad@microsoft.com>
> 
> A proof-of-concept based on this draft from Bharath.
> Looking for comments on how to improve.

Looks good.

Just one minor thing for now. To me the cifs.ko module version doesn't
say much as it seems to be not reliable (apologies if I'm mistaken).

Also, the same version could have different implementations in different
distributions. modinfo -F srcversion cifs is a better way to
differentiate cifs versions but not to compare versions. So the solution
is either remove this or bump it in every change using X.Y.Z.

Further, have you thought about how the client can use this in its favor
other than diagnosing/debugging a faulty server?

I think we need to be clear on what is allowed here, to me it seems
quirks, workarounds and perf tuning? Maybe this can be used to improve
interaction between linux client and linux server?

Thanks,

-- 
Henrique
SUSE Labs

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-06 22:45   ` Henrique Carvalho
@ 2026-03-06 23:04     ` Steve French
  2026-03-06 23:19       ` Paulo Alcantara
  2026-03-06 23:30       ` Henrique Carvalho
  0 siblings, 2 replies; 15+ messages in thread
From: Steve French @ 2026-03-06 23:04 UTC (permalink / raw)
  To: Henrique Carvalho
  Cc: Shyam Prasad N, linux-cifs, pc, bharathsm, dhowells,
	Shyam Prasad N

On Fri, Mar 6, 2026 at 4:45 PM Henrique Carvalho
<henrique.carvalho@suse.com> wrote:
>
> On Wed, Mar 04, 2026 at 06:04:05PM +0530, Shyam Prasad N wrote: > On Wed, Mar 4, 2026 at 5:59 PM <nspmangalore@gmail.com> wrote: From: Shyam Prasad N <sprasad@microsoft.com>
> >
> > A proof-of-concept based on this draft from Bharath.
> > Looking for comments on how to improve.
>
> Looks good.
>
> Just one minor thing for now. To me the cifs.ko module version doesn't
> say much as it seems to be not reliable (apologies if I'm mistaken).

It does get incremented every 10 weeks.

> Also, the same version could have different implementations in different
> distributions. modinfo -F srcversion cifs is a better way to
> differentiate cifs versions but not to compare versions. So the solution
> is either remove this or bump it in every change using X.Y.Z.

We do bump the module version every kernel release, e.g. we are at
2.59 in Linux 7.0 (7.0-rc2)
Would bump it when someone does a 'full backport' of most cifs fixes
to an earlier kernel.

> Further, have you thought about how the client can use this in its favor
> other than diagnosing/debugging a faulty server?

I thought this was for the reverse - so the server support team can
get metrics on whether the client is an old client with known bugs

> I think we need to be clear on what is allowed here, to me it seems
> quirks, workarounds and perf tuning? Maybe this can be used to improve
> interaction between linux client and linux server?

presumably primarily for customer support to be able to recognise
known client problems on clients accessing a server


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-06 23:04     ` Steve French
@ 2026-03-06 23:19       ` Paulo Alcantara
  2026-03-06 23:23         ` Steve French
  2026-03-09 16:34         ` Shyam Prasad N
  2026-03-06 23:30       ` Henrique Carvalho
  1 sibling, 2 replies; 15+ messages in thread
From: Paulo Alcantara @ 2026-03-06 23:19 UTC (permalink / raw)
  To: Steve French, Henrique Carvalho
  Cc: Shyam Prasad N, linux-cifs, bharathsm, dhowells, Shyam Prasad N

Steve French <smfrench@gmail.com> writes:

> On Fri, Mar 6, 2026 at 4:45 PM Henrique Carvalho
> <henrique.carvalho@suse.com> wrote:
>>
>> On Wed, Mar 04, 2026 at 06:04:05PM +0530, Shyam Prasad N wrote: > On Wed, Mar 4, 2026 at 5:59 PM <nspmangalore@gmail.com> wrote: From: Shyam Prasad N <sprasad@microsoft.com>
>> >
>> > A proof-of-concept based on this draft from Bharath.
>> > Looking for comments on how to improve.
>>
>> Looks good.
>>
>> Just one minor thing for now. To me the cifs.ko module version doesn't
>> say much as it seems to be not reliable (apologies if I'm mistaken).
>
> It does get incremented every 10 weeks.
>
>> Also, the same version could have different implementations in different
>> distributions. modinfo -F srcversion cifs is a better way to
>> differentiate cifs versions but not to compare versions. So the solution
>> is either remove this or bump it in every change using X.Y.Z.
>
> We do bump the module version every kernel release, e.g. we are at
> 2.59 in Linux 7.0 (7.0-rc2)
> Would bump it when someone does a 'full backport' of most cifs fixes
> to an earlier kernel.

Who?

>> Further, have you thought about how the client can use this in its favor
>> other than diagnosing/debugging a faulty server?
>
> I thought this was for the reverse - so the server support team can
> get metrics on whether the client is an old client with known bugs

The client version is entirely pointless, especially for distribution
kernels.  The support team can't figure out by just looking at the
client version as the backports are what really matter in terms of a
distro kernel.  Most distro kernels don't even bother backporting those
commits that bump the client version, which makes it even more
inaccurate.

>> I think we need to be clear on what is allowed here, to me it seems
>> quirks, workarounds and perf tuning? Maybe this can be used to improve
>> interaction between linux client and linux server?
>
> presumably primarily for customer support to be able to recognise
> known client problems on clients accessing a server

Neither the client or kernel version will tell you _exactly_ where the
problem is in distro kernels.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-06 23:19       ` Paulo Alcantara
@ 2026-03-06 23:23         ` Steve French
  2026-03-09 16:34         ` Shyam Prasad N
  1 sibling, 0 replies; 15+ messages in thread
From: Steve French @ 2026-03-06 23:23 UTC (permalink / raw)
  To: Paulo Alcantara
  Cc: Henrique Carvalho, Shyam Prasad N, linux-cifs, bharathsm,
	dhowells, Shyam Prasad N

On Fri, Mar 6, 2026 at 5:19 PM Paulo Alcantara <pc@manguebit.org> wrote:
>
> Steve French <smfrench@gmail.com> writes:
>
> > On Fri, Mar 6, 2026 at 4:45 PM Henrique Carvalho
> > <henrique.carvalho@suse.com> wrote:
> >>
> >> On Wed, Mar 04, 2026 at 06:04:05PM +0530, Shyam Prasad N wrote: > On Wed, Mar 4, 2026 at 5:59 PM <nspmangalore@gmail.com> wrote: From: Shyam Prasad N <sprasad@microsoft.com>
> >> >
> >> > A proof-of-concept based on this draft from Bharath.
> >> > Looking for comments on how to improve.
> >>
> >> Looks good.
> >>
> >> Just one minor thing for now. To me the cifs.ko module version doesn't
> >> say much as it seems to be not reliable (apologies if I'm mistaken).
> >
> > It does get incremented every 10 weeks.
> >
> >> Also, the same version could have different implementations in different
> >> distributions. modinfo -F srcversion cifs is a better way to
> >> differentiate cifs versions but not to compare versions. So the solution
> >> is either remove this or bump it in every change using X.Y.Z.
> >
> > We do bump the module version every kernel release, e.g. we are at
> > 2.59 in Linux 7.0 (7.0-rc2)
> > Would bump it when someone does a 'full backport' of most cifs fixes
> > to an earlier kernel.
>
> Who?
>
> >> Further, have you thought about how the client can use this in its favor
> >> other than diagnosing/debugging a faulty server?
> >
> > I thought this was for the reverse - so the server support team can
> > get metrics on whether the client is an old client with known bugs
>
> The client version is entirely pointless, especially for distribution
> kernels.  The support team can't figure out by just looking at the
> client version as the backports are what really matter in terms of a
> distro kernel.  Most distro kernels don't even bother backporting those
> commits that bump the client version, which makes it even more
> inaccurate.
>
> >> I think we need to be clear on what is allowed here, to me it seems
> >> quirks, workarounds and perf tuning? Maybe this can be used to improve
> >> interaction between linux client and linux server?
> >
> > presumably primarily for customer support to be able to recognise
> > known client problems on clients accessing a server
>
> Neither the client or kernel version will tell you _exactly_ where the
> problem is in distro kernels.

The combination of the various version fields would be 99% likely to
be able to match to a particular distro version (at least for the
major ones, SuSE, Redhat, Ubuntu, Mariner).  Unfortunately there are
many customers out there who run kernels more than four years old so
can be helpful to know client os version

-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-06 23:04     ` Steve French
  2026-03-06 23:19       ` Paulo Alcantara
@ 2026-03-06 23:30       ` Henrique Carvalho
  1 sibling, 0 replies; 15+ messages in thread
From: Henrique Carvalho @ 2026-03-06 23:30 UTC (permalink / raw)
  To: Steve French
  Cc: Shyam Prasad N, linux-cifs, pc, bharathsm, dhowells,
	Shyam Prasad N

On Fri, Mar 06, 2026 at 05:04:20PM -0600, Steve French wrote:
> On Fri, Mar 6, 2026 at 4:45 PM Henrique Carvalho
> <henrique.carvalho@suse.com> wrote:
> >
> > On Wed, Mar 04, 2026 at 06:04:05PM +0530, Shyam Prasad N wrote: > On Wed, Mar 4, 2026 at 5:59 PM <nspmangalore@gmail.com> wrote: From: Shyam Prasad N <sprasad@microsoft.com>
> > >
> > > A proof-of-concept based on this draft from Bharath.
> > > Looking for comments on how to improve.
> >
> > Looks good.
> >
> > Just one minor thing for now. To me the cifs.ko module version doesn't
> > say much as it seems to be not reliable (apologies if I'm mistaken).
> 
> It does get incremented every 10 weeks.
> 

Okay. I guess we've skipped sometimes.

> > Also, the same version could have different implementations in different
> > distributions. modinfo -F srcversion cifs is a better way to
> > differentiate cifs versions but not to compare versions. So the solution
> > is either remove this or bump it in every change using X.Y.Z.
> 
> We do bump the module version every kernel release, e.g. we are at
> 2.59 in Linux 7.0 (7.0-rc2)
> Would bump it when someone does a 'full backport' of most cifs fixes
> to an earlier kernel.
> 
> > Further, have you thought about how the client can use this in its favor
> > other than diagnosing/debugging a faulty server?
> 
> I thought this was for the reverse - so the server support team can
> get metrics on whether the client is an old client with known bugs
> 
> > I think we need to be clear on what is allowed here, to me it seems
> > quirks, workarounds and perf tuning? Maybe this can be used to improve
> > interaction between linux client and linux server?
> 
> presumably primarily for customer support to be able to recognise
> known client problems on clients accessing a server
> 

Yes, but also the server will be able to send back context as well,
correct? This may allow more than bug triaging.

-- 
Henrique
SUSE Labs

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-04 12:27 [PATCH] cifs: implementation id context as negotiate context nspmangalore
  2026-03-04 12:34 ` Shyam Prasad N
@ 2026-03-09 16:19 ` Ralph Boehme
  2026-03-09 16:37   ` Shyam Prasad N
  1 sibling, 1 reply; 15+ messages in thread
From: Ralph Boehme @ 2026-03-09 16:19 UTC (permalink / raw)
  To: nspmangalore, linux-cifs, smfrench, pc, bharathsm, dhowells
  Cc: Shyam Prasad N


[-- Attachment #1.1: Type: text/plain, Size: 6628 bytes --]

Hi!

I wonder which servers are expected to be implementing this? I suppose 
this protocol extension is not proposed without a server vendor 
interested in actually implementing it, otherwise the whole metrics 
story doesn't make sense.

*scratches head*

Thanks!
-slow

On 3/4/26 1:27 PM, nspmangalore@gmail.com wrote:
> From: Shyam Prasad N <sprasad@microsoft.com>
> 
> MS-SMB2 does not allow any fields for the client to communicate
> the client version details to the server. This change is a
> proof-of-concept to add client details in a new negotiate context.
> 
> Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
> ---
>   fs/smb/client/smb2pdu.c | 78 +++++++++++++++++++++++++++++++++++++++++
>   fs/smb/common/smb2pdu.h | 32 +++++++++++++++++
>   2 files changed, 110 insertions(+)
> 
> diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
> index ef655acf673df..9c89f6b4a6709 100644
> --- a/fs/smb/client/smb2pdu.c
> +++ b/fs/smb/client/smb2pdu.c
> @@ -24,6 +24,7 @@
>   #include <linux/pagemap.h>
>   #include <linux/xattr.h>
>   #include <linux/netfs.h>
> +#include <linux/utsname.h>
>   #include <trace/events/netfs.h>
>   #include "cifsglob.h"
>   #include "cifsproto.h"
> @@ -45,6 +46,7 @@
>   #include "cached_dir.h"
>   #include "compress.h"
>   #include "fs_context.h"
> +#include "cifsfs.h"
>   
>   /*
>    *  The following table defines the expected "StructureSize" of SMB2 requests
> @@ -724,6 +726,75 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
>   	pneg_ctxt->Name[15] = 0x7C;
>   }
>   
> +static unsigned int
> +build_implementation_id_ctxt(struct smb2_implementation_id_context *pneg_ctxt)
> +{
> +	struct nls_table *cp = load_nls_default();
> +	struct new_utsname *uts = utsname();
> +	const char *impl_domain = "kernel.org";
> +	const char *impl_name = "fs/smb/client";
> +	const char *os_name = "Linux";
> +	unsigned int data_len = 0;
> +	__u8 *data_ptr;
> +	int len;
> +
> +	pneg_ctxt->ContextType = SMB2_IMPLEMENTATION_ID_CONTEXT_ID;
> +	data_ptr = pneg_ctxt->Data;
> +
> +	/* ImplDomain */
> +	len = cifs_strtoUTF16((__le16 *)data_ptr, impl_domain,
> +			      SMB2_IMPL_ID_MAX_DOMAIN_LEN, cp);
> +	pneg_ctxt->ImplDomainLength = cpu_to_le16(len * 2);
> +	data_ptr += len * 2;
> +	data_len += len * 2;
> +
> +	/* ImplName */
> +	len = cifs_strtoUTF16((__le16 *)data_ptr, impl_name,
> +			      SMB2_IMPL_ID_MAX_NAME_LEN, cp);
> +	pneg_ctxt->ImplNameLength = cpu_to_le16(len * 2);
> +	data_ptr += len * 2;
> +	data_len += len * 2;
> +
> +	/* ImplVersion - CIFS_VERSION from cifsfs.h */
> +	len = cifs_strtoUTF16((__le16 *)data_ptr, CIFS_VERSION,
> +			      SMB2_IMPL_ID_MAX_VERSION_LEN, cp);
> +	pneg_ctxt->ImplVersionLength = cpu_to_le16(len * 2);
> +	data_ptr += len * 2;
> +	data_len += len * 2;
> +
> +	/* HostName - from utsname()->nodename */
> +	len = cifs_strtoUTF16((__le16 *)data_ptr, uts->nodename,
> +			      SMB2_IMPL_ID_MAX_HOSTNAME_LEN, cp);
> +	pneg_ctxt->HostNameLength = cpu_to_le16(len * 2);
> +	data_ptr += len * 2;
> +	data_len += len * 2;
> +
> +	/* OSName */
> +	len = cifs_strtoUTF16((__le16 *)data_ptr, os_name,
> +			      SMB2_IMPL_ID_MAX_OS_NAME_LEN, cp);
> +	pneg_ctxt->OSNameLength = cpu_to_le16(len * 2);
> +	data_ptr += len * 2;
> +	data_len += len * 2;
> +
> +	/* OSVersion - from utsname()->release */
> +	len = cifs_strtoUTF16((__le16 *)data_ptr, uts->release,
> +			      SMB2_IMPL_ID_MAX_OS_VERSION_LEN, cp);
> +	pneg_ctxt->OSVersionLength = cpu_to_le16(len * 2);
> +	data_ptr += len * 2;
> +	data_len += len * 2;
> +
> +	/* Arch - from utsname()->machine */
> +	len = cifs_strtoUTF16((__le16 *)data_ptr, uts->machine,
> +			      SMB2_IMPL_ID_MAX_ARCH_LEN, cp);
> +	pneg_ctxt->ArchLength = cpu_to_le16(len * 2);
> +	data_len += len * 2;
> +
> +	pneg_ctxt->Reserved2 = 0;
> +	pneg_ctxt->DataLength = cpu_to_le16(data_len + 14); /* 14 = 7 length fields * 2 bytes */
> +	/* Context size is DataLength + minimal smb2_neg_context, aligned to 8 */
> +	return ALIGN(le16_to_cpu(pneg_ctxt->DataLength) + sizeof(struct smb2_neg_context), 8);
> +}
> +
>   static void
>   assemble_neg_contexts(struct smb2_negotiate_req *req,
>   		      struct TCP_Server_Info *server, unsigned int *total_len)
> @@ -797,6 +868,13 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
>   		neg_context_count++;
>   	}
>   
> +	/* Add implementation ID context */
> +	ctxt_len = build_implementation_id_ctxt((struct smb2_implementation_id_context *)
> +				pneg_ctxt);
> +	*total_len += ctxt_len;
> +	pneg_ctxt += ctxt_len;
> +	neg_context_count++;
> +
>   	/* check for and add transport_capabilities and signing capabilities */
>   	req->NegotiateContextCount = cpu_to_le16(neg_context_count);
>   
> diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
> index e482c86ceb00d..1ad7b57ce2952 100644
> --- a/fs/smb/common/smb2pdu.h
> +++ b/fs/smb/common/smb2pdu.h
> @@ -457,6 +457,7 @@ struct smb2_tree_disconnect_rsp {
>   #define SMB2_TRANSPORT_CAPABILITIES		cpu_to_le16(6)
>   #define SMB2_RDMA_TRANSFORM_CAPABILITIES	cpu_to_le16(7)
>   #define SMB2_SIGNING_CAPABILITIES		cpu_to_le16(8)
> +#define SMB2_IMPLEMENTATION_ID_CONTEXT_ID	cpu_to_le16(0xF100)
>   #define SMB2_POSIX_EXTENSIONS_AVAILABLE		cpu_to_le16(0x100)
>   
>   struct smb2_neg_context {
> @@ -596,6 +597,37 @@ struct smb2_signing_capabilities {
>   	/*  Followed by padding to 8 byte boundary (required by some servers) */
>   } __packed;
>   
> +/*
> + * For implementation ID context see MS-SMB2 2.2.3.1.8
> + * Maximum string lengths per specification
> + */
> +#define SMB2_IMPL_ID_MAX_DOMAIN_LEN	128
> +#define SMB2_IMPL_ID_MAX_NAME_LEN	260
> +#define SMB2_IMPL_ID_MAX_VERSION_LEN	260
> +#define SMB2_IMPL_ID_MAX_HOSTNAME_LEN	64
> +#define SMB2_IMPL_ID_MAX_OS_NAME_LEN	64
> +#define SMB2_IMPL_ID_MAX_OS_VERSION_LEN	64
> +#define SMB2_IMPL_ID_MAX_ARCH_LEN	64
> +
> +struct smb2_implementation_id_context {
> +	__le16	ContextType; /* 9 */
> +	__le16	DataLength;
> +	__le32	Reserved;
> +	__le16	ImplDomainLength;
> +	__le16	ImplNameLength;
> +	__le16	ImplVersionLength;
> +	__le16	HostNameLength;
> +	__le16	OSNameLength;
> +	__le16	OSVersionLength;
> +	__le16	ArchLength;
> +	__le16	Reserved2;
> +	/* Followed by variable length UTF-16 strings:
> +	 * ImplDomain, ImplName, ImplVersion, HostName,
> +	 * OSName, OSVersion, Arch
> +	 */
> +	__u8	Data[];
> +} __packed;
> +
>   #define POSIX_CTXT_DATA_LEN	16
>   struct smb2_posix_neg_context {
>   	__le16	ContextType; /* 0x100 */


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-06 23:19       ` Paulo Alcantara
  2026-03-06 23:23         ` Steve French
@ 2026-03-09 16:34         ` Shyam Prasad N
  1 sibling, 0 replies; 15+ messages in thread
From: Shyam Prasad N @ 2026-03-09 16:34 UTC (permalink / raw)
  To: Paulo Alcantara
  Cc: Steve French, Henrique Carvalho, linux-cifs, bharathsm, dhowells,
	Shyam Prasad N

On Sat, Mar 7, 2026 at 4:49 AM Paulo Alcantara <pc@manguebit.org> wrote:
>
> Steve French <smfrench@gmail.com> writes:
>
> > On Fri, Mar 6, 2026 at 4:45 PM Henrique Carvalho
> > <henrique.carvalho@suse.com> wrote:
> >>
> >> On Wed, Mar 04, 2026 at 06:04:05PM +0530, Shyam Prasad N wrote: > On Wed, Mar 4, 2026 at 5:59 PM <nspmangalore@gmail.com> wrote: From: Shyam Prasad N <sprasad@microsoft.com>
> >> >
> >> > A proof-of-concept based on this draft from Bharath.
> >> > Looking for comments on how to improve.
> >>
> >> Looks good.
> >>
> >> Just one minor thing for now. To me the cifs.ko module version doesn't
> >> say much as it seems to be not reliable (apologies if I'm mistaken).
> >
> > It does get incremented every 10 weeks.
> >
> >> Also, the same version could have different implementations in different
> >> distributions. modinfo -F srcversion cifs is a better way to
> >> differentiate cifs versions but not to compare versions. So the solution
> >> is either remove this or bump it in every change using X.Y.Z.
> >
> > We do bump the module version every kernel release, e.g. we are at
> > 2.59 in Linux 7.0 (7.0-rc2)
> > Would bump it when someone does a 'full backport' of most cifs fixes
> > to an earlier kernel.
>
> Who?
>
> >> Further, have you thought about how the client can use this in its favor
> >> other than diagnosing/debugging a faulty server?
> >
> > I thought this was for the reverse - so the server support team can
> > get metrics on whether the client is an old client with known bugs
>
> The client version is entirely pointless, especially for distribution
> kernels.  The support team can't figure out by just looking at the
> client version as the backports are what really matter in terms of a
> distro kernel.  Most distro kernels don't even bother backporting those
> commits that bump the client version, which makes it even more
> inaccurate.
>
> >> I think we need to be clear on what is allowed here, to me it seems
> >> quirks, workarounds and perf tuning? Maybe this can be used to improve
> >> interaction between linux client and linux server?
> >
> > presumably primarily for customer support to be able to recognise
> > known client problems on clients accessing a server
>
> Neither the client or kernel version will tell you _exactly_ where the
> problem is in distro kernels.

Hi Paulo / Henrique,

Good points.
srcversion is probably something that can be unique for a specific
version. But is there a common place where srcversion values are
documented by distros today?
If that is the case, perhaps that with the combination of the kernel
version can tell us what cifs.ko the client machine is actually
running.

-- 
Regards,
Shyam

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-09 16:19 ` Ralph Boehme
@ 2026-03-09 16:37   ` Shyam Prasad N
  2026-03-09 17:35     ` Ralph Boehme
  2026-03-09 17:59     ` Enzo Matsumiya
  0 siblings, 2 replies; 15+ messages in thread
From: Shyam Prasad N @ 2026-03-09 16:37 UTC (permalink / raw)
  To: Ralph Boehme
  Cc: linux-cifs, smfrench, pc, bharathsm, dhowells, Shyam Prasad N

On Mon, Mar 9, 2026 at 9:49 PM Ralph Boehme <slow@samba.org> wrote:
>
> Hi!
>
> I wonder which servers are expected to be implementing this? I suppose
> this protocol extension is not proposed without a server vendor
> interested in actually implementing it, otherwise the whole metrics
> story doesn't make sense.

Hi Ralph,

This is supposed to give the server an idea of what version of cifs.ko
the client is actually running.
This can be useful for servers like Azure SMB servers, where it is not
easy to explain client side behaviour without knowing what exact
version of the code is running on the client.

>
> *scratches head*
>
> Thanks!
> -slow
>
> On 3/4/26 1:27 PM, nspmangalore@gmail.com wrote:
> > From: Shyam Prasad N <sprasad@microsoft.com>
> >
> > MS-SMB2 does not allow any fields for the client to communicate
> > the client version details to the server. This change is a
> > proof-of-concept to add client details in a new negotiate context.
> >
> > Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
> > ---
> >   fs/smb/client/smb2pdu.c | 78 +++++++++++++++++++++++++++++++++++++++++
> >   fs/smb/common/smb2pdu.h | 32 +++++++++++++++++
> >   2 files changed, 110 insertions(+)
> >
> > diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
> > index ef655acf673df..9c89f6b4a6709 100644
> > --- a/fs/smb/client/smb2pdu.c
> > +++ b/fs/smb/client/smb2pdu.c
> > @@ -24,6 +24,7 @@
> >   #include <linux/pagemap.h>
> >   #include <linux/xattr.h>
> >   #include <linux/netfs.h>
> > +#include <linux/utsname.h>
> >   #include <trace/events/netfs.h>
> >   #include "cifsglob.h"
> >   #include "cifsproto.h"
> > @@ -45,6 +46,7 @@
> >   #include "cached_dir.h"
> >   #include "compress.h"
> >   #include "fs_context.h"
> > +#include "cifsfs.h"
> >
> >   /*
> >    *  The following table defines the expected "StructureSize" of SMB2 requests
> > @@ -724,6 +726,75 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
> >       pneg_ctxt->Name[15] = 0x7C;
> >   }
> >
> > +static unsigned int
> > +build_implementation_id_ctxt(struct smb2_implementation_id_context *pneg_ctxt)
> > +{
> > +     struct nls_table *cp = load_nls_default();
> > +     struct new_utsname *uts = utsname();
> > +     const char *impl_domain = "kernel.org";
> > +     const char *impl_name = "fs/smb/client";
> > +     const char *os_name = "Linux";
> > +     unsigned int data_len = 0;
> > +     __u8 *data_ptr;
> > +     int len;
> > +
> > +     pneg_ctxt->ContextType = SMB2_IMPLEMENTATION_ID_CONTEXT_ID;
> > +     data_ptr = pneg_ctxt->Data;
> > +
> > +     /* ImplDomain */
> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, impl_domain,
> > +                           SMB2_IMPL_ID_MAX_DOMAIN_LEN, cp);
> > +     pneg_ctxt->ImplDomainLength = cpu_to_le16(len * 2);
> > +     data_ptr += len * 2;
> > +     data_len += len * 2;
> > +
> > +     /* ImplName */
> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, impl_name,
> > +                           SMB2_IMPL_ID_MAX_NAME_LEN, cp);
> > +     pneg_ctxt->ImplNameLength = cpu_to_le16(len * 2);
> > +     data_ptr += len * 2;
> > +     data_len += len * 2;
> > +
> > +     /* ImplVersion - CIFS_VERSION from cifsfs.h */
> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, CIFS_VERSION,
> > +                           SMB2_IMPL_ID_MAX_VERSION_LEN, cp);
> > +     pneg_ctxt->ImplVersionLength = cpu_to_le16(len * 2);
> > +     data_ptr += len * 2;
> > +     data_len += len * 2;
> > +
> > +     /* HostName - from utsname()->nodename */
> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, uts->nodename,
> > +                           SMB2_IMPL_ID_MAX_HOSTNAME_LEN, cp);
> > +     pneg_ctxt->HostNameLength = cpu_to_le16(len * 2);
> > +     data_ptr += len * 2;
> > +     data_len += len * 2;
> > +
> > +     /* OSName */
> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, os_name,
> > +                           SMB2_IMPL_ID_MAX_OS_NAME_LEN, cp);
> > +     pneg_ctxt->OSNameLength = cpu_to_le16(len * 2);
> > +     data_ptr += len * 2;
> > +     data_len += len * 2;
> > +
> > +     /* OSVersion - from utsname()->release */
> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, uts->release,
> > +                           SMB2_IMPL_ID_MAX_OS_VERSION_LEN, cp);
> > +     pneg_ctxt->OSVersionLength = cpu_to_le16(len * 2);
> > +     data_ptr += len * 2;
> > +     data_len += len * 2;
> > +
> > +     /* Arch - from utsname()->machine */
> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, uts->machine,
> > +                           SMB2_IMPL_ID_MAX_ARCH_LEN, cp);
> > +     pneg_ctxt->ArchLength = cpu_to_le16(len * 2);
> > +     data_len += len * 2;
> > +
> > +     pneg_ctxt->Reserved2 = 0;
> > +     pneg_ctxt->DataLength = cpu_to_le16(data_len + 14); /* 14 = 7 length fields * 2 bytes */
> > +     /* Context size is DataLength + minimal smb2_neg_context, aligned to 8 */
> > +     return ALIGN(le16_to_cpu(pneg_ctxt->DataLength) + sizeof(struct smb2_neg_context), 8);
> > +}
> > +
> >   static void
> >   assemble_neg_contexts(struct smb2_negotiate_req *req,
> >                     struct TCP_Server_Info *server, unsigned int *total_len)
> > @@ -797,6 +868,13 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
> >               neg_context_count++;
> >       }
> >
> > +     /* Add implementation ID context */
> > +     ctxt_len = build_implementation_id_ctxt((struct smb2_implementation_id_context *)
> > +                             pneg_ctxt);
> > +     *total_len += ctxt_len;
> > +     pneg_ctxt += ctxt_len;
> > +     neg_context_count++;
> > +
> >       /* check for and add transport_capabilities and signing capabilities */
> >       req->NegotiateContextCount = cpu_to_le16(neg_context_count);
> >
> > diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
> > index e482c86ceb00d..1ad7b57ce2952 100644
> > --- a/fs/smb/common/smb2pdu.h
> > +++ b/fs/smb/common/smb2pdu.h
> > @@ -457,6 +457,7 @@ struct smb2_tree_disconnect_rsp {
> >   #define SMB2_TRANSPORT_CAPABILITIES         cpu_to_le16(6)
> >   #define SMB2_RDMA_TRANSFORM_CAPABILITIES    cpu_to_le16(7)
> >   #define SMB2_SIGNING_CAPABILITIES           cpu_to_le16(8)
> > +#define SMB2_IMPLEMENTATION_ID_CONTEXT_ID    cpu_to_le16(0xF100)
> >   #define SMB2_POSIX_EXTENSIONS_AVAILABLE             cpu_to_le16(0x100)
> >
> >   struct smb2_neg_context {
> > @@ -596,6 +597,37 @@ struct smb2_signing_capabilities {
> >       /*  Followed by padding to 8 byte boundary (required by some servers) */
> >   } __packed;
> >
> > +/*
> > + * For implementation ID context see MS-SMB2 2.2.3.1.8
> > + * Maximum string lengths per specification
> > + */
> > +#define SMB2_IMPL_ID_MAX_DOMAIN_LEN  128
> > +#define SMB2_IMPL_ID_MAX_NAME_LEN    260
> > +#define SMB2_IMPL_ID_MAX_VERSION_LEN 260
> > +#define SMB2_IMPL_ID_MAX_HOSTNAME_LEN        64
> > +#define SMB2_IMPL_ID_MAX_OS_NAME_LEN 64
> > +#define SMB2_IMPL_ID_MAX_OS_VERSION_LEN      64
> > +#define SMB2_IMPL_ID_MAX_ARCH_LEN    64
> > +
> > +struct smb2_implementation_id_context {
> > +     __le16  ContextType; /* 9 */
> > +     __le16  DataLength;
> > +     __le32  Reserved;
> > +     __le16  ImplDomainLength;
> > +     __le16  ImplNameLength;
> > +     __le16  ImplVersionLength;
> > +     __le16  HostNameLength;
> > +     __le16  OSNameLength;
> > +     __le16  OSVersionLength;
> > +     __le16  ArchLength;
> > +     __le16  Reserved2;
> > +     /* Followed by variable length UTF-16 strings:
> > +      * ImplDomain, ImplName, ImplVersion, HostName,
> > +      * OSName, OSVersion, Arch
> > +      */
> > +     __u8    Data[];
> > +} __packed;
> > +
> >   #define POSIX_CTXT_DATA_LEN 16
> >   struct smb2_posix_neg_context {
> >       __le16  ContextType; /* 0x100 */
>


-- 
Regards,
Shyam

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-09 16:37   ` Shyam Prasad N
@ 2026-03-09 17:35     ` Ralph Boehme
  2026-03-11 23:50       ` Shyam Prasad N
  2026-03-09 17:59     ` Enzo Matsumiya
  1 sibling, 1 reply; 15+ messages in thread
From: Ralph Boehme @ 2026-03-09 17:35 UTC (permalink / raw)
  To: Shyam Prasad N
  Cc: linux-cifs, smfrench, pc, bharathsm, dhowells, Shyam Prasad N


[-- Attachment #1.1: Type: text/plain, Size: 516 bytes --]

Hi Shyam,

On 3/9/26 5:37 PM, Shyam Prasad N wrote:
> This can be useful for servers like Azure SMB servers, where it is not
> easy to explain client side behaviour without knowing what exact
> version of the code is running on the client.
so it is planned that MS is going to implement this in their servers?

I was kind of assuming this which made me wonder why is this made an 
community extension instead of a protocol feature will full MS backing 
including inclusion in MS-SMB2.

Thanks!
-slow


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-09 16:37   ` Shyam Prasad N
  2026-03-09 17:35     ` Ralph Boehme
@ 2026-03-09 17:59     ` Enzo Matsumiya
  2026-03-11 23:52       ` Shyam Prasad N
  1 sibling, 1 reply; 15+ messages in thread
From: Enzo Matsumiya @ 2026-03-09 17:59 UTC (permalink / raw)
  To: Shyam Prasad N
  Cc: Ralph Boehme, linux-cifs, smfrench, pc, bharathsm, dhowells,
	Shyam Prasad N

On 03/09, Shyam Prasad N wrote:
>On Mon, Mar 9, 2026 at 9:49 PM Ralph Boehme <slow@samba.org> wrote:
>>
>> Hi!
>>
>> I wonder which servers are expected to be implementing this? I suppose
>> this protocol extension is not proposed without a server vendor
>> interested in actually implementing it, otherwise the whole metrics
>> story doesn't make sense.
>
>Hi Ralph,
>
>This is supposed to give the server an idea of what version of cifs.ko
>the client is actually running.

I agree with others on this point -- cifs.ko version is useless to match
to a particular behaviour or pinpoint a specific bug.

>This can be useful for servers like Azure SMB servers, where it is not
>easy to explain client side behaviour without knowing what exact
>version of the code is running on the client.

If the proposal is going to be bidirectional, it would be much better,
for cifs.ko, to have servers sending such information to clients
instead;  even when there's a problem on the server, it'll usually
reflect on the client (crashes, misbehaviour, etc).

Also useful for cases where customers don't have direct/easy access to
their SMB infrastructure (e.g. external/3rd party hosting, or 1000s of
servers mixed with DFS and/or clusters).


Cheers,

Enzo

>> *scratches head*
>>
>> Thanks!
>> -slow
>>
>> On 3/4/26 1:27 PM, nspmangalore@gmail.com wrote:
>> > From: Shyam Prasad N <sprasad@microsoft.com>
>> >
>> > MS-SMB2 does not allow any fields for the client to communicate
>> > the client version details to the server. This change is a
>> > proof-of-concept to add client details in a new negotiate context.
>> >
>> > Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
>> > ---
>> >   fs/smb/client/smb2pdu.c | 78 +++++++++++++++++++++++++++++++++++++++++
>> >   fs/smb/common/smb2pdu.h | 32 +++++++++++++++++
>> >   2 files changed, 110 insertions(+)
>> >
>> > diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
>> > index ef655acf673df..9c89f6b4a6709 100644
>> > --- a/fs/smb/client/smb2pdu.c
>> > +++ b/fs/smb/client/smb2pdu.c
>> > @@ -24,6 +24,7 @@
>> >   #include <linux/pagemap.h>
>> >   #include <linux/xattr.h>
>> >   #include <linux/netfs.h>
>> > +#include <linux/utsname.h>
>> >   #include <trace/events/netfs.h>
>> >   #include "cifsglob.h"
>> >   #include "cifsproto.h"
>> > @@ -45,6 +46,7 @@
>> >   #include "cached_dir.h"
>> >   #include "compress.h"
>> >   #include "fs_context.h"
>> > +#include "cifsfs.h"
>> >
>> >   /*
>> >    *  The following table defines the expected "StructureSize" of SMB2 requests
>> > @@ -724,6 +726,75 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
>> >       pneg_ctxt->Name[15] = 0x7C;
>> >   }
>> >
>> > +static unsigned int
>> > +build_implementation_id_ctxt(struct smb2_implementation_id_context *pneg_ctxt)
>> > +{
>> > +     struct nls_table *cp = load_nls_default();
>> > +     struct new_utsname *uts = utsname();
>> > +     const char *impl_domain = "kernel.org";
>> > +     const char *impl_name = "fs/smb/client";
>> > +     const char *os_name = "Linux";
>> > +     unsigned int data_len = 0;
>> > +     __u8 *data_ptr;
>> > +     int len;
>> > +
>> > +     pneg_ctxt->ContextType = SMB2_IMPLEMENTATION_ID_CONTEXT_ID;
>> > +     data_ptr = pneg_ctxt->Data;
>> > +
>> > +     /* ImplDomain */
>> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, impl_domain,
>> > +                           SMB2_IMPL_ID_MAX_DOMAIN_LEN, cp);
>> > +     pneg_ctxt->ImplDomainLength = cpu_to_le16(len * 2);
>> > +     data_ptr += len * 2;
>> > +     data_len += len * 2;
>> > +
>> > +     /* ImplName */
>> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, impl_name,
>> > +                           SMB2_IMPL_ID_MAX_NAME_LEN, cp);
>> > +     pneg_ctxt->ImplNameLength = cpu_to_le16(len * 2);
>> > +     data_ptr += len * 2;
>> > +     data_len += len * 2;
>> > +
>> > +     /* ImplVersion - CIFS_VERSION from cifsfs.h */
>> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, CIFS_VERSION,
>> > +                           SMB2_IMPL_ID_MAX_VERSION_LEN, cp);
>> > +     pneg_ctxt->ImplVersionLength = cpu_to_le16(len * 2);
>> > +     data_ptr += len * 2;
>> > +     data_len += len * 2;
>> > +
>> > +     /* HostName - from utsname()->nodename */
>> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, uts->nodename,
>> > +                           SMB2_IMPL_ID_MAX_HOSTNAME_LEN, cp);
>> > +     pneg_ctxt->HostNameLength = cpu_to_le16(len * 2);
>> > +     data_ptr += len * 2;
>> > +     data_len += len * 2;
>> > +
>> > +     /* OSName */
>> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, os_name,
>> > +                           SMB2_IMPL_ID_MAX_OS_NAME_LEN, cp);
>> > +     pneg_ctxt->OSNameLength = cpu_to_le16(len * 2);
>> > +     data_ptr += len * 2;
>> > +     data_len += len * 2;
>> > +
>> > +     /* OSVersion - from utsname()->release */
>> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, uts->release,
>> > +                           SMB2_IMPL_ID_MAX_OS_VERSION_LEN, cp);
>> > +     pneg_ctxt->OSVersionLength = cpu_to_le16(len * 2);
>> > +     data_ptr += len * 2;
>> > +     data_len += len * 2;
>> > +
>> > +     /* Arch - from utsname()->machine */
>> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, uts->machine,
>> > +                           SMB2_IMPL_ID_MAX_ARCH_LEN, cp);
>> > +     pneg_ctxt->ArchLength = cpu_to_le16(len * 2);
>> > +     data_len += len * 2;
>> > +
>> > +     pneg_ctxt->Reserved2 = 0;
>> > +     pneg_ctxt->DataLength = cpu_to_le16(data_len + 14); /* 14 = 7 length fields * 2 bytes */
>> > +     /* Context size is DataLength + minimal smb2_neg_context, aligned to 8 */
>> > +     return ALIGN(le16_to_cpu(pneg_ctxt->DataLength) + sizeof(struct smb2_neg_context), 8);
>> > +}
>> > +
>> >   static void
>> >   assemble_neg_contexts(struct smb2_negotiate_req *req,
>> >                     struct TCP_Server_Info *server, unsigned int *total_len)
>> > @@ -797,6 +868,13 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
>> >               neg_context_count++;
>> >       }
>> >
>> > +     /* Add implementation ID context */
>> > +     ctxt_len = build_implementation_id_ctxt((struct smb2_implementation_id_context *)
>> > +                             pneg_ctxt);
>> > +     *total_len += ctxt_len;
>> > +     pneg_ctxt += ctxt_len;
>> > +     neg_context_count++;
>> > +
>> >       /* check for and add transport_capabilities and signing capabilities */
>> >       req->NegotiateContextCount = cpu_to_le16(neg_context_count);
>> >
>> > diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
>> > index e482c86ceb00d..1ad7b57ce2952 100644
>> > --- a/fs/smb/common/smb2pdu.h
>> > +++ b/fs/smb/common/smb2pdu.h
>> > @@ -457,6 +457,7 @@ struct smb2_tree_disconnect_rsp {
>> >   #define SMB2_TRANSPORT_CAPABILITIES         cpu_to_le16(6)
>> >   #define SMB2_RDMA_TRANSFORM_CAPABILITIES    cpu_to_le16(7)
>> >   #define SMB2_SIGNING_CAPABILITIES           cpu_to_le16(8)
>> > +#define SMB2_IMPLEMENTATION_ID_CONTEXT_ID    cpu_to_le16(0xF100)
>> >   #define SMB2_POSIX_EXTENSIONS_AVAILABLE             cpu_to_le16(0x100)
>> >
>> >   struct smb2_neg_context {
>> > @@ -596,6 +597,37 @@ struct smb2_signing_capabilities {
>> >       /*  Followed by padding to 8 byte boundary (required by some servers) */
>> >   } __packed;
>> >
>> > +/*
>> > + * For implementation ID context see MS-SMB2 2.2.3.1.8
>> > + * Maximum string lengths per specification
>> > + */
>> > +#define SMB2_IMPL_ID_MAX_DOMAIN_LEN  128
>> > +#define SMB2_IMPL_ID_MAX_NAME_LEN    260
>> > +#define SMB2_IMPL_ID_MAX_VERSION_LEN 260
>> > +#define SMB2_IMPL_ID_MAX_HOSTNAME_LEN        64
>> > +#define SMB2_IMPL_ID_MAX_OS_NAME_LEN 64
>> > +#define SMB2_IMPL_ID_MAX_OS_VERSION_LEN      64
>> > +#define SMB2_IMPL_ID_MAX_ARCH_LEN    64
>> > +
>> > +struct smb2_implementation_id_context {
>> > +     __le16  ContextType; /* 9 */
>> > +     __le16  DataLength;
>> > +     __le32  Reserved;
>> > +     __le16  ImplDomainLength;
>> > +     __le16  ImplNameLength;
>> > +     __le16  ImplVersionLength;
>> > +     __le16  HostNameLength;
>> > +     __le16  OSNameLength;
>> > +     __le16  OSVersionLength;
>> > +     __le16  ArchLength;
>> > +     __le16  Reserved2;
>> > +     /* Followed by variable length UTF-16 strings:
>> > +      * ImplDomain, ImplName, ImplVersion, HostName,
>> > +      * OSName, OSVersion, Arch
>> > +      */
>> > +     __u8    Data[];
>> > +} __packed;
>> > +
>> >   #define POSIX_CTXT_DATA_LEN 16
>> >   struct smb2_posix_neg_context {
>> >       __le16  ContextType; /* 0x100 */
>>
>
>
>-- 
>Regards,
>Shyam
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-09 17:35     ` Ralph Boehme
@ 2026-03-11 23:50       ` Shyam Prasad N
  0 siblings, 0 replies; 15+ messages in thread
From: Shyam Prasad N @ 2026-03-11 23:50 UTC (permalink / raw)
  To: Ralph Boehme
  Cc: linux-cifs, smfrench, pc, bharathsm, dhowells, Shyam Prasad N

On Mon, Mar 9, 2026 at 11:05 PM Ralph Boehme <slow@samba.org> wrote:
>
> Hi Shyam,
>
> On 3/9/26 5:37 PM, Shyam Prasad N wrote:
> > This can be useful for servers like Azure SMB servers, where it is not
> > easy to explain client side behaviour without knowing what exact
> > version of the code is running on the client.
> so it is planned that MS is going to implement this in their servers?
>
> I was kind of assuming this which made me wonder why is this made an
> community extension instead of a protocol feature will full MS backing
> including inclusion in MS-SMB2.
>
> Thanks!
> -slow
>

Hi Ralph,

We are working with the responsible team to get it into MS-SMB2.
However, we also wanted to get an early POC and review comments on the
proposed draft and the client changes.

-- 
Regards,
Shyam

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-09 17:59     ` Enzo Matsumiya
@ 2026-03-11 23:52       ` Shyam Prasad N
  2026-03-12  0:00         ` Steve French
  0 siblings, 1 reply; 15+ messages in thread
From: Shyam Prasad N @ 2026-03-11 23:52 UTC (permalink / raw)
  To: Enzo Matsumiya
  Cc: Ralph Boehme, linux-cifs, smfrench, pc, bharathsm, dhowells,
	Shyam Prasad N

On Mon, Mar 9, 2026 at 11:29 PM Enzo Matsumiya <ematsumiya@suse.de> wrote:
>
> On 03/09, Shyam Prasad N wrote:
> >On Mon, Mar 9, 2026 at 9:49 PM Ralph Boehme <slow@samba.org> wrote:
> >>
> >> Hi!
> >>
> >> I wonder which servers are expected to be implementing this? I suppose
> >> this protocol extension is not proposed without a server vendor
> >> interested in actually implementing it, otherwise the whole metrics
> >> story doesn't make sense.
> >
> >Hi Ralph,
> >
> >This is supposed to give the server an idea of what version of cifs.ko
> >the client is actually running.
>
> I agree with others on this point -- cifs.ko version is useless to match
> to a particular behaviour or pinpoint a specific bug.

Acked. Can you suggest an alternative field that will make the matching easier?

>
> >This can be useful for servers like Azure SMB servers, where it is not
> >easy to explain client side behaviour without knowing what exact
> >version of the code is running on the client.
>
> If the proposal is going to be bidirectional, it would be much better,
> for cifs.ko, to have servers sending such information to clients
> instead;  even when there's a problem on the server, it'll usually
> reflect on the client (crashes, misbehaviour, etc).
>
> Also useful for cases where customers don't have direct/easy access to
> their SMB infrastructure (e.g. external/3rd party hosting, or 1000s of
> servers mixed with DFS and/or clusters).

Good point. Let me rework the draft on this.

>
>
> Cheers,
>
> Enzo
>
> >> *scratches head*
> >>
> >> Thanks!
> >> -slow
> >>
> >> On 3/4/26 1:27 PM, nspmangalore@gmail.com wrote:
> >> > From: Shyam Prasad N <sprasad@microsoft.com>
> >> >
> >> > MS-SMB2 does not allow any fields for the client to communicate
> >> > the client version details to the server. This change is a
> >> > proof-of-concept to add client details in a new negotiate context.
> >> >
> >> > Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
> >> > ---
> >> >   fs/smb/client/smb2pdu.c | 78 +++++++++++++++++++++++++++++++++++++++++
> >> >   fs/smb/common/smb2pdu.h | 32 +++++++++++++++++
> >> >   2 files changed, 110 insertions(+)
> >> >
> >> > diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
> >> > index ef655acf673df..9c89f6b4a6709 100644
> >> > --- a/fs/smb/client/smb2pdu.c
> >> > +++ b/fs/smb/client/smb2pdu.c
> >> > @@ -24,6 +24,7 @@
> >> >   #include <linux/pagemap.h>
> >> >   #include <linux/xattr.h>
> >> >   #include <linux/netfs.h>
> >> > +#include <linux/utsname.h>
> >> >   #include <trace/events/netfs.h>
> >> >   #include "cifsglob.h"
> >> >   #include "cifsproto.h"
> >> > @@ -45,6 +46,7 @@
> >> >   #include "cached_dir.h"
> >> >   #include "compress.h"
> >> >   #include "fs_context.h"
> >> > +#include "cifsfs.h"
> >> >
> >> >   /*
> >> >    *  The following table defines the expected "StructureSize" of SMB2 requests
> >> > @@ -724,6 +726,75 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
> >> >       pneg_ctxt->Name[15] = 0x7C;
> >> >   }
> >> >
> >> > +static unsigned int
> >> > +build_implementation_id_ctxt(struct smb2_implementation_id_context *pneg_ctxt)
> >> > +{
> >> > +     struct nls_table *cp = load_nls_default();
> >> > +     struct new_utsname *uts = utsname();
> >> > +     const char *impl_domain = "kernel.org";
> >> > +     const char *impl_name = "fs/smb/client";
> >> > +     const char *os_name = "Linux";
> >> > +     unsigned int data_len = 0;
> >> > +     __u8 *data_ptr;
> >> > +     int len;
> >> > +
> >> > +     pneg_ctxt->ContextType = SMB2_IMPLEMENTATION_ID_CONTEXT_ID;
> >> > +     data_ptr = pneg_ctxt->Data;
> >> > +
> >> > +     /* ImplDomain */
> >> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, impl_domain,
> >> > +                           SMB2_IMPL_ID_MAX_DOMAIN_LEN, cp);
> >> > +     pneg_ctxt->ImplDomainLength = cpu_to_le16(len * 2);
> >> > +     data_ptr += len * 2;
> >> > +     data_len += len * 2;
> >> > +
> >> > +     /* ImplName */
> >> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, impl_name,
> >> > +                           SMB2_IMPL_ID_MAX_NAME_LEN, cp);
> >> > +     pneg_ctxt->ImplNameLength = cpu_to_le16(len * 2);
> >> > +     data_ptr += len * 2;
> >> > +     data_len += len * 2;
> >> > +
> >> > +     /* ImplVersion - CIFS_VERSION from cifsfs.h */
> >> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, CIFS_VERSION,
> >> > +                           SMB2_IMPL_ID_MAX_VERSION_LEN, cp);
> >> > +     pneg_ctxt->ImplVersionLength = cpu_to_le16(len * 2);
> >> > +     data_ptr += len * 2;
> >> > +     data_len += len * 2;
> >> > +
> >> > +     /* HostName - from utsname()->nodename */
> >> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, uts->nodename,
> >> > +                           SMB2_IMPL_ID_MAX_HOSTNAME_LEN, cp);
> >> > +     pneg_ctxt->HostNameLength = cpu_to_le16(len * 2);
> >> > +     data_ptr += len * 2;
> >> > +     data_len += len * 2;
> >> > +
> >> > +     /* OSName */
> >> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, os_name,
> >> > +                           SMB2_IMPL_ID_MAX_OS_NAME_LEN, cp);
> >> > +     pneg_ctxt->OSNameLength = cpu_to_le16(len * 2);
> >> > +     data_ptr += len * 2;
> >> > +     data_len += len * 2;
> >> > +
> >> > +     /* OSVersion - from utsname()->release */
> >> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, uts->release,
> >> > +                           SMB2_IMPL_ID_MAX_OS_VERSION_LEN, cp);
> >> > +     pneg_ctxt->OSVersionLength = cpu_to_le16(len * 2);
> >> > +     data_ptr += len * 2;
> >> > +     data_len += len * 2;
> >> > +
> >> > +     /* Arch - from utsname()->machine */
> >> > +     len = cifs_strtoUTF16((__le16 *)data_ptr, uts->machine,
> >> > +                           SMB2_IMPL_ID_MAX_ARCH_LEN, cp);
> >> > +     pneg_ctxt->ArchLength = cpu_to_le16(len * 2);
> >> > +     data_len += len * 2;
> >> > +
> >> > +     pneg_ctxt->Reserved2 = 0;
> >> > +     pneg_ctxt->DataLength = cpu_to_le16(data_len + 14); /* 14 = 7 length fields * 2 bytes */
> >> > +     /* Context size is DataLength + minimal smb2_neg_context, aligned to 8 */
> >> > +     return ALIGN(le16_to_cpu(pneg_ctxt->DataLength) + sizeof(struct smb2_neg_context), 8);
> >> > +}
> >> > +
> >> >   static void
> >> >   assemble_neg_contexts(struct smb2_negotiate_req *req,
> >> >                     struct TCP_Server_Info *server, unsigned int *total_len)
> >> > @@ -797,6 +868,13 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
> >> >               neg_context_count++;
> >> >       }
> >> >
> >> > +     /* Add implementation ID context */
> >> > +     ctxt_len = build_implementation_id_ctxt((struct smb2_implementation_id_context *)
> >> > +                             pneg_ctxt);
> >> > +     *total_len += ctxt_len;
> >> > +     pneg_ctxt += ctxt_len;
> >> > +     neg_context_count++;
> >> > +
> >> >       /* check for and add transport_capabilities and signing capabilities */
> >> >       req->NegotiateContextCount = cpu_to_le16(neg_context_count);
> >> >
> >> > diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
> >> > index e482c86ceb00d..1ad7b57ce2952 100644
> >> > --- a/fs/smb/common/smb2pdu.h
> >> > +++ b/fs/smb/common/smb2pdu.h
> >> > @@ -457,6 +457,7 @@ struct smb2_tree_disconnect_rsp {
> >> >   #define SMB2_TRANSPORT_CAPABILITIES         cpu_to_le16(6)
> >> >   #define SMB2_RDMA_TRANSFORM_CAPABILITIES    cpu_to_le16(7)
> >> >   #define SMB2_SIGNING_CAPABILITIES           cpu_to_le16(8)
> >> > +#define SMB2_IMPLEMENTATION_ID_CONTEXT_ID    cpu_to_le16(0xF100)
> >> >   #define SMB2_POSIX_EXTENSIONS_AVAILABLE             cpu_to_le16(0x100)
> >> >
> >> >   struct smb2_neg_context {
> >> > @@ -596,6 +597,37 @@ struct smb2_signing_capabilities {
> >> >       /*  Followed by padding to 8 byte boundary (required by some servers) */
> >> >   } __packed;
> >> >
> >> > +/*
> >> > + * For implementation ID context see MS-SMB2 2.2.3.1.8
> >> > + * Maximum string lengths per specification
> >> > + */
> >> > +#define SMB2_IMPL_ID_MAX_DOMAIN_LEN  128
> >> > +#define SMB2_IMPL_ID_MAX_NAME_LEN    260
> >> > +#define SMB2_IMPL_ID_MAX_VERSION_LEN 260
> >> > +#define SMB2_IMPL_ID_MAX_HOSTNAME_LEN        64
> >> > +#define SMB2_IMPL_ID_MAX_OS_NAME_LEN 64
> >> > +#define SMB2_IMPL_ID_MAX_OS_VERSION_LEN      64
> >> > +#define SMB2_IMPL_ID_MAX_ARCH_LEN    64
> >> > +
> >> > +struct smb2_implementation_id_context {
> >> > +     __le16  ContextType; /* 9 */
> >> > +     __le16  DataLength;
> >> > +     __le32  Reserved;
> >> > +     __le16  ImplDomainLength;
> >> > +     __le16  ImplNameLength;
> >> > +     __le16  ImplVersionLength;
> >> > +     __le16  HostNameLength;
> >> > +     __le16  OSNameLength;
> >> > +     __le16  OSVersionLength;
> >> > +     __le16  ArchLength;
> >> > +     __le16  Reserved2;
> >> > +     /* Followed by variable length UTF-16 strings:
> >> > +      * ImplDomain, ImplName, ImplVersion, HostName,
> >> > +      * OSName, OSVersion, Arch
> >> > +      */
> >> > +     __u8    Data[];
> >> > +} __packed;
> >> > +
> >> >   #define POSIX_CTXT_DATA_LEN 16
> >> >   struct smb2_posix_neg_context {
> >> >       __le16  ContextType; /* 0x100 */
> >>
> >
> >
> >--
> >Regards,
> >Shyam
> >



-- 
Regards,
Shyam

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] cifs: implementation id context as negotiate context
  2026-03-11 23:52       ` Shyam Prasad N
@ 2026-03-12  0:00         ` Steve French
  0 siblings, 0 replies; 15+ messages in thread
From: Steve French @ 2026-03-12  0:00 UTC (permalink / raw)
  To: Shyam Prasad N
  Cc: Enzo Matsumiya, Ralph Boehme, linux-cifs, pc, bharathsm, dhowells,
	Shyam Prasad N

On Wed, Mar 11, 2026 at 6:52 PM Shyam Prasad N <nspmangalore@gmail.com> wrote:
>
> On Mon, Mar 9, 2026 at 11:29 PM Enzo Matsumiya <ematsumiya@suse.de> wrote:
> >
> > On 03/09, Shyam Prasad N wrote:
> > >On Mon, Mar 9, 2026 at 9:49 PM Ralph Boehme <slow@samba.org> wrote:
> > >>
> > >> Hi!
> > >>
> > >> I wonder which servers are expected to be implementing this? I suppose
> > >> this protocol extension is not proposed without a server vendor
> > >> interested in actually implementing it, otherwise the whole metrics
> > >> story doesn't make sense.
> > >
> > >Hi Ralph,
> > >
> > >This is supposed to give the server an idea of what version of cifs.ko
> > >the client is actually running.
> >
> > I agree with others on this point -- cifs.ko version is useless to match
> > to a particular behaviour or pinpoint a specific bug.
>
> Acked. Can you suggest an alternative field that will make the matching easier?

Kernel version is useful (major/minor #) but I don't see a problem
with using cifs.ko version as well as we do today since we had a few
cases where it could be updated for 'full backports' but in any case
either of these will help narrow client down a lot.

-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-03-12  0:00 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-04 12:27 [PATCH] cifs: implementation id context as negotiate context nspmangalore
2026-03-04 12:34 ` Shyam Prasad N
2026-03-06 22:45   ` Henrique Carvalho
2026-03-06 23:04     ` Steve French
2026-03-06 23:19       ` Paulo Alcantara
2026-03-06 23:23         ` Steve French
2026-03-09 16:34         ` Shyam Prasad N
2026-03-06 23:30       ` Henrique Carvalho
2026-03-09 16:19 ` Ralph Boehme
2026-03-09 16:37   ` Shyam Prasad N
2026-03-09 17:35     ` Ralph Boehme
2026-03-11 23:50       ` Shyam Prasad N
2026-03-09 17:59     ` Enzo Matsumiya
2026-03-11 23:52       ` Shyam Prasad N
2026-03-12  0:00         ` Steve French

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox