Re: [PATCH v3 nft] Set/print standard chain priorities with textual names

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <ecklm94@xxxxxxxxx>
> ---
>  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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux