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 [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html