2

I am actually learning to use nftables on a test environment and I'm actually working with nftables sets. I was on version 0.7 and since my tests weren't working I updated to 0.9.4 version but my problem was still the same.

I can create my sets on my table without any problems. And my set elements must contain ipv4 adresses. I worked with nftables tables, chains and sets without problems, my rules worked etc...

So what I want to do but can't find how to do it is to delete all my set's elements without precising the ipv4 addresses one by one.

Let's say my table's name is test and my set name's is tmp with an ipv4_addr type, my configuration will looks like that:

table ip test {
        set tmp {
                type ipv4_addr
        }
}

I can add element to this set successfully with this command:

nft add element ip test tmp { 10.10.10.10 }

Now what I want to do is to delete all the elements of my set, I looked in the man page of nft and it say that I can flush all elements from my set with the flush command:

SETS
[...]
flush    Remove all elements from the specified set.

So I tried this command to delete all my elements from my set:

nft flush set test tmp

But it returns me this error:

Error: Could not process rule: Invalid argument
flush set test tmp
^^^^^^^^^^^^^^^^^^^

I tried a lot of commands in the same way (adding table before set, not precising the table), it always returns me an error, but not every time the same.

I think I must do something wrong but I can't figure what. If you have any idea please? I will be very thankful!

Maybe my overall configuration is bad and I must not think of sets that way?

And if it's not possible to flush the elements from a set, is there a way to delete all elements from a set (besides defining a flag timeout)?

Sorry if my message isn't clear, I'm french and it's a little hard writing in an other language to describe a problem...

Thanks!

Regards.

mjtn
  • 51
  • 6

2 Answers2

3

So I contacted the netfilter team and gave me an answer.

The flush option for a set only works from Linux 4.10 onwards and my version was below.

I found a way to flush the table anyway with these commands on Debian if you are interested:

Store the elements from the set in variable:

elements=$(nft list set test tmp | awk '/{ /,/}/' | cut -d '=' -f 2)

Delete the elements with the delete command

nft delete element test tmp ${ip_elements}

Hope it'll help some people.

mjtn
  • 51
  • 6
0

If you are using a nft script for the atomic update functionality, you can also store your set as a variable in that script.

Using a named set, you would do something like

#!/usr/sbin/nft -f

flush set ip test tmp

table ip test {
  set tmp {
    type ipv4_addr
    elements = { 10.10.10.10 }
  }

  chain somechain {
    type filter hook input priority 0; policy accept
    ip saddr @tmp meta nftrace set 1
  }
}

but since that doesn't work, you can do this instead

define tmp = { 10.10.10.10 }

flush chain ip test somechain

table ip test {
  chain somechain {
    type filter hook input priority 0; policy accept
    ip saddr $tmp meta nftrace set 1
  }
}

This keeps the readability of using the named set, but it is converted to an in-line anonymous set upon execution.

This updates the whole rule, and thus "flushes" the old values in the set.

Of cause, this requires that the rule is in a chain you can flush and recreate on every run.