diff mbox

[libnftables] parsing: add interface to parse from file

Message ID 20140102132103.23299.58753.stgit@nfdev.cica.es
State Changes Requested
Headers show

Commit Message

Arturo Borrero Jan. 2, 2014, 1:21 p.m. UTC
This patch adds API interfaces to parse nft objects from a given filename.

I found this useful in `nft', where I'm trying to parse XML/JSON from a file.

Examples will be updated in a separated patch.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
 include/libnftables/chain.h   |    1 +
 include/libnftables/rule.h    |    1 +
 include/libnftables/ruleset.h |    1 +
 include/libnftables/set.h     |    2 ++
 include/libnftables/table.h   |    1 +
 src/chain.c                   |   15 +++++++++++++++
 src/internal.h                |    8 +++++++-
 src/libnftables.map           |    6 ++++++
 src/rule.c                    |   14 ++++++++++++++
 src/ruleset.c                 |   14 ++++++++++++++
 src/set.c                     |   14 ++++++++++++++
 src/set_elem.c                |   14 ++++++++++++++
 src/table.c                   |   14 ++++++++++++++
 src/utils.c                   |   34 ++++++++++++++++++++++++++++++++++
 14 files changed, 138 insertions(+), 1 deletion(-)


--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Pablo Neira Ayuso Jan. 2, 2014, 1:52 p.m. UTC | #1
On Thu, Jan 02, 2014 at 02:21:03PM +0100, Arturo Borrero Gonzalez wrote:
> This patch adds API interfaces to parse nft objects from a given filename.
> 
> I found this useful in `nft', where I'm trying to parse XML/JSON from a file.
> 
> Examples will be updated in a separated patch.
> 
> Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
> ---
>  include/libnftables/chain.h   |    1 +
>  include/libnftables/rule.h    |    1 +
>  include/libnftables/ruleset.h |    1 +
>  include/libnftables/set.h     |    2 ++
>  include/libnftables/table.h   |    1 +
>  src/chain.c                   |   15 +++++++++++++++
>  src/internal.h                |    8 +++++++-
>  src/libnftables.map           |    6 ++++++
>  src/rule.c                    |   14 ++++++++++++++
>  src/ruleset.c                 |   14 ++++++++++++++
>  src/set.c                     |   14 ++++++++++++++
>  src/set_elem.c                |   14 ++++++++++++++
>  src/table.c                   |   14 ++++++++++++++
>  src/utils.c                   |   34 ++++++++++++++++++++++++++++++++++
>  14 files changed, 138 insertions(+), 1 deletion(-)
> 
> diff --git a/include/libnftables/chain.h b/include/libnftables/chain.h
> index 8b4eab9..619088f 100644
> --- a/include/libnftables/chain.h
> +++ b/include/libnftables/chain.h
> @@ -52,6 +52,7 @@ struct nlmsghdr;
>  void nft_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nft_chain *t);
>  
>  int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type, const char *data);
> +int nft_chain_fparse(struct nft_chain *c, enum nft_parse_type type, const char *filename);

Please, rework this to pass a file descriptor instead so it's
consistent with _fprintf API and we can use it with pipes as well.
Thanks.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arturo Borrero Jan. 2, 2014, 6:47 p.m. UTC | #2
On 2 January 2014 14:52, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
>
> Please, rework this to pass a file descriptor instead so it's
> consistent with _fprintf API and we can use it with pipes as well.

Should I do a fread() based input?:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

If so, the API func may look like:

int nft_chain_fparse(struct nft_chain *c, type, size_t size, FILE *stream);

And then I will need to malloc(size).

Is this OK?

regards.
Pablo Neira Ayuso Jan. 2, 2014, 7:21 p.m. UTC | #3
On Thu, Jan 02, 2014 at 07:47:38PM +0100, Arturo Borrero Gonzalez wrote:
> On 2 January 2014 14:52, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> >
> > Please, rework this to pass a file descriptor instead so it's
> > consistent with _fprintf API and we can use it with pipes as well.
> 
> Should I do a fread() based input?:
> 
> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
> 
> If so, the API func may look like:
> 
> int nft_chain_fparse(struct nft_chain *c, type, size_t size, FILE *stream);

That interface is fine.

> And then I will need to malloc(size).

