Commit 5858ae44 authored by Steve French's avatar Steve French

[CIFS] Add IPv6 support

IPv6 support was started a few years ago in the cifs client, but lacked a
kernel helper function for parsing the ascii form of the ipv6 address. Now
that that is added (and now IPv6 is the default that some OS use now) it
was fairly easy to finish  the cifs ipv6 support.  This  requires that
CIFS_EXPERIMENTAL be enabled and (at least until the mount.cifs module is
modified to use a new ipv6 friendly call instead of gethostbyname) and the
ipv6 address be passed on the mount as "ip=" mount option.

Thanks
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent cbac3cba
Verison 1.48 Version 1.49
------------
IPv6 support. Enable ipv6 addresses to be passed on mount (put the ipv6
address after the "ip=" mount option, at least until mount.cifs is fixed to
handle DNS host to ipv6 name translation).
Version 1.48
------------ ------------
Fix mtime bouncing around from local idea of last write times to remote time. Fix mtime bouncing around from local idea of last write times to remote time.
Fix hang (in i_size_read) when simultaneous size update of same remote file Fix hang (in i_size_read) when simultaneous size update of same remote file
......
...@@ -1790,11 +1790,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -1790,11 +1790,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr, existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
NULL /* no ipv6 addr */, NULL /* no ipv6 addr */,
volume_info.username, &srvTcp); volume_info.username, &srvTcp);
else if(address_type == AF_INET6) else if(address_type == AF_INET6) {
cFYI(1,("looking for ipv6 address"));
existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */, existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
&sin_server6.sin6_addr, &sin_server6.sin6_addr,
volume_info.username, &srvTcp); volume_info.username, &srvTcp);
else { } else {
kfree(volume_info.UNC); kfree(volume_info.UNC);
kfree(volume_info.password); kfree(volume_info.password);
kfree(volume_info.prepath); kfree(volume_info.prepath);
...@@ -1810,12 +1811,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -1810,12 +1811,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
sin_server.sin_port = htons(volume_info.port); sin_server.sin_port = htons(volume_info.port);
else else
sin_server.sin_port = 0; sin_server.sin_port = 0;
rc = ipv4_connect(&sin_server,&csocket, if (address_type == AF_INET6) {
cFYI(1,("attempting ipv6 connect"));
/* BB should we allow ipv6 on port 139? */
/* other OS never observed in Wild doing 139 with v6 */
rc = ipv6_connect(&sin_server6,&csocket);
} else
rc = ipv4_connect(&sin_server,&csocket,
volume_info.source_rfc1001_name, volume_info.source_rfc1001_name,
volume_info.target_rfc1001_name); volume_info.target_rfc1001_name);
if (rc < 0) { if (rc < 0) {
cERROR(1, cERROR(1,
("Error connecting to IPv4 socket. Aborting operation")); ("Error connecting to IPv4 socket. Aborting operation"));
if(csocket != NULL) if(csocket != NULL)
sock_release(csocket); sock_release(csocket);
kfree(volume_info.UNC); kfree(volume_info.UNC);
......
...@@ -30,6 +30,9 @@ ...@@ -30,6 +30,9 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <asm/div64.h> #include <asm/div64.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#ifdef CONFIG_CIFS_EXPERIMENTAL
#include <linux/inet.h>
#endif
#include "cifsfs.h" #include "cifsfs.h"
#include "cifspdu.h" #include "cifspdu.h"
#include "cifsglob.h" #include "cifsglob.h"
...@@ -129,11 +132,27 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = { ...@@ -129,11 +132,27 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
/* Convert string containing dotted ip address to binary form */ /* Convert string containing dotted ip address to binary form */
/* returns 0 if invalid address */ /* returns 0 if invalid address */
/* BB add address family, change rc to status flag and return union or for ipv6 */
/* will need parent to call something like inet_pton to convert ipv6 address BB */
int int
cifs_inet_pton(int address_family, char *cp,void *dst) cifs_inet_pton(int address_family, char *cp,void *dst)
{ {
#ifdef CONFIG_CIFS_EXPERIMENTAL
int ret = 0;
/* calculate length by finding first slash or NULL */
/* BB Should we convert '/' slash to '\' here since it seems already done
before this */
if( address_family == AF_INET ){
ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL);
} else if( address_family == AF_INET6 ){
ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
}
#ifdef CONFIG_CIFS_DEBUG2
cFYI(1,("address conversion returned %d for %s", ret, cp));
#endif
if (ret > 0)
ret = 1;
return ret;
#else
int value; int value;
int digit; int digit;
int i; int i;
...@@ -192,6 +211,7 @@ cifs_inet_pton(int address_family, char *cp,void *dst) ...@@ -192,6 +211,7 @@ cifs_inet_pton(int address_family, char *cp,void *dst)
*((__be32 *)dst) = *((__be32 *) bytes) | htonl(value); *((__be32 *)dst) = *((__be32 *) bytes) | htonl(value);
return 1; /* success */ return 1; /* success */
#endif /* EXPERIMENTAL */
} }
/***************************************************************************** /*****************************************************************************
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment