Verdict Maps (vmaps)

From nftables wiki
Revision as of 13:18, 30 July 2019 by Arturo (talk | contribs) (→‎Literal dictionaries: typo double 'that')
Jump to navigation Jump to search

The dictionaries, also known as verdict maps, are one of the most interesting features available in nftables. Basically, they allow you to attach an action to an element. Dictionaries internally use the generic set infrastructure.

Literal dictionaries

The following example shows how to create a tree of chains that whose traversal depends on the layer 4 protocol type:

% nft add rule ip filter input ip protocol vmap { tcp : jump tcp-chain, udp : jump udp-chain , icmp : jump icmp-chain }
% nft add rule ip filter input counter drop

This example above assumes that you've already created the tcp-chain, udp-chain and icmp-chain custom chains. Then, by attaching simple rules to account the traffic, ie.

% nft add rule filter icmp-chain counter
% nft add rule filter tcp-chain counter
% nft add rule filter udp-chain counter

You can check that the classification is already happening:

% nft list table filter
table ip filter {
        chain input {
                 type filter hook input priority 0;
                 ip protocol vmap { udp : jump udp-chain, tcp : jump tcp-chain, icmp : jump icmp-chain}
        }

        chain tcp-chain {
                 counter packets 4 bytes 520
        }

        chain udp-chain {
                 counter packets 4 bytes 678
        }

        chain icmp-chain {
                 counter packets 4 bytes 336
        }
}

As you probably already noticed, one of the the good things of nftables is that you can use dictionaries to construct performance rule-sets. This rule-set arrangement allows you to reduce the amount of linear list inspections to classify your packets.

Dictionary declarations

You can also declarate dictionaries and populate its content dynamically, for example:

% nft add map filter mydict { type ipv4_addr : verdict\; }

Then, you can add elements:

% nft add element filter mydict { 192.168.0.10 : drop, 192.168.0.11 : accept }

You can bind this set to a rule using the following command:

% nft add rule filter input ip saddr vmap @mydict

In case you want to build your own directionary, but you don't know what is the datatype name. Remember that you can inquire nft to know the datatype name:

% nft describe tcp dport
payload expression, datatype inet_service (internet network service) (basetype integer), 16 bits

See the inet_service string after datatype.