From 83e0f4402fb731633975b54ee043820d3cc7ed8e Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 15 Jun 2023 15:24:28 +0200 Subject: Implement 'reset {set,map,element}' commands All these are used to reset state in set/map elements, i.e. reset the timeout or zero quota and counter values. While 'reset element' expects a (list of) elements to be specified which should be reset, 'reset set/map' will reset all elements in the given set/map. Signed-off-by: Phil Sutter --- src/cache.c | 9 +++++++-- src/evaluate.c | 5 +++++ src/mnl.c | 22 ++++++++++++++++++---- src/netlink.c | 8 ++++---- src/parser_bison.y | 12 ++++++++++++ src/parser_json.c | 4 ++++ src/rule.c | 15 ++++++++++++--- 7 files changed, 62 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/cache.c b/src/cache.c index d908ae0a..5cab2622 100644 --- a/src/cache.c +++ b/src/cache.c @@ -282,6 +282,11 @@ static unsigned int evaluate_cache_reset(struct cmd *cmd, unsigned int flags, flags |= NFT_CACHE_SET | NFT_CACHE_FLOWTABLE | NFT_CACHE_OBJECT | NFT_CACHE_CHAIN; break; + case CMD_OBJ_ELEMENTS: + case CMD_OBJ_SET: + case CMD_OBJ_MAP: + flags |= NFT_CACHE_SET; + break; default: flags |= NFT_CACHE_TABLE; break; @@ -1069,7 +1074,7 @@ static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags, continue; ret = netlink_list_setelems(ctx, &set->handle, - set); + set, false); if (ret < 0) goto cache_fails; } @@ -1082,7 +1087,7 @@ static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags, continue; ret = netlink_list_setelems(ctx, &set->handle, - set); + set, false); if (ret < 0) goto cache_fails; } diff --git a/src/evaluate.c b/src/evaluate.c index 3dc2be0d..33e4ac93 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -5470,6 +5470,11 @@ static int cmd_evaluate_reset(struct eval_ctx *ctx, struct cmd *cmd) return table_not_found(ctx); return 0; + case CMD_OBJ_ELEMENTS: + return setelem_evaluate(ctx, cmd); + case CMD_OBJ_SET: + case CMD_OBJ_MAP: + return cmd_evaluate_list(ctx, cmd); default: BUG("invalid command object type %u\n", cmd->obj); } diff --git a/src/mnl.c b/src/mnl.c index 91775c41..9406fc48 100644 --- a/src/mnl.c +++ b/src/mnl.c @@ -1870,14 +1870,21 @@ int mnl_nft_setelem_del(struct netlink_ctx *ctx, struct cmd *cmd, } struct nftnl_set *mnl_nft_setelem_get_one(struct netlink_ctx *ctx, - struct nftnl_set *nls_in) + struct nftnl_set *nls_in, + bool reset) { char buf[MNL_SOCKET_BUFFER_SIZE]; struct nftnl_set *nls_out; struct nlmsghdr *nlh; + int msg_type; int err; - nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETSETELEM, + if (reset) + msg_type = NFT_MSG_GETSETELEM_RESET; + else + msg_type = NFT_MSG_GETSETELEM; + + nlh = nftnl_nlmsg_build_hdr(buf, msg_type, nftnl_set_get_u32(nls_in, NFTNL_SET_FAMILY), NLM_F_ACK, ctx->seqnum); nftnl_set_elems_nlmsg_build_payload(nlh, nls_in); @@ -1900,12 +1907,19 @@ struct nftnl_set *mnl_nft_setelem_get_one(struct netlink_ctx *ctx, return nls_out; } -int mnl_nft_setelem_get(struct netlink_ctx *ctx, struct nftnl_set *nls) +int mnl_nft_setelem_get(struct netlink_ctx *ctx, struct nftnl_set *nls, + bool reset) { char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; + int msg_type; + + if (reset) + msg_type = NFT_MSG_GETSETELEM_RESET; + else + msg_type = NFT_MSG_GETSETELEM; - nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETSETELEM, + nlh = nftnl_nlmsg_build_hdr(buf, msg_type, nftnl_set_get_u32(nls, NFTNL_SET_FAMILY), NLM_F_DUMP, ctx->seqnum); nftnl_set_elems_nlmsg_build_payload(nlh, nls); diff --git a/src/netlink.c b/src/netlink.c index 3352ad0a..ed61cd89 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1515,7 +1515,7 @@ static int list_setelements(struct nftnl_set *s, struct netlink_ctx *ctx) } int netlink_list_setelems(struct netlink_ctx *ctx, const struct handle *h, - struct set *set) + struct set *set, bool reset) { struct nftnl_set *nls; int err; @@ -1530,7 +1530,7 @@ int netlink_list_setelems(struct netlink_ctx *ctx, const struct handle *h, if (h->handle.id) nftnl_set_set_u64(nls, NFTNL_SET_HANDLE, h->handle.id); - err = mnl_nft_setelem_get(ctx, nls); + err = mnl_nft_setelem_get(ctx, nls, reset); if (err < 0) { nftnl_set_free(nls); if (errno == EINTR) @@ -1558,7 +1558,7 @@ int netlink_list_setelems(struct netlink_ctx *ctx, const struct handle *h, int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, const struct location *loc, struct set *cache_set, - struct set *set, struct expr *init) + struct set *set, struct expr *init, bool reset) { struct nftnl_set *nls, *nls_out = NULL; int err = 0; @@ -1577,7 +1577,7 @@ int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, netlink_dump_set(nls, ctx); - nls_out = mnl_nft_setelem_get_one(ctx, nls); + nls_out = mnl_nft_setelem_get_one(ctx, nls, reset); if (!nls_out) { nftnl_set_free(nls); return -1; diff --git a/src/parser_bison.y b/src/parser_bison.y index beb277b6..553ddf97 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -1742,6 +1742,18 @@ reset_cmd : COUNTERS ruleset_spec { $$ = cmd_alloc(CMD_RESET, CMD_OBJ_RULE, &$2, &@$, NULL); } + | ELEMENT set_spec set_block_expr + { + $$ = cmd_alloc(CMD_RESET, CMD_OBJ_ELEMENTS, &$2, &@$, $3); + } + | SET set_or_id_spec + { + $$ = cmd_alloc(CMD_RESET, CMD_OBJ_SET, &$2, &@$, NULL); + } + | MAP set_or_id_spec + { + $$ = cmd_alloc(CMD_RESET, CMD_OBJ_MAP, &$2, &@$, NULL); + } ; flush_cmd : TABLE table_spec diff --git a/src/parser_json.c b/src/parser_json.c index 55c6b8c7..92cffee9 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -3169,6 +3169,7 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root, case CMD_DESTROY: case CMD_LIST: case CMD_FLUSH: + case CMD_RESET: return cmd_alloc(op, obj, &h, int_loc, NULL); default: break; @@ -3918,6 +3919,9 @@ static struct cmd *json_parse_cmd_reset(struct json_ctx *ctx, { "quotas", CMD_OBJ_QUOTAS, json_parse_cmd_list_multiple }, { "rule", CMD_OBJ_RULE, json_parse_cmd_reset_rule }, { "rules", CMD_OBJ_RULES, json_parse_cmd_reset_rule }, + { "element", CMD_OBJ_ELEMENTS, json_parse_cmd_add_element }, + { "set", CMD_OBJ_SET, json_parse_cmd_add_set }, + { "map", CMD_OBJ_MAP, json_parse_cmd_add_set }, }; unsigned int i; json_t *tmp; diff --git a/src/rule.c b/src/rule.c index 18a566f9..533161d3 100644 --- a/src/rule.c +++ b/src/rule.c @@ -2381,7 +2381,7 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd) return 0; } -static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd) +static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd, bool reset) { struct set *set, *new_set; struct expr *init; @@ -2399,7 +2399,7 @@ static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd) /* Fetch from kernel the elements that have been requested .*/ err = netlink_get_setelem(ctx, &cmd->handle, &cmd->location, - cmd->elem.set, new_set, init); + cmd->elem.set, new_set, init, reset); if (err >= 0) __do_list_set(ctx, cmd, new_set); @@ -2415,7 +2415,7 @@ static int do_command_get(struct netlink_ctx *ctx, struct cmd *cmd) { switch (cmd->obj) { case CMD_OBJ_ELEMENTS: - return do_get_setelems(ctx, cmd); + return do_get_setelems(ctx, cmd, false); default: BUG("invalid command object type %u\n", cmd->obj); } @@ -2452,6 +2452,15 @@ static int do_command_reset(struct netlink_ctx *ctx, struct cmd *cmd) return do_command_list(ctx, cmd); case CMD_OBJ_RULE: return netlink_reset_rules(ctx, cmd, false); + case CMD_OBJ_ELEMENTS: + return do_get_setelems(ctx, cmd, true); + case CMD_OBJ_SET: + case CMD_OBJ_MAP: + ret = netlink_list_setelems(ctx, &cmd->handle, cmd->set, true); + if (ret < 0) + return ret; + + return do_command_list(ctx, cmd); default: BUG("invalid command object type %u\n", cmd->obj); } -- cgit v1.2.3