]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
src: support JSON format in chain, rule and expressions
authorÁlvaro Neira Ayuso <alvaroneay@gmail.com>
Thu, 27 Jun 2013 19:56:18 +0000 (21:56 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 29 Jun 2013 09:56:05 +0000 (11:56 +0200)
While at it, order possible switch cases of _snprintf.

Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
21 files changed:
include/libnftables/rule.h
src/chain.c
src/expr/bitwise.c
src/expr/byteorder.c
src/expr/cmp.c
src/expr/counter.c
src/expr/ct.c
src/expr/data_reg.c
src/expr/exthdr.c
src/expr/immediate.c
src/expr/limit.c
src/expr/log.c
src/expr/lookup.c
src/expr/match.c
src/expr/meta.c
src/expr/nat.c
src/expr/payload.c
src/expr/target.c
src/internal.h
src/rule.c
src/table.c

index fb6e80490c8ad58c75adc3eed3175b9f8b3db601..186c82cc42837a82c3a0544c21b8c21b2f7b9660 100644 (file)
@@ -44,6 +44,7 @@ void nft_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_rule *t);
 enum {
        NFT_RULE_O_DEFAULT      = 0,
        NFT_RULE_O_XML,
+       NFT_RULE_O_JSON,
 };
 
 enum nft_rule_parse_type {
index bdcfec252094f079a39eb33abd920d4d8ae1716e..68744bc229702a5026fce000ae5b712d2e2c58d4 100644 (file)
@@ -794,12 +794,12 @@ int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *c,
                       uint32_t type, uint32_t flags)
 {
        switch(type) {
-       case NFT_CHAIN_O_JSON:
-               return nft_chain_snprintf_json(buf, size, c);
-       case NFT_CHAIN_O_XML:
-               return nft_chain_snprintf_xml(buf, size, c);
        case NFT_CHAIN_O_DEFAULT:
                return nft_chain_snprintf_default(buf, size, c);
+       case NFT_CHAIN_O_XML:
+               return nft_chain_snprintf_xml(buf, size, c);
+       case NFT_CHAIN_O_JSON:
+               return nft_chain_snprintf_json(buf, size, c);
        default:
                break;
        }
index 80c4f2039484c7eb07f0edfb0b8e0b622bf1d0b4..6843086eabdaa086abcd918fe00d2f5c69d93a2a 100644 (file)
@@ -324,6 +324,37 @@ nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, char *xml)
 #endif
 }
 
