diff options
author | Patrick McHardy <kaber@trash.net> | 2014-01-21 12:39:31 +0000 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2014-01-21 12:39:31 +0000 |
commit | 0e9a6ee6aa16d90633acc3cf60836a140f2c5d87 (patch) | |
tree | 3becbe32d7d5b3885b93362d034413c144218252 | |
parent | a085d80754af0be8e650724329187aa69e23630d (diff) |
cmd: add create command for tables and chains
We currently always use NLM_F_EXCL for add, which makes adding existing
chains or tables fail. There's usually no reason why you would care about
this, so change "add" to not use NLM_F_EXCL and add a new "create" command
in case you do care.
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | include/netlink.h | 4 | ||||
-rw-r--r-- | include/rule.h | 4 | ||||
-rw-r--r-- | src/evaluate.c | 1 | ||||
-rw-r--r-- | src/mnl.c | 14 | ||||
-rw-r--r-- | src/netlink.c | 10 | ||||
-rw-r--r-- | src/parser.y | 31 | ||||
-rw-r--r-- | src/rule.c | 22 | ||||
-rw-r--r-- | src/scanner.l | 1 |
8 files changed, 62 insertions, 25 deletions
diff --git a/include/netlink.h b/include/netlink.h index fbaaaeba..3f8d465c 100644 --- a/include/netlink.h +++ b/include/netlink.h @@ -82,7 +82,7 @@ extern int netlink_del_rule_batch(struct netlink_ctx *ctx, extern int netlink_add_chain(struct netlink_ctx *ctx, const struct handle *h, const struct location *loc, - const struct chain *chain); + const struct chain *chain, bool excl); extern int netlink_rename_chain(struct netlink_ctx *ctx, const struct handle *h, const struct location *loc, const char *name); extern int netlink_delete_chain(struct netlink_ctx *ctx, const struct handle *h, @@ -98,7 +98,7 @@ extern int netlink_flush_chain(struct netlink_ctx *ctx, const struct handle *h, extern int netlink_add_table(struct netlink_ctx *ctx, const struct handle *h, const struct location *loc, - const struct table *table); + const struct table *table, bool excl); extern int netlink_delete_table(struct netlink_ctx *ctx, const struct handle *h, const struct location *loc); extern int netlink_list_tables(struct netlink_ctx *ctx, const struct handle *h, diff --git a/include/rule.h b/include/rule.h index 2a7b7980..30a4d12c 100644 --- a/include/rule.h +++ b/include/rule.h @@ -198,7 +198,8 @@ extern void set_print(const struct set *set); * enum cmd_ops - command operations * * @CMD_INVALID: invalid - * @CMD_ADD: add object + * @CMD_ADD: add object (non-exclusive) + * @CMD_CREATE: create object (exclusive) * @CMD_INSERT: insert object * @CMD_DELETE: delete object * @CMD_LIST: list container @@ -208,6 +209,7 @@ extern void set_print(const struct set *set); enum cmd_ops { CMD_INVALID, CMD_ADD, + CMD_CREATE, CMD_INSERT, CMD_DELETE, CMD_LIST, diff --git a/src/evaluate.c b/src/evaluate.c index 2b2427a5..cf30ed92 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1397,6 +1397,7 @@ static int cmd_evaluate(struct eval_ctx *ctx, struct cmd *cmd) ctx->cmd = cmd; switch (cmd->op) { case CMD_ADD: + case CMD_CREATE: case CMD_INSERT: return cmd_evaluate_add(ctx, cmd); case CMD_DELETE: @@ -280,7 +280,7 @@ int mnl_nft_rule_batch_add(struct nft_rule *nlr, unsigned int flags, nlh = nft_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch), NFT_MSG_NEWRULE, nft_rule_attr_get_u32(nlr, NFT_RULE_ATTR_FAMILY), - flags|NLM_F_CREATE, seqnum); + NLM_F_CREATE | flags, seqnum); nft_rule_nlmsg_build_payload(nlh, nlr); if (!mnl_nlmsg_batch_next(batch)) @@ -318,7 +318,7 @@ int mnl_nft_rule_add(struct mnl_socket *nf_sock, struct nft_rule *nlr, nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, nft_rule_attr_get_u32(nlr, NFT_RULE_ATTR_FAMILY), - flags|NLM_F_ACK|NLM_F_CREATE, seq); + NLM_F_ACK | NLM_F_CREATE | flags, seq); nft_rule_nlmsg_build_payload(nlh, nlr); return mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL); @@ -394,7 +394,7 @@ int mnl_nft_chain_add(struct mnl_socket *nf_sock, struct nft_chain *nlc, nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_FAMILY), - NLM_F_CREATE|NLM_F_ACK|flags, seq); + NLM_F_CREATE | NLM_F_ACK | flags, seq); nft_chain_nlmsg_build_payload(nlh, nlc); return mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL); @@ -472,7 +472,7 @@ int mnl_nft_chain_get(struct mnl_socket *nf_sock, struct nft_chain *nlc, nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_FAMILY), - NLM_F_ACK|flags, seq); + NLM_F_ACK | flags, seq); nft_chain_nlmsg_build_payload(nlh, nlc); return mnl_talk(nf_sock, nlh, nlh->nlmsg_len, chain_get_cb, nlc); @@ -489,7 +489,7 @@ int mnl_nft_table_add(struct mnl_socket *nf_sock, struct nft_table *nlt, nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, nft_table_attr_get_u32(nlt, NFT_TABLE_ATTR_FAMILY), - NLM_F_EXCL|NLM_F_ACK, seq); + NLM_F_ACK | flags, seq); nft_table_nlmsg_build_payload(nlh, nlt); return mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL); @@ -590,7 +590,7 @@ int mnl_nft_set_add(struct mnl_socket *nf_sock, struct nft_set *nls, nlh = nft_set_nlmsg_build_hdr(buf, NFT_MSG_NEWSET, nft_set_attr_get_u32(nls, NFT_SET_ATTR_FAMILY), - flags|NLM_F_CREATE|NLM_F_ACK, seq); + NLM_F_CREATE | NLM_F_ACK | flags, seq); nft_set_nlmsg_build_payload(nlh, nls); return mnl_talk(nf_sock, nlh, nlh->nlmsg_len, set_add_cb, nls); @@ -695,7 +695,7 @@ int mnl_nft_setelem_add(struct mnl_socket *nf_sock, struct nft_set *nls, nlh = nft_set_elem_nlmsg_build_hdr(buf, NFT_MSG_NEWSETELEM, nft_set_attr_get_u32(nls, NFT_SET_ATTR_FAMILY), - NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK, seq); + NLM_F_CREATE | NLM_F_ACK | flags, seq); nft_set_elems_nlmsg_build_payload(nlh, nls); return mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL); diff --git a/src/netlink.c b/src/netlink.c index 7f69995d..84be505d 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -451,7 +451,8 @@ void netlink_dump_chain(struct nft_chain *nlc) } int netlink_add_chain(struct netlink_ctx *ctx, const struct handle *h, - const struct location *loc, const struct chain *chain) + const struct location *loc, const struct chain *chain, + bool excl) { struct nft_chain *nlc; int err; @@ -466,7 +467,7 @@ int netlink_add_chain(struct netlink_ctx *ctx, const struct handle *h, chain->type); } netlink_dump_chain(nlc); - err = mnl_nft_chain_add(nf_sock, nlc, NLM_F_EXCL); + err = mnl_nft_chain_add(nf_sock, nlc, excl ? NLM_F_EXCL : 0); nft_chain_free(nlc); if (err < 0) @@ -625,13 +626,14 @@ int netlink_flush_chain(struct netlink_ctx *ctx, const struct handle *h, } int netlink_add_table(struct netlink_ctx *ctx, const struct handle *h, - const struct location *loc, const struct table *table) + const struct location *loc, const struct table *table, + bool excl) { struct nft_table *nlt; int err; nlt = alloc_nft_table(h); - err = mnl_nft_table_add(nf_sock, nlt, NLM_F_EXCL); + err = mnl_nft_table_add(nf_sock, nlt, excl ? NLM_F_EXCL : 0); nft_table_free(nlt); if (err < 0) diff --git a/src/parser.y b/src/parser.y index 3e3abedd..cd9ade14 100644 --- a/src/parser.y +++ b/src/parser.y @@ -169,6 +169,7 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token INET "inet" %token ADD "add" +%token CREATE "create" %token INSERT "insert" %token DELETE "delete" %token LIST "list" @@ -351,8 +352,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 insert_cmd delete_cmd list_cmd flush_cmd rename_cmd -%destructor { cmd_free($$); } base_cmd add_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd +%type <cmd> base_cmd add_cmd create_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd +%destructor { cmd_free($$); } base_cmd add_cmd create_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd %type <handle> table_spec tables_spec chain_spec chain_identifier ruleid_spec %destructor { handle_free(&$$); } table_spec tables_spec chain_spec chain_identifier ruleid_spec @@ -537,6 +538,7 @@ line : common_block { $$ = NULL; } base_cmd : /* empty */ add_cmd { $$ = $1; } | ADD add_cmd { $$ = $2; } + | CREATE create_cmd { $$ = $2; } | INSERT insert_cmd { $$ = $2; } | DELETE delete_cmd { $$ = $2; } | LIST list_cmd { $$ = $2; } @@ -601,6 +603,31 @@ add_cmd : TABLE table_spec } ; +create_cmd : TABLE table_spec + { + $$ = cmd_alloc(CMD_CREATE, CMD_OBJ_TABLE, &$2, &@$, NULL); + } + | TABLE table_spec table_block_alloc + '{' table_block '}' + { + handle_merge(&$3->handle, &$2); + close_scope(state); + $$ = cmd_alloc(CMD_CREATE, CMD_OBJ_TABLE, &$2, &@$, $5); + } + | CHAIN chain_spec + { + $$ = cmd_alloc(CMD_CREATE, CMD_OBJ_CHAIN, &$2, &@$, NULL); + } + | CHAIN chain_spec chain_block_alloc + '{' chain_block '}' + { + $5->location = @5; + handle_merge(&$3->handle, &$2); + close_scope(state); + $$ = cmd_alloc(CMD_CREATE, CMD_OBJ_CHAIN, &$2, &@$, $5); + } + ; + insert_cmd : RULE ruleid_spec rule { $$ = cmd_alloc(CMD_INSERT, CMD_OBJ_RULE, &$2, &@$, $3); @@ -462,9 +462,10 @@ void cmd_free(struct cmd *cmd) #include <netlink.h> static int do_add_chain(struct netlink_ctx *ctx, const struct handle *h, - const struct location *loc, struct chain *chain) + const struct location *loc, struct chain *chain, + bool excl) { - if (netlink_add_chain(ctx, h, loc, chain) < 0) + if (netlink_add_chain(ctx, h, loc, chain, excl) < 0) return -1; if (chain != NULL) { if (netlink_add_rule_list(ctx, h, &chain->rules) < 0) @@ -496,12 +497,13 @@ static int do_add_set(struct netlink_ctx *ctx, const struct handle *h, } static int do_add_table(struct netlink_ctx *ctx, const struct handle *h, - const struct location *loc, struct table *table) + const struct location *loc, struct table *table, + bool excl) { struct chain *chain; struct set *set; - if (netlink_add_table(ctx, h, loc, table) < 0) + if (netlink_add_table(ctx, h, loc, table, excl) < 0) return -1; if (table != NULL) { list_for_each_entry(set, &table->sets, list) { @@ -511,22 +513,22 @@ static int do_add_table(struct netlink_ctx *ctx, const struct handle *h, } list_for_each_entry(chain, &table->chains, list) { if (do_add_chain(ctx, &chain->handle, &chain->location, - chain) < 0) + chain, excl) < 0) return -1; } } return 0; } -static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd) +static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd, bool excl) { switch (cmd->obj) { case CMD_OBJ_TABLE: return do_add_table(ctx, &cmd->handle, &cmd->location, - cmd->table); + cmd->table, excl); case CMD_OBJ_CHAIN: return do_add_chain(ctx, &cmd->handle, &cmd->location, - cmd->chain); + cmd->chain, excl); case CMD_OBJ_RULE: return netlink_add_rule_batch(ctx, &cmd->handle, cmd->rule, NLM_F_APPEND); @@ -726,7 +728,9 @@ int do_command(struct netlink_ctx *ctx, struct cmd *cmd) { switch (cmd->op) { case CMD_ADD: - return do_command_add(ctx, cmd); + return do_command_add(ctx, cmd, false); + case CMD_CREATE: + return do_command_add(ctx, cmd, true); case CMD_INSERT: return do_command_insert(ctx, cmd); case CMD_DELETE: diff --git a/src/scanner.l b/src/scanner.l index a0ca7d75..f133f237 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -249,6 +249,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "inet" { return INET; } "add" { return ADD; } +"create" { return CREATE; } "insert" { return INSERT; } "delete" { return DELETE; } "list" { return LIST; } |