Re: [PATCH 1/2 nft v3 preview] src: osf: add ttl option support

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

 



On Mon, Oct 22, 2018 at 10:46:18PM +0200, Fernando Fernandez Mancera wrote:
> Add support for ttl option in "osf" expression. Example:
> 
> table ip foo {
> 	chain bar {
> 		type filter hook input priority filter; policy accept;
> 		osf skip name "Linux"

osf ttl skip
osf ttl loose

Don't remove the 'ttl' token from there.

I just didn't want to have: osf ttl ttl-nocheck, which was sort of
redundant.

> 	}
> }
> 
> Signed-off-by: Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx>
> ---
> v1:initial patch
> v2:use "ttl-global, ttl-nocheck.." instead of "1, 2.."
> v3:better names for ttl options, add json and tests/py support

Could you describe what is not yet working here? Thanks!

> ---
>  include/expression.h                |  4 +++
>  include/linux/netfilter/nf_tables.h |  2 ++
>  include/osf.h                       |  2 +-
>  src/json.c                          |  2 +-
>  src/netlink_delinearize.c           |  5 +++-
>  src/netlink_linearize.c             |  1 +
>  src/osf.c                           | 26 ++++++++++++++++--
>  src/parser_bison.y                  | 19 +++++++++++--
>  src/parser_json.c                   |  5 ++--
>  tests/py/inet/osf.t                 |  3 +++
>  tests/py/inet/osf.t.json            |  3 +++
>  tests/py/inet/osf.t.payload         | 41 +++++++++++++++++++----------
>  12 files changed, 90 insertions(+), 23 deletions(-)
> 
> diff --git a/include/expression.h b/include/expression.h
> index d6977c3..f018c95 100644
> --- a/include/expression.h
> +++ b/include/expression.h
> @@ -345,6 +345,10 @@ struct expr {
>  			uint8_t		direction;
>  			uint8_t		spnum;
>  		} xfrm;
> +		struct {
> +			/* EXPR_OSF */
> +			uint8_t			ttl;
> +		} osf;
>  	};
>  };
>  
> diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
> index 4e28598..1d13ad3 100644
> --- a/include/linux/netfilter/nf_tables.h
> +++ b/include/linux/netfilter/nf_tables.h
> @@ -939,10 +939,12 @@ enum nft_socket_keys {
>   * enum nft_osf_attributes - nf_tables osf expression netlink attributes
>   *
>   * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
> + * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
>   */
>  enum nft_osf_attributes {
>  	NFTA_OSF_UNSPEC,
>  	NFTA_OSF_DREG,
> +	NFTA_OSF_TTL,
>  	__NFTA_OSF_MAX
>  };
>  #define NFT_OSF_MAX		(__NFTA_OSF_MAX - 1)
> diff --git a/include/osf.h b/include/osf.h
> index 54cdd4a..23ea34d 100644
> --- a/include/osf.h
> +++ b/include/osf.h
> @@ -1,7 +1,7 @@
>  #ifndef NFTABLES_OSF_H
>  #define NFTABLES_OSF_H
>  
> -struct expr *osf_expr_alloc(const struct location *loc);
> +struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl);
>  
>  extern int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
>  
> diff --git a/src/json.c b/src/json.c
> index 1cde270..cea9f19 100644
> --- a/src/json.c
> +++ b/src/json.c
> @@ -857,7 +857,7 @@ json_t *socket_expr_json(const struct expr *expr, struct output_ctx *octx)
>  
>  json_t *osf_expr_json(const struct expr *expr, struct output_ctx *octx)
>  {
> -	return json_pack("{s:{s:s}}", "osf", "key", "name");
> +	return json_pack("{s:{s:i, s:s}}", "osf", "ttl", expr->osf.ttl, "key", "name");
>  }
>  
>  json_t *xfrm_expr_json(const struct expr *expr, struct output_ctx *octx)
> diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
> index cd05885..84948db 100644
> --- a/src/netlink_delinearize.c
> +++ b/src/netlink_delinearize.c
> @@ -655,8 +655,11 @@ static void netlink_parse_osf(struct netlink_parse_ctx *ctx,
>  {
>  	enum nft_registers dreg;
>  	struct expr *expr;
> +	uint8_t ttl;
> +
> +	ttl = nftnl_expr_get_u8(nle, NFTNL_EXPR_OSF_TTL);
> +	expr = osf_expr_alloc(loc, ttl);
>  
> -	expr = osf_expr_alloc(loc);
>  	dreg = netlink_parse_register(nle, NFTNL_EXPR_OSF_DREG);
>  	netlink_set_register(ctx, dreg, expr);
>  }
> diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
> index 0ac51bd..0c8f5fe 100644
> --- a/src/netlink_linearize.c
> +++ b/src/netlink_linearize.c
> @@ -227,6 +227,7 @@ static void netlink_gen_osf(struct netlink_linearize_ctx *ctx,
>  
>  	nle = alloc_nft_expr("osf");
>  	netlink_put_register(nle, NFTNL_EXPR_OSF_DREG, dreg);
> +	nftnl_expr_set_u8(nle, NFTNL_EXPR_OSF_TTL, expr->osf.ttl);
>  	nftnl_rule_add_expr(ctx->nlr, nle);
>  }
>  
> diff --git a/src/osf.c b/src/osf.c
> index 85c9573..1a224fd 100644
> --- a/src/osf.c
> +++ b/src/osf.c
> @@ -5,13 +5,32 @@
>  #include <osf.h>
>  #include <json.h>
>  
> +static const char *osf_ttl_int_to_str(const uint8_t ttl)
> +{
> +	if (ttl == 1)
> +		return "loose ";
> +	else if (ttl == 2)
> +		return "skip ";
> +
> +	return "";
> +}
> +
>  static void osf_expr_print(const struct expr *expr, struct output_ctx *octx)
>  {
> -	nft_print(octx, "osf name");
> +	const char *ttl_str;
> +
> +	ttl_str = osf_ttl_int_to_str(expr->osf.ttl);
> +	nft_print(octx, "osf %sname", ttl_str);
>  }
>  
>  static void osf_expr_clone(struct expr *new, const struct expr *expr)
>  {
> +	new->osf.ttl = expr->osf.ttl;
> +}
> +
> +static bool osf_expr_cmp(const struct expr *e1, const struct expr *e2)
> +{
> +	return e1->osf.ttl == e2->osf.ttl;
>  }
>  
>  static const struct expr_ops osf_expr_ops = {
> @@ -19,10 +38,11 @@ static const struct expr_ops osf_expr_ops = {
>  	.name		= "osf",
>  	.print		= osf_expr_print,
>  	.clone		= osf_expr_clone,
> +	.cmp		= osf_expr_cmp,
>  	.json		= osf_expr_json,
>  };
>  
> -struct expr *osf_expr_alloc(const struct location *loc)
> +struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl)
>  {
>  	unsigned int len = NFT_OSF_MAXGENRELEN * BITS_PER_BYTE;
>  	const struct datatype *type = &string_type;
> @@ -31,5 +51,7 @@ struct expr *osf_expr_alloc(const struct location *loc)
>  	expr = expr_alloc(loc, &osf_expr_ops, type,
>  			  BYTEORDER_HOST_ENDIAN, len);
>  
> +	expr->osf.ttl = ttl;
> +
>  	return expr;
>  }
> diff --git a/src/parser_bison.y b/src/parser_bison.y
> index 947a3cd..8bf4f1c 100644
> --- a/src/parser_bison.y
> +++ b/src/parser_bison.y
> @@ -15,12 +15,14 @@
>  #include <inttypes.h>
>  #include <syslog.h>
>  #include <netinet/ip.h>
> +#include <netinet/tcp.h>
>  #include <netinet/if_ether.h>
>  #include <linux/netfilter.h>
>  #include <linux/netfilter/nf_tables.h>
>  #include <linux/netfilter/nf_conntrack_tuple_common.h>
>  #include <linux/netfilter/nf_nat.h>
>  #include <linux/netfilter/nf_log.h>
> +#include <linux/netfilter/nfnetlink_osf.h>
>  #include <linux/xfrm.h>
>  #include <netinet/ip_icmp.h>
>  #include <netinet/icmp6.h>
> @@ -743,6 +745,7 @@ int nft_lex(void *, void *, void *);
>  %type <val>			fib_tuple	fib_result	fib_flag
>  
>  %type <expr>			osf_expr
> +%type <val>			osf_ttl
>  %destructor { expr_free($$); }	osf_expr
>  
>  %type <val>			markup_format
> @@ -3176,9 +3179,21 @@ fib_tuple		:  	fib_flag	DOT	fib_tuple
>  			|	fib_flag
>  			;
>  
> -osf_expr		:	OSF	NAME
> +osf_expr		:	OSF	osf_ttl		NAME
>  			{
> -				$$ = osf_expr_alloc(&@$);
> +				$$ = osf_expr_alloc(&@$, $2);
> +			}
> +			;
> +
> +osf_ttl			:	/* empty */	{ $$ = NF_OSF_TTL_TRUE; }
> +			|	STRING
> +			{
> +				if (!strcmp($1, "loose"))
> +					$$ = NF_OSF_TTL_LESS;
> +				else if (!strcmp($1, "skip"))
> +					$$ = NF_OSF_TTL_NOCHECK;
> +				else
> +					$$ = 3;
>  			}
>  			;
>  
> diff --git a/src/parser_json.c b/src/parser_json.c
> index 7047c00..fc0dc9a 100644
> --- a/src/parser_json.c
> +++ b/src/parser_json.c
> @@ -376,12 +376,13 @@ static struct expr *json_parse_osf_expr(struct json_ctx *ctx,
>  					const char *type, json_t *root)
>  {
>  	const char *key;
> +	uint8_t ttl;
>  
> -	if (json_unpack_err(ctx, root, "{s:s}", "key", &key))
> +	if (json_unpack_err(ctx, root, "{s:i, s:s}", "ttl", ttl,"key", &key))
>  		return NULL;
>  
>  	if (!strcmp(key, "name"))
> -		return osf_expr_alloc(int_loc);
> +		return osf_expr_alloc(int_loc, ttl);
>  
>  	json_error(ctx, "Invalid osf key value.");
>  	return NULL;
> diff --git a/tests/py/inet/osf.t b/tests/py/inet/osf.t
> index bccfc75..10439a6 100644
> --- a/tests/py/inet/osf.t
> +++ b/tests/py/inet/osf.t
> @@ -5,6 +5,9 @@
>  *inet;osfinet;osfchain
>  
>  osf name "Linux";ok
> +osf loose name "Linux";ok
> +osf skip name "Linux";ok
> +osf nottl name "Linux";fail
>  osf name "morethansixteenbytes";fail
>  osf name ;fail
>  osf name { "Windows", "MacOs" };ok
> diff --git a/tests/py/inet/osf.t.json b/tests/py/inet/osf.t.json
> index 4bb413c..4c5e26d 100644
> --- a/tests/py/inet/osf.t.json
> +++ b/tests/py/inet/osf.t.json
> @@ -4,6 +4,7 @@
>          "match": {
>              "left": {
>                  "osf": {
> +		    "ttl": 0,
   ^^^^^^^^^^^^^^^^^
Phil is using spaces here, not tabs. Note that "ttl" line is not
aligned with the one below.

>                      "key": "name"
>                  }
>              },
> @@ -19,6 +20,7 @@
>          "match": {
>              "left": {
>                  "osf": {
> +		    "ttl": 0,
>                      "key": "name"
>                  }
>              },
> @@ -58,6 +60,7 @@
>                      },
>                      "key": {
>                          "osf": {
> +			    "osf": 0,
>                              "key": "name"
>                          }
>                      }
> diff --git a/tests/py/inet/osf.t.payload b/tests/py/inet/osf.t.payload
> index 850ca29..7897fea 100644
> --- a/tests/py/inet/osf.t.payload
> +++ b/tests/py/inet/osf.t.payload
> @@ -13,19 +13,32 @@ inet osfinet osfchain
>    [ osf dreg 1 ]
>    [ cmp eq reg 1 0x756e694c 0x00000078 0x00000000 0x00000000 ]
>  
> -# osf name { "Windows", "MacOs" }
> -__set%d osfinet 3 size 2
> -__set%d osfinet 0
> -	element 646e6957 0073776f 00000000 00000000  : 0 [end]	element 4f63614d 00000073 00000000 00000000  : 0 [end]
> -inet osfinet osfchain 
> -  [ osf dreg 1 ]
> -  [ lookup reg 1 set __set%d ]
> -
> -# ct mark set osf name map { "Windows" : 0x00000001, "MacOs" : 0x00000002 }
> -__map%d osfip b size 2
> -__map%d osfip 0
> -        element 646e6957 0073776f 00000000 00000000  : 00000001 0 [end] element 4f63614d 00000073 00000000 00000000  : 00000002 0 [end]

Please, don't remove these tests lines...

> +# osf loose name "Linux"
>  ip osfip osfchain
>    [ osf dreg 1 ]
> -  [ lookup reg 1 set __map%d dreg 1 ]
> -  [ ct set mark with reg 1 ]
> +  [ cmp eq reg 1 0x756e694c 0x00000078 0x00000000 0x00000000 ]
> +
> +# osf loose name "Linux"
> +ip6 osfip6 osfchain
> +  [ osf dreg 1 ]
> +  [ cmp eq reg 1 0x756e694c 0x00000078 0x00000000 0x00000000 ]
> +
> +# osf loose name "Linux"
> +inet osfinet osfchain
> +  [ osf dreg 1 ]
> +  [ cmp eq reg 1 0x756e694c 0x00000078 0x00000000 0x00000000 ]
> +
> +# osf skip name "Linux"
> +ip osfip osfchain
> +  [ osf dreg 1 ]
> +  [ cmp eq reg 1 0x756e694c 0x00000078 0x00000000 0x00000000 ]
> +
> +# osf skip name "Linux"
> +ip6 osfip6 osfchain
> +  [ osf dreg 1 ]
> +  [ cmp eq reg 1 0x756e694c 0x00000078 0x00000000 0x00000000 ]
> +
> +# osf skip name "Linux"
> +inet osfinet osfchain
> +  [ osf dreg 1 ]
> +  [ cmp eq reg 1 0x756e694c 0x00000078 0x00000000 0x00000000 ]
> -- 
> 2.19.1
> 



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

  Powered by Linux