Score:1

How to refresh set element timeout in nftables?

us flag

How do I refresh a set element's timeout/expires value with nft before it is expired?

Adding an existing element to the set does not reset the timeout/expires value:

nft add element ip mytable myset { 10.10.10.1 timeout 60s }
# wait 10s
nft add element ip mytable myset { 10.10.10.1 timeout 60s expires 60s }
nft list set ip mytable myset

With iptables/ipset I could refresh timeouts by adding existing elements:

ipset add myset 10.10.10.1 timeout 60
# wait 10s
ipset add myset 10.10.10.1 -exist timeout 60
ipset list myset
Score:2
cl flag
A.B

While atomic rule replacement is documented:

Atomic Rule Replacement

You can use the -f option to atomically update your ruleset:

% nft -f file

it's not explicitly documented for element replacement, but that's really just a case of rule replacement. One can delete and add back the element in a single atomic transaction introduced with -f: this will replace the older entry with the newer and its updated expiration time, without ever getting the element temporarily missing.

So instead of doing the following, which wouldn't be atomic because between the two invocations of nft, the element would be temporarily not existing and rules depending on this set would temporarily not match:

# nft delete element ip mytable myset '{ 10.10.10.1 }'
# nft add element ip mytable myset '{ 10.10.10.1 timeout 60s expires 60s }'

this should be done using -f and an input file (- standing for stdin counts as valid input file):

# nft -f - <<'EOF'
delete element ip mytable myset { 10.10.10.1 }
add element ip mytable myset { 10.10.10.1 timeout 60s }
EOF

where the element will never cease to existing because it's an atomic change.

As usual with this nft construct, if one wants to do this idempotently, without having to know if the element already exists, and without touching other elements, it should be added, deleted and re-added, because while adding an existing element isn't an error, deleting a missing element will be an error:

# nft -f - <<'EOF'
add element ip mytable myset { 10.10.10.1 }
delete element ip mytable myset { 10.10.10.1 }
add element ip mytable myset { 10.10.10.1 timeout 60s }
EOF

It's still a single atomic transaction.


Additional notes

  • from packet path

    When doing this from packet path there's a distinction between add @myset which will set the timeout only when creating a new element, but won't update the timeout of an already existing element, allowing it to timeout over its full duration later, and update @myset which does set the timeout in all cases.

  • atomic rule update isn't limited to elements but can be used at any level

    For example the same can be done at the set level if there's a single element to care for:

    # nft -f - <<'EOF'
    add set ip mytable myset { type ipv4_addr; flags timeout; }
    delete set ip mytable myset
    add set ip mytable myset {
        type ipv4_addr
        flags timeout
        elements = { 127.0.0.1 timeout 1m }
    }
    EOF
    

    Actually above example will likely fail because there's probably a rule referencing the set, so it isn't allowed to delete it even during the transaction (one could instead rewrite likewise the whole table, with add table ip mytable, delete table ip mytable, add table ip mytable { ...). If the set is known to exist before, flushing it before adding back the single element is enough:

    # nft -f - <<'EOF'
    flush set ip mytable myset
    add element ip mytable myset { 127.0.0.1 timeout 1m }
    EOF
    

Of course an actual file can be used instead of - <<'EOF'...EOF.

Rabin avatar
in flag
By using flush you remove all the IP's in the set, Is there a real alternative to `ipset add -exist`?, which add or update the time stamp.
A.B avatar
cl flag
A.B
@Rabin yes it's described in my last example before the additional notes: you do in an atomic operation add + delete + add. adding alone won't update the timestamp. deleting alone without add before might fail. So the 3 are required. Though, very recent nftables and kernel accept a destroy which can replace add+delete (so use only two lines instead of 3: destroy+add). I insist on the fact that the result is atomic: the element never disappears during this transaction.
Rabin avatar
in flag
I care about updating the timestamp, and I'm looking for simple solution which don't require check if exist → remove → add operation.
A.B avatar
cl flag
A.B
@Rabin that is exactly what I'm talking about. Did you test what I wrote? Because it does what you are asking.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.