]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
rule: add rule insertion (prepend) support
authorPatrick McHardy <kaber@trash.net>
Fri, 14 Dec 2012 16:50:10 +0000 (17:50 +0100)
committerPatrick McHardy <kaber@trash.net>
Fri, 14 Dec 2012 16:50:10 +0000 (17:50 +0100)
Signed-off-by: Patrick McHardy <kaber@trash.net>
include/netlink.h
include/rule.h
src/evaluate.c
src/netlink.c
src/parser.y
src/rule.c
src/scanner.l

index 8edd1a3916a5b6fdd50bfb3765ad50411c51d4f5..3252569bf970fd08d2325d12e86a239cb3a61e81 100644 (file)
@@ -51,7 +51,7 @@ extern struct rule *netlink_delinearize_rule(struct netlink_ctx *ctx,
                                             const struct nl_object *obj);
 
 extern int netlink_add_rule(struct netlink_ctx *ctx, const struct handle *h,
-                           const struct rule *rule);
+                           const struct rule *rule, uint32_t flags);
 extern int netlink_delete_rule(struct netlink_ctx *ctx, const struct handle *h);
 extern int netlink_get_rule(struct netlink_ctx *ctx, const struct handle *h);
 
index e468e8e8feb81f0f55769cf7822633c097e6be93..a992489b0e999cdbc693b58311e7bc68b9a400e4 100644 (file)
@@ -187,6 +187,7 @@ extern void set_print(const struct set *set);
  *
  * @CMD_INVALID:       invalid
  * @CMD_ADD:           add object
+ * @CMD_INSERT:                insert object
  * @CMD_DELETE:                delete object
  * @CMD_LIST:          list container
  * @CMD_FLUSH:         flush container
