]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: allow to specify the default policy for base chains
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 17 Mar 2015 15:36:15 +0000 (16:36 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 17 Mar 2015 16:26:03 +0000 (17:26 +0100)
The new syntax is:

 nft add chain filter input { hook input type filter priority 0\; policy accept\; }

but the previous syntax is still allowed:

 nft add chain filter input { hook input type filter priority 0\; }

this assumes default policy to accept.

If the base chain already exists, you can update the policy via:

 nft add chain filter input { policy drop\; }

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
doc/nft.xml
include/rule.h
src/netlink.c
src/parser_bison.y
src/rule.c

index 696a4c3470b38a09f756bc586ac76863deec5c09..8d79016c1f777c5728c2644b1e6ce83f325eb305 100644 (file)
@@ -456,6 +456,7 @@ filter input iif $int_ifs accept
                                <arg choice="req"><replaceable>chain</replaceable></arg>
                                <arg choice="req"><replaceable>hook</replaceable></arg>
                                <arg choice="req"><replaceable>priority</replaceable></arg>
+                               <arg choice="req"><replaceable>policy</replaceable></arg>
                        </cmdsynopsis>
                        <cmdsynopsis>
                                <group choice="req">
index 90836bc474c1089777543b04145255c01ca9dcc2..97959f7b36fb79b6838c6c6de73dbb3922eafa86 100644 (file)
@@ -111,6 +111,7 @@ enum chain_flags {
  * @hookstr:   unified and human readable hook name (base chains)
  * @hooknum:   hook number (base chains)
  * @priority:  hook priority (base chains)
+ * @policy:    default chain policy (base chains)
  * @type:      chain type
  * @rules:     rules contained in the chain
  */
@@ -122,6 +123,7 @@ struct chain {
        const char              *hookstr;
        unsigned int            hooknum;
        int                     priority;
+       int                     policy;
        const char              *type;
        struct scope            scope;
        struct list_head        rules;
index 8c37ec5d59cc9ce8f4a7751565281b5614d3111e..2d1fb7936fa5acbb12d01cc984c9c920fcc6b9d3 100644 (file)
@@ -508,6 +508,10 @@ static int netlink_add_chain_compat(struct netlink_ctx *ctx,
                nft_chain_attr_set_str(nlc, NFT_CHAIN_ATTR_TYPE,
                                       chain->type);
        }
+       if (chain->policy != -1)
+               nft_chain_attr_set_u32(nlc, NFT_CHAIN_ATTR_POLICY,
+                                      chain->policy);
+
        netlink_dump_chain(nlc);
        err = mnl_nft_chain_add(nf_sock, nlc, excl ? NLM_F_EXCL : 0);
        nft_chain_free(nlc);
@@ -535,6 +539,10 @@ static int netlink_add_chain_batch(struct netlink_ctx *ctx,
                nft_chain_attr_set_str(nlc, NFT_CHAIN_ATTR_TYPE,
                                       chain->type);
        }
+       if (chain->policy != -1)
+               nft_chain_attr_set_u32(nlc, NFT_CHAIN_ATTR_POLICY,
+                                      chain->policy);
+
        netlink_dump_chain(nlc);
        err = mnl_nft_chain_batch_add(nlc, excl ? NLM_F_EXCL : 0,
                                      ctx->seqnum);
@@ -665,13 +673,16 @@ static struct chain *netlink_delinearize_chain(struct netlink_ctx *ctx,
 
        if (nft_chain_attr_is_set(nlc, NFT_CHAIN_ATTR_HOOKNUM) &&
            nft_chain_attr_is_set(nlc, NFT_CHAIN_ATTR_PRIO) &&
-           nft_chain_attr_is_set(nlc, NFT_CHAIN_ATTR_TYPE)) {
+           nft_chain_attr_is_set(nlc, NFT_CHAIN_ATTR_TYPE) &&
+           nft_chain_attr_is_set(nlc, NFT_CHAIN_ATTR_POLICY)) {
                chain->hooknum       =
                        nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_HOOKNUM);
                chain->priority      =
                        nft_chain_attr_get_s32(nlc, NFT_CHAIN_ATTR_PRIO);
                chain->type          =
                        xstrdup(nft_chain_attr_get_str(nlc, NFT_CHAIN_ATTR_TYPE));
+               chain->policy          =
+                       nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_POLICY);
                chain->flags        |= CHAIN_F_BASECHAIN;
        }
 
index 6fc834d02984901bf8e413299d313049be20b832..ea3ff52698bd75260204fa64fc5e28d3fb7b38d0 100644 (file)
@@ -913,6 +913,7 @@ chain_block         :       /* empty */     { $$ = $<chain>-1; }
                        |       chain_block     common_block
                        |       chain_block     stmt_seperator
                        |       chain_block     hook_spec       stmt_seperator
+                       |       chain_block     policy_spec     stmt_seperator
                        |       chain_block     rule            stmt_seperator
                        {
                                list_add_tail(&$2->list, &$1->rules);
@@ -1070,6 +1071,26 @@ hook_spec                :       TYPE            STRING          HOOK            STRING          PRIORITY        NUM
                        }
                        ;
 
+policy_spec            :       POLICY          ACCEPT
+                       {
+                               if ($<chain>0->policy != -1) {
+                                       erec_queue(error(&@$, "you cannot set chain policy twice"),
+                                                  state->msgs);
+                                       YYERROR;
+                               }
+                               $<chain>0->policy       = NF_ACCEPT;
+                       }
+                       |       POLICY          DROP
+                       {
+                               if ($<chain>0->policy != -1) {
+                                       erec_queue(error(&@$, "you cannot set chain policy twice"),
+                                                  state->msgs);
+                                       YYERROR;
+                               }
+                               $<chain>0->policy       = NF_DROP;
+                       }
+                       ;
+
 identifier             :       STRING
                        ;
 
index 28283793dd217d34ba95b6cd9504508cd5d0bcd9..9f27019f4d0a709e623c872b7e75c2d892ea3d9f 100644 (file)
@@ -336,6 +336,8 @@ struct chain *chain_alloc(const char *name)
        init_list_head(&chain->scope.symbols);
        if (name != NULL)
                chain->handle.chain = xstrdup(name);
+
+       chain->policy = -1;
        return chain;
 }
 
@@ -425,15 +427,27 @@ static const char *hooknum2str(unsigned int family, unsigned int hooknum)
        return "unknown";
 }
 
