mirror of https://gitee.com/openkylin/linux.git
netfilter: ipset: list:set timeout variant fixes
- the timeout value was actually not set - the garbage collector was broken The variant is fixed, the tests to the ipset testsuite are added. Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
4dd5ffe4fc
commit
512d06b5b6
|
@ -43,14 +43,19 @@ struct list_set {
|
||||||
static inline struct set_elem *
|
static inline struct set_elem *
|
||||||
list_set_elem(const struct list_set *map, u32 id)
|
list_set_elem(const struct list_set *map, u32 id)
|
||||||
{
|
{
|
||||||
return (struct set_elem *)((char *)map->members + id * map->dsize);
|
return (struct set_elem *)((void *)map->members + id * map->dsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct set_telem *
|
||||||
|
list_set_telem(const struct list_set *map, u32 id)
|
||||||
|
{
|
||||||
|
return (struct set_telem *)((void *)map->members + id * map->dsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
list_set_timeout(const struct list_set *map, u32 id)
|
list_set_timeout(const struct list_set *map, u32 id)
|
||||||
{
|
{
|
||||||
const struct set_telem *elem =
|
const struct set_telem *elem = list_set_telem(map, id);
|
||||||
(const struct set_telem *) list_set_elem(map, id);
|
|
||||||
|
|
||||||
return ip_set_timeout_test(elem->timeout);
|
return ip_set_timeout_test(elem->timeout);
|
||||||
}
|
}
|
||||||
|
@ -58,19 +63,11 @@ list_set_timeout(const struct list_set *map, u32 id)
|
||||||
static inline bool
|
static inline bool
|
||||||
list_set_expired(const struct list_set *map, u32 id)
|
list_set_expired(const struct list_set *map, u32 id)
|
||||||
{
|
{
|
||||||
const struct set_telem *elem =
|
const struct set_telem *elem = list_set_telem(map, id);
|
||||||
(const struct set_telem *) list_set_elem(map, id);
|
|
||||||
|
|
||||||
return ip_set_timeout_expired(elem->timeout);
|
return ip_set_timeout_expired(elem->timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
|
||||||
list_set_exist(const struct set_telem *elem)
|
|
||||||
{
|
|
||||||
return elem->id != IPSET_INVALID_ID &&
|
|
||||||
!ip_set_timeout_expired(elem->timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set list without and with timeout */
|
/* Set list without and with timeout */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -146,11 +143,11 @@ list_elem_tadd(struct list_set *map, u32 i, ip_set_id_t id,
|
||||||
struct set_telem *e;
|
struct set_telem *e;
|
||||||
|
|
||||||
for (; i < map->size; i++) {
|
for (; i < map->size; i++) {
|
||||||
e = (struct set_telem *)list_set_elem(map, i);
|
e = list_set_telem(map, i);
|
||||||
swap(e->id, id);
|
swap(e->id, id);
|
||||||
|
swap(e->timeout, timeout);
|
||||||
if (e->id == IPSET_INVALID_ID)
|
if (e->id == IPSET_INVALID_ID)
|
||||||
break;
|
break;
|
||||||
swap(e->timeout, timeout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +161,7 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id,
|
||||||
/* Last element replaced: e.g. add new,before,last */
|
/* Last element replaced: e.g. add new,before,last */
|
||||||
ip_set_put_byindex(e->id);
|
ip_set_put_byindex(e->id);
|
||||||
if (with_timeout(map->timeout))
|
if (with_timeout(map->timeout))
|
||||||
list_elem_tadd(map, i, id, timeout);
|
list_elem_tadd(map, i, id, ip_set_timeout_set(timeout));
|
||||||
else
|
else
|
||||||
list_elem_add(map, i, id);
|
list_elem_add(map, i, id);
|
||||||
|
|
||||||
|
@ -172,11 +169,11 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
list_set_del(struct list_set *map, ip_set_id_t id, u32 i)
|
list_set_del(struct list_set *map, u32 i)
|
||||||
{
|
{
|
||||||
struct set_elem *a = list_set_elem(map, i), *b;
|
struct set_elem *a = list_set_elem(map, i), *b;
|
||||||
|
|
||||||
ip_set_put_byindex(id);
|
ip_set_put_byindex(a->id);
|
||||||
|
|
||||||
for (; i < map->size - 1; i++) {
|
for (; i < map->size - 1; i++) {
|
||||||
b = list_set_elem(map, i + 1);
|
b = list_set_elem(map, i + 1);
|
||||||
|
@ -308,11 +305,11 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||||
(before == 0 ||
|
(before == 0 ||
|
||||||
(before > 0 &&
|
(before > 0 &&
|
||||||
next_id_eq(map, i, refid))))
|
next_id_eq(map, i, refid))))
|
||||||
ret = list_set_del(map, id, i);
|
ret = list_set_del(map, i);
|
||||||
else if (before < 0 &&
|
else if (before < 0 &&
|
||||||
elem->id == refid &&
|
elem->id == refid &&
|
||||||
next_id_eq(map, i, id))
|
next_id_eq(map, i, id))
|
||||||
ret = list_set_del(map, id, i + 1);
|
ret = list_set_del(map, i + 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -461,16 +458,14 @@ list_set_gc(unsigned long ul_set)
|
||||||
struct set_telem *e;
|
struct set_telem *e;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
/* We run parallel with other readers (test element)
|
/* nfnl_lock should be called */
|
||||||
* but adding/deleting new entries is locked out */
|
write_lock_bh(&set->lock);
|
||||||
read_lock_bh(&set->lock);
|
for (i = 0; i < map->size; i++) {
|
||||||
for (i = map->size - 1; i >= 0; i--) {
|
e = list_set_telem(map, i);
|
||||||
e = (struct set_telem *) list_set_elem(map, i);
|
if (e->id != IPSET_INVALID_ID && list_set_expired(map, i))
|
||||||
if (e->id != IPSET_INVALID_ID &&
|
list_set_del(map, i);
|
||||||
list_set_expired(map, i))
|
|
||||||
list_set_del(map, e->id, i);
|
|
||||||
}
|
}
|
||||||
read_unlock_bh(&set->lock);
|
write_unlock_bh(&set->lock);
|
||||||
|
|
||||||
map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
|
map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
|
||||||
add_timer(&map->gc);
|
add_timer(&map->gc);
|
||||||
|
|
Loading…
Reference in New Issue