@@ -195,6 +196,7 @@ extern void set_print(const struct set *set);
 enum cmd_ops {
        CMD_INVALID,
        CMD_ADD,
+       CMD_INSERT,
        CMD_DELETE,
        CMD_LIST,
        CMD_FLUSH,
index 28681d0d80a3db218af21d4a0da2bfc30a5d72d4..7aee41b3c17d6bf51cad7c726487472084974efc 100644 (file)
@@ -1306,6 +1306,7 @@ static int cmd_evaluate(struct eval_ctx *ctx, struct cmd *cmd)
        ctx->cmd = cmd;
        switch (cmd->op) {
        case CMD_ADD:
+       case CMD_INSERT:
                return cmd_evaluate_add(ctx, cmd);
        case CMD_DELETE:
                return cmd_evaluate_delete(ctx, cmd);
index 53ef2ba9d990321da20d65d619648c5452aba4ee..4c60c4a2ec8113bd3bfc77a5276e017a666a3b1c 100644 (file)
@@ -293,7 +293,7 @@ struct expr *netlink_alloc_data(const struct location *loc,
 }
 
 int netlink_add_rule(struct netlink_ctx *ctx, const struct handle *h,
-                    const struct rule *rule)
+                    const struct rule *rule, uint32_t flags)
 {
        struct nfnl_nft_rule *nlr;
        int err;
@@ -301,7 +301,7 @@ int netlink_add_rule(struct netlink_ctx *ctx, const struct handle *h,
        nlr = alloc_nft_rule(&rule->handle);
        err = netlink_linearize_rule(ctx, nlr, rule);
        if (err == 0) {
-               err = nfnl_nft_rule_add(nf_sock, nlr, NLM_F_EXCL | NLM_F_APPEND);
+               err = nfnl_nft_rule_add(nf_sock, nlr, flags | NLM_F_EXCL);
                if (err < 0)
                        netlink_io_error(ctx, &rule->location,
                                         "Could not add rule: %s", nl_geterror(err));
index 2b0700db739962a2af33dd1196d3b33cd669955a..fc72458822447419be6ea5b1996789147e099ea0 100644 (file)
@@ -166,6 +166,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %token HANDLE                  "handle"
 
 %token ADD                     "add"
+%token INSERT                  "insert"
 %token DELETE                  "delete"
 %token LIST                    "list"
 %token FLUSH                   "flush"
@@ -328,8 +329,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 delete_cmd list_cmd flush_cmd rename_cmd
-%destructor { cmd_free($$); }  base_cmd add_cmd delete_cmd list_cmd flush_cmd rename_cmd
+%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 <handle>                 table_spec chain_spec chain_identifier ruleid_spec
 %destructor { handle_free(&$$); } table_spec chain_spec chain_identifier ruleid_spec
@@ -509,6 +510,7 @@ line                        :       common_block                    { $$ = NULL; }
 
 base_cmd               :       /* empty */     add_cmd         { $$ = $1; }
                        |       ADD             add_cmd         { $$ = $2; }
+                       |       INSERT          insert_cmd      { $$ = $2; }
                        |       DELETE          delete_cmd      { $$ = $2; }
                        |       LIST            list_cmd        { $$ = $2; }
                        |       FLUSH           flush_cmd       { $$ = $2; }
@@ -571,6 +573,12 @@ add_cmd                    :       TABLE           table_spec
                        }
                        ;
 
+insert_cmd             :       RULE            ruleid_spec     rule
+                       {
+                               $$ = cmd_alloc(CMD_INSERT, CMD_OBJ_RULE, &$2, $3);
+                       }
+                       ;
+
 delete_cmd             :       TABLE           table_spec
                        {
                                $$ = cmd_alloc(CMD_DELETE, CMD_OBJ_TABLE, &$2, NULL);
index f671117d77fb2d9b4fd412e2e8c1254e1a252763..7d0887aae481f14d9d3d785352881d6c4439f1cd 100644 (file)
@@ -347,7 +347,8 @@ static int do_add_chain(struct netlink_ctx *ctx, const struct handle *h,
                return -1;
        if (chain != NULL) {
                list_for_each_entry(rule, &chain->rules, list) {
-                       if (netlink_add_rule(ctx, &rule->handle, rule) < 0)
+                       if (netlink_add_rule(ctx, &rule->handle, rule,
+                                            NLM_F_APPEND) < 0)
                                return -1;
                }
        }
@@ -406,7 +407,8 @@ static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd)
        case CMD_OBJ_CHAIN:
                return do_add_chain(ctx, &cmd->handle, cmd->chain);
        case CMD_OBJ_RULE:
-               return netlink_add_rule(ctx, &cmd->handle, cmd->rule);
+               return netlink_add_rule(ctx, &cmd->handle, cmd->rule,
+                                       NLM_F_APPEND);
        case CMD_OBJ_SET:
                return do_add_set(ctx, &cmd->handle, cmd->set);
        case CMD_OBJ_SETELEM:
@@ -417,6 +419,17 @@ static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd)
        return 0;
 }
 
+static int do_command_insert(struct netlink_ctx *ctx, struct cmd *cmd)
+{
+       switch (cmd->obj) {
+       case CMD_OBJ_RULE:
+               return netlink_add_rule(ctx, &cmd->handle, cmd->rule, 0);
+       default:
+               BUG("invalid command object type %u\n", cmd->obj);
+       }
+       return 0;
+}
+
 static int do_command_delete(struct netlink_ctx *ctx, struct cmd *cmd)
 {
        switch (cmd->obj) {
@@ -555,6 +568,8 @@ int do_command(struct netlink_ctx *ctx, struct cmd *cmd)
        switch (cmd->op) {
        case CMD_ADD:
                return do_command_add(ctx, cmd);
+       case CMD_INSERT:
+               return do_command_insert(ctx, cmd);
        case CMD_DELETE:
                return do_command_delete(ctx, cmd);
        case CMD_LIST:
index 47397691f26d7abecdfad2c504faa5a7e1c7d4c2..7ceae09d8b3902a28f99f1e70a9b8ad8e863632a 100644 (file)
@@ -242,6 +242,7 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 "queue"                        { return QUEUE; }
 
 "add"                  { return ADD; }
+"insert"               { return INSERT; }
 "delete"               { return DELETE; }
 "list"                 { return LIST; }
 "flush"                        { return FLUSH; }