summaryrefslogtreecommitdiffstats
path: root/kernel/net/netfilter/ipset/ip_set_list_set.c
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2013-09-07 00:10:07 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2013-09-07 00:10:07 +0200
commit71b092cb42cff157a8459dc62ae3a12e04e7d863 (patch)
treecfc36856a5cd047e042ae050f84d44eedc578fb3 /kernel/net/netfilter/ipset/ip_set_list_set.c
parenta36264dba1edfd6584022660346a6d7fe2519a2b (diff)
Move extension data to set structure
Default timeout and extension offsets are moved to struct set, because all set types supports all extensions and it makes possible to generalize extension support.
Diffstat (limited to 'kernel/net/netfilter/ipset/ip_set_list_set.c')
-rw-r--r--kernel/net/netfilter/ipset/ip_set_list_set.c116
1 files changed, 52 insertions, 64 deletions
diff --git a/kernel/net/netfilter/ipset/ip_set_list_set.c b/kernel/net/netfilter/ipset/ip_set_list_set.c
index 0ed19b5..f22d05d 100644
--- a/kernel/net/netfilter/ipset/ip_set_list_set.c
+++ b/kernel/net/netfilter/ipset/ip_set_list_set.c
@@ -58,24 +58,13 @@ struct set_adt_elem {
/* Type structure */
struct list_set {
- size_t dsize; /* element size */
- size_t offset[IPSET_EXT_ID_MAX]; /* Offsets to extensions */
u32 size; /* size of set list array */
- u32 timeout; /* timeout value */
struct timer_list gc; /* garbage collection */
struct set_elem members[0]; /* the set members */
};
-static inline struct set_elem *
-list_set_elem(const struct list_set *map, u32 id)
-{
- return (struct set_elem *)((void *)map->members + id * map->dsize);
-}
-
-#define ext_timeout(e, m) \
-(unsigned long *)((void *)(e) + (m)->offset[IPSET_EXT_ID_TIMEOUT])
-#define ext_counter(e, m) \
-(struct ip_set_counter *)((void *)(e) + (m)->offset[IPSET_EXT_ID_COUNTER])
+#define list_set_elem(set, map, id) \
+ (struct set_elem *)((void *)(map)->members + (id) * (set)->dsize)
static int
list_set_ktest(struct ip_set *set, const struct sk_buff *skb,
@@ -92,16 +81,16 @@ list_set_ktest(struct ip_set *set, const struct sk_buff *skb,
if (opt->cmdflags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE)
opt->cmdflags &= ~IPSET_FLAG_SKIP_COUNTER_UPDATE;
for (i = 0; i < map->size; i++) {
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
if (e->id == IPSET_INVALID_ID)
return 0;
if (SET_WITH_TIMEOUT(set) &&
- ip_set_timeout_expired(ext_timeout(e, map)))
+ ip_set_timeout_expired(ext_timeout(e, set)))
continue;
ret = ip_set_test(e->id, skb, par, opt);
if (ret > 0) {
if (SET_WITH_COUNTER(set))
- ip_set_update_counter(ext_counter(e, map),
+ ip_set_update_counter(ext_counter(e, set),
ext, &opt->ext,
cmdflags);
return ret;
@@ -121,11 +110,11 @@ list_set_kadd(struct ip_set *set, const struct sk_buff *skb,
int ret;
for (i = 0; i < map->size; i++) {
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
if (e->id == IPSET_INVALID_ID)
return 0;
if (SET_WITH_TIMEOUT(set) &&
- ip_set_timeout_expired(ext_timeout(e, map)))
+ ip_set_timeout_expired(ext_timeout(e, set)))
continue;
ret = ip_set_add(e->id, skb, par, opt);
if (ret == 0)
@@ -145,11 +134,11 @@ list_set_kdel(struct ip_set *set, const struct sk_buff *skb,
int ret;
for (i = 0; i < map->size; i++) {
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
if (e->id == IPSET_INVALID_ID)
return 0;
if (SET_WITH_TIMEOUT(set) &&
- ip_set_timeout_expired(ext_timeout(e, map)))
+ ip_set_timeout_expired(ext_timeout(e, set)))
continue;
ret = ip_set_del(e->id, skb, par, opt);
if (ret == 0)
@@ -163,8 +152,7 @@ list_set_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct xt_action_param *par,
enum ipset_adt adt, struct ip_set_adt_opt *opt)
{
- struct list_set *map = set->data;
- struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map);
+ struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
switch (adt) {
case IPSET_TEST:
@@ -188,10 +176,10 @@ id_eq(const struct ip_set *set, u32 i, ip_set_id_t id)
if (i >= map->size)
return 0;
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
return !!(e->id == id &&
!(SET_WITH_TIMEOUT(set) &&
- ip_set_timeout_expired(ext_timeout(e, map))));
+ ip_set_timeout_expired(ext_timeout(e, set))));
}
static int
@@ -199,28 +187,29 @@ list_set_add(struct ip_set *set, u32 i, struct set_adt_elem *d,
const struct ip_set_ext *ext)
{
struct list_set *map = set->data;
- struct set_elem *e = list_set_elem(map, i);
+ struct set_elem *e = list_set_elem(set, map, i);
if (e->id != IPSET_INVALID_ID) {
if (i == map->size - 1)
/* Last element replaced: e.g. add new,before,last */
ip_set_put_byindex(e->id);
else {
- struct set_elem *x = list_set_elem(map, map->size - 1);
+ struct set_elem *x = list_set_elem(set, map,
+ map->size - 1);
/* Last element pushed off */
if (x->id != IPSET_INVALID_ID)
ip_set_put_byindex(x->id);
- memmove(list_set_elem(map, i + 1), e,
- map->dsize * (map->size - (i + 1)));
+ memmove(list_set_elem(set, map, i + 1), e,
+ set->dsize * (map->size - (i + 1)));
}
}
e->id = d->id;
if (SET_WITH_TIMEOUT(set))
- ip_set_timeout_set(ext_timeout(e, map), ext->timeout);
+ ip_set_timeout_set(ext_timeout(e, set), ext->timeout);
if (SET_WITH_COUNTER(set))
- ip_set_init_counter(ext_counter(e, map), ext);
+ ip_set_init_counter(ext_counter(e, set), ext);
return 0;
}
@@ -228,16 +217,16 @@ static int
list_set_del(struct ip_set *set, u32 i)
{
struct list_set *map = set->data;
- struct set_elem *e = list_set_elem(map, i);
+ struct set_elem *e = list_set_elem(set, map, i);
ip_set_put_byindex(e->id);
if (i < map->size - 1)
- memmove(e, list_set_elem(map, i + 1),
- map->dsize * (map->size - (i + 1)));
+ memmove(e, list_set_elem(set, map, i + 1),
+ set->dsize * (map->size - (i + 1)));
/* Last element */
- e = list_set_elem(map, map->size - 1);
+ e = list_set_elem(set, map, map->size - 1);
e->id = IPSET_INVALID_ID;
return 0;
}
@@ -250,9 +239,9 @@ set_cleanup_entries(struct ip_set *set)
u32 i;
for (i = 0; i < map->size; i++) {
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
if (e->id != IPSET_INVALID_ID &&
- ip_set_timeout_expired(ext_timeout(e, map)))
+ ip_set_timeout_expired(ext_timeout(e, set)))
list_set_del(set, i);
}
}
@@ -268,11 +257,11 @@ list_set_utest(struct ip_set *set, void *value, const struct ip_set_ext *ext,
int ret;
for (i = 0; i < map->size; i++) {
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
if (e->id == IPSET_INVALID_ID)
return 0;
else if (SET_WITH_TIMEOUT(set) &&
- ip_set_timeout_expired(ext_timeout(e, map)))
+ ip_set_timeout_expired(ext_timeout(e, set)))
continue;
else if (e->id != d->id)
continue;
@@ -301,11 +290,11 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
/* Check already added element */
for (i = 0; i < map->size; i++) {
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
if (e->id == IPSET_INVALID_ID)
goto insert;
else if (SET_WITH_TIMEOUT(set) &&
- ip_set_timeout_expired(ext_timeout(e, map)))
+ ip_set_timeout_expired(ext_timeout(e, set)))
continue;
else if (e->id != d->id)
continue;
@@ -320,9 +309,9 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
return -IPSET_ERR_EXIST;
/* Update extensions */
if (SET_WITH_TIMEOUT(set))
- ip_set_timeout_set(ext_timeout(e, map), ext->timeout);
+ ip_set_timeout_set(ext_timeout(e, set), ext->timeout);
if (SET_WITH_COUNTER(set))
- ip_set_init_counter(ext_counter(e, map), ext);
+ ip_set_init_counter(ext_counter(e, set), ext);
/* Set is already added to the list */
ip_set_put_byindex(d->id);
return 0;
@@ -330,7 +319,7 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
insert:
ret = -IPSET_ERR_LIST_FULL;
for (i = 0; i < map->size && ret == -IPSET_ERR_LIST_FULL; i++) {
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
if (e->id == IPSET_INVALID_ID)
ret = d->before != 0 ? -IPSET_ERR_REF_EXIST
: list_set_add(set, i, d, ext);
@@ -355,12 +344,12 @@ list_set_udel(struct ip_set *set, void *value, const struct ip_set_ext *ext,
u32 i;
for (i = 0; i < map->size; i++) {
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
if (e->id == IPSET_INVALID_ID)
return d->before != 0 ? -IPSET_ERR_REF_EXIST
: -IPSET_ERR_EXIST;
else if (SET_WITH_TIMEOUT(set) &&
- ip_set_timeout_expired(ext_timeout(e, map)))
+ ip_set_timeout_expired(ext_timeout(e, set)))
continue;
else if (e->id != d->id)
continue;
@@ -383,10 +372,9 @@ static int
list_set_uadt(struct ip_set *set, struct nlattr *tb[],
enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
{
- struct list_set *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct set_adt_elem e = { .refid = IPSET_INVALID_ID };
- struct ip_set_ext ext = IP_SET_INIT_UEXT(map);
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
struct ip_set *s;
int ret = 0;
@@ -454,7 +442,7 @@ list_set_flush(struct ip_set *set)
u32 i;
for (i = 0; i < map->size; i++) {
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
if (e->id != IPSET_INVALID_ID) {
ip_set_put_byindex(e->id);
e->id = IPSET_INVALID_ID;
@@ -486,13 +474,13 @@ list_set_head(struct ip_set *set, struct sk_buff *skb)
goto nla_put_failure;
if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) ||
(SET_WITH_TIMEOUT(set) &&
- nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(set->timeout))) ||
(SET_WITH_COUNTER(set) &&
nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS,
htonl(IPSET_FLAG_WITH_COUNTERS))) ||
nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
- htonl(sizeof(*map) + map->size * map->dsize)))
+ htonl(sizeof(*map) + map->size * set->dsize)))
goto nla_put_failure;
ipset_nest_end(skb, nested);
@@ -515,11 +503,11 @@ list_set_list(const struct ip_set *set,
return -EMSGSIZE;
for (; cb->args[2] < map->size; cb->args[2]++) {
i = cb->args[2];
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
if (e->id == IPSET_INVALID_ID)
goto finish;
if (SET_WITH_TIMEOUT(set) &&
- ip_set_timeout_expired(ext_timeout(e, map)))
+ ip_set_timeout_expired(ext_timeout(e, set)))
continue;
nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
if (!nested) {
@@ -535,10 +523,10 @@ list_set_list(const struct ip_set *set,
if (SET_WITH_TIMEOUT(set) &&
nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
htonl(ip_set_timeout_get(
- ext_timeout(e, map)))))
+ ext_timeout(e, set)))))
goto nla_put_failure;
if (SET_WITH_COUNTER(set) &&
- ip_set_put_counter(skb, ext_counter(e, map)))
+ ip_set_put_counter(skb, ext_counter(e, set)))
goto nla_put_failure;
ipset_nest_end(skb, nested);
}
@@ -565,7 +553,7 @@ list_set_same_set(const struct ip_set *a, const struct ip_set *b)
const struct list_set *y = b->data;
return x->size == y->size &&
- x->timeout == y->timeout &&
+ a->timeout == b->timeout &&
a->extensions == b->extensions;
}
@@ -594,7 +582,7 @@ list_set_gc(unsigned long ul_set)
set_cleanup_entries(set);
write_unlock_bh(&set->lock);
- map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
+ map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
add_timer(&map->gc);
}
@@ -606,7 +594,7 @@ list_set_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
init_timer(&map->gc);
map->gc.data = (unsigned long) set;
map->gc.function = gc;
- map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
+ map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
add_timer(&map->gc);
}
@@ -625,12 +613,12 @@ init_list_set(struct ip_set *set, u32 size, size_t dsize,
return NULL;
map->size = size;
- map->dsize = dsize;
- map->timeout = timeout;
+ set->dsize = dsize;
+ set->timeout = timeout;
set->data = map;
for (i = 0; i < size; i++) {
- e = list_set_elem(map, i);
+ e = list_set_elem(set, map, i);
e->id = IPSET_INVALID_ID;
}
@@ -667,9 +655,9 @@ list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
if (!map)
return -ENOMEM;
set->extensions |= IPSET_EXT_TIMEOUT;
- map->offset[IPSET_EXT_ID_TIMEOUT] =
+ set->offset[IPSET_EXT_ID_TIMEOUT] =
offsetof(struct setct_elem, timeout);
- map->offset[IPSET_EXT_ID_COUNTER] =
+ set->offset[IPSET_EXT_ID_COUNTER] =
offsetof(struct setct_elem, counter);
list_set_gc_init(set, list_set_gc);
} else {
@@ -677,7 +665,7 @@ list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
sizeof(struct setc_elem), 0);
if (!map)
return -ENOMEM;
- map->offset[IPSET_EXT_ID_COUNTER] =
+ set->offset[IPSET_EXT_ID_COUNTER] =
offsetof(struct setc_elem, counter);
}
} else if (tb[IPSET_ATTR_TIMEOUT]) {
@@ -686,7 +674,7 @@ list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
if (!map)
return -ENOMEM;
set->extensions |= IPSET_EXT_TIMEOUT;
- map->offset[IPSET_EXT_ID_TIMEOUT] =
+ set->offset[IPSET_EXT_ID_TIMEOUT] =
offsetof(struct sett_elem, timeout);
list_set_gc_init(set, list_set_gc);
} else {