Re: [PATCH nf-next] netfilter: nft_osf: Add version option support

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

 



Sorry about the wrong mailing list, it was a mistake. I am fine with
your comments so I am going to send a v2. Thanks.

On 3/6/19 5:15 PM, Pablo Neira Ayuso wrote:
> Ups, wrong mailing list. For patches use
> netfilter-devel@xxxxxxxxxxxxxxx, so patchwork catches these patches:
> 
> http://patchwork.ozlabs.org/project/netfilter-devel/list/
> 
> Anyway, no worries, comments below.
> 
> On Wed, Mar 06, 2019 at 01:44:35PM +0100, Fernando Fernandez Mancera wrote:
>> Add version option support to the nftables "osf" expression.
>>
>> Signed-off-by: Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx>
>> ---
>>  include/linux/netfilter/nfnetlink_osf.h  | 11 ++++++---
>>  include/uapi/linux/netfilter/nf_tables.h |  6 +++++
>>  net/netfilter/nfnetlink_osf.c            | 14 +++++------
>>  net/netfilter/nft_osf.c                  | 31 ++++++++++++++++++++----
>>  4 files changed, 47 insertions(+), 15 deletions(-)
>>
>> diff --git a/include/linux/netfilter/nfnetlink_osf.h b/include/linux/netfilter/nfnetlink_osf.h
>> index c6000046c966..788613f36935 100644
>> --- a/include/linux/netfilter/nfnetlink_osf.h
>> +++ b/include/linux/netfilter/nfnetlink_osf.h
>> @@ -21,13 +21,18 @@ struct nf_osf_finger {
>>  	struct nf_osf_user_finger	finger;
>>  };
>>  
>> +struct nf_osf_data {
>> +	const char *genre;
>> +	const char *version;
>> +};
>> +
>>  bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
>>  		  int hooknum, struct net_device *in, struct net_device *out,
>>  		  const struct nf_osf_info *info, struct net *net,
>>  		  const struct list_head *nf_osf_fingers);
>>  
>> -const char *nf_osf_find(const struct sk_buff *skb,
>> -			const struct list_head *nf_osf_fingers,
>> -			const int ttl_check);
>> +bool nf_osf_find(const struct sk_buff *skb,
>> +		 const struct list_head *nf_osf_fingers,
>> +		 const int ttl_check, struct nf_osf_data *data);
>>  
>>  #endif /* _NFOSF_H */
>> diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
>> index a66c8de006cc..39bbb79ef4c2 100644
>> --- a/include/uapi/linux/netfilter/nf_tables.h
>> +++ b/include/uapi/linux/netfilter/nf_tables.h
>> @@ -1522,15 +1522,21 @@ enum nft_flowtable_hook_attributes {
>>   *
>>   * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
>>   * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
>> + * @NFTA_OSF_FLAGS: flags (NLA_U8)
> 
> Please, use NLA_U32 for this.
> 
>>   */
>>  enum nft_osf_attributes {
>>  	NFTA_OSF_UNSPEC,
>>  	NFTA_OSF_DREG,
>>  	NFTA_OSF_TTL,
>> +	NFTA_OSF_FLAGS,
>>  	__NFTA_OSF_MAX,
>>  };
>>  #define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
>>  
>> +enum nft_osf_flags {
>> +	NFT_OSF_F_VERSION = (1 << 0),
>> +};
>> +
>>  /**
>>   * enum nft_device_attributes - nf_tables device netlink attributes
>>   *
>> diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
>> index 1f1d90c1716b..7b827bcb412c 100644
>> --- a/net/netfilter/nfnetlink_osf.c
>> +++ b/net/netfilter/nfnetlink_osf.c
>> @@ -255,9 +255,9 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
>>  }
>>  EXPORT_SYMBOL_GPL(nf_osf_match);
>>  
>> -const char *nf_osf_find(const struct sk_buff *skb,
>> -			const struct list_head *nf_osf_fingers,
>> -			const int ttl_check)
>> +bool nf_osf_find(const struct sk_buff *skb,
>> +		 const struct list_head *nf_osf_fingers,
>> +		 const int ttl_check, struct nf_osf_data *data)
>>  {
>>  	const struct iphdr *ip = ip_hdr(skb);
>>  	const struct nf_osf_user_finger *f;
>> @@ -265,24 +265,24 @@ const char *nf_osf_find(const struct sk_buff *skb,
>>  	const struct nf_osf_finger *kf;
>>  	struct nf_osf_hdr_ctx ctx;
>>  	const struct tcphdr *tcp;
>> -	const char *genre = NULL;
>>  
>>  	memset(&ctx, 0, sizeof(ctx));
>>  
>>  	tcp = nf_osf_hdr_ctx_init(&ctx, skb, ip, opts);
>>  	if (!tcp)
>> -		return NULL;
>> +		return false;
>>  
>>  	list_for_each_entry_rcu(kf, &nf_osf_fingers[ctx.df], finger_entry) {
>>  		f = &kf->finger;
>>  		if (!nf_osf_match_one(skb, f, ttl_check, &ctx))
>>  			continue;
>>  
>> -		genre = f->genre;
>> +		data->genre = f->genre;
>> +		data->version = f->version;
>>  		break;
>>  	}
>>  
>> -	return genre;
>> +	return true;
>>  }
>>  EXPORT_SYMBOL_GPL(nf_osf_find);
>>  
>> diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
>> index b13618c764ec..b7fe8df7b6cc 100644
>> --- a/net/netfilter/nft_osf.c
>> +++ b/net/netfilter/nft_osf.c
>> @@ -7,11 +7,13 @@
>>  struct nft_osf {
>>  	enum nft_registers	dreg:8;
>>  	u8			ttl;
>> +	u8			flags;
>>  };
>>  
>>  static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
>>  	[NFTA_OSF_DREG]		= { .type = NLA_U32 },
>>  	[NFTA_OSF_TTL]		= { .type = NLA_U8 },
>> +	[NFTA_OSF_FLAGS]	= { .type = NLA_U8 },
>>  };
>>  
>>  static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
>> @@ -20,9 +22,10 @@ static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
>>  	struct nft_osf *priv = nft_expr_priv(expr);
>>  	u32 *dest = &regs->data[priv->dreg];
>>  	struct sk_buff *skb = pkt->skb;
>> +	char os_match[NFT_OSF_MAXGENRELEN + 1];
>>  	const struct tcphdr *tcp;
>> +	struct nf_osf_data data;
>>  	struct tcphdr _tcph;
>> -	const char *os_name;
>>  
>>  	tcp = skb_header_pointer(skb, ip_hdrlen(skb),
>>  				 sizeof(struct tcphdr), &_tcph);
>> @@ -35,11 +38,18 @@ static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
>>  		return;
>>  	}
>>  
>> -	os_name = nf_osf_find(skb, nf_osf_fingers, priv->ttl);
>> -	if (!os_name)
>> +	if (!nf_osf_find(skb, nf_osf_fingers, priv->ttl, &data)) {
>>  		strncpy((char *)dest, "unknown", NFT_OSF_MAXGENRELEN);
>> -	else
>> -		strncpy((char *)dest, os_name, NFT_OSF_MAXGENRELEN);
>> +	} else {
>> +		if (priv->flags & NFT_OSF_F_VERSION) {
>> +			strlcpy(os_match, data.genre, NFT_OSF_MAXGENRELEN);
>> +			strlcat(os_match, ":", NFT_OSF_MAXGENRELEN);
>> +			strlcat(os_match, data.version, NFT_OSF_MAXGENRELEN);
> 
> Probably use snprintf for this?
> 
>         snprintf(os_match, NFT_OSF_MAXGENRELEN, "%s:%s", data.genre, data.version);
> 
>> +		} else {
>> +			strlcpy(os_match, data.genre, NFT_OSF_MAXGENRELEN);
>> +		}
>> +		strncpy((char *)dest, os_match, NFT_OSF_MAXGENRELEN);
>> +	}
>>  }
>>  
>>  static int nft_osf_init(const struct nft_ctx *ctx,
>> @@ -47,6 +57,7 @@ static int nft_osf_init(const struct nft_ctx *ctx,
>>  			const struct nlattr * const tb[])
>>  {
>>  	struct nft_osf *priv = nft_expr_priv(expr);
>> +	u8 flags;
>>  	int err;
>>  	u8 ttl;
>>  
>> @@ -57,6 +68,13 @@ static int nft_osf_init(const struct nft_ctx *ctx,
>>  		priv->ttl = ttl;
>>  	}
>>  
>> +	if (tb[NFTA_OSF_FLAGS]) {
>> +		flags = nla_get_u8(tb[NFTA_OSF_FLAGS]);
> 
> If you turn this into a NLA_U32, then you have to use here.
> 
>                 flags = ntohl(nla_get_be32(tb[NFTA_OSF_FLAGS]));
> 
>> +		if (flags != NFT_OSF_F_VERSION && flags != 0)
> 
> No need to restrict flags != 0, remove that part of the check.
> 
>> +			return -EINVAL;
>> +		priv->flags = flags;
>> +	}
>> +
>>  	priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]);
>>  	err = nft_validate_register_store(ctx, priv->dreg, NULL,
>>  					  NFT_DATA_VALUE, NFT_OSF_MAXGENRELEN);
>> @@ -73,6 +91,9 @@ static int nft_osf_dump(struct sk_buff *skb, const struct nft_expr *expr)
>>  	if (nla_put_u8(skb, NFTA_OSF_TTL, priv->ttl))
>>  		goto nla_put_failure;
>>  
>> +	if (nla_put_u8(skb, NFTA_OSF_FLAGS, priv->flags))
> 
> And
>         if (nla_put_be32(skb, NFTA_OSF_FLAGS, ntohl(priv->flags))
> 
> here.
> 
> Other than that, patch looks good!
> 
>> +		goto nla_put_failure;
>> +
>>  	if (nft_dump_register(skb, NFTA_OSF_DREG, priv->dreg))
>>  		goto nla_put_failure;
>>  
>> -- 
>> 2.20.1
>>



[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux