summaryrefslogtreecommitdiff
path: root/ovn
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2016-10-06 17:54:19 -0700
committerBen Pfaff <blp@ovn.org>2016-10-11 08:34:58 -0700
commit97ba1d55139d8348a7574b7947b21251befb2d4c (patch)
treec3df1ccceac54de718d98091a2567775721850c9 /ovn
parent85be6684f8afcfd215695a443fdbbc503286544b (diff)
downloadopenvswitch-97ba1d55139d8348a7574b7947b21251befb2d4c.tar.gz
expr: Simplify "x == 0/0" into 1.
An expression like "x == 0/0" does not test any actual bits in field x, so it resolves to true, but expr_simplify() was not smart enough to see this. This goes beyond an optimization, to become a bug fix, because expr_normalize() will assert-fail for expressions that become trivial when this simplification is omitted. For example: $ echo 'eth.dst == 0/0 && eth.dst == 0/0' | tests/ovstest test-ovn normalize-expr test-ovn: ../include/openvswitch/list.h:245: assertion !ovs_list_is_empty(list) failed in ovs_list_front() Aborted (core dumped) This commit fixes this and related problems. The test added by this commit is very specific to the particular problem, whereas a more general test would be better. A later commit adds the general test. Signed-off-by: Ben Pfaff <blp@ovn.org> Acked-by: Andy Zhou <azhou@ovn.org>
Diffstat (limited to 'ovn')
-rw-r--r--ovn/lib/expr.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/ovn/lib/expr.c b/ovn/lib/expr.c
index 4ae6b0b6b..a5dbcfaa4 100644
--- a/ovn/lib/expr.c
+++ b/ovn/lib/expr.c
@@ -1669,6 +1669,18 @@ expr_annotate(struct expr *expr, const struct shash *symtab, char **errorp)
}
static struct expr *
+expr_simplify_eq(struct expr *expr)
+{
+ const union mf_subvalue *mask = &expr->cmp.mask;
+ if (is_all_zeros(mask, sizeof *mask)) {
+ /* Simplify "ip4.dst == 0/0" to just "1" (plus a prerequisite). */
+ expr_destroy(expr);
+ return expr_create_boolean(true);
+ }
+ return expr;
+}
+
+static struct expr *
expr_simplify_ne(struct expr *expr)
{
struct expr *new = NULL;
@@ -1742,7 +1754,8 @@ expr_simplify(struct expr *expr)
switch (expr->type) {
case EXPR_T_CMP:
- return (expr->cmp.relop == EXPR_R_EQ || !expr->cmp.symbol->width ? expr
+ return (!expr->cmp.symbol->width ? expr
+ : expr->cmp.relop == EXPR_R_EQ ? expr_simplify_eq(expr)
: expr->cmp.relop == EXPR_R_NE ? expr_simplify_ne(expr)
: expr_simplify_relational(expr));