Skip to content

Commit 6d74016

Browse files
Paulo Alcantarasmfrench
authored andcommitted
cifs: set resolved ip in sockaddr
All callers from dns_resolve_server_name_to_ip() used to convert the ip addr string back to sockaddr, so do that inside dns_resolve_server_name_to_ip() and avoid duplicating code. Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 2301bc1 commit 6d74016

File tree

6 files changed

+55
-103
lines changed

6 files changed

+55
-103
lines changed

fs/cifs/connect.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
9191
{
9292
int rc;
9393
int len;
94-
char *unc, *ipaddr = NULL;
94+
char *unc;
95+
struct sockaddr_storage ss;
9596
time64_t expiry, now;
9697
unsigned long ttl = SMB_DNS_RESOLVE_INTERVAL_DEFAULT;
9798

@@ -111,7 +112,11 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
111112
}
112113
scnprintf(unc, len, "\\\\%s", server->hostname);
113114

114-
rc = dns_resolve_server_name_to_ip(unc, &ipaddr, &expiry);
115+
spin_lock(&server->srv_lock);
116+
ss = server->dstaddr;
117+
spin_unlock(&server->srv_lock);
118+
119+
rc = dns_resolve_server_name_to_ip(unc, (struct sockaddr *)&ss, &expiry);
115120
kfree(unc);
116121

117122
if (rc < 0) {
@@ -121,22 +126,13 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
121126
}
122127

123128
spin_lock(&server->srv_lock);
124-
rc = cifs_convert_address((struct sockaddr *)&server->dstaddr, ipaddr,
125-
strlen(ipaddr));
129+
memcpy(&server->dstaddr, &ss, sizeof(server->dstaddr));
126130
spin_unlock(&server->srv_lock);
127-
kfree(ipaddr);
128131

129-
/* rc == 1 means success here */
130-
if (rc) {
131-
now = ktime_get_real_seconds();
132-
if (expiry && expiry > now)
133-
/*
134-
* To make sure we don't use the cached entry, retry 1s
135-
* after expiry.
136-
*/
137-
ttl = max_t(unsigned long, expiry - now, SMB_DNS_RESOLVE_INTERVAL_MIN) + 1;
138-
}
139-
rc = !rc ? -1 : 0;
132+
now = ktime_get_real_seconds();
133+
if (expiry && expiry > now)
134+
/* To make sure we don't use the cached entry, retry 1s */
135+
ttl = max_t(unsigned long, expiry - now, SMB_DNS_RESOLVE_INTERVAL_MIN) + 1;
140136

141137
requeue_resolve:
142138
cifs_dbg(FYI, "%s: next dns resolution scheduled for %lu seconds in the future\n",

fs/cifs/dfs.c

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,6 @@
99
#include "fs_context.h"
1010
#include "dfs.h"
1111

12-
/* Resolve UNC server name and set destination ip address in fs context */
13-
static int resolve_unc(const char *path, struct smb3_fs_context *ctx)
14-
{
15-
int rc;
16-
char *ip = NULL;
17-
18-
rc = dns_resolve_server_name_to_ip(path, &ip, NULL);
19-
if (rc < 0) {
20-
cifs_dbg(FYI, "%s: failed to resolve UNC server name: %d\n", __func__, rc);
21-
return rc;
22-
}
23-
24-
if (!cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip, strlen(ip))) {
25-
cifs_dbg(VFS, "%s: could not determinate destination address\n", __func__);
26-
rc = -EHOSTUNREACH;
27-
} else
28-
rc = 0;
29-
30-
kfree(ip);
31-
return rc;
32-
}
33-
3412
/**
3513
* dfs_parse_target_referral - set fs context for dfs target referral
3614
*
@@ -68,7 +46,7 @@ int dfs_parse_target_referral(const char *full_path, const struct dfs_info3_para
6846
if (rc)
6947
goto out;
7048

71-
rc = resolve_unc(path, ctx);
49+
rc = dns_resolve_server_name_to_ip(path, (struct sockaddr *)&ctx->dstaddr, NULL);
7250

7351
out:
7452
kfree(path);

fs/cifs/dfs_cache.c

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,8 +1314,7 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, c
13141314
char unc[sizeof("\\\\") + SERVER_NAME_LENGTH] = {0};
13151315
const char *host;
13161316
size_t hostlen;
1317-
char *ip = NULL;
1318-
struct sockaddr sa;
1317+
struct sockaddr_storage ss;
13191318
bool match;
13201319
int rc;
13211320

@@ -1330,23 +1329,17 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, c
13301329
extract_unc_hostname(s1, &host, &hostlen);
13311330
scnprintf(unc, sizeof(unc), "\\\\%.*s", (int)hostlen, host);
13321331

1333-
rc = dns_resolve_server_name_to_ip(unc, &ip, NULL);
1332+
rc = dns_resolve_server_name_to_ip(unc, (struct sockaddr *)&ss, NULL);
13341333
if (rc < 0) {
13351334
cifs_dbg(FYI, "%s: could not resolve %.*s. assuming server address matches.\n",
13361335
__func__, (int)hostlen, host);
13371336
return true;
13381337
}
13391338

1340-
if (!cifs_convert_address(&sa, ip, strlen(ip))) {
1341-
cifs_dbg(VFS, "%s: failed to convert address \'%s\'. skip address matching.\n",
1342-
__func__, ip);
1343-
} else {
1344-
cifs_server_lock(server);
1345-
match = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, &sa);
1346-
cifs_server_unlock(server);
1347-
}
1339+
cifs_server_lock(server);
1340+
match = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, (struct sockaddr *)&ss);
1341+
cifs_server_unlock(server);
13481342

1349-
kfree(ip);
13501343
return match;
13511344
}
13521345

fs/cifs/dns_resolve.c

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
*
1313
*/
1414