Please, explain why you need this.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/include/libnftables/chain.h b/include/libnftables/chain.h
index 8b4eab9..619088f 100644
--- a/include/libnftables/chain.h
+++ b/include/libnftables/chain.h
@@ -52,6 +52,7 @@  struct nlmsghdr;
 void nft_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nft_chain *t);
 
 int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type, const char *data);
+int nft_chain_fparse(struct nft_chain *c, enum nft_parse_type type, const char *filename);
 int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *t, uint32_t type, uint32_t flags);
 int nft_chain_fprintf(FILE *fp, struct nft_chain *c, uint32_t type, uint32_t flags);
 
diff --git a/include/libnftables/rule.h b/include/libnftables/rule.h
index 86dbc17..1f53acd 100644
--- a/include/libnftables/rule.h
+++ b/include/libnftables/rule.h
@@ -48,6 +48,7 @@  struct nlmsghdr;
 void nft_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_rule *t);
 
 int nft_rule_parse(struct nft_rule *r, enum nft_parse_type type, const char *data);
+int nft_rule_fparse(struct nft_rule *r, enum nft_parse_type type, const char *filename);
 int nft_rule_snprintf(char *buf, size_t size, struct nft_rule *t, uint32_t type, uint32_t flags);
 int nft_rule_fprintf(FILE *fp, struct nft_rule *r, uint32_t type, uint32_t flags);
 
diff --git a/include/libnftables/ruleset.h b/include/libnftables/ruleset.h
index 1ec3059..210da80 100644
--- a/include/libnftables/ruleset.h
+++ b/include/libnftables/ruleset.h
@@ -31,6 +31,7 @@  void nft_ruleset_attr_set(struct nft_ruleset *r, uint16_t attr, void *data);
 const void *nft_ruleset_attr_get(const struct nft_ruleset *r, uint16_t attr);
 
 int nft_ruleset_parse(struct nft_ruleset *rs, enum nft_parse_type type, const char *data);
+int nft_ruleset_fparse(struct nft_ruleset *rs, enum nft_parse_type type, const char *filename);
 int nft_ruleset_snprintf(char *buf, size_t size, const struct nft_ruleset *rs, uint32_t type, uint32_t flags);
 int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type, uint32_t flags);
 
diff --git a/include/libnftables/set.h b/include/libnftables/set.h
index 13ac857..c27e8b0 100644
--- a/include/libnftables/set.h
+++ b/include/libnftables/set.h
@@ -61,6 +61,7 @@  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);
 
 int nft_set_parse(struct nft_set *s, enum nft_parse_type type, const char *data);
