]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
mnl: store netlink error location for set elements
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 27 Jun 2022 08:20:46 +0000 (10:20 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 27 Jun 2022 10:00:07 +0000 (12:00 +0200)
Store set element location in the per-command netlink error location
array.  This allows for fine grain error reporting when adding and
deleting elements.

 # nft -f test.nft
 test.nft:5:4-20: Error: Could not process rule: File exists
                        00:01:45:09:0b:26 : drop,
                        ^^^^^^^^^^^^^^^^^

test.nft contains a large map with one redundant entry.

Thus, users do not have to find the needle in the stack.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/mnl.h
src/mnl.c
src/rule.c

index 4c701d4ee6dc1c2d7b67919b76e5cc0b115c4beb..8e0a7e3fccab9e0f7e101b0505f95e7c517c9f1c 100644 (file)
@@ -60,10 +60,11 @@ int mnl_nft_set_del(struct netlink_ctx *ctx, struct cmd *cmd);
 struct nftnl_set_list *mnl_nft_set_dump(struct netlink_ctx *ctx, int family,
                                        const char *table, const char *set);
 
-int mnl_nft_setelem_add(struct netlink_ctx *ctx, const struct set *set,
-                       const struct expr *expr, unsigned int flags);
-int mnl_nft_setelem_del(struct netlink_ctx *ctx, const struct handle *h,
-                       const struct expr *init);
+int mnl_nft_setelem_add(struct netlink_ctx *ctx, struct cmd *cmd,
+                       const struct set *set, const struct expr *expr,
+                       unsigned int flags);
+int mnl_nft_setelem_del(struct netlink_ctx *ctx, struct cmd *cmd,
+                       const struct handle *h, const struct expr *init);
 int mnl_nft_setelem_flush(struct netlink_ctx *ctx, const struct cmd *cmd);
 int mnl_nft_setelem_get(struct netlink_ctx *ctx, struct nftnl_set *nls);
 struct nftnl_set *mnl_nft_setelem_get_one(struct netlink_ctx *ctx,
index 7dd77be1bec0b688e33a3e4f14bcec3e19acb580..e87b033870b0f1e73e2308eadf4b9ed97845e293 100644 (file)
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -1609,9 +1609,9 @@ static void netlink_dump_setelem_done(struct netlink_ctx *ctx)
        fprintf(fp, "\n");
 }
 
-static int mnl_nft_setelem_batch(const struct nftnl_set *nls,
+static int mnl_nft_setelem_batch(const struct nftnl_set *nls, struct cmd *cmd,
                                 struct nftnl_batch *batch,
-                                enum nf_tables_msg_types cmd,
+                                enum nf_tables_msg_types msg_type,
                                 unsigned int flags, uint32_t seqnum,
                                 const struct expr *set,
                                 struct netlink_ctx *ctx)
@@ -1622,14 +1622,14 @@ static int mnl_nft_setelem_batch(const struct nftnl_set *nls,
        struct expr *expr = NULL;
        int i = 0;
 
-       if (cmd == NFT_MSG_NEWSETELEM)
+       if (msg_type == NFT_MSG_NEWSETELEM)
                flags |= NLM_F_CREATE;
 
        if (set)
                expr = list_first_entry(&set->expressions, struct expr, list);
 
 next:
-       nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(batch), cmd,
+       nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(batch), msg_type,
                                    nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
                                    flags, seqnum);
 
@@ -1653,7 +1653,12 @@ next:
        nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_LIST_ELEMENTS);
        list_for_each_entry_from(expr, &set->expressions, list) {
                nlse = alloc_nftnl_setelem(set, expr);
-               nest2 = nftnl_set_elem_nlmsg_build(nlh, nlse, ++i);
+
+               cmd_add_loc(cmd, nlh->nlmsg_len, &expr->location);
+               nest2 = mnl_attr_nest_start(nlh, ++i);
+               nftnl_set_elem_nlmsg_build_payload(nlh, nlse);
+               mnl_attr_nest_end(nlh, nest2);
+
                netlink_dump_setelem(nlse, ctx);
                nftnl_set_elem_free(nlse);
                if (mnl_nft_attr_nest_overflow(nlh, nest1, nest2)) {
@@ -1669,8 +1674,9 @@ next:
        return 0;
 }
 
-int mnl_nft_setelem_add(struct netlink_ctx *ctx, const struct set *set,
-                       const struct expr *expr, unsigned int flags)
+int mnl_nft_setelem_add(struct netlink_ctx *ctx, struct cmd *cmd,
+                       const struct set *set, const struct expr *expr,
+                       unsigned int flags)
 {
        const struct handle *h = &set->handle;
        struct nftnl_set *nls;
@@ -1691,7 +1697,7 @@ int mnl_nft_setelem_add(struct netlink_ctx *ctx, const struct set *set,
 
        netlink_dump_set(nls, ctx);
 
-       err = mnl_nft_setelem_batch(nls, ctx->batch, NFT_MSG_NEWSETELEM,
+       err = mnl_nft_setelem_batch(nls, cmd, ctx->batch, NFT_MSG_NEWSETELEM,
                                    flags, ctx->seqnum, expr, ctx);
        nftnl_set_free(nls);
 
@@ -1728,8 +1734,8 @@ int mnl_nft_setelem_flush(struct netlink_ctx *ctx, const struct cmd *cmd)
        return 0;
 }
 
-int mnl_nft_setelem_del(struct netlink_ctx *ctx, const struct handle *h,
-                       const struct expr *init)
+int mnl_nft_setelem_del(struct netlink_ctx *ctx, struct cmd *cmd,
+                       const struct handle *h, const struct expr *init)
 {
        struct nftnl_set *nls;
        int err;
@@ -1747,7 +1753,7 @@ int mnl_nft_setelem_del(struct netlink_ctx *ctx, const struct handle *h,
 
        netlink_dump_set(nls, ctx);
 
-       err = mnl_nft_setelem_batch(nls, ctx->batch, NFT_MSG_DELSETELEM, 0,
+       err = mnl_nft_setelem_batch(nls, cmd, ctx->batch, NFT_MSG_DELSETELEM, 0,
                                    ctx->seqnum, init, ctx);
        nftnl_set_free(nls);
 
index c71f022670ef51bbaed6c93a7f7daa7ba10f00f5..79d4b77756e4e6c84db7c711c17957976e20fbe4 100644 (file)
@@ -1550,11 +1550,11 @@ void cmd_free(struct cmd *cmd)
 #include <netlink.h>
 #include <mnl.h>
 
-static int __do_add_elements(struct netlink_ctx *ctx, struct set *set,
-                            struct expr *expr, uint32_t flags)
+static int __do_add_elements(struct netlink_ctx *ctx, struct cmd *cmd,
+                            struct set *set, struct expr *expr, uint32_t flags)
 {
        expr->set_flags |= set->flags;
-       if (mnl_nft_setelem_add(ctx, set, expr, flags) < 0)
+       if (mnl_nft_setelem_add(ctx, cmd, set, expr, flags) < 0)
                return -1;
 
        return 0;
@@ -1570,7 +1570,7 @@ static int do_add_elements(struct netlink_ctx *ctx, struct cmd *cmd,
            set_to_intervals(set, init, true) < 0)
                return -1;
 
-       return __do_add_elements(ctx, set, init, flags);
+       return __do_add_elements(ctx, cmd, set, init, flags);
 }
 
 static int do_add_setelems(struct netlink_ctx *ctx, struct cmd *cmd,
@@ -1578,7 +1578,7 @@ static int do_add_setelems(struct netlink_ctx *ctx, struct cmd *cmd,
 {
        struct set *set = cmd->set;
 
-       return __do_add_elements(ctx, set, set->init, flags);
+       return __do_add_elements(ctx, cmd, set, set->init, flags);
 }
 
 static int do_add_set(struct netlink_ctx *ctx, struct cmd *cmd,
@@ -1672,7 +1672,7 @@ static int do_delete_setelems(struct netlink_ctx *ctx, struct cmd *cmd)
            set_to_intervals(set, expr, false) < 0)
                return -1;
 
-       if (mnl_nft_setelem_del(ctx, &cmd->handle, cmd->elem.expr) < 0)
+       if (mnl_nft_setelem_del(ctx, cmd, &cmd->handle, cmd->elem.expr) < 0)
                return -1;
 
        return 0;