rule: Add json parser support
PATCH 1/3 rule: Add json parser support
From: Álvaro Neira Ayuso <[email protected]>
Add function for parsing rules in JSON format
--- include/libnftables/rule.h | 1 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 ++++++++++ src/expr_ops.h | 5 ++ src/internal.h | 8 ++++ src/jansson.c | 91 ++++++++++++++++++++++++++++++++++++++++++++ src/rule.c | 90 ++++++++++++++++++++++++++++++++++++++++++++ 22 files changed, 839 insertions(+), 2 deletions(-)
include/libnftables/rule.h +1 -0
@@ -51,6 +51,7 @@ enum {enum nft_rule_parse_type {NFT_RULE_PARSE_NONE =0 ,NFT_RULE_PARSE_XML , +NFT_RULE_PARSE_JSON ,NFT_RULE_PARSE_MAX , };
src/expr/bitwise.c +45 -0
57 lines not on this page · raw message
src/expr/byteorder.c +50 -0
62 lines not on this page · raw message
src/expr/cmp.c +38 -0
@@ -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 ) {
src/expr/counter.c +26 -0
@@ -119,6 +119,31 @@ nft_rule_expr_counter_parse(struct nft_rule_expr *e, struct nlattr *attr) }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) {#ifdef XML_PARSING
@@ -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 )
src/expr/ct.c +49 -0
61 lines not on this page · raw message
src/expr/data_reg.c +77 -0
83 lines not on this page · raw message
src/expr/data_reg.h +5 -0
@@ -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
src/expr/exthdr.c +43 -0
55 lines not on this page · raw message
src/expr/immediate.c +40 -0
@@ -178,6 +178,45 @@ nft_rule_expr_immediate_parse(struct nft_rule_expr *e, struct nlattr *attr) }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) {#ifdef XML_PARSING
@@ -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 )
src/expr/limit.c +25 -0
@@ -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 )
src/expr/log.c +39 -0
@@ -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 )
src/expr/lookup.c +31 -0
@@ -143,6 +143,36 @@ nft_rule_expr_lookup_parse(struct nft_rule_expr *e, struct nlattr *attr) }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) {#ifdef XML_PARSING
@@ -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 )
src/expr/match.c +21 -1
@@ -170,6 +170,25 @@ static int nft_rule_expr_match_parse(struct nft_rule_expr *e, struct nlattr *attreturn 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 )
src/expr/meta.c +33 -1
@@ -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 )
src/expr/nat.c +59 -0
71 lines not on this page · raw message
src/expr/payload.c +43 -0
55 lines not on this page · raw message
src/expr/target.c +20 -0
@@ -171,6 +171,25 @@ static int nft_rule_expr_target_parse(struct nft_rule_expr *e, struct nlattr *at }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) {#ifdef XML_PARSING
@@ -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 )
src/expr_ops.h +5 -0
@@ -13,6 +13,10 @@ struct nft_rule_expr;#define mxml_node_t void#endif +#ifndef JSON_PARSING +#define json_t void +#endif +struct expr_ops {struct list_head head;
@@ -25,6 +29,7 @@ struct expr_ops {void (*build)(struct nlmsghdr *nlh,struct nft_rule_expr *e);int (*snprintf)(char *buf,size_t len,uint32_t type,uint32_t flags,struct nft_rule_expr *e);int (*xml_parse)(struct nft_rule_expr *e,mxml_node_t *tree); +int (*json_parse)(struct nft_rule_expr *e,json_t *data); };void nft_expr_ops_register (struct expr_ops *ops);
src/internal.h +8 -0
@@ -52,6 +52,14 @@ json_t *nft_jansson_create_root(char *json, json_error_t *err);json_t *nft_jansson_get_node (json_t *root,const char *tag);void nft_jansson_free_root (json_t *root);int nft_jansson_parse_family (json_t *root,void *out); +int nft_jansson_str2num (json_t *root,const char *tag,int base,void *out, +enum nft_type type); +int nft_jansson_value_parse_reg (json_t *root,const char *tag, +int type,void *out); +struct nft_rule_expr *nft_jansson_expr_parse (json_t *root); +union nft_data_reg ; +int nft_jansson_data_reg_parse (json_t *root,const char *tag, +union nft_data_reg *data_reg);#endif const char *nft_family2str (uint32_t family);
src/jansson.c +91 -0
101 lines not on this page · raw message
src/rule.c +90 -0
102 lines not on this page · raw message
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/3 tests: rule: add json parsing support
From: Álvaro Neira Ayuso <[email protected]>
Test the functions for parsing rules in JSON.
--- tests/jsonfiles/20-rule-bitwise.json | 1 + tests/jsonfiles/21-rule-byteorder.json | 1 + tests/jsonfiles/22-rule-cmp.json | 1 + tests/jsonfiles/23-rule-counter.json | 1 + tests/jsonfiles/24-rule-ct.json | 1 + tests/jsonfiles/25-rule-exthdr.json | 1 + tests/jsonfiles/26-rule-immediate.json | 1 + tests/jsonfiles/27-rule-limit.json | 1 + tests/jsonfiles/28-rule-log.json | 1 + tests/jsonfiles/29-rule-match.json | 1 + tests/jsonfiles/30-rule-lookup.json | 1 + tests/jsonfiles/31-rule-meta.json | 1 + tests/jsonfiles/32-rule-nat4.json | 1 + tests/jsonfiles/33-rule-nat6.json | 1 + tests/jsonfiles/34-rule-payload.json | 1 + tests/jsonfiles/35-rule-target.json | 1 + tests/jsonfiles/36-rule-real.json | 1 + tests/jsonfiles/37-rule-real.json | 1 + tests/jsonfiles/38-rule-real.json | 1 + tests/jsonfiles/39-rule-real.json | 1 + tests/jsonfiles/40-rule-real.json | 1 + tests/jsonfiles/41-rule-real.json | 1 + tests/jsonfiles/42-rule-real.json | 1 + tests/jsonfiles/43-rule-real.json | 1 + tests/jsonfiles/44-rule-real.json | 1 + tests/jsonfiles/45-rule-real.json | 1 + tests/jsonfiles/46-rule-real.json | 1 + tests/jsonfiles/47-rule-real.json | 1 + tests/jsonfiles/48-rule-real.json | 1 + tests/jsonfiles/49-rule-real.json | 1 + tests/jsonfiles/50-rule-real.json | 1 + tests/jsonfiles/51-rule-real.json | 1 + tests/jsonfiles/52-rule-real.json | 1 + tests/jsonfiles/53-rule-real.json | 1 + tests/jsonfiles/54-rule-real.json | 1 + tests/jsonfiles/55-rule-real.json | 1 + tests/jsonfiles/56-rule-real.json | 1 + tests/jsonfiles/57-rule-real.json | 1 + tests/jsonfiles/58-rule-real.json | 1 + tests/jsonfiles/59-rule-real.json | 1 + tests/jsonfiles/60-rule-real.json | 1 + tests/jsonfiles/61-rule-real.json | 1 + tests/nft-parsing-test.c | 11 +++++++++++ 43 files changed, 53 insertions(+) create mode 100644 tests/jsonfiles/20-rule-bitwise.json create mode 100644 tests/jsonfiles/21-rule-byteorder.json create mode 100644 tests/jsonfiles/22-rule-cmp.json create mode 100644 tests/jsonfiles/23-rule-counter.json create mode 100644 tests/jsonfiles/24-rule-ct.json create mode 100644 tests/jsonfiles/25-rule-exthdr.json create mode 100644 tests/jsonfiles/26-rule-immediate.json create mode 100644 tests/jsonfiles/27-rule-limit.json create mode 100644 tests/jsonfiles/28-rule-log.json create mode 100644 tests/jsonfiles/29-rule-match.json create mode 100644 tests/jsonfiles/30-rule-lookup.json create mode 100644 tests/jsonfiles/31-rule-meta.json create mode 100644 tests/jsonfiles/32-rule-nat4.json create mode 100644 tests/jsonfiles/33-rule-nat6.json create mode 100644 tests/jsonfiles/34-rule-payload.json create mode 100644 tests/jsonfiles/35-rule-target.json create mode 100644 tests/jsonfiles/36-rule-real.json create mode 100644 tests/jsonfiles/37-rule-real.json create mode 100644 tests/jsonfiles/38-rule-real.json create mode 100644 tests/jsonfiles/39-rule-real.json create mode 100644 tests/jsonfiles/40-rule-real.json create mode 100644 tests/jsonfiles/41-rule-real.json create mode 100644 tests/jsonfiles/42-rule-real.json create mode 100644 tests/jsonfiles/43-rule-real.json create mode 100644 tests/jsonfiles/44-rule-real.json create mode 100644 tests/jsonfiles/45-rule-real.json create mode 100644 tests/jsonfiles/46-rule-real.json create mode 100644 tests/jsonfiles/47-rule-real.json create mode 100644 tests/jsonfiles/48-rule-real.json create mode 100644 tests/jsonfiles/49-rule-real.json create mode 100644 tests/jsonfiles/50-rule-real.json create mode 100644 tests/jsonfiles/51-rule-real.json create mode 100644 tests/jsonfiles/52-rule-real.json create mode 100644 tests/jsonfiles/53-rule-real.json create mode 100644 tests/jsonfiles/54-rule-real.json create mode 100644 tests/jsonfiles/55-rule-real.json create mode 100644 tests/jsonfiles/56-rule-real.json create mode 100644 tests/jsonfiles/57-rule-real.json create mode 100644 tests/jsonfiles/58-rule-real.json create mode 100644 tests/jsonfiles/59-rule-real.json create mode 100644 tests/jsonfiles/60-rule-real.json create mode 100644 tests/jsonfiles/61-rule-real.json
tests/jsonfiles/20-rule-bitwise.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "input", "handle" : 20,"flags" : 0, "expr" : [ { "type" : "bitwise", "sreg" : 1, "dreg" : 1, "len" : 4, "mask" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x0000000a"}}, "xor" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x00000000"}}}]}}
tests/jsonfiles/21-rule-byteorder.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "input", "handle" : 21,"flags" : 0, "expr" : [ { "type" : "byteorder", "sreg" : 3, "dreg" : 4, "op" : "hton", "len" : 4, "size" : 4}]}}
tests/jsonfiles/22-rule-cmp.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "forward", "handle" : 22,"flags" : 0, "expr" : [ { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 16, "data0" : "0x00000000", "data1" : "0x6e6f6200", "data2" : "0x2e303164", "data3" : "0x00393331"}}}]}}
tests/jsonfiles/23-rule-counter.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 23,"flags" : 0, "expr" : [ { "type" : "counter", "pkts" : 135, "bytes" : 21655}]}}
tests/jsonfiles/24-rule-ct.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "input", "handle" : 24,"flags" : 0, "expr" : [ { "type" : "ct", "dreg" : 1, "key" : "state"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x00000008"}}}]}}
tests/jsonfiles/25-rule-exthdr.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "input", "handle" : 25,"flags" : 0, "expr" : [ { "type" : "exthdr", "dreg" : 1, "exthdr_type" : "mh", "offset" : 2, "len" : 16}]}}
tests/jsonfiles/26-rule-immediate.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "input", "handle" : 26,"flags" : 0, "expr" : [ { "type" : "immediate", "dreg" : 0, "immediatedata" : {"data_reg": {"type" : "verdict", "verdict" : "accept"}}}]}}
tests/jsonfiles/27-rule-limit.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "input", "handle" : 27,"flags" : 0, "expr" : [ { "type" : "limit", "rate" : 321321, "depth" : 0 }]}}
tests/jsonfiles/28-rule-log.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "input", "handle" : 28,"flags" : 0, "expr" : [ { "type" : "log", "prefix" : "test_chain", "group" : 1, "snaplen" : 0, "qthreshold" : 0 }]}}
tests/jsonfiles/29-rule-match.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "input", "handle" : 9,"flags" : 0, "expr" : [ { "type" : "match", "name" : "state"}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/30-rule-lookup.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "input", "handle" : 8,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 12, "len" : 4, "base" : "network"}, { "type" : "lookup", "set" : "set0", "sreg" : 1, "dreg" : 0}]}}
tests/jsonfiles/31-rule-meta.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 8,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "protocol"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x000003e8"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/32-rule-nat4.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "input", "handle" : 10,"flags" : 0, "expr" : [ { "type" : "nat", "nat_type" : "dnat", "family" : "ip", "sreg_addr_min" : 1, "sreg_addr_max" : 2, "sreg_proto_min" : 3, "sreg_proto_max" : 4}]}}
tests/jsonfiles/33-rule-nat6.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip6", "table" : "nat", "chain" : "output", "handle" : 33,"flags" : 0, "expr" : [ { "type" : "nat", "nat_type" : "snat", "family" : "ip6", "sreg_addr_min" : 1, "sreg_addr_max" : 2, "sreg_proto_min" : 3, "sreg_proto_max" : 4}]}}
tests/jsonfiles/34-rule-payload.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "input", "handle" : 26,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 9, "len" : 1, "base" : "network"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 1, "data0" : "0x00000006"}}}, { "type" : "payload", "dreg" : 1, "offset" : 2, "len" : 2, "base" : "transport"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 2, "data0" : "0x00001600"}}}, { "type" : "immediate", "dreg" : 0, "immediatedata" : {"data_reg": {"type" : "verdict", "verdict" : "accept"}}}]}}
tests/jsonfiles/35-rule-target.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "INPUT", "handle" : 20,"flags" : 0, "expr" : [ { "type" : "counter", "pkts" : 17, "bytes" : 4436}, { "type" : "target", "name" : "LOG"}]}}
tests/jsonfiles/36-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 36,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 12, "len" : 8, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 8, "data0" : "0x0100a8c0", "data1" : "0x6400a8c0"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/37-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 37,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 16, "len" : 4, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x0100a8c0"}}}]}}
tests/jsonfiles/38-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 38,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 16, "len" : 4, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x0100a8c0"}}}]}}
tests/jsonfiles/39-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 39,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 16, "len" : 4, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "gte", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x0100a8c0"}}}, { "type" : "cmp", "sreg" : 1, "op" : "lte", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0xfa00a8c0"}}}]}}
tests/jsonfiles/40-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 40,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 16, "len" : 4, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x0100a8c0"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/41-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 41,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 16, "len" : 4, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x0100a8c0"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}, { "type" : "immediate", "dreg" : 0, "immediatedata" : {"data_reg": {"type" : "verdict", "verdict" : "drop"}}}]}}
tests/jsonfiles/42-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 42,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 16, "len" : 4, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x0100a8c0"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}, { "type" : "log", "prefix" : "(null)", "group" : 0, "snaplen" : 0, "qthreshold" : 0 }]}}
tests/jsonfiles/43-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 43,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 9, "len" : 1, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 1, "data0" : "0x00000006"}}}, { "type" : "payload", "dreg" : 1, "offset" : 2, "len" : 2, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 2, "data0" : "0x00001600"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/44-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 44,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 9, "len" : 1, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 1, "data0" : "0x00000006"}}}, { "type" : "payload", "dreg" : 1, "offset" : 0, "len" : 4, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x16000004"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/45-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 45,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 12, "len" : 8, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 8, "data0" : "0x0100a8c0", "data1" : "0x6400a8c0"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/46-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 46,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 9, "len" : 1, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 1, "data0" : "0x00000006"}}}, { "type" : "payload", "dreg" : 1, "offset" : 0, "len" : 8, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 8, "data0" : "0x16000004", "data1" : "0x00000000"}}}]}}
tests/jsonfiles/47-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 47,"flags" : 0, "expr" : [ { "type" : "payload", "dreg" : 1, "offset" : 9, "len" : 1, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 1, "data0" : "0x00000006"}}}, { "type" : "payload", "dreg" : 1, "offset" : 0, "len" : 8, "base" : "link"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 8, "data0" : "0x16000004", "data1" : "0x00000000"}}}]}}
tests/jsonfiles/48-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 48,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "len"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x000003e8"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/49-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 49,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "mark"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x00000000"}}}, { "type" : "counter", "pkts" : 55, "bytes" : 11407}]}}
tests/jsonfiles/50-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 50,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "iif"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x00000001"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/51-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 51,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "iifname"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 16, "data0" : "0x00000000", "data1" : "0x00000000", "data2" : "0x65000000", "data3" : "0x00306874"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/52-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 52,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "oif"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x00000001"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/53-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 53,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "oifname"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 16, "data0" : "0x00000000", "data1" : "0x00000000", "data2" : "0x65000000", "data3" : "0x00306874"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/54-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 54,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "skuid"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x000003e8"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/55-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 55,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "skgid"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x000003e8"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/56-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 56,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "secmark"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x00000000"}}}, { "type" : "counter", "pkts" : 55, "bytes" : 11407}]}}
tests/jsonfiles/57-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 57,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "len"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x000003e8"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/58-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 58,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "protocol"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 2, "data0" : "0x00000008"}}}, { "type" : "counter", "pkts" : 55, "bytes" : 11407}]}}
tests/jsonfiles/59-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 59,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "mark"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x00000000"}}}, { "type" : "counter", "pkts" : 55, "bytes" : 11407}]}}
tests/jsonfiles/60-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 60,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "iif"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 4, "data0" : "0x00000001"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/jsonfiles/61-rule-real.json new file +1 -0
@@ -0,0 +1 @@ +{ "rule": { "family" : "ip", "table" : "filter", "chain" : "output", "handle" : 61,"flags" : 0, "expr" : [ { "type" : "meta", "dreg" : 1, "key" : "iifname"}, { "type" : "cmp", "sreg" : 1, "op" : "eq", "cmpdata" : {"data_reg": { "type" : "value", "len" : 16, "data0" : "0x00000000", "data1" : "0x00000000", "data2" : "0x65000000", "data3" : "0x00306874"}}}, { "type" : "counter", "pkts" : 0, "bytes" : 0}]}}
tests/nft-parsing-test.c +11 -0
@@ -157,6 +157,7 @@ static int test_json(const char *filename)int ret =-1 ;struct nft_table *t =NULL ;struct nft_chain *c =NULL ; +struct nft_rule *r =NULL ;json_t *root;json_error_t error;char *json =NULL ;
@@ -189,6 +190,16 @@ static int test_json(const char *filename)nft_chain_free (c); } + }else if (json_object_get (root,"rule" ) !=NULL ) { + r =nft_rule_alloc (); +if (r !=NULL ) { +if (nft_rule_parse (r,NFT_RULE_PARSE_JSON , json) ==0 ) + ret =compare_test (TEST_JSON_RULE , r, filename); +else + goto failparsing; + +nft_rule_free (r); + } }free (json);
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/3 examples: Add nft-rule-json-add
In reply to Alvaro NeiraFrom: Álvaro Neira Ayuso <[email protected]>
--- examples/Makefile.am | 4 + examples/nft-rule-json-add.c | 117 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 examples/nft-rule-json-add.c
examples/Makefile.am +4 -0
@@ -14,6 +14,7 @@ check_PROGRAMS = nft-table-add \ nft-rule-add \ nft-rule-insert \ nft-rule-xml-add \ + nft-rule-json-add \ nft-rule-del \ nft-rule-get \ nft-events \
@@ -67,6 +68,9 @@ nft_rule_insert_LDADD = ../src/libnftables.la ${LIBMNL_LIBS} ${LIBXML_LIBS} nft_rule_xml_add_SOURCES = nft-rule-xml-add.c nft_rule_xml_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS} +nft_rule_json_add_SOURCES = nft-rule-json-add.c +nft_rule_json_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS} + nft_rule_del_SOURCES = nft-rule-del.c nft_rule_del_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
examples/nft-rule-json-add.c new file +117 -0
117 lines not on this page · raw message
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Pablo Neira Ayuso
maintainerApplied from 1 to 3, thanks Alvaro.