+static const char *chain_policy2str(uint32_t policy)
+{
+       switch (policy) {
+       case NF_DROP:
+               return "drop";
+       case NF_ACCEPT:
+               return "accept";
+       }
+       return "unknown";
+}
+
 static void chain_print(const struct chain *chain)
 {
        struct rule *rule;
 
        printf("\tchain %s {\n", chain->handle.chain);
        if (chain->flags & CHAIN_F_BASECHAIN) {
-               printf("\t\t type %s hook %s priority %d;\n", chain->type,
+               printf("\t\t type %s hook %s priority %d; policy %s;\n",
+                      chain->type,
                       hooknum2str(chain->handle.family, chain->hooknum),
-                      chain->priority);
+                      chain->priority, chain_policy2str(chain->policy));
        }
        list_for_each_entry(rule, &chain->rules, list) {
                printf("\t\t");
@@ -452,9 +466,10 @@ void chain_print_plain(const struct chain *chain)
               chain->handle.table, chain->handle.chain);
 
        if (chain->flags & CHAIN_F_BASECHAIN) {
-               printf(" { type %s hook %s priority %d; }", chain->type,
+               printf(" { type %s hook %s priority %d; policy %s; }",
+                      chain->type,
                       hooknum2str(chain->handle.family, chain->hooknum),
-                      chain->priority);
+                      chain->priority, chain_policy2str(chain->policy));
        }
 
        printf("\n");