Trond Myklebust wrote: > On Thu, 2007-11-15 at 12:23 -0500, Chuck Lever wrote: >> Trond Myklebust wrote: >>> On Thu, 2007-11-15 at 08:55 -0500, Chuck Lever wrote: >>> >>>> What do you think of changing the rq_daddr field to be a sockaddr_storage? >>> Why? You've already got rq_addr. >> OK, here's what I've ended up with. I think this is what you and Neil >> have been suggesting. Comments? >> >> /* >> * Find an NLM client handle in the cache. If there is none, create it. >> * >> * Manufacture a specific source address in case we're using multiple >> * IP addresses on a single NIC. NB: the family of the address in >> * rq_daddr is guaranteed to be the same as the family of rq_addr. >> */ >> struct nlm_host * >> nlmsvc_lookup_host(struct svc_rqst *rqstp, >> const char *hostname, unsigned int hostname_len) >> { >> struct sockaddr_in6 source = { >> .sin6_family = AF_INET6, >> }; >> >> switch(svc_addr(rqstp)->sa_family) { >> case AF_INET: { >> struct sockaddr_in *sin = (struct sockaddr_in *)&source; >> sin->sin_family = AF_INET; >> sin->sin_addr.s_addr = rqstp->rq_daddr.addr.s_addr; >> break; >> } >> case AF_INET6: >> ipv6_addr_copy(&source.sin6_addr, >> &rqstp->rq_daddr.addr6); >> break; >> } >> >> return nlm_lookup_host(1, svc_addr_in(rqstp), >> rqstp->rq_prot, rqstp->rq_vers, >> hostname, hostname_len, >> (struct sockaddr *)&source); >> } > > That works for me. Technically, I suppose we should really pass a > source_len to nlm_lookup_host() if only to ensure that the comparisons > don't overrun memory, however in practice I doubt this is a problem. We > always know that the kernel allocates enough space. My IPv6-aware version of nlm_cmp_addr takes a pair of sockaddr *'s; no lengths are needed for the comparison of either AF_INET or AF_INET6 addresses. In fact, in most cases, it appears that the address length is unneeded for us. Both INET families use fixed-size addresses.