+static int
+nft_rule_expr_bitwise_snprintf_json(char *buf, size_t size,
+                                  struct nft_expr_bitwise *bitwise)
+{
+       int len = size, offset = 0, ret;
+
+       ret = snprintf(buf, len, "\"sreg\" : %u, "
+                               "\"dreg\" : %u, ",
+                      bitwise->sreg, bitwise->dreg);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = snprintf(buf+offset, len, "\"mask\" : ");
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = nft_data_reg_snprintf(buf+offset, len, &bitwise->mask,
+                                   NFT_RULE_O_JSON, 0, DATA_VALUE);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = snprintf(buf+offset, len, ", \"xor\" : ");
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = nft_data_reg_snprintf(buf+offset, len, &bitwise->xor,
+                                   NFT_RULE_O_JSON, 0, DATA_VALUE);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = snprintf(buf+offset, len, "\"");
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
 static int
 nft_rule_expr_bitwise_snprintf_xml(char *buf, size_t size,
                                   struct nft_expr_bitwise *bitwise)
@@ -389,11 +420,13 @@ nft_rule_expr_bitwise_snprintf(char *buf, size_t size, uint32_t type,
        struct nft_expr_bitwise *bitwise = (struct nft_expr_bitwise *)e->data;
 
        switch(type) {
-       case NFT_RULE_O_XML:
-               return nft_rule_expr_bitwise_snprintf_xml(buf, size, bitwise);
        case NFT_RULE_O_DEFAULT:
                return nft_rule_expr_bitwise_snprintf_default(buf, size,
                                                              bitwise);
+       case NFT_RULE_O_XML:
+               return nft_rule_expr_bitwise_snprintf_xml(buf, size, bitwise);
+       case NFT_RULE_O_JSON:
+               return nft_rule_expr_bitwise_snprintf_json(buf, size, bitwise);
        default:
                break;
        }
index b0ba0095aa331b8e8f23da288832d7959b2dc565..bb47f10f44a78f86f16cda1c21a74ee7d026bda5 100644 (file)
@@ -297,6 +297,25 @@ err:
 #endif
 }
 
+static int
+nft_rule_expr_byteorder_snprintf_json(char *buf, size_t size,
+                                      struct nft_expr_byteorder *byteorder)
+{
+       int len = size, offset = 0, ret;
+
+       ret = snprintf(buf, len, "\"sreg\" : %u, "
+                                "\"dreg\" : %u, "
+                                "\"op\" : \"%s\", "
+                                "\"len\" : %u, "
+                                "\"size\" : %u",
+                      byteorder->sreg, byteorder->dreg,
+                      expr_byteorder_str[byteorder->op],
+                      byteorder->len, byteorder->size);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
 static int
 nft_rule_expr_byteorder_snprintf_xml(char *buf, size_t size,
                                   struct nft_expr_byteorder *byteorder)
@@ -344,6 +363,9 @@ nft_rule_expr_byteorder_snprintf(char *buf, size_t size, uint32_t type,
        case NFT_RULE_O_XML:
                return nft_rule_expr_byteorder_snprintf_xml(buf, size,
                                                            byteorder);
+       case NFT_RULE_O_JSON:
+               return nft_rule_expr_byteorder_snprintf_json(buf, size,
+                                                           byteorder);
        default:
                break;
        }
index 9507a0e2339ef1e63e7eaba1ff245211ab32f5d8..f92b3b6827ed13c1c6649d04e358bfa78b971c8e 100644 (file)
@@ -264,6 +264,25 @@ static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, char *xml)
 #endif
 }
 
