Re: [RFC PATCH] netfilter: nf_tables: extend payload to support writing data

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

 



On Mon, Feb 17, 2014 at 07:12:17PM +0100, Nikolay Aleksandrov wrote:
> This patch extends the payload expression to support packet writing.
> The new payload attribute - SREG specifies the source register to use
> when changing packet data, the rest of the attributes are the same:
> base - where to start from
> offset - offset in the packet
> len - length to write
> 
> The DREG attribute should not be set if writing is intended, if both
> attributes are set the SREG (packet writing) will take precedence.
> When the expression is dumped both registers will get dumped and the
> user can differentiate the type of the payload (reading/writing) by
> checking if the sreg attribute is different from zero.

I'd suggest to return an error if both are set. We should only accept
clearly defined input and reject everything else.

> I'm sending this patch early thus the RFC (I'm still testing),
> just to see if you have any comments on the structure and changes. Now to
> justify a few of the changes:
> I added the sreg as a separate variable to struct nft_payload in order for
> the user to be able to recognize which payload type is the expression when
> dumping since both SREG and DREG get dumped.

Adding another register seems fine. I'd suggest to only dump the one
actually used though.

> I also factored the offset code in nft_payload_make_offset since it's used
> by both evaluation functions, returns -1 on error.
> The two init functions check only the registers as that's what is different
> the rest of the attributes are still checked by the select_ops. I've also
> allowed to have both SREG and DREG set but in such case SREG takes
> precedence.

See above.

> I left the old payload names as they were, but they can get _get or
> something else if you'd like.

Actually I dislike the _get and _set suffixes, so I'm happy to use them
as little as possible :)

> diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
> index a2aeb31..1b42668 100644
> --- a/net/netfilter/nft_payload.c
> +++ b/net/netfilter/nft_payload.c
> @@ -17,23 +17,19 @@
>  #include <net/netfilter/nf_tables_core.h>
>  #include <net/netfilter/nf_tables.h>
>  
> -static void nft_payload_eval(const struct nft_expr *expr,
> -			     struct nft_data data[NFT_REG_MAX + 1],
> -			     const struct nft_pktinfo *pkt)
> +static int nft_payload_make_offset(const struct nft_pktinfo *pkt,
> +				   const struct nft_payload *payload)

We're using priv everywhere. Please keep this consistent. Also please
make sure (in the entire patch) that arguments are aligned with the
opening (.

>  {
> -	const struct nft_payload *priv = nft_expr_priv(expr);
> -	const struct sk_buff *skb = pkt->skb;
> -	struct nft_data *dest = &data[priv->dreg];
> -	int offset;
> +	int offset = -1;
>  
> -	switch (priv->base) {
> +	switch (payload->base) {
>  	case NFT_PAYLOAD_LL_HEADER:
> -		if (!skb_mac_header_was_set(skb))
> -			goto err;
> -		offset = skb_mac_header(skb) - skb->data;
> +		if (!skb_mac_header_was_set(pkt->skb))

Why don't you keep the local skb pointer?

> +			return offset;
> +		offset = skb_mac_header(pkt->skb) - pkt->skb->data;
>  		break;
>  	case NFT_PAYLOAD_NETWORK_HEADER:
> -		offset = skb_network_offset(skb);
> +		offset = skb_network_offset(pkt->skb);
>  		break;
>  	case NFT_PAYLOAD_TRANSPORT_HEADER:
>  		offset = pkt->xt.thoff;

> +static void nft_payload_set_eval(const struct nft_expr *expr,
> +				 struct nft_data data[NFT_REG_MAX + 1],
> +				 const struct nft_pktinfo *pkt)
> +{
> +	const struct nft_payload *priv = nft_expr_priv(expr);
> +	struct nft_data *source = &data[priv->sreg];
> +	int offset = nft_payload_make_offset(pkt, priv);
> +
> +	if (offset == -1)
> +		goto err;
> +	if (!skb_make_writable(pkt->skb, offset + priv->len))
> +		goto err;
> +	memcpy(pkt->skb->data + offset, source, priv->len);

We need to take care of checksumming. Shouldn't be too hard to get *most*
cases right using the existing checksum helpers.

> +
> +	return;
> +err:
> +	data[NFT_REG_VERDICT].verdict = NFT_BREAK;
> +}
> +
--
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