summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2014-01-09 18:54:02 +0000
committerPatrick McHardy <kaber@trash.net>2014-01-09 18:54:02 +0000
commitf930cc50031851c6975058e33408214ad0c240b6 (patch)
treefb9cb26875448789bf602aeec1886c0c7493edf1
parenta54d7b05fb241dae62039d2c200e9a18941cf250 (diff)
nftables: fix supression of "permission denied" errors
Introduction of batch support broke displaying of EPERM since those are generated by the kernel before batch processing starts and thus have the sequence number of the NFNL_MSG_BATCH_BEGIN message instead of the command messages. Also only a single error message is generated for the entire batch. This patch fixes this by noting the batch sequence number and displaying the error for all commands since this is what would happen if the permission check was inside batch processing as every other check. Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/mnl.h2
-rw-r--r--src/main.c12
-rw-r--r--src/mnl.c8
3 files changed, 14 insertions, 8 deletions
diff --git a/include/mnl.h b/include/mnl.h
index fe2fb400..a6306058 100644
--- a/include/mnl.h
+++ b/include/mnl.h
@@ -18,7 +18,7 @@ void mnl_err_list_free(struct mnl_err *err);
void mnl_batch_init(void);
bool mnl_batch_ready(void);
void mnl_batch_reset(void);
-void mnl_batch_begin(void);
+uint32_t mnl_batch_begin(void);
void mnl_batch_end(void);
int mnl_batch_talk(struct mnl_socket *nl, struct list_head *err_list);
int mnl_nft_rule_batch_add(struct nft_rule *nlr, unsigned int flags,
diff --git a/src/main.c b/src/main.c
index 0c97120b..32a991a6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -156,9 +156,10 @@ static int nft_netlink(struct parser_state *state, struct list_head *msgs)
struct cmd *cmd, *next;
struct mnl_err *err, *tmp;
LIST_HEAD(err_list);
+ uint32_t batch_seqnum;
int ret = 0;
- mnl_batch_begin();
+ batch_seqnum = mnl_batch_begin();
list_for_each_entry(cmd, &state->cmds, list) {
memset(&ctx, 0, sizeof(ctx));
ctx.msgs = msgs;
@@ -179,12 +180,15 @@ static int nft_netlink(struct parser_state *state, struct list_head *msgs)
list_for_each_entry_safe(err, tmp, &err_list, head) {
list_for_each_entry(cmd, &state->cmds, list) {
- if (err->seqnum == cmd->seqnum) {
+ if (err->seqnum == cmd->seqnum ||
+ err->seqnum == batch_seqnum) {
netlink_io_error(&ctx, &cmd->location,
"Could not process rule in batch: %s",
strerror(err->err));
- mnl_err_list_free(err);
- break;
+ if (err->seqnum == cmd->seqnum) {
+ mnl_err_list_free(err);
+ break;
+ }
}
}
}
diff --git a/src/mnl.c b/src/mnl.c
index a711b5e2..a4a4c4af 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -106,7 +106,7 @@ static void mnl_batch_page_add(void)
batch = mnl_batch_alloc();
}
-static void mnl_batch_put(int type)
+static uint32_t mnl_batch_put(int type)
{
struct nlmsghdr *nlh;
struct nfgenmsg *nfg;
@@ -123,11 +123,13 @@ static void mnl_batch_put(int type)
if (!mnl_nlmsg_batch_next(batch))
mnl_batch_page_add();
+
+ return nlh->nlmsg_seq;
}
-void mnl_batch_begin(void)
+uint32_t mnl_batch_begin(void)
{
- mnl_batch_put(NFNL_MSG_BATCH_BEGIN);
+ return mnl_batch_put(NFNL_MSG_BATCH_BEGIN);
}
void mnl_batch_end(void)