Submitted by:            DJ Lucas (dj_AT_linuxfromscratch_DOT_org)
Date:                    2019-11-29
Initial Package Version: 0.9.2
Upstream Status:         Comitted
Origin:                  http://git.netfilter.org/nftables/commit/?id=8ecb8855895915513e757ffc8d3b7342e63e9fe6
                         http://git.netfilter.org/nftables/commit/?id=860671662d3f7aeec156932aff648e04f0e2ec92
                         http://git.netfilter.org/nftables/commit/?id=e64c42b19a9e50009b4d8877aeee95edb6818990
                         http://git.netfilter.org/nftables/commit/?id=2e57d4ff79fa166f2dea3686ca4fe051b656a8d2
Description:             Provides upstrea JSON fixes requried for firewalld-0.8.0

diff --git a/include/netlink.h b/include/netlink.h
index 279723f3..e6941714 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -171,7 +171,6 @@ struct netlink_mon_handler {
 	struct netlink_ctx	*ctx;
 	const struct location	*loc;
 	unsigned int		debug_mask;
-	bool			cache_needed;
 	struct nft_cache	*cache;
 };
 
diff --git a/src/monitor.c b/src/monitor.c
index 20810a5d..ea0393cd 100644
--- a/src/monitor.c
+++ b/src/monitor.c
@@ -609,6 +609,12 @@ static void netlink_events_cache_addset(struct netlink_mon_handler *monh,
 		goto out;
 	}
 
+	if (nft_output_echo(&monh->ctx->nft->output) &&
+	    !set_is_anonymous(s->flags)) {
+		set_free(s);
+		goto out;
+	}
+
 	set_add_hash(s, t);
 out:
 	nftnl_set_free(nls);
@@ -636,6 +642,10 @@ static void netlink_events_cache_addsetelem(struct netlink_mon_handler *monh,
 		goto out;
 	}
 
+	if (nft_output_echo(&monh->ctx->nft->output) &&
+	    !set_is_anonymous(set->flags))
+		goto out;
+
 	nlsei = nftnl_set_elems_iter_create(nls);
 	if (nlsei == NULL)
 		memory_allocation_error();
@@ -744,7 +754,8 @@ out:
 static void netlink_events_cache_update(struct netlink_mon_handler *monh,
 					const struct nlmsghdr *nlh, int type)
 {
-	if (!monh->cache_needed)
+	if (nft_output_echo(&monh->ctx->nft->output) &&
+	    type != NFT_MSG_NEWSET && type != NFT_MSG_NEWSETELEM)
 		return;
 
 	switch (type) {
diff --git a/src/rule.c b/src/rule.c
index 19a06bea..55894cbd 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -2502,23 +2502,6 @@ static int do_command_rename(struct netlink_ctx *ctx, struct cmd *cmd)
 	return 0;
 }
 
-static bool need_cache(const struct cmd *cmd)
-{
-	/*
-	 *  - new rules in default format
-	 *  - new elements
-	 */
-	if (((cmd->monitor->flags & (1 << NFT_MSG_NEWRULE)) &&
-	    (cmd->monitor->format == NFTNL_OUTPUT_DEFAULT)) ||
-	    (cmd->monitor->flags & (1 << NFT_MSG_NEWSETELEM)))
-		return true;
-
-	if (cmd->monitor->flags & (1 << NFT_MSG_TRACE))
-		return true;
-
-	return false;
-}
-
 static int do_command_monitor(struct netlink_ctx *ctx, struct cmd *cmd)
 {
 	struct netlink_mon_handler monhandler = {
@@ -2533,8 +2516,6 @@ static int do_command_monitor(struct netlink_ctx *ctx, struct cmd *cmd)
 	if (nft_output_json(&ctx->nft->output))
 		monhandler.format = NFTNL_OUTPUT_JSON;
 
-	monhandler.cache_needed = need_cache(cmd);
-
 	return netlink_monitor(&monhandler, ctx->nft->nf_sock);
 }
 


diff --git a/src/parser_json.c b/src/parser_json.c
index 8ca07d71..183d9c97 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -3258,7 +3258,11 @@ static struct cmd *json_parse_cmd_add(struct json_ctx *ctx,
 static struct cmd *json_parse_cmd_replace(struct json_ctx *ctx,
 					  json_t *root, enum cmd_ops op)
 {
-	struct handle h = { 0 };
+	struct handle h = {
+		.table.location = *int_loc,
+		.chain.location = *int_loc,
+		.index.location = *int_loc,
+	};
 	json_t *tmp, *value;
 	const char *family;
 	struct rule *rule;

diff --git a/src/cache.c b/src/cache.c
index cffcbb62..a778650a 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -104,11 +104,9 @@ unsigned int cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
 		case CMD_ADD:
 		case CMD_INSERT:
 		case CMD_CREATE:
-			if (nft_output_echo(&nft->output)) {
-				flags = NFT_CACHE_FULL;
-				break;
-			}
 			flags = evaluate_cache_add(cmd, flags);
+			if (nft_output_echo(&nft->output))
+				flags |= NFT_CACHE_FULL;
 			break;
 		case CMD_REPLACE:
 			flags = NFT_CACHE_FULL;



diff --git a/src/mnl.c b/src/mnl.c
index 9c1f5356..8031bd6a 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -304,6 +304,8 @@ static ssize_t mnl_nft_socket_sendmsg(struct netlink_ctx *ctx,
 	return sendmsg(mnl_socket_get_fd(ctx->nft->nf_sock), msg, 0);
 }
 
+#define NFT_MNL_ECHO_RCVBUFF_DEFAULT	(MNL_SOCKET_BUFFER_SIZE * 1024)
+
 int mnl_batch_talk(struct netlink_ctx *ctx, struct list_head *err_list,
 		   uint32_t num_cmds)
 {
@@ -311,8 +313,6 @@ int mnl_batch_talk(struct netlink_ctx *ctx, struct list_head *err_list,
 	int ret, fd = mnl_socket_get_fd(nl), portid = mnl_socket_get_portid(nl);
 	uint32_t iov_len = nftnl_batch_iovec_len(ctx->batch);
 	char rcv_buf[MNL_SOCKET_BUFFER_SIZE];
-	unsigned int enobuf_restarts = 0;
-	size_t avg_msg_size, batch_size;
 	const struct sockaddr_nl snl = {
 		.nl_family = AF_NETLINK
 	};
@@ -321,17 +321,24 @@ int mnl_batch_talk(struct netlink_ctx *ctx, struct list_head *err_list,
 		.tv_usec	= 0
 	};
 	struct iovec iov[iov_len];
-	unsigned int scale = 4;
 	struct msghdr msg = {};
+	unsigned int rcvbufsiz;
+	size_t batch_size;
 	fd_set readfds;
 
 	mnl_set_sndbuffer(ctx->nft->nf_sock, ctx->batch);
 
 	batch_size = mnl_nft_batch_to_msg(ctx, &msg, &snl, iov, iov_len);
-	avg_msg_size = div_round_up(batch_size, num_cmds);
 
-restart:
-	mnl_set_rcvbuffer(ctx->nft->nf_sock, num_cmds * avg_msg_size * scale);
+	if (nft_output_echo(&ctx->nft->output)) {
+		rcvbufsiz = num_cmds * 1024;
+		if (rcvbufsiz < NFT_MNL_ECHO_RCVBUFF_DEFAULT)
+			rcvbufsiz = NFT_MNL_ECHO_RCVBUFF_DEFAULT;
+	} else {
+		rcvbufsiz = num_cmds * div_round_up(batch_size, num_cmds) * 4;
+	}
+
+	mnl_set_rcvbuffer(ctx->nft->nf_sock, rcvbufsiz);
 
 	ret = mnl_nft_socket_sendmsg(ctx, &msg);
 	if (ret == -1)
@@ -350,13 +357,8 @@ restart:
 			break;
 
 		ret = mnl_socket_recvfrom(nl, rcv_buf, sizeof(rcv_buf));
-		if (ret == -1) {
-			if (errno == ENOBUFS && enobuf_restarts++ < 3) {
-				scale *= 2;
-				goto restart;
-			}
+		if (ret == -1)
 			return -1;
-		}
 
 		ret = mnl_cb_run(rcv_buf, ret, 0, portid, &netlink_echo_callback, ctx);
 		/* Continue on error, make sure we get all acknowledgments */


