[PATCH] cifs: add a v6scope= option for specifying the ipv6 scopeid

Jeff Layton <[email protected]>
Newsgroups gmane.linux.file-systems.cifs
Message-ID <[email protected]>
This should allow people to mount servers on IPv6 link-local addresses.

Signed-off-by: Jeff Layton <[email protected]>
---
 fs/cifs/connect.c |   22 +++++++++++++++++-----
 1 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 7a39c22..2fc0cb8 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -102,6 +102,7 @@ struct smb_vol {
 	unsigned int wsize;
 	unsigned int sockopt;
 	unsigned short int port;
+	unsigned int v6scope;
 	char *prepath;
 };
 
@@ -801,7 +802,7 @@ static int
 cifs_parse_mount_options(char *options, const char *devname,
 			 struct smb_vol *vol)
 {
-	char *value;
+	char *value, *endptr;
 	char *data;
 	unsigned int  temp_len, i, j;
 	char separator[2];
@@ -958,6 +959,14 @@ cifs_parse_mount_options(char *options, const char *devname,
 				}
 				strcpy(vol->password, value);
 			}
+		} else if (!strnicmp(data, "v6scope", 7)) {
+			vol->v6scope = (unsigned int) simple_strtoul(value,
+								&endptr, 0);
+			if (!*value || *endptr) {
+				cERROR(1, ("Invalid scope_id specified!\n"));
+				return 1;
+			}
+			continue;
 		} else if (!strnicmp(data, "ip", 2) ||
 			   !strnicmp(data, "addr", 4)) {
 			if (!value || !*value) {
@@ -1387,8 +1396,10 @@ cifs_find_tcp_session(struct sockaddr_storage *addr)
 		     server->addr.sockAddr.sin_addr.s_addr))
 			continue;
 		else if (addr->ss_family == AF_INET6 &&
-			 !ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr,
-					  &addr6->sin6_addr))
+			 (!ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr,
+					   &addr6->sin6_addr) ||
+			  server->addr.sockAddr6.sin6_scope_id !=
+					   addr6->sin6_scope_id))
 			continue;
 
 		++server->srv_count;
@@ -1442,8 +1453,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
 			/* not ipv4 address, try ipv6 */
 			rc = cifs_inet_pton(AF_INET6, volume_info->UNCip,
 					    &sin_server6->sin6_addr.in6_u);
-			if (rc > 0)
-				addr.ss_family = AF_INET6;
+			addr.ss_family = AF_INET6;
+			sin_server6->sin6_scope_id = volume_info->v6scope;
 		} else {
 			addr.ss_family = AF_INET;
 		}
@@ -1517,6 +1528,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
 		memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
 			sizeof(struct sockaddr_in6));
 		sin_server6->sin6_port = htons(volume_info->port);
+		sin_server6->sin6_scope_id = volume_info->v6scope;
 		rc = ipv6_connect(tcp_ses);
 	} else {
 		memcpy(&tcp_ses->addr.sockAddr, sin_server,
-- 
1.6.0.6
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.