Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53a0b9c4 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

NFS: Replace nfs_parse_ip_address() with rpc_pton()



Clean up: Use the common routine now provided in sunrpc.ko for parsing mount
addresses.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent c877b849
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -214,7 +214,6 @@ void nfs_zap_acl_cache(struct inode *inode);
extern int nfs_wait_bit_killable(void *word);

/* super.c */
void nfs_parse_ip_address(char *, size_t, struct sockaddr *, size_t *);
extern struct file_system_type nfs_xdev_fs_type;
#ifdef CONFIG_NFS_V4
extern struct file_system_type nfs4_xdev_fs_type;
+3 −3
Original line number Diff line number Diff line
@@ -121,9 +121,9 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,

		if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len))
			continue;
		nfs_parse_ip_address(buf->data, buf->len,
				mountdata->addr, &mountdata->addrlen);
		if (mountdata->addr->sa_family == AF_UNSPEC)
		mountdata->addrlen = rpc_pton(buf->data, buf->len,
				mountdata->addr, mountdata->addrlen);
		if (mountdata->addrlen == 0)
			continue;
		nfs_set_port(mountdata->addr, NFS_PORT);

+19 −129
Original line number Diff line number Diff line
@@ -742,129 +742,10 @@ static int nfs_verify_server_address(struct sockaddr *addr)
	}
	}

	dfprintk(MOUNT, "NFS: Invalid IP address specified\n");
	return 0;
}

static void nfs_parse_ipv4_address(char *string, size_t str_len,
				   struct sockaddr *sap, size_t *addr_len)
{
	struct sockaddr_in *sin = (struct sockaddr_in *)sap;
	u8 *addr = (u8 *)&sin->sin_addr.s_addr;

	if (str_len <= INET_ADDRSTRLEN) {
		dfprintk(MOUNT, "NFS: parsing IPv4 address %*s\n",
				(int)str_len, string);

		sin->sin_family = AF_INET;
		*addr_len = sizeof(*sin);
		if (in4_pton(string, str_len, addr, '\0', NULL))
			return;
	}

	sap->sa_family = AF_UNSPEC;
	*addr_len = 0;
}

#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static int nfs_parse_ipv6_scope_id(const char *string, const size_t str_len,
				   const char *delim,
				   struct sockaddr_in6 *sin6)
{
	char *p;
	size_t len;

	if ((string + str_len) == delim)
		return 1;

	if (*delim != IPV6_SCOPE_DELIMITER)
		return 0;

	if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
		return 0;

	len = (string + str_len) - delim - 1;
	p = kstrndup(delim + 1, len, GFP_KERNEL);
	if (p) {
		unsigned long scope_id = 0;
		struct net_device *dev;

		dev = dev_get_by_name(&init_net, p);
		if (dev != NULL) {
			scope_id = dev->ifindex;
			dev_put(dev);
		} else {
			if (strict_strtoul(p, 10, &scope_id) == 0) {
				kfree(p);
				return 0;
			}
		}

		kfree(p);

		sin6->sin6_scope_id = scope_id;
		dfprintk(MOUNT, "NFS: IPv6 scope ID = %lu\n", scope_id);
		return 1;
	}

	return 0;
}

static void nfs_parse_ipv6_address(char *string, size_t str_len,
				   struct sockaddr *sap, size_t *addr_len)
{
	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
	u8 *addr = (u8 *)&sin6->sin6_addr.in6_u;
	const char *delim;

	if (str_len <= INET6_ADDRSTRLEN) {
		dfprintk(MOUNT, "NFS: parsing IPv6 address %*s\n",
				(int)str_len, string);

		sin6->sin6_family = AF_INET6;
		*addr_len = sizeof(*sin6);
		if (in6_pton(string, str_len, addr,
					IPV6_SCOPE_DELIMITER, &delim) != 0) {
			if (nfs_parse_ipv6_scope_id(string, str_len,
							delim, sin6) != 0)
				return;
		}
	}

	sap->sa_family = AF_UNSPEC;
	*addr_len = 0;
}
#else
static void nfs_parse_ipv6_address(char *string, size_t str_len,
				   struct sockaddr *sap, size_t *addr_len)
{
	sap->sa_family = AF_UNSPEC;
	*addr_len = 0;
}
#endif

/*
 * Construct a sockaddr based on the contents of a string that contains
 * an IP address in presentation format.
 *
 * If there is a problem constructing the new sockaddr, set the address
 * family to AF_UNSPEC.
 */
void nfs_parse_ip_address(char *string, size_t str_len,
				 struct sockaddr *sap, size_t *addr_len)
{
	unsigned int i, colons;

	colons = 0;
	for (i = 0; i < str_len; i++)
		if (string[i] == ':')
			colons++;

	if (colons >= 2)
		nfs_parse_ipv6_address(string, str_len, sap, addr_len);
	else
		nfs_parse_ipv4_address(string, str_len, sap, addr_len);
}

/*
 * Sanity check the NFS transport protocol.
 *
@@ -1344,11 +1225,14 @@ static int nfs_parse_mount_options(char *raw,
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;
			nfs_parse_ip_address(string, strlen(string),
			mnt->nfs_server.addrlen =
				rpc_pton(string, strlen(string),
					(struct sockaddr *)
					&mnt->nfs_server.address,
					     &mnt->nfs_server.addrlen);
					sizeof(mnt->nfs_server.address));
			kfree(string);
			if (mnt->nfs_server.addrlen == 0)
				goto out_invalid_address;
			break;
		case Opt_clientaddr:
			string = match_strdup(args);
@@ -1368,11 +1252,14 @@ static int nfs_parse_mount_options(char *raw,
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;
			nfs_parse_ip_address(string, strlen(string),
			mnt->mount_server.addrlen =
				rpc_pton(string, strlen(string),
					(struct sockaddr *)
					&mnt->mount_server.address,
					     &mnt->mount_server.addrlen);
					sizeof(mnt->mount_server.address));
			kfree(string);
			if (mnt->mount_server.addrlen == 0)
				goto out_invalid_address;
			break;
		case Opt_lookupcache:
			string = match_strdup(args);
@@ -1424,6 +1311,9 @@ static int nfs_parse_mount_options(char *raw,

	return 1;

out_invalid_address:
	printk(KERN_INFO "NFS: bad IP address specified: %s\n", p);
	return 0;
out_invalid_value:
	printk(KERN_INFO "NFS: bad mount option value specified: %s\n", p);
	return 0;