+static int
+nft_rule_expr_cmp_snprintf_json(char *buf, size_t size, struct nft_expr_cmp *cmp)
+{
+       int len = size, offset = 0, ret;
+
+       ret = snprintf(buf, len, "\"sreg\" : %u, \"op\" : \"%s\", \"cmpdata\" : {",
+                      cmp->sreg, expr_cmp_str[cmp->op]);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = nft_data_reg_snprintf(buf+offset, len, &cmp->data,
+                                   NFT_RULE_O_JSON, 0, DATA_VALUE);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = snprintf(buf+offset, len, "}");
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
 static int
 nft_rule_expr_cmp_snprintf_xml(char *buf, size_t size, struct nft_expr_cmp *cmp)
 {
@@ -306,10 +325,12 @@ nft_rule_expr_cmp_snprintf(char *buf, size_t size, uint32_t type,
 {
        struct nft_expr_cmp *cmp = (struct nft_expr_cmp *)e->data;
        switch(type) {
-       case NFT_RULE_O_XML:
-               return nft_rule_expr_cmp_snprintf_xml(buf, size, cmp);
        case NFT_RULE_O_DEFAULT:
                return nft_rule_expr_cmp_snprintf_default(buf, size, cmp);
+       case NFT_RULE_O_XML:
+               return nft_rule_expr_cmp_snprintf_xml(buf, size, cmp);
+       case NFT_RULE_O_JSON:
+               return nft_rule_expr_cmp_snprintf_json(buf, size, cmp);
        default:
                break;
        }
index 77054e208291464bb8f2cb72db72cc38103d7f6d..62bd143a536475b8dd94718e569af2be83b5412d 100644 (file)
@@ -194,11 +194,14 @@ nft_rule_expr_counter_snprintf(char *buf, size_t len, uint32_t type,
        struct nft_expr_counter *ctr = (struct nft_expr_counter *)e->data;
 
        switch(type) {
+       case NFT_RULE_O_DEFAULT:
+               return snprintf(buf, len, "pkts=%lu bytes=%lu ",
+                               ctr->pkts, ctr->bytes);
        case NFT_RULE_O_XML:
                return snprintf(buf, len, "<pkts>%lu</pkts><bytes>%lu</bytes>",
                                ctr->pkts, ctr->bytes);
-       case NFT_RULE_O_DEFAULT:
-               return snprintf(buf, len, "pkts=%lu bytes=%lu ",
+       case NFT_RULE_O_JSON:
+               return snprintf(buf, len, "\"pkts\" : %lu, \"bytes\" : %lu",
                                ctr->pkts, ctr->bytes);
        default:
                break;
index e4ab3edb0b34817ddd65545f50b099251b6167f4..fcdabce0ba5dfa7abce34e937a21e3fd3aed3f54 100644 (file)
@@ -279,6 +279,11 @@ nft_rule_expr_ct_snprintf(char *buf, size_t len, uint32_t type,
                                          "<key>%s</key>"
                                          "<dir>%u</dir>",
                                ct->dreg, ctkey2str(ct->key), ct->dir);
+       case NFT_RULE_O_JSON:
+               return snprintf(buf, len, "\"dreg\" : %u, "
+                                         "\"key\" : \"%s\", "
+                                         "\"dir\" : %u",
+                               ct->dreg, ctkey2str(ct->key), ct->dir);
        default:
                break;
        }
index c123d882c53e53aa4fef1a945269c7ed7b0c2b6f..fd0549977bbba2bec53189637d1abe561fa3a3bc 100644 (file)
@@ -253,6 +253,44 @@ int nft_data_reg_xml_parse(union nft_data_reg *reg, char *xml)
 #endif
 }
 
+static int
+nft_data_reg_value_snprintf_json(char *buf, size_t size,
+                                          union nft_data_reg *reg,
+                                          uint32_t flags)
+{
+       int len = size, offset = 0, ret, i, j;
+       uint32_t utemp;
+       uint8_t *tmp;
+       int data_len = reg->len/sizeof(uint32_t);
+
+       ret = snprintf(buf, len, "\"data_reg\": { \"type\" : \"value\", ");
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = snprintf(buf+offset, len, "\"len\" : %zd, ", reg->len);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       for (i = 0; i<data_len; i++) {
+               ret = snprintf(buf+offset, len, "\"data%d\" : \"0x", i);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+               utemp = htonl(reg->val[i]);
+               tmp = (uint8_t *)&utemp;
+
+               for (j = 0; j<sizeof(uint32_t); j++) {
+                       ret = snprintf(buf+offset, len, "%.02x", tmp[j]);
+                       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+               }
+
+               ret = snprintf(buf+offset, len, "\"");
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+       }
+
+       ret = snprintf(buf+offset, len, "}");
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
 static
 int nft_data_reg_value_snprintf_xml(char *buf, size_t size,
                                    union nft_data_reg *reg, uint32_t flags)
@@ -310,36 +348,49 @@ int nft_data_reg_snprintf(char *buf, size_t size, union nft_data_reg *reg,
        switch(reg_type) {
        case DATA_VALUE:
                switch(output_format) {
-               case NFT_RULE_O_XML:
-                       return nft_data_reg_value_snprintf_xml(buf, size,
-                                                              reg, flags);
                case NFT_RULE_O_DEFAULT:
                        return nft_data_reg_value_snprintf_default(buf, size,
                                                                   reg, flags);
+               case NFT_RULE_O_XML:
+                       return nft_data_reg_value_snprintf_xml(buf, size,
+                                                              reg, flags);
+               case NFT_RULE_O_JSON:
+                       return nft_data_reg_value_snprintf_json(buf, size,
+                                                              reg, flags);
                default:
                        break;
                }
        case DATA_VERDICT:
                switch(output_format) {
+               case NFT_RULE_O_DEFAULT:
+                       return snprintf(buf, size, "verdict=%d", reg->verdict);
                case NFT_RULE_O_XML:
                        return snprintf(buf, size,
                                        "<data_reg type=\"verdict\">"
                                                "<verdict>%d</verdict>"
                                        "</data_reg>", reg->verdict);
-               case NFT_RULE_O_DEFAULT:
-                       return snprintf(buf, size, "verdict=%d", reg->verdict);
+               case NFT_RULE_O_JSON:
+                       return snprintf(buf, size,
+                                       "\"data_reg\": { \"type\" : \"verdict\", "
+                                               "\"verdict\" : %d"
+                                       "}", reg->verdict);
                default:
                        break;
                }
        case DATA_CHAIN:
                switch(output_format) {
+               case NFT_RULE_O_DEFAULT:
+                       return snprintf(buf, size, "chain=%s", reg->chain);
                case NFT_RULE_O_XML:
                        return snprintf(buf, size,
                                        "<data_reg type=\"chain\">"
                                                "<chain>%s</chain>"
                                        "</data_reg>", reg->chain);
-               case NFT_RULE_O_DEFAULT:
-                       return snprintf(buf, size, "chain=%s", reg->chain);
+               case NFT_RULE_O_JSON:
+                       return snprintf(buf, size,
+                                       "\"data_reg\": { \"type\" : \"chain\", "
+                                               "\"chain\" : %d"
+                                       "}", reg->verdict);
                default:
                        break;
                }
index a31f079f9ae029a294b21f78781055578af7071a..b4b9c1303a15a7f53560e96d5489a6306046aac7 100644 (file)
@@ -325,6 +325,10 @@ nft_rule_expr_exthdr_snprintf(char *buf, size_t len, uint32_t type,
        struct nft_expr_exthdr *exthdr = (struct nft_expr_exthdr *)e->data;
 
        switch(type) {
+       case NFT_RULE_O_DEFAULT:
+               return snprintf(buf, len, "dreg=%u type=%u offset=%u len=%u ",
+                               exthdr->dreg, exthdr->type,
+                               exthdr->offset, exthdr->len);
        case NFT_RULE_O_XML:
                return snprintf(buf, len, "<dreg>%u</dreg>"
                                          "<exthdr_type>%s</exthdr_type>"
@@ -333,11 +337,13 @@ nft_rule_expr_exthdr_snprintf(char *buf, size_t len, uint32_t type,
                                        exthdr->dreg,
                                        exthdr_type2str(exthdr->type),
                                        exthdr->offset, exthdr->len);
-
-       case NFT_RULE_O_DEFAULT:
-               return snprintf(buf, len, "dreg=%u type=%u offset=%u len=%u ",
-                               exthdr->dreg, exthdr->type,
-                               exthdr->offset, exthdr->len);
+       case NFT_RULE_O_JSON:
+               return snprintf(buf, len, "\"dreg\" : %u, "
+                                         "\"exthdr_type\" : \"%s\", \"offset\" : %u, "
+                                         "\"len\" : %u",
+                                       exthdr->dreg,
+                                       exthdr_type2str(exthdr->type),
+                                       exthdr->offset, exthdr->len);
        default:
                break;
        }
index 8bc810cfa4b5835eade773a1e8f9eba52f3b49cd..1937d82508d1f972947b2c6ad7073497210909ad 100644 (file)
@@ -299,6 +299,40 @@ nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, char *xml)
 #endif
 }
 
+static int
+nft_rule_expr_immediate_snprintf_json(char *buf, size_t len,
+                                    struct nft_rule_expr *e, uint32_t flags)
+{
+       int size = len, offset = 0, ret;
+       struct nft_expr_immediate *imm = (struct nft_expr_immediate *)e->data;
+
+       ret = snprintf(buf, len, "\"dreg\" : %u, "
+                               "\"immediatedata\" : {", imm->dreg);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+
+       if (e->flags & (1 << NFT_EXPR_IMM_DATA)) {
+               ret = nft_data_reg_snprintf(buf+offset, len, &imm->data,
+                                           NFT_RULE_O_JSON, flags, DATA_VALUE);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       } else if (e->flags & (1 << NFT_EXPR_IMM_VERDICT)) {
+               ret = nft_data_reg_snprintf(buf+offset, len, &imm->data,
+                                         NFT_RULE_O_JSON, flags, DATA_VERDICT);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       } else if (e->flags & (1 << NFT_EXPR_IMM_CHAIN)) {
+               ret = nft_data_reg_snprintf(buf+offset, len, &imm->data,
+                                           NFT_RULE_O_JSON, flags, DATA_CHAIN);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+       }
+
+       ret = snprintf(buf+offset, len, "}");
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
 static int
 nft_rule_expr_immediate_snprintf_xml(char *buf, size_t len,
                                     struct nft_rule_expr *e, uint32_t flags)
@@ -367,10 +401,12 @@ nft_rule_expr_immediate_snprintf(char *buf, size_t len, uint32_t type,
                                 uint32_t flags, struct nft_rule_expr *e)
 {
        switch(type) {
-       case NFT_RULE_O_XML:
-               return nft_rule_expr_immediate_snprintf_xml(buf, len, e, flags);
        case NFT_RULE_O_DEFAULT:
                return nft_rule_expr_immediate_snprintf_default(buf, len, e, flags);
+       case NFT_RULE_O_XML:
+               return nft_rule_expr_immediate_snprintf_xml(buf, len, e, flags);
+       case NFT_RULE_O_JSON:
+               return nft_rule_expr_immediate_snprintf_json(buf, len, e, flags);
        default:
                break;
        }
index d6dc9008620f68492fd8edf771a369328c23ffd6..1e843ce56076275da3316594e4448bc6e3d9aaa1 100644 (file)
@@ -195,6 +195,10 @@ nft_rule_expr_limit_snprintf(char *buf, size_t len, uint32_t type,
                return snprintf(buf, len, "<rate>%"PRIu64"</rate>"
                                          "<depth>%"PRIu64"</depth>",
                                limit->rate, limit->depth);
+       case NFT_RULE_O_JSON:
+               return snprintf(buf, len, "\"rate\" : %"PRIu64", "
+                                         "\"depth\" : %"PRIu64" ",
+                               limit->rate, limit->depth);
        default:
                break;
        }
index 2d93b2ae41bdfdeacace1ec68bd9ede29863ead3..8dc5201e766716bddd13510e717b3a7e6eb7856e 100644 (file)
@@ -263,6 +263,13 @@ nft_rule_expr_log_snprintf(char *buf, size_t len, uint32_t type,
                                          "<qthreshold>%u</qthreshold>",
                                log->prefix, log->group,
                                log->snaplen, log->qthreshold);
+       case NFT_RULE_O_JSON:
+               return snprintf(buf, len, "\"prefix\" : \"%s\", "
+                                         "\"group\" : %u, "
+                                         "\"snaplen\" : %u, "
+                                         "\"qthreshold\" : %u ",
+                               log->prefix, log->group,
+                               log->snaplen, log->qthreshold);
        default:
                break;
        }
index ecc07cb999cb0a83271c0f86c7d5fece494b92af..8591d4e56e650ea85018f74eb45b2778ed97b5ce 100644 (file)
@@ -238,6 +238,20 @@ nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, char *xml)
 #endif
 }
 
+static int
+nft_rule_expr_lookup_snprintf_json(char *buf, size_t size,
+                                 struct nft_expr_lookup *l)
+{
+       int len = size, offset = 0, ret;
+
+       ret = snprintf(buf, len, "\"set\" : \"%s\", \"sreg\" : %u, \"dreg\" : %u",
+                       l->set_name, l->sreg, l->dreg);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
+
 static int
 nft_rule_expr_lookup_snprintf_xml(char *buf, size_t size,
                                  struct nft_expr_lookup *l)
@@ -271,10 +285,12 @@ nft_rule_expr_lookup_snprintf(char *buf, size_t size, uint32_t type,
        struct nft_expr_lookup *lookup = (struct nft_expr_lookup *)e->data;
 
        switch(type) {
-       case NFT_RULE_O_XML:
-               return nft_rule_expr_lookup_snprintf_xml(buf, size, lookup);
        case NFT_RULE_O_DEFAULT:
                return nft_rule_expr_lookup_snprintf_default(buf, size, lookup);
+       case NFT_RULE_O_XML:
+               return nft_rule_expr_lookup_snprintf_xml(buf, size, lookup);
+       case NFT_RULE_O_JSON:
+               return nft_rule_expr_lookup_snprintf_json(buf, size, lookup);
        default:
                break;
        }
index 7b4377fcda6efa8c8965a5c0e839dce772f98bf1..7d0f07805e54ded347359c6080efe98c814800d6 100644 (file)
@@ -226,6 +226,18 @@ static int nft_rule_expr_match_xml_parse(struct nft_rule_expr *e, char *xml)
 #endif
 }
 
+static int nft_rule_expr_match_snprintf_json(char *buf, size_t len,
+                                           struct nft_expr_match *mt)
+{
+       int ret, size = len, offset = 0;
+
+       ret = snprintf(buf, len, "\"name\" : \"%s\"",
+                               mt->name);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
 static int nft_rule_expr_match_snprintf_xml(char *buf, size_t len,
                                            struct nft_expr_match *mt)
 {
@@ -246,11 +258,13 @@ nft_rule_expr_match_snprintf(char *buf, size_t len, uint32_t type,
        struct nft_expr_match *match = (struct nft_expr_match *)e->data;
 
        switch(type) {
-       case NFT_RULE_O_XML:
-               return nft_rule_expr_match_snprintf_xml(buf, len, match);
        case NFT_RULE_O_DEFAULT:
                return snprintf(buf, len, "name=%s rev=%u ",
                                match->name, match->rev);
+       case NFT_RULE_O_XML:
+               return nft_rule_expr_match_snprintf_xml(buf, len, match);
+       case NFT_RULE_O_JSON:
+               return nft_rule_expr_match_snprintf_json(buf, len, match);
        default:
                break;
        }
index d5d297bf263fb0d9a734a9bb3c90b1fa28a031b1..1a609cf95df75fc265a1ba176f713e373b3b0053 100644 (file)
@@ -246,13 +246,17 @@ nft_rule_expr_meta_snprintf(char *buf, size_t len, uint32_t type,
        struct nft_expr_meta *meta = (struct nft_expr_meta *)e->data;
 
        switch(type) {
+       case NFT_RULE_O_DEFAULT:
+               return snprintf(buf, len, "dreg=%u key=%u ",
+                               meta->dreg, meta->key);
        case NFT_RULE_O_XML:
                return snprintf(buf, len, "<dreg>%u</dreg>"
                                          "<key>%s</key>",
                                meta->dreg, meta_key2str(meta->key));
-       case NFT_RULE_O_DEFAULT:
-               return snprintf(buf, len, "dreg=%u key=%u ",
-                               meta->dreg, meta->key);
+       case NFT_RULE_O_JSON:
+               return snprintf(buf, len, "\"dreg\" : %u, "
+                                         "\"key\" : %s",
+                               meta->dreg, meta_key2str(meta->key));
        default:
                break;
        }
index 506c0b1e8ccf4f7b69309d1a907040993092a2c2..b753069aac8b7b4bee9e7ffa6f68d574f3120ef7 100644 (file)
@@ -327,6 +327,44 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, char *xml)
 #endif
 }
 
+static int
+nft_rule_expr_nat_snprintf_json(char *buf, size_t size,
+                               struct nft_rule_expr *e)
+{
+       struct nft_expr_nat *nat = (struct nft_expr_nat *)e->data;
+       int len = size, offset = 0, ret = 0;
+
+       if (nat->type == NFT_NAT_SNAT)
+               ret = snprintf(buf, len, "\"nat_type\" : \"snat\", ");
+       else if (nat->type == NFT_NAT_DNAT)
+               ret = snprintf(buf, len, "\nat_type\" : \"dnat\", ");
+
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = snprintf(buf+offset, len, "\"family\" : \"%s\", ",
+                      nft_family2str(nat->family));
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       if (e->flags & (1 << NFT_EXPR_NAT_REG_ADDR_MIN)) {
+               ret = snprintf(buf+offset, len,
+                               "\"sreg_addr_min\" : %u, "
+                               "\"sreg_addr_max\" : %u, ",
+                              nat->sreg_addr_min, nat->sreg_addr_max);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+       }
+
+       if (e->flags & (1 << NFT_EXPR_NAT_REG_PROTO_MIN)) {
+               ret = snprintf(buf+offset, len,
+                               "\"sreg_proto_min\" : %u, "
+                               "\"sreg_proto_max\" : %u",
+                      nat->sreg_proto_min, nat->sreg_proto_max);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+       }
+
+       return offset;
+}
+
+
 static int
 nft_rule_expr_nat_snprintf_xml(char *buf, size_t size,
                                struct nft_rule_expr *e)
@@ -410,10 +448,12 @@ nft_rule_expr_nat_snprintf(char *buf, size_t size, uint32_t type,
                           uint32_t flags, struct nft_rule_expr *e)
 {
        switch (type) {
-       case NFT_RULE_O_XML:
-               return nft_rule_expr_nat_snprintf_xml(buf, size, e);
        case NFT_RULE_O_DEFAULT:
                return nft_rule_expr_nat_snprintf_default(buf, size, e);
+       case NFT_RULE_O_XML:
+               return nft_rule_expr_nat_snprintf_xml(buf, size, e);
+       case NFT_RULE_O_JSON:
+               return nft_rule_expr_nat_snprintf_json(buf, size, e);
        default:
                break;
        }
index ae72fa2bf014ff0bf9bd87bf5ad575f0ffc2597d..2111c47c6633a213555c4625a658ea25e0db6dc4 100644 (file)
@@ -166,6 +166,36 @@ nft_rule_expr_payload_parse(struct nft_rule_expr *e, struct nlattr *attr)
        return 0;
 }
 
+static int
+nft_rule_expr_payload_snprintf_json(char *buf, size_t len, uint32_t flags,
+                                  struct nft_expr_payload *p)
+{
+       int size = len, offset = 0, ret;
+
+       ret = snprintf(buf, len, "\"dreg\" : %u, \"offset\" : %u, \"len\" : %u, ",
+                                       p->dreg, p->offset, p->len);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       switch (p->base) {
+       case NFT_PAYLOAD_LL_HEADER:
+               ret = snprintf(buf+offset, len, "\"base\" : \"link\"");
+               break;
+       case NFT_PAYLOAD_NETWORK_HEADER:
+               ret = snprintf(buf+offset, len, "\"base\" : \"network\"");
+               break;
+       case NFT_PAYLOAD_TRANSPORT_HEADER:
+               ret = snprintf(buf+offset, len, "\"base\" : \"transport\"");
+               break;
+       default:
+               ret = snprintf(buf+offset, len, "\"base\" : \"unknown\"");
+               break;
+       }
+
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
 static int
 nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, char *xml)
 {
@@ -304,13 +334,16 @@ nft_rule_expr_payload_snprintf(char *buf, size_t len, uint32_t type,
        struct nft_expr_payload *payload = (struct nft_expr_payload *)e->data;
 
        switch(type) {
-       case NFT_RULE_O_XML:
-               return nft_rule_expr_payload_snprintf_xml(buf, len, flags,
-                                                         payload);
        case NFT_RULE_O_DEFAULT:
                return snprintf(buf, len, "dreg=%u base=%u offset=%u len=%u ",
                                payload->dreg, payload->base,
                                payload->offset, payload->len);
+       case NFT_RULE_O_XML:
+               return nft_rule_expr_payload_snprintf_xml(buf, len, flags,
+                                                         payload);
+       case NFT_RULE_O_JSON:
+               return nft_rule_expr_payload_snprintf_json(buf, len, flags,
+                                                         payload);
        default:
                break;
        }
index ed29f6d240850ee1bda2e79c3741a29c567e22ea..0ad39d59d671a224bca2b14208f415aff604194a 100644 (file)
@@ -227,6 +227,19 @@ nft_rule_expr_target_xml_parse(struct nft_rule_expr *e, char *xml)
 #endif
 }
 
+static
+int nft_rule_exp_target_snprintf_json(char *buf, size_t len,
+                               struct nft_expr_target *tg)
+{
+       int ret, size = len, offset = 0;
+
+       ret = snprintf(buf, len, "\"name\" : \"%s\"",
+                       tg->name);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
 static
 int nft_rule_exp_target_snprintf_xml(char *buf, size_t len,
                                struct nft_expr_target *tg)
@@ -247,11 +260,13 @@ nft_rule_expr_target_snprintf(char *buf, size_t len, uint32_t type,
        struct nft_expr_target *target = (struct nft_expr_target *)e->data;
 
        switch(type) {
-       case NFT_RULE_O_XML:
-               return nft_rule_exp_target_snprintf_xml(buf, len, target);
        case NFT_RULE_O_DEFAULT:
                return snprintf(buf, len, "name=%s rev=%u ",
                                target->name, target->rev);
+       case NFT_RULE_O_XML:
+               return nft_rule_exp_target_snprintf_xml(buf, len, target);
+       case NFT_RULE_O_JSON:
+               return nft_rule_exp_target_snprintf_json(buf, len, target);
        default:
                break;
        }
index 23a3e5903d7276e06cb1845a2bcd9ccc80917dd5..55505be2ce7375df8958e29c8dc9c6d233e2be05 100644 (file)
@@ -22,6 +22,7 @@
 #define NFT_RULE_XML_VERSION 0
 #define NFT_TABLE_JSON_VERSION 0
 #define NFT_CHAIN_JSON_VERSION 0
+#define NFT_RULE_JSON_VERSION 0
 
 const char *nft_family2str(uint32_t family);
 int nft_str2family(const char *family);
index e792169a8ba2d1ce32fbed6198254a3da54a62ea..5e9b16d525419f50e05ed35e76e99fe4144d03e4 100644 (file)
@@ -668,6 +668,52 @@ int nft_rule_parse(struct nft_rule *r, enum nft_rule_parse_type type, char *data
 }
 EXPORT_SYMBOL(nft_rule_parse);
 
+static int nft_rule_snprintf_json(char *buf, size_t size, struct nft_rule *r,
+                                        uint32_t type, uint32_t flags)
+{
+       int ret, len = size, offset = 0;
+       struct nft_rule_expr *expr;
+
+       ret = snprintf(buf, size,
+                               "{ \"rule\": { \"family\" : \"%s\", \"table\" : \"%s\", "
+                               "\"chain\"  : \"%s\", \"handle\" : %llu, \"version\" : %d, ",
+                               nft_family2str(r->family), r->table, r->chain,
+                               (unsigned long long)r->handle,
+                               NFT_RULE_JSON_VERSION);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = snprintf(buf+offset, len, "\"rule_flags\" : %u, ",
+                                       r->rule_flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       if(NFT_RULE_ATTR_COMPAT_PROTO != 0 || NFT_RULE_ATTR_COMPAT_FLAGS != 0){
+               ret = snprintf(buf+offset,len,"\"compat_flags\" : %u, "
+                                                                         "\"compat_proto\" : %u, ",
+                                       r->compat.flags, r->compat.proto);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+       }
+
+       ret = snprintf(buf+offset, len, "\"expr\" : [");
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       list_for_each_entry(expr, &r->expr_list, head) {
+               ret = snprintf(buf+offset, len,
+                               " { \"type\" : \"%s\", ", expr->ops->name);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+               ret = expr->ops->snprintf(buf+offset, len, type, flags, expr);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+               ret = snprintf(buf+offset, len, "},");
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       }
+       ret = snprintf(buf+offset-1, len, "]}}");
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
 static int nft_rule_snprintf_xml(char *buf, size_t size, struct nft_rule *r,
                                 uint32_t type, uint32_t flags)
 {
@@ -739,10 +785,12 @@ int nft_rule_snprintf(char *buf, size_t size, struct nft_rule *r,
                       uint32_t type, uint32_t flags)
 {
        switch(type) {
-       case NFT_RULE_O_XML:
-               return nft_rule_snprintf_xml(buf, size, r, type, flags);
        case NFT_RULE_O_DEFAULT:
                return nft_rule_snprintf_default(buf, size, r, type, flags);
+       case NFT_RULE_O_XML:
+               return nft_rule_snprintf_xml(buf, size, r, type, flags);
+       case NFT_RULE_O_JSON:
+               return nft_rule_snprintf_json(buf, size, r, type, flags);
        default:
                break;
        }
index dc0c2a1c15f754e96e356210ec2c8dcb5a240e30..982d101fb30532a71adcc8111046ef04705edaf2 100644 (file)
@@ -367,12 +367,12 @@ int nft_table_snprintf(char *buf, size_t size, struct nft_table *t,
                       uint32_t type, uint32_t flags)
 {
        switch(type) {
+       case NFT_TABLE_O_DEFAULT:
+               return nft_table_snprintf_default(buf, size, t);
        case NFT_TABLE_O_XML:
                return nft_table_snprintf_xml(buf, size, t);
        case NFT_TABLE_O_JSON:
                return nft_table_snprintf_json(buf, size, t);
-       case NFT_TABLE_O_DEFAULT:
-               return nft_table_snprintf_default(buf, size, t);
        default:
                break;
        }