I'm not sure it's just me or you that are missing something here. On Wed, 28 Jul 2021 at 05:05, Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> wrote: > > On Wed, Jul 28, 2021 at 02:36:18AM +0800, Tom Yan wrote: > > Hmm, that means `tcp flags & (fin | syn | rst | ack) syn` is now > > equivalent to 'tcp flags & (fin | syn | rst | ack) == syn'. > > Yes, those two are equivalent. > > > Does that mean `tcp flags syn` (was supposed to be and) is now > > equivalent to `tcp flags == syn` > > tcp flag syn > > is a shortcut to match on the syn bit regarless other bit values, it's > a property of the bitmask datatypes. Don't you think the syntax will be inconsistent then? As a user, it looks pretty irrational to me: with a mask, just `syn` checks the exact value of the flags (combined); without a mask, it checks and checks only whether the specific bit is on. At least to me I would then expect `tcp flags syn` should be equivalent / is a shortcut to `tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) syn` hence `tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == syn` hence `tcp flags == syn`. > > tcp flags == syn > > is an exact match, it checks that the syn bit is set on. > > > instead of `tcp flags & syn == syn` / `tcp flags & syn != 0`? > > these two above are equivalent, I just sent a patch to fix the > tcp flags & syn == syn case. > > > Suppose `tcp flags & syn != 0` should then be translated to `tcp flags > > syn / syn` instead, please note that while nft translates `tcp flags & > > syn == syn` to `tcp flags syn / syn`, it does not accept the > > translation as input (when the mask is not a comma-separated list): > > > > # nft --debug=netlink add rule meh tcp_flags 'tcp flags syn / syn' > > Error: syntax error, unexpected newline, expecting comma > > add rule meh tcp_flags tcp flags syn / syn > > ^ > > The most simple way to express this is: tcp flags == syn. That does not sound right to me at all. Doesn't `syn / syn` means "with the mask (the second/"denominator" `syn`) applied on the flags, we get the value (the first/"nominator" `syn`), which means `tcp flags & syn == syn` instead of `tcp flags == syn` (which in turn means all bits but syn are cleared). > > > Also, does that mean `tcp flags & (fin | syn | rst | ack) fin,syn,ack` > > will now be equivalent to `tcp flags & (fin | syn | rst | ack) = (fin > > | syn | ack)` > > Yes, those two are equivalent. This is the same example as the one you > have used at the beginning of this email. > > > instead of (ultimately) `tcp flags & (fin | syn | ack) != 0`? > > That's equivalent to: > > tcp flags fin,syn,ack > > A quick summary: > > - If you want an exact match: > > tcp flags == fin,syn,ack > > - If you want to check that those three bits are set on (regardless > the remaining bits): > > tcp flags fin,syn,ack / fin,syn,ack > > - If you want to check that any of these three bits is set on: > > tcp flags fin,syn,ack > > > Which means `tcp flags & (fin | syn | ack) != 0` should not be > > translated to `tcp flags fin,syn,ack`? > > tcp flags & (fin | syn | ack) != 0 is checking for any of these three > bits to be set on, this translation is correct.