diff options
author | Steve French <steve.french@primarydata.com> | 2014-12-17 23:52:58 -0500 |
---|---|---|
committer | Steve French <steve.french@primarydata.com> | 2015-06-27 23:23:32 -0400 |
commit | 5f7fbf733c9dd6b58d40fa394313a5949b696f84 (patch) | |
tree | 8124f7318569872366b1138680ef81800cb20ffe | |
parent | f291095f340db986271e951e3891bb95624a93ea (diff) |
Allow parsing vers=3.11 on cifs mount
Parses and recognizes "vers=3.1.1" on cifs mount and allows sending
0x0311 as a new CIFS/SMB3 dialect. Subsequent patches will add
the new negotiate contexts and updated session setup
Reviewed-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: Steve French <steve.french@primarydata.com>
-rw-r--r-- | fs/cifs/Kconfig | 9 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 7 | ||||
-rw-r--r-- | fs/cifs/connect.c | 10 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 22 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 4 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 10 |
6 files changed, 59 insertions, 3 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index a2172f3f69e3..e7b478b49985 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig | |||
@@ -192,6 +192,15 @@ config CIFS_SMB2 | |||
192 | options are also slightly simpler (compared to CIFS) due | 192 | options are also slightly simpler (compared to CIFS) due |
193 | to protocol improvements. | 193 | to protocol improvements. |
194 | 194 | ||
195 | config CIFS_SMB311 | ||
196 | bool "SMB3.1.1 network file system support (Experimental)" | ||
197 | depends on CIFS_SMB2 && INET | ||
198 | |||
199 | help | ||
200 | This enables experimental support for the newest, SMB3.1.1, dialect. | ||
201 | This dialect includes improved security negotiation features. | ||
202 | If unsure, say N | ||
203 | |||
195 | config CIFS_FSCACHE | 204 | config CIFS_FSCACHE |
196 | bool "Provide CIFS client caching support" | 205 | bool "Provide CIFS client caching support" |
197 | depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y | 206 | depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 22b289a3b1c4..71bf86e6de9a 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -171,6 +171,10 @@ enum smb_version { | |||
171 | Smb_21, | 171 | Smb_21, |
172 | Smb_30, | 172 | Smb_30, |
173 | Smb_302, | 173 | Smb_302, |
174 | #ifdef CONFIG_CIFS_SMB311 | ||
175 | Smb_311, | ||
176 | #endif /* SMB311 */ | ||
177 | Smb_version_err | ||
174 | }; | 178 | }; |
175 | 179 | ||
176 | struct mid_q_entry; | 180 | struct mid_q_entry; |
@@ -1617,4 +1621,7 @@ extern struct smb_version_values smb30_values; | |||
1617 | #define SMB302_VERSION_STRING "3.02" | 1621 | #define SMB302_VERSION_STRING "3.02" |
1618 | /*extern struct smb_version_operations smb302_operations;*/ /* not needed yet */ | 1622 | /*extern struct smb_version_operations smb302_operations;*/ /* not needed yet */ |
1619 | extern struct smb_version_values smb302_values; | 1623 | extern struct smb_version_values smb302_values; |
1624 | #define SMB311_VERSION_STRING "3.1.1" | ||
1625 | /*extern struct smb_version_operations smb311_operations;*/ /* not needed yet */ | ||
1626 | extern struct smb_version_values smb311_values; | ||
1620 | #endif /* _CIFS_GLOB_H */ | 1627 | #endif /* _CIFS_GLOB_H */ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 8383d5ea4202..9300b98d8584 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -280,6 +280,10 @@ static const match_table_t cifs_smb_version_tokens = { | |||
280 | { Smb_21, SMB21_VERSION_STRING }, | 280 | { Smb_21, SMB21_VERSION_STRING }, |
281 | { Smb_30, SMB30_VERSION_STRING }, | 281 | { Smb_30, SMB30_VERSION_STRING }, |
282 | { Smb_302, SMB302_VERSION_STRING }, | 282 | { Smb_302, SMB302_VERSION_STRING }, |
283 | #ifdef CONFIG_CIFS_SMB311 | ||
284 | { Smb_311, SMB311_VERSION_STRING }, | ||
285 | #endif /* SMB311 */ | ||
286 | { Smb_version_err, NULL } | ||
283 | }; | 287 | }; |
284 | 288 | ||
285 | static int ip_connect(struct TCP_Server_Info *server); | 289 | static int ip_connect(struct TCP_Server_Info *server); |
@@ -1133,6 +1137,12 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol) | |||
1133 | vol->ops = &smb30_operations; /* currently identical with 3.0 */ | 1137 | vol->ops = &smb30_operations; /* currently identical with 3.0 */ |
1134 | vol->vals = &smb302_values; | 1138 | vol->vals = &smb302_values; |
1135 | break; | 1139 | break; |
1140 | #ifdef CONFIG_CIFS_SMB311 | ||
1141 | case Smb_311: | ||
1142 | vol->ops = &smb30_operations; /* currently identical with 3.0 */ | ||
1143 | vol->vals = &smb311_values; | ||
1144 | break; | ||
1145 | #endif /* SMB311 */ | ||
1136 | #endif | 1146 | #endif |
1137 | default: | 1147 | default: |
1138 | cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value); | 1148 | cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value); |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 54daee5ad4c1..a7d520cc2cfd 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -1714,3 +1714,25 @@ struct smb_version_values smb302_values = { | |||
1714 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, | 1714 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, |
1715 | .create_lease_size = sizeof(struct create_lease_v2), | 1715 | .create_lease_size = sizeof(struct create_lease_v2), |
1716 | }; | 1716 | }; |
1717 | |||
1718 | #ifdef CONFIG_CIFS_SMB311 | ||
1719 | struct smb_version_values smb311_values = { | ||
1720 | .version_string = SMB311_VERSION_STRING, | ||
1721 | .protocol_id = SMB311_PROT_ID, | ||
1722 | .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU, | ||
1723 | .large_lock_type = 0, | ||
1724 | .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, | ||
1725 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, | ||
1726 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, | ||
1727 | .header_size = sizeof(struct smb2_hdr), | ||
1728 | .max_header_size = MAX_SMB2_HDR_SIZE, | ||
1729 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, | ||
1730 | .lock_cmd = SMB2_LOCK, | ||
1731 | .cap_unix = 0, | ||
1732 | .cap_nt_find = SMB2_NT_FIND, | ||
1733 | .cap_large_files = SMB2_LARGE_FILES, | ||
1734 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, | ||
1735 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, | ||
1736 | .create_lease_size = sizeof(struct create_lease_v2), | ||
1737 | }; | ||
1738 | #endif /* SMB311 */ | ||
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 54cbe19d9c08..150dbe3e2822 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -393,6 +393,10 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) | |||
393 | cifs_dbg(FYI, "negotiated smb3.0 dialect\n"); | 393 | cifs_dbg(FYI, "negotiated smb3.0 dialect\n"); |
394 | else if (rsp->DialectRevision == cpu_to_le16(SMB302_PROT_ID)) | 394 | else if (rsp->DialectRevision == cpu_to_le16(SMB302_PROT_ID)) |
395 | cifs_dbg(FYI, "negotiated smb3.02 dialect\n"); | 395 | cifs_dbg(FYI, "negotiated smb3.02 dialect\n"); |
396 | #ifdef CONFIG_CIFS_SMB311 | ||
397 | else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) | ||
398 | cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n"); | ||
399 | #endif /* SMB311 */ | ||
396 | else { | 400 | else { |
397 | cifs_dbg(VFS, "Illegal dialect returned by server %d\n", | 401 | cifs_dbg(VFS, "Illegal dialect returned by server %d\n", |
398 | le16_to_cpu(rsp->DialectRevision)); | 402 | le16_to_cpu(rsp->DialectRevision)); |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 70867d54fb8b..994b34843c3a 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -191,7 +191,10 @@ struct smb2_negotiate_req { | |||
191 | __le16 Reserved; /* MBZ */ | 191 | __le16 Reserved; /* MBZ */ |
192 | __le32 Capabilities; | 192 | __le32 Capabilities; |
193 | __u8 ClientGUID[SMB2_CLIENT_GUID_SIZE]; | 193 | __u8 ClientGUID[SMB2_CLIENT_GUID_SIZE]; |
194 | __le64 ClientStartTime; /* MBZ */ | 194 | /* In SMB3.02 and earlier next three were MBZ le64 ClientStartTime */ |
195 | __le32 NegotiateContextOffset; /* SMB3.1.1 only. MBZ earlier */ | ||
196 | __le16 NegotiateContextCount; /* SMB3.1.1 only. MBZ earlier */ | ||
197 | __le16 Reserved2; | ||
195 | __le16 Dialects[1]; /* One dialect (vers=) at a time for now */ | 198 | __le16 Dialects[1]; /* One dialect (vers=) at a time for now */ |
196 | } __packed; | 199 | } __packed; |
197 | 200 | ||
@@ -200,6 +203,7 @@ struct smb2_negotiate_req { | |||
200 | #define SMB21_PROT_ID 0x0210 | 203 | #define SMB21_PROT_ID 0x0210 |
201 | #define SMB30_PROT_ID 0x0300 | 204 | #define SMB30_PROT_ID 0x0300 |
202 | #define SMB302_PROT_ID 0x0302 | 205 | #define SMB302_PROT_ID 0x0302 |
206 | #define SMB311_PROT_ID 0x0311 | ||
203 | #define BAD_PROT_ID 0xFFFF | 207 | #define BAD_PROT_ID 0xFFFF |
204 | 208 | ||
205 | /* SecurityMode flags */ | 209 | /* SecurityMode flags */ |
@@ -222,7 +226,7 @@ struct smb2_negotiate_rsp { | |||
222 | __le16 StructureSize; /* Must be 65 */ | 226 | __le16 StructureSize; /* Must be 65 */ |
223 | __le16 SecurityMode; | 227 | __le16 SecurityMode; |
224 | __le16 DialectRevision; | 228 | __le16 DialectRevision; |
225 | __le16 Reserved; /* MBZ */ | 229 | __le16 NegotiateContextCount; /* Prior to SMB3.1.1 was Reserved & MBZ */ |
226 | __u8 ServerGUID[16]; | 230 | __u8 ServerGUID[16]; |
227 | __le32 Capabilities; | 231 | __le32 Capabilities; |
228 | __le32 MaxTransactSize; | 232 | __le32 MaxTransactSize; |
@@ -232,7 +236,7 @@ struct smb2_negotiate_rsp { | |||
232 | __le64 ServerStartTime; | 236 | __le64 ServerStartTime; |
233 | __le16 SecurityBufferOffset; | 237 | __le16 SecurityBufferOffset; |
234 | __le16 SecurityBufferLength; | 238 | __le16 SecurityBufferLength; |
235 | __le32 Reserved2; /* may be any value, ignore */ | 239 | __le32 NegotiateContextOffset; /* Pre:SMB3.1.1 was reserved/ignored */ |
236 | __u8 Buffer[1]; /* variable length GSS security buffer */ | 240 | __u8 Buffer[1]; /* variable length GSS security buffer */ |
237 | } __packed; | 241 | } __packed; |
238 | 242 | ||