diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2020-02-17 22:38:13 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2020-02-19 15:17:11 +0100 |
commit | f8aec603aa7e9dad1316079d42c7efcc52b773fa (patch) | |
tree | 2c2f9c1c601610464431683c6d90ca0e8af27d2b /src/libnftables.c | |
parent | 9491f1a8eecf1c023ebe3a30b1e92e44a4a39a05 (diff) |
src: initial extended netlink error reporting
This patch correlates the in-kernel extended netlink error offset and
the location information.
Assuming 'foo' table does not exist, then error reporting shows:
# nft delete table foo
Error: Could not process rule: No such file or directory
delete table foo
^^^
Similarly, if table uniquely identified by handle '1234' does not exist,
then error reporting shows:
# nft delete table handle 1234
Error: Could not process rule: No such file or directory
delete table handle 1234
^^^^
Assuming 'bar' chain does not exists in the kernel, while 'foo' does:
# nft delete chain foo bar
Error: Could not process rule: No such file or directory
delete chain foo bar
^^^
This also gives us a hint when adding rules:
# nft add rule ip foo bar counter
Error: Could not process rule: No such file or directory
add rule ip foo bar counter
^^^
This is based on ("src: basic support for extended netlink errors") from
Florian Westphal, posted in 2018, with no netlink offset correlation
support.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/libnftables.c')
-rw-r--r-- | src/libnftables.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/libnftables.c b/src/libnftables.c index cd2fcf2f..eaa4736c 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -17,6 +17,25 @@ #include <stdlib.h> #include <string.h> +static void nft_error(struct netlink_ctx *ctx, struct cmd *cmd, + struct mnl_err *err) +{ + struct location *loc = NULL; + int i; + + for (i = 0; i < cmd->num_attrs; i++) { + if (!cmd->attr[i].offset) + break; + if (cmd->attr[i].offset == err->offset) + loc = cmd->attr[i].location; + } + if (!loc) + loc = &cmd->location; + + netlink_io_error(ctx, loc, "Could not process rule: %s", + strerror(err->err)); +} + static int nft_netlink(struct nft_ctx *nft, struct list_head *cmds, struct list_head *msgs, struct mnl_socket *nf_sock) @@ -68,9 +87,7 @@ static int nft_netlink(struct nft_ctx *nft, list_for_each_entry(cmd, cmds, list) { if (err->seqnum == cmd->seqnum || err->seqnum == batch_seqnum) { - netlink_io_error(&ctx, &cmd->location, - "Could not process rule: %s", - strerror(err->err)); + nft_error(&ctx, cmd, err); errno = err->err; if (err->seqnum == cmd->seqnum) { mnl_err_list_free(err); |