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