static void monitor_print_json(struct netlink_mon_handler *monh,
const char *cmd, json_t *obj)
{
+ struct nft_ctx *nft = monh->ctx->nft;
+
obj = json_pack("{s:o}", cmd, obj);
- json_dumpf(obj, monh->ctx->nft->output.output_fp, 0);
- json_decref(obj);
+ if (nft_output_echo(&nft->output) && !nft->json_root) {
+ json_array_append_new(nft->json_echo, obj);
+ } else {
+ json_dumpf(obj, nft->output.output_fp, 0);
+ json_decref(obj);
+ }
}
void monitor_print_table_json(struct netlink_mon_handler *monh,
monitor_print_json(monh, cmd, rule_print_json(octx, r));
}
+
+void json_alloc_echo(struct nft_ctx *nft)
+{
+ nft->json_echo = json_array();
+ if (!nft->json_echo)
+ memory_allocation_error();
+}
if (nft_output_handle(&monh->ctx->nft->output))
nft_mon_print(monh, " # handle %" PRIu64 "",
t->handle.handle.id);
+ nft_mon_print(monh, "\n");
break;
case NFTNL_OUTPUT_JSON:
monitor_print_table_json(monh, cmd, t);
+ if(!nft_output_echo(&monh->ctx->nft->output))
+ nft_mon_print(monh, "\n");
break;
}
- nft_mon_print(monh, "\n");
table_free(t);
nftnl_table_free(nlt);
return MNL_CB_OK;
c->handle.chain.name);
break;
}
+ nft_mon_print(monh, "\n");
break;
case NFTNL_OUTPUT_JSON:
monitor_print_chain_json(monh, cmd, c);
+ if(!nft_output_echo(&monh->ctx->nft->output))
+ nft_mon_print(monh, "\n");
break;
}
- nft_mon_print(monh, "\n");
chain_free(c);
nftnl_chain_free(nlc);
return MNL_CB_OK;
set->handle.set.name);
break;
}
+ nft_mon_print(monh, "\n");
break;
case NFTNL_OUTPUT_JSON:
monitor_print_set_json(monh, cmd, set);
+ if(!nft_output_echo(&monh->ctx->nft->output))
+ nft_mon_print(monh, "\n");
break;
}
- nft_mon_print(monh, "\n");
set_free(set);
out:
nftnl_set_free(nls);
nft_mon_print(monh, "%s element %s %s %s ",
cmd, family2str(family), table, setname);
expr_print(dummyset->init, &monh->ctx->nft->output);
+ nft_mon_print(monh, "\n");
break;
case NFTNL_OUTPUT_JSON:
dummyset->handle.family = family;
/* prevent set_free() from trying to free those */
dummyset->handle.set.name = NULL;
dummyset->handle.table.name = NULL;
+ if(!nft_output_echo(&monh->ctx->nft->output))
+ nft_mon_print(monh, "\n");
break;
}
- nft_mon_print(monh, "\n");
set_free(dummyset);
out:
nftnl_set_free(nls);
obj->handle.obj.name);
break;
}
+ nft_mon_print(monh, "\n");
break;
case NFTNL_OUTPUT_JSON:
monitor_print_obj_json(monh, cmd, obj);
+ if(!nft_output_echo(&monh->ctx->nft->output))
+ nft_mon_print(monh, "\n");
break;
}
- nft_mon_print(monh, "\n");
obj_free(obj);
nftnl_obj_free(nlo);
return MNL_CB_OK;
r->handle.handle.id);
break;
}
+ nft_mon_print(monh, "\n");
break;
case NFTNL_OUTPUT_JSON:
monitor_print_rule_json(monh, cmd, r);
+ if(!nft_output_echo(&monh->ctx->nft->output))
+ nft_mon_print(monh, "\n");
break;
}
- nft_mon_print(monh, "\n");
rule_free(r);
nftnl_rule_free(nlr);
return MNL_CB_OK;
{
struct netlink_cb_data *nl_cb_data = data;
struct netlink_ctx *ctx = nl_cb_data->nl_ctx;
+ struct nft_ctx *nft = ctx->nft;
+
struct netlink_mon_handler echo_monh = {
.format = NFTNL_OUTPUT_DEFAULT,
.ctx = ctx,
if (!nft_output_echo(&echo_monh.ctx->nft->output))
return MNL_CB_OK;
- if (nft_output_json(&ctx->nft->output))
- return json_events_cb(nlh, &echo_monh);
+ if (nft_output_json(&nft->output)) {
+ if (nft->json_root)
+ return json_events_cb(nlh, &echo_monh);
+
+ json_alloc_echo(nft);
+ echo_monh.format = NFTNL_OUTPUT_JSON;
+ }
return netlink_events_cb(nlh, &echo_monh);
}
void json_print_echo(struct nft_ctx *ctx)
{
- if (!ctx->json_root)
- return;
-
- json_dumpf(ctx->json_root, ctx->output.output_fp, JSON_PRESERVE_ORDER);
- json_cmd_assoc_free();
- json_decref(ctx->json_root);
- ctx->json_root = NULL;
+ if (!ctx->json_root) {
+ if (!ctx->json_echo)
+ return;
+
+ ctx->json_echo = json_pack("{s:o}", "nftables", ctx->json_echo);
+ json_dumpf(ctx->json_echo, ctx->output.output_fp, JSON_PRESERVE_ORDER);
+ json_decref(ctx->json_echo);
+ ctx->json_echo = NULL;
+ fprintf(ctx->output.output_fp, "\n");
+ fflush(ctx->output.output_fp);
+ } else {
+ json_dumpf(ctx->json_root, ctx->output.output_fp, JSON_PRESERVE_ORDER);
+ json_cmd_assoc_free();
+ json_decref(ctx->json_root);
+ ctx->json_root = NULL;
+ }
}