summaryrefslogtreecommitdiffstats
path: root/kernel/ip_set_nethash.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/ip_set_nethash.c')
-rw-r--r--kernel/ip_set_nethash.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/kernel/ip_set_nethash.c b/kernel/ip_set_nethash.c
index d5b7a76..268fe6a 100644
--- a/kernel/ip_set_nethash.c
+++ b/kernel/ip_set_nethash.c
@@ -44,6 +44,7 @@ nethash_id_cidr(const struct ip_set_nethash *map,
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
if (*elem == *hash_ip)
return id;
+ /* No shortcut - there can be deleted entries. */
}
return UINT_MAX;
}
@@ -99,17 +100,21 @@ __nethash_add(struct ip_set_nethash *map, ip_set_ip_t *ip)
{
__u32 probe;
u_int16_t i;
- ip_set_ip_t *elem;
+ ip_set_ip_t *elem, *slot = NULL;
for (i = 0; i < map->probes; i++) {
probe = jhash_ip(map, i, *ip) % map->hashsize;
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe);
if (*elem == *ip)
return -EEXIST;
- if (!*elem) {
- *elem = *ip;
- return 0;
- }
+ if (!(slot || *elem))
+ slot = elem;
+ /* There can be deleted entries, must check all slots */
+ }
+ if (slot) {
+ *slot = *ip;
+ map->elements++;
+ return 0;
}
/* Trigger rehashing */
return -EAGAIN;