]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
cmd: add create command for tables and chains
authorPatrick McHardy <kaber@trash.net>
Tue, 21 Jan 2014 12:39:31 +0000 (12:39 +0000)
committerPatrick McHardy <kaber@trash.net>
Tue, 21 Jan 2014 12:39:31 +0000 (12:39 +0000)
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>
include/netlink.h
include/rule.h
src/evaluate.c
src/mnl.c
src/netlink.c
src/parser.y
src/rule.c
src/scanner.l

index fbaaaeba9c8af6892b029ddee89d13e1c544d18f..3f8d465c869226b80e9d6b64323e941a351d22b6 100644 (file)
@@ -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,
index 2a7b7980d167c542c0456923c63bbadf5b018a60..30a4d12ccd4286370e2cfa5b55b88056460d01a9 100644 (file)
@@ -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,
index 2b2427a5af052c16a046acdd24dde4751009ea28..cf30ed92ecb43f8d18f851c955cd52bf03875490 100644 (file)
@@ -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:
index b867902274f0d9d5db31aa3068ab3aeb6da9f942..7ac1fc5788687aeb45732663ae0d74dd583899b0 100644 (file)
--- 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);
index 7f69995d8805b6f8683a60cb7c9ba87362e9c8ba..84be505ddb51708d3ad9dc7a2e4e23bd16abff81 100644 (file)
@@ -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)
index 3e3abeddf1de573b9a04a61ee023977d7969ef57..cd9ade147d8526e58b10c292f3fe3691870857ba 100644 (file)
@@ -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);
index a721d4797d535b101cae442c229ebf9fd9683adb..18d72d9dc62afd03dbcc8f62d5a4a7aae8a089a8 100644 (file)
@@ -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:
index a0ca7d755f794c4dcfec8caf8c0bbb9f012818d6..f133f237bbe284a54794c50b722b628cb9254572 100644 (file)
@@ -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; }