]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: Add command "replace" for rules
authorCarlos Falgueras García <carlosfg@riseup.net>
Tue, 27 Oct 2015 11:58:07 +0000 (12:58 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 2 Nov 2015 11:51:31 +0000 (12:51 +0100)
Modify the parser and add necessary functions to provide the command "nft
replace rule <ruleid_spec> <new_rule>"

Example of use:

# nft list ruleset -a
table ip filter {
chain output {
ip daddr 8.8.8.7 counter packets 0 bytes 0 # handle 3
}
}
# nft replace rule filter output handle 3 ip daddr 8.8.8.8 counter
# nft list ruleset -a
table ip filter {
chain output {
ip daddr 8.8.8.8 counter packets 0 bytes 0 # handle 3
}
}

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/mnl.h
include/netlink.h
include/rule.h
src/evaluate.c
src/mnl.c
src/netlink.c
src/parser_bison.y
src/rule.c
src/scanner.l

index 9c14e1aa1029ecbf1f3bdb7d7c218308431327a6..f74dfee5c8c6f3c8e969d2db2870b84ab6572980 100644 (file)
@@ -26,6 +26,8 @@ int mnl_nft_rule_batch_add(struct nftnl_rule *nlr, unsigned int flags,
                           uint32_t seqnum);
 int mnl_nft_rule_batch_del(struct nftnl_rule *nlr, unsigned int flags,
                           uint32_t seqnum);
+int mnl_nft_rule_batch_replace(struct nftnl_rule *nlr, unsigned int flags,
+                              uint32_t seqnum);
 
 int mnl_nft_rule_add(struct mnl_socket *nf_sock, struct nftnl_rule *r,
                     unsigned int flags);
index 7bf7ea0d39466987223248946bcea773ab70e560..844474220cf47a532d86f4aeacb8d5a97becc4e2 100644 (file)
@@ -98,6 +98,10 @@ extern int netlink_add_rule_batch(struct netlink_ctx *ctx,
 extern int netlink_del_rule_batch(struct netlink_ctx *ctx,
                                  const struct handle *h,
                                  const struct location *loc);
+extern int netlink_replace_rule_batch(struct netlink_ctx *ctx,
+                                     const struct handle *h,
+                                     const struct rule *rule,
+                                     const struct location *loc);
 
 extern int netlink_add_chain(struct netlink_ctx *ctx, const struct handle *h,
                             const struct location *loc,
index 30b4597d31120191b6c64f7496271a627df410a5..a86f600b013b624b5f3e42a300634e62b169b861 100644 (file)
@@ -237,6 +237,7 @@ extern void set_print_plain(const struct set *s);
  *
  * @CMD_INVALID:       invalid
  * @CMD_ADD:           add object (non-exclusive)
+ * @CMD_REPLACE,       replace object
  * @CMD_CREATE:                create object (exclusive)
  * @CMD_INSERT:                insert object
  * @CMD_DELETE:                delete object
@@ -250,6 +251,7 @@ extern void set_print_plain(const struct set *s);
 enum cmd_ops {
        CMD_INVALID,
        CMD_ADD,
+       CMD_REPLACE,
        CMD_CREATE,
        CMD_INSERT,
        CMD_DELETE,
index ea43fc1b7879f4f1425ba34a8eb0360b80cb2927..e776d2cfa9e979a43b335946276b302526811edb 100644 (file)
@@ -2241,6 +2241,7 @@ int cmd_evaluate(struct eval_ctx *ctx, struct cmd *cmd)
        ctx->cmd = cmd;
        switch (cmd->op) {
        case CMD_ADD:
+       case CMD_REPLACE:
        case CMD_CREATE:
        case CMD_INSERT:
                return cmd_evaluate_add(ctx, cmd);
index e4253e53ed3d0bb0ebb62a627962044b8da81ec9..52875f4a16da9ae3bc0330aac26a1d12c53f4a9d 100644 (file)
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -301,6 +301,22 @@ int mnl_nft_rule_batch_add(struct nftnl_rule *nlr, unsigned int flags,
        return 0;
 }
 
+int mnl_nft_rule_batch_replace(struct nftnl_rule *nlr, unsigned int flags,
+                              uint32_t seqnum)
+{
+       struct nlmsghdr *nlh;
+
+       nlh = nftnl_rule_nlmsg_build_hdr(nftnl_batch_buffer(batch),
+                       NFT_MSG_NEWRULE,
+                       nftnl_rule_get_u32(nlr, NFTNL_RULE_FAMILY),
+                       NLM_F_REPLACE | flags, seqnum);
+
+       nftnl_rule_nlmsg_build_payload(nlh, nlr);
+       mnl_nft_batch_continue();
+
+       return 0;
+}
+
 int mnl_nft_rule_batch_del(struct nftnl_rule *nlr, unsigned int flags,
                           uint32_t seqnum)
 {
index 4d1e977f333fbeb5afe0529a36de11b1d5408388..ad86084e8d259e804d8e9c34fea87ab38daa74d3 100644 (file)
@@ -382,6 +382,24 @@ int netlink_add_rule_batch(struct netlink_ctx *ctx,
        return err;
 }
 
+int netlink_replace_rule_batch(struct netlink_ctx *ctx, const struct handle *h,
+                              const struct rule *rule,
+                              const struct location *loc)
+{
+       struct nftnl_rule *nlr;
+       int err;
+
+       nlr = alloc_nftnl_rule(&rule->handle);
+       netlink_linearize_rule(ctx, nlr, rule);
+       err = mnl_nft_rule_batch_replace(nlr, 0, ctx->seqnum);
+       nftnl_rule_free(nlr);
+
+       if (err < 0)
+               netlink_io_error(ctx, loc, "Could not replace rule to batch: %s",
+                                strerror(errno));
+       return err;
+}
+
 int netlink_add_rule_list(struct netlink_ctx *ctx, const struct handle *h,
                          struct list_head *rule_list)
 {
index 98480b600eb545699f60520bb9c723ce1843618c..519eabbf5af65bd0480643ab93e42f11f384a835 100644 (file)
@@ -184,6 +184,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 
 %token ADD                     "add"
 %token UPDATE                  "update"
+%token REPLACE                 "replace"
 %token CREATE                  "create"
 %token INSERT                  "insert"
 %token DELETE                  "delete"
@@ -413,8 +414,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 replace_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 replace_cmd create_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd export_cmd monitor_cmd describe_cmd
 
 %type <handle>                 table_spec chain_spec chain_identifier ruleid_spec ruleset_spec
 %destructor { handle_free(&$$); } table_spec chain_spec chain_identifier ruleid_spec ruleset_spec
@@ -649,6 +650,7 @@ line                        :       common_block                    { $$ = NULL; }
 
 base_cmd               :       /* empty */     add_cmd         { $$ = $1; }
                        |       ADD             add_cmd         { $$ = $2; }
+                       |       REPLACE         replace_cmd     { $$ = $2; }
                        |       CREATE          create_cmd      { $$ = $2; }
                        |       INSERT          insert_cmd      { $$ = $2; }
                        |       DELETE          delete_cmd      { $$ = $2; }
@@ -711,6 +713,12 @@ add_cmd                    :       TABLE           table_spec
                        }
                        ;
 
+replace_cmd            :       RULE            ruleid_spec     rule
+                       {
+                               $$ = cmd_alloc(CMD_REPLACE, CMD_OBJ_RULE, &$2, &@$, $3);
+                       }
+                       ;
+
 create_cmd             :       TABLE           table_spec
                        {
                                $$ = cmd_alloc(CMD_CREATE, CMD_OBJ_TABLE, &$2, &@$, NULL);
index 0a814693691d4805dd1355969ed60ef510d5b59c..c154062be50db91f607d0ef8ac27cb570fe0dd27 100644 (file)
@@ -935,6 +935,18 @@ static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd, bool excl)
        return 0;
 }
 
+static int do_command_replace(struct netlink_ctx *ctx, struct cmd *cmd)
+{
+       switch (cmd->obj) {
+       case CMD_OBJ_RULE:
+               return netlink_replace_rule_batch(ctx, &cmd->handle, cmd->rule,
+                                                 &cmd->location);
+       default:
+               BUG("invalid command object type %u\n", cmd->obj);
+       }
+       return 0;
+}
+
 static int do_command_insert(struct netlink_ctx *ctx, struct cmd *cmd)
 {
        switch (cmd->obj) {
@@ -1229,6 +1241,8 @@ int do_command(struct netlink_ctx *ctx, struct cmd *cmd)
                return do_command_add(ctx, cmd, true);
        case CMD_INSERT:
                return do_command_insert(ctx, cmd);
+       case CMD_REPLACE:
+               return do_command_replace(ctx, cmd);
        case CMD_DELETE:
                return do_command_delete(ctx, cmd);
        case CMD_LIST:
index b827489a599aeaed71a6d85a6eff8af1ddd6b561..1a9f43f8d57cd736021c3262cb747d47094d6a72 100644 (file)
@@ -259,6 +259,7 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 "netdev"               { return NETDEV; }
 
 "add"                  { return ADD; }
+"replace"              { return REPLACE; }
 "update"               { return UPDATE; }
 "create"               { return CREATE; }
 "insert"               { return INSERT; }