Hi Pablo, > ct status == dnat and ct state != dnat checks for _exact_ matching. But if ct status != dnat is an exact equality check... why did it return true for all of the possible values? > Then: > > ct status dnat > > based on the datatype, provides a shortcut for > > ct status and dnat == dnat > > For inverted matching, please use: > > ct status and dnat != dnat Aha! I had a suspicion something like this might be possible but I couldn't figure out how to make it work. Maybe the documentation* for ct status should include examples like this? Here's what I did... nft add rule inet PerIfRouteTable PerIfRoute_Forward \( ct status \& dnat \) != dnat ct mark != 0 ct mark set 0 And how it got reported back to me... ct status & dnat != dnat ct mark != 0x00000000 ct mark set 0x00000000 It works as expected :) * I'm not sure where all the documentation is, but I found this page and it only suggested no-op, != and {} matching. https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes#Ct I did a bit of experimentation... I failed to make == and != do anything useful, at least with ct status (but nftables does not expose all of the underlying bitmask values, so maybe that's why?). It more or less seems like this to me... ct status == value # never matches ct status != value # always matches But I was able to observe these things working: ( ct status & token ) == token # true if the token bit is set ct status and token == token # shell-friendly alternative ct status token # convenient alternative ( ct status & token ) != token # true if the token bit is not set ct status and token != token # shell-friendly alternative ct status {token1,token2} # true if either token bit is set ct status token1,token2 # shell-friendly alternative ct status token1 ct status token2 # true if both token bits are set Lincoln