Hi!
This looks good, but some comments.
On Tue, Jun 19, 2018 at 11:50:24AM +0200, Máté Eckl wrote:
> v3:
> - no tokens are used for priority names, lookup is used instead
> - names and values are moved out to a structure
> - the helper function became unnecessary, thus I removed it
>
> -- 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; }
The command uses "mangleprio"
[...]
> nft> list ruleset
> table ip x {
> chain y {
> type filter hook prerouting priority mangle; policy
> accept;
listing uses "mangle"
I guess you only need to amend the commit message, it's a leftover,
right?
We already agreed to use "mangle" for this, as the listing shows.
> }
>
> chain z {
> type filter hook prerouting priority mangle + 1; policy
> accept;
> }
>
> chain w {
> type filter hook prerouting priority mangle - 5; policy
> accept;
> }
>
> chain r {
> type filter hook prerouting priority filter + 10;
> policy accept;
> }
>
> chain t {
> type filter hook prerouting priority raw; policy accept;
> }
>
> chain q {
> type filter hook prerouting priority -289; policy
> accept;
> }
>
> chain h {
> type filter hook prerouting priority 15; policy accept;
> }
> }
>
> nft> add chain x h { type filter hook rerouting priority first; }
> Error: priority name 'first' is invalid
> add chain x h { type filter hook prerouting priority first; }
> ^^^^^
>
> Signed-off-by: Máté Eckl <[email protected]>
> ---
> include/rule.h | 1 +
> src/parser_bison.y | 24 ++++++++++++++++---
> src/rule.c | 59 ++++++++++++++++++++++++++++++++++++++++++----
> src/scanner.l | 2 ++
> 4 files changed, 79 insertions(+), 7 deletions(-)
>
> diff --git a/include/rule.h b/include/rule.h
> index 909ff36..bed9c2a 100644
> --- a/include/rule.h
> +++ b/include/rule.h
> @@ -193,6 +193,7 @@ struct chain {
> struct list_head rules;
> };
>
> +extern int chain_std_prio_lookup(const char *std_prio_name);
> extern const char *chain_type_name_lookup(const char *name);
> extern const char *chain_hookname_lookup(const char *name);
> extern struct chain *chain_alloc(const char *name);
> diff --git a/src/parser_bison.y b/src/parser_bison.y
> index 98bfeba..d753fd9 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"
> @@ -521,7 +524,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 standard_prio
>
> %type <string> dev_spec quota_unit
> %destructor { xfree($$); } dev_spec quota_unit
> @@ -1794,8 +1797,23 @@ 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; }
> + | standard_prio
> + | standard_prio PLUS NUM { $$ = $1 + $3; }
> + | standard_prio DASH NUM { $$ = $1 - $3; }
> + ;
> +
> +standard_prio : STRING
> + {
> + int tmp = chain_std_prio_lookup($1);
> + if (tmp == NF_IP_PRI_LAST) {
> + erec_queue(error(&@$, "priority name
> '%s' is invalid", $1),
> + state->msgs);
> + YYERROR;
> + }
> + $$ = tmp;
> + }
> ;
>
> dev_spec : DEVICE STRING { $$ = $2; }
> diff --git a/src/rule.c b/src/rule.c
> index 56b956a..11d11b1 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)
> {
> @@ -769,6 +770,56 @@ const char *chain_policy2str(uint32_t policy)
> return "unknown";
> }
>
> +struct chain_prio_tag{
> + int val;
> + const char *str;
> +};
> +
> +const static struct chain_prio_tag chain_std_prios[] = {
> + { NF_IP_PRI_RAW, "raw" },
> + { NF_IP_PRI_MANGLE, "mangle" },
> + { NF_IP_PRI_NAT_DST, "dnat" },
> + { NF_IP_PRI_FILTER, "filter" },
> + { NF_IP_PRI_SECURITY, "security" },
> + { NF_IP_PRI_NAT_SRC, "snat" },
> +};
> +
> +int chain_std_prio_lookup(const char *std_prio_name) {
> + long unsigned int i;
> +
> + for (i = 0; i < sizeof(chain_std_prios) / sizeof(struct
> chain_prio_tag); ++i) {
Add ARRAY_SIZE() and use it, eg.
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
So this looks like:
for (i = 0; i < ARRAY_SIZE(chain_std_prios; ++i) {
> + if (!strcmp(chain_std_prios[i].str, std_prio_name))
> + return chain_std_prios[i].val;
> + }
> + return NF_IP_PRI_LAST;
Probably return -1 instead?
> +}
> +
> +static const char *chain_prio2str(int prio)
> +{
> + static char ret[256];
Can we avoid this 'static char', better pass a buffer to this function
as parameter. Return 0 in case of matching, otherwise, return -1.
> + char offstr[20];
> + const int reach = 10;
> + size_t i;
> +
> + ret[0] = 0;
> + offstr[0] = 0;
> + for (i = 0; i < sizeof(chain_std_prios) / sizeof(struct
> chain_prio_tag); ++i) {
> + const int sdt_prio = chain_std_prios[i].val;
> + const char *sdt_prio_str = chain_std_prios[i].str;
Better define sdt_prio at the very beginning of this function (BTW, I
guess you meant std instead of sdt).
> + if (prio >= sdt_prio - reach && prio <= sdt_prio + reach) {
> + int offset = prio - sdt_prio;
Same thing with the offset, define it at the beginning.
> + if (offset != 0) {
> + snprintf(offstr, sizeof(offstr), " %c %d",
> + offset > 0 ? '+' : '-', abs(offset));
> + }
> + sprintf(ret, "%s%s", sdt_prio_str, offstr);
> + return ret;
> + }
> + }
> + sprintf(ret, "%d", prio);
> + return ret;
> +}
--
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