Blame SOURCES/0039-json-Fix-seqnum_to_json-functionality.patch

19e5f4
From 0dcfa1b0211fa50201d51d0f52869a8e2d93ba76 Mon Sep 17 00:00:00 2001
19e5f4
From: Phil Sutter <psutter@redhat.com>
19e5f4
Date: Mon, 7 Dec 2020 18:29:15 +0100
19e5f4
Subject: [PATCH] json: Fix seqnum_to_json() functionality
19e5f4
19e5f4
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1900565
19e5f4
Upstream Status: nftables commit 299ec575faa6b
19e5f4
19e5f4
commit 299ec575faa6b070940b483dc517ecd883b9f1a4
19e5f4
Author: Phil Sutter <phil@nwl.cc>
19e5f4
Date:   Wed Dec 2 23:07:11 2020 +0100
19e5f4
19e5f4
    json: Fix seqnum_to_json() functionality
19e5f4
19e5f4
    Introduction of json_cmd_assoc_hash missed that by the time the hash
19e5f4
    table insert happens, the struct cmd object's 'seqnum' field which is
19e5f4
    used as key is not initialized yet. This doesn't happen until
19e5f4
    nft_netlink() prepares the batch object which records the lowest seqnum.
19e5f4
    Therefore push all json_cmd_assoc objects into a temporary list until
19e5f4
    the first lookup happens. At this time, all referenced cmd objects have
19e5f4
    their seqnum set and the list entries can be moved into the hash table
19e5f4
    for fast lookups.
19e5f4
19e5f4
    To expose such problems in the future, make json_events_cb() emit an
19e5f4
    error message if the passed message has a handle but no assoc entry is
19e5f4
    found for its seqnum.
19e5f4
19e5f4
    Fixes: 389a0e1edc89a ("json: echo: Speedup seqnum_to_json()")
19e5f4
    Cc: Derek Dai <daiderek@gmail.com>
19e5f4
    Signed-off-by: Phil Sutter <phil@nwl.cc>
19e5f4
---
19e5f4
 src/parser_json.c | 27 +++++++++++++++++++++++----
19e5f4
 1 file changed, 23 insertions(+), 4 deletions(-)
19e5f4
19e5f4
diff --git a/src/parser_json.c b/src/parser_json.c
19e5f4
index 107dc38..785f0e7 100644
19e5f4
--- a/src/parser_json.c
19e5f4
+++ b/src/parser_json.c
19e5f4
@@ -3646,6 +3646,7 @@ static int json_verify_metainfo(struct json_ctx *ctx, json_t *root)
19e5f4
 }
19e5f4
 
19e5f4
 struct json_cmd_assoc {
19e5f4
+	struct json_cmd_assoc *next;
19e5f4
 	struct hlist_node hnode;
19e5f4
 	const struct cmd *cmd;
19e5f4
 	json_t *json;
19e5f4
@@ -3653,6 +3654,7 @@ struct json_cmd_assoc {
19e5f4
 
19e5f4
 #define CMD_ASSOC_HSIZE		512
19e5f4
 static struct hlist_head json_cmd_assoc_hash[CMD_ASSOC_HSIZE];
19e5f4
+static struct json_cmd_assoc *json_cmd_assoc_list;
19e5f4
 
19e5f4
 static void json_cmd_assoc_free(void)
19e5f4
 {
19e5f4
@@ -3660,6 +3662,12 @@ static void json_cmd_assoc_free(void)
19e5f4
 	struct hlist_node *pos, *n;
19e5f4
 	int i;
19e5f4
 
19e5f4
+	while (json_cmd_assoc_list) {
19e5f4
+		cur = json_cmd_assoc_list->next;
19e5f4
+		free(json_cmd_assoc_list);
19e5f4
+		json_cmd_assoc_list = cur;
19e5f4
+	}
19e5f4
+
19e5f4
 	for (i = 0; i < CMD_ASSOC_HSIZE; i++) {
19e5f4
 		hlist_for_each_entry_safe(cur, pos, n,
19e5f4
 					  &json_cmd_assoc_hash[i], hnode)
19e5f4
@@ -3670,21 +3678,29 @@ static void json_cmd_assoc_free(void)
19e5f4
 static void json_cmd_assoc_add(json_t *json, const struct cmd *cmd)
19e5f4
 {
19e5f4
 	struct json_cmd_assoc *new = xzalloc(sizeof *new);
19e5f4
-	int key = cmd->seqnum % CMD_ASSOC_HSIZE;
19e5f4
 
19e5f4
 	new->json	= json;
19e5f4
 	new->cmd	= cmd;
19e5f4
+	new->next	= json_cmd_assoc_list;
19e5f4
 
19e5f4
-	hlist_add_head(&new->hnode, &json_cmd_assoc_hash[key]);
19e5f4
+	json_cmd_assoc_list = new;
19e5f4
 }
19e5f4
 
19e5f4
 static json_t *seqnum_to_json(const uint32_t seqnum)
19e5f4
 {
19e5f4
-	int key = seqnum % CMD_ASSOC_HSIZE;
19e5f4
 	struct json_cmd_assoc *cur;
19e5f4
 	struct hlist_node *n;
19e5f4
+	int key;
19e5f4
 
19e5f4
+	while (json_cmd_assoc_list) {
19e5f4
+		cur = json_cmd_assoc_list;
19e5f4
+		json_cmd_assoc_list = cur->next;
19e5f4
 
19e5f4
+		key = cur->cmd->seqnum % CMD_ASSOC_HSIZE;
19e5f4
+		hlist_add_head(&cur->hnode, &json_cmd_assoc_hash[key]);
19e5f4
+	}
19e5f4
+
19e5f4
+	key = seqnum % CMD_ASSOC_HSIZE;
19e5f4
 	hlist_for_each_entry(cur, n, &json_cmd_assoc_hash[key], hnode) {
19e5f4
 		if (cur->cmd->seqnum == seqnum)
19e5f4
 			return cur->json;
19e5f4
@@ -3865,8 +3881,11 @@ int json_events_cb(const struct nlmsghdr *nlh, struct netlink_mon_handler *monh)
19e5f4
 		return MNL_CB_OK;
19e5f4
 
19e5f4
 	json = seqnum_to_json(nlh->nlmsg_seq);
19e5f4
-	if (!json)
19e5f4
+	if (!json) {
19e5f4
+		json_echo_error(monh, "No JSON command found with seqnum %lu\n",
19e5f4
+				nlh->nlmsg_seq);
19e5f4
 		return MNL_CB_OK;
19e5f4
+	}
19e5f4
 
19e5f4
 	tmp = json_object_get(json, "add");
19e5f4
 	if (!tmp)
19e5f4
-- 
bfbb76
2.31.1
19e5f4