Commit d4f0b6d3 authored by Pavel Shilovsky's avatar Pavel Shilovsky

Fix tunnel port problem for 2.6.31

parent 4cfbb7cd
......@@ -1382,13 +1382,16 @@ cifs_parse_mount_options(char *options, const char *devname,
}
static struct TCP_Server_Info *
cifs_find_tcp_session(struct sockaddr_storage *addr)
cifs_find_tcp_session(struct sockaddr_storage *addr, unsigned short int port)
{
struct list_head *tmp;
struct TCP_Server_Info *server;
struct sockaddr_in *addr4 = (struct sockaddr_in *) addr;
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr;
if (!port)
port = CIFS_PORT;
write_lock(&cifs_tcp_ses_lock);
list_for_each(tmp, &cifs_tcp_ses_list) {
server = list_entry(tmp, struct TCP_Server_Info,
......@@ -1403,12 +1406,14 @@ cifs_find_tcp_session(struct sockaddr_storage *addr)
continue;
if (addr->ss_family == AF_INET &&
(addr4->sin_addr.s_addr !=
server->addr.sockAddr.sin_addr.s_addr))
((addr4->sin_addr.s_addr !=
server->addr.sockAddr.sin_addr.s_addr) ||
(htons(port) != server->addr.sockAddr.sin_port)))
continue;
else if (addr->ss_family == AF_INET6 &&
(!ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr,
&addr6->sin6_addr) ||
(htons(port) != server->addr.sockAddr.sin_port) ||
server->addr.sockAddr6.sin6_scope_id !=
addr6->sin6_scope_id))
continue;
......@@ -1480,7 +1485,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
}
/* see if we already have a matching tcp_ses */
tcp_ses = cifs_find_tcp_session(&addr);
tcp_ses = cifs_find_tcp_session(&addr, volume_info->port);
if (tcp_ses)
return tcp_ses;
......@@ -1750,7 +1755,7 @@ ipv4_connect(struct TCP_Server_Info *server)
{
int rc = 0;
bool connected = false;
__be16 orig_port = 0;
bool orig_port_error = false;
struct socket *socket = server->ssocket;
if (socket == NULL) {
......@@ -1768,20 +1773,18 @@ ipv4_connect(struct TCP_Server_Info *server)
cifs_reclassify_socket4(socket);
}
/* user overrode default port */
/* user overrode default port or we perform reconnect */
if (server->addr.sockAddr.sin_port) {
rc = socket->ops->connect(socket, (struct sockaddr *)
&server->addr.sockAddr,
sizeof(struct sockaddr_in), 0);
if (rc >= 0)
connected = true;
else
orig_port_error = true;
}
if (!connected) {
/* save original port so we can retry user specified port
later if fall back ports fail this time */
orig_port = server->addr.sockAddr.sin_port;
if (!orig_port_error && !connected) {
/* do not retry on the same port we just failed on */
if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
server->addr.sockAddr.sin_port = htons(CIFS_PORT);
......@@ -1793,7 +1796,8 @@ ipv4_connect(struct TCP_Server_Info *server)
connected = true;
}
}
if (!connected) {
if (!orig_port_error && !connected) {
server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
rc = socket->ops->connect(socket, (struct sockaddr *)
&server->addr.sockAddr,
......@@ -1805,15 +1809,12 @@ ipv4_connect(struct TCP_Server_Info *server)
/* give up here - unless we want to retry on different
protocol families some day */
if (!connected) {
if (orig_port)
server->addr.sockAddr.sin_port = orig_port;
cFYI(1, ("Error %d connecting to server via ipv4", rc));
sock_release(socket);
server->ssocket = NULL;
return rc;
}
/*
* Eventually check for other socket options to change from
* the default. sock_setsockopt not used because it expects
......@@ -1902,7 +1903,7 @@ ipv6_connect(struct TCP_Server_Info *server)
{
int rc = 0;
bool connected = false;
__be16 orig_port = 0;
bool orig_port_error = false;
struct socket *socket = server->ssocket;
if (socket == NULL) {
......@@ -1928,13 +1929,11 @@ ipv6_connect(struct TCP_Server_Info *server)
sizeof(struct sockaddr_in6), 0);
if (rc >= 0)
connected = true;
else
orig_port_error = true;
}
if (!connected) {
/* save original port so we can retry user specified port
later if fall back ports fail this time */
orig_port = server->addr.sockAddr6.sin6_port;
if (!orig_port_error && !connected) {
/* do not retry on the same port we just failed on */
if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
......@@ -1945,7 +1944,8 @@ ipv6_connect(struct TCP_Server_Info *server)
connected = true;
}
}
if (!connected) {
if (!orig_port_error && !connected) {
server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
rc = socket->ops->connect(socket, (struct sockaddr *)
&server->addr.sockAddr6,
......@@ -1957,8 +1957,6 @@ ipv6_connect(struct TCP_Server_Info *server)
/* give up here - unless we want to retry on different
protocol families some day */
if (!connected) {
if (orig_port)
server->addr.sockAddr6.sin6_port = orig_port;
cFYI(1, ("Error %d connecting to server via ipv6", rc));
sock_release(socket);
server->ssocket = NULL;
......
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