From c83c53a26de25c1e2900f7841647cec3b57c7438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Neira=20Ayuso?= Date: Tue, 20 Aug 2013 17:58:46 +0200 Subject: rule: Add json parser support Add function for parsing rules in JSON format Signed-off-by: Alvaro Neira Ayuso Signed-off-by: Pablo Neira Ayuso --- src/expr/bitwise.c | 45 ++++++++++++++++++++++++++++++ src/expr/byteorder.c | 50 ++++++++++++++++++++++++++++++++++ src/expr/cmp.c | 38 ++++++++++++++++++++++++++ src/expr/counter.c | 26 ++++++++++++++++++ src/expr/ct.c | 49 +++++++++++++++++++++++++++++++++ src/expr/data_reg.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/expr/data_reg.h | 5 ++++ src/expr/exthdr.c | 43 +++++++++++++++++++++++++++++ src/expr/immediate.c | 40 +++++++++++++++++++++++++++ src/expr/limit.c | 25 +++++++++++++++++ src/expr/log.c | 39 ++++++++++++++++++++++++++ src/expr/lookup.c | 31 +++++++++++++++++++++ src/expr/match.c | 22 ++++++++++++++- src/expr/meta.c | 34 ++++++++++++++++++++++- src/expr/nat.c | 59 ++++++++++++++++++++++++++++++++++++++++ src/expr/payload.c | 43 +++++++++++++++++++++++++++++ src/expr/target.c | 20 ++++++++++++++ 17 files changed, 644 insertions(+), 2 deletions(-) (limited to 'src/expr') diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c index 6c86acb..8cea075 100644 --- a/src/expr/bitwise.c +++ b/src/expr/bitwise.c @@ -180,6 +180,50 @@ nft_rule_expr_bitwise_parse(struct nft_rule_expr *e, struct nlattr *attr) return ret; } +static int +nft_rule_expr_bitwise_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + struct nft_expr_bitwise *bitwise = nft_expr_data(e); + uint32_t reg, len; + + if (nft_jansson_value_parse_reg(root, "sreg", NFT_TYPE_U32, ®) == -1) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_SREG, reg); + + if (nft_jansson_value_parse_reg(root, "dreg", NFT_TYPE_U32, ®) == -1) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_DREG, reg); + + if (nft_jansson_value_parse_val(root, "len", NFT_TYPE_U32, &len) == -1) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_LEN, len); + + if (nft_jansson_data_reg_parse(root, "mask", + &bitwise->mask) != DATA_VALUE) + return -1; + + e->flags |= (1 << NFT_EXPR_BITWISE_MASK); + + if (nft_jansson_data_reg_parse(root, "xor", + &bitwise->xor) != DATA_VALUE) + return -1; + + e->flags |= (1 << NFT_EXPR_BITWISE_XOR); + + if (bitwise->mask.len != bitwise->xor.len) + return -1; + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { @@ -349,6 +393,7 @@ struct expr_ops expr_ops_bitwise = { .build = nft_rule_expr_bitwise_build, .snprintf = nft_rule_expr_bitwise_snprintf, .xml_parse = nft_rule_expr_bitwise_xml_parse, + .json_parse = nft_rule_expr_bitwise_json_parse, }; static void __init expr_bitwise(void) diff --git a/src/expr/byteorder.c b/src/expr/byteorder.c index e2d442c..f596ff3 100644 --- a/src/expr/byteorder.c +++ b/src/expr/byteorder.c @@ -193,6 +193,55 @@ static inline int nft_str2ntoh(const char *op) } } +static int +nft_rule_expr_byteorder_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + const char *op; + uint32_t uval32; + int ntoh; + + if (nft_jansson_value_parse_reg(root, "sreg", NFT_TYPE_U32, + &uval32) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_SREG, uval32); + + if (nft_jansson_value_parse_reg(root, "dreg", NFT_TYPE_U32, + &uval32) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_DREG, uval32); + + op = nft_jansson_value_parse_str(root, "op"); + if (op == NULL) + return -1; + + ntoh = nft_str2ntoh(op); + if (ntoh < 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_OP, ntoh); + + if (nft_jansson_value_parse_val(root, "len", NFT_TYPE_U32, + &uval32) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_LEN, uval32); + + if (nft_jansson_value_parse_val(root, "size", NFT_TYPE_U32, + &uval32) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_SIZE, uval32); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { @@ -329,6 +378,7 @@ struct expr_ops expr_ops_byteorder = { .build = nft_rule_expr_byteorder_build, .snprintf = nft_rule_expr_byteorder_snprintf, .xml_parse = nft_rule_expr_byteorder_xml_parse, + .json_parse = nft_rule_expr_byteorder_json_parse, }; static void __init expr_byteorder_init(void) diff --git a/src/expr/cmp.c b/src/expr/cmp.c index 8ca4cb5..16be540 100644 --- a/src/expr/cmp.c +++ b/src/expr/cmp.c @@ -174,6 +174,43 @@ static inline int nft_str2cmp(const char *op) } } +static int nft_rule_expr_cmp_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + struct nft_expr_cmp *cmp = nft_expr_data(e); + const char *op; + uint32_t uval32; + int base; + + if (nft_jansson_value_parse_val(root, "sreg", NFT_TYPE_U32, + &uval32) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_CMP_SREG, uval32); + + op = nft_jansson_value_parse_str(root, "op"); + if (op == NULL) + return -1; + + base = nft_str2cmp(op); + if (base < 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_CMP_OP, base); + + if (nft_jansson_data_reg_parse(root, "cmpdata", + &cmp->data) != DATA_VALUE) + return -1; + + e->flags |= (1 << NFT_EXPR_CMP_DATA); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { #ifdef XML_PARSING @@ -296,6 +333,7 @@ struct expr_ops expr_ops_cmp = { .build = nft_rule_expr_cmp_build, .snprintf = nft_rule_expr_cmp_snprintf, .xml_parse = nft_rule_expr_cmp_xml_parse, + .json_parse = nft_rule_expr_cmp_json_parse, }; static void __init expr_cmp_init(void) { diff --git a/src/expr/counter.c b/src/expr/counter.c index 75ad469..6cdd637 100644 --- a/src/expr/counter.c +++ b/src/expr/counter.c @@ -118,6 +118,31 @@ nft_rule_expr_counter_parse(struct nft_rule_expr *e, struct nlattr *attr) return 0; } +static int +nft_rule_expr_counter_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + uint64_t uval64; + + if (nft_jansson_value_parse_val(root, "pkts", NFT_TYPE_U64, + &uval64) != 0) + return -1; + + nft_rule_expr_set_u64(e, NFT_EXPR_CTR_PACKETS, uval64); + + if (nft_jansson_value_parse_val(root, "bytes", NFT_TYPE_U64, + &uval64) != 0) + return -1; + + nft_rule_expr_set_u64(e, NFT_EXPR_CTR_BYTES, uval64); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_rule_expr_counter_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { @@ -175,6 +200,7 @@ struct expr_ops expr_ops_counter = { .build = nft_rule_expr_counter_build, .snprintf = nft_rule_expr_counter_snprintf, .xml_parse = nft_rule_expr_counter_xml_parse, + .json_parse = nft_rule_expr_counter_json_parse, }; static void __init expr_counter_init(void) diff --git a/src/expr/ct.c b/src/expr/ct.c index f86fd4d..c131e67 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -178,6 +178,54 @@ static inline int str2ctkey(const char *ctkey) return -1; } +static int nft_rule_expr_ct_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + const char *key_str; + uint32_t reg; + uint8_t dir; + int key; + + if (nft_jansson_value_parse_reg(root, "dreg", NFT_TYPE_U32, ®) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_CT_DREG, reg); + + if (nft_jansson_node_exist(root, "key")) { + key_str = nft_jansson_value_parse_str(root, "key"); + if (key_str == NULL) + return -1; + + key = str2ctkey(key_str); + if (key < 0) + goto err; + + nft_rule_expr_set_u32(e, NFT_EXPR_CT_KEY, key); + + } + + if (nft_jansson_node_exist(root, "dir")) { + if (nft_jansson_value_parse_val(root, "dir", NFT_TYPE_U8, + &dir) != 0) + return -1; + + if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY) + goto err; + + nft_rule_expr_set_u8(e, NFT_EXPR_CT_DIR, dir); + } + + return 0; +err: + errno = EINVAL; + return -1; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + + static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { #ifdef XML_PARSING @@ -282,6 +330,7 @@ struct expr_ops expr_ops_ct = { .build = nft_rule_expr_ct_build, .snprintf = nft_rule_expr_ct_snprintf, .xml_parse = nft_rule_expr_ct_xml_parse, + .json_parse = nft_rule_expr_ct_json_parse, }; static void __init expr_ct_init(void) diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c index 4c354ef..d0e1a83 100644 --- a/src/expr/data_reg.c +++ b/src/expr/data_reg.c @@ -26,6 +26,83 @@ #include "data_reg.h" #include "internal.h" +#ifdef JSON_PARSING +static int nft_data_reg_verdict_json_parse(union nft_data_reg *reg, json_t *data) +{ + int verdict; + const char *verdict_str; + + verdict_str = nft_jansson_value_parse_str(data, "verdict"); + if (verdict_str == NULL) + return -1; + + verdict = nft_str2verdict(verdict_str); + if (verdict < 0) + return -1; + + reg->verdict = (uint32_t)verdict; + + return 0; +} + +static int nft_data_reg_chain_json_parse(union nft_data_reg *reg, json_t *data) +{ + reg->chain = strdup(nft_jansson_value_parse_str(data, "chain")); + if (reg->chain == NULL) { + return -1; + } + + return 0; +} + +static int nft_data_reg_value_json_parse(union nft_data_reg *reg, json_t *data) +{ + int i; + char node_name[6]; + + if (nft_jansson_value_parse_val(data, "len", NFT_TYPE_U8, + ®->len) != 0) + return -1; + + for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) { + sprintf(node_name, "data%d", i); + + if (nft_jansson_str2num(data, node_name, BASE_HEX, + ®->val[i], NFT_TYPE_U32) != 0) + return -1; + } + + return 0; +} +#endif + +int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data) +{ +#ifdef JSON_PARSING + + const char *type; + + type = nft_jansson_value_parse_str(data, "type"); + if (type == NULL) { + return -1; + } + + /* Select what type of parsing is needed */ + if (strcmp(type, "value") == 0) { + return nft_data_reg_value_json_parse(reg, data); + } else if (strcmp(type, "verdict") == 0) { + return nft_data_reg_verdict_json_parse(reg, data); + } else if (strcmp(type, "chain") == 0) { + return nft_data_reg_chain_json_parse(reg, data); + } + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + #ifdef XML_PARSING static int nft_data_reg_verdict_xml_parse(union nft_data_reg *reg, char *xml) { diff --git a/src/expr/data_reg.h b/src/expr/data_reg.h index 9aee11f..7819919 100644 --- a/src/expr/data_reg.h +++ b/src/expr/data_reg.h @@ -18,9 +18,14 @@ union nft_data_reg { }; }; +#ifndef JSON_PARSING +#define json_t void +#endif + int nft_data_reg_snprintf(char *buf, size_t size, union nft_data_reg *reg, uint32_t output_format, uint32_t flags, int reg_type); int nft_data_reg_xml_parse(union nft_data_reg *reg, char *xml); int nft_parse_data(union nft_data_reg *data, struct nlattr *attr, int *type); +int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data); #endif diff --git a/src/expr/exthdr.c b/src/expr/exthdr.c index 9781232..8d4e8b7 100644 --- a/src/expr/exthdr.c +++ b/src/expr/exthdr.c @@ -192,6 +192,48 @@ static inline int str2exthdr_type(const char *str) return -1; } +static int +nft_rule_expr_exthdr_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + const char *exthdr_type; + uint32_t uval32; + int type; + + if (nft_jansson_value_parse_reg(root, "dreg", NFT_TYPE_U32, + &uval32) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_EXTHDR_DREG, uval32); + + exthdr_type = nft_jansson_value_parse_str(root, "exthdr_type"); + if (exthdr_type == NULL) + return -1; + + type = str2exthdr_type(exthdr_type); + if (type < 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_EXTHDR_TYPE, type); + + if (nft_jansson_value_parse_val(root, "offset", NFT_TYPE_U32, + &uval32) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_EXTHDR_OFFSET, uval32); + + if (nft_jansson_value_parse_val(root, "len", NFT_TYPE_U32, + &uval32) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_EXTHDR_LEN, uval32); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} static int nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) @@ -284,6 +326,7 @@ struct expr_ops expr_ops_exthdr = { .build = nft_rule_expr_exthdr_build, .snprintf = nft_rule_expr_exthdr_snprintf, .xml_parse = nft_rule_expr_exthdr_xml_parse, + .json_parse = nft_rule_expr_exthdr_json_parse, }; static void __init expr_exthdr_init(void) diff --git a/src/expr/immediate.c b/src/expr/immediate.c index 2061172..d548b75 100644 --- a/src/expr/immediate.c +++ b/src/expr/immediate.c @@ -177,6 +177,45 @@ nft_rule_expr_immediate_parse(struct nft_rule_expr *e, struct nlattr *attr) return ret; } +static int +nft_rule_expr_immediate_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + struct nft_expr_immediate *imm = nft_expr_data(e); + int datareg_type; + uint32_t reg; + + if (nft_jansson_value_parse_reg(root, "dreg", NFT_TYPE_U32, ®) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_IMM_DREG, reg); + + datareg_type = nft_jansson_data_reg_parse(root, "immediatedata", + &imm->data); + if (datareg_type < 0) + return -1; + + switch (datareg_type) { + case DATA_VALUE: + e->flags |= (1 << NFT_EXPR_IMM_DATA); + break; + case DATA_VERDICT: + e->flags |= (1 << NFT_EXPR_IMM_VERDICT); + break; + case DATA_CHAIN: + e->flags |= (1 << NFT_EXPR_IMM_CHAIN); + break; + default: + return -1; + } + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { @@ -342,6 +381,7 @@ struct expr_ops expr_ops_immediate = { .build = nft_rule_expr_immediate_build, .snprintf = nft_rule_expr_immediate_snprintf, .xml_parse = nft_rule_expr_immediate_xml_parse, + .json_parse = nft_rule_expr_immediate_json_parse, }; static void __init expr_immediate_init(void) diff --git a/src/expr/limit.c b/src/expr/limit.c index 336bdb0..d65c0a9 100644 --- a/src/expr/limit.c +++ b/src/expr/limit.c @@ -118,6 +118,30 @@ nft_rule_expr_limit_parse(struct nft_rule_expr *e, struct nlattr *attr) return 0; } +static int nft_rule_expr_limit_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + uint64_t uval64; + + if (nft_jansson_value_parse_val(root, "rate", NFT_TYPE_U64, + &uval64) != 0) + return -1; + + nft_rule_expr_set_u64(e, NFT_EXPR_LIMIT_RATE, uval64); + + if (nft_jansson_value_parse_val(root, "depth", NFT_TYPE_U64, + &uval64) != 0) + return -1; + + nft_rule_expr_set_u64(e, NFT_EXPR_LIMIT_DEPTH, uval64); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_rule_expr_limit_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { #ifdef XML_PARSING @@ -176,6 +200,7 @@ struct expr_ops expr_ops_limit = { .build = nft_rule_expr_limit_build, .snprintf = nft_rule_expr_limit_snprintf, .xml_parse = nft_rule_expr_limit_xml_parse, + .json_parse = nft_rule_expr_limit_json_parse, }; static void __init expr_limit_init(void) diff --git a/src/expr/log.c b/src/expr/log.c index 38b59f1..1dfea1b 100644 --- a/src/expr/log.c +++ b/src/expr/log.c @@ -156,6 +156,44 @@ nft_rule_expr_log_parse(struct nft_rule_expr *e, struct nlattr *attr) return 0; } +static int nft_rule_expr_log_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + const char *prefix; + uint32_t snaplen; + uint16_t uval16; + + prefix = nft_jansson_value_parse_str(root, "prefix"); + if (prefix == NULL) + return -1; + + nft_rule_expr_set_str(e, NFT_EXPR_LOG_PREFIX, prefix); + + if (nft_jansson_value_parse_val(root, "group", NFT_TYPE_U16, + &uval16) != 0) + return -1; + + nft_rule_expr_set_u16(e, NFT_EXPR_LOG_GROUP, uval16); + + if (nft_jansson_value_parse_val(root, "snaplen", NFT_TYPE_U32, + &snaplen) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_LOG_SNAPLEN, snaplen); + + if (nft_jansson_value_parse_val(root, "qthreshold", NFT_TYPE_U16, + &uval16) != 0) + return -1; + + nft_rule_expr_set_u16(e, NFT_EXPR_LOG_QTHRESHOLD, uval16); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_rule_expr_log_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { #ifdef XML_PARSING @@ -236,6 +274,7 @@ struct expr_ops expr_ops_log = { .build = nft_rule_expr_log_build, .snprintf = nft_rule_expr_log_snprintf, .xml_parse = nft_rule_expr_log_xml_parse, + .json_parse = nft_rule_expr_log_json_parse, }; static void __init expr_log_init(void) diff --git a/src/expr/lookup.c b/src/expr/lookup.c index d66577b..34f484c 100644 --- a/src/expr/lookup.c +++ b/src/expr/lookup.c @@ -142,6 +142,36 @@ nft_rule_expr_lookup_parse(struct nft_rule_expr *e, struct nlattr *attr) return ret; } +static int +nft_rule_expr_lookup_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + const char *set_name; + int32_t reg; + + set_name = nft_jansson_value_parse_str(root, "set"); + if (set_name == NULL) + return -1; + + nft_rule_expr_set_str(e, NFT_EXPR_LOOKUP_SET, set_name); + + if (nft_jansson_value_parse_reg(root, "sreg", NFT_TYPE_U32, ®) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_SREG, reg); + + if (nft_jansson_value_parse_reg(root, "dreg", NFT_TYPE_U32, ®) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_DREG, reg); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { @@ -248,6 +278,7 @@ struct expr_ops expr_ops_lookup = { .build = nft_rule_expr_lookup_build, .snprintf = nft_rule_expr_lookup_snprintf, .xml_parse = nft_rule_expr_lookup_xml_parse, + .json_parse = nft_rule_expr_lookup_json_parse, }; static void __init expr_lookup_init(void) diff --git a/src/expr/match.c b/src/expr/match.c index d155bb3..763e11e 100644 --- a/src/expr/match.c +++ b/src/expr/match.c @@ -170,6 +170,25 @@ static int nft_rule_expr_match_parse(struct nft_rule_expr *e, struct nlattr *att return 0; } +static int nft_rule_expr_match_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + const char *name; + + name = nft_jansson_value_parse_str(root, "name"); + if (name == NULL) + return -1; + + nft_rule_expr_set_str(e, NFT_EXPR_MT_NAME, name); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + + static int nft_rule_expr_match_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { #ifdef XML_PARSING @@ -247,7 +266,8 @@ struct expr_ops expr_ops_match = { .parse = nft_rule_expr_match_parse, .build = nft_rule_expr_match_build, .snprintf = nft_rule_expr_match_snprintf, - .xml_parse = nft_rule_expr_match_xml_parse, + .xml_parse = nft_rule_expr_match_xml_parse, + .json_parse = nft_rule_expr_match_json_parse, }; static void __init expr_match_init(void) diff --git a/src/expr/meta.c b/src/expr/meta.c index 8f163f6..84b8ba8 100644 --- a/src/expr/meta.c +++ b/src/expr/meta.c @@ -156,9 +156,40 @@ static inline int str2meta_key(const char *str) return i; } + errno = EINVAL; return -1; } +static int nft_rule_expr_meta_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + const char *key_str; + uint32_t reg; + int key; + + if (nft_jansson_value_parse_reg(root, "dreg", NFT_TYPE_U32, ®) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_META_DREG, reg); + + key_str = nft_jansson_value_parse_str(root, "key"); + if (key_str == NULL) + return -1; + + key = str2meta_key(key_str); + if (key < 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_META_KEY, key); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + + static int nft_rule_expr_meta_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { #ifdef XML_PARSING @@ -225,7 +256,8 @@ struct expr_ops expr_ops_meta = { .parse = nft_rule_expr_meta_parse, .build = nft_rule_expr_meta_build, .snprintf = nft_rule_expr_meta_snprintf, - .xml_parse = nft_rule_expr_meta_xml_parse, + .xml_parse = nft_rule_expr_meta_xml_parse, + .json_parse = nft_rule_expr_meta_json_parse, }; static void __init expr_meta_init(void) diff --git a/src/expr/nat.c b/src/expr/nat.c index e6866ec..312594f 100644 --- a/src/expr/nat.c +++ b/src/expr/nat.c @@ -196,6 +196,64 @@ static inline int nft_str2nat(const char *nat) } } +static int nft_rule_expr_nat_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + const char *nat_type, *family_str; + uint32_t reg; + int val32; + + nat_type = nft_jansson_value_parse_str(root, "nat_type"); + if (nat_type == NULL) + return -1; + + val32 = nft_str2nat(nat_type); + if (val32 < 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_NAT_TYPE, val32); + + family_str = nft_jansson_value_parse_str(root, "family"); + if (family_str == NULL) + return -1; + + val32 = nft_str2family(family_str); + if (val32 < 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_NAT_FAMILY, val32); + + if (nft_jansson_value_parse_reg(root, "sreg_addr_min", NFT_TYPE_U32, + ®) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MIN, reg); + + if (nft_jansson_value_parse_reg(root, "sreg_addr_max", NFT_TYPE_U32, + ®) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MAX, reg); + + if (nft_jansson_value_parse_reg(root, "sreg_proto_min", NFT_TYPE_U32, + ®) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_PROTO_MIN, reg); + + if (nft_jansson_value_parse_reg(root, "sreg_proto_max", NFT_TYPE_U32, + ®) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_PROTO_MAX, reg); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { #ifdef XML_PARSING @@ -402,6 +460,7 @@ struct expr_ops expr_ops_nat = { .build = nft_rule_expr_nat_build, .snprintf = nft_rule_expr_nat_snprintf, .xml_parse = nft_rule_expr_nat_xml_parse, + .json_parse = nft_rule_expr_nat_json_parse, }; static void __init expr_nat_init(void) diff --git a/src/expr/payload.c b/src/expr/payload.c index 340a0d8..84346a1 100644 --- a/src/expr/payload.c +++ b/src/expr/payload.c @@ -193,6 +193,48 @@ static inline int nft_str2base(const char *base) } } +static int +nft_rule_expr_payload_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + const char *base_str; + uint32_t reg, uval32; + int base; + + if (nft_jansson_value_parse_reg(root, "dreg", NFT_TYPE_U32, ®) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_DREG, reg); + + base_str = nft_jansson_value_parse_str(root, "base"); + if (base_str == NULL) + return -1; + + base = nft_str2base(base_str); + if (base < 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_BASE, base); + + if (nft_jansson_value_parse_val(root, "offset", NFT_TYPE_U32, + &uval32) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_OFFSET, uval32); + + if (nft_jansson_value_parse_val(root, "len", NFT_TYPE_U32, + &uval32) != 0) + return -1; + + nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_LEN, uval32); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { @@ -286,6 +328,7 @@ struct expr_ops expr_ops_payload = { .build = nft_rule_expr_payload_build, .snprintf = nft_rule_expr_payload_snprintf, .xml_parse = nft_rule_expr_payload_xml_parse, + .json_parse = nft_rule_expr_payload_json_parse, }; static void __init expr_payload_init(void) diff --git a/src/expr/target.c b/src/expr/target.c index 5ef53cb..ede4830 100644 --- a/src/expr/target.c +++ b/src/expr/target.c @@ -170,6 +170,25 @@ static int nft_rule_expr_target_parse(struct nft_rule_expr *e, struct nlattr *at return 0; } +static int +nft_rule_expr_target_json_parse(struct nft_rule_expr *e, json_t *root) +{ +#ifdef JSON_PARSING + const char *name; + + name = nft_jansson_value_parse_str(root, "name"); + if (name == NULL) + return -1; + + nft_rule_expr_set_str(e, NFT_EXPR_TG_NAME, name); + + return 0; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_rule_expr_target_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { @@ -250,6 +269,7 @@ struct expr_ops expr_ops_target = { .build = nft_rule_expr_target_build, .snprintf = nft_rule_expr_target_snprintf, .xml_parse = nft_rule_expr_target_xml_parse, + .json_parse = nft_rule_expr_target_json_parse, }; static void __init expr_target_init(void) -- cgit v1.2.3