|
@@ -149,17 +149,21 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
|
|
|
#endif
|
|
|
|
|
|
/* cidr + 1 is stored in net_prefixes to support /0 */
|
|
|
-#define SCIDR(cidr, i) (__CIDR(cidr, i) + 1)
|
|
|
+#define NCIDR_PUT(cidr) ((cidr) + 1)
|
|
|
+#define NCIDR_GET(cidr) ((cidr) - 1)
|
|
|
|
|
|
#ifdef IP_SET_HASH_WITH_NETS_PACKED
|
|
|
/* When cidr is packed with nomatch, cidr - 1 is stored in the data entry */
|
|
|
-#define GCIDR(cidr, i) (__CIDR(cidr, i) + 1)
|
|
|
-#define NCIDR(cidr) (cidr)
|
|
|
+#define DCIDR_PUT(cidr) ((cidr) - 1)
|
|
|
+#define DCIDR_GET(cidr, i) (__CIDR(cidr, i) + 1)
|
|
|
#else
|
|
|
-#define GCIDR(cidr, i) (__CIDR(cidr, i))
|
|
|
-#define NCIDR(cidr) (cidr - 1)
|
|
|
+#define DCIDR_PUT(cidr) (cidr)
|
|
|
+#define DCIDR_GET(cidr, i) __CIDR(cidr, i)
|
|
|
#endif
|
|
|
|
|
|
+#define INIT_CIDR(cidr, host_mask) \
|
|
|
+ DCIDR_PUT(((cidr) ? NCIDR_GET(cidr) : host_mask))
|
|
|
+
|
|
|
#define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128)
|
|
|
|
|
|
#ifdef IP_SET_HASH_WITH_NET0
|
|
@@ -303,7 +307,8 @@ struct htype {
|
|
|
|
|
|
#ifdef IP_SET_HASH_WITH_NETS
|
|
|
/* Network cidr size book keeping when the hash stores different
|
|
|
- * sized networks */
|
|
|
+ * sized networks. cidr == real cidr + 1 to support /0.
|
|
|
+ */
|
|
|
static void
|
|
|
mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
|
|
|
{
|
|
@@ -498,8 +503,10 @@ mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize)
|
|
|
pr_debug("expired %u/%u\n", i, j);
|
|
|
#ifdef IP_SET_HASH_WITH_NETS
|
|
|
for (k = 0; k < IPSET_NET_COUNT; k++)
|
|
|
- mtype_del_cidr(h, SCIDR(data->cidr, k),
|
|
|
- nets_length, k);
|
|
|
+ mtype_del_cidr(h,
|
|
|
+ NCIDR_PUT(DCIDR_GET(data->cidr,
|
|
|
+ k)),
|
|
|
+ nets_length, k);
|
|
|
#endif
|
|
|
ip_set_ext_destroy(set, data);
|
|
|
if (j != n->pos - 1)
|
|
@@ -692,9 +699,9 @@ reuse_slot:
|
|
|
data = ahash_data(n, j, set->dsize);
|
|
|
#ifdef IP_SET_HASH_WITH_NETS
|
|
|
for (i = 0; i < IPSET_NET_COUNT; i++) {
|
|
|
- mtype_del_cidr(h, SCIDR(data->cidr, i),
|
|
|
+ mtype_del_cidr(h, NCIDR_PUT(DCIDR_GET(data->cidr, i)),
|
|
|
NLEN(set->family), i);
|
|
|
- mtype_add_cidr(h, SCIDR(d->cidr, i),
|
|
|
+ mtype_add_cidr(h, NCIDR_PUT(DCIDR_GET(d->cidr, i)),
|
|
|
NLEN(set->family), i);
|
|
|
}
|
|
|
#endif
|
|
@@ -711,8 +718,8 @@ reuse_slot:
|
|
|
data = ahash_data(n, n->pos++, set->dsize);
|
|
|
#ifdef IP_SET_HASH_WITH_NETS
|
|
|
for (i = 0; i < IPSET_NET_COUNT; i++)
|
|
|
- mtype_add_cidr(h, SCIDR(d->cidr, i), NLEN(set->family),
|
|
|
- i);
|
|
|
+ mtype_add_cidr(h, NCIDR_PUT(DCIDR_GET(d->cidr, i)),
|
|
|
+ NLEN(set->family), i);
|
|
|
#endif
|
|
|
h->elements++;
|
|
|
}
|
|
@@ -772,8 +779,8 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
|
|
|
h->elements--;
|
|
|
#ifdef IP_SET_HASH_WITH_NETS
|
|
|
for (j = 0; j < IPSET_NET_COUNT; j++)
|
|
|
- mtype_del_cidr(h, SCIDR(d->cidr, j), NLEN(set->family),
|
|
|
- j);
|
|
|
+ mtype_del_cidr(h, NCIDR_PUT(DCIDR_GET(d->cidr, j)),
|
|
|
+ NLEN(set->family), j);
|
|
|
#endif
|
|
|
ip_set_ext_destroy(set, data);
|
|
|
if (n->pos + AHASH_INIT_SIZE < n->size) {
|
|
@@ -836,12 +843,13 @@ mtype_test_cidrs(struct ip_set *set, struct mtype_elem *d,
|
|
|
for (; j < nets_length && h->nets[j].cidr[0] && !multi; j++) {
|
|
|
#if IPSET_NET_COUNT == 2
|
|
|
mtype_data_reset_elem(d, &orig);
|
|
|
- mtype_data_netmask(d, NCIDR(h->nets[j].cidr[0]), false);
|
|
|
+ mtype_data_netmask(d, NCIDR_GET(h->nets[j].cidr[0]), false);
|
|
|
for (k = 0; k < nets_length && h->nets[k].cidr[1] && !multi;
|
|
|
k++) {
|
|
|
- mtype_data_netmask(d, NCIDR(h->nets[k].cidr[1]), true);
|
|
|
+ mtype_data_netmask(d, NCIDR_GET(h->nets[k].cidr[1]),
|
|
|
+ true);
|
|
|
#else
|
|
|
- mtype_data_netmask(d, NCIDR(h->nets[j].cidr[0]));
|
|
|
+ mtype_data_netmask(d, NCIDR_GET(h->nets[j].cidr[0]));
|
|
|
#endif
|
|
|
key = HKEY(d, h->initval, t->htable_bits);
|
|
|
n = hbucket(t, key);
|
|
@@ -889,7 +897,7 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
|
|
|
/* If we test an IP address and not a network address,
|
|
|
* try all possible network sizes */
|
|
|
for (i = 0; i < IPSET_NET_COUNT; i++)
|
|
|
- if (GCIDR(d->cidr, i) != SET_HOST_MASK(set->family))
|
|
|
+ if (DCIDR_GET(d->cidr, i) != SET_HOST_MASK(set->family))
|
|
|
break;
|
|
|
if (i == IPSET_NET_COUNT) {
|
|
|
ret = mtype_test_cidrs(set, d, ext, mext, flags);
|