v2:
- more comprehensive names
- expose basic priorities used by iptables
- use arithmetics with new names (+-)
- print friendly names with arithmetics with an epsilon of 10

-- 8< --
This patch adds the possibility to use textual names to set the chain priority
to basic values so that numeric values do not need to be learnt any more for
basic usage.

Basic arithmetic can also be done with them to ease the addition of
relatively higher/lower priority chains.
Addition and substraction is possible.

Values are also printed with their friendly name within the range of
<basicprio> +- 10.

Example:
        nft> add table x
        nft> add chain x y { type filter hook prerouting priority mangleprio; }
        nft> add chain x z { type filter hook prerouting priority mangleprio + 
1; }
        nft> add chain x w { type filter hook prerouting priority mangleprio - 
5; }
        nft> add chain x r { type filter hook prerouting priority filterprio + 
10; }
        nft> add chain x t { type filter hook prerouting priority rawprio; }
        nft> add chain x q { type filter hook prerouting priority rawprio + 11; 
}
        nft> list ruleset
        table ip x {
                chain y {
                        type filter hook prerouting priority mangleprio; policy 
accept;
                }

                chain z {
                        type filter hook prerouting priority mangleprio + 1; 
policy accept;
                }

                chain w {
                        type filter hook prerouting priority mangleprio - 5; 
policy accept;
                }

                chain r {
                        type filter hook prerouting priority filterprio + 10; 
policy accept;
                }

                chain t {
                        type filter hook prerouting priority rawprio; policy 
accept;
                }

                chain q {
                        type filter hook prerouting priority -289; policy 
accept;
                }
        }

Signed-off-by: Máté Eckl <[email protected]>
---
 src/parser_bison.y | 27 ++++++++++++++++++++++++---
 src/rule.c         | 46 ++++++++++++++++++++++++++++++++++++++++++----
 src/scanner.l      |  9 +++++++++
 3 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/src/parser_bison.y b/src/parser_bison.y
index 33915ed..10b4f96 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -21,6 +21,7 @@
 #include <linux/netfilter/nf_conntrack_tuple_common.h>
 #include <linux/netfilter/nf_nat.h>
 #include <linux/netfilter/nf_log.h>
+#include <linux/netfilter_ipv4.h>
 #include <netinet/ip_icmp.h>
 #include <netinet/icmp6.h>
 #include <libnftnl/common.h>
@@ -182,6 +183,8 @@ int nft_lex(void *, void *, void *);
 %token AT                      "@"
 %token VMAP                    "vmap"
 
+%token PLUS                    "+"
+
 %token INCLUDE                 "include"
 %token DEFINE                  "define"
 %token REDEFINE                        "redefine"
@@ -313,6 +316,13 @@ int nft_lex(void *, void *, void *);
 %token NEXTHDR                 "nexthdr"
 %token HOPLIMIT                        "hoplimit"
 
+%token PRIO_RAW                 "rawprio"
+%token PRIO_MANGLE              "mangleprio"
+%token PRIO_NAT_DST             "dstnatprio"
+%token PRIO_FILTER              "filterprio"
+%token PRIO_SECURITY            "securityprio"
+%token PRIO_NAT_SRC             "srcnatprio"
+
 %token ICMP6                   "icmpv6"
 %token PPTR                    "param-problem"
 %token MAXDELAY                        "max-delay"
@@ -520,7 +530,7 @@ int nft_lex(void *, void *, void *);
 %destructor { handle_free(&$$); } table_spec tableid_spec chain_spec 
chainid_spec flowtable_spec chain_identifier ruleid_spec handle_spec 
position_spec rule_position ruleset_spec index_spec
 %type <handle>                 set_spec setid_spec set_identifier 
flowtable_identifier obj_spec objid_spec obj_identifier
 %destructor { handle_free(&$$); } set_spec setid_spec set_identifier obj_spec 
objid_spec obj_identifier
-%type <val>                    family_spec family_spec_explicit chain_policy 
prio_spec
+%type <val>                    family_spec family_spec_explicit chain_policy 
prio_spec prio_base
 
 %type <string>                 dev_spec quota_unit
 %destructor { xfree($$); }     dev_spec quota_unit
@@ -1792,8 +1802,19 @@ hook_spec                :       TYPE            STRING  
        HOOK            STRING          dev_spec        PRIORITY        
prio_spec
                        }
                        ;
 
