Verdict Maps (vmaps): Difference between revisions

From nftables wiki
Jump to navigation Jump to search
(link to sets)
m (→‎Valid vmap Verdicts: Link nft man page)
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
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 [[Sets | generic set infrastructure]] and therefore share some semantics and options.
Verdict maps, created using the ''vmap'' statement, allow you to map elements directly to verdict statements. Internally they use the [[Sets | generic set infrastructure]] and therefore share some semantics and options. Some documentation may refer to vmaps as ''dictionaries''.


= Literal dictionaries =
 
= Anonymous vmaps =


The following example shows how to create a tree of chains that whose traversal depends on the layer 4 protocol type:
The following example shows how to create a tree of chains that whose traversal depends on the layer 4 protocol type:
Line 17: Line 18:
</source>
</source>


You can check that the classification is already happening:
You can check that the classification is happening:


<source lang="bash">
<source lang="bash">
Line 41: Line 42:
</source>
</source>


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.
The branching chain structure illustrated above is a powerful way to reduce the number of linear list inspections needed to classify your packets.


= Dictionary declarations =


You can also declarate dictionaries and populate its content dynamically, for example:
= Named vmaps =
 
You can also declare named vmaps, which can then be populated dynamically. For example:


<source lang="bash">
<source lang="bash">
Line 57: Line 59:
</source>
</source>


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


<source lang="bash">
<source lang="bash">
Line 63: Line 65:
</source>
</source>


In case you want to build your own dictionary, but you don't know what is the datatype name. Remember that you can inquire ''nft'' to know the datatype name:
Note that in the above example we had to specify the correct ipv4_addr [[Data_types | data&nbsp;type]] when creating the ''mydict'' vmap. In case you are unsure of the correct data type to specify, recall that you can ask ''nft'':
 
<nowiki>% nft describe ip saddr
payload expression, datatype ipv4_addr (IPv4 address) (basetype integer), 32 bits</nowiki>
 


<source lang="bash">
= Valid vmap Verdicts =
% nft describe tcp dport
payload expression, datatype inet_service (internet network service) (basetype integer), 16 bits
</source>


See the ''inet_service'' string after datatype.
The name ''verdict map'' can be taken literally: each element must map to a single simple ''verdict statement''. To recap the [[Further_documentation | ''nft''&nbsp;man&nbsp;page]] section, the complete list of such verdict statements is:
* accept
* drop
* queue
* continue
* return
* jump ''chain''
* goto ''chain''

Latest revision as of 11:08, 12 February 2021

Verdict maps, created using the vmap statement, allow you to map elements directly to verdict statements. Internally they use the generic set infrastructure and therefore share some semantics and options. Some documentation may refer to vmaps as dictionaries.


Anonymous vmaps

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 }

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 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
        }
}

The branching chain structure illustrated above is a powerful way to reduce the number of linear list inspections needed to classify your packets.


Named vmaps

You can also declare named vmaps, which can then be populated 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 vmap to a rule using the following command:

% nft add rule filter input ip saddr vmap @mydict

Note that in the above example we had to specify the correct ipv4_addr data type when creating the mydict vmap. In case you are unsure of the correct data type to specify, recall that you can ask nft:

% nft describe ip saddr
payload expression, datatype ipv4_addr (IPv4 address) (basetype integer), 32 bits


Valid vmap Verdicts

The name verdict map can be taken literally: each element must map to a single simple verdict statement. To recap the nft man page section, the complete list of such verdict statements is:

  • accept
  • drop
  • queue
  • continue
  • return
  • jump chain
  • goto chain