Re: [PATCH nft] evaluate: set NFT_SET_EVAL flag if dynamic set already exists

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

 



On Thu, May 18, 2023 at 02:58:06PM +0200, Pablo Neira Ayuso wrote:
>  # cat test.nft
>  table ip test {
>         set dlist {
>                 type ipv4_addr
>                 size 65535
>         }
> 
>         chain output {
>                 type filter hook output priority filter; policy accept;
>                 udp dport 1234 update @dlist { ip daddr } counter packets 0 bytes 0
>         }
>  }
>  # nft -f test.nft
>  # nft -f test.nft
>  test.nft:2:6-10: Error: Could not process rule: File exists
>          set dlist {
>              ^^^^^
> 
> Phil Sutter says:
> 
> In the first call, the set lacking 'dynamic' flag does not exist
> and is therefore added to the cache. Consequently, both the 'add set'
> command and the set statement point at the same set object. In the
> second call, a set with same name exists already, so the object created
> for 'add set' command is not added to cache and consequently not updated
> with the missing flag. The kernel thus rejects the NEWSET request as the
> existing set differs from the new one.
> 
> Set on the NFT_SET_EVAL flag if the existing set sets it on.
> 
> Fixes: 8d443adfcc8c1 ("evaluate: attempt to set_eval flag if dynamic updates requested")
> Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
> ---
> Hi Phil,
> 
> Maybe this fix so there is no need for revert?
> 
>  src/evaluate.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/src/evaluate.c b/src/evaluate.c
> index 63e3e4147a40..09ad4ea19409 100644
> --- a/src/evaluate.c
> +++ b/src/evaluate.c
> @@ -4516,6 +4516,14 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
>  		existing_set = set_cache_find(table, set->handle.set.name);
>  		if (!existing_set)
>  			set_cache_add(set_get(set), table);
> +
> +		if (existing_set && existing_set->flags & NFT_SET_EVAL) {
> +			uint32_t existing_flags = existing_set->flags & ~NFT_SET_EVAL;
> +			uint32_t new_flags = set->flags & ~NFT_SET_EVAL;
> +
> +			if (existing_flags == new_flags)
> +				set->flags |= NFT_SET_EVAL;
> +		}
>  	}
>  
>  	if (!(set->flags & NFT_SET_INTERVAL) && set->automerge)
> -- 
> 2.30.2

Tested-by: Eric Garver <eric@xxxxxxxxxxx>

Thanks Pablo! This fixes the issue for me. Verified with my reproducer
[1].

[1]: https://bugzilla.redhat.com/show_bug.cgi?id=2177667#c2




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

  Powered by Linux