Commit 9a776628 authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

netfilter: Use rhashtable walk iterator

This patch gets rid of the manual rhashtable walk in nft_hash
which touches rhashtable internals that should not be exposed.
It does so by using the rhashtable iterator primitives.

Note that I'm leaving nft_hash_destroy alone since it's only
invoked on shutdown and it shouldn't be affected by changes
to rhashtable internals (or at least not what I'm planning to
change).
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 56d28b1e
...@@ -130,31 +130,50 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set, ...@@ -130,31 +130,50 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set,
struct nft_set_iter *iter) struct nft_set_iter *iter)
{ {
struct rhashtable *priv = nft_set_priv(set); struct rhashtable *priv = nft_set_priv(set);
const struct bucket_table *tbl;
const struct nft_hash_elem *he; const struct nft_hash_elem *he;
struct rhashtable_iter hti;
struct nft_set_elem elem; struct nft_set_elem elem;
unsigned int i; int err;
tbl = rht_dereference_rcu(priv->tbl, priv); err = rhashtable_walk_init(priv, &hti);
for (i = 0; i < tbl->size; i++) { iter->err = err;
struct rhash_head *pos; if (err)
return;
err = rhashtable_walk_start(&hti);
if (err && err != -EAGAIN) {
iter->err = err;
goto out;
}
rht_for_each_entry_rcu(he, pos, tbl, i, node) { while ((he = rhashtable_walk_next(&hti))) {
if (iter->count < iter->skip) if (IS_ERR(he)) {
goto cont; err = PTR_ERR(he);
if (err != -EAGAIN) {
iter->err = err;
goto out;
}
}
if (iter->count < iter->skip)
goto cont;
memcpy(&elem.key, &he->key, sizeof(elem.key));
if (set->flags & NFT_SET_MAP)
memcpy(&elem.data, he->data, sizeof(elem.data));
elem.flags = 0;
memcpy(&elem.key, &he->key, sizeof(elem.key)); iter->err = iter->fn(ctx, set, iter, &elem);
if (set->flags & NFT_SET_MAP) if (iter->err < 0)
memcpy(&elem.data, he->data, sizeof(elem.data)); goto out;
elem.flags = 0;
iter->err = iter->fn(ctx, set, iter, &elem);
if (iter->err < 0)
return;
cont: cont:
iter->count++; iter->count++;
}
} }
out:
rhashtable_walk_stop(&hti);
rhashtable_walk_exit(&hti);
} }
static unsigned int nft_hash_privsize(const struct nlattr * const nla[]) static unsigned int nft_hash_privsize(const struct nlattr * const nla[])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment