From 0e9a6ee6aa16d90633acc3cf60836a140f2c5d87 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 21 Jan 2014 12:39:31 +0000 Subject: 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 --- src/evaluate.c | 1 + src/mnl.c | 14 +++++++------- src/netlink.c | 10 ++++++---- src/parser.y | 31 +++++++++++++++++++++++++++++-- src/rule.c | 22 +++++++++++++--------- src/scanner.l | 1 + 6 files changed, 57 insertions(+), 22 deletions(-) (limited to 'src') 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: diff --git a/src/mnl.c b/src/mnl.c index b8679022..7ac1fc57 100644 --- a/src/mnl.c +++ b/src/mnl.c @@ -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 line %destructor { cmd_free($$); } line -%type 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 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 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); diff --git a/src/rule.c b/src/rule.c index a721d479..18d72d9d 100644 --- a/src/rule.c +++ b/src/rule.c @@ -462,9 +462,10 @@ void cmd_free(struct cmd *cmd) #include 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; } -- cgit v1.2.3