(I hope these questions aren't too stupid for this list!) A stateful firewall ruleset usually starts like: ct state established,related accept ct state invalid drop # Hooray, 99% of packets are now decided; # we only need to think hard the ones in ct state new! If you want to guard against a coworker "accidentally" adding NOTRACK in raw, you might tweak that to drop "ct untracked" as well: ct state established,related accept ct state != new drop But nftables has these "verdict map" things now: ct state vmap { established:accept, related:accept, invalid:drop } Is that "better" than the original? It's one less rule, so it ought to be more efficient, right? One obvious downside is you lose the ability to counter/log/reject the ct state invalid packets, because those aren't valid in verdict_expr. Why is the original allowed to have "established,related" without braces? [UPDATE: answered below] I'm a little bit worried because "nft describe ct state" looks like a list of flags (powers of two), and in parser_bison.y I don't understand ct_expr, but set_flag_list is using a comma as a bitwise OR. Can a packet be *both* established and related at the same time? If so, is "ct state established,related" matching any packet that has established or related *OR BOTH*? If so, does that mean it will accept some packets that my vmap (above) won't? The parser won't accept "{related,established: accept}" in a vmap, but it will accept a pipe. Does this has the same meaning as the original pair of rules? ct state vmap { invalid : drop, established | related : accept } I think so, because the pipe comes back out as a comma here: # nft add rule 'inet x y ct state established|related accept' # nft list chain inet x y table inet x chain y { ct state established,related accept } } Oh using the English word "or" is probably clearer, at least for anglophones: ct state established or related accept ct state vmap { established or related: accept, invalid: drop } The equivalence of "or" and "|" and "," --- except inside a set/map --- wasn't obvious to me from the nft manpage (as at 0.9.1). I "caught on" because equivalences like "ne" and "!=" were mentioned here: https://wiki.nftables.org/wiki-nftables/index.php/Building_rules_through_expressions (no bitwise operators there, though) PS: AFAICT if a vmap doesn't match, the rule doesn't match, so processing just carries on to the next rule. Is there a way to have a "default value" in the vmap? e.g. ct state vmap { established or related: accept, new: continue, OTHERWISE: return } I can't see it in verdict_map_list_expr or in the manpage. PPS: my earlier "chain comment" question, I now realize the "NOOP rule" I wanted is just "continue", e.g. table inet x { chain y { continue comment "This chain is the common start for INPUT and FORWARD." continue comment "It allows the things you (almost always) want." ct state vmap { established or related: accept; invalid: drop } iiftype loopback accept icmp type { ... } accept icmpv6 type { ... } accept } }