-prio_spec              :       NUM                     { $$ = $1; }
-                       |       DASH    NUM             { $$ = -$2; }
+prio_spec              :       NUM                 { $$ =   $1; }
+                       |       DASH    NUM             { $$ =  -$2; }
+                       |       prio_base
+                       |       prio_base PLUS NUM { $$ = $1 + $3; }
+                       |       prio_base DASH NUM { $$ = $1 - $3; }
+                       ;
+
+prio_base      :       PRIO_RAW                { $$ = NF_IP_PRI_RAW; }
+                       |       PRIO_MANGLE             { $$ = 
NF_IP_PRI_MANGLE; }
+                       |       PRIO_NAT_DST            { $$ = 
NF_IP_PRI_NAT_DST; }
+                       |       PRIO_FILTER             { $$ = 
NF_IP_PRI_FILTER; }
+                       |       PRIO_SECURITY           { $$ = 
NF_IP_PRI_SECURITY; }
+                       |       PRIO_NAT_SRC            { $$ = 
NF_IP_PRI_NAT_SRC; }
                        ;
 
 dev_spec               :       DEVICE  STRING          { $$ = $2; }
diff --git a/src/rule.c b/src/rule.c
index 3e8dea4..afb9510 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -28,6 +28,7 @@
 #include <netinet/ip.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter_arp.h>
+#include <linux/netfilter_ipv4.h>
 
 void handle_free(struct handle *h)
 {
@@ -752,6 +753,43 @@ const char *chain_policy2str(uint32_t policy)
        return "unknown";
 }
 
+static bool chain_prio2str_helper(char *dst, const int origo, const char* 
origostr,
+                          const int prio, const int e)
+{
+       char t[15];
+
+       t[0] = 0;
+       if (prio >= origo - e && prio <= origo + e) {
+               int tp = prio - origo;
+               if (tp != 0) {
+                       sprintf(t, " %c %d",tp > 0 ? '+' : '-', abs(tp));
+               }
+               sprintf(dst, "%s%s", origostr, t);
+               return true;
+       }
+       return false;
+}
+
+static const char *chain_prio2str(int prio)
+{
+       static char pe[256];
+       const int e = 10;
+
+       pe[0] = 0;
+       if(chain_prio2str_helper(pe, NF_IP_PRI_RAW, "rawprio", prio, e) ||
+          chain_prio2str_helper(pe, NF_IP_PRI_MANGLE, "mangleprio", prio, e) ||
+          chain_prio2str_helper(pe, NF_IP_PRI_NAT_DST, "dstnatprio", prio, e) 
||
+          chain_prio2str_helper(pe, NF_IP_PRI_FILTER, "filterprio", prio, e) ||
+          chain_prio2str_helper(pe, NF_IP_PRI_SECURITY, "securityprio", prio, 
e) ||
+          chain_prio2str_helper(pe, NF_IP_PRI_NAT_SRC, "srcnatprio", prio, e)
+         )
+               return pe;
+       else {
+               sprintf(pe, "%d", prio);
+               return pe;
+       }
+}
+
 static void chain_print_declaration(const struct chain *chain,
                                    struct output_ctx *octx)
 {
@@ -764,8 +802,8 @@ static void chain_print_declaration(const struct chain 
*chain,
                          hooknum2str(chain->handle.family, chain->hooknum));
                if (chain->dev != NULL)
                        nft_print(octx, " device %s", chain->dev);
-               nft_print(octx, " priority %d; policy %s;\n",
-                         chain->priority, chain_policy2str(chain->policy));
+               nft_print(octx, " priority %s; policy %s;\n",
+                         chain_prio2str(chain->priority), 
chain_policy2str(chain->policy));
        }
 }
 
@@ -789,9 +827,9 @@ void chain_print_plain(const struct chain *chain, struct 
output_ctx *octx)
                  chain->handle.table.name, chain->handle.chain.name);
 
        if (chain->flags & CHAIN_F_BASECHAIN) {
-               nft_print(octx, " { type %s hook %s priority %d; policy %s; }",
+               nft_print(octx, " { type %s hook %s priority %s; policy %s; }",
                          chain->type, chain->hookstr,
-                         chain->priority, chain_policy2str(chain->policy));
+                         chain_prio2str(chain->priority), 
chain_policy2str(chain->policy));
        }
        if (octx->handle > 0)
                nft_print(octx, " # handle %" PRIu64, chain->handle.handle.id);
diff --git a/src/scanner.l b/src/scanner.l
index 416bd27..887e80c 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -232,6 +232,8 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 "="                    { return '='; }
 "vmap"                 { return VMAP; }
 
+"+"            { return PLUS; }
+
 "include"              { return INCLUDE; }
 "define"               { return DEFINE; }
 "redefine"             { return REDEFINE; }
@@ -427,6 +429,13 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
 "nexthdr"              { return NEXTHDR; }
 "hoplimit"             { return HOPLIMIT; }
 
+"rawprio"       { return PRIO_RAW; }
+"mangleprio"    { return PRIO_MANGLE; }
+"dstnatprio"    { return PRIO_NAT_DST; }
+"filterprio"    { return PRIO_FILTER; }
+"securityprio"  { return PRIO_SECURITY; }
+"srcnatprio"    { return PRIO_NAT_SRC; }
+
 "icmpv6"               { return ICMP6; }
 "param-problem"                { return PPTR; }
 "max-delay"            { return MAXDELAY; }
-- 
ecklm

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to