set: XML parse
PATCH v2 1/1 set: XML parse
Sets are now parsed, following this previous snprintf pattern:
<set name="xx" table="xx" version="xx">
<set_flags>uint32_t</set_flags> <key_type>uint32_t</key_type> <key_len>size_t</key_len> <data_type>uint32_t</data_type> <data_len>size_t</data_len> <set_elem> <set_elem_flags>uint32_t</set_elem_flags> <set_elem_key> <data_reg type="value"> <len></len> <dataN></dataN> </data_reg> </set_elem_key> <set_elem_data> <data_reg type="xx"> [...] </data_reg> </set_elem_data> </set_elem>
</set>
---
v1: initial version.
v2: - let helper version set errno.
- Move set_elem parsing to a helper function.
- <set_elem_data> is now optional.
- realistic testsfiles, also with IPv6 data.
tests/nft-parsing-test.c | 10 ++++++++++ tests/xmlfiles/73-set.xml | 36 ++++++++++++++++++++++++++++++++++++ tests/xmlfiles/74-set.xml | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 tests/xmlfiles/73-set.xml create mode 100644 tests/xmlfiles/74-set.xml
include/libnftables/set.h +9 -0
@@ -52,6 +52,14 @@ struct nft_set *nft_set_list_iter_cur(struct nft_set_list_iter *iter);struct nft_set *nft_set_list_iter_next (struct nft_set_list_iter *iter);void nft_set_list_iter_destroy (struct nft_set_list_iter *iter); +enum nft_set_parse_type { +NFT_SET_PARSE_NONE =0 , +NFT_SET_PARSE_XML , +NFT_SET_PARSE_MAX , +}; + +int nft_set_parse (struct nft_set *s,enum nft_set_parse_type type,char *data); +/* * Set elements */
@@ -94,6 +102,7 @@ void nft_set_elem_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_set_elemint nft_set_elem_nlmsg_parse (const struct nlmsghdr *nlh,struct nft_set_elem *s); +int nft_set_elem_parse (struct nft_set_elem *e,enum nft_set_parse_type type,char *data);int nft_set_elem_snprintf (char *buf,size_t size,struct nft_set_elem *s,uint32_t type,uint32_t flags);int nft_set_elem_foreach (struct nft_set *s,int (*cb)(struct nft_set_elem *e,void *data),void *data);
src/internal.h +1 -0
@@ -36,6 +36,7 @@ union nft_data_reg;int nft_mxml_data_reg_parse (mxml_node_t *tree,const char *node_name,union nft_data_reg *data_reg);int nft_mxml_num_parse (mxml_node_t *tree,const char *node_name,uint32_t mxml_flags,int base,void *number,enum nft_type type);const char *nft_mxml_str_parse (mxml_node_t *tree,const char *node_name,uint32_t mxml_flags); +struct nft_set_elem *nft_mxml_set_elem_parse (mxml_node_t *node);#endif #ifdef JSON_PARSING
src/libnftables.map +2 -0
@@ -120,6 +120,7 @@ global: nft_set_nlmsg_build_hdr; nft_set_nlmsg_build_payload; nft_set_nlmsg_parse; + nft_set_parse; nft_set_snprintf; nft_set_list_alloc;
@@ -149,6 +150,7 @@ global: nft_set_elem_nlmsg_build_hdr; nft_set_elem_nlmsg_build_payload; nft_set_elem_nlmsg_parse; + nft_set_elem_parse; nft_set_elem_snprintf; nft_set_elems_nlmsg_build_payload;
src/mxml.c +46 -0
56 lines not on this page · raw message
src/set.c +137 -0
149 lines not on this page · raw message
src/set_elem.c +84 -1
98 lines not on this page · raw message
tests/nft-parsing-test.c +10 -0
@@ -9,6 +9,7 @@#include <libnftables/table.h> #include <libnftables/chain.h> #include <libnftables/rule.h> +#include <libnftables/set.h> #ifdef XML_PARSING #include <mxml.h>
@@ -62,6 +63,7 @@ static int test_xml(const char *filename)struct nft_table *t =NULL ;struct nft_chain *c =NULL ;struct nft_rule *r =NULL ; +struct nft_set *s =NULL ;FILE *fp;mxml_node_t *tree =NULL ;;char *xml =NULL ;
@@ -102,6 +104,14 @@ static int test_xml(const char *filename)nft_rule_free (r); } + }else if (strcmp (tree->value.opaque,"set" ) ==0 ) { + s =nft_set_alloc (); +if (s !=NULL ) { +if (nft_set_parse (s,NFT_SET_PARSE_XML , xml) ==0 ) + ret =0 ; + +nft_set_free (s); + } }return ret;
tests/xmlfiles/73-set.xml new file +36 -0
@@ -0,0 +1,36 @@ +<set name="set0" table="filter" version="0"> + <family>ip</family> + <set_flags>0</set_flags> + <key_type>0</key_type> + <key_len>0</key_len> + <data_type>0</data_type> + <data_len>0</data_len> + <set_elem> + <set_elem_flags>0</set_elem_flags> + <set_elem_key> + <data_reg type="value"> + <len>4</len> + <data0>0x0300a8c0</data0> + </data_reg> + </set_elem_key> + </set_elem> + <set_elem> + <set_elem_flags>0</set_elem_flags> + <set_elem_key> + <data_reg type="value"> + <len>4</len> + <data0>0x0200a8c0</data0> + </data_reg> + </set_elem_key> + </set_elem> + <set_elem> + <set_elem_flags>0</set_elem_flags> + <set_elem_key> + <data_reg type="value"> + <len>4</len> + <data0>0x0100a8c0</data0> + </data_reg> + </set_elem_key> + </set_elem> +</set> +<!-- nft add rule ip filter test ip daddr { 192.168.0.1, 192.168.0.2, 192.168.0.3 } tcp dport 443 counter accept -->
tests/xmlfiles/74-set.xml new file +33 -0
@@ -0,0 +1,33 @@ +<set name="set0" table="filter" version="0"> + <family>ip6</family> + <set_flags>0</set_flags> + <key_type>0</key_type> + <key_len>0</key_len> + <data_type>0</data_type> + <data_len>0</data_len> + <set_elem> + <set_elem_flags>0</set_elem_flags> + <set_elem_key> + <data_reg type="value"> + <len>16</len> + <data0>0xc09a002a</data0> + <data1>0x2700cac1</data1> + <data2>0x00000000</data2> + <data3>0x70010000</data3> + </data_reg> + </set_elem_key> + </set_elem> + <set_elem> + <set_elem_flags>0</set_elem_flags> + <set_elem_key> + <data_reg type="value"> + <len>16</len> + <data0>0xc09a002a</data0> + <data1>0x2700cac1</data1> + <data2>0x00000000</data2> + <data3>0x50010000</data3> + </data_reg> + </set_elem_key> + </set_elem> +</set> +<!-- nft add rule ip6 filter test ip6 daddr { 2a00:9ac0:c1ca:27::150, 2a00:9ac0:c1ca:27::170, } counter accept -->
--
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
maintainerQuoted 192 lines · Arturo Borrero Gonzalez
Sets are now parsed, following this previous snprintf pattern:
<set name="xx" table="xx" version="xx">
<set_flags>uint32_t</set_flags> <key_type>uint32_t</key_type> <key_len>size_t</key_len> <data_type>uint32_t</data_type> <data_len>size_t</data_len> <set_elem> <set_elem_flags>uint32_t</set_elem_flags> <set_elem_key> <data_reg type="value"> <len></len> <dataN></dataN> </data_reg> </set_elem_key> <set_elem_data> <data_reg type="xx"> [...] </data_reg> </set_elem_data> </set_elem></set>
Signed-off-by Arturo Borrero González <[email protected]>---
v1: initial version.
v2: - let helper version set errno.
- Moveset_elemparsing to a helper function.
- <set_elem_data> is now optional.
- realistic testsfiles, also with IPv6 data.tests/nft-parsing-test.c | 10 ++++++++++ tests/xmlfiles/73-set.xml | 36 ++++++++++++++++++++++++++++++++++++ tests/xmlfiles/74-set.xml | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 tests/xmlfiles/73-set.xml create mode 100644 tests/xmlfiles/74-set.xmlinclude/libnftables/set.h +9
-0@@ -52,6 +52,14 @@ struct nft_set *nft_set_list_iter_cur(struct nft_set_list_iter *iter);struct nft_set *nft_set_list_iter_next (struct nft_set_list_iter *iter);void nft_set_list_iter_destroy (struct nft_set_list_iter *iter); +enum nft_set_parse_type { +NFT_SET_PARSE_NONE =0 , +NFT_SET_PARSE_XML , +NFT_SET_PARSE_MAX , +}; + +int nft_set_parse (struct nft_set *s,enum nft_set_parse_type type,char *data); +/* * Set elements */ @@ -94,6 +102,7 @@ void nft_set_elem_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_set_elemint nft_set_elem_nlmsg_parse (const struct nlmsghdr *nlh,struct nft_set_elem *s); +int nft_set_elem_parse (struct nft_set_elem *e,enum nft_set_parse_type type,char *data);int nft_set_elem_snprintf (char *buf,size_t size,struct nft_set_elem *s,uint32_t type,uint32_t flags);int nft_set_elem_foreach (struct nft_set *s,int (*cb)(struct nft_set_elem *e,void *data),void *data);src/internal.h +1
-0@@ -36,6 +36,7 @@ union nft_data_reg;int nft_mxml_data_reg_parse (mxml_node_t *tree,const char *node_name,union nft_data_reg *data_reg);int nft_mxml_num_parse (mxml_node_t *tree,const char *node_name,uint32_t mxml_flags,int base,void *number,enum nft_type type);const char *nft_mxml_str_parse (mxml_node_t *tree,const char *node_name,uint32_t mxml_flags); +struct nft_set_elem *nft_mxml_set_elem_parse (mxml_node_t *node);#endif #ifdef JSON_PARSING src/libnftables.map +2
-0@@ -120,6 +120,7 @@ global: nft_set_nlmsg_build_hdr; nft_set_nlmsg_build_payload; nft_set_nlmsg_parse; + nft_set_parse; nft_set_snprintf; nft_set_list_alloc;@@ -149,6 +150,7 @@ global: nft_set_elem_nlmsg_build_hdr; nft_set_elem_nlmsg_build_payload; nft_set_elem_nlmsg_parse; + nft_set_elem_parse; nft_set_elem_snprintf; nft_set_elems_nlmsg_build_payload;src/mxml.c +46
-0@@ -17,6 +17,7 @@#include <linux/netfilter/nf_tables.h> #include <libnftables/rule.h> #include <libnftables/expr.h> +#include <libnftables/set.h> #ifdef XML_PARSING struct nft_rule_expr *nft_mxml_expr_parse (mxml_node_t *node)@@ -165,4 +166,49 @@ const char *nft_mxml_str_parse(mxml_node_t *tree, const char *node_name,return strdup (node->child->value.opaque); } +struct nft_set_elem *nft_mxml_set_elem_parse (mxml_node_t *node) +{ +mxml_node_t *save; +char *set_elem_str; +struct nft_set_elem *elem; + +if (node ==NULL ) + goto einval; + +if (strcmp (node->value.opaque,"set_elem" ) !=0 ) + goto einval; + + elem =nft_set_elem_alloc (); +if (elem ==NULL ) + goto enomem; + +/* This is a hack for mxml to print just the current node */ + save = node->next; + node->next =NULL ; + + set_elem_str =mxmlSaveAllocString (node,MXML_NO_CALLBACK ); + node->next = save; + +if (set_elem_str ==NULL ) { +free (elem); + goto enomem; + } + +if (nft_set_elem_parse (elem,NFT_SET_PARSE_XML , + set_elem_str) !=0 ) { +free (set_elem_str); +free (elem); +return NULL ; + } + +free (set_elem_str); + +return elem; +einval: + errno =EINVAL ; +return NULL ; +enomem: + errno =ENOMEM ; +return NULL ; +}#endif src/set.c +16
-0@@ -16,6 +16,8 @@#include <stdlib.h> #include <string.h> #include <netinet/in.h> +#include <limits.h> +#include <errno.h> #include <libmnl/libmnl.h> #include <linux/netfilter/nfnetlink.h> @@ -301,6 +303,141 @@ int nft_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set *s) }EXPORT_SYMBOL (nft_set_nlmsg_parse); +static int nft_set_xml_parse (struct nft_set *s,char *xml) +{ +#ifdef XML_PARSING +mxml_node_t *tree; +mxml_node_t *node =NULL ; +struct nft_set_elem *elem; +int version; +int family; +char *family_str; + + tree =mxmlLoadString (NULL , xml,MXML_OPAQUE_CALLBACK ); +if (tree ==NULL ) { + errno =EINVAL ; +return -1 ;
src/set.c int nft_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set *s) · line 329
Quoted 10 lines
src/set.c +10
-0+ } + +if (strcmp (tree->value.opaque,"set" ) !=0 ) + goto err; + +if (mxmlElementGetAttr (tree,"version" ) ==NULL ) + goto err; + +if (nft_strtoi (mxmlElementGetAttr (tree,"version" ),10 , &version, +NFT_TYPE_U64 ) !=0 )
I noticed that we cannot use nft_mxml_num_parse here because it's an attribute.
My proposal is:
1) make patch to convert XML attributes to XML nodes in sets.
2) make a patch to add the XML parsing for sets, now using the existing helper functions that we have.
Thanks.
--
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