summaryrefslogtreecommitdiffstats
path: root/src/libnftables.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2019-05-29 20:23:23 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2019-05-31 17:57:35 +0200
commit89c82c261bb53bfb0b671437a1323830dd7e4019 (patch)
treea9a1cd8f03fbdf8e4ad735c1e91990887bb6c27d /src/libnftables.c
parentf718751f306d0de7ae2976f0003f6c1892fd0094 (diff)
mnl: estimate receiver buffer size
Set a receiver buffer size based on the number of commands and the average message size, this is useful for the --echo option in order to avoid ENOBUFS errors. On the kernel side, each skbuff consumes truesize from the socket queue (although it uses NLMSG_GOODSIZE to allocate it), which is approximately four times the estimated size per message that we get in turn for each echo message to ensure enough receiver buffer space. We could also explore increasing the buffer and retry if mnl_nft_socket_sendmsg() hits ENOBUFS if we ever hit this problem again. Reported-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/libnftables.c')
-rw-r--r--src/libnftables.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/src/libnftables.c b/src/libnftables.c
index 199dbc97..a58b8ca9 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -21,7 +21,7 @@ static int nft_netlink(struct nft_ctx *nft,
struct list_head *cmds, struct list_head *msgs,
struct mnl_socket *nf_sock)
{
- uint32_t batch_seqnum, seqnum = 0;
+ uint32_t batch_seqnum, seqnum = 0, num_cmds = 0;
struct nftnl_batch *batch;
struct netlink_ctx ctx;
struct cmd *cmd;
@@ -49,6 +49,7 @@ static int nft_netlink(struct nft_ctx *nft,
strerror(errno));
goto out;
}
+ num_cmds++;
}
if (!nft->check)
mnl_batch_end(batch, mnl_seqnum_alloc(&seqnum));
@@ -56,7 +57,7 @@ static int nft_netlink(struct nft_ctx *nft,
if (!mnl_batch_ready(batch))
goto out;
- ret = mnl_batch_talk(&ctx, &err_list);
+ ret = mnl_batch_talk(&ctx, &err_list, num_cmds);
list_for_each_entry_safe(err, tmp, &err_list, head) {
list_for_each_entry(cmd, cmds, list) {