]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: Add support for insertion inside rule list
authorEric Leblond <eric@regit.org>
Sat, 6 Jul 2013 15:33:57 +0000 (17:33 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 19 Jul 2013 15:48:11 +0000 (17:48 +0200)
This patch adds support to insert and to add rule using a rule
handle as reference. The rule handle syntax has an new optional
position field which take a handle as argument.

Two examples:

  nft add rule filter output position 5 ip daddr 1.2.3.1 drop
  nft insert rule filter output position 5 ip daddr 1.2.3.1 drop

Signed-off-by: Eric Leblond <eric@regit.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/rule.h
src/mnl.c
src/netlink.c
src/netlink_delinearize.c
src/parser.y
src/rule.c
src/scanner.l

index e0debe3b795db79b5d249b1d69d9bbfda705c791..2577cff530f3edfbcc38e5052fbbe17201b38f2d 100644 (file)
@@ -13,6 +13,7 @@
  * @chain:     chain name (chains and rules only)
  * @set:       set name (sets only)
  * @handle:    rule handle (rules only)
+ * @position:  rule position (rules only)
  */
 struct handle {
        uint32_t                family;
@@ -20,6 +21,7 @@ struct handle {
        const char              *chain;
        const char              *set;
        uint64_t                handle;
+       uint64_t                position;
 };
 
 extern void handle_merge(struct handle *dst, const struct handle *src);
index a58f7ea89de0c86c6145492d89179c3eaae13477..928d692f8f61315853b159dc6cf7238044128675 100644 (file)
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -61,7 +61,7 @@ int mnl_nft_rule_add(struct mnl_socket *nf_sock, struct nft_rule *nlr,
 
        nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE,
                        nft_rule_attr_get_u32(nlr, NFT_RULE_ATTR_FAMILY),
-                       NLM_F_APPEND|NLM_F_ACK|NLM_F_CREATE, seq);
+                       flags|NLM_F_ACK|NLM_F_CREATE, seq);
        nft_rule_nlmsg_build_payload(nlh, nlr);
 
        return mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL);
index 2a7bdb567fa784d1a64068555e2bc9e55358fed7..5129cac630f3cf7296672d3b23ab7763d590b4b3 100644 (file)
@@ -105,6 +105,8 @@ struct nft_rule *alloc_nft_rule(const struct handle *h)
                nft_rule_attr_set_str(nlr, NFT_RULE_ATTR_CHAIN, h->chain);
        if (h->handle)
                nft_rule_attr_set_u64(nlr, NFT_RULE_ATTR_HANDLE, h->handle);
+       if (h->position)
+               nft_rule_attr_set_u64(nlr, NFT_RULE_ATTR_POSITION, h->position);
        return nlr;
 }
 
index 93489138f1851ef06433be79a6fef00917b43490..f92e83f315440c317d7bb713e4d53db008f9aed0 100644 (file)
@@ -796,6 +796,8 @@ struct rule *netlink_delinearize_rule(struct netlink_ctx *ctx,
        h.table  = xstrdup(nft_rule_attr_get_str(nlr, NFT_RULE_ATTR_TABLE));
        h.chain  = xstrdup(nft_rule_attr_get_str(nlr, NFT_RULE_ATTR_CHAIN));
        h.handle = nft_rule_attr_get_u64(nlr, NFT_RULE_ATTR_HANDLE);
+       if (nft_rule_attr_is_set(nlr, NFT_RULE_ATTR_POSITION))
+               h.position = nft_rule_attr_get_u64(nlr, NFT_RULE_ATTR_POSITION);
 
        pctx->rule = rule_alloc(&internal_location, &h);
        pctx->table = table_lookup(&h);
index 2923b598ebf7975245e2bb314853ab59db44a84a..91981e9a0d73373693de85a4c21d0846815ddc53 100644 (file)
@@ -326,6 +326,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %token SNAT                    "snat"
 %token DNAT                    "dnat"
 
+%token POSITION                        "position"
+
 %type <string>                 identifier string
 %destructor { xfree($$); }     identifier string
 
@@ -339,7 +341,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %destructor { handle_free(&$$); } table_spec tables_spec chain_spec chain_identifier ruleid_spec
 %type <handle>                 set_spec set_identifier
 %destructor { handle_free(&$$); } set_spec set_identifier
-%type <val>                    handle_spec family_spec
+%type <val>                    handle_spec family_spec position_spec
 
 %type <table>                  table_block_alloc table_block
 %destructor { table_free($$); }        table_block_alloc
@@ -842,10 +844,21 @@ handle_spec               :       /* empty */
                        }
                        ;
 
-ruleid_spec            :       chain_spec      handle_spec
+position_spec          :       /* empty */
+                       {
+                               $$ = 0;
+                       }
+                       |       POSITION        NUM
+                       {
+                               $$ = $2;
+                       }
+                       ;
+
+ruleid_spec            :       chain_spec      handle_spec     position_spec
                        {
                                $$              = $1;
                                $$.handle       = $2;
+                               $$.position     = $3;
                        }
                        ;
 
index 5a894cc9284d48d897bfaa4b01e273fba8d79a6d..836862407ab98890ccba5544ee51c97e44293fab 100644 (file)
@@ -41,6 +41,8 @@ void handle_merge(struct handle *dst, const struct handle *src)
                dst->set = xstrdup(src->set);
        if (dst->handle == 0)
                dst->handle = src->handle;
+       if (dst->position == 0)
+               dst->position = src->position;
 }
 
 struct set *set_alloc(const struct location *loc)
index fe7b86c4bfdf128d852de0a0761964972300f78f..7946e94fa777a6d23fdd97d6400eadf9e74d6b71 100644 (file)
@@ -249,6 +249,8 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 "flush"                        { return FLUSH; }
 "rename"               { return RENAME; }
 
+"position"             { return POSITION; }
+
 "counter"              { return COUNTER; }
 "packets"              { return PACKETS; }
 "bytes"                        { return BYTES; }