I'm trying to work out if there is a simple way to use nft to dynamically build a list of saddr and count the packets/bytes on each of them. I don't want to apply any limits on traffic - just measure it.

I know how to build a dynamic set and add discovered saddrs to it. but I'm failing to find any syntax which would allow me to add a counter for each saddr.

I know how to add a counter to the rule which adds saddrs to the set. ( not what I want though )

I know how to create and use an explicit counter for an individual named saddr.

I know I could use the knowledge I have already to create a dynamic set - examine it and then create individual rules for each saddr but it just seems there must be a better way to do this.

I see plenty of examples of connection limiting code which when listed suggest a count is available but none which seem directly applicable ( and none which seem to pass syntax checking by nft on my machine ).

I'm running this in a raspberry pi 4 ( raspbian buster ), kernel version 5.4.51 and nftables v0.9.0 (Fearless Fosdick)

I'm a complete nft beginner.

  • Welcome to U&L. if you post the code you have that works without the counter then someone may be able to guide you. Without that it's going to be a bit of a guess what's best.
    – bu5hman
    Sep 1, 2020 at 17:28

1 Answer 1


Multiple improvements about using counters with sets were added in nftables versions after 0.9.0.

0.9.1 is required for your intended use. If you want to save and restore those counters to their previous value (eg: during a reboot), then 0.9.4 should be used. 0.9.4 also allows to simplify syntax when pre-populating a set where every element should have a counter.

So for a very basic example counting all incoming source addresses, following the examples in those links and keeping the older type syntax rather than typeof, one could use (with at least nftables 0.9.1):

table ip accounting
delete table ip accounting

table ip accounting {
        set inputcounters {
                type ipv4_addr    # with 0.9.4 could be replaced with: typeof ip saddr
#                counter           # optional, requires 0.9.4
                flags dynamic     # appeared in 0.9.1
#                timeout 7d        # consider using a timeout, possibly shorter, to avoid overflowing the set
                size 65535        # or a bigger size

        chain input {
                type filter hook input priority 0; policy accept;
                add @inputcounters { ip saddr counter } # 0.9.1 mandatory. Add new element *with counter* if not already present
                ip saddr @inputcounters # match element so increment its counter

There might be optimizations. Maybe ct state new is cached and is faster than trying to add a duplicate address (resulting in a no-op) in a set. etc.

Debian's buster-backports currently provides nftables 0.9.6.

You could try and use it directly (although beware of the FrankenDebian) or better recompile from sources in debian format, probably easier if coming directly from Debian's buster-backports since they are already suited for a buster target. eg by following and adapting the example in Debian's SimpleBackportCreation.

There are likely multiple steps involved (eg: "backporting" first the libnftnl source is needed before nftables) and of course this will trigger the installation of many development packages (better do this in a container or on an other system), but this is out of the scope of this answer.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .