diff options
author | Phil Sutter <phil@nwl.cc> | 2022-10-14 23:19:22 +0200 |
---|---|---|
committer | Phil Sutter <phil@nwl.cc> | 2023-01-18 14:58:48 +0100 |
commit | 1694df2de79f39c5037f82601e02226022b2e38f (patch) | |
tree | 57c6b99a1c7de8a414b5693e86cd6cf36816fd42 /src/cache.c | |
parent | ce04d25b4a116ef04f27d0b71994f61a24114d6d (diff) |
Implement 'reset rule' and 'reset rules' commands
Reset rule counters and quotas in kernel, i.e. without having to reload
them. Requires respective kernel patch to support NFT_MSG_GETRULE_RESET
message type.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'src/cache.c')
-rw-r--r-- | src/cache.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/src/cache.c b/src/cache.c index 85de970f..0f5d1099 100644 --- a/src/cache.c +++ b/src/cache.c @@ -263,6 +263,30 @@ static unsigned int evaluate_cache_list(struct nft_ctx *nft, struct cmd *cmd, return flags; } +static unsigned int evaluate_cache_reset(struct cmd *cmd, unsigned int flags, + struct nft_cache_filter *filter) +{ + switch (cmd->obj) { + case CMD_OBJ_RULES: + if (filter) { + if (cmd->handle.table.name) { + filter->list.family = cmd->handle.family; + filter->list.table = cmd->handle.table.name; + } + if (cmd->handle.chain.name) + filter->list.chain = cmd->handle.chain.name; + } + flags |= NFT_CACHE_SET | NFT_CACHE_FLOWTABLE | + NFT_CACHE_OBJECT | NFT_CACHE_CHAIN; + break; + default: + flags |= NFT_CACHE_TABLE; + break; + } + + return flags; +} + static int nft_handle_validate(const struct cmd *cmd, struct list_head *msgs) { const struct handle *h = &cmd->handle; @@ -277,6 +301,7 @@ static int nft_handle_validate(const struct cmd *cmd, struct list_head *msgs) } break; case CMD_OBJ_RULE: + case CMD_OBJ_RULES: case CMD_OBJ_CHAIN: case CMD_OBJ_CHAINS: if (h->table.name && @@ -403,7 +428,7 @@ int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds, flags = evaluate_cache_get(cmd, flags); break; case CMD_RESET: - flags |= NFT_CACHE_TABLE; + flags |= evaluate_cache_reset(cmd, flags, filter); break; case CMD_LIST: flags |= evaluate_cache_list(nft, cmd, flags, filter); @@ -591,8 +616,8 @@ static int list_rule_cb(struct nftnl_rule *nlr, void *data) table = nftnl_rule_get_str(nlr, NFTNL_RULE_TABLE); chain = nftnl_rule_get_str(nlr, NFTNL_RULE_CHAIN); - if (h->family != family || - strcmp(table, h->table.name) != 0 || + if ((h->family != NFPROTO_UNSPEC && h->family != family) || + (h->table.name && strcmp(table, h->table.name) != 0) || (h->chain.name && strcmp(chain, h->chain.name) != 0)) return 0; @@ -604,19 +629,23 @@ static int list_rule_cb(struct nftnl_rule *nlr, void *data) return 0; } -static int rule_cache_dump(struct netlink_ctx *ctx, const struct handle *h, - const struct nft_cache_filter *filter) +int rule_cache_dump(struct netlink_ctx *ctx, const struct handle *h, + const struct nft_cache_filter *filter, + bool dump, bool reset) { struct nftnl_rule_list *rule_cache; const char *table = NULL; const char *chain = NULL; + uint64_t rule_handle = 0; if (filter) { table = filter->list.table; chain = filter->list.chain; + rule_handle = filter->list.rule_handle; } - rule_cache = mnl_nft_rule_dump(ctx, h->family, table, chain); + rule_cache = mnl_nft_rule_dump(ctx, h->family, + table, chain, rule_handle, dump, reset); if (rule_cache == NULL) { if (errno == EINTR) return -1; @@ -948,7 +977,7 @@ static int rule_init_cache(struct netlink_ctx *ctx, struct table *table, struct chain *chain; int ret; - ret = rule_cache_dump(ctx, &table->handle, filter); + ret = rule_cache_dump(ctx, &table->handle, filter, true, false); list_for_each_entry_safe(rule, nrule, &ctx->list, list) { chain = chain_cache_find(table, rule->handle.chain.name); |