Skip to contentSkip to conversation

src: add import operation

RFC PATCH In review Arturo Borrero Gonzalez 2 participants 2 messages Oct 21, 2014 – Nov 12, 2014 netfilter

lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 src: add import operation

The import operation reads a XML or JSON file, with syntax:
% nft import {xml|json}

A basic way to test this new functionality is:
% nft export xml | nft import xml

---

NOTE: This patchs requires:
* [nft] mnl: delete useless parameter nf_sock in batch functions
* [libnftnl] ruleset: deconstify _get interface

Please comment :-)

 include/mnl.h     |   12 ++++
 include/netlink.h |    4 +
 include/rule.h    |   13 ++++
 src/evaluate.c    |    1 
 src/mnl.c         |  170 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/netlink.c     |   64 ++++++++++++++++++++
 src/parser.y      |   20 +++++-
 src/rule.c        |   52 ++++++++++++++++
 src/scanner.l     |    1 
 9 files changed, 330 insertions(+), 7 deletions(-)
include/mnl.h +12 -0
index a0dfa1b..4126f18 100644
@@ -24,6 +24,8 @@ void mnl_batch_end(void);
 int mnl_batch_talk(struct mnl_socket *nl, struct list_head *err_list);
 int mnl_nft_rule_batch_add(struct nft_rule *nlr, unsigned int flags,
 			   uint32_t seqnum);
+int mnl_nft_rule_list_batch_add(struct nft_rule_list *nlrl,
+				unsigned int flags);
 int mnl_nft_rule_batch_del(struct nft_rule *nlr, unsigned int flags,
 			   uint32_t seqnum);
 
@@ -38,6 +40,8 @@ int mnl_nft_chain_add(struct mnl_socket *nf_sock, struct nft_chain *nlc,
 		      unsigned int flags);
 int mnl_nft_chain_batch_add(struct nft_chain *nlc,
 			    unsigned int flags, uint32_t seq);
+int mnl_nft_chain_list_batch_add(struct nft_chain_list *nlcl,
+				 unsigned int flags);
 int mnl_nft_chain_delete(struct mnl_socket *nf_sock, struct nft_chain *nlc,
                          unsigned int flags);
 int mnl_nft_chain_batch_del(struct nft_chain *nlc,
@@ -51,6 +55,8 @@ int mnl_nft_table_add(struct mnl_socket *nf_sock, struct nft_table *nlt,
 		      unsigned int flags);
 int mnl_nft_table_batch_add(struct nft_table *nlt,
 			    unsigned int flags, uint32_t seq);
+int mnl_nft_table_list_batch_add(struct nft_table_list *nltl,
+				 unsigned int flags);
 int mnl_nft_table_delete(struct mnl_socket *nf_sock, struct nft_table *nlt,
 			 unsigned int flags);
 int mnl_nft_table_batch_del(struct nft_table *nlt,
@@ -64,6 +70,7 @@ int mnl_nft_set_add(struct mnl_socket *nf_sock, struct nft_set *nls,
 		    unsigned int flags);
 int mnl_nft_set_batch_add(struct nft_set *nls,
 			  unsigned int flags, uint32_t seq);
+int mnl_nft_set_list_batch_add(struct nft_set_list *nlsl, unsigned int flags);
 int mnl_nft_set_delete(struct mnl_socket *nf_sock, struct nft_set *nls,
 		       unsigned int flags);
 int mnl_nft_set_batch_del(struct nft_set *nls,
@@ -76,6 +83,8 @@ int mnl_nft_setelem_add(struct mnl_socket *nf_sock, struct nft_set *nls,
 			unsigned int flags);
 int mnl_nft_setelem_batch_add(struct nft_set *nls,
 			      unsigned int flags, uint32_t seq);
+int mnl_nft_setelem_set_list_batch_add(struct nft_set_list *nlsl,
+				       unsigned int flags);
 int mnl_nft_setelem_delete(struct mnl_socket *nf_sock, struct nft_set *nls,
 			   unsigned int flags);
 int mnl_nft_setelem_batch_del(struct nft_set *nls,
@@ -84,6 +93,9 @@ int mnl_nft_setelem_get(struct mnl_socket *nf_sock, struct nft_set *nls);
 
 struct nft_ruleset *mnl_nft_ruleset_dump(struct mnl_socket *nf_sock,
 					 uint32_t family);
+int mnl_nft_ruleset_batch_add(const struct nft_ruleset *rs,
+			      uint32_t table_flags, uint32_t chain_flags,
+			      uint32_t sets_flags, uint32_t rule_flags);
 int mnl_nft_event_listener(struct mnl_socket *nf_sock,
 			   int (*cb)(const struct nlmsghdr *nlh, void *data),
 			   void *cb_data);
include/netlink.h +4 -0
index 4f79470..6584277 100644
@@ -154,6 +154,10 @@ extern int netlink_flush_ruleset(struct netlink_ctx *ctx,
 extern struct nft_ruleset *netlink_dump_ruleset(struct netlink_ctx *ctx,
 						const struct handle *h,
 						const struct location *loc);
+int netlink_add_ruleset(struct netlink_ctx *ctx, const struct handle *h,
+			const struct location *loc,
+			struct nft_ruleset *rs);
+
 struct netlink_mon_handler {
 	uint32_t		monitor_flags;
 	uint32_t		format;
include/rule.h +12 -1
index 936177b..4669ba4 100644
@@ -223,6 +223,7 @@ extern void set_print_plain(const struct set *s);
  * @CMD_FLUSH:		flush container
  * @CMD_RENAME:		rename object
  * @CMD_EXPORT:		export the ruleset in a given format
+ * @CMD_IMPORT:		import a ruleset in a given format
  * @CMD_MONITOR:	event listener
  * @CMD_DESCRIBE:	describe an expression
  */
@@ -236,6 +237,7 @@ enum cmd_ops {
 	CMD_FLUSH,
 	CMD_RENAME,
 	CMD_EXPORT,
+	CMD_IMPORT,
 	CMD_MONITOR,
 	CMD_DESCRIBE,
 };
@@ -254,6 +256,7 @@ enum cmd_ops {
  * @CMD_OBJ_EXPR:	expression
  * @CMD_OBJ_MONITOR:	monitor
  * @CMD_OBJ_EXPORT:	export
+ * @CMD_OBJ_IMPORT:	import
  */
 enum cmd_obj {
 	CMD_OBJ_INVALID,
@@ -267,6 +270,7 @@ enum cmd_obj {
 	CMD_OBJ_EXPR,
 	CMD_OBJ_MONITOR,
 	CMD_OBJ_EXPORT,
+	CMD_OBJ_IMPORT,
 };
 
 struct export {
@@ -276,6 +280,13 @@ struct export {
 struct export *export_alloc(uint32_t format);
 void export_free(struct export *e);
 
+struct import {
+	uint32_t	format;
+};
+
+struct import *import_alloc(uint32_t format);
+void import_free(struct import *i);
+
 enum {
 	CMD_MONITOR_OBJ_ANY,
 	CMD_MONITOR_OBJ_TABLES,
@@ -308,7 +319,6 @@ void monitor_free(struct monitor *m);
  * @seqnum:	sequence number to match netlink errors
  * @union:	object
  * @arg:	argument data
- * @format:	info about the export/import format
  */
 struct cmd {
 	struct list_head	list;
@@ -326,6 +336,7 @@ struct cmd {
 		struct table	*table;
 		struct monitor	*monitor;
 		struct export	*export;
+		struct import	*import;
 	};
 	const void		*arg;
 };
src/evaluate.c +1 -0
index d61d76b..6085d5f 100644
@@ -1776,6 +1776,7 @@ int cmd_evaluate(struct eval_ctx *ctx, struct cmd *cmd)
 	case CMD_FLUSH:
 	case CMD_RENAME:
 	case CMD_EXPORT:
+	case CMD_IMPORT:
 	case CMD_DESCRIBE:
 		return 0;
 	case CMD_MONITOR:
src/mnl.c +167 -3

218 lines not on this page · raw message

src/netlink.c +64 -0

76 lines not on this page · raw message

src/parser.y +17 -3
index 9e9a839..d1f884c 100644
@@ -189,6 +189,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %token RENAME			"rename"
 %token DESCRIBE			"describe"
 %token EXPORT			"export"
+%token IMPORT			"import"
 %token MONITOR			"monitor"
 
 %token ACCEPT			"accept"
@@ -396,8 +397,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %type <cmd>			line
 %destructor { cmd_free($$); }	line
 
-%type <cmd>			base_cmd add_cmd create_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd export_cmd monitor_cmd describe_cmd
-%destructor { cmd_free($$); }	base_cmd add_cmd create_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd export_cmd monitor_cmd describe_cmd
+%type <cmd>			base_cmd add_cmd create_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd export_cmd import_cmd monitor_cmd describe_cmd
+%destructor { cmd_free($$); }	base_cmd add_cmd create_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd export_cmd import_cmd monitor_cmd describe_cmd
 
 %type <handle>			table_spec tables_spec chain_spec chain_identifier ruleid_spec ruleset_spec
 %destructor { handle_free(&$$); } table_spec tables_spec chain_spec chain_identifier ruleid_spec ruleset_spec
@@ -529,7 +530,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %destructor { expr_free($$); }	ct_expr
 %type <val>			ct_key
 
-%type <val>			export_format
+%type <val>			export_format	import_format
 %type <string>			monitor_event
 %destructor { xfree($$); }	monitor_event
 %type <val>			monitor_object	monitor_format
@@ -632,6 +633,7 @@ base_cmd		:	/* empty */	add_cmd		{ $$ = $1; }
 			|	FLUSH		flush_cmd	{ $$ = $2; }
 			|	RENAME		rename_cmd	{ $$ = $2; }
 			|	EXPORT		export_cmd	{ $$ = $2; }
+			|	IMPORT		import_cmd	{ $$ = $2; }
 			|	MONITOR		monitor_cmd	{ $$ = $2; }
 			|	DESCRIBE	describe_cmd	{ $$ = $2; }
 			;
@@ -803,6 +805,14 @@ export_cmd		:	export_format
 			}
 			;
 
+import_cmd		:	import_format
+			{
+				struct handle h = { .family = NFPROTO_UNSPEC };
+				struct import *import = import_alloc($1);
+				$$ = cmd_alloc(CMD_IMPORT, CMD_OBJ_IMPORT, &h, &@$, import);
+			}
+			;
+
 monitor_cmd		:	monitor_event	monitor_object	monitor_format
 			{
 				struct handle h = { .family = NFPROTO_UNSPEC };
@@ -832,6 +842,10 @@ export_format		: 	XML 		{ $$ = NFT_OUTPUT_XML; }
 			|	JSON		{ $$ = NFT_OUTPUT_JSON; }
 			;
 
+import_format		: 	XML 		{ $$ = NFT_PARSE_XML; }
+			|	JSON		{ $$ = NFT_PARSE_JSON; }
+			;
+
 describe_cmd		:	primary_expr
 			{
 				struct handle h = { .family = NFPROTO_UNSPEC };
src/rule.c +52 -0

76 lines not on this page · raw message

src/scanner.l +1 -0
index 32e59d9..880cb2f 100644
@@ -259,6 +259,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "flush"			{ return FLUSH; }
 "rename"		{ return RENAME; }
 "export"		{ return EXPORT; }
+"import"		{ return IMPORT; }
 "monitor"		{ return MONITOR; }
 
 "position"		{ return POSITION; }
#1 lore raw
Quoted 6 lines · Arturo Borrero Gonzalez

The import operation reads a XML or JSON file, with syntax:
% nft import {xml|json}

A basic way to test this new functionality is:
% nft export xml | nft import xml

Quoted 8 lines

---

NOTE: This patchs requires:
* [nft] mnl: delete useless parameter nf_sock in batch functions
* [libnftnl] ruleset: deconstify _get interface

Please comment :-)

The existing approach doesn't support incremental updates. I think it's important to provide a way to say: 'add this and delete that' when importing something too, so this interface becomes equivalent to nft -f.

I think we need a new _parse_file() function to takes a callback as argument. This callback is invoked per object parsed from the file, so we can reuse the existing "struct cmd" in nft. I think it's important to consolidate code, the existing approach where we have different code to do basically the same is not desirable.

Quoted 3 lines
src/mnl.c +3 -0
+int mnl_nft_ruleset_batch_add(const struct nft_ruleset *rs,
+			      uint32_t table_flags, uint32_t chain_flags,
+			      uint32_t set_flags, uint32_t rule_flags)

[...]

src/netlink.c struct nft_ruleset *netlink_dump_ruleset(struct netlink_ctx *ctx, · line 1569

Quoted 1 line
src/netlink.c +1 -0
+	ret = mnl_nft_ruleset_batch_add(rs, 0, 0, 0, 0);

So we don't make any global assumption on the flags and so on.

Thanks.