Commit
6979625686ec ("relational: Eliminate meta OPs") introduced some
bugs when printing bitmask types.
First, during the post-processing phase of delinearization, the
expression for "tcp flags syn" (PAYLOAD & flag != 0) gets converted to
PAYLOAD == flag, which is not equivalent. This should be
PAYLOAD (IMPL) flag.
Then, during output, the "==" sign from "tcp flags == syn" is dropped,
because the bitmask condition in must_print_eq_op() was removed. Let's
restore it, so that "tcp flags == syn" doesn't get printed as
"tcp flags syn". An extra check for value types is added, so that we
don't start printing "==" for sets such as "tcp flags {syn,ack}"
Finally, add a regression test for this particular case.
Fixes: 6979625686ec ("relational: Eliminate meta OPs")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
bool must_print_eq_op(const struct expr *expr)
{
+ if (expr->right->dtype->basetype != NULL &&
+ expr->right->dtype->basetype->type == TYPE_BITMASK &&
+ expr->right->ops->type == EXPR_VALUE)
+ return true;
+
return expr->left->ops->type == EXPR_BINOP;
}
expr->left = expr_get(binop->left);
expr->right = binop_tree_to_list(NULL, binop->right);
- expr->op = OP_EQ;
+ expr->op = OP_IMPLICIT;
expr_free(binop);
} else if (binop->left->dtype->flags & DTYPE_F_PREFIX &&
tcp flags != { fin, urg, ecn, cwr} drop;ok
tcp flags cwr;ok
tcp flags != cwr;ok
+tcp flags == syn;ok
tcp flags & (syn|fin) == (syn|fin);ok;tcp flags & (fin | syn) == fin | syn
tcp window 22222;ok
[ payload load 1b @ transport header + 13 => reg 1 ]
[ cmp neq reg 1 0x00000080 ]
+# tcp flags == syn
+inet test-inet input
+ [ meta load l4proto => reg 1 ]
+ [ cmp eq reg 1 0x00000006 ]
+ [ payload load 1b @ transport header + 13 => reg 1 ]
+ [ cmp eq reg 1 0x00000002 ]
+
# tcp flags & (syn|fin) == (syn|fin)
inet test-inet input
[ meta load l4proto => reg 1 ]