* cannot use != with ct status
@ 2020-10-14 4:16 Ramsay, Lincoln
2020-10-14 10:04 ` Pablo Neira Ayuso
0 siblings, 1 reply; 12+ messages in thread
From: Ramsay, Lincoln @ 2020-10-14 4:16 UTC (permalink / raw)
To: netfilter@vger.kernel.org
Hi,
I've just confirmed that I can't make a rule that matches ct status != dnat.
TL;DR I have to use ct status {expected,seen-reply,assured,confirmed,snat,dying} instead. This feels like a bug.
This page suggests using != and also lists all the valid values (or at least, I hope that's all the valid values): https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes#Ct
I have a firewalld-created dnat rule.
chain nat_PRE_wan_allow {
tcp dport 5007 dnat to xx.xx.xx.xx:7
}
There's a rule that sets a ct mark depending on the interface (so replies will correctly return, avoiding a problem with default routes).
chain PerIfRoute_Prerouting {
ct state established,related ct direction reply meta mark set ct mark
iifname "wwan0" ct state new ct mark set 4
iifname "wwan0" ct state new ct mark 4 meta mark set 4
ct direction original meta mark set 0
}
I have a forwarding rule that wants to match ct status != dnat.
chain PerIfRoute_Forward {
ct status != dnat ct mark != 0 ct mark set 0
}
I turned on nftrace and see that this condition matches?!
trace id 04c0aaee ip firewalld nat_PRE_wan_allow packet: iif "wwan0" ip saddr xx.xx.xx.xx ip daddr xx.xx.xx.xx ip dscp cs0 ip ecn not-ect ip ttl 50 ip id 2777 ip length 60 tcp sport 20692 tcp dport 5007 tcp flags == syn tcp window 64240
trace id 04c0aaee ip firewalld nat_PRE_wan_allow rule tcp dport 5007 dnat to xx.xx.xx.xx:7 (verdict accept)
trace id 04c0aaee inet PerIfRouteTable PerIfRoute_Prerouting packet: iif "wwan0" ip saddr xx.xx.xx.xx ip daddr xx.xx.xx.xx ip dscp cs0 ip ecn not-ect ip ttl 50 ip id 2777 ip protocol tcp ip length 60 tcp sport 20692 tcp dport 7 tcp flags == syn tcp window 64240
trace id 04c0aaee inet PerIfRouteTable PerIfRoute_Markers rule iifname "wwan0" ct state new ct mark set 0x00000004 (verdict continue)
trace id 04c0aaee inet PerIfRouteTable PerIfRoute_Markers rule iifname "wwan0" ct state new ct mark 0x00000004 meta mark set 0x00000004 (verdict continue)
trace id 04c0aaee inet PerIfRouteTable PerIfRoute_Prerouting rule ct direction original meta mark set 0x00000000 (verdict continue)
trace id 04c0aaee inet PerIfRouteTable PerIfRoute_Forward packet: iif "wwan0" oif "net2" ip saddr xx.xx.xx.xx ip daddr xx.xx.xx.xx ip dscp cs0 ip ecn not-ect ip ttl 49 ip id 2777 ip protocol tcp ip length 60 tcp sport 20692 tcp dport 7 tcp flags == syn tcp window 64240
trace id 04c0aaee inet PerIfRouteTable PerIfRoute_Forward rule ct status != dnat ct mark != 0x00000000 ct mark set 0x00000000 (verdict continue)
I did some tests...
Positive matching works as expected
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status ne expected nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status ne seen-reply nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status ne assured nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status ne confirmed nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status ne snat nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status ne dnat nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status ne dying nftrace set 1
Gives
trace id 6bc7de6c inet PerIfRouteTable PerIfRoute_Forward rule ct status dnat meta nftrace set 1 (verdict continue)
But the != matching always matches
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status != expected nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status != seen-reply nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status != assured nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status != confirmed nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status != snat nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status != dnat nftrace set 1
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status != dying nftrace set 1
Gives
trace id 6bc7de6c inet PerIfRouteTable PerIfRoute_Forward rule ct status != expected meta nftrace set 1 (verdict continue)
trace id 6bc7de6c inet PerIfRouteTable PerIfRoute_Forward rule ct status != seen-reply meta nftrace set 1 (verdict continue)
trace id 6bc7de6c inet PerIfRouteTable PerIfRoute_Forward rule ct status != assured meta nftrace set 1 (verdict continue)
trace id 6bc7de6c inet PerIfRouteTable PerIfRoute_Forward rule ct status != confirmed meta nftrace set 1 (verdict continue)
trace id 6bc7de6c inet PerIfRouteTable PerIfRoute_Forward rule ct status != snat meta nftrace set 1 (verdict continue)
trace id 6bc7de6c inet PerIfRouteTable PerIfRoute_Forward rule ct status != dnat meta nftrace set 1 (verdict continue)
trace id 6bc7de6c inet PerIfRouteTable PerIfRoute_Forward rule ct status != dying meta nftrace set 1 (verdict continue)
If I rewrite my match to catch all the valid values, it works.
nft insert rule inet PerIfRouteTable PerIfRoute_Forward position 2 ct status '{expected,seen-reply,assured,confirmed,snat,dying}' nftrace set 1
This does not match when ct status == dnat.
With all that debugging in, I saw a reply packet too. It ... complicates things?
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward packet: iif "net2" oif "wwan0" ether saddr xx:xx:xx:xx:xx:xx ether daddr xx:xx:xx:xx:xx:xx ip saddr xx.xx.xx.xx ip daddr xx.xx.xx.xx ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 0 ip protocol tcp ip length 60 tcp sport 7 tcp dport 57444 tcp flags == 0x12 tcp window 28960
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward rule ct status seen-reply meta nftrace set 1 (verdict continue)
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward rule ct status confirmed meta nftrace set 1 (verdict continue)
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward rule ct status snat meta nftrace set 1 (verdict continue)
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward rule ct status dnat meta nftrace set 1 (verdict continue)
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward rule ct status != expected meta nftrace set 1 (verdict continue)
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward rule ct status != seen-reply meta nftrace set 1 (verdict continue)
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward rule ct status != assured meta nftrace set 1 (verdict continue)
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward rule ct status != confirmed meta nftrace set 1 (verdict continue)
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward rule ct status != snat meta nftrace set 1 (verdict continue)
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward rule ct status != dnat meta nftrace set 1 (verdict continue)
trace id 2df38b4d inet PerIfRouteTable PerIfRoute_Forward rule ct status != dying meta nftrace set 1 (verdict continue)
Matching multiple statuses?! I had a look and it seems ct status is a bitmask underneath, not a single value.
I guess the = operator is doing "is this value in the bitmask" logic? I don't know what != is doing, but I'd expect the "opposite" (ie. "is this value not in the bitmask").
I'm using Yocto (Dunfell) which has given me these versions:
- Linux 5.4
- nftables 0.9.3
- libnftnl 1.1.5
Lincoln
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: cannot use != with ct status 2020-10-14 4:16 cannot use != with ct status Ramsay, Lincoln @ 2020-10-14 10:04 ` Pablo Neira Ayuso 2020-10-14 10:25 ` Jozsef Kadlecsik 2020-10-14 23:29 ` Ramsay, Lincoln 0 siblings, 2 replies; 12+ messages in thread From: Pablo Neira Ayuso @ 2020-10-14 10:04 UTC (permalink / raw) To: Ramsay, Lincoln; +Cc: netfilter@vger.kernel.org On Wed, Oct 14, 2020 at 04:16:40AM +0000, Ramsay, Lincoln wrote: > Hi, > > I've just confirmed that I can't make a rule that matches ct status != dnat. ct status == dnat and ct state != dnat checks for _exact_ matching. 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: cannot use != with ct status 2020-10-14 10:04 ` Pablo Neira Ayuso @ 2020-10-14 10:25 ` Jozsef Kadlecsik 2020-10-14 10:30 ` Pablo Neira Ayuso 2020-10-14 11:02 ` G.W. Haywood 2020-10-14 23:29 ` Ramsay, Lincoln 1 sibling, 2 replies; 12+ messages in thread From: Jozsef Kadlecsik @ 2020-10-14 10:25 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: Ramsay, Lincoln, netfilter@vger.kernel.org On Wed, 14 Oct 2020, Pablo Neira Ayuso wrote: > On Wed, Oct 14, 2020 at 04:16:40AM +0000, Ramsay, Lincoln wrote: > > Hi, > > > > I've just confirmed that I can't make a rule that matches ct status != dnat. > > ct status == dnat and ct state != dnat checks for _exact_ matching. > > Then: > > ct status dnat > > based on the datatype, provides a shortcut for > > ct status and dnat == dnat Sorry, but it looks like really strange. "ct status nat" would be more natural to me. > For inverted matching, please use: > > ct status and dnat != dnat Best regards, Jozsef - E-mail : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.hu PGP key : https://wigner.hu/~kadlec/pgp_public_key.txt Address : Wigner Research Centre for Physics H-1525 Budapest 114, POB. 49, Hungary ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: cannot use != with ct status 2020-10-14 10:25 ` Jozsef Kadlecsik @ 2020-10-14 10:30 ` Pablo Neira Ayuso 2020-10-14 18:09 ` Jozsef Kadlecsik 2020-10-14 11:02 ` G.W. Haywood 1 sibling, 1 reply; 12+ messages in thread From: Pablo Neira Ayuso @ 2020-10-14 10:30 UTC (permalink / raw) To: Jozsef Kadlecsik; +Cc: Ramsay, Lincoln, netfilter@vger.kernel.org Hi Jozsef, On Wed, Oct 14, 2020 at 12:25:40PM +0200, Jozsef Kadlecsik wrote: > On Wed, 14 Oct 2020, Pablo Neira Ayuso wrote: > > > On Wed, Oct 14, 2020 at 04:16:40AM +0000, Ramsay, Lincoln wrote: > > > Hi, > > > > > > I've just confirmed that I can't make a rule that matches ct status != dnat. > > > > ct status == dnat and ct state != dnat checks for _exact_ matching. > > > > Then: > > > > ct status dnat > > > > based on the datatype, provides a shortcut for > > > > ct status and dnat == dnat > > Sorry, but it looks like really strange. "ct status nat" would be more > natural to me. This is based on the ct status bits, so dnat is matching for destination NAT updates (ie. IPS_DST_NAT). Then, snat is matching for IPS_SRC_NAT. It should be possible to add ct status nat but such nat would be (IPS_SRC_NAT | IPS_DST_NAT) ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: cannot use != with ct status 2020-10-14 10:30 ` Pablo Neira Ayuso @ 2020-10-14 18:09 ` Jozsef Kadlecsik 2020-10-14 18:54 ` Pablo Neira Ayuso 0 siblings, 1 reply; 12+ messages in thread From: Jozsef Kadlecsik @ 2020-10-14 18:09 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: Ramsay, Lincoln, netfilter@vger.kernel.org On Wed, 14 Oct 2020, Pablo Neira Ayuso wrote: > > > > I've just confirmed that I can't make a rule that matches ct > > > > status != dnat. > > > > > > ct status == dnat and ct state != dnat checks for _exact_ matching. > > > > > > Then: > > > > > > ct status dnat > > > > > > based on the datatype, provides a shortcut for > > > > > > ct status and dnat == dnat > > > > Sorry, but it looks like really strange. "ct status nat" would be more > > natural to me. > > This is based on the ct status bits, so dnat is matching for > destination NAT updates (ie. IPS_DST_NAT). Then, snat is matching for > IPS_SRC_NAT. I could not express myself properly. I had no problem with the shortcut "ct status dnat" at all but with the expression "ct status and dnat == dnat". One could split it at the "and" part and thus the "dnat == dnat" part looks confusing. If one splits at "==" then the "and" in "ct status and dnat" is not quite intuitive. (I could not find the description of "and" in the manpage, at least at http://netfilter.org/projects/nftables/index.html.) Why is the "and" keyword required? Why couldn't the same syntax be used like at "ct state"? Best regards, Jozsef - E-mail : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.hu PGP key : https://wigner.hu/~kadlec/pgp_public_key.txt Address : Wigner Research Centre for Physics H-1525 Budapest 114, POB. 49, Hungary ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: cannot use != with ct status 2020-10-14 18:09 ` Jozsef Kadlecsik @ 2020-10-14 18:54 ` Pablo Neira Ayuso 0 siblings, 0 replies; 12+ messages in thread From: Pablo Neira Ayuso @ 2020-10-14 18:54 UTC (permalink / raw) To: Jozsef Kadlecsik; +Cc: Ramsay, Lincoln, netfilter@vger.kernel.org On Wed, Oct 14, 2020 at 08:09:45PM +0200, Jozsef Kadlecsik wrote: > On Wed, 14 Oct 2020, Pablo Neira Ayuso wrote: > > > > > > I've just confirmed that I can't make a rule that matches ct > > > > > status != dnat. > > > > > > > > ct status == dnat and ct state != dnat checks for _exact_ matching. > > > > > > > > Then: > > > > > > > > ct status dnat > > > > > > > > based on the datatype, provides a shortcut for > > > > > > > > ct status and dnat == dnat > > > > > > Sorry, but it looks like really strange. "ct status nat" would be more > > > natural to me. > > > > This is based on the ct status bits, so dnat is matching for > > destination NAT updates (ie. IPS_DST_NAT). Then, snat is matching for > > IPS_SRC_NAT. > > I could not express myself properly. I had no problem with the shortcut > "ct status dnat" at all but with the expression "ct status and dnat == > dnat". > > One could split it at the "and" part and thus the "dnat == dnat" part > looks confusing. If one splits at "==" then the "and" in "ct status and > dnat" is not quite intuitive. (I could not find the description of "and" > in the manpage, at least at > http://netfilter.org/projects/nftables/index.html.) Why is the "and" > keyword required? Why couldn't the same syntax be used like at "ct state"? This uses the same syntax as ct state, for most cases: ct state new is just enough. The original thread refers to matching if the dnat bit is _unset_, ie. inverted matching. # nft -i # add rule x y (ct status & dnat) != dnat '&' is equivalent to 'and', it's the same token actually in the parser. I was using 'and' instead because I was in the shell, and I wanted to avoid escaping the &. The parens are optional, without the parens, bitwise operation takes precedence over comparison. Still confusing? ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: cannot use != with ct status 2020-10-14 10:25 ` Jozsef Kadlecsik 2020-10-14 10:30 ` Pablo Neira Ayuso @ 2020-10-14 11:02 ` G.W. Haywood 2020-10-14 12:50 ` Pablo Neira Ayuso 1 sibling, 1 reply; 12+ messages in thread From: G.W. Haywood @ 2020-10-14 11:02 UTC (permalink / raw) To: netfilter@vger.kernel.org Hi there, On Wed, 14 Oct 2020, Jozsef Kadlecsik wrote: > On Wed, 14 Oct 2020, Pablo Neira Ayuso wrote: > >> On Wed, Oct 14, 2020 at 04:16:40AM +0000, Ramsay, Lincoln wrote: >>> Hi, >>> >>> I've just confirmed that I can't make a rule that matches ct status != dnat. >> >> ct status == dnat and ct state != dnat checks for _exact_ matching. >> >> Then: >> >> ct status dnat >> >> based on the datatype, provides a shortcut for >> >> ct status and dnat == dnat > > Sorry, but it looks like really strange. ... +1 On Wed, 14 Oct 2020, Pablo Neira Ayuso wrote: > For inverted matching, please use: > > ct status and dnat != dnat > If you will forgive me some pseudocode, I'd interpret that as !(ct.status & dnat) and deduce (1) that 'ct status' is some sort of atom and (2) _either_ that '!=' has a lower precedence than 'and' _or_ that we must always assume left-to-right evaluation of the expression. Would any of that be right? After years of little more than occasionally looking at netfilter expressions, and despite having read the Wiki, the main things which still confuse me are what must be spelt out in full and what can be abbreviated, what will be associated with what, and where to put any (notional) parentheses when reading it. I don't know how I would ever have come up with Pablo's version of the expression. I find the syntax quite bewildering. Is there a way to write expressions for netfilter like my pseudocode, even if it's more verbose? Even if the alternative were *much* more verbose, as long as it looked something like the other things that I've been writing for nearly fifty years I'd find it much easier to understand. -- 73, Ged. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: cannot use != with ct status 2020-10-14 11:02 ` G.W. Haywood @ 2020-10-14 12:50 ` Pablo Neira Ayuso 2020-10-14 13:54 ` G.W. Haywood 0 siblings, 1 reply; 12+ messages in thread From: Pablo Neira Ayuso @ 2020-10-14 12:50 UTC (permalink / raw) To: G.W. Haywood; +Cc: netfilter@vger.kernel.org On Wed, Oct 14, 2020 at 12:02:08PM +0100, G.W. Haywood wrote: > Hi there, > > On Wed, 14 Oct 2020, Jozsef Kadlecsik wrote: > > On Wed, 14 Oct 2020, Pablo Neira Ayuso wrote: > > > > > On Wed, Oct 14, 2020 at 04:16:40AM +0000, Ramsay, Lincoln wrote: > > > > Hi, > > > > > > > > I've just confirmed that I can't make a rule that matches ct status != dnat. > > > > > > ct status == dnat and ct state != dnat checks for _exact_ matching. > > > > > > Then: > > > > > > ct status dnat > > > > > > based on the datatype, provides a shortcut for > > > > > > ct status and dnat == dnat > > > > Sorry, but it looks like really strange. ... > > +1 I think Jozsef got confused about _dnat_ specifically, not about the way the expression is represented itself - he refers to _nat_, but maybe he can clarify this. As I explained, we can probably improve documentation on how the bitwise datatype works for: ct status value where ct status is a key whose base datatype is bitwise (flags). You can check for the key datatype here: # nft describe ct status ct expression, datatype ct_status (conntrack status) (basetype bitmask, integer), 32 bits pre-defined symbolic constants (in hexadecimal): expected 0x00000001 seen-reply 0x00000002 assured 0x00000004 confirmed 0x00000008 snat 0x00000010 dnat 0x00000020 dying 0x00000200 You can also check for the instructions that nft generates: # nft --debug=netlink add x y ct status dnat ip [ ct load status => reg 1 ] [ bitwise reg 1 = (reg=1 & 0x00000020 ) ^ 0x00000000 ] [ cmp neq reg 1 0x00000000 ] > On Wed, 14 Oct 2020, Pablo Neira Ayuso wrote: > > > For inverted matching, please use: > > > > ct status and dnat != dnat > > > > If you will forgive me some pseudocode, I'd interpret that as > > !(ct.status & dnat) > > and deduce > > (1) that 'ct status' is some sort of atom and We call it 'key', this is basically telling the core to fetch such 'key' and place it in a register, ie. place 'ct status' 32-bits field in the conntrack entry into a register for matching. > (2) _either_ that '!=' has a lower precedence than 'and' _or_ that we > must always assume left-to-right evaluation of the expression. The binary operation always takes precedence to the comparison. > Would any of that be right? > > After years of little more than occasionally looking at netfilter > expressions, and despite having read the Wiki, the main things which > still confuse me are what must be spelt out in full and what can be > abbreviated, what will be associated with what, and where to put any > (notional) parentheses when reading it. Parens are optional, just in similar languages, some people like to use them explicitly so they do not have to remember about operation precedence, eg. # nft -i nft> add x y (ct status and dnat) == dnat > I don't know how I would ever have come up with Pablo's version of the > expression. I find the syntax quite bewildering. Is there a way to > write expressions for netfilter like my pseudocode, even if it's more > verbose? Even if the alternative were *much* more verbose, as long as > it looked something like the other things that I've been writing for > nearly fifty years I'd find it much easier to understand. Maybe. I've been trying to convince my system administrator friends to write programs in C, which is my language of preference, but they still prefer command line tools and rule-based languages :-) Please, if you have any proposal to express this in a more compact way that makes sense into the expression language, we'll be glad to take into consideration. Thanks. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: cannot use != with ct status 2020-10-14 12:50 ` Pablo Neira Ayuso @ 2020-10-14 13:54 ` G.W. Haywood 2020-10-14 14:11 ` Pablo Neira Ayuso 0 siblings, 1 reply; 12+ messages in thread From: G.W. Haywood @ 2020-10-14 13:54 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: netfilter@vger.kernel.org Hi there, On Wed, 14 Oct 2020, Pablo Neira Ayuso wrote: > ... friends ... still prefer command line tools ... :/ > Please, if you have any proposal to express this in a more compact way > that makes sense into the expression language, we'll be glad to take > into consideration. Thanks, first of all, for taking the trouble to help everyone here. Looking at your command line example: > nft> add x y (ct status and dnat) == dnat When I analyze something like this, I find it quite impressive how much (I didn't know that) I read into logical expressions without thinking about it, and how badly it can go wrong when things aren't as I expect. :/ Three things about this one throw me into a flat spin. I have no idea if any of this "makes sense into the expression language" as you put it but I hope at least I'll be able to explain the kinds of thing which I find confusing. 1. "ct status" Why is that not "ct.status" or "ct->status" or even "ct_status"? I see the space after "ct", I think it's a delimiter, and fall over it. 2. "and" The word "and" says to me that you're combining two boolean values, not doing a bitwise mask operation. I'd expect the bitwise operation to be represented by "&". The word "and" could perhaps alternatively be written as "&&", but never "&". Do your sysadmin friends do Perl? I'm not necessarily asking for the niceties of Perl precedence, but I really do have a lot invested in the meanings of logical operators in several very different languages. 3. "== dnat" This seems to be completely superfluous. If you do a bitwise mask operation the result is either zero or not, that's the whole point. All you need to know is if the result is TRUE (non-zero) or FALSE. Granted that sometimes code *might* be written this way for comparing values with e.g. 'enum' types, but only for some clarification which is not AFAICT necessary in this context - and usually only in fairly dense code which might otherwise be tricky for a human to follow. A relatively minor point is that predefined constants like "dnat" ought to be more readily distinguished from things like names of structure elements or whatever you call them like "status". That's often done by using upper case or some prefix, but I don't know if that would be feasible here. Is it somehow possible to 'alias' any of these names? I hope this all makes sense to you in English, even if it does _not_ make sense in the "expression language"; I hope it helps; I hope I'm not teaching my grandmother to suck anything; and I must apologize that I could not even attempt to express these thoughts in Spanish! -- 73, Ged. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: cannot use != with ct status 2020-10-14 13:54 ` G.W. Haywood @ 2020-10-14 14:11 ` Pablo Neira Ayuso 2020-10-14 14:22 ` G.W. Haywood 0 siblings, 1 reply; 12+ messages in thread From: Pablo Neira Ayuso @ 2020-10-14 14:11 UTC (permalink / raw) To: G.W. Haywood; +Cc: netfilter@vger.kernel.org On Wed, Oct 14, 2020 at 02:54:59PM +0100, G.W. Haywood wrote: > Hi there, > > On Wed, 14 Oct 2020, Pablo Neira Ayuso wrote: > > > ... friends ... still prefer command line tools ... > > :/ > > > Please, if you have any proposal to express this in a more compact way > > that makes sense into the expression language, we'll be glad to take > > into consideration. > > Thanks, first of all, for taking the trouble to help everyone here. > > Looking at your command line example: > > > nft> add x y (ct status and dnat) == dnat > > When I analyze something like this, I find it quite impressive how much > (I didn't know that) I read into logical expressions without thinking > about it, and how badly it can go wrong when things aren't as I expect. :/ > > Three things about this one throw me into a flat spin. I have no idea > if any of this "makes sense into the expression language" as you put it > but I hope at least I'll be able to explain the kinds of thing which I > find confusing. > > 1. "ct status" > > Why is that not "ct.status" or "ct->status" or even "ct_status"? I > see the space after "ct", I think it's a delimiter, and fall over it. That's right, you don't have to know what comes after ct. So far there is the manpage only. Autocompletion should do the trick in this case, so you just tab-tab and will get suggestions. > 2. "and" > > The word "and" says to me that you're combining two boolean values, > not doing a bitwise mask operation. I'd expect the bitwise operation > to be represented by "&". The word "and" could perhaps alternatively > be written as "&&", but never "&". In the rule-based language every statement (combination of matches and targets is && basically). > Do your sysadmin friends do Perl? I'm not necessarily asking for > the niceties of Perl precedence, but I really do have a lot invested > in the meanings of logical operators in several very different > languages. > > 3. "== dnat" > > This seems to be completely superfluous. If you do a bitwise mask > operation the result is either zero or not, that's the whole point. Exactly: ct status and dnat == dnat is superfluous. That's why you have: ct status dnat as I said before, which is providing a shortcut to check that the dnat status bit is set on. For the negation, which still sounds like a very uncommon operation (show me a use-case...), it's more verbose, yes. > All you need to know is if the result is TRUE (non-zero) or FALSE. > Granted that sometimes code *might* be written this way for comparing > values with e.g. 'enum' types, but only for some clarification which > is not AFAICT necessary in this context - and usually only in fairly > dense code which might otherwise be tricky for a human to follow. A > relatively minor point is that predefined constants like "dnat" ought > to be more readily distinguished from things like names of structure > elements or whatever you call them like "status". That's often done > by using upper case or some prefix, but I don't know if that would be > feasible here. Is it somehow possible to 'alias' any of these names? > > I hope this all makes sense to you in English, even if it does _not_ > make sense in the "expression language"; I hope it helps; I hope I'm > not teaching my grandmother to suck anything; and I must apologize > that I could not even attempt to express these thoughts in Spanish! No worries. I might not sound convincing enough: Command line tools and expression-based languages have their own limitations. But they can be easily extended in the shortrun by adding more extensions to assist users in what they type, and to spew warnings when they express things that make no sense and even recommend better ways to do it. All that I say above will come sooner or later, it's just a matter of time. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: cannot use != with ct status 2020-10-14 14:11 ` Pablo Neira Ayuso @ 2020-10-14 14:22 ` G.W. Haywood 0 siblings, 0 replies; 12+ messages in thread From: G.W. Haywood @ 2020-10-14 14:22 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: netfilter@vger.kernel.org Hi there, On Wed, 14 Oct 2020, Pablo Neira Ayuso wrote: > ... Autocompletion should do the trick in this case, so you just > tab-tab and will get suggestions. That's a useful tip, thanks! In at least two places in PDFs on the people.netfilter.org site it says autocompletion is still missing. :( https://people.netfilter.org/pablo/netdev0.1/slides/nftables-netdev-2015.pdf http://people.netfilter.org/pablo/nft-tutorial.pdf > All that I say above will come sooner or later, it's just a matter of time. OK, I can wait. :) -- 73, Ged. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: cannot use != with ct status 2020-10-14 10:04 ` Pablo Neira Ayuso 2020-10-14 10:25 ` Jozsef Kadlecsik @ 2020-10-14 23:29 ` Ramsay, Lincoln 1 sibling, 0 replies; 12+ messages in thread From: Ramsay, Lincoln @ 2020-10-14 23:29 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: netfilter@vger.kernel.org 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2020-10-14 23:29 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-10-14 4:16 cannot use != with ct status Ramsay, Lincoln 2020-10-14 10:04 ` Pablo Neira Ayuso 2020-10-14 10:25 ` Jozsef Kadlecsik 2020-10-14 10:30 ` Pablo Neira Ayuso 2020-10-14 18:09 ` Jozsef Kadlecsik 2020-10-14 18:54 ` Pablo Neira Ayuso 2020-10-14 11:02 ` G.W. Haywood 2020-10-14 12:50 ` Pablo Neira Ayuso 2020-10-14 13:54 ` G.W. Haywood 2020-10-14 14:11 ` Pablo Neira Ayuso 2020-10-14 14:22 ` G.W. Haywood 2020-10-14 23:29 ` Ramsay, Lincoln
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.