* 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: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: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: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.