From e87d2f9ef8a4a298de5514b30ec2d43d3c90a644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Neira=20Ayuso?= Date: Mon, 6 Jan 2014 00:51:14 +0100 Subject: src: new error reporting approach for XML/JSON parsers I have added a new structure for reporting some errors in parser that we can't cover with errno. In this patch, we have three errors that we can't cover with errno: NFT_PARSE_EBADINPUT : Bad XML/JSON format in the input NFT_PARSE_EMISSINGNODE : Missing node in our input NFT_PARSE_EBADTYPE : Wrong type value in a node Signed-off-by: Alvaro Neira Ayuso Signed-off-by: Pablo Neira Ayuso --- src/expr/ct.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src/expr/ct.c') diff --git a/src/expr/ct.c b/src/expr/ct.c index 46e3cef..59d05a5 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -178,7 +178,8 @@ 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) +static int nft_rule_expr_ct_json_parse(struct nft_rule_expr *e, json_t *root, + struct nft_parse_err *err) { #ifdef JSON_PARSING const char *key_str; @@ -186,13 +187,13 @@ static int nft_rule_expr_ct_json_parse(struct nft_rule_expr *e, json_t *root) uint8_t dir; int key; - if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, ®) < 0) + if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, ®, err) < 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_parse_str(root, "key"); + key_str = nft_jansson_parse_str(root, "key", err); if (key_str == NULL) return -1; @@ -205,7 +206,8 @@ static int nft_rule_expr_ct_json_parse(struct nft_rule_expr *e, json_t *root) } if (nft_jansson_node_exist(root, "dir")) { - if (nft_jansson_parse_val(root, "dir", NFT_TYPE_U8, &dir) < 0) + if (nft_jansson_parse_val(root, "dir", NFT_TYPE_U8, &dir, + err) < 0) return -1; if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY) @@ -225,7 +227,8 @@ err: } -static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) +static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, + struct nft_parse_err *err) { #ifdef XML_PARSING struct nft_expr_ct *ct = nft_expr_data(e); @@ -234,7 +237,7 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree int key; uint8_t dir; - reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST); + reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST, err); if (reg < 0) return -1; @@ -242,7 +245,7 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree e->flags |= (1 << NFT_EXPR_CT_DREG); key_str = nft_mxml_str_parse(tree, "key", MXML_DESCEND_FIRST, - NFT_XML_MAND); + NFT_XML_MAND, err); if (key_str == NULL) return -1; @@ -254,7 +257,7 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree e->flags |= (1 << NFT_EXPR_CT_KEY); if (nft_mxml_num_parse(tree, "dir", MXML_DESCEND_FIRST, BASE_DEC, - &dir, NFT_TYPE_U8, NFT_XML_MAND) != 0) + &dir, NFT_TYPE_U8, NFT_XML_MAND, err) != 0) return -1; if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY) -- cgit v1.2.3 From 6bdc8a89f7c0dd94684974c5c775bdc411a4e6e2 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 10 Jan 2014 13:21:44 +0100 Subject: expr: fix incorrect data type for several expression object fields This patch fixes the incorrect data type (from uint8_t to uint32_t) in several private data area of the expressions. It also cleans up this by translating several unsigned int to uint32_t. Signed-off-by: Pablo Neira Ayuso --- src/expr/ct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/expr/ct.c') diff --git a/src/expr/ct.c b/src/expr/ct.c index 59d05a5..7e20464 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -24,7 +24,7 @@ struct nft_expr_ct { enum nft_ct_keys key; - uint32_t dreg; /* enum nft_registers */ + enum nft_registers dreg; uint8_t dir; }; -- cgit v1.2.3 From 16c04f3be3f9596f065a75fad2cfb8a37ab53b24 Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Wed, 15 Jan 2014 11:42:17 +0100 Subject: mxml: add optional/mandatory flag to nft_mxml_reg_parse There are some cases where a reg is not mandatory, for example: * dreg in lookup * dreg/sreg in meta (last version) So, lets change the function nft_mxml_reg_parse() to add an optional/mandatory flag. dreg in lookup is optional as stated at: net/netfilter/nft_lookup.c:nft_lookup_init() Signed-off-by: Arturo Borrero Gonzalez Signed-off-by: Pablo Neira Ayuso --- src/expr/ct.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/expr/ct.c') diff --git a/src/expr/ct.c b/src/expr/ct.c index 7e20464..97f9dcc 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -233,12 +233,12 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree #ifdef XML_PARSING struct nft_expr_ct *ct = nft_expr_data(e); const char *key_str; - int32_t reg; int key; uint8_t dir; + uint32_t reg; - reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST, err); - if (reg < 0) + if (nft_mxml_reg_parse(tree, "dreg", ®, MXML_DESCEND_FIRST, + NFT_XML_MAND, err) != 0) return -1; ct->dreg = reg; -- cgit v1.2.3 From aa07b0d424e7a4b9a964e916b89859caedc63671 Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Wed, 15 Jan 2014 19:18:46 +0100 Subject: expr: ct: fix missing NFT_CT_L3PROTOCOL in ctkey2str_array Due to missing NFT_CT_L3PROTOCOL key in ctkey2str_array, a segfault is produced when the str2ctkey() loop reaches that position, since strcmp() will try to compare a NULL value. Signed-off-by: Arturo Borrero Gonzalez Signed-off-by: Pablo Neira Ayuso --- src/expr/ct.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/expr/ct.c') diff --git a/src/expr/ct.c b/src/expr/ct.c index 97f9dcc..e960134 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -151,6 +151,7 @@ const char *ctkey2str_array[NFT_CT_MAX] = { [NFT_CT_SECMARK] = "secmark", [NFT_CT_EXPIRATION] = "expiration", [NFT_CT_HELPER] = "helper", + [NFT_CT_L3PROTOCOL] = "l3protocol", [NFT_CT_PROTOCOL] = "protocol", [NFT_CT_SRC] = "src", [NFT_CT_DST] = "dst", -- cgit v1.2.3 From db7a982ba56792ea4b716ee15c3e3ff282566a9c Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Fri, 17 Jan 2014 02:15:06 +0100 Subject: expr: ct: direction is optional The 'dir' attribute is optional as stated in the kernel sources. Previous to this patch, using XML/JSON to manage this expr produces some undefined and erroneous behaviours. While at it, fix also the default output format. Signed-off-by: Arturo Borrero Gonzalez Signed-off-by: Pablo Neira Ayuso --- src/expr/ct.c | 62 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 16 deletions(-) (limited to 'src/expr/ct.c') diff --git a/src/expr/ct.c b/src/expr/ct.c index e960134..3070795 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -258,14 +258,12 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree e->flags |= (1 << NFT_EXPR_CT_KEY); if (nft_mxml_num_parse(tree, "dir", MXML_DESCEND_FIRST, BASE_DEC, - &dir, NFT_TYPE_U8, NFT_XML_MAND, err) != 0) - return -1; - - if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY) - goto err; + &dir, NFT_TYPE_U8, NFT_XML_OPT, err) == 0) { + if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY) + goto err; - ct->dir = dir; - e->flags |= (1 << NFT_EXPR_CT_DIR); + nft_rule_expr_set_u8(e, NFT_EXPR_CT_DIR, dir); + } return 0; err: @@ -292,30 +290,62 @@ nft_expr_ct_snprintf_json(char *buf, size_t size, struct nft_rule_expr *e) SNPRINTF_BUFFER_SIZE(ret, size, len, offset); } - if (e->flags & (1 << NFT_EXPR_CT_DIR)) { + if (nft_rule_expr_is_set(e, NFT_EXPR_CT_DIR)) { ret = snprintf(buf+offset, len, ",\"dir\":%u", ct->dir); SNPRINTF_BUFFER_SIZE(ret, size, len, offset); } return offset; +} + +static int +nft_expr_ct_snprintf_xml(char *buf, size_t size, struct nft_rule_expr *e) +{ + int ret, len = size, offset = 0; + struct nft_expr_ct *ct = nft_expr_data(e); + + ret = snprintf(buf, len, "%u", ct->dreg); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + + ret = snprintf(buf+offset, len, "%s", + ctkey2str(ct->key)); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + + if (nft_rule_expr_is_set(e, NFT_EXPR_CT_DIR)) { + ret = snprintf(buf+offset, len, "%u", ct->dir); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + } + + return offset; +} + +static int +nft_expr_ct_snprintf_default(char *buf, size_t size, struct nft_rule_expr *e) +{ + int ret, len = size, offset = 0; + struct nft_expr_ct *ct = nft_expr_data(e); + + ret = snprintf(buf, len, "load %s => reg %u ", + ctkey2str(ct->key), ct->dreg); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + if (nft_rule_expr_is_set(e, NFT_EXPR_CT_DIR)) { + ret = snprintf(buf+offset, len, "dir %u ", ct->dir); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + } + + return offset; } static int nft_rule_expr_ct_snprintf(char *buf, size_t len, uint32_t type, uint32_t flags, struct nft_rule_expr *e) { - struct nft_expr_ct *ct = nft_expr_data(e); - switch(type) { case NFT_OUTPUT_DEFAULT: - return snprintf(buf, len, "load %s => reg %u dir %u ", - ctkey2str(ct->key), ct->dreg, ct->dir); + return nft_expr_ct_snprintf_default(buf, len, e); case NFT_OUTPUT_XML: - return snprintf(buf, len, "%u" - "%s" - "%u", - ct->dreg, ctkey2str(ct->key), ct->dir); + return nft_expr_ct_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: return nft_expr_ct_snprintf_json(buf, len, e); default: -- cgit v1.2.3 From a205a5022259f40aa3ad74017d39e64546d4155c Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Sat, 18 Jan 2014 20:01:32 +0100 Subject: ct: use a string with 'dir' attribute This patch implements a string to represent directions in the CT expression: * original (0) * reply (1) Signed-off-by: Arturo Borrero Gonzalez Signed-off-by: Pablo Neira Ayuso --- src/expr/ct.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 11 deletions(-) (limited to 'src/expr/ct.c') diff --git a/src/expr/ct.c b/src/expr/ct.c index 3070795..a09976c 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -179,11 +179,38 @@ static inline int str2ctkey(const char *ctkey) return -1; } +static const char *ctdir2str(uint8_t ctdir) +{ + switch (ctdir) { + case IP_CT_DIR_ORIGINAL: + return "original"; + case IP_CT_DIR_REPLY: + return "reply"; + default: + return "unknow"; + } +} + +static int str2ctdir(const char *str, uint8_t *ctdir) +{ + if (strcmp(str, "original") == 0) { + *ctdir = IP_CT_DIR_ORIGINAL; + return 0; + } + + if (strcmp(str, "reply") == 0) { + *ctdir = IP_CT_DIR_REPLY; + return 0; + } + + return -1; +} + static int nft_rule_expr_ct_json_parse(struct nft_rule_expr *e, json_t *root, struct nft_parse_err *err) { #ifdef JSON_PARSING - const char *key_str; + const char *key_str, *dir_str; uint32_t reg; uint8_t dir; int key; @@ -207,12 +234,15 @@ static int nft_rule_expr_ct_json_parse(struct nft_rule_expr *e, json_t *root, } if (nft_jansson_node_exist(root, "dir")) { - if (nft_jansson_parse_val(root, "dir", NFT_TYPE_U8, &dir, - err) < 0) + dir_str = nft_jansson_parse_str(root, "dir", err); + if (dir_str == NULL) return -1; - if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY) + if (str2ctdir(dir_str, &dir) != 0) { + err->node_name = "dir"; + err->error = NFT_PARSE_EBADTYPE; goto err; + } nft_rule_expr_set_u8(e, NFT_EXPR_CT_DIR, dir); } @@ -233,7 +263,7 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree { #ifdef XML_PARSING struct nft_expr_ct *ct = nft_expr_data(e); - const char *key_str; + const char *key_str, *dir_str; int key; uint8_t dir; uint32_t reg; @@ -257,10 +287,14 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree ct->key = key; e->flags |= (1 << NFT_EXPR_CT_KEY); - if (nft_mxml_num_parse(tree, "dir", MXML_DESCEND_FIRST, BASE_DEC, - &dir, NFT_TYPE_U8, NFT_XML_OPT, err) == 0) { - if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY) + dir_str = nft_mxml_str_parse(tree, "dir", MXML_DESCEND_FIRST, + NFT_XML_OPT, err); + if (dir_str != NULL) { + if (str2ctdir(dir_str, &dir) != 0) { + err->node_name = "dir"; + err->error = NFT_PARSE_EBADTYPE; goto err; + } nft_rule_expr_set_u8(e, NFT_EXPR_CT_DIR, dir); } @@ -291,7 +325,8 @@ nft_expr_ct_snprintf_json(char *buf, size_t size, struct nft_rule_expr *e) } if (nft_rule_expr_is_set(e, NFT_EXPR_CT_DIR)) { - ret = snprintf(buf+offset, len, ",\"dir\":%u", ct->dir); + ret = snprintf(buf+offset, len, ",\"dir\":\"%s\"", + ctdir2str(ct->dir)); SNPRINTF_BUFFER_SIZE(ret, size, len, offset); } @@ -312,7 +347,8 @@ nft_expr_ct_snprintf_xml(char *buf, size_t size, struct nft_rule_expr *e) SNPRINTF_BUFFER_SIZE(ret, size, len, offset); if (nft_rule_expr_is_set(e, NFT_EXPR_CT_DIR)) { - ret = snprintf(buf+offset, len, "%u", ct->dir); + ret = snprintf(buf+offset, len, "%s", + ctdir2str(ct->dir)); SNPRINTF_BUFFER_SIZE(ret, size, len, offset); } @@ -330,7 +366,8 @@ nft_expr_ct_snprintf_default(char *buf, size_t size, struct nft_rule_expr *e) SNPRINTF_BUFFER_SIZE(ret, size, len, offset); if (nft_rule_expr_is_set(e, NFT_EXPR_CT_DIR)) { - ret = snprintf(buf+offset, len, "dir %u ", ct->dir); + ret = snprintf(buf+offset, len, ", dir %s ", + ctdir2str(ct->dir)); SNPRINTF_BUFFER_SIZE(ret, size, len, offset); } -- cgit v1.2.3 From 8460aa61e7136973ea01c40098f348b13d9af26f Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 20 Jan 2014 10:18:03 +0100 Subject: expr: ct: fix compilation warning when json/xml support is missing CC expr/ct.lo expr/ct.c:194:12: warning: 'str2ctdir' defined but not used [-Wunused-function] Signed-off-by: Pablo Neira Ayuso --- src/expr/ct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/expr/ct.c') diff --git a/src/expr/ct.c b/src/expr/ct.c index a09976c..584f7a6 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -191,7 +191,7 @@ static const char *ctdir2str(uint8_t ctdir) } } -static int str2ctdir(const char *str, uint8_t *ctdir) +static inline int str2ctdir(const char *str, uint8_t *ctdir) { if (strcmp(str, "original") == 0) { *ctdir = IP_CT_DIR_ORIGINAL; -- cgit v1.2.3 From 59e949294f4688bafe44b7def2972987224520c8 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 20 Jan 2014 10:26:57 +0100 Subject: rename library to libnftnl We plan to use this library name for the higher layer library. Signed-off-by: Pablo Neira Ayuso --- src/expr/ct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/expr/ct.c') diff --git a/src/expr/ct.c b/src/expr/ct.c index 584f7a6..051a1c5 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -18,8 +18,8 @@ #include "internal.h" #include -#include -#include +#include +#include #include "expr_ops.h" struct nft_expr_ct { -- cgit v1.2.3