Re: [PATCH nf-next v4] netfilter: nf_tables: Add SYNPROXY support

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

 



Hi Pablo,

On 6/26/19 11:24 AM, Pablo Neira Ayuso wrote:
> On Tue, Jun 25, 2019 at 12:37:11PM +0200, Fernando Fernandez Mancera wrote:
> [...]
>> +static int nft_synproxy_init(const struct nft_ctx *ctx,
>> +			     const struct nft_expr *expr,
>> +			     const struct nlattr * const tb[])
>> +{
>> +	struct synproxy_net *snet = synproxy_pernet(ctx->net);
>> +	struct nft_synproxy *priv = nft_expr_priv(expr);
>> +	u32 flags;
>> +	int err;
>> +
>> +	if (tb[NFTA_SYNPROXY_MSS])
>> +		priv->info.mss = ntohs(nla_get_be16(tb[NFTA_SYNPROXY_MSS]));
>> +	if (tb[NFTA_SYNPROXY_WSCALE])
>> +		priv->info.wscale = nla_get_u8(tb[NFTA_SYNPROXY_WSCALE]);
>> +	if (tb[NFTA_SYNPROXY_FLAGS]) {
>> +		flags = ntohl(nla_get_be32(tb[NFTA_SYNPROXY_FLAGS]));
>> +		if (flags != 0 && (flags & NF_SYNPROXY_OPT_MASK) == 0)
> 
> Question: Is flag == 0 valid? If so, no need to return EINVAL in this
> case.

Yes, following the iptables behavior, in nftables we can set something
like this:

table ip x {
	chain y {
        	type filter hook prerouting priority raw; policy accept;
                tcp flags syn notrack
        }

        chain z {
        	type filter hook input priority filter; policy accept;
                ct state { invalid, untracked } synproxy
                ct state invalid drop
        }
}

In this case, flags == 0 because there is anything set.

> 
>> +			return -EINVAL;
>> +		priv->info.options = flags;
>> +	}
>> +
>> +	err = nf_ct_netns_get(ctx->net, ctx->family);
>> +	if (err)
>> +		return err;
>> +
>> +	switch (ctx->family) {
>> +	case NFPROTO_IPV4:
>> +		err = nf_synproxy_ipv4_init(snet, ctx->net);
>> +		if (err)
>> +			goto nf_ct_failure;
>> +		snet->hook_ref4++;
> 
> nf_synproxy_ipv4_init() internally deals with bumping hook_ref4,
> right?
> 

Yes, sorry I forgot to remove it. Same for the IPv6 bump.

>> +		break;
>> +#if IS_ENABLED(CONFIG_IPV6)
>> +	case NFPROTO_IPV6:
>> +		err = nf_synproxy_ipv6_init(snet, ctx->net);
>> +		if (err)
>> +			goto nf_ct_failure;
>> +		snet->hook_ref6++;
> 
> Same here.
> 
>> +		break;
> 
> #endif /* CONFIG_IPV6 */
> 
> Note that #endif should finish here, NFPROTO_INET and NFPROTO_BRIDGE
> should not be wrapper by this.
> 
> finishes here. You can probably replace this to CONFIG_NF_TABLES_IPV6
> as above, right?

Yes. In this case we can replace it with CONFIG_NF_TABLES_IPV6.

> 
>> +	case NFPROTO_INET:
>> +	case NFPROTO_BRIDGE:
>> +		err = nf_synproxy_ipv4_init(snet, ctx->net);
>> +		if (err)
>> +			goto nf_ct_failure;
> 
> Missing ifdef.
> 
>> +		err = nf_synproxy_ipv6_init(snet, ctx->net);
>> +		if (err)
>> +			goto nf_ct_failure;
>> +		snet->hook_ref4++;
>> +		snet->hook_ref6++;
> 
> Bumping refcnt manually?
> 
>> +		break;
>> +#endif
>> +	}
>> +
>> +	return 0;
>> +
>> +nf_ct_failure:
>> +	nf_ct_netns_put(ctx->net, ctx->family);
>> +	return err;
>> +}
>> +
>> +static void nft_synproxy_destroy(const struct nft_ctx *ctx,
>> +				 const struct nft_expr *expr)
>> +{
>> +	struct synproxy_net *snet = synproxy_pernet(ctx->net);
>> +
>> +	switch (ctx->family) {
>> +	case NFPROTO_IPV4:
>> +		nf_synproxy_ipv4_fini(snet, ctx->net);
>> +		break;
>> +#if IS_ENABLED(CONFIG_IPV6)
>> +	case NFPROTO_IPV6:
>> +		nf_synproxy_ipv6_fini(snet, ctx->net);
>> +		break;
>> +	case NFPROTO_INET:
>> +	case NFPROTO_BRIDGE:
>> +		nf_synproxy_ipv4_fini(snet, ctx->net);
> 
> We should allow bridge to run only with IPv4, if CONFIG_IPV6 is unset.
> 
> Just wrap this:
> 
> #ifdef IS_ENABLED(...)
> 
>> +		nf_synproxy_ipv6_fini(snet, ctx->net);
> 
> #endif
> 
> Or there's another trick you can do, in the header file, you add:
> 
> #ifdef IS_ENABLED(...)
> void nf_synproxy_ipv6_fini(..., ...);
> #else
> static inline void nf_synproxy_ipv6_fini(..., ...) {}
> #endid
> 
> so we don't need this #ifdef in the code.
> 

If there is no problem to have an inline definition with an empty body
then this is a good trick to avoid the #ifdef.



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

  Powered by Linux