+int nft_set_fparse(struct nft_set *s, enum nft_parse_type type, const char *filename);
 
 /*
  * Set elements
@@ -99,6 +100,7 @@  void nft_set_elem_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_set_elem
 int 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_parse_type type, const char *data);
+int nft_set_elem_fparse(struct nft_set_elem *e, enum nft_parse_type type, const char *filename);
 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_fprintf(FILE *fp, struct nft_set_elem *se, uint32_t type, uint32_t flags);
 
diff --git a/include/libnftables/table.h b/include/libnftables/table.h
index 1d2be07..562b955 100644
--- a/include/libnftables/table.h
+++ b/include/libnftables/table.h
@@ -41,6 +41,7 @@  struct nlmsghdr;
 void nft_table_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nft_table *t);
 
 int nft_table_parse(struct nft_table *t, enum nft_parse_type type, const char *data);
+int nft_table_fparse(struct nft_table *t, enum nft_parse_type type, const char *filename);
 int nft_table_snprintf(char *buf, size_t size, struct nft_table *t, uint32_t type, uint32_t flags);
 int nft_table_fprintf(FILE *fp, struct nft_table *t, uint32_t type, uint32_t flags);
 
diff --git a/src/chain.c b/src/chain.c
index a0004b5..aa689d3 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -741,6 +741,21 @@  int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type,
 }
 EXPORT_SYMBOL(nft_chain_parse);
 
+static inline int nft_chain_do_fparse(void *c,
+				      enum nft_parse_type type,
+				      const char *buf)
+{
+	return nft_chain_parse(c, type, buf);
+}
+
+int nft_chain_fparse(struct nft_chain *c, enum nft_parse_type type,
+		     const char *filename)
+{
+	return nft_fparse(c, type, filename, nft_chain_do_fparse);
+}
+EXPORT_SYMBOL(nft_chain_fparse);
+
+
 static int nft_chain_snprintf_json(char *buf, size_t size, struct nft_chain *c)
 {
 	int ret, len = size, offset = 0;
diff --git a/src/internal.h b/src/internal.h
index a10d874..5dcbc4e 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -91,8 +91,14 @@  int nft_str2verdict(const char *verdict);
 int nft_get_value(enum nft_type type, void *val, void *out);
 
 #include <stdio.h>
-int nft_fprintf(FILE *fp, void *obj, uint32_t type, uint32_t flags, int (*snprintf_cb)(char *buf, size_t bufsiz, void *obj, uint32_t type, uint32_t flags));
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
 
+#include <libnftables/common.h>
+int nft_fprintf(FILE *fp, void *obj, uint32_t type, uint32_t flags, int (*snprintf_cb)(char *buf, size_t bufsiz, void *obj, uint32_t type, uint32_t flags));
+int nft_fparse(void *obj, enum nft_parse_type type, const char *filename, int (*parse_cb)(void *obj, enum nft_parse_type type, const char *data));
 void xfree(const void *ptr);
 
 struct expr_ops;
diff --git a/src/libnftables.map b/src/libnftables.map
index 7dc9aee..eb5ed5c 100644
--- a/src/libnftables.map
+++ b/src/libnftables.map
@@ -13,6 +13,7 @@  global:
   nft_table_attr_get_u32;
   nft_table_attr_get_str;
   nft_table_parse;
+  nft_table_fparse;
   nft_table_snprintf;
   nft_table_fprintf;
   nft_table_nlmsg_build_payload;
@@ -45,6 +46,7 @@  global:
   nft_chain_attr_get_u64;
   nft_chain_attr_get_str;
   nft_chain_parse;
+  nft_chain_fparse;
   nft_chain_snprintf;
   nft_chain_fprintf;
   nft_chain_nlmsg_build_payload;
@@ -74,6 +76,7 @@  global:
   nft_rule_attr_get_u64;
   nft_rule_attr_get_str;
   nft_rule_parse;
+  nft_rule_fparse;
   nft_rule_snprintf;
   nft_rule_fprintf;
   nft_rule_nlmsg_build_payload;
@@ -128,6 +131,7 @@  global:
   nft_set_nlmsg_build_payload;
   nft_set_nlmsg_parse;
   nft_set_parse;
+  nft_set_fparse;
   nft_set_snprintf;
   nft_set_fprintf;
 
@@ -159,6 +163,7 @@  global:
   nft_set_elem_nlmsg_build_payload;
   nft_set_elem_nlmsg_parse;
   nft_set_elem_parse;
+  nft_set_elem_fparse;
   nft_set_elem_snprintf;
   nft_set_elem_fprinf;
 
@@ -179,6 +184,7 @@  global:
   nft_ruleset_attr_set;
   nft_ruleset_attr_get;
   nft_ruleset_parse;
+  nft_ruleset_fparse;
   nft_ruleset_snprintf;
   nft_ruleset_fprintf;
 
diff --git a/src/rule.c b/src/rule.c
index 280350a..863c436 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -659,6 +659,20 @@  int nft_rule_parse(struct nft_rule *r, enum nft_parse_type type,
 }
 EXPORT_SYMBOL(nft_rule_parse);
 
+static inline int nft_rule_do_fparse(void *r,
+				     enum nft_parse_type type,
+				     const char *buf)
+{
+	return nft_rule_parse(r, type, buf);
+}
+
+int nft_rule_fparse(struct nft_rule *r, enum nft_parse_type type,
+		    const char *filename)
+{
+	return nft_fparse(r, type, filename, nft_rule_do_fparse);
+}
+EXPORT_SYMBOL(nft_rule_fparse);
+
 static int nft_rule_snprintf_json(char *buf, size_t size, struct nft_rule *r,
 					 uint32_t type, uint32_t flags)
 {
diff --git a/src/ruleset.c b/src/ruleset.c
index f591382..7194b02 100644
--- a/src/ruleset.c
+++ b/src/ruleset.c
@@ -579,6 +579,20 @@  int nft_ruleset_parse(struct nft_ruleset *r, enum nft_parse_type type,
 }
 EXPORT_SYMBOL(nft_ruleset_parse);
 
+static inline int nft_ruleset_do_fparse(void *rs,
+					enum nft_parse_type type,
+					const char *buf)
+{
+	return nft_ruleset_parse(rs, type, buf);
+}
+
+int nft_ruleset_fparse(struct nft_ruleset *rs, enum nft_parse_type type,
+		       const char *filename)
+{
+	return nft_fparse(rs, type, filename, nft_ruleset_do_fparse);
+}
+EXPORT_SYMBOL(nft_ruleset_fparse);
+
 static const char *nft_ruleset_o_opentag(uint32_t type)
 {
 	switch (type) {
diff --git a/src/set.c b/src/set.c
index c5204cc..43dd489 100644
--- a/src/set.c
+++ b/src/set.c
@@ -516,6 +516,20 @@  int nft_set_parse(struct nft_set *s, enum nft_parse_type type,
 }
 EXPORT_SYMBOL(nft_set_parse);
 
+static inline int nft_set_do_fparse(void *s,
+				    enum nft_parse_type type,
+				    const char *buf)
+{
+	return nft_set_parse(s, type, buf);
+}
+
+int nft_set_fparse(struct nft_set *s, enum nft_parse_type type,
+		   const char *filename)
+{
+	return nft_fparse(s, type, filename, nft_set_do_fparse);
+}
+EXPORT_SYMBOL(nft_set_fparse);
+
 static int nft_set_snprintf_json(char *buf, size_t size, struct nft_set *s,
 				  uint32_t type, uint32_t flags)
 {
diff --git a/src/set_elem.c b/src/set_elem.c
index fce9c1d..9724142 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -430,6 +430,20 @@  int nft_set_elem_parse(struct nft_set_elem *e,
 }
 EXPORT_SYMBOL(nft_set_elem_parse);
 
+static inline int nft_set_elem_do_fparse(void *e,
+					 enum nft_parse_type type,
+					 const char *buf)
+{
+	return nft_set_elem_parse(e, type, buf);
+}
+
+int nft_set_elem_fparse(struct nft_set_elem *e, enum nft_parse_type type,
+			const char *filename)
+{
+	return nft_fparse(e, type, filename, nft_set_elem_do_fparse);
+}
+EXPORT_SYMBOL(nft_set_elem_fparse);
+
 static int nft_set_elem_snprintf_json(char *buf, size_t size,
 				      struct nft_set_elem *e, uint32_t flags)
 {
diff --git a/src/table.c b/src/table.c
index ba84264..4cf047d 100644
--- a/src/table.c
+++ b/src/table.c
@@ -357,6 +357,20 @@  int nft_table_parse(struct nft_table *t, enum nft_parse_type type,
 }
 EXPORT_SYMBOL(nft_table_parse);
 
+static inline int nft_table_do_fparse(void *t,
+				      enum nft_parse_type type,
+				      const char *buf)
+{
+	return nft_table_parse(t, type, buf);
+}
+
+int nft_table_fparse(struct nft_table *t, enum nft_parse_type type,
+		     const char *filename)
+{
+	return nft_fparse(t, type, filename, nft_table_do_fparse);
+}
+EXPORT_SYMBOL(nft_table_fparse);
+
 static int nft_table_snprintf_json(char *buf, size_t size, struct nft_table *t)
 {
 	return snprintf(buf, size,
diff --git a/src/utils.c b/src/utils.c
index 2415917..713541d 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -16,6 +16,7 @@ 
 #include <arpa/inet.h>
 #include <errno.h>
 #include <inttypes.h>
+#include <unistd.h>
 
 #include <linux/netfilter.h>
 #include <linux/netfilter/nf_tables.h>
@@ -201,3 +202,36 @@  int nft_fprintf(FILE *fp, void *obj, uint32_t type, uint32_t flags,
 
 	return ret;
 }
+
+int nft_fparse(void *obj, enum nft_parse_type type, const char *filename,
+	       int (*parse_cb)(void *obj, enum nft_parse_type type,
+			       const char *data))
+{
+	char *buf;
+	struct stat s;
+	int fd, ret;
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0)
+		return -1;
+
+	fstat(fd, &s);
+	buf = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+
+	if (buf == (void *)-1)
+		goto err;
+
+	ret = parse_cb(obj, type, buf);
+	if (ret < 0)
+		goto err_unmap;
+
+	munmap(buf, s.st_size);
+	close(fd);
+	return ret;
+
+err_unmap:
+	munmap(buf, s.st_size);
+err:
+	close(fd);
+	return -1;
+}