]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.fixes/cifs-fix-ssh-tunneled-mounts
Fix oinkmaster patch.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.fixes / cifs-fix-ssh-tunneled-mounts
CommitLineData
82094b55
AF
1From: Suresh Jayaraman <sjayaraman@suse.de>
2Subject: [PATCH] cifs: fix broken mounts when a SSH tunnel is used (try #4)
3References: bnc#527754
4Patch-mainline: in cifs-2.6.git (merge expected in 2.6.32-rcX)
5
6 It seems there is a regression that got introduced while Jeff fixed
7 all the mount/umount races. While attempting to find whether a tcp
8 session is already existing, we were not checking whether the "port"
9 used are the same. When a second mount is attempted with a different
10 "port=" option, it is being ignored. Because of this the cifs mounts
11 that uses a SSH tunnel appears to be broken.
12
13 Steps to reproduce:
14
15 1. create 2 shares
16 # SSH Tunnel a SMB session
17 2. ssh -f -L 6111:127.0.0.1:445 root@localhost "sleep 86400"
18 3. ssh -f -L 6222:127.0.0.1:445 root@localhost "sleep 86400"
19 4. tcpdump -i lo 6111 &
20 5. mkdir -p /mnt/mnt1
21 6. mkdir -p /mnt/mnt2
22 7. mount.cifs //localhost/a /mnt/mnt1 -o username=guest,ip=127.0.0.1,port=6111
23 #(shows tcpdump activity on port 6111)
24 8. mount.cifs //localhost/b /mnt/mnt2 -o username=guest,ip=127.0.0.1,port=6222
25 #(shows tcpdump activity only on port 6111 and not on 6222
26
27 Fix by adding a check to compare the port _only_ if the user tries to
28 override the tcp port with "port=" option, before deciding that an
29 existing tcp session is found. Also, clean up a bit by replacing
30 if-else if by a switch statment while at it as suggested by Jeff.
31
32Reviewed-by: Jeff Layton <jlayton@redhat.com>
33Reviewed-by: Shirish Pargaonkar <shirishp@us.ibm.com>
34Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
35Signed-off-by: Steve French <sfrench@us.ibm.com>
36---
37 fs/cifs/connect.c | 44 ++++++++++++++++++++++++++++++++++----------
38 1 file changed, 34 insertions(+), 10 deletions(-)
39
40Index: linux-2.6.27-SLE11_BRANCH/fs/cifs/connect.c
41===================================================================
42--- linux-2.6.27-SLE11_BRANCH.orig/fs/cifs/connect.c
43+++ linux-2.6.27-SLE11_BRANCH/fs/cifs/connect.c
44@@ -35,6 +35,7 @@
45 #include <linux/freezer.h>
46 #include <asm/uaccess.h>
47 #include <asm/processor.h>
48+#include <net/ipv6.h>
49 #include "cifspdu.h"
50 #include "cifsglob.h"
51 #include "cifsproto.h"
52@@ -1349,7 +1350,7 @@ cifs_parse_mount_options(char *options,
53 }
54
55 static struct TCP_Server_Info *
56-cifs_find_tcp_session(struct sockaddr_storage *addr)
57+cifs_find_tcp_session(struct sockaddr_storage *addr, unsigned short int port)
58 {
59 struct list_head *tmp;
60 struct TCP_Server_Info *server;
61@@ -1369,14 +1370,37 @@ cifs_find_tcp_session(struct sockaddr_st
62 if (server->tcpStatus == CifsNew)
63 continue;
64
65- if (addr->ss_family == AF_INET &&
66- (addr4->sin_addr.s_addr !=
67- server->addr.sockAddr.sin_addr.s_addr))
68- continue;
69- else if (addr->ss_family == AF_INET6 &&
70- memcmp(&server->addr.sockAddr6.sin6_addr,
71- &addr6->sin6_addr, sizeof(addr6->sin6_addr)))
72- continue;
73+ switch (addr->ss_family) {
74+ case AF_INET:
75+ if (addr4->sin_addr.s_addr ==
76+ server->addr.sockAddr.sin_addr.s_addr) {
77+ addr4->sin_port = htons(port);
78+ /* user overrode default port? */
79+ if (addr4->sin_port) {
80+ if (addr4->sin_port !=
81+ server->addr.sockAddr.sin_port)
82+ continue;
83+ }
84+ break;
85+ } else
86+ continue;
87+
88+ case AF_INET6:
89+ if (ipv6_addr_equal(&addr6->sin6_addr,
90+ &server->addr.sockAddr6.sin6_addr) &&
91+ (addr6->sin6_scope_id ==
92+ server->addr.sockAddr6.sin6_scope_id)) {
93+ addr6->sin6_port = htons(port);
94+ /* user overrode default port? */
95+ if (addr6->sin6_port) {
96+ if (addr6->sin6_port !=
97+ server->addr.sockAddr6.sin6_port)
98+ continue;
99+ }
100+ break;
101+ } else
102+ continue;
103+ }
104
105 ++server->srv_count;
106 write_unlock(&cifs_tcp_ses_lock);
107@@ -2111,7 +2135,7 @@ cifs_mount(struct super_block *sb, struc
108 }
109 }
110
111- srvTcp = cifs_find_tcp_session(&addr);
112+ srvTcp = cifs_find_tcp_session(&addr, volume_info.port);
113 if (!srvTcp) { /* create socket */
114 if (addr.ss_family == AF_INET6) {
115 cFYI(1, ("attempting ipv6 connect"));