d9f08f29ae
* Thu Nov 07 2024 Phil Sutter <psutter@redhat.com> [1.1.1-1.el10] - monitor: Recognize flowtable add/del events (Phil Sutter) [RHEL-65346] - tests: py: Fix for storing payload into missing file (Phil Sutter) [RHEL-65346] - json: Support typeof in set and map types (Phil Sutter) [RHEL-65346] - json: collapse set element commands from parser (Phil Sutter) [RHEL-65346] - doc: extend description of fib expression (Phil Sutter) [RHEL-65346] - tests: monitor: fix up test case breakage (Phil Sutter) [RHEL-65346] - src: fix extended netlink error reporting with large set elements (Phil Sutter) [RHEL-65346] - rule: netlink attribute offset is uint32_t for struct nlerr_loc (Phil Sutter) [RHEL-65346] - mnl: update cmd_add_loc() to take struct nlmsghdr (Phil Sutter) [RHEL-65346] - mnl: rename to mnl_seqnum_alloc() to mnl_seqnum_inc() (Phil Sutter) [RHEL-65346] - src: collapse set element commands from parser (Phil Sutter) [RHEL-65346] - libnftables-json: fix raw payload expression documentation (Phil Sutter) [RHEL-65346] - tests: shell: fix spurious dump failure in vmap timeout test (Phil Sutter) [RHEL-65346] - Rebase onto version 1.1.1 (Phil Sutter) [RHEL-65346] Resolves: RHEL-65346
194 lines
6.4 KiB
Diff
194 lines
6.4 KiB
Diff
From c62c11ee27daf90c74a46353df4936b869624e72 Mon Sep 17 00:00:00 2001
|
|
From: Phil Sutter <psutter@redhat.com>
|
|
Date: Thu, 7 Nov 2024 18:38:45 +0100
|
|
Subject: [PATCH] src: fix extended netlink error reporting with large set
|
|
elements
|
|
|
|
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
|
Upstream Status: nftables commit 68d2de3ca6c6eb18f5b32f7b4324a85c9c6c358e
|
|
|
|
commit 68d2de3ca6c6eb18f5b32f7b4324a85c9c6c358e
|
|
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
Date: Thu Oct 24 00:24:55 2024 +0200
|
|
|
|
src: fix extended netlink error reporting with large set elements
|
|
|
|
Large sets can expand into several netlink messages, use sequence number
|
|
and attribute offset to correlate the set element and the location.
|
|
|
|
When set element command expands into several netlink messages,
|
|
increment sequence number for each netlink message. Update struct cmd to
|
|
store the range of netlink messages that result from this command.
|
|
|
|
struct nlerr_loc remains in the same size in x86_64.
|
|
|
|
# nft -f set-65535.nft
|
|
set-65535.nft:65029:22-32: Error: Could not process rule: File exists
|
|
create element x y { 1.1.254.253 }
|
|
^^^^^^^^^^^
|
|
|
|
Fixes: f8aec603aa7e ("src: initial extended netlink error reporting")
|
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
---
|
|
include/rule.h | 4 +++-
|
|
src/cmd.c | 4 +++-
|
|
src/libnftables.c | 12 ++++++++----
|
|
src/mnl.c | 9 +++++----
|
|
src/parser_json.c | 4 ++--
|
|
5 files changed, 21 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/include/rule.h b/include/rule.h
|
|
index 3fcfa44..48e148e 100644
|
|
--- a/include/rule.h
|
|
+++ b/include/rule.h
|
|
@@ -695,6 +695,7 @@ void monitor_free(struct monitor *m);
|
|
#define NFT_NLATTR_LOC_MAX 32
|
|
|
|
struct nlerr_loc {
|
|
+ uint32_t seqnum;
|
|
uint32_t offset;
|
|
const struct location *location;
|
|
};
|
|
@@ -717,7 +718,8 @@ struct cmd {
|
|
enum cmd_ops op;
|
|
enum cmd_obj obj;
|
|
struct handle handle;
|
|
- uint32_t seqnum;
|
|
+ uint32_t seqnum_from;
|
|
+ uint32_t seqnum_to;
|
|
union {
|
|
void *data;
|
|
struct expr *expr;
|
|
diff --git a/src/cmd.c b/src/cmd.c
|
|
index 0c7a43e..eb44b98 100644
|
|
--- a/src/cmd.c
|
|
+++ b/src/cmd.c
|
|
@@ -24,6 +24,7 @@ void cmd_add_loc(struct cmd *cmd, const struct nlmsghdr *nlh, const struct locat
|
|
cmd->attr = xrealloc(cmd->attr, sizeof(struct nlerr_loc) * cmd->attr_array_len);
|
|
}
|
|
|
|
+ cmd->attr[cmd->num_attrs].seqnum = nlh->nlmsg_seq;
|
|
cmd->attr[cmd->num_attrs].offset = nlh->nlmsg_len;
|
|
cmd->attr[cmd->num_attrs].location = loc;
|
|
cmd->num_attrs++;
|
|
@@ -323,7 +324,8 @@ void nft_cmd_error(struct netlink_ctx *ctx, struct cmd *cmd,
|
|
uint32_t i;
|
|
|
|
for (i = 0; i < cmd->num_attrs; i++) {
|
|
- if (cmd->attr[i].offset == err->offset)
|
|
+ if (cmd->attr[i].seqnum == err->seqnum &&
|
|
+ cmd->attr[i].offset == err->offset)
|
|
loc = cmd->attr[i].location;
|
|
}
|
|
|
|
diff --git a/src/libnftables.c b/src/libnftables.c
|
|
index 3550961..1df22b3 100644
|
|
--- a/src/libnftables.c
|
|
+++ b/src/libnftables.c
|
|
@@ -39,7 +39,7 @@ static int nft_netlink(struct nft_ctx *nft,
|
|
|
|
batch_seqnum = mnl_batch_begin(ctx.batch, mnl_seqnum_inc(&seqnum));
|
|
list_for_each_entry(cmd, cmds, list) {
|
|
- ctx.seqnum = cmd->seqnum = mnl_seqnum_inc(&seqnum);
|
|
+ ctx.seqnum = cmd->seqnum_from = mnl_seqnum_inc(&seqnum);
|
|
ret = do_command(&ctx, cmd);
|
|
if (ret < 0) {
|
|
netlink_io_error(&ctx, &cmd->location,
|
|
@@ -47,6 +47,8 @@ static int nft_netlink(struct nft_ctx *nft,
|
|
strerror(errno));
|
|
goto out;
|
|
}
|
|
+ seqnum = cmd->seqnum_to = ctx.seqnum;
|
|
+ mnl_seqnum_inc(&seqnum);
|
|
num_cmds++;
|
|
}
|
|
if (!nft->check)
|
|
@@ -80,12 +82,14 @@ static int nft_netlink(struct nft_ctx *nft,
|
|
cmd = list_first_entry(cmds, struct cmd, list);
|
|
|
|
list_for_each_entry_from(cmd, cmds, list) {
|
|
- last_seqnum = cmd->seqnum;
|
|
- if (err->seqnum == cmd->seqnum ||
|
|
+ last_seqnum = cmd->seqnum_to;
|
|
+ if ((err->seqnum >= cmd->seqnum_from &&
|
|
+ err->seqnum <= cmd->seqnum_to) ||
|
|
err->seqnum == batch_seqnum) {
|
|
nft_cmd_error(&ctx, cmd, err);
|
|
errno = err->err;
|
|
- if (err->seqnum == cmd->seqnum) {
|
|
+ if (err->seqnum >= cmd->seqnum_from ||
|
|
+ err->seqnum <= cmd->seqnum_to) {
|
|
mnl_err_list_free(err);
|
|
break;
|
|
}
|
|
diff --git a/src/mnl.c b/src/mnl.c
|
|
index 42d1b0d..12a6345 100644
|
|
--- a/src/mnl.c
|
|
+++ b/src/mnl.c
|
|
@@ -1722,7 +1722,7 @@ static void netlink_dump_setelem_done(struct netlink_ctx *ctx)
|
|
static int mnl_nft_setelem_batch(const struct nftnl_set *nls, struct cmd *cmd,
|
|
struct nftnl_batch *batch,
|
|
enum nf_tables_msg_types msg_type,
|
|
- unsigned int flags, uint32_t seqnum,
|
|
+ unsigned int flags, uint32_t *seqnum,
|
|
const struct expr *set,
|
|
struct netlink_ctx *ctx)
|
|
{
|
|
@@ -1741,7 +1741,7 @@ static int mnl_nft_setelem_batch(const struct nftnl_set *nls, struct cmd *cmd,
|
|
next:
|
|
nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(batch), msg_type,
|
|
nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
|
|
- flags, seqnum);
|
|
+ flags, *seqnum);
|
|
|
|
if (nftnl_set_is_set(nls, NFTNL_SET_TABLE)) {
|
|
mnl_attr_put_strz(nlh, NFTA_SET_ELEM_LIST_TABLE,
|
|
@@ -1774,6 +1774,7 @@ next:
|
|
if (mnl_nft_attr_nest_overflow(nlh, nest1, nest2)) {
|
|
mnl_attr_nest_end(nlh, nest1);
|
|
mnl_nft_batch_continue(batch);
|
|
+ mnl_seqnum_inc(seqnum);
|
|
goto next;
|
|
}
|
|
}
|
|
@@ -1808,7 +1809,7 @@ int mnl_nft_setelem_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
|
netlink_dump_set(nls, ctx);
|
|
|
|
err = mnl_nft_setelem_batch(nls, cmd, ctx->batch, NFT_MSG_NEWSETELEM,
|
|
- flags, ctx->seqnum, expr, ctx);
|
|
+ flags, &ctx->seqnum, expr, ctx);
|
|
nftnl_set_free(nls);
|
|
|
|
return err;
|
|
@@ -1868,7 +1869,7 @@ int mnl_nft_setelem_del(struct netlink_ctx *ctx, struct cmd *cmd,
|
|
msg_type = NFT_MSG_DESTROYSETELEM;
|
|
|
|
err = mnl_nft_setelem_batch(nls, cmd, ctx->batch, msg_type, 0,
|
|
- ctx->seqnum, init, ctx);
|
|
+ &ctx->seqnum, init, ctx);
|
|
nftnl_set_free(nls);
|
|
|
|
return err;
|
|
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
index bbe3b1c..37ec34c 100644
|
|
--- a/src/parser_json.c
|
|
+++ b/src/parser_json.c
|
|
@@ -4269,13 +4269,13 @@ static json_t *seqnum_to_json(const uint32_t seqnum)
|
|
cur = json_cmd_assoc_list;
|
|
json_cmd_assoc_list = cur->next;
|
|
|
|
- key = cur->cmd->seqnum % CMD_ASSOC_HSIZE;
|
|
+ key = cur->cmd->seqnum_from % CMD_ASSOC_HSIZE;
|
|
hlist_add_head(&cur->hnode, &json_cmd_assoc_hash[key]);
|
|
}
|
|
|
|
key = seqnum % CMD_ASSOC_HSIZE;
|
|
hlist_for_each_entry(cur, n, &json_cmd_assoc_hash[key], hnode) {
|
|
- if (cur->cmd->seqnum == seqnum)
|
|
+ if (cur->cmd->seqnum_from == seqnum)
|
|
return cur->json;
|
|
}
|
|
|