Re: [PATCHv2] netfilter: nft: add queue module

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

 



Hi,

On Wed, 2013-12-04 at 12:00 +0100, Pablo Neira Ayuso wrote:
> Hi Eric,
> 
> First off, thanks for this patch. Some comments below.
> 
> On Sat, Nov 30, 2013 at 04:14:04PM +0100, Eric Leblond wrote:
> > This patch adds a new nft module named "nft_queue" which is a
> > nftables target sending packet to nfnetlink_queue subsystem. It has
> > the same level of functionnality as is iptables ancestor and share
> > some code with it.
> > 
> > Signed-off-by: Eric Leblond <eric@xxxxxxxxx>
> > ---
> >  include/uapi/linux/netfilter/nf_tables.h |  20 ++++
...
> > +#include <linux/jhash.h>
> > +#include <linux/netfilter.h>
> > +#include <linux/netfilter/nf_tables.h>
> > +#include <net/netfilter/nf_tables.h>
> > +
> > +struct nft_queue {
> > +	u16			queuenum;
> > +	u16			queues_total;
> > +	u16			flags;
> > +	int			family;
>                                 ^
> This structure is very important that it doesn't have any hole (at its
> best) to reduce the size of the expression area in the rule. My
> proposal:

OK, fixing this.

> ...
> {
> 	u16			queue_num;
> 	u16			queue_total;
> 	u16			flags;
> 	u8			family;
> }
> 
> > +};
> > +
> > +static u32 jhash_initval __read_mostly;
> 
> From here:
> 
> > +static u32 hash_v4(const struct sk_buff *skb)
> > +{
> > +	const struct iphdr *iph = ip_hdr(skb);
> > +
> > +	/* packets in either direction go into same queue */
> > +	if ((__force u32)iph->saddr < (__force u32)iph->daddr)
> > +		return jhash_3words((__force u32)iph->saddr,
> > +			(__force u32)iph->daddr, iph->protocol, jhash_initval);
> > +
> > +	return jhash_3words((__force u32)iph->daddr,
> > +			(__force u32)iph->saddr, iph->protocol, jhash_initval);
> > +}
> > +
> > +#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
> > +static u32 hash_v6(const struct sk_buff *skb)
> > +{
> > +	const struct ipv6hdr *ip6h = ipv6_hdr(skb);
> > +	u32 a, b, c;
> > +
> > +	if ((__force u32)ip6h->saddr.s6_addr32[3] <
> > +	    (__force u32)ip6h->daddr.s6_addr32[3]) {
> > +		a = (__force u32) ip6h->saddr.s6_addr32[3];
> > +		b = (__force u32) ip6h->daddr.s6_addr32[3];
> > +	} else {
> > +		b = (__force u32) ip6h->saddr.s6_addr32[3];
> > +		a = (__force u32) ip6h->daddr.s6_addr32[3];
> > +	}
> > +
> > +	if ((__force u32)ip6h->saddr.s6_addr32[1] <
> > +	    (__force u32)ip6h->daddr.s6_addr32[1])
> > +		c = (__force u32) ip6h->saddr.s6_addr32[1];
> > +	else
> > +		c = (__force u32) ip6h->daddr.s6_addr32[1];
> > +
> > +	return jhash_3words(a, b, c, jhash_initval);
> > +}
> > +#endif
> > +
> > +static u32
> > +nfqueue_hash(const struct nft_pktinfo *pkt, const struct nft_queue *priv)
> > +{
> > +	u32 queue = priv->queuenum;
> > +
> > +	if (priv->family == AF_INET)
> > +		queue += ((u64) hash_v4(pkt->skb) * priv->queues_total) >> 32;
> > +#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
> > +	else if (priv->family == AF_INET6)
> > +		queue += ((u64) hash_v6(pkt->skb) * priv->queues_total) >> 32;
> > +#endif
> > +
> > +	return queue;
> > +}
> 
> to there, it looks very similar to NFQUEUE. You can move these
> functions to net/netfilter/nf_queue.h. You'll have to inline them and
> add the jhash_initval parameter. You'll need an initial patch to
> prepare this change and adapt xt_NFQUEUE.c

I'm ok with the two hash functions but the nfqueue_hash the second
argument is different. Do you want me to introduce a new common
structure for xt_NFQUEUE and nft_queue ?

> > +
> > +static void nft_queue_eval(const struct nft_expr *expr,
> > +			      struct nft_data data[NFT_REG_MAX + 1],
> > +			      const struct nft_pktinfo *pkt)
> > +{
> > +	struct nft_queue *priv = nft_expr_priv(expr);
...
> ret = NF_QUEUE_NR(queue);
> > +	if (priv->flags & NFT_QUEUE_FLAG_BYPASS)
> > +		ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
> > +
> > +	data[NFT_REG_VERDICT].verdict = ret;
> > +}
> > +
> > +static const struct nla_policy nft_queue_policy[NFTA_QUEUE_MAX + 1] = {
> > +	[NFTA_QUEUE_NUM]		= { .type = NLA_U16 },
> > +	[NFTA_QUEUE_TOTAL]		= { .type = NLA_U16 },
> > +	[NFTA_QUEUE_FLAGS]		= { .type = NLA_U16 },
>                           ^------------^
> Comestic: I think one tab should be fine.

OK.

> > +};
> > +
> > +static int nft_queue_init(const struct nft_ctx *ctx,
> > +			   const struct nft_expr *expr,
..
> > +}
> > +
> > +static int nft_queue_dump(struct sk_buff *skb, const struct nft_expr *expr)
> > +{
> > +	const struct nft_queue *priv = nft_expr_priv(expr);
> > +
> > +	if (nla_put_be16(skb, NFTA_QUEUE_NUM, htons(priv->queuenum)))
> > +		goto nla_put_failure;
> > +
> > +	if (nla_put_be16(skb, NFTA_QUEUE_TOTAL, htons(priv->queues_total)))
> > +		goto nla_put_failure;
> > +
> > +	if (nla_put_be16(skb, NFTA_QUEUE_FLAGS, htons(priv->flags)))
> > +		goto nla_put_failure;
> 
> Comestic: Perhaps you can squash these three put lines in one single
> if to save a couple of lines, the code will be still quite readable.

Done.

BR
-- 
Eric Leblond <eric@xxxxxxxxx>

--
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