#define STRCASEQ(a, b) (strcasecmp(a, b) == 0)
#define STRNCASEQ(a, b, n) (strncasecmp(a, b, n) == 0)
-/* Match set type names */
-#define MATCH_TYPENAME(a, b) STRNEQ(a, b, strlen(b))
-
/* Stringify tokens */
#define _STR(c) #c
#define STR(c) _STR(c)
u8 flags;
/* Default timeout value, if enabled */
u32 timeout;
+ /* Number of elements (vs timeout) */
+ u32 elements;
/* Element data size */
size_t dsize;
/* Offsets to extensions in elements */
#define IPSET_BITMAP_MAX_RANGE 0x0000FFFF
enum {
+ IPSET_ADD_STORE_PLAIN_TIMEOUT = -1,
IPSET_ADD_FAILED = 1,
- IPSET_ADD_STORE_PLAIN_TIMEOUT,
IPSET_ADD_START_STORED_TIMEOUT,
};
if (set->extensions & IPSET_EXT_DESTROY)
mtype_ext_cleanup(set);
memset(map->members, 0, map->memsize);
+ set->elements = 0;
}
/* Calculate the actual memory size of the set data */
goto nla_put_failure;
if (mtype_do_head(skb, map) ||
nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
- nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)))
+ nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) ||
+ nla_put_net32(skb, IPSET_ATTR_ELEMENTS, htonl(set->elements)))
goto nla_put_failure;
if (unlikely(ip_set_put_flags(skb, set)))
goto nla_put_failure;
if (ret == IPSET_ADD_FAILED) {
if (SET_WITH_TIMEOUT(set) &&
ip_set_timeout_expired(ext_timeout(x, set))) {
+ set->elements--;
ret = 0;
} else if (!(flags & IPSET_FLAG_EXIST)) {
set_bit(e->id, map->members);
/* Element is re-added, cleanup extensions */
ip_set_ext_destroy(set, x);
}
+ if (ret > 0)
+ set->elements--;
if (SET_WITH_TIMEOUT(set))
#ifdef IP_SET_BITMAP_STORED_TIMEOUT
/* Activate element */
set_bit(e->id, map->members);
+ set->elements++;
return 0;
}
return -IPSET_ERR_EXIST;
ip_set_ext_destroy(set, x);
+ set->elements--;
if (SET_WITH_TIMEOUT(set) &&
ip_set_timeout_expired(ext_timeout(x, set)))
return -IPSET_ERR_EXIST;
if (ip_set_timeout_expired(ext_timeout(x, set))) {
clear_bit(id, map->members);
ip_set_ext_destroy(set, x);
+ set->elements--;
}
}
spin_unlock_bh(&set->lock);
struct htype {
struct htable __rcu *table; /* the hash table */
u32 maxelem; /* max elements in the hash */
- u32 elements; /* current element (vs timeout) */
u32 initval; /* random jhash init value */
#ifdef IP_SET_HASH_WITH_MARKMASK
u32 markmask; /* markmask value for mark mask to store */
#ifdef IP_SET_HASH_WITH_NETS
memset(h->nets, 0, sizeof(struct net_prefixes) * NLEN(set->family));
#endif
- h->elements = 0;
+ set->elements = 0;
}
/* Destroy the hashtable part of the set */
nets_length, k);
#endif
ip_set_ext_destroy(set, data);
- h->elements--;
+ set->elements--;
d++;
}
}
bool deleted = false, forceadd = false, reuse = false;
u32 key, multi = 0;
- if (h->elements >= h->maxelem) {
+ if (set->elements >= h->maxelem) {
if (SET_WITH_TIMEOUT(set))
/* FIXME: when set is full, we slow down here */
mtype_expire(set, h, NLEN(set->family), set->dsize);
- if (h->elements >= h->maxelem && SET_WITH_FORCEADD(set))
+ if (set->elements >= h->maxelem && SET_WITH_FORCEADD(set))
forceadd = true;
}
pr_warn("Set %s is full, maxelem %u reached\n",
set->name, h->maxelem);
return -IPSET_ERR_HASH_FULL;
- } else if (h->elements >= h->maxelem) {
+ } else if (set->elements >= h->maxelem) {
goto set_full;
}
old = NULL;
NLEN(set->family), i);
#endif
ip_set_ext_destroy(set, data);
- h->elements--;
+ set->elements--;
}
goto copy_data;
}
- if (h->elements >= h->maxelem)
+ if (set->elements >= h->maxelem)
goto set_full;
/* Create a new slot */
if (n->pos >= n->size) {
j = n->pos++;
data = ahash_data(n, j, set->dsize);
copy_data:
- h->elements++;
+ set->elements++;
#ifdef IP_SET_HASH_WITH_NETS
for (i = 0; i < IPSET_NET_COUNT; i++)
mtype_add_cidr(h, NCIDR_PUT(DCIDR_GET(d->cidr, i)),
smp_mb__after_atomic();
if (i + 1 == n->pos)
n->pos--;
- h->elements--;
+ set->elements--;
#ifdef IP_SET_HASH_WITH_NETS
for (j = 0; j < IPSET_NET_COUNT; j++)
mtype_del_cidr(h, NCIDR_PUT(DCIDR_GET(d->cidr, j)),
#endif
if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) ||
- nla_put_net32(skb, IPSET_ATTR_ELEMENTS, htonl(h->elements)))
+ nla_put_net32(skb, IPSET_ATTR_ELEMENTS, htonl(set->elements)))
goto nla_put_failure;
if (unlikely(ip_set_put_flags(skb, set)))
goto nla_put_failure;
static inline void
list_set_del(struct ip_set *set, struct set_elem *e)
{
+ set->elements--;
list_del_rcu(&e->list);
__list_set_del(set, e);
}
list_add_rcu(&e->list, &prev->list);
else
list_add_tail_rcu(&e->list, &map->members);
+ set->elements++;
return 0;
}
list_for_each_entry_safe(e, n, &map->members, list)
list_set_del(set, e);
+ set->elements = 0;
}
static void
goto nla_put_failure;
if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) ||
nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
- nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)))
+ nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) ||
+ nla_put_net32(skb, IPSET_ATTR_ELEMENTS, htonl(set->elements)))
goto nla_put_failure;
if (unlikely(ip_set_put_flags(skb, set)))
goto nla_put_failure;
{ },
};
+/* Match set type names */
+#define MATCH_TYPENAME(a, b) STRNEQ(a, b, strlen(b))
+
/**
* ipset_errcode - interpret a kernel error code
* @session: session structure
safe_dprintf(session, ipset_print_number, IPSET_OPT_MEMSIZE);
safe_snprintf(session, "\nReferences: ");
safe_dprintf(session, ipset_print_number, IPSET_OPT_REFERENCES);
- if (MATCH_TYPENAME(type->name , "hash:")) {
+ if (ipset_data_test(data, IPSET_OPT_ELEMENTS)) {
safe_snprintf(session, "\nNumber of entries: ");
safe_dprintf(session, ipset_print_number, IPSET_OPT_ELEMENTS);
}
safe_snprintf(session, "</memsize>\n<references>");
safe_dprintf(session, ipset_print_number, IPSET_OPT_REFERENCES);
safe_snprintf(session, "</references>\n");
- if (MATCH_TYPENAME(type->name , "hash:")) {
+ if (ipset_data_test(data, IPSET_OPT_ELEMENTS)) {
safe_snprintf(session, "<numentries>");
safe_dprintf(session, ipset_print_number, IPSET_OPT_ELEMENTS);
safe_snprintf(session, "</numentries>\n");
.IP
ipset \-exist add test 192.168.0.1 timeout 600
.PP
+When listing the set, the number of entries printed in the header might be
+larger than the listed number of entries for sets with the timeout extensions:
+the number of entries in the set is updated when elements added/deleted to the
+set and periodically when the garbage colletor evicts the timed out entries.
+.PP
.SS "counters, packets, bytes"
All set types support the optional \fBcounters\fR
option when creating a set. If the option is specified then the set is created
Name: test
Type: bitmap:ip
Header: range 2.0.0.1-2.1.0.0 timeout 5
-Size in memory: 524408
+Size in memory: 532640
References: 0
+Number of entries: 1
Members:
2.1.0.0 timeout 0
Name: test
Type: bitmap:ip
Header: range 2.0.0.0-2.0.255.255 timeout 5
-Size in memory: 524408
+Size in memory: 532640
References: 0
+Number of entries: 1
Members:
2.0.0.0 timeout 0
Name: test
Type: bitmap:ip
Header: range 10.0.0.0-10.255.255.255 netmask 24 timeout 5
-Size in memory: 524408
+Size in memory: 532640
References: 0
+Number of entries: 1
Members:
10.255.255.0 timeout 0
Name: test
Type: bitmap:ip
Header: range 0.0.0.0-255.255.255.255 netmask 16 timeout 5
-Size in memory: 524408
+Size in memory: 532640
References: 0
+Number of entries: 2
Members:
0.0.0.0 timeout 0
255.255.0.0 timeout 0
Name: test
Type: bitmap:ip
Header: range 2.0.0.1-2.1.0.0 timeout x
-Size in memory: 524408
+Size in memory: 532640
References: 0
+Number of entries: 6
Members:
2.0.0.1 timeout x
2.0.0.128 timeout x
Name: test
Type: bitmap:ip
Header: range 2.0.0.0-2.0.255.255 timeout x
-Size in memory: 524408
+Size in memory: 532640
References: 0
+Number of entries: 2
Members:
2.0.0.0 timeout x
2.0.255.255 timeout x
Name: test
Type: bitmap:ip
Header: range 10.0.0.0-10.255.255.255 netmask 24 timeout x
-Size in memory: 524408
+Size in memory: 532640
References: 0
+Number of entries: 258
Members:
10.0.0.0 timeout x
10.8.0.0 timeout x
Header: range 2.0.0.1-2.1.0.0 comment
Size in memory: 532640
References: 0
+Number of entries: 1
Members:
2.0.0.1 comment "text message"
Header: range 2.0.0.1-2.1.0.0 comment
Size in memory: 532640
References: 0
+Number of entries: 255
Members:
2.0.0.1 comment "text message 1"
2.0.0.2 comment "text message 2"
Name: test
Type: bitmap:ip
Header: range 2.0.0.1-2.1.0.0 timeout x comment
-Size in memory: 1581216
+Size in memory: 1056928
References: 0
+Number of entries: 510
Members:
2.0.0.1 timeout x comment "text message 1"
2.0.0.2 timeout x comment "text message 2"
Name: test
Type: bitmap:ip
Header: range 2.0.0.1-2.1.0.0 timeout x comment
-Size in memory: 1581216
+Size in memory: 1056928
References: 0
+Number of entries: 510
Members:
2.0.1.1 timeout x comment "text message 1"
2.0.1.2 timeout x comment "text message 2"
Name: test
Type: bitmap:ip
Header: range 2.0.0.1-2.1.0.0
-Size in memory: 8232
+Size in memory: 8352
References: 0
+Number of entries: 6
Members:
2.0.0.1
2.0.0.128
Name: test
Type: bitmap:ip
Header: range 2.0.0.1-2.1.0.0
-Size in memory: 8232
+Size in memory: 8352
References: 0
+Number of entries: 2
Members:
2.0.0.1
2.1.0.0
Name: test
Type: bitmap:ip
Header: range 2.0.0.0-2.0.255.255
-Size in memory: 8232
+Size in memory: 8352
References: 0
+Number of entries: 2
Members:
2.0.0.0
2.0.255.255
Name: test
Type: bitmap:ip
Header: range 10.0.0.0-10.255.255.255 netmask 24
-Size in memory: 8232
+Size in memory: 8352
References: 0
+Number of entries: 258
Members:
10.0.0.0
10.8.0.0
Name: test
Type: bitmap:ip
Header: range 0.0.0.0-255.255.255.255 netmask 16
-Size in memory: 8232
+Size in memory: 8352
References: 0
+Number of entries: 2
Members:
0.0.0.0
255.255.0.0
Name: test
Type: bitmap:ip,mac
Header: range 2.0.0.1-2.1.0.0
-Size in memory: 458864
+Size in memory: 532632
References: 0
+Number of entries: 3
Members:
2.0.0.1,00:11:22:33:44:56
2.0.0.2,00:11:22:33:44:55
Name: test
Type: bitmap:ip,mac
Header: range 2.0.0.0-2.0.255.255
-Size in memory: 458864
+Size in memory: 532632
References: 0
+Number of entries: 3
Members:
2.0.0.0
2.0.0.2,00:11:22:33:44:55
Name: test
Type: bitmap:ip,mac
Header: range 2.0.0.1-2.1.0.0 timeout x
-Size in memory: 1048688
+Size in memory: 1056920
References: 0
+Number of entries: 1
Members:
2.1.0.0 timeout x
Name: test
Type: bitmap:ip,mac
Header: range 2.0.0.1-2.1.0.0 timeout x
-Size in memory: 1048688
+Size in memory: 1056920
References: 0
+Number of entries: 3
Members:
2.0.0.1,00:11:22:33:44:56 timeout x
2.0.0.2,00:11:22:33:44:55 timeout x
Name: test
Type: bitmap:port
Header: range 1-1024
-Size in memory: 152
+Size in memory: 276
References: 0
+Number of entries: 2
Members:
1
1024
Name: test
Type: bitmap:port
Header: range 0-65535
-Size in memory: 8216
+Size in memory: 8340
References: 0
+Number of entries: 2
Members:
0
65535
Name: test
Type: bitmap:port
-Header: range 0-65535 timeout 8
-Elements: 1
-Size in memory: 524288
+Header: range 0-65535 timeout x
+Size in memory: 532628
References: 0
+Number of entries: 2
Members:
-65535 timeout 0
+0 timeout x
+65535 timeout x
Name: test
Type: bitmap:port
Header: range 0-65535 timeout x
-Size in memory: 524400
+Size in memory: 532628
References: 0
+Number of entries: 2
Members:
0 timeout x
65535 timeout x
Name: test
Type: list:set
Header: size 8
-Size in memory: 112
+Size in memory: 224
References: 0
+Number of entries: 2
Members:
foo
bar
Name: test
Type: list:set
Header: size 8
-Size in memory: 120
+Size in memory: 264
References: 0
+Number of entries: 3
Members:
a
b
Name: test
Type: list:set
Header: size 8
-Size in memory: 120
+Size in memory: 224
References: 0
+Number of entries: 2
Members:
a
c
Name: test
Type: list:set
Header: size 8
-Size in memory: 120
+Size in memory: 184
References: 0
+Number of entries: 1
Members:
a