[linux-cifs-client] [PATCH 4/5] cifs: have cifs parse scope_id outof IPv6 addresses and use it

David Holder david at erion.co.uk
Thu Jun 11 15:13:05 GMT 2009


Jeff,

Great to see this going into the code. Do you plan to allow for textual
interface names after the %?

You can use getnameinfo() with the NI_NUMERICHOST flag to convert the
textual interface name and IPv6 address to numeric format or just use
if_nametoindex().

Regards, David

> This patch has CIFS look for a '%' in an IPv6 address. If one is
> present then it will try to treat that value as a numeric interface
> index suitable for stuffing into the sin6_scope_id field.
>
> This should allow people to mount servers on IPv6 link-local addresses.
>
> Signed-off-by: Jeff Layton <jlayton at redhat.com>
> ---
>  fs/cifs/connect.c     |    6 ++++--
>  fs/cifs/dns_resolve.c |    4 ++--
>  fs/cifs/netmisc.c     |   34 ++++++++++++++++++++++++++++------
>  3 files changed, 34 insertions(+), 10 deletions(-)
>
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 6a91b5f..c9e489c 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -1374,8 +1374,10 @@ cifs_find_tcp_session(struct sockaddr_storage
> *addr)
>  		     server->addr.sockAddr.sin_addr.s_addr))
>  			continue;
>  		else if (addr->ss_family == AF_INET6 &&
> -			 !ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr,
> -					  &addr6->sin6_addr))
> +			 (!ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr,
> +					   &addr6->sin6_addr) ||
> +			  server->addr.sockAddr6.sin6_scope_id !=
> +					   addr6->sin6_scope_id))
>  			continue;
>
>  		++server->srv_count;
> diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c
> index 91b5500..8794814 100644
> --- a/fs/cifs/dns_resolve.c
> +++ b/fs/cifs/dns_resolve.c
> @@ -35,7 +35,7 @@
>   * 		0 - name is not IP
>   */
>  static int
> -is_ip(const char *name)
> +is_ip(char *name)
>  {
>  	struct sockaddr_storage ss;
>
> @@ -57,7 +57,7 @@ dns_resolver_instantiate(struct key *key, const void
> *data,
>  	ip[datalen] = '\0';
>
>  	/* make sure this looks like an address */
> -	if (!is_ip((const char *) ip)) {
> +	if (!is_ip(ip)) {
>  		kfree(ip);
>  		return -EINVAL;
>  	}
> diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
> index 00e6e35..bd6d689 100644
> --- a/fs/cifs/netmisc.c
> +++ b/fs/cifs/netmisc.c
> @@ -158,25 +158,47 @@ cifs_inet_pton(const int address_family, const char
> *cp, void *dst)
>  /*
>   * Try to convert a string to an IPv4 address and then attempt to convert
>   * it to an IPv6 address if that fails. Set the family field if either
> - * succeeds.
> + * succeeds. If it's an IPv6 address and it has a '%' sign in it, try to
> + * treat the part following it as a numeric sin6_scope_id.
>   *
>   * Returns 0 on failure.
>   */
>  int
>  cifs_convert_address(char *src, void *dst)
>  {
> +	int rc;
> +	char *pct, *endp;
>  	struct sockaddr_in *s4 = (struct sockaddr_in *) dst;
> -	struct sockaddr_in6 *s6 = (Struct sockaddr_in6 *) dst;
> +	struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) dst;
>
> +	/* IPv4 address */
>  	if (cifs_inet_pton(AF_INET, src, &s4->sin_addr.s_addr)) {
>  		s4->sin_family = AF_INET;
>  		return 1;
> -	} else if (cifs_inet_pton(AF_INET6, src, &s6->sin6_addr.s6_addr)) {
> -		s6->sin6_family = AF_INET6;
> -		return 1;
>  	}
>
> -	return 0;
> +	/* temporarily terminate string */
> +	pct = strchr(src, '%');
> +	if (pct)
> +		*pct = '\0';
> +
> +	rc = cifs_inet_pton(AF_INET6, src, &s6->sin6_addr.s6_addr);
> +
> +	/* repair temp termination (if any) and make pct point to scopeid */
> +	if (pct)
> +		*pct++ = '%';
> +
> +	if (!rc)
> +		return rc;
> +
> +	s6->sin6_family = AF_INET6;
> +	if (pct) {
> +		s6->sin6_scope_id = (u32) simple_strtoul(pct, &endp, 0);
> +		if (!*pct || *endp)
> +			return 0;
> +	}
> +
> +	return rc;
>  }
>
>  /*****************************************************************************
> --
> 1.6.0.6
>
> _______________________________________________
> linux-cifs-client mailing list
> linux-cifs-client at lists.samba.org
> https://lists.samba.org/mailman/listinfo/linux-cifs-client
>




More information about the linux-cifs-client mailing list