]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: allow to specify the base chain type
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 22 Aug 2013 15:26:31 +0000 (17:26 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 26 Aug 2013 22:38:01 +0000 (00:38 +0200)
This patch allows you to specify the type of the base chain, eg.

add table mangle
add chain mangle OUTPUT { type route hook NF_INET_LOCAL_OUT 0; }

The chain type determines the semantics of the chain, we currently
have three types:

* filter, used for plain packet filtering.
* nat, it only sees the first packet of the flow.
* route, which is the equivalent of the iptables mangle table, that
  triggers a re-route if there is any change in some of the packet header
  fields, eg. IP TOS/DSCP, or the packet metainformation, eg. mark.

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

index 2577cff530f3edfbcc38e5052fbbe17201b38f2d..4f68431956830a44df023d866fb55fb3b70f6487 100644 (file)
@@ -100,6 +100,7 @@ enum chain_flags {
  * @flags:     chain flags
  * @hooknum:   hook number (base chains)
  * @priority:  hook priority (base chains)
+ * @type:      chain type
  * @rules:     rules contained in the chain
  */
 struct chain {
@@ -109,6 +110,7 @@ struct chain {
        uint32_t                flags;
        unsigned int            hooknum;
        unsigned int            priority;
+       const char              *type;
        struct scope            scope;
        struct list_head        rules;
 };
index 5129cac630f3cf7296672d3b23ab7763d590b4b3..962561f313198c4857643c473b1f1d67f1cf7e1d 100644 (file)
@@ -461,6 +461,8 @@ int netlink_add_chain(struct netlink_ctx *ctx, const struct handle *h,
                                       chain->hooknum);
                nft_chain_attr_set_u32(nlc, NFT_CHAIN_ATTR_PRIO,
                                       chain->priority);
+               nft_chain_attr_set_str(nlc, NFT_CHAIN_ATTR_TYPE,
+                                      chain->type);
        }
        netlink_dump_chain(nlc);
        err = mnl_nft_chain_add(nf_sock, nlc, NLM_F_EXCL);
@@ -524,10 +526,17 @@ static int list_chain_cb(struct nft_chain *nlc, void *arg)
                xstrdup(nft_chain_attr_get_str(nlc, NFT_CHAIN_ATTR_NAME));
        chain->handle.handle =
                nft_chain_attr_get_u64(nlc, NFT_CHAIN_ATTR_HANDLE);
-       chain->hooknum       =
-               nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_HOOKNUM);
-       chain->priority      =
-               nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_PRIO);
+
+       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)) {
+               chain->hooknum       =
+                       nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_HOOKNUM);
+               chain->priority      =
+                       nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_PRIO);
+               chain->type          =
+                       xstrdup(nft_chain_attr_get_str(nlc, NFT_CHAIN_ATTR_TYPE));
+       }
        list_add_tail(&chain->list, &ctx->list);
 
        return 0;
@@ -579,8 +588,13 @@ int netlink_get_chain(struct netlink_ctx *ctx, const struct handle *h,
        chain->handle.family = nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_FAMILY);
        chain->handle.table  = xstrdup(nft_chain_attr_get_str(nlc, NFT_CHAIN_ATTR_TABLE));
        chain->handle.handle = nft_chain_attr_get_u64(nlc, NFT_CHAIN_ATTR_HANDLE);
-       chain->hooknum       = nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_HOOKNUM);
-       chain->priority      = nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_PRIO);
+       if (nft_chain_attr_is_set(nlc, NFT_CHAIN_ATTR_TYPE) &&
+           nft_chain_attr_is_set(nlc, NFT_CHAIN_ATTR_HOOKNUM) &&
+           nft_chain_attr_is_set(nlc, NFT_CHAIN_ATTR_PRIO)) {
+               chain->hooknum       = nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_HOOKNUM);
+               chain->priority      = nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_PRIO);
+               chain->type          = xstrdup(nft_chain_attr_get_str(nlc, NFT_CHAIN_ATTR_TYPE));
+       }
        list_add_tail(&chain->list, &ctx->list);
 
        nft_chain_free(nlc);
index ff8de47f8b7a02c1ada0b899f415cf5980720191..f0eb8e32bb36e3949740eb4d421bd79ffd53c7f7 100644 (file)
@@ -766,16 +766,18 @@ map_block         :       /* empty */     { $$ = $<set>-1; }
                        }
                        ;
 
-hook_spec              :       HOOK            HOOKNUM         NUM
+hook_spec              :       TYPE            STRING          HOOK            HOOKNUM         NUM
                        {
-                               $<chain>0->hooknum      = $2;
-                               $<chain>0->priority     = $3;
+                               $<chain>0->type         = $2;
+                               $<chain>0->hooknum      = $4;
+                               $<chain>0->priority     = $5;
                                $<chain>0->flags        |= CHAIN_F_BASECHAIN;
                        }
-                       |       HOOK            HOOKNUM         DASH    NUM
+                       |       TYPE            STRING          HOOK            HOOKNUM         DASH    NUM
                        {
-                               $<chain>0->hooknum      = $2;
-                               $<chain>0->priority     = -$4;
+                               $<chain>0->type         = $2;
+                               $<chain>0->hooknum      = $4;
+                               $<chain>0->priority     = -$6;
                                $<chain>0->flags        |= CHAIN_F_BASECHAIN;
                        }
                        ;
index 836862407ab98890ccba5544ee51c97e44293fab..fb0387c3d461cac7d3ec6c3a9de039402889f0ec 100644 (file)
@@ -250,9 +250,8 @@ static void chain_print(const struct chain *chain)
 
        printf("\tchain %s {\n", chain->handle.chain);
        if (chain->hooknum) {
-               printf("\t\t hook %s %u;\n",
-               hooknum2str(chain->hooknum),
-               chain->priority);
+               printf("\t\t type %s hook %s %u;\n", chain->type,
+                      hooknum2str(chain->hooknum), chain->priority);
        }
        list_for_each_entry(rule, &chain->rules, list) {
                printf("\t\t");