diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-11-27 23:42:54 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2017-01-03 14:21:53 +0100 |
commit | 8ec2e8438a7c4c48c8005a5f352c8ea6cd40d2fe (patch) | |
tree | 19ba8713e768dcc95d6ca5b65a097f6184e8e069 /src/rule.c | |
parent | 4d38878b39be44ea3d6a146a7dd678c269a9804a (diff) |
src: reset internal stateful objects
This patch allows you to atomically dump and reset stateful objects, eg.
# nft list counters
table ip filter {
counter test {
packets 1024 bytes 100000
}
}
# nft reset quotas table filter
counter test {
packets 1024 bytes 100000
}
# nft reset quotas table filter
counter test {
packets 0 bytes 0
}
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/rule.c')
-rw-r--r-- | src/rule.c | 43 |
1 files changed, 38 insertions, 5 deletions
@@ -95,11 +95,13 @@ static int cache_init_objects(struct netlink_ctx *ctx, enum cmd_ops cmd) return -1; list_splice_tail_init(&ctx->list, &table->chains); - /* Don't check for errors on listings, this would break nft with - * old kernels with no stateful object support. - */ - netlink_list_objs(ctx, &table->handle, &internal_location); - list_splice_tail_init(&ctx->list, &table->objs); + if (cmd != CMD_RESET) { + /* Don't check for errors on listings, this would break + * nft with old kernels with no stateful object support. + */ + netlink_list_objs(ctx, &table->handle, &internal_location); + list_splice_tail_init(&ctx->list, &table->objs); + } /* Skip caching other objects to speed up things: We only need * a full cache when listing the existing ruleset. @@ -1398,6 +1400,35 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd) return 0; } +static int do_command_reset(struct netlink_ctx *ctx, struct cmd *cmd) +{ + struct obj *obj, *next; + struct table *table; + uint32_t type; + int ret; + + switch (cmd->obj) { + case CMD_OBJ_COUNTERS: + type = NFT_OBJECT_COUNTER; + break; + case CMD_OBJ_QUOTAS: + type = NFT_OBJECT_QUOTA; + break; + default: + BUG("invalid command object type %u\n", cmd->obj); + } + + ret = netlink_reset_objs(ctx, &cmd->handle, &cmd->location, type); + list_for_each_entry_safe(obj, next, &ctx->list, list) { + table = table_lookup(&obj->handle); + list_move(&obj->list, &table->objs); + } + if (ret < 0) + return ret; + + return do_list_obj(ctx, cmd, type); +} + static int do_command_flush(struct netlink_ctx *ctx, struct cmd *cmd) { switch (cmd->obj) { @@ -1518,6 +1549,8 @@ int do_command(struct netlink_ctx *ctx, struct cmd *cmd) return do_command_delete(ctx, cmd); case CMD_LIST: return do_command_list(ctx, cmd); + case CMD_RESET: + return do_command_reset(ctx, cmd); case CMD_FLUSH: return do_command_flush(ctx, cmd); case CMD_RENAME: |