From 15ad64734a544a9af033e54d232f112971072c15 Mon Sep 17 00:00:00 2001 From: Alvaro Neira Ayuso Date: Mon, 9 Feb 2015 21:09:53 +0100 Subject: src: add command tag in JSON/XML export support Currently, we can't do incremental updates via JSON/XML. This patch enriches the existing output to indicate the kind of update that you want to perform. So, if we have a ruleset like: table ip filter { chain input { type filter hook input priority 0; } } The new output looks like: {"nftables":[{"add":[{"table":{"name":"filter",...}}]}]} ^^^^^ Where we explicitly indicate that we want to add a table. We support all the actions that we can do with nft, they are: - Add, delete and flush tables and chains. - Add, delete, replace and insert rules. - Add and delete sets. - Add and delete set elements. - Flush ruleset. You only need to add the command tag: {"nftables":[{"delete":[{...}, {...},...}]}]} ^^^^^^^^ The possible command tags that you can use are "add", "delete", "insert", "replace" and "flush". - Flush table or chain, eg.: {"nftables":[{"flush":[{"table":{"name":...}}]}]} - Delete table, chain, set or rule: {"nftables":[{"delete":[{"chain":{"name":...}]}]} - Replace a rule (you have to specify the handle): {"nftables":[{"replace":[{"rule":{...}}]}]} - Insert a rule: {"nftables":[{"insert":[{"rule":{...}}]}]} Signed-off-by: Alvaro Neira Ayuso Signed-off-by: Pablo Neira Ayuso --- src/common.c | 85 ++++++++++++++++++++++++++++-------------------------------- 1 file changed, 40 insertions(+), 45 deletions(-) (limited to 'src/common.c') diff --git a/src/common.c b/src/common.c index a6f2508..139be55 100644 --- a/src/common.c +++ b/src/common.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "internal.h" @@ -70,86 +71,80 @@ int nft_parse_perror(const char *msg, struct nft_parse_err *err) } EXPORT_SYMBOL(nft_parse_perror); -int nft_event_header_snprintf(char *buf, size_t size, uint32_t type, - uint32_t flags) +int nft_cmd_header_snprintf(char *buf, size_t size, uint32_t cmd, uint32_t type, + uint32_t flags) { - int ret = 0; + NFT_BUF_INIT(b, buf, size); - if (!(flags & NFT_OF_EVENT_ANY)) + if (cmd == NFT_CMD_UNSPEC) return 0; switch (type) { case NFT_OUTPUT_XML: - if (flags & NFT_OF_EVENT_NEW) { - ret = snprintf(buf, size, "new"); - } else if (flags & NFT_OF_EVENT_DEL) { - ret = snprintf(buf, size, - "delete"); - } else { - ret = snprintf(buf, size, - "unknown"); - } - break; case NFT_OUTPUT_JSON: - if (flags & NFT_OF_EVENT_NEW) { - ret = snprintf(buf, size, "{event:{type:\"new\",{\""); - } else if (flags & NFT_OF_EVENT_DEL) { - ret = snprintf(buf, size, - "{event:{type:\"delete\",{\""); - } else { - ret = snprintf(buf, size, - "{event:{type:\"unknown\",{\""); - } + nft_buf_open_array(&b, type, nft_cmd2tag(cmd)); break; default: - if (flags & NFT_OF_EVENT_NEW) { - ret = snprintf(buf, size, "%9s", "[NEW] "); - } else if (flags & NFT_OF_EVENT_DEL) { - ret = snprintf(buf, size, "%9s", "[DELETE] "); - } else { - ret = snprintf(buf, size, "%9s", "[unknown] "); + switch (cmd) { + case NFT_CMD_ADD: + return snprintf(buf, size, "%9s", "[ADD] "); + case NFT_CMD_DELETE: + return snprintf(buf, size, "%9s", "[DELETE] "); + default: + return snprintf(buf, size, "%9s", "[unknown] "); } break; } - return ret; + return nft_buf_done(&b); } -static int nft_event_header_fprintf_cb(char *buf, size_t size, void *unused, - uint32_t type, uint32_t flags) + + +static int nft_cmd_header_fprintf_cb(char *buf, size_t size, void *obj, + uint32_t cmd, uint32_t type, + uint32_t flags) { - return nft_event_header_snprintf(buf, size, type, flags); + return nft_cmd_header_snprintf(buf, size, cmd, type, flags); } -int nft_event_header_fprintf(FILE *fp, uint32_t type, uint32_t flags) +int nft_cmd_header_fprintf(FILE *fp, uint32_t cmd, uint32_t type, + uint32_t flags) { - return nft_fprintf(fp, NULL, type, flags, nft_event_header_fprintf_cb); + return nft_fprintf(fp, NULL, cmd, type, flags, + nft_cmd_header_fprintf_cb); } -int nft_event_footer_snprintf(char *buf, size_t size, uint32_t type, - uint32_t flags) +int nft_cmd_footer_snprintf(char *buf, size_t size, uint32_t cmd, uint32_t type, + uint32_t flags) { - if (!(flags & NFT_OF_EVENT_ANY)) + NFT_BUF_INIT(b, buf, size); + + if (cmd == NFT_CMD_UNSPEC) return 0; switch (type) { case NFT_OUTPUT_XML: - return snprintf(buf, size, ""); case NFT_OUTPUT_JSON: - return snprintf(buf, size, "}}}"); + nft_buf_close_array(&b, type, nft_cmd2tag(cmd)); + break; default: return 0; } + return nft_buf_done(&b); } -static int nft_event_footer_fprintf_cb(char *buf, size_t size, void *unused, - uint32_t type, uint32_t flags) +static int nft_cmd_footer_fprintf_cb(char *buf, size_t size, void *obj, + uint32_t cmd, uint32_t type, + uint32_t flags) { - return nft_event_footer_snprintf(buf, size, type, flags); + return nft_cmd_footer_snprintf(buf, size, cmd, type, flags); } -int nft_event_footer_fprintf(FILE *fp, uint32_t type, uint32_t flags) +int nft_cmd_footer_fprintf(FILE *fp, uint32_t cmd, uint32_t type, + uint32_t flags) { - return nft_fprintf(fp, NULL, type, flags, nft_event_footer_fprintf_cb); + return nft_fprintf(fp, NULL, cmd, type, flags, + nft_cmd_footer_fprintf_cb); } static void nft_batch_build_hdr(char *buf, uint16_t type, uint32_t seq) -- cgit v1.2.3