Remove shifts-by-0. These can occur after binop postprocessing
has adjusted the RHS value to account for a mask operation.
Example: frag frag-off @s4
Is internally represented via:
[ exthdr load ipv6 2b @ 44 + 2 => reg 1 ]
[ bitwise reg 1 = ( reg 1 & 0x0000f8ff ) ^ 0x00000000 ]
[ bitwise reg 1 = ( reg 1 >> 0x00000003 ) ]
[ lookup reg 1 set s ]
First binop masks out unwanted parts of the 16-bit field.
Second binop needs to left-shift so that lookups in the set will work.
When decoding, the first binop is removed after the exthdr load
has been adjusted accordingly. Constant propagation adjusts the
shift-value to 0 on removal. This change then gets rid of the
shift-by-0 entirely.
After this change, 'frag frag-off @s4' input is shown as-is.
Signed-off-by: Florian Westphal <fw@strlen.de>
binop_postprocess(ctx, expr, &expr->map);
}
+static bool is_shift_by_zero(const struct expr *binop)
+{
+ struct expr *rhs;
+
+ if (binop->op != OP_RSHIFT && binop->op != OP_LSHIFT)
+ return false;
+
+ rhs = binop->right;
+ if (rhs->etype != EXPR_VALUE || rhs->len > 64)
+ return false;
+
+ return mpz_get_uint64(rhs->value) == 0;
+}
+
static void relational_binop_postprocess(struct rule_pp_ctx *ctx,
struct expr **exprp)
{
*/
binop_postprocess(ctx, binop, &binop->left);
+ if (is_shift_by_zero(binop)) {
+ struct expr *lhs = binop->left;
+
+ expr_get(lhs);
+ expr_free(binop);
+ expr->left = lhs;
+ }
}
}
vlan id @s2 accept
}
+ chain c4 {
+ frag frag-off @s4 accept
+ }
+
chain c5 {
ip option ra value @s5 accept
}
sctp chunk init num-inbound-streams @s7 accept
}
+ chain c8 {
+ ip version @s8 accept
+ }
+
chain c9 {
ip hdrlength @s9 accept
}
ether type vlan vlan id @s2 accept
}
+ chain c4 {
+ frag frag-off @s4 accept
+ }
+
chain c5 {
ip option ra value @s5 accept
}
sctp chunk init num-inbound-streams @s7 accept
}
+ chain c8 {
+ ip version @s8 accept
+ }
+
chain c9 {
ip hdrlength @s9 accept
}