diff --git a/nbase/nbase_addrset.c b/nbase/nbase_addrset.c
index 6f91bc1b2a..849044e4e3 100644
--- a/nbase/nbase_addrset.c
+++ b/nbase/nbase_addrset.c
@@ -477,30 +477,32 @@ static int sockaddr_to_addr(const struct sockaddr *sa, u32 *addr)
 
 static int sockaddr_to_mask (const struct sockaddr *sa, int bits, u32 *mask)
 {
-  s8 i;
-  int unmasked_bits = 0;
+  int i, k;
   if (bits >= 0) {
     if (sa->sa_family == AF_INET) {
-      unmasked_bits = 32 - bits;
+      bits += 96;
     }
 #ifdef HAVE_IPV6
     else if (sa->sa_family == AF_INET6) {
-      unmasked_bits = 128 - bits;
+      ; /* do nothing */
     }
 #endif
     else {
       return 0;
     }
   }
+  else
+    bits = 128;
+  k = bits / 32;
   for (i=0; i < 4; i++) {
-    if (unmasked_bits <= 32 * (3 - i)) {
+    if (i < k) {
       mask[i] = 0xffffffff;
     }
-    else if (unmasked_bits >= 32 * (4 - i)) {
+    else if (i > k) {
       mask[i] = 0;
     }
     else {
-      mask[i] = ~((1 << (unmasked_bits - (32 * (4 - i)))) - 1);
+      mask[i] = 0xfffffffe << (31 - bits % 32);
     }
   }
   return 1;
diff --git a/ncat/test/test-addrset.sh b/ncat/test/test-addrset.sh
index 7f54023c52..285c7b675a 100755
--- a/ncat/test/test-addrset.sh
+++ b/ncat/test/test-addrset.sh
@@ -208,6 +208,25 @@ test_addrset "1:2::0003/120" "1:2::3 1:2::0 1:2::ff" <<EOF
 1:3::3
 EOF
 
+# IPv6 CIDR netmask.
+test_addrset "1:2::3:4:5/95" "1:2::3:4:5 1:2::2:0:0 1:2::3:ffff:ffff" <<EOF
+1:2::3:4:5
+1:2::1:ffff:ffff
+1:2::2:0:0
+1:2::3:ffff:ffff
+1:2::4:0:0
+1:3::3
+EOF
+
+# IPv6 CIDR netmask.
+test_addrset "11::2/15" "11::2:3:4:5 10::1 11:ffff:ffff:ffff:ffff:ffff:ffff:ffff" <<EOF
+11::2:3:4:5
+9:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+10::1
+11:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+12::0
+EOF
+
 # /128 netmask.
 test_addrset "1:2::0003/128" "1:2::3" <<EOF
 1:2::3