15+
#include <linux/inet.h>
1516
#include <linux/slab.h>
1617
#include <linux/dns_resolver.h>
1718
#include "dns_resolve.h"
@@ -25,17 +26,13 @@
2526
* @ip_addr: Where to return the IP address.
2627
* @expiry: Where to return the expiry time for the dns record.
2728
*
28-
* The IP address will be returned in string form, and the caller is
29-
* responsible for freeing it.
30-
*
31-
* Returns length of result on success, -ve on error.
29+
* Returns zero success, -ve on error.
3230
*/
3331
int
34-
dns_resolve_server_name_to_ip(const char *unc, char **ip_addr, time64_t *expiry)
32+
dns_resolve_server_name_to_ip(const char *unc, struct sockaddr *ip_addr, time64_t *expiry)
3533
{
36-
struct sockaddr_storage ss;
3734
const char *hostname, *sep;
38-
char *name;
35+
char *ip;
3936
int len, rc;
4037

4138
if (!ip_addr || !unc)
@@ -60,30 +57,32 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr, time64_t *expiry)
6057
__func__, unc);
6158

6259
/* Try to interpret hostname as an IPv4 or IPv6 address */
63-
rc = cifs_convert_address((struct sockaddr *)&ss, hostname, len);
64-
if (rc > 0)
65-
goto name_is_IP_address;
60+
rc = cifs_convert_address(ip_addr, hostname, len);
61+
if (rc > 0) {
62+
cifs_dbg(FYI, "%s: unc is IP, skipping dns upcall: %*.*s\n", __func__, len, len,
63+
hostname);
64+
return 0;
65+
}
6666

6767
/* Perform the upcall */
6868
rc = dns_query(current->nsproxy->net_ns, NULL, hostname, len,
69-
NULL, ip_addr, expiry, false);
70-
if (rc < 0)
69+
NULL, &ip, expiry, false);
70+
if (rc < 0) {
7171
cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n",
7272
__func__, len, len, hostname);
73-
else
73+
} else {
7474
cifs_dbg(FYI, "%s: resolved: %*.*s to %s expiry %llu\n",
75-
__func__, len, len, hostname, *ip_addr,
75+
__func__, len, len, hostname, ip,
7676
expiry ? (*expiry) : 0);
77-
return rc;
7877

79-
name_is_IP_address:
80-
name = kmalloc(len + 1, GFP_KERNEL);
81-
if (!name)
82-
return -ENOMEM;
83-
memcpy(name, hostname, len);
84-
name[len] = 0;
85-
cifs_dbg(FYI, "%s: unc is IP, skipping dns upcall: %s\n",
86-
__func__, name);
87-
*ip_addr = name;
88-
return 0;
78+
rc = cifs_convert_address(ip_addr, ip, strlen(ip));
79+
kfree(ip);
80+
81+
if (!rc) {
82+
cifs_dbg(FYI, "%s: unable to determine ip address\n", __func__);
83+
rc = -EHOSTUNREACH;
84+
} else
85+
rc = 0;
86+
}
87+
return rc;
8988
}

fs/cifs/dns_resolve.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
#ifndef _DNS_RESOLVE_H
1212
#define _DNS_RESOLVE_H
1313

14+
#include <linux/net.h>
15+
1416
#ifdef __KERNEL__
15-
extern int dns_resolve_server_name_to_ip(const char *unc, char **ip_addr, time64_t *expiry);
17+
int dns_resolve_server_name_to_ip(const char *unc, struct sockaddr *ip_addr, time64_t *expiry);
1618
#endif /* KERNEL */
1719

1820
#endif /* _DNS_RESOLVE_H */

fs/cifs/misc.c

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,44 +1258,28 @@ int match_target_ip(struct TCP_Server_Info *server,
12581258
bool *result)
12591259
{
12601260
int rc;
1261-
char *target, *tip = NULL;
1262-
struct sockaddr tipaddr;
1261+
char *target;
1262+
struct sockaddr_storage ss;
12631263

12641264
*result = false;
12651265

12661266
target = kzalloc(share_len + 3, GFP_KERNEL);
1267-
if (!target) {
1268-
rc = -ENOMEM;
1269-
goto out;
1270-
}
1267+
if (!target)
1268+
return -ENOMEM;
12711269

12721270
scnprintf(target, share_len + 3, "\\\\%.*s", (int)share_len, share);
12731271

12741272
cifs_dbg(FYI, "%s: target name: %s\n", __func__, target + 2);
12751273

1276-
rc = dns_resolve_server_name_to_ip(target, &tip, NULL);
1277-
if (rc < 0)
1278-
goto out;
1279-
1280-
cifs_dbg(FYI, "%s: target ip: %s\n", __func__, tip);
1274+
rc = dns_resolve_server_name_to_ip(target, (struct sockaddr *)&ss, NULL);
1275+
kfree(target);
12811276

1282-
if (!cifs_convert_address(&tipaddr, tip, strlen(tip))) {
1283-
cifs_dbg(VFS, "%s: failed to convert target ip address\n",
1284-
__func__);
1285-
rc = -EINVAL;
1286-
goto out;
1287-
}
1277+
if (rc < 0)
1278+
return rc;
12881279

1289-
*result = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr,
1290-
&tipaddr);
1280+
*result = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, (struct sockaddr *)&ss);
12911281
cifs_dbg(FYI, "%s: ip addresses match: %u\n", __func__, *result);
1292-
rc = 0;
1293-
1294-
out:
1295-
kfree(target);
1296-
kfree(tip);
1297-
1298-
return rc;
1282+
return 0;
12991283
}
13001284

13011285
int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix)

0 commit comments

Comments
 (0)