+out_badprefix:
+ xlog(L_ERROR, "Invalid prefix `%s' for %s", slash + 1, clp->m_hostname);
+ return 0;
+}
+
+#ifdef IPV6_SUPPORTED
+static int
+init_netmask6(nfs_client *clp, const char *slash)
+{
+ struct sockaddr_in6 sin6 = {
+ .sin6_family = AF_INET6,
+ };
+ unsigned long prefixlen;
+ uint32_t shift;
+ int i;
+
+ /*
+ * Decide what kind of netmask was specified. If there's
+ * no '/' present, assume the netmask is all ones. If
+ * there is a '/' and at least one ':', look for a spelled-
+ * out netmask. Otherwise, assume it was a prefixlen.
+ */
+ if (slash == NULL)
+ prefixlen = 128;
+ else {
+ if (strchr(slash + 1, ':') != NULL) {
+ if (!inet_pton(AF_INET6, slash + 1, &sin6.sin6_addr))
+ goto out_badmask;
+ set_addrlist_in6(clp, 1, &sin6);
+ return 1;
+ } else {
+ char *endptr;
+
+ prefixlen = strtoul(slash + 1, &endptr, 10);
+ if (*endptr != '\0' && prefixlen != ULONG_MAX &&
+ errno != ERANGE)
+ goto out_badprefix;
+ }
+ if (prefixlen > 128)
+ goto out_badprefix;
+ }
+
+ /*
+ * Now construct the full netmask bitmask in a sockaddr_in6,
+ * and plant it in the nfs_client record.
+ */
+ for (i = 0; prefixlen > 32; i++) {
+ sin6.sin6_addr.s6_addr32[i] = 0xffffffff;
+ prefixlen -= 32;
+ }
+ shift = 32 - (uint32_t)prefixlen;
+ sin6.sin6_addr.s6_addr32[i] = htonl((uint32_t)~0 << shift);
+ set_addrlist_in6(clp, 1, &sin6);
+
+ return 1;
+