[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <46E027DD.4030505@hp.com>
Date: Thu, 06 Sep 2007 12:16:29 -0400
From: Brian Haley <brian.haley@...com>
To: Aurélien Charbon <aurelien.charbon@....bull.net>
Cc: Mailing list NFSv4 <nfsv4@...ux-nfs.org>,
netdev ML <netdev@...r.kernel.org>
Subject: Re: [PATCH 1/1] NFS: change the ip_map cache code to handle IPv6
addresses
Hi Aurelien,
More comments.
Aurélien Charbon wrote:
> This is a small part of missing pieces of IPv6 support for the server.
> It deals with the ip_map caching code part.
> /* Insert client into hashtable. */
> - for (i = 0; i < ncp->cl_naddr; i++)
> - auth_unix_add_addr(ncp->cl_addrlist[i], dom);
> -
> + for (i = 0; i < ncp->cl_naddr; i++) {
> + /* Mapping address */
> + ipv6_addr_v4map(ncp->cl_addrlist[i], addr6);
ipv6_addr_set(&addr6, 0, 0, htonl(0x0000FFFF), ncp->cl_addrlist[i]);
See below.
> @@ -236,7 +237,11 @@ static ssize_t write_getfs(struct file *
> res = (struct knfsd_fh*)buf;
>
> exp_readlock();
> - if (!(clp = auth_unix_lookup(sin->sin_addr)))
> +
> + /* IPv6 address mapping */
> + ipv6_addr_v4map(sin->sin_addr, in6);
ipv6_addr_set(&in6, 0, 0, htonl(0x0000FFFF), sin->sin_addr);
See below.
> @@ -271,7 +277,11 @@ static ssize_t write_getfd(struct file *
> res = buf;
> sin = (struct sockaddr_in *)&data->gd_addr;
> exp_readlock();
> - if (!(clp = auth_unix_lookup(sin->sin_addr)))
> +
> + /* IPv6 address mapping */
> + ipv6_addr_v4map(sin->sin_addr, in6);
ipv6_addr_set(&in6, 0, 0, htonl(0x0000FFFF), sin->sin_addr);
See below.
> +#define IS_ADDR_MAPPED(a) \
> + (((uint32_t *) (a))[0] == 0 \
> + && ((uint32_t *) (a))[1] == 0 \
> + && (((uint32_t *) (a))[2] == 0 \
> + || ((uint32_t *) (a))[2] == htonl(0xffff)))
Can go away, right?
> +static inline void ipv6_addr_v4map(const struct in_addr a1, struct in6_addr a2)
> +{
> + a2.s6_addr32[0] = 0;
> + a2.s6_addr32[1] = 0;
> + a2.s6_addr32[2] = htonl(0xffff);
> + a2.s6_addr32[3] = (uint32_t)a1.s_addr;
> +}
This can go away. Looking at other code that does this - TCP, UDP,
DCCP, they just call ipv6_addr_set() directly.
> +static inline int hash_ip6(struct in6_addr ip)
> +{
> + return (hash_ip(ip.s6_addr32[0]) ^
> + hash_ip(ip.s6_addr32[1]) ^
> + hash_ip(ip.s6_addr32[2]) ^
> + hash_ip(ip.s6_addr32[3]));
> +}
Should probably use a pointer to the address (*ip), probably doesn't
matter that much since it's an inline.
> @@ -151,20 +159,22 @@ static void ip_map_request(struct cache_
> {
> char text_addr[20];
This needs to be at least 40 since you're passing that to snprintf() below.
> + if (ipv6_addr_v4mapped(&(im->m_addr))) {
> + snprintf(text_addr, 20, NIPQUAD_FMT,
> + ntohl(im->m_addr.s6_addr32[3]) >> 24 & 0xff,
> + ntohl(im->m_addr.s6_addr32[3]) >> 16 & 0xff,
> + ntohl(im->m_addr.s6_addr32[3]) >> 8 & 0xff,
> + ntohl(im->m_addr.s6_addr32[3]) >> 0 & 0xff);
> + } else {
> + snprintf(text_addr, 40, NIP6_FMT, NIP6(im->m_addr));
> + }
Here -------------------------------^^
> -static struct ip_map *ip_map_lookup(char *class, struct in_addr addr)
> +static struct ip_map *ip_map_lookup(char *class, struct in6_addr addr)
Maybe you should pass a pointer to the address (*addr) to avoid passing
it on the stack.
> -int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
> +int auth_unix_add_addr(struct in6_addr addr, struct auth_domain *dom)
Here too.
> -struct auth_domain *auth_unix_lookup(struct in_addr addr)
> +struct auth_domain *auth_unix_lookup(struct in6_addr addr)
Here too.
> @@ -641,7 +669,19 @@ static int unix_gid_find(uid_t uid, stru
> int
> svcauth_unix_set_client(struct svc_rqst *rqstp)
> {
> - struct sockaddr_in *sin = svc_addr_in(rqstp);
> + struct sockaddr_in *sin;
> + struct sockaddr_in6 *sin6;
Will need change this to something like:
> + struct sockaddr_in6 *sin6, sin6_storage;
See below.
> +
> + switch (rqstp->rq_addr.ss_family) {
> + default:
> + BUG();
> + case AF_INET:
> + sin = svc_addr_in(rqstp);
> + ipv6_addr_v4map(sin->sin_addr, sin6->sin6_addr);
sin6 here is uninitialized, and in order to create a mapped address
you'll need to allocate storage space on the stack to hold it. New code
would be:
sin6 = &sin6_storage;
ipv6_addr_set(&sin6->sin6_addr, 0, 0, htonl(0x0000FFFF),
sin->sin_addr);
gcc really should have complained about that...
Maybe in the future rq_addr can just be in the correct form, but there's
a lot of other code that would need to change for that.
-Brian
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists