aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/client.c
diff options
context:
space:
mode:
authorAnna Schumaker <Anna.Schumaker@netapp.com>2015-07-13 14:01:28 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-08-17 14:29:51 -0400
commitd8efa4e62505f5113e363572b5438b7be0d08b12 (patch)
treeb5d6ce8aa44591dcef853a2ff51fa6788f7939f9 /fs/nfs/client.c
parent58cc8a55aa38655d472a4c381df465c9ab97b4d6 (diff)
NFS: Use RPC functions for matching sockaddrs
They already exist and do the exact same thing. Let's save ourselves several lines of code! Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r--fs/nfs/client.c113
1 files changed, 2 insertions, 111 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 4a90c9bb3135..57c5a02f6213 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -20,6 +20,7 @@
20#include <linux/stat.h> 20#include <linux/stat.h>
21#include <linux/errno.h> 21#include <linux/errno.h>
22#include <linux/unistd.h> 22#include <linux/unistd.h>
23#include <linux/sunrpc/addr.h>
23#include <linux/sunrpc/clnt.h> 24#include <linux/sunrpc/clnt.h>
24#include <linux/sunrpc/stats.h> 25#include <linux/sunrpc/stats.h>
25#include <linux/sunrpc/metrics.h> 26#include <linux/sunrpc/metrics.h>
@@ -285,116 +286,6 @@ void nfs_put_client(struct nfs_client *clp)
285} 286}
286EXPORT_SYMBOL_GPL(nfs_put_client); 287EXPORT_SYMBOL_GPL(nfs_put_client);
287 288
288#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
289/*
290 * Test if two ip6 socket addresses refer to the same socket by
291 * comparing relevant fields. The padding bytes specifically, are not
292 * compared. sin6_flowinfo is not compared because it only affects QoS
293 * and sin6_scope_id is only compared if the address is "link local"
294 * because "link local" addresses need only be unique to a specific
295 * link. Conversely, ordinary unicast addresses might have different
296 * sin6_scope_id.
297 *
298 * The caller should ensure both socket addresses are AF_INET6.
299 */
300static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
301 const struct sockaddr *sa2)
302{
303 const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sa1;
304 const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sa2;
305
306 if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
307 return 0;
308 else if (ipv6_addr_type(&sin1->sin6_addr) & IPV6_ADDR_LINKLOCAL)
309 return sin1->sin6_scope_id == sin2->sin6_scope_id;
310
311 return 1;
312}
313#else /* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */
314static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
315 const struct sockaddr *sa2)
316{
317 return 0;
318}
319#endif
320
321/*
322 * Test if two ip4 socket addresses refer to the same socket, by
323 * comparing relevant fields. The padding bytes specifically, are
324 * not compared.
325 *
326 * The caller should ensure both socket addresses are AF_INET.
327 */
328static int nfs_sockaddr_match_ipaddr4(const struct sockaddr *sa1,
329 const struct sockaddr *sa2)
330{
331 const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
332 const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
333
334 return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
335}
336
337static int nfs_sockaddr_cmp_ip6(const struct sockaddr *sa1,
338 const struct sockaddr *sa2)
339{
340 const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sa1;
341 const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sa2;
342
343 return nfs_sockaddr_match_ipaddr6(sa1, sa2) &&
344 (sin1->sin6_port == sin2->sin6_port);
345}
346
347static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1,
348 const struct sockaddr *sa2)
349{
350 const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
351 const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
352
353 return nfs_sockaddr_match_ipaddr4(sa1, sa2) &&
354 (sin1->sin_port == sin2->sin_port);
355}
356
357#if defined(CONFIG_NFS_V4_1)
358/*
359 * Test if two socket addresses represent the same actual socket,
360 * by comparing (only) relevant fields, excluding the port number.
361 */
362int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
363 const struct sockaddr *sa2)
364{
365 if (sa1->sa_family != sa2->sa_family)
366 return 0;
367
368 switch (sa1->sa_family) {
369 case AF_INET:
370 return nfs_sockaddr_match_ipaddr4(sa1, sa2);
371 case AF_INET6:
372 return nfs_sockaddr_match_ipaddr6(sa1, sa2);
373 }
374 return 0;
375}
376EXPORT_SYMBOL_GPL(nfs_sockaddr_match_ipaddr);
377#endif /* CONFIG_NFS_V4_1 */
378
379/*
380 * Test if two socket addresses represent the same actual socket,
381 * by comparing (only) relevant fields, including the port number.
382 */
383static int nfs_sockaddr_cmp(const struct sockaddr *sa1,
384 const struct sockaddr *sa2)
385{
386 if (sa1->sa_family != sa2->sa_family)
387 return 0;
388
389 switch (sa1->sa_family) {
390 case AF_INET:
391 return nfs_sockaddr_cmp_ip4(sa1, sa2);
392 case AF_INET6:
393 return nfs_sockaddr_cmp_ip6(sa1, sa2);
394 }
395 return 0;
396}
397
398/* 289/*
399 * Find an nfs_client on the list that matches the initialisation data 290 * Find an nfs_client on the list that matches the initialisation data
400 * that is supplied. 291 * that is supplied.
@@ -421,7 +312,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
421 if (clp->cl_minorversion != data->minorversion) 312 if (clp->cl_minorversion != data->minorversion)
422 continue; 313 continue;
423 /* Match the full socket address */ 314 /* Match the full socket address */
424 if (!nfs_sockaddr_cmp(sap, clap)) 315 if (!rpc_cmp_addr_port(sap, clap))
425 continue; 316 continue;
426 317
427 atomic_inc(&clp->cl_count); 318 atomic_inc(&clp->cl_count);