summaryrefslogtreecommitdiffstats
path: root/src/rule.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2021-03-11 13:34:10 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2021-03-11 14:31:42 +0100
commit4cb7f91edf1409e64f0fafcef190bb7c37a50854 (patch)
treeee16977d9b82f5e07840e285775c8cbc493a2722 /src/rule.c
parent281beafa5afad6e4bc0ac18d218f5d76f4973d92 (diff)
src: move remaining cache functions in rule.c to cache.c
Move all the cache logic to src/cache.c Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/rule.c')
-rw-r--r--src/rule.c201
1 files changed, 0 insertions, 201 deletions
diff --git a/src/rule.c b/src/rule.c
index cf4d2cbe..1c6010c0 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -138,207 +138,6 @@ void handle_merge(struct handle *dst, const struct handle *src)
dst->index = src->index;
}
-static int cache_init_tables(struct netlink_ctx *ctx, struct handle *h,
- struct nft_cache *cache)
-{
- int ret;
-
- ret = netlink_list_tables(ctx, h);
- if (ret < 0)
- return -1;
-
- list_splice_tail_init(&ctx->list, &cache->list);
- return 0;
-}
-
-static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags)
-{
- struct nftnl_chain_list *chain_list = NULL;
- struct rule *rule, *nrule;
- struct table *table;
- struct chain *chain;
- struct set *set;
- int ret = 0;
-
- if (flags & NFT_CACHE_CHAIN_BIT) {
- chain_list = chain_cache_dump(ctx, &ret);
- if (!chain_list)
- return ret;
- }
-
- list_for_each_entry(table, &ctx->nft->cache.list, list) {
- if (flags & NFT_CACHE_SET_BIT) {
- ret = netlink_list_sets(ctx, &table->handle);
- list_splice_tail_init(&ctx->list, &table->sets);
- if (ret < 0) {
- ret = -1;
- goto cache_fails;
- }
- }
- if (flags & NFT_CACHE_SETELEM_BIT) {
- list_for_each_entry(set, &table->sets, list) {
- ret = netlink_list_setelems(ctx, &set->handle,
- set);
- if (ret < 0) {
- ret = -1;
- goto cache_fails;
- }
- }
- }
- if (flags & NFT_CACHE_CHAIN_BIT) {
- ret = chain_cache_init(ctx, table, chain_list);
- if (ret < 0) {
- ret = -1;
- goto cache_fails;
- }
- }
- if (flags & NFT_CACHE_FLOWTABLE_BIT) {
- ret = netlink_list_flowtables(ctx, &table->handle);
- if (ret < 0) {
- ret = -1;
- goto cache_fails;
- }
- list_splice_tail_init(&ctx->list, &table->flowtables);
- }
- if (flags & NFT_CACHE_OBJECT_BIT) {
- ret = netlink_list_objs(ctx, &table->handle);
- if (ret < 0) {
- ret = -1;
- goto cache_fails;
- }
- list_splice_tail_init(&ctx->list, &table->objs);
- }
-
- if (flags & NFT_CACHE_RULE_BIT) {
- ret = netlink_list_rules(ctx, &table->handle);
- list_for_each_entry_safe(rule, nrule, &ctx->list, list) {
- chain = chain_cache_find(table, &rule->handle);
- if (!chain)
- chain = chain_binding_lookup(table,
- rule->handle.chain.name);
- list_move_tail(&rule->list, &chain->rules);
- }
- if (ret < 0) {
- ret = -1;
- goto cache_fails;
- }
- }
- }
-
-cache_fails:
- if (flags & NFT_CACHE_CHAIN_BIT)
- nftnl_chain_list_free(chain_list);
-
- return ret;
-}
-
-static int cache_init(struct netlink_ctx *ctx, unsigned int flags)
-{
- struct handle handle = {
- .family = NFPROTO_UNSPEC,
- };
- int ret;
-
- if (flags == NFT_CACHE_EMPTY)
- return 0;
-
- /* assume NFT_CACHE_TABLE is always set. */
- ret = cache_init_tables(ctx, &handle, &ctx->nft->cache);
- if (ret < 0)
- return ret;
- ret = cache_init_objects(ctx, flags);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static bool cache_is_complete(struct nft_cache *cache, unsigned int flags)
-{
- return (cache->flags & flags) == flags;
-}
-
-static bool cache_needs_refresh(struct nft_cache *cache)
-{
- return cache->flags & NFT_CACHE_REFRESH;
-}
-
-static bool cache_is_updated(struct nft_cache *cache, uint16_t genid)
-{
- return genid && genid == cache->genid;
-}
-
-bool cache_needs_update(struct nft_cache *cache)
-{
- return cache->flags & NFT_CACHE_UPDATE;
-}
-
-int cache_update(struct nft_ctx *nft, unsigned int flags, struct list_head *msgs)
-{
- struct netlink_ctx ctx = {
- .list = LIST_HEAD_INIT(ctx.list),
- .nft = nft,
- .msgs = msgs,
- };
- struct nft_cache *cache = &nft->cache;
- uint32_t genid, genid_stop, oldflags;
- int ret;
-replay:
- ctx.seqnum = cache->seqnum++;
- genid = mnl_genid_get(&ctx);
- if (!cache_needs_refresh(cache) &&
- cache_is_complete(cache, flags) &&
- cache_is_updated(cache, genid))
- return 0;
-
- if (cache->genid)
- cache_release(cache);
-
- if (flags & NFT_CACHE_FLUSHED) {
- oldflags = flags;
- flags = NFT_CACHE_EMPTY;
- if (oldflags & NFT_CACHE_UPDATE)
- flags |= NFT_CACHE_UPDATE;
- goto skip;
- }
-
- ret = cache_init(&ctx, flags);
- if (ret < 0) {
- cache_release(cache);
- if (errno == EINTR)
- goto replay;
-
- return -1;
- }
-
- genid_stop = mnl_genid_get(&ctx);
- if (genid != genid_stop) {
- cache_release(cache);
- goto replay;
- }
-skip:
- cache->genid = genid;
- cache->flags = flags;
- return 0;
-}
-
-static void __cache_flush(struct list_head *table_list)
-{
- struct table *table, *next;
-
- list_for_each_entry_safe(table, next, table_list, list) {
- list_del(&table->list);
- table_free(table);
- }
-}
-
-void cache_release(struct nft_cache *cache)
-{
- __cache_flush(&cache->list);
- cache->genid = 0;
- cache->flags = NFT_CACHE_EMPTY;
-}
-
/* internal ID to uniquely identify a set in the batch */
static uint32_t set_id;