]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: Allow reset single stateful object
authorElise Lennion <elise.lennion@gmail.com>
Thu, 26 Jan 2017 17:09:44 +0000 (15:09 -0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 27 Jan 2017 12:33:20 +0000 (13:33 +0100)
Currently the stateful objects can only be reseted in groups. With this
patch reseting a single object is allowed:

$ nft reset counter filter https-traffic
table ip filter {
counter https-traffic {
packets 8774 bytes 542668
}
}

$ nft list counter filter https-traffic
table ip filter {
counter https-traffic {
packets 0 bytes 0
}
}

Heavily based on work from Pablo Neira Ayuso <pablo@netfilter.org>.

Signed-off-by: Elise Lennion <elise.lennion@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/mnl.h
include/netlink.h
src/evaluate.c
src/mnl.c
src/netlink.c
src/parser_bison.y
src/rule.c

index 4a99972d416384eee39f8dffb513f7c637809f10..69dd0b744830f154867be353a7300d5db5660d95 100644 (file)
@@ -87,8 +87,8 @@ int mnl_nft_setelem_batch_flush(struct nftnl_set *nls, unsigned int flags,
 int mnl_nft_setelem_get(struct mnl_socket *nf_sock, struct nftnl_set *nls);
 
 struct nftnl_obj_list *mnl_nft_obj_dump(struct mnl_socket *nf_sock, int family,
-                                       const char *table, uint32_t type,
-                                       bool reset);
+                                       const char *table, const char *name,
+                                       uint32_t type, bool dump, bool reset);
 int mnl_nft_obj_batch_add(struct nftnl_obj *nln, unsigned int flags,
                          uint32_t seqnum);
 int mnl_nft_obj_batch_del(struct nftnl_obj *nln, unsigned int flags,
index 450aba571a979ca7aff1320e100b9de42d373b79..d3fb8c5da33ca3d887398656a5d7abe60b84f989 100644 (file)
@@ -172,7 +172,8 @@ extern int netlink_flush_setelems(struct netlink_ctx *ctx, const struct handle *
 extern int netlink_list_objs(struct netlink_ctx *ctx, const struct handle *h,
                             const struct location *loc);
 extern int netlink_reset_objs(struct netlink_ctx *ctx, const struct handle *h,
-                             const struct location *loc, uint32_t type);
+                             const struct location *loc, uint32_t type,
+                             bool dump);
 extern int netlink_add_obj(struct netlink_ctx *ctx, const struct handle *h,
                           struct obj *obj, bool excl);
 extern int netlink_delete_obj(struct netlink_ctx *ctx, const struct handle *h,
index bcbced1e3dfa6d30b028eab840575248feb6d304..1d2f9258e90c5e6507e26736cb949a2b341291da 100644 (file)
@@ -2949,6 +2949,29 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
        }
 }
 
+static int cmd_evaluate_reset(struct eval_ctx *ctx, struct cmd *cmd)
+{
+       int ret;
+
+       ret = cache_update(cmd->op, ctx->msgs);
+       if (ret < 0)
+               return ret;
+
+       switch (cmd->obj) {
+       case CMD_OBJ_COUNTER:
+       case CMD_OBJ_QUOTA:
+               if (table_lookup(&cmd->handle) == NULL)
+                       return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
+                                        cmd->handle.table);
+               return 0;
+       case CMD_OBJ_COUNTERS:
+       case CMD_OBJ_QUOTAS:
+               return 0;
+       default:
+               BUG("invalid command object type %u\n", cmd->obj);
+       }
+}
+
 static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
 {
        int ret;
@@ -3140,8 +3163,9 @@ int cmd_evaluate(struct eval_ctx *ctx, struct cmd *cmd)
        case CMD_DELETE:
                return cmd_evaluate_delete(ctx, cmd);
        case CMD_LIST:
-       case CMD_RESET:
                return cmd_evaluate_list(ctx, cmd);
+       case CMD_RESET:
+               return cmd_evaluate_reset(ctx, cmd);
        case CMD_FLUSH:
                return cmd_evaluate_flush(ctx, cmd);
        case CMD_RENAME:
index 1c4b070324f14d60ba9ab9564cd8682280e09292..295dd84a58406edb919a5d2d8085a2d3fca2d536 100644 (file)
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -849,8 +849,9 @@ err_free:
 
 struct nftnl_obj_list *
 mnl_nft_obj_dump(struct mnl_socket *nf_sock, int family, const char *table,
-                uint32_t type, bool reset)
+                const char *name,  uint32_t type, bool dump, bool reset)
 {
+       uint16_t nl_flags = dump ? NLM_F_DUMP : 0;
        struct nftnl_obj_list *nln_list;
        char buf[MNL_SOCKET_BUFFER_SIZE];
        struct nftnl_obj *n;
@@ -867,9 +868,11 @@ mnl_nft_obj_dump(struct mnl_socket *nf_sock, int family, const char *table,
                memory_allocation_error();
 
        nlh = nftnl_nlmsg_build_hdr(buf, msg_type, family,
-                                   NLM_F_DUMP | NLM_F_ACK, seq);
+                                   nl_flags | NLM_F_ACK, seq);
        if (table != NULL)
-               nftnl_obj_set(n, NFTNL_OBJ_TABLE, table);
+               nftnl_obj_set_str(n, NFTNL_OBJ_TABLE, table);
+       if (name != NULL)
+               nftnl_obj_set_str(n, NFTNL_OBJ_NAME, name);
        if (type != NFT_OBJECT_UNSPEC)
                nftnl_obj_set_u32(n, NFTNL_OBJ_TYPE, type);
        nftnl_obj_nlmsg_build_payload(nlh, n);
index 73ee5c973d168424cb96650f1957acdea1e2bf52..0cc3a517cd902d9ebcd28b494b9d3a3eb57fc567 100644 (file)
@@ -1775,8 +1775,8 @@ int netlink_list_objs(struct netlink_ctx *ctx, const struct handle *h,
        struct nftnl_obj_list *obj_cache;
        int err;
 
-       obj_cache = mnl_nft_obj_dump(nf_sock, h->family, h->table,
-                                    NFT_OBJECT_UNSPEC, false);
+       obj_cache = mnl_nft_obj_dump(nf_sock, h->family, h->table, NULL,
+                                    0, true, false);
        if (obj_cache == NULL) {
                if (errno == EINTR)
                        return -1;
@@ -1790,12 +1790,13 @@ int netlink_list_objs(struct netlink_ctx *ctx, const struct handle *h,
 }
 
 int netlink_reset_objs(struct netlink_ctx *ctx, const struct handle *h,
-                      const struct location *loc, uint32_t type)
+                      const struct location *loc, uint32_t type, bool dump)
 {
        struct nftnl_obj_list *obj_cache;
        int err;
 
-       obj_cache = mnl_nft_obj_dump(nf_sock, h->family, h->table, type, true);
+       obj_cache = mnl_nft_obj_dump(nf_sock, h->family, h->table, h->obj,
+                                    type, dump, true);
        if (obj_cache == NULL) {
                if (errno == EINTR)
                        return -1;
index 4749c9fa8730889cb28c8376da138aa599cfdd1d..a1b8b088cb40d25dd9b4c34cf90ff9101b48be42 100644 (file)
@@ -974,6 +974,10 @@ reset_cmd          :       COUNTERS        ruleset_spec
                        {
                                $$ = cmd_alloc(CMD_RESET, CMD_OBJ_COUNTERS, &$3, &@$, NULL);
                        }
+                       |       COUNTER         obj_spec
+                       {
+                               $$ = cmd_alloc(CMD_RESET, CMD_OBJ_COUNTER, &$2,&@$, NULL);
+                       }
                        |       QUOTAS          ruleset_spec
                        {
                                $$ = cmd_alloc(CMD_RESET, CMD_OBJ_QUOTAS, &$2, &@$, NULL);
@@ -982,6 +986,10 @@ reset_cmd          :       COUNTERS        ruleset_spec
                        {
                                $$ = cmd_alloc(CMD_RESET, CMD_OBJ_QUOTAS, &$3, &@$, NULL);
                        }
+                       |       QUOTA           obj_spec
+                       {
+                               $$ = cmd_alloc(CMD_RESET, CMD_OBJ_QUOTA, &$2, &@$, NULL);
+                       }
                        ;
 
 flush_cmd              :       TABLE           table_spec
index b5181a90f795d5ce3aa23a8131187c237ce661f7..a9f3a496a34578b3a0864bf225223f15a3b631eb 100644 (file)
@@ -1435,21 +1435,26 @@ static int do_command_reset(struct netlink_ctx *ctx, struct cmd *cmd)
 {
        struct obj *obj, *next;
        struct table *table;
+       bool dump = false;
        uint32_t type;
        int ret;
 
        switch (cmd->obj) {
        case CMD_OBJ_COUNTERS:
+               dump = true;
+       case CMD_OBJ_COUNTER:
                type = NFT_OBJECT_COUNTER;
                break;
        case CMD_OBJ_QUOTAS:
+               dump = true;
+       case CMD_OBJ_QUOTA:
                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);
+       ret = netlink_reset_objs(ctx, &cmd->handle, &cmd->location, type, dump);
        list_for_each_entry_safe(obj, next, &ctx->list, list) {
                table = table_lookup(&obj->handle);
                list_move(&obj->list, &table->objs);