1

Using sets in nftables is really cool. I am currently using a lot of statements like these in my nftables.conf rulesets:

iifname {clients0, dockernet} oifname wan0 accept \
    comment "Allow clients and Docker containers to reach the internet"

In the rule above {clients0, dockernet} is an anonymous (inline) set of interfaces. Instead of repetition in the rules over and over, I'd like to define a set of interfaces at the top of the file, called a named set in nftables. The manpage (Debian Buster) shows how to do that for several types of sets: ipv4_addr, ipv6_addr, ether_addr, inet_proto, inet_service and mark. However, it seems it's not available for interfaces by name or simple primitive type such as strings.

I've the approach below, but this does not work with the errors given:

  1. Omitting the type:

    table inet filter {
      set myset {
        elements = {
          clients0,
          dockernet,           
        }
      }
      [...]
    }
    

    Result: Error: set definition does not specify key.

  2. Using the string type:

    table inet filter {
      type string;
      set myset {
        elements = {
          clients0,
          dockernet,           
        }
      }
      [...]
    }
    

    Result: Error: unqualified key type string specified in set definition.

Is there really no way of naming the anonymous set I've shown on the top?

0
2

By searching in the source for version 0.9.0:

static const struct datatype *datatypes[TYPE_MAX + 1] = {

[...]

  [TYPE_IFINDEX]      = &ifindex_type,

[...]

  [TYPE_IFNAME]       = &ifname_type,
};

and then looking for where they are defined:

const struct datatype ifindex_type = {
  .type       = TYPE_IFINDEX,
  .name       = "iface_index",
  .desc       = "network interface index",

[...]

const struct datatype ifname_type = {
  .type       = TYPE_IFNAME,
  .name       = "ifname",
  .desc       = "network interface name",

it's possible to find that the needed types are iface_index (eg: iif lo) and ifname (eg iifname "lo"), even if (as of writing this answer) it's undocumented in nft's man page.

nft add set inet filter if-index-set '{ type iface_index;  }'
nft add set inet filter if-name-set '{ type ifname;  }'

nft add element inet filter if-index-set '{ lo }'
nft add element inet filter if-name-set '{ lo }'

nft add chain inet filter input '{ type filter hook input priority 0; }'
nft add rule inet filter input iif @if-index-set counter
nft add rule inet filter input iifname @if-name-set counter

Note that it appears wildcards don't work for an ifname set.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.