]> git.proxmox.com Git - ovs.git/blame - ovn/lib/expr.c
ovn: Implement basic ARP support for L3 logical routers.
[ovs.git] / ovn / lib / expr.c
CommitLineData
e0840f11 1/*
f1c16a85 2 * Copyright (c) 2015, 2016 Nicira, Inc.
e0840f11
BP
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <config.h>
18#include "expr.h"
19#include "dynamic-string.h"
20#include "json.h"
21#include "lex.h"
b4970837 22#include "logical-fields.h"
e0840f11 23#include "match.h"
3b7cb7e1 24#include "ofp-actions.h"
e0840f11 25#include "shash.h"
f386a8a7 26#include "simap.h"
9d4aecca 27#include "sset.h"
e0840f11
BP
28#include "openvswitch/vlog.h"
29
30VLOG_DEFINE_THIS_MODULE(expr);
31\f
32/* Returns the name of measurement level 'level'. */
33const char *
34expr_level_to_string(enum expr_level level)
35{
36 switch (level) {
37 case EXPR_L_NOMINAL: return "nominal";
38 case EXPR_L_BOOLEAN: return "Boolean";
39 case EXPR_L_ORDINAL: return "ordinal";
40 default: OVS_NOT_REACHED();
41 }
42}
43\f
44/* Relational operators. */
45
46/* Returns a string form of relational operator 'relop'. */
47const char *
48expr_relop_to_string(enum expr_relop relop)
49{
50 switch (relop) {
51 case EXPR_R_EQ: return "==";
52 case EXPR_R_NE: return "!=";
53 case EXPR_R_LT: return "<";
54 case EXPR_R_LE: return "<=";
55 case EXPR_R_GT: return ">";
56 case EXPR_R_GE: return ">=";
57 default: OVS_NOT_REACHED();
58 }
59}
60
61bool
62expr_relop_from_token(enum lex_type type, enum expr_relop *relop)
63{
64 enum expr_relop r;
65
66 switch ((int) type) {
67 case LEX_T_EQ: r = EXPR_R_EQ; break;
68 case LEX_T_NE: r = EXPR_R_NE; break;
69 case LEX_T_LT: r = EXPR_R_LT; break;
70 case LEX_T_LE: r = EXPR_R_LE; break;
71 case LEX_T_GT: r = EXPR_R_GT; break;
72 case LEX_T_GE: r = EXPR_R_GE; break;
73 default: return false;
74 }
75
76 if (relop) {
77 *relop = r;
78 }
79 return true;
80}
81
82/* Returns the relational operator that 'relop' becomes if you turn the
83 * relation's operands around, e.g. EXPR_R_EQ does not change because "a == b"
84 * and "b == a" are equivalent, but EXPR_R_LE becomes EXPR_R_GE because "a <=
85 * b" is equivalent to "b >= a". */
86static enum expr_relop
87expr_relop_turn(enum expr_relop relop)
88{
89 switch (relop) {
90 case EXPR_R_EQ: return EXPR_R_EQ;
91 case EXPR_R_NE: return EXPR_R_NE;
92 case EXPR_R_LT: return EXPR_R_GT;
93 case EXPR_R_LE: return EXPR_R_GE;
94 case EXPR_R_GT: return EXPR_R_LT;
95 case EXPR_R_GE: return EXPR_R_LE;
96 default: OVS_NOT_REACHED();
97 }
98}
99
100/* Returns the relational operator that is the opposite of 'relop'. */
101static enum expr_relop
102expr_relop_invert(enum expr_relop relop)
103{
104 switch (relop) {
105 case EXPR_R_EQ: return EXPR_R_NE;
106 case EXPR_R_NE: return EXPR_R_EQ;
107 case EXPR_R_LT: return EXPR_R_GE;
108 case EXPR_R_LE: return EXPR_R_GT;
109 case EXPR_R_GT: return EXPR_R_LE;
110 case EXPR_R_GE: return EXPR_R_LT;
111 default: OVS_NOT_REACHED();
112 }
113}
114\f
115/* Constructing and manipulating expressions. */
116
117/* Creates and returns a logical AND or OR expression (according to 'type',
118 * which must be EXPR_T_AND or EXPR_T_OR) that initially has no
119 * sub-expressions. (To satisfy the invariants for expressions, the caller
120 * must add at least two sub-expressions whose types are different from
121 * 'type'.) */
122struct expr *
123expr_create_andor(enum expr_type type)
124{
125 struct expr *e = xmalloc(sizeof *e);
126 e->type = type;
127 list_init(&e->andor);
128 return e;
129}
130
131/* Returns a logical AND or OR expression (according to 'type', which must be
132 * EXPR_T_AND or EXPR_T_OR) whose sub-expressions are 'a' and 'b', with some
133 * flexibility:
134 *
135 * - If 'a' or 'b' is NULL, just returns the other one (which means that if
136 * that other one is not of the given 'type', then the returned
137 * expression is not either).
138 *
139 * - If 'a' or 'b', or both, have type 'type', then they are combined into
140 * a single node that satisfies the invariants for expressions. */
141struct expr *
142expr_combine(enum expr_type type, struct expr *a, struct expr *b)
143{
144 if (!a) {
145 return b;
146 } else if (!b) {
147 return a;
148 } else if (a->type == type) {
149 if (b->type == type) {
150 list_splice(&a->andor, b->andor.next, &b->andor);
151 free(b);
152 } else {
153 list_push_back(&a->andor, &b->node);
154 }
155 return a;
156 } else if (b->type == type) {
157 list_push_front(&b->andor, &a->node);
158 return b;
159 } else {
160 struct expr *e = expr_create_andor(type);
161 list_push_back(&e->andor, &a->node);
162 list_push_back(&e->andor, &b->node);
163 return e;
164 }
165}
166
167static void
168expr_insert_andor(struct expr *andor, struct expr *before, struct expr *new)
169{
170 if (new->type == andor->type) {
171 if (andor->type == EXPR_T_AND) {
172 /* Conjunction junction, what's your function? */
173 }
174 list_splice(&before->node, new->andor.next, &new->andor);
175 free(new);
176 } else {
177 list_insert(&before->node, &new->node);
178 }
179}
180
181/* Returns an EXPR_T_BOOLEAN expression with value 'b'. */
182struct expr *
183expr_create_boolean(bool b)
184{
185 struct expr *e = xmalloc(sizeof *e);
186 e->type = EXPR_T_BOOLEAN;
187 e->boolean = b;
188 return e;
189}
190
191static void
192expr_not(struct expr *expr)
193{
194 struct expr *sub;
195
196 switch (expr->type) {
197 case EXPR_T_CMP:
198 expr->cmp.relop = expr_relop_invert(expr->cmp.relop);
199 break;
200
201 case EXPR_T_AND:
202 case EXPR_T_OR:
203 LIST_FOR_EACH (sub, node, &expr->andor) {
204 expr_not(sub);
205 }
206 expr->type = expr->type == EXPR_T_AND ? EXPR_T_OR : EXPR_T_AND;
207 break;
208
209 case EXPR_T_BOOLEAN:
210 expr->boolean = !expr->boolean;
211 break;
212 default:
213 OVS_NOT_REACHED();
214 }
215}
216
217static struct expr *
218expr_fix_andor(struct expr *expr, bool short_circuit)
219{
220 struct expr *sub, *next;
221
222 LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
223 if (sub->type == EXPR_T_BOOLEAN) {
224 if (sub->boolean == short_circuit) {
225 expr_destroy(expr);
226 return expr_create_boolean(short_circuit);
227 } else {
228 list_remove(&sub->node);
229 expr_destroy(sub);
230 }
231 }
232 }
233
234 if (list_is_short(&expr->andor)) {
235 if (list_is_empty(&expr->andor)) {
236 free(expr);
237 return expr_create_boolean(!short_circuit);
238 } else {
239 sub = expr_from_node(list_front(&expr->andor));
240 free(expr);
241 return sub;
242 }
243 } else {
244 return expr;
245 }
246}
247
fd477c6e
BP
248/* Returns 'expr' modified so that top-level oddities are fixed up:
249 *
250 * - Eliminates any EXPR_T_BOOLEAN operands at the top level.
251 *
252 * - Replaces one-operand EXPR_T_AND or EXPR_T_OR by its subexpression. */
e0840f11
BP
253static struct expr *
254expr_fix(struct expr *expr)
255{
256 switch (expr->type) {
257 case EXPR_T_CMP:
258 return expr;
259
260 case EXPR_T_AND:
261 return expr_fix_andor(expr, false);
262
263 case EXPR_T_OR:
264 return expr_fix_andor(expr, true);
265
266 case EXPR_T_BOOLEAN:
267 return expr;
268
269 default:
270 OVS_NOT_REACHED();
271 }
272}
273\f
274/* Formatting. */
275
276static void
277find_bitwise_range(const union mf_subvalue *sv, int width,
278 int *startp, int *n_bitsp)
279{
280 unsigned int start = bitwise_scan(sv, sizeof *sv, true, 0, width);
281 if (start < width) {
282 unsigned int end = bitwise_scan(sv, sizeof *sv, false, start, width);
283 if (end >= width
284 || bitwise_scan(sv, sizeof *sv, true, end, width) >= width) {
285 *startp = start;
286 *n_bitsp = end - start;
287 return;
288 }
289 }
290 *startp = *n_bitsp = 0;
291}
292
e0840f11
BP
293static void
294expr_format_cmp(const struct expr *e, struct ds *s)
295{
296 /* The common case is numerical comparisons.
297 * Handle string comparisons as a special case. */
298 if (!e->cmp.symbol->width) {
299 ds_put_format(s, "%s %s ", e->cmp.symbol->name,
300 expr_relop_to_string(e->cmp.relop));
3b626771 301 json_string_escape(e->cmp.string, s);
e0840f11
BP
302 return;
303 }
304
305 int ofs, n;
306 find_bitwise_range(&e->cmp.mask, e->cmp.symbol->width, &ofs, &n);
307 if (n == 1 && (e->cmp.relop == EXPR_R_EQ || e->cmp.relop == EXPR_R_NE)) {
308 bool positive;
309
310 positive = bitwise_get_bit(&e->cmp.value, sizeof e->cmp.value, ofs);
311 positive ^= e->cmp.relop == EXPR_R_NE;
312 if (!positive) {
313 ds_put_char(s, '!');
314 }
315 ds_put_cstr(s, e->cmp.symbol->name);
316 if (e->cmp.symbol->width > 1) {
317 ds_put_format(s, "[%d]", ofs);
318 }
319 return;
320 }
321
322 ds_put_cstr(s, e->cmp.symbol->name);
323 if (n > 0 && n < e->cmp.symbol->width) {
324 if (n > 1) {
325 ds_put_format(s, "[%d..%d]", ofs, ofs + n - 1);
326 } else {
327 ds_put_format(s, "[%d]", ofs);
328 }
329 }
330
331 ds_put_format(s, " %s ", expr_relop_to_string(e->cmp.relop));
332
333 if (n) {
334 union mf_subvalue value;
335
336 memset(&value, 0, sizeof value);
337 bitwise_copy(&e->cmp.value, sizeof e->cmp.value, ofs,
338 &value, sizeof value, 0,
339 n);
340 mf_format_subvalue(&value, s);
341 } else {
342 mf_format_subvalue(&e->cmp.value, s);
343 ds_put_char(s, '/');
344 mf_format_subvalue(&e->cmp.mask, s);
345 }
346}
347
348static void
349expr_format_andor(const struct expr *e, const char *op, struct ds *s)
350{
351 struct expr *sub;
352 int i = 0;
353
354 LIST_FOR_EACH (sub, node, &e->andor) {
355 if (i++) {
356 ds_put_format(s, " %s ", op);
357 }
358
359 if (sub->type == EXPR_T_AND || sub->type == EXPR_T_OR) {
360 ds_put_char(s, '(');
361 expr_format(sub, s);
362 ds_put_char(s, ')');
363 } else {
364 expr_format(sub, s);
365 }
366 }
367}
368
369/* Appends a string form of 'e' to 's'. The string form is acceptable for
370 * parsing back into an equivalent expression. */
371void
372expr_format(const struct expr *e, struct ds *s)
373{
374 switch (e->type) {
375 case EXPR_T_CMP:
376 expr_format_cmp(e, s);
377 break;
378
379 case EXPR_T_AND:
380 expr_format_andor(e, "&&", s);
381 break;
382
383 case EXPR_T_OR:
384 expr_format_andor(e, "||", s);
385 break;
386
387 case EXPR_T_BOOLEAN:
388 ds_put_char(s, e->boolean ? '1' : '0');
389 break;
390 }
391}
392
393/* Prints a string form of 'e' on stdout, followed by a new-line. */
394void
395expr_print(const struct expr *e)
396{
397 struct ds output;
398
399 ds_init(&output);
400 expr_format(e, &output);
401 puts(ds_cstr(&output));
402 ds_destroy(&output);
403}
404\f
405/* Parsing. */
406
407/* Type of a "union expr_constant" or "struct expr_constant_set". */
408enum expr_constant_type {
409 EXPR_C_INTEGER,
410 EXPR_C_STRING
411};
412
413/* A string or integer constant (one must know which from context). */
414union expr_constant {
415 /* Integer constant.
416 *
417 * The width of a constant isn't always clear, e.g. if you write "1",
418 * there's no way to tell whether you mean for that to be a 1-bit constant
419 * or a 128-bit constant or somewhere in between. */
420 struct {
421 union mf_subvalue value;
422 union mf_subvalue mask; /* Only initialized if 'masked'. */
423 bool masked;
424
425 enum lex_format format; /* From the constant's lex_token. */
426 };
427
428 /* Null-terminated string constant. */
429 char *string;
430};
431
432/* A collection of "union expr_constant"s of the same type. */
433struct expr_constant_set {
434 union expr_constant *values; /* Constants. */
435 size_t n_values; /* Number of constants. */
436 enum expr_constant_type type; /* Type of the constants. */
437 bool in_curlies; /* Whether the constants were in {}. */
438};
439
440/* A reference to a symbol or a subfield of a symbol.
441 *
442 * For string fields, ofs and n_bits are 0. */
443struct expr_field {
444 const struct expr_symbol *symbol; /* The symbol. */
445 int ofs; /* Starting bit offset. */
446 int n_bits; /* Number of bits. */
447};
448
449/* Context maintained during expr_parse(). */
450struct expr_context {
451 struct lexer *lexer; /* Lexer for pulling more tokens. */
452 const struct shash *symtab; /* Symbol table. */
453 char *error; /* Error, if any, otherwise NULL. */
454 bool not; /* True inside odd number of NOT operators. */
455};
456
457struct expr *expr_parse__(struct expr_context *);
458static void expr_not(struct expr *);
459static void expr_constant_set_destroy(struct expr_constant_set *);
460static bool parse_field(struct expr_context *, struct expr_field *);
461
462static bool
463expr_error_handle_common(struct expr_context *ctx)
464{
465 if (ctx->error) {
466 /* Already have an error, suppress this one since the cascade seems
467 * unlikely to be useful. */
468 return true;
469 } else if (ctx->lexer->token.type == LEX_T_ERROR) {
470 /* The lexer signaled an error. Nothing at the expression level
471 * accepts an error token, so we'll inevitably end up here with some
472 * meaningless parse error. Report the lexical error instead. */
473 ctx->error = xstrdup(ctx->lexer->token.s);
474 return true;
475 } else {
476 return false;
477 }
478}
479
480static void OVS_PRINTF_FORMAT(2, 3)
481expr_error(struct expr_context *ctx, const char *message, ...)
482{
483 if (expr_error_handle_common(ctx)) {
484 return;
485 }
486
487 va_list args;
488 va_start(args, message);
489 ctx->error = xvasprintf(message, args);
490 va_end(args);
491}
492
493static void OVS_PRINTF_FORMAT(2, 3)
494expr_syntax_error(struct expr_context *ctx, const char *message, ...)
495{
496 if (expr_error_handle_common(ctx)) {
497 return;
498 }
499
500 struct ds s;
501
502 ds_init(&s);
503 ds_put_cstr(&s, "Syntax error ");
504 if (ctx->lexer->token.type == LEX_T_END) {
505 ds_put_cstr(&s, "at end of input ");
506 } else if (ctx->lexer->start) {
507 ds_put_format(&s, "at `%.*s' ",
508 (int) (ctx->lexer->input - ctx->lexer->start),
509 ctx->lexer->start);
510 }
511
512 va_list args;
513 va_start(args, message);
514 ds_put_format_valist(&s, message, args);
515 va_end(args);
516
517 ctx->error = ds_steal_cstr(&s);
518}
519
520static struct expr *
521make_cmp__(const struct expr_field *f, enum expr_relop r,
522 const union expr_constant *c)
523{
524 struct expr *e = xzalloc(sizeof *e);
525 e->type = EXPR_T_CMP;
526 e->cmp.symbol = f->symbol;
527 e->cmp.relop = r;
528 if (f->symbol->width) {
529 bitwise_copy(&c->value, sizeof c->value, 0,
530 &e->cmp.value, sizeof e->cmp.value, f->ofs,
531 f->n_bits);
532 if (c->masked) {
533 bitwise_copy(&c->mask, sizeof c->mask, 0,
534 &e->cmp.mask, sizeof e->cmp.mask, f->ofs,
535 f->n_bits);
536 } else {
537 bitwise_one(&e->cmp.mask, sizeof e->cmp.mask, f->ofs,
538 f->n_bits);
539 }
540 } else {
541 e->cmp.string = xstrdup(c->string);
542 }
543 return e;
544}
545
546/* Returns the minimum reasonable width for integer constant 'c'. */
547static int
548expr_constant_width(const union expr_constant *c)
549{
550 if (c->masked) {
551 return mf_subvalue_width(&c->mask);
552 }
553
554 switch (c->format) {
555 case LEX_F_DECIMAL:
556 case LEX_F_HEXADECIMAL:
557 return mf_subvalue_width(&c->value);
558
559 case LEX_F_IPV4:
560 return 32;
561
562 case LEX_F_IPV6:
563 return 128;
564
565 case LEX_F_ETHERNET:
566 return 48;
567
568 default:
569 OVS_NOT_REACHED();
570 }
571}
572
3b7cb7e1
BP
573static bool
574type_check(struct expr_context *ctx, const struct expr_field *f,
575 struct expr_constant_set *cs)
576{
577 if (cs->type != (f->symbol->width ? EXPR_C_INTEGER : EXPR_C_STRING)) {
578 expr_error(ctx, "%s field %s is not compatible with %s constant.",
579 f->symbol->width ? "Integer" : "String",
580 f->symbol->name,
581 cs->type == EXPR_C_INTEGER ? "integer" : "string");
582 return false;
583 }
584
585 if (f->symbol->width) {
586 for (size_t i = 0; i < cs->n_values; i++) {
587 int w = expr_constant_width(&cs->values[i]);
588 if (w > f->symbol->width) {
589 expr_error(ctx, "%d-bit constant is not compatible with "
590 "%d-bit field %s.",
591 w, f->symbol->width, f->symbol->name);
592 return false;
593 }
594 }
595 }
596
597 return true;
598}
599
e0840f11
BP
600static struct expr *
601make_cmp(struct expr_context *ctx,
602 const struct expr_field *f, enum expr_relop r,
603 struct expr_constant_set *cs)
604{
605 struct expr *e = NULL;
606
3b7cb7e1 607 if (!type_check(ctx, f, cs)) {
e0840f11
BP
608 goto exit;
609 }
610
611 if (r != EXPR_R_EQ && r != EXPR_R_NE) {
612 if (cs->in_curlies) {
613 expr_error(ctx, "Only == and != operators may be used "
614 "with value sets.");
615 goto exit;
616 }
617 if (f->symbol->level == EXPR_L_NOMINAL ||
618 f->symbol->level == EXPR_L_BOOLEAN) {
619 expr_error(ctx, "Only == and != operators may be used "
620 "with %s field %s.",
621 expr_level_to_string(f->symbol->level),
622 f->symbol->name);
623 goto exit;
624 }
625 if (cs->values[0].masked) {
626 expr_error(ctx, "Only == and != operators may be used with "
627 "masked constants. Consider using subfields instead "
628 "(e.g. eth.src[0..15] > 0x1111 in place of "
629 "eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff).");
630 goto exit;
631 }
632 }
633
634 if (f->symbol->level == EXPR_L_NOMINAL) {
635 if (f->symbol->expansion) {
fd477c6e 636 ovs_assert(f->symbol->width > 0);
e0840f11
BP
637 for (size_t i = 0; i < cs->n_values; i++) {
638 const union mf_subvalue *value = &cs->values[i].value;
639 bool positive = (value->integer & htonll(1)) != 0;
640 positive ^= r == EXPR_R_NE;
641 positive ^= ctx->not;
642 if (!positive) {
643 const char *name = f->symbol->name;
644 expr_error(ctx, "Nominal predicate %s may only be tested "
645 "positively, e.g. `%s' or `%s == 1' but not "
646 "`!%s' or `%s == 0'.",
647 name, name, name, name, name);
648 goto exit;
649 }
650 }
651 } else if (r != (ctx->not ? EXPR_R_NE : EXPR_R_EQ)) {
652 expr_error(ctx, "Nominal field %s may only be tested for "
653 "equality (taking enclosing `!' operators into "
654 "account).", f->symbol->name);
655 goto exit;
656 }
657 }
658
e0840f11
BP
659 e = make_cmp__(f, r, &cs->values[0]);
660 for (size_t i = 1; i < cs->n_values; i++) {
661 e = expr_combine(r == EXPR_R_EQ ? EXPR_T_OR : EXPR_T_AND,
662 e, make_cmp__(f, r, &cs->values[i]));
663 }
664exit:
665 expr_constant_set_destroy(cs);
666 return e;
667}
668
669static bool
670expr_get_int(struct expr_context *ctx, int *value)
671{
558ec83d
BP
672 bool ok = lexer_get_int(ctx->lexer, value);
673 if (!ok) {
e0840f11 674 expr_syntax_error(ctx, "expecting small integer.");
e0840f11 675 }
558ec83d 676 return ok;
e0840f11
BP
677}
678
679static bool
680parse_field(struct expr_context *ctx, struct expr_field *f)
681{
682 const struct expr_symbol *symbol;
683
684 if (ctx->lexer->token.type != LEX_T_ID) {
685 expr_syntax_error(ctx, "expecting field name.");
686 return false;
687 }
688
689 symbol = shash_find_data(ctx->symtab, ctx->lexer->token.s);
690 if (!symbol) {
691 expr_syntax_error(ctx, "expecting field name.");
692 return false;
693 }
694 lexer_get(ctx->lexer);
695
696 f->symbol = symbol;
697 if (lexer_match(ctx->lexer, LEX_T_LSQUARE)) {
698 int low, high;
699
700 if (!symbol->width) {
701 expr_error(ctx, "Cannot select subfield of string field %s.",
702 symbol->name);
703 return false;
704 }
705
706 if (!expr_get_int(ctx, &low)) {
707 return false;
708 }
709 if (lexer_match(ctx->lexer, LEX_T_ELLIPSIS)) {
710 if (!expr_get_int(ctx, &high)) {
711 return false;
712 }
713 } else {
714 high = low;
715 }
716
717 if (!lexer_match(ctx->lexer, LEX_T_RSQUARE)) {
718 expr_syntax_error(ctx, "expecting `]'.");
719 return false;
720 }
721
722 if (low > high) {
723 expr_error(ctx, "Invalid bit range %d to %d.", low, high);
724 return false;
725 } else if (high >= symbol->width) {
726 expr_error(ctx, "Cannot select bits %d to %d of %d-bit field %s.",
727 low, high, symbol->width, symbol->name);
728 return false;
729 } else if (symbol->level == EXPR_L_NOMINAL
730 && (low != 0 || high != symbol->width - 1)) {
731 expr_error(ctx, "Cannot select subfield of nominal field %s.",
732 symbol->name);
733 return false;
734 }
735
736 f->ofs = low;
737 f->n_bits = high - low + 1;
738 } else {
739 f->ofs = 0;
740 f->n_bits = symbol->width;
741 }
742
743 return true;
744}
745
746static bool
747parse_relop(struct expr_context *ctx, enum expr_relop *relop)
748{
749 if (expr_relop_from_token(ctx->lexer->token.type, relop)) {
750 lexer_get(ctx->lexer);
751 return true;
752 } else {
753 expr_syntax_error(ctx, "expecting relational operator.");
754 return false;
755 }
756}
757
758static bool
759assign_constant_set_type(struct expr_context *ctx,
760 struct expr_constant_set *cs,
761 enum expr_constant_type type)
762{
763 if (!cs->n_values || cs->type == type) {
764 cs->type = type;
765 return true;
766 } else {
767 expr_syntax_error(ctx, "expecting %s.",
768 cs->type == EXPR_C_INTEGER ? "integer" : "string");
769 return false;
770 }
771}
772
773static bool
774parse_constant(struct expr_context *ctx, struct expr_constant_set *cs,
775 size_t *allocated_values)
776{
777 if (cs->n_values >= *allocated_values) {
778 cs->values = x2nrealloc(cs->values, allocated_values,
779 sizeof *cs->values);
780 }
781
782 if (ctx->lexer->token.type == LEX_T_STRING) {
783 if (!assign_constant_set_type(ctx, cs, EXPR_C_STRING)) {
784 return false;
785 }
786 cs->values[cs->n_values++].string = xstrdup(ctx->lexer->token.s);
787 lexer_get(ctx->lexer);
788 return true;
789 } else if (ctx->lexer->token.type == LEX_T_INTEGER ||
790 ctx->lexer->token.type == LEX_T_MASKED_INTEGER) {
791 if (!assign_constant_set_type(ctx, cs, EXPR_C_INTEGER)) {
792 return false;
793 }
794
795 union expr_constant *c = &cs->values[cs->n_values++];
796 c->value = ctx->lexer->token.value;
797 c->format = ctx->lexer->token.format;
798 c->masked = ctx->lexer->token.type == LEX_T_MASKED_INTEGER;
799 if (c->masked) {
800 c->mask = ctx->lexer->token.mask;
801 }
802 lexer_get(ctx->lexer);
803 return true;
804 } else {
805 expr_syntax_error(ctx, "expecting constant.");
806 return false;
807 }
808}
809
810/* Parses a single or {}-enclosed set of integer or string constants into 'cs',
811 * which the caller need not have initialized. Returns true on success, in
812 * which case the caller owns 'cs', false on failure, in which case 'cs' is
813 * indeterminate. */
814static bool
815parse_constant_set(struct expr_context *ctx, struct expr_constant_set *cs)
816{
817 size_t allocated_values = 0;
818 bool ok;
819
820 memset(cs, 0, sizeof *cs);
821 if (lexer_match(ctx->lexer, LEX_T_LCURLY)) {
822 ok = true;
823 cs->in_curlies = true;
824 do {
825 if (!parse_constant(ctx, cs, &allocated_values)) {
826 ok = false;
827 break;
828 }
829 lexer_match(ctx->lexer, LEX_T_COMMA);
830 } while (!lexer_match(ctx->lexer, LEX_T_RCURLY));
831 } else {
832 ok = parse_constant(ctx, cs, &allocated_values);
833 }
834 if (!ok) {
835 expr_constant_set_destroy(cs);
836 }
837 return ok;
838}
839
840static void
841expr_constant_set_destroy(struct expr_constant_set *cs)
842{
843 if (cs) {
844 if (cs->type == EXPR_C_STRING) {
845 for (size_t i = 0; i < cs->n_values; i++) {
846 free(cs->values[i].string);
847 }
848 }
849 free(cs->values);
850 }
851}
852
853static struct expr *
854expr_parse_primary(struct expr_context *ctx, bool *atomic)
855{
856 *atomic = false;
857 if (lexer_match(ctx->lexer, LEX_T_LPAREN)) {
858 struct expr *e = expr_parse__(ctx);
859 if (!lexer_match(ctx->lexer, LEX_T_RPAREN)) {
860 expr_destroy(e);
861 expr_syntax_error(ctx, "expecting `)'.");
862 return NULL;
863 }
864 *atomic = true;
865 return e;
866 }
867
868 if (ctx->lexer->token.type == LEX_T_ID) {
869 struct expr_field f;
870 enum expr_relop r;
871 struct expr_constant_set c;
872
873 if (!parse_field(ctx, &f)) {
874 return NULL;
875 }
876
877 if (!expr_relop_from_token(ctx->lexer->token.type, &r)) {
878 if (f.n_bits > 1 && !ctx->not) {
879 expr_error(ctx, "Explicit `!= 0' is required for inequality "
880 "test of multibit field against 0.");
881 return NULL;
882 }
883
884 *atomic = true;
885
886 union expr_constant *cst = xzalloc(sizeof *cst);
887 cst->format = LEX_F_HEXADECIMAL;
888 cst->masked = false;
889
890 c.type = EXPR_C_INTEGER;
891 c.values = cst;
892 c.n_values = 1;
893 c.in_curlies = false;
894 return make_cmp(ctx, &f, EXPR_R_NE, &c);
895 } else if (parse_relop(ctx, &r) && parse_constant_set(ctx, &c)) {
896 return make_cmp(ctx, &f, r, &c);
897 } else {
898 return NULL;
899 }
900 } else {
901 struct expr_constant_set c1;
902 if (!parse_constant_set(ctx, &c1)) {
903 return NULL;
904 }
905
906 if (!expr_relop_from_token(ctx->lexer->token.type, NULL)
907 && c1.n_values == 1
908 && c1.type == EXPR_C_INTEGER
909 && c1.values[0].format == LEX_F_DECIMAL
910 && !c1.values[0].masked
911 && !c1.in_curlies) {
912 uint64_t x = ntohll(c1.values[0].value.integer);
913 if (x <= 1) {
914 *atomic = true;
915 expr_constant_set_destroy(&c1);
916 return expr_create_boolean(x);
917 }
918 }
919
920 enum expr_relop r1;
921 struct expr_field f;
922 if (!parse_relop(ctx, &r1) || !parse_field(ctx, &f)) {
923 expr_constant_set_destroy(&c1);
924 return NULL;
925 }
926
927 if (!expr_relop_from_token(ctx->lexer->token.type, NULL)) {
928 return make_cmp(ctx, &f, expr_relop_turn(r1), &c1);
929 }
930
931 enum expr_relop r2;
932 struct expr_constant_set c2;
933 if (!parse_relop(ctx, &r2) || !parse_constant_set(ctx, &c2)) {
934 expr_constant_set_destroy(&c1);
935 return NULL;
936 } else {
937 /* Reject "1 == field == 2", "1 < field > 2", and so on. */
938 if (!(((r1 == EXPR_R_LT || r1 == EXPR_R_LE) &&
939 (r2 == EXPR_R_LT || r2 == EXPR_R_LE)) ||
940 ((r1 == EXPR_R_GT || r1 == EXPR_R_GE) &&
941 (r2 == EXPR_R_GT || r2 == EXPR_R_GE)))) {
942 expr_error(ctx, "Range expressions must have the form "
943 "`x < field < y' or `x > field > y', with each "
944 "`<' optionally replaced by `<=' or `>' by `>=').");
945 expr_constant_set_destroy(&c1);
946 expr_constant_set_destroy(&c2);
947 return NULL;
948 }
949
950 struct expr *e1 = make_cmp(ctx, &f, expr_relop_turn(r1), &c1);
951 struct expr *e2 = make_cmp(ctx, &f, r2, &c2);
952 if (ctx->error) {
953 expr_destroy(e1);
954 expr_destroy(e2);
955 return NULL;
956 }
957 return expr_combine(EXPR_T_AND, e1, e2);
958 }
959 }
960}
961
962static struct expr *
963expr_parse_not(struct expr_context *ctx)
964{
965 bool atomic;
966
967 if (lexer_match(ctx->lexer, LEX_T_LOG_NOT)) {
968 ctx->not = !ctx->not;
969 struct expr *expr = expr_parse_primary(ctx, &atomic);
970 ctx->not = !ctx->not;
971
972 if (expr) {
973 if (!atomic) {
974 expr_error(ctx, "Missing parentheses around operand of !.");
975 expr_destroy(expr);
976 return NULL;
977 }
978 expr_not(expr);
979 }
980 return expr;
981 } else {
982 return expr_parse_primary(ctx, &atomic);
983 }
984}
985
986struct expr *
987expr_parse__(struct expr_context *ctx)
988{
989 struct expr *e = expr_parse_not(ctx);
990 if (!e) {
991 return NULL;
992 }
993
994 enum lex_type lex_type = ctx->lexer->token.type;
995 if (lex_type == LEX_T_LOG_AND || lex_type == LEX_T_LOG_OR) {
996 enum expr_type expr_type
997 = lex_type == LEX_T_LOG_AND ? EXPR_T_AND : EXPR_T_OR;
998
999 lexer_get(ctx->lexer);
1000 do {
1001 struct expr *e2 = expr_parse_not(ctx);
1002 if (!e2) {
1003 expr_destroy(e);
1004 return NULL;
1005 }
1006 e = expr_combine(expr_type, e, e2);
1007 } while (lexer_match(ctx->lexer, lex_type));
1008 if (ctx->lexer->token.type == LEX_T_LOG_AND
1009 || ctx->lexer->token.type == LEX_T_LOG_OR) {
1010 expr_destroy(e);
1011 expr_error(ctx,
1012 "&& and || must be parenthesized when used together.");
1013 return NULL;
1014 }
1015 }
1016 return e;
1017}
1018
1019/* Parses an expression using the symbols in 'symtab' from 'lexer'. If
1020 * successful, returns the new expression and sets '*errorp' to NULL. On
1021 * failure, returns NULL and sets '*errorp' to an explanatory error message.
1022 * The caller must eventually free the returned expression (with
1023 * expr_destroy()) or error (with free()). */
1024struct expr *
1025expr_parse(struct lexer *lexer, const struct shash *symtab, char **errorp)
1026{
1027 struct expr_context ctx;
1028
1029 ctx.lexer = lexer;
1030 ctx.symtab = symtab;
1031 ctx.error = NULL;
1032 ctx.not = false;
1033
1034 struct expr *e = expr_parse__(&ctx);
1035 *errorp = ctx.error;
1036 ovs_assert((ctx.error != NULL) != (e != NULL));
1037 return e;
1038}
1039
1040/* Like expr_parse(), but the expression is taken from 's'. */
1041struct expr *
1042expr_parse_string(const char *s, const struct shash *symtab, char **errorp)
1043{
1044 struct lexer lexer;
1045 struct expr *expr;
1046
1047 lexer_init(&lexer, s);
1048 lexer_get(&lexer);
1049 expr = expr_parse(&lexer, symtab, errorp);
8b34ccda 1050 if (!*errorp && lexer.token.type != LEX_T_END) {
e0840f11
BP
1051 *errorp = xstrdup("Extra tokens at end of input.");
1052 expr_destroy(expr);
1053 expr = NULL;
1054 }
1055 lexer_destroy(&lexer);
1056
1057 return expr;
1058}
1059\f
1060static struct expr_symbol *
1061add_symbol(struct shash *symtab, const char *name, int width,
1062 const char *prereqs, enum expr_level level,
1063 bool must_crossproduct)
1064{
1065 struct expr_symbol *symbol = xzalloc(sizeof *symbol);
1066 symbol->name = xstrdup(name);
1067 symbol->prereqs = prereqs && prereqs[0] ? xstrdup(prereqs) : NULL;
1068 symbol->width = width;
1069 symbol->level = level;
1070 symbol->must_crossproduct = must_crossproduct;
1071 shash_add_assert(symtab, symbol->name, symbol);
1072 return symbol;
1073}
1074
1075/* Adds field 'id' to symbol table 'symtab' under the given 'name'. Whenever
1076 * 'name' is referenced, expression annotation (see expr_annotate()) will
1077 * ensure that 'prereqs' are also true. If 'must_crossproduct' is true, then
1078 * conversion to flows will never attempt to use the field as a conjunctive
1079 * match dimension (see "Crossproducting" in the large comment on struct
1080 * expr_symbol in expr.h for an example).
1081 *
1082 * A given field 'id' must only be used for a single symbol in a symbol table.
1083 * Use subfields to duplicate or subset a field (you can even make a subfield
1084 * include all the bits of the "parent" field if you like). */
1085struct expr_symbol *
1086expr_symtab_add_field(struct shash *symtab, const char *name,
1087 enum mf_field_id id, const char *prereqs,
1088 bool must_crossproduct)
1089{
1090 const struct mf_field *field = mf_from_id(id);
1091 struct expr_symbol *symbol;
1092
1093 symbol = add_symbol(symtab, name, field->n_bits, prereqs,
1094 (field->maskable == MFM_FULLY
1095 ? EXPR_L_ORDINAL
1096 : EXPR_L_NOMINAL),
1097 must_crossproduct);
1098 symbol->field = field;
1099 return symbol;
1100}
1101
1102static bool
1103parse_field_from_string(const char *s, const struct shash *symtab,
1104 struct expr_field *field, char **errorp)
1105{
1106 struct lexer lexer;
1107 lexer_init(&lexer, s);
1108 lexer_get(&lexer);
1109
1110 struct expr_context ctx;
1111 ctx.lexer = &lexer;
1112 ctx.symtab = symtab;
1113 ctx.error = NULL;
1114 ctx.not = false;
1115
1116 bool ok = parse_field(&ctx, field);
1117 if (!ok) {
1118 *errorp = ctx.error;
1119 } else if (lexer.token.type != LEX_T_END) {
1120 *errorp = xstrdup("Extra tokens at end of input.");
1121 ok = false;
1122 }
1123
1124 lexer_destroy(&lexer);
1125
1126 return ok;
1127}
1128
1129/* Adds 'name' as a subfield of a larger field in 'symtab'. Whenever
1130 * 'name' is referenced, expression annotation (see expr_annotate()) will
1131 * ensure that 'prereqs' are also true.
1132 *
1133 * 'subfield' must describe the subfield as a string, e.g. "vlan.tci[0..11]"
1134 * for the low 12 bits of a larger field named "vlan.tci". */
1135struct expr_symbol *
1136expr_symtab_add_subfield(struct shash *symtab, const char *name,
1137 const char *prereqs, const char *subfield)
1138{
1139 struct expr_symbol *symbol;
1140 struct expr_field f;
1141 char *error;
1142
1143 if (!parse_field_from_string(subfield, symtab, &f, &error)) {
1144 VLOG_WARN("%s: error parsing %s subfield (%s)", subfield, name, error);
1145 free(error);
1146 return NULL;
1147 }
1148
1149 enum expr_level level = f.symbol->level;
1150 if (level != EXPR_L_ORDINAL) {
1151 VLOG_WARN("can't define %s as subfield of %s field %s",
1152 name, expr_level_to_string(level), f.symbol->name);
1153 }
1154
1155 symbol = add_symbol(symtab, name, f.n_bits, prereqs, level, false);
1156 symbol->expansion = xstrdup(subfield);
1157 return symbol;
1158}
1159
1160/* Adds a string-valued symbol named 'name' to 'symtab' with the specified
1161 * 'prereqs'. */
1162struct expr_symbol *
1163expr_symtab_add_string(struct shash *symtab, const char *name,
f386a8a7 1164 enum mf_field_id id, const char *prereqs)
e0840f11 1165{
f386a8a7
BP
1166 const struct mf_field *field = mf_from_id(id);
1167 struct expr_symbol *symbol;
1168
1169 symbol = add_symbol(symtab, name, 0, prereqs, EXPR_L_NOMINAL, false);
1170 symbol->field = field;
1171 return symbol;
e0840f11
BP
1172}
1173
1174static enum expr_level
1175expr_get_level(const struct expr *expr)
1176{
1177 const struct expr *sub;
1178 enum expr_level level = EXPR_L_ORDINAL;
1179
1180 switch (expr->type) {
1181 case EXPR_T_CMP:
1182 return (expr->cmp.symbol->level == EXPR_L_NOMINAL
1183 ? EXPR_L_NOMINAL
1184 : EXPR_L_BOOLEAN);
1185
1186 case EXPR_T_AND:
1187 case EXPR_T_OR:
1188 LIST_FOR_EACH (sub, node, &expr->andor) {
1189 enum expr_level sub_level = expr_get_level(sub);
1190 level = MIN(level, sub_level);
1191 }
1192 return level;
1193
1194 case EXPR_T_BOOLEAN:
1195 return EXPR_L_BOOLEAN;
1196
1197 default:
1198 OVS_NOT_REACHED();
1199 }
1200}
1201
1202static enum expr_level
1203expr_parse_level(const char *s, const struct shash *symtab, char **errorp)
1204{
1205 struct expr *expr = expr_parse_string(s, symtab, errorp);
1206 enum expr_level level = expr ? expr_get_level(expr) : EXPR_L_NOMINAL;
1207 expr_destroy(expr);
1208 return level;
1209}
1210
1211/* Adds a predicate symbol, whose value is the given Boolean 'expression',
44283953 1212 * named 'name' to 'symtab'. For example, "ip4 && ip4.proto == 6" might be an
e0840f11
BP
1213 * appropriate predicate named "tcp4". */
1214struct expr_symbol *
1215expr_symtab_add_predicate(struct shash *symtab, const char *name,
1216 const char *expansion)
1217{
1218 struct expr_symbol *symbol;
1219 enum expr_level level;
1220 char *error;
1221
1222 level = expr_parse_level(expansion, symtab, &error);
1223 if (error) {
1224 VLOG_WARN("%s: error parsing %s expansion (%s)",
1225 expansion, name, error);
1226 free(error);
1227 return NULL;
1228 }
1229
1230 symbol = add_symbol(symtab, name, 1, NULL, level, false);
1231 symbol->expansion = xstrdup(expansion);
1232 return symbol;
1233}
1234
1235/* Destroys 'symtab' and all of its symbols. */
1236void
1237expr_symtab_destroy(struct shash *symtab)
1238{
1239 struct shash_node *node, *next;
1240
1241 SHASH_FOR_EACH_SAFE (node, next, symtab) {
1242 struct expr_symbol *symbol = node->data;
1243
1244 shash_delete(symtab, node);
1245 free(symbol->name);
1246 free(symbol->prereqs);
1247 free(symbol->expansion);
1248 free(symbol);
1249 }
1250}
1251\f
1252/* Cloning. */
1253
1254static struct expr *
1255expr_clone_cmp(struct expr *expr)
1256{
1257 struct expr *new = xmemdup(expr, sizeof *expr);
1258 if (!new->cmp.symbol->width) {
1259 new->cmp.string = xstrdup(new->cmp.string);
1260 }
1261 return new;
1262}
1263
1264static struct expr *
1265expr_clone_andor(struct expr *expr)
1266{
1267 struct expr *new = expr_create_andor(expr->type);
1268 struct expr *sub;
1269
1270 LIST_FOR_EACH (sub, node, &expr->andor) {
1271 struct expr *new_sub = expr_clone(sub);
1272 list_push_back(&new->andor, &new_sub->node);
1273 }
1274 return new;
1275}
1276
1277/* Returns a clone of 'expr'. This is a "deep copy": neither the returned
1278 * expression nor any of its substructure will be shared with 'expr'. */
1279struct expr *
1280expr_clone(struct expr *expr)
1281{
1282 switch (expr->type) {
1283 case EXPR_T_CMP:
1284 return expr_clone_cmp(expr);
1285
1286 case EXPR_T_AND:
1287 case EXPR_T_OR:
1288 return expr_clone_andor(expr);
1289
1290 case EXPR_T_BOOLEAN:
1291 return expr_create_boolean(expr->boolean);
1292 }
1293 OVS_NOT_REACHED();
1294}
1295\f
1296/* Destroys 'expr' and all of the sub-expressions it references. */
1297void
1298expr_destroy(struct expr *expr)
1299{
1300 if (!expr) {
1301 return;
1302 }
1303
1304 struct expr *sub, *next;
1305
1306 switch (expr->type) {
1307 case EXPR_T_CMP:
1308 if (!expr->cmp.symbol->width) {
1309 free(expr->cmp.string);
1310 }
1311 break;
1312
1313 case EXPR_T_AND:
1314 case EXPR_T_OR:
1315 LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
1316 list_remove(&sub->node);
1317 expr_destroy(sub);
1318 }
1319 break;
1320
1321 case EXPR_T_BOOLEAN:
1322 break;
1323 }
1324 free(expr);
1325}
1326\f
1327/* Annotation. */
1328
1329/* An element in a linked list of symbols.
1330 *
1331 * Used to detect when a symbol is being expanded recursively, to allow
1332 * flagging an error. */
1333struct annotation_nesting {
1334 struct ovs_list node;
1335 const struct expr_symbol *symbol;
1336};
1337
1338struct expr *expr_annotate__(struct expr *, const struct shash *symtab,
1339 struct ovs_list *nesting, char **errorp);
1340
1341static struct expr *
1342parse_and_annotate(const char *s, const struct shash *symtab,
1343 struct ovs_list *nesting, char **errorp)
1344{
1345 char *error;
1346 struct expr *expr;
1347
1348 expr = expr_parse_string(s, symtab, &error);
1349 if (expr) {
1350 expr = expr_annotate__(expr, symtab, nesting, &error);
1351 }
3b7cb7e1
BP
1352 if (expr) {
1353 *errorp = NULL;
1354 } else {
e0840f11
BP
1355 *errorp = xasprintf("Error parsing expression `%s' encountered as "
1356 "prerequisite or predicate of initial expression: "
1357 "%s", s, error);
1358 free(error);
1359 }
1360 return expr;
1361}
1362
1363static struct expr *
1364expr_annotate_cmp(struct expr *expr, const struct shash *symtab,
1365 struct ovs_list *nesting, char **errorp)
1366{
1367 const struct expr_symbol *symbol = expr->cmp.symbol;
1368 const struct annotation_nesting *iter;
1369 LIST_FOR_EACH (iter, node, nesting) {
1370 if (iter->symbol == symbol) {
1371 *errorp = xasprintf("Recursive expansion of symbol `%s'.",
1372 symbol->name);
1373 expr_destroy(expr);
1374 return NULL;
1375 }
1376 }
1377
1378 struct annotation_nesting an;
1379 an.symbol = symbol;
1380 list_push_back(nesting, &an.node);
1381
1382 struct expr *prereqs = NULL;
1383 if (symbol->prereqs) {
1384 prereqs = parse_and_annotate(symbol->prereqs, symtab, nesting, errorp);
1385 if (!prereqs) {
1386 goto error;
1387 }
1388 }
1389
1390 if (symbol->expansion) {
1391 if (symbol->level == EXPR_L_ORDINAL) {
1392 struct expr_field field;
1393
1394 if (!parse_field_from_string(symbol->expansion, symtab,
1395 &field, errorp)) {
1396 goto error;
1397 }
1398
1399 expr->cmp.symbol = field.symbol;
1400 mf_subvalue_shift(&expr->cmp.value, field.ofs);
1401 mf_subvalue_shift(&expr->cmp.mask, field.ofs);
1402 } else {
1403 struct expr *expansion;
1404
1405 expansion = parse_and_annotate(symbol->expansion, symtab,
1406 nesting, errorp);
1407 if (!expansion) {
1408 goto error;
1409 }
1410
1411 bool positive = (expr->cmp.value.integer & htonll(1)) != 0;
1412 positive ^= expr->cmp.relop == EXPR_R_NE;
1413 if (!positive) {
1414 expr_not(expansion);
1415 }
1416
1417 expr_destroy(expr);
1418 expr = expansion;
1419 }
1420 }
1421
1422 list_remove(&an.node);
1423 return prereqs ? expr_combine(EXPR_T_AND, expr, prereqs) : expr;
1424
1425error:
1426 expr_destroy(expr);
1427 expr_destroy(prereqs);
1428 list_remove(&an.node);
1429 return NULL;
1430}
1431
1432struct expr *
1433expr_annotate__(struct expr *expr, const struct shash *symtab,
1434 struct ovs_list *nesting, char **errorp)
1435{
1436 switch (expr->type) {
1437 case EXPR_T_CMP:
1438 return expr_annotate_cmp(expr, symtab, nesting, errorp);
1439
1440 case EXPR_T_AND:
1441 case EXPR_T_OR: {
1442 struct expr *sub, *next;
1443
1444 LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
1445 list_remove(&sub->node);
1446 struct expr *new_sub = expr_annotate__(sub, symtab,
1447 nesting, errorp);
1448 if (!new_sub) {
1449 expr_destroy(expr);
1450 return NULL;
1451 }
1452 expr_insert_andor(expr, next, new_sub);
1453 }
1454 *errorp = NULL;
1455 return expr;
1456 }
1457
1458 case EXPR_T_BOOLEAN:
1459 *errorp = NULL;
1460 return expr;
1461
1462 default:
1463 OVS_NOT_REACHED();
1464 }
1465}
1466
1467/* "Annotates" 'expr', which does the following:
1468 *
1469 * - Applies prerequisites, by locating each comparison operator whose
1470 * field has a prerequisite and adding a logical AND against those
1471 * prerequisites.
1472 *
1473 * - Expands references to subfield symbols, by replacing them by
1474 * references to their underlying field symbols (suitably shifted).
1475 *
1476 * - Expands references to predicate symbols, by replacing them by the
1477 * expressions that they expand to.
1478 *
1385d7b7
JP
1479 * In each case, annotation occurs recursively as necessary.
1480 *
1481 * On failure, returns NULL and sets '*errorp' to an explanatory error
1482 * message, which the caller must free. */
e0840f11
BP
1483struct expr *
1484expr_annotate(struct expr *expr, const struct shash *symtab, char **errorp)
1485{
1486 struct ovs_list nesting = OVS_LIST_INITIALIZER(&nesting);
1487 return expr_annotate__(expr, symtab, &nesting, errorp);
1488}
1489\f
1490static struct expr *
1491expr_simplify_ne(struct expr *expr)
1492{
1493 struct expr *new = NULL;
1494 const union mf_subvalue *value = &expr->cmp.value;
1495 const union mf_subvalue *mask = &expr->cmp.mask;
1496 int w = expr->cmp.symbol->width;
1497 int i;
1498
1499 for (i = 0; (i = bitwise_scan(mask, sizeof *mask, true, i, w)) < w; i++) {
1500 struct expr *e;
1501
1502 e = xzalloc(sizeof *e);
1503 e->type = EXPR_T_CMP;
1504 e->cmp.symbol = expr->cmp.symbol;
1505 e->cmp.relop = EXPR_R_EQ;
1506 bitwise_put_bit(&e->cmp.value, sizeof e->cmp.value, i,
1507 !bitwise_get_bit(value, sizeof *value, i));
1508 bitwise_put1(&e->cmp.mask, sizeof e->cmp.mask, i);
1509
1510 new = expr_combine(EXPR_T_OR, new, e);
1511 }
1512 ovs_assert(new);
1513
1514 expr_destroy(expr);
1515
1516 return new;
1517}
1518
1519static struct expr *
1520expr_simplify_relational(struct expr *expr)
1521{
1522 const union mf_subvalue *value = &expr->cmp.value;
1523 int start, n_bits, end;
1524
1525 find_bitwise_range(&expr->cmp.mask, expr->cmp.symbol->width,
1526 &start, &n_bits);
1527 ovs_assert(n_bits > 0);
1528 end = start + n_bits;
1529
1530 struct expr *new;
1531 if (expr->cmp.relop == EXPR_R_LE || expr->cmp.relop == EXPR_R_GE) {
1532 new = xmemdup(expr, sizeof *expr);
1533 new->cmp.relop = EXPR_R_EQ;
1534 } else {
1535 new = NULL;
1536 }
1537
1538 bool b = expr->cmp.relop == EXPR_R_LT || expr->cmp.relop == EXPR_R_LE;
1539 for (int z = bitwise_scan(value, sizeof *value, b, start, end);
1540 z < end;
1541 z = bitwise_scan(value, sizeof *value, b, z + 1, end)) {
1542 struct expr *e;
1543
1544 e = xmemdup(expr, sizeof *expr);
1545 e->cmp.relop = EXPR_R_EQ;
1546 bitwise_toggle_bit(&e->cmp.value, sizeof e->cmp.value, z);
1547 bitwise_zero(&e->cmp.value, sizeof e->cmp.value, start, z - start);
1548 bitwise_zero(&e->cmp.mask, sizeof e->cmp.mask, start, z - start);
1549 new = expr_combine(EXPR_T_OR, new, e);
1550 }
1551 expr_destroy(expr);
1552 return new ? new : expr_create_boolean(false);
1553}
1554
1555/* Takes ownership of 'expr' and returns an equivalent expression whose
1556 * EXPR_T_CMP nodes use only tests for equality (EXPR_R_EQ). */
1557struct expr *
1558expr_simplify(struct expr *expr)
1559{
1560 struct expr *sub, *next;
1561
1562 switch (expr->type) {
1563 case EXPR_T_CMP:
1564 return (expr->cmp.relop == EXPR_R_EQ || !expr->cmp.symbol->width ? expr
1565 : expr->cmp.relop == EXPR_R_NE ? expr_simplify_ne(expr)
1566 : expr_simplify_relational(expr));
1567
1568 case EXPR_T_AND:
1569 case EXPR_T_OR:
1570 LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
1571 list_remove(&sub->node);
1572 expr_insert_andor(expr, next, expr_simplify(sub));
1573 }
1574 return expr_fix(expr);
1575
1576 case EXPR_T_BOOLEAN:
1577 return expr;
1578 }
1579 OVS_NOT_REACHED();
1580}
1581\f
1582static const struct expr_symbol *
1583expr_is_cmp(const struct expr *expr)
1584{
1585 switch (expr->type) {
1586 case EXPR_T_CMP:
1587 return expr->cmp.symbol;
1588
1589 case EXPR_T_AND:
1590 case EXPR_T_OR: {
1591 const struct expr_symbol *prev = NULL;
1592 struct expr *sub;
1593
1594 LIST_FOR_EACH (sub, node, &expr->andor) {
1595 const struct expr_symbol *symbol = expr_is_cmp(sub);
1596 if (!symbol || (prev && symbol != prev)) {
1597 return NULL;
1598 }
1599 prev = symbol;
1600 }
1601 return prev;
1602 }
1603
1604 case EXPR_T_BOOLEAN:
1605 return NULL;
1606
1607 default:
1608 OVS_NOT_REACHED();
1609 }
1610}
1611
1612struct expr_sort {
1613 struct expr *expr;
1614 const struct expr_symbol *relop;
1615 enum expr_type type;
1616};
1617
1618static int
1619compare_expr_sort(const void *a_, const void *b_)
1620{
1621 const struct expr_sort *a = a_;
1622 const struct expr_sort *b = b_;
1623
1624 if (a->type != b->type) {
1625 return a->type < b->type ? -1 : 1;
1626 } else if (a->relop) {
1627 int cmp = strcmp(a->relop->name, b->relop->name);
1628 if (cmp) {
1629 return cmp;
1630 }
1631
1632 enum expr_type a_type = a->expr->type;
1633 enum expr_type b_type = a->expr->type;
1634 return a_type < b_type ? -1 : a_type > b_type;
1635 } else if (a->type == EXPR_T_AND || a->type == EXPR_T_OR) {
1636 size_t a_len = list_size(&a->expr->andor);
1637 size_t b_len = list_size(&b->expr->andor);
1638 return a_len < b_len ? -1 : a_len > b_len;
1639 } else {
1640 return 0;
1641 }
1642}
1643
1644static struct expr *crush_cmps(struct expr *, const struct expr_symbol *);
1645
9d4aecca
BP
1646static bool
1647disjunction_matches_string(const struct expr *or, const char *s)
1648{
1649 const struct expr *sub;
1650
1651 LIST_FOR_EACH (sub, node, &or->andor) {
1652 if (!strcmp(sub->cmp.string, s)) {
1653 return true;
1654 }
1655 }
1656
1657 return false;
1658}
1659
1660/* Implementation of crush_cmps() for expr->type == EXPR_T_AND and a
1661 * string-typed 'symbol'. */
e0840f11 1662static struct expr *
9d4aecca
BP
1663crush_and_string(struct expr *expr, const struct expr_symbol *symbol)
1664{
1665 ovs_assert(!list_is_short(&expr->andor));
1666
1667 struct expr *singleton = NULL;
1668
1669 /* First crush each subexpression into either a single EXPR_T_CMP or an
1670 * EXPR_T_OR with EXPR_T_CMP subexpressions. */
1671 struct expr *sub, *next = NULL;
1672 LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
1673 list_remove(&sub->node);
1674 struct expr *new = crush_cmps(sub, symbol);
1675 switch (new->type) {
1676 case EXPR_T_CMP:
1677 if (!singleton) {
1678 list_insert(&next->node, &new->node);
1679 singleton = new;
1680 } else {
1681 bool match = !strcmp(new->cmp.string, singleton->cmp.string);
1682 expr_destroy(new);
1683 if (!match) {
1684 expr_destroy(expr);
1685 return expr_create_boolean(false);
1686 }
1687 }
1688 break;
1689 case EXPR_T_AND:
1690 OVS_NOT_REACHED();
1691 case EXPR_T_OR:
1692 list_insert(&next->node, &new->node);
1693 break;
1694 case EXPR_T_BOOLEAN:
1695 if (!new->boolean) {
1696 expr_destroy(expr);
1697 return new;
1698 }
1699 free(new);
1700 break;
1701 }
1702 }
1703
1704 /* If we have a singleton, then the result is either the singleton itself
1705 * (if the ORs allow the singleton) or false. */
1706 if (singleton) {
1707 LIST_FOR_EACH (sub, node, &expr->andor) {
1708 if (sub->type == EXPR_T_OR
1709 && !disjunction_matches_string(sub, singleton->cmp.string)) {
1710 expr_destroy(expr);
1711 return expr_create_boolean(false);
1712 }
1713 }
1714 list_remove(&singleton->node);
1715 expr_destroy(expr);
1716 return singleton;
1717 }
1718
1719 /* Otherwise the result is the intersection of all of the ORs. */
1720 struct sset result = SSET_INITIALIZER(&result);
1721 LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
1722 struct sset strings = SSET_INITIALIZER(&strings);
1723 const struct expr *s;
1724 LIST_FOR_EACH (s, node, &sub->andor) {
1725 sset_add(&strings, s->cmp.string);
1726 }
1727 if (sset_is_empty(&result)) {
1728 sset_swap(&result, &strings);
1729 } else {
1730 sset_intersect(&result, &strings);
1731 }
1732 sset_destroy(&strings);
1733
1734 if (sset_is_empty(&result)) {
1735 expr_destroy(expr);
1736 sset_destroy(&result);
1737 return expr_create_boolean(false);
1738 }
1739 }
1740
1741 expr_destroy(expr);
1742 expr = expr_create_andor(EXPR_T_OR);
1743
1744 const char *string;
1745 SSET_FOR_EACH (string, &result) {
1746 sub = xmalloc(sizeof *sub);
1747 sub->type = EXPR_T_CMP;
1748 sub->cmp.symbol = symbol;
1749 sub->cmp.string = xstrdup(string);
1750 list_push_back(&expr->andor, &sub->node);
1751 }
1cad4a75 1752 sset_destroy(&result);
9d4aecca
BP
1753 return expr_fix(expr);
1754}
1755
1756/* Implementation of crush_cmps() for expr->type == EXPR_T_AND and a
1757 * numeric-typed 'symbol'. */
1758static struct expr *
1759crush_and_numeric(struct expr *expr, const struct expr_symbol *symbol)
e0840f11
BP
1760{
1761 ovs_assert(!list_is_short(&expr->andor));
1762
1763 union mf_subvalue value, mask;
1764 memset(&value, 0, sizeof value);
1765 memset(&mask, 0, sizeof mask);
1766
1767 struct expr *sub, *next = NULL;
1768 LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
1769 list_remove(&sub->node);
1770 struct expr *new = crush_cmps(sub, symbol);
1771 switch (new->type) {
1772 case EXPR_T_CMP:
1773 if (!mf_subvalue_intersect(&value, &mask,
1774 &new->cmp.value, &new->cmp.mask,
1775 &value, &mask)) {
1776 expr_destroy(new);
1777 expr_destroy(expr);
1778 return expr_create_boolean(false);
1779 }
1780 expr_destroy(new);
1781 break;
1782 case EXPR_T_AND:
1783 OVS_NOT_REACHED();
1784 case EXPR_T_OR:
1785 list_insert(&next->node, &new->node);
1786 break;
1787 case EXPR_T_BOOLEAN:
1788 if (!new->boolean) {
1789 expr_destroy(expr);
1790 return new;
1791 }
45c4387b 1792 expr_destroy(new);
e0840f11
BP
1793 break;
1794 }
1795 }
1796 if (list_is_empty(&expr->andor)) {
1797 if (is_all_zeros(&mask, sizeof mask)) {
1798 expr_destroy(expr);
1799 return expr_create_boolean(true);
1800 } else {
1801 struct expr *cmp;
1802 cmp = xmalloc(sizeof *cmp);
1803 cmp->type = EXPR_T_CMP;
1804 cmp->cmp.symbol = symbol;
1805 cmp->cmp.relop = EXPR_R_EQ;
1806 cmp->cmp.value = value;
1807 cmp->cmp.mask = mask;
1808 expr_destroy(expr);
1809 return cmp;
1810 }
1811 } else if (list_is_short(&expr->andor)) {
1812 /* Transform "a && (b || c || d)" into "ab || ac || ad" where "ab" is
1813 * computed as "a && b", etc. */
1814 struct expr *disjuncts = expr_from_node(list_pop_front(&expr->andor));
1815 struct expr *or;
1816
1817 or = xmalloc(sizeof *or);
1818 or->type = EXPR_T_OR;
1819 list_init(&or->andor);
1820
1821 ovs_assert(disjuncts->type == EXPR_T_OR);
1822 LIST_FOR_EACH_SAFE (sub, next, node, &disjuncts->andor) {
1823 ovs_assert(sub->type == EXPR_T_CMP);
1824 list_remove(&sub->node);
1825 if (mf_subvalue_intersect(&value, &mask,
1826 &sub->cmp.value, &sub->cmp.mask,
1827 &sub->cmp.value, &sub->cmp.mask)) {
1828 list_push_back(&or->andor, &sub->node);
1829 } else {
45c4387b 1830 expr_destroy(sub);
e0840f11
BP
1831 }
1832 }
1833 free(disjuncts);
1834 free(expr);
1835 if (list_is_empty(&or->andor)) {
1836 free(or);
1837 return expr_create_boolean(false);
1838 } else if (list_is_short(&or->andor)) {
1839 struct expr *cmp = expr_from_node(list_pop_front(&or->andor));
1840 free(or);
1841 return cmp;
1842 } else {
1843 return or;
1844 }
1845 } else {
1846 /* Transform "x && (a0 || a1) && (b0 || b1) && ..." into
1847 * "(xa0b0 || xa0b1 || xa1b0 || xa1b1) && ...". */
1848 struct expr *as = expr_from_node(list_pop_front(&expr->andor));
1849 struct expr *bs = expr_from_node(list_pop_front(&expr->andor));
1850 struct expr *new = NULL;
1851 struct expr *or;
1852
1853 or = xmalloc(sizeof *or);
1854 or->type = EXPR_T_OR;
1855 list_init(&or->andor);
1856
1857 struct expr *a;
1858 LIST_FOR_EACH (a, node, &as->andor) {
1859 union mf_subvalue a_value, a_mask;
1860
1861 ovs_assert(a->type == EXPR_T_CMP);
1862 if (!mf_subvalue_intersect(&value, &mask,
1863 &a->cmp.value, &a->cmp.mask,
1864 &a_value, &a_mask)) {
1865 continue;
1866 }
1867
1868 struct expr *b;
1869 LIST_FOR_EACH (b, node, &bs->andor) {
1870 ovs_assert(b->type == EXPR_T_CMP);
1871 if (!new) {
1872 new = xmalloc(sizeof *new);
1873 new->type = EXPR_T_CMP;
1874 new->cmp.symbol = symbol;
1875 new->cmp.relop = EXPR_R_EQ;
1876 }
1877 if (mf_subvalue_intersect(&a_value, &a_mask,
1878 &b->cmp.value, &b->cmp.mask,
1879 &new->cmp.value, &new->cmp.mask)) {
1880 list_push_back(&or->andor, &new->node);
1881 new = NULL;
1882 }
1883 }
1884 }
1885 expr_destroy(as);
1886 expr_destroy(bs);
1887 free(new);
1888
1889 if (list_is_empty(&or->andor)) {
1890 expr_destroy(expr);
1891 free(or);
1892 return expr_create_boolean(false);
1893 } else if (list_is_short(&or->andor)) {
1894 struct expr *cmp = expr_from_node(list_pop_front(&or->andor));
1895 free(or);
1896 if (list_is_empty(&expr->andor)) {
1897 expr_destroy(expr);
1898 return crush_cmps(cmp, symbol);
1899 } else {
1900 return crush_cmps(expr_combine(EXPR_T_AND, cmp, expr), symbol);
1901 }
1902 } else if (!list_is_empty(&expr->andor)) {
1903 struct expr *e = expr_combine(EXPR_T_AND, or, expr);
1904 ovs_assert(!list_is_short(&e->andor));
1905 return crush_cmps(e, symbol);
1906 } else {
1907 expr_destroy(expr);
1908 return crush_cmps(or, symbol);
1909 }
1910 }
1911}
1912
1913static int
9d4aecca
BP
1914compare_cmps_3way(const struct expr *a, const struct expr *b)
1915{
1916 ovs_assert(a->cmp.symbol == b->cmp.symbol);
1917 if (!a->cmp.symbol->width) {
1918 return strcmp(a->cmp.string, b->cmp.string);
1919 } else {
1920 int d = memcmp(&a->cmp.value, &b->cmp.value, sizeof a->cmp.value);
1921 if (!d) {
1922 d = memcmp(&a->cmp.mask, &b->cmp.mask, sizeof a->cmp.mask);
1923 }
1924 return d;
1925 }
1926}
1927
1928static int
1929compare_cmps_cb(const void *a_, const void *b_)
e0840f11
BP
1930{
1931 const struct expr *const *ap = a_;
1932 const struct expr *const *bp = b_;
1933 const struct expr *a = *ap;
1934 const struct expr *b = *bp;
9d4aecca 1935 return compare_cmps_3way(a, b);
e0840f11
BP
1936}
1937
fd477c6e 1938/* Implementation of crush_cmps() for expr->type == EXPR_T_OR. */
e0840f11
BP
1939static struct expr *
1940crush_or(struct expr *expr, const struct expr_symbol *symbol)
1941{
1942 struct expr *sub, *next = NULL;
1943
1944 /* First, crush all the subexpressions. That might eliminate the
fd477c6e
BP
1945 * OR-expression entirely; if so, return the result. Otherwise, 'expr'
1946 * is now a disjunction of cmps over the same symbol. */
e0840f11
BP
1947 LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
1948 list_remove(&sub->node);
1949 expr_insert_andor(expr, next, crush_cmps(sub, symbol));
1950 }
1951 expr = expr_fix(expr);
1952 if (expr->type != EXPR_T_OR) {
1953 return expr;
1954 }
1955
fd477c6e 1956 /* Sort subexpressions by value and mask, to bring together duplicates. */
e0840f11
BP
1957 size_t n = list_size(&expr->andor);
1958 struct expr **subs = xmalloc(n * sizeof *subs);
1959
1960 size_t i = 0;
1961 LIST_FOR_EACH (sub, node, &expr->andor) {
1962 subs[i++] = sub;
1963 }
1964 ovs_assert(i == n);
1965
9d4aecca 1966 qsort(subs, n, sizeof *subs, compare_cmps_cb);
e0840f11 1967
9d4aecca 1968 /* Eliminate duplicates. */
e0840f11
BP
1969 list_init(&expr->andor);
1970 list_push_back(&expr->andor, &subs[0]->node);
1971 for (i = 1; i < n; i++) {
1972 struct expr *a = expr_from_node(list_back(&expr->andor));
1973 struct expr *b = subs[i];
9d4aecca 1974 if (compare_cmps_3way(a, b)) {
e0840f11
BP
1975 list_push_back(&expr->andor, &b->node);
1976 } else {
45c4387b 1977 expr_destroy(b);
e0840f11
BP
1978 }
1979 }
1980 free(subs);
1981 return expr_fix(expr);
1982}
1983
fd477c6e
BP
1984/* Takes ownership of 'expr', which must be a cmp in the sense determined by
1985 * 'expr_is_cmp(expr)', where 'symbol' is the symbol returned by that function.
1986 * Returns an equivalent expression owned by the caller that is a single
1987 * EXPR_T_CMP or a disjunction of them or a EXPR_T_BOOLEAN. */
e0840f11
BP
1988static struct expr *
1989crush_cmps(struct expr *expr, const struct expr_symbol *symbol)
1990{
1991 switch (expr->type) {
1992 case EXPR_T_OR:
1993 return crush_or(expr, symbol);
1994
1995 case EXPR_T_AND:
9d4aecca
BP
1996 return (symbol->width
1997 ? crush_and_numeric(expr, symbol)
1998 : crush_and_string(expr, symbol));
e0840f11
BP
1999
2000 case EXPR_T_CMP:
2001 return expr;
2002
2003 case EXPR_T_BOOLEAN:
2004 return expr;
2005
2006 default:
2007 OVS_NOT_REACHED();
2008 }
2009}
2010
2011static struct expr *
2012expr_sort(struct expr *expr)
2013{
2014 size_t n = list_size(&expr->andor);
2015 struct expr_sort *subs = xmalloc(n * sizeof *subs);
2016 struct expr *sub;
2017 size_t i;
2018
2019 i = 0;
2020 LIST_FOR_EACH (sub, node, &expr->andor) {
2021 subs[i].expr = sub;
2022 subs[i].relop = expr_is_cmp(sub);
2023 subs[i].type = subs[i].relop ? EXPR_T_CMP : sub->type;
2024 i++;
2025 }
2026 ovs_assert(i == n);
2027
2028 qsort(subs, n, sizeof *subs, compare_expr_sort);
2029
2030 list_init(&expr->andor);
2031 for (int i = 0; i < n; ) {
2032 if (subs[i].relop) {
2033 int j;
2034 for (j = i + 1; j < n; j++) {
2035 if (subs[i].relop != subs[j].relop) {
2036 break;
2037 }
2038 }
2039
2040 struct expr *crushed;
2041 if (j == i + 1) {
2042 crushed = crush_cmps(subs[i].expr, subs[i].relop);
2043 } else {
2044 struct expr *combined = subs[i].expr;
2045 for (int k = i + 1; k < j; k++) {
2046 combined = expr_combine(EXPR_T_AND, combined,
2047 subs[k].expr);
2048 }
2049 ovs_assert(!list_is_short(&combined->andor));
2050 crushed = crush_cmps(combined, subs[i].relop);
2051 }
2052 if (crushed->type == EXPR_T_BOOLEAN) {
2053 if (!crushed->boolean) {
2054 for (int k = j; k < n; k++) {
2055 expr_destroy(subs[k].expr);
2056 }
2057 expr_destroy(expr);
2058 expr = crushed;
2059 break;
2060 } else {
2061 free(crushed);
2062 }
2063 } else {
2064 expr = expr_combine(EXPR_T_AND, expr, crushed);
2065 }
2066 i = j;
2067 } else {
2068 expr = expr_combine(EXPR_T_AND, expr, subs[i++].expr);
2069 }
2070 }
2071 free(subs);
2072
2073 return expr;
2074}
2075
2076static struct expr *expr_normalize_or(struct expr *expr);
2077
2078/* Returns 'expr', which is an AND, reduced to OR(AND(clause)) where
2079 * a clause is a cmp or a disjunction of cmps on a single field. */
2080static struct expr *
2081expr_normalize_and(struct expr *expr)
2082{
2083 ovs_assert(expr->type == EXPR_T_AND);
2084
2085 expr = expr_sort(expr);
2086 if (expr->type != EXPR_T_AND) {
2087 ovs_assert(expr->type == EXPR_T_BOOLEAN);
2088 return expr;
2089 }
2090
2091 struct expr *a, *b;
2092 LIST_FOR_EACH_SAFE (a, b, node, &expr->andor) {
2093 if (&b->node == &expr->andor
9d4aecca
BP
2094 || a->type != EXPR_T_CMP || b->type != EXPR_T_CMP
2095 || a->cmp.symbol != b->cmp.symbol) {
e0840f11 2096 continue;
9d4aecca
BP
2097 } else if (a->cmp.symbol->width
2098 ? mf_subvalue_intersect(&a->cmp.value, &a->cmp.mask,
2099 &b->cmp.value, &b->cmp.mask,
2100 &b->cmp.value, &b->cmp.mask)
2101 : !strcmp(a->cmp.string, b->cmp.string)) {
e0840f11
BP
2102 list_remove(&a->node);
2103 expr_destroy(a);
2104 } else {
2105 expr_destroy(expr);
2106 return expr_create_boolean(false);
2107 }
2108 }
2109 if (list_is_short(&expr->andor)) {
2110 struct expr *sub = expr_from_node(list_front(&expr->andor));
2111 free(expr);
2112 return sub;
2113 }
2114
2115 struct expr *sub;
2116 LIST_FOR_EACH (sub, node, &expr->andor) {
2117 if (sub->type == EXPR_T_CMP) {
2118 continue;
2119 }
2120
2121 ovs_assert(sub->type == EXPR_T_OR);
2122 const struct expr_symbol *symbol = expr_is_cmp(sub);
2123 if (!symbol || symbol->must_crossproduct) {
2124 struct expr *or = expr_create_andor(EXPR_T_OR);
2125 struct expr *k;
2126
2127 LIST_FOR_EACH (k, node, &sub->andor) {
2128 struct expr *and = expr_create_andor(EXPR_T_AND);
2129 struct expr *m;
2130
2131 LIST_FOR_EACH (m, node, &expr->andor) {
2132 struct expr *term = m == sub ? k : m;
2133 if (term->type == EXPR_T_AND) {
2134 struct expr *p;
2135
2136 LIST_FOR_EACH (p, node, &term->andor) {
2137 struct expr *new = expr_clone(p);
2138 list_push_back(&and->andor, &new->node);
2139 }
2140 } else {
2141 struct expr *new = expr_clone(term);
2142 list_push_back(&and->andor, &new->node);
2143 }
2144 }
2145 list_push_back(&or->andor, &and->node);
2146 }
2147 expr_destroy(expr);
2148 return expr_normalize_or(or);
2149 }
2150 }
2151 return expr;
2152}
2153
2154static struct expr *
2155expr_normalize_or(struct expr *expr)
2156{
2157 struct expr *sub, *next;
2158
2159 LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
2160 if (sub->type == EXPR_T_AND) {
2161 list_remove(&sub->node);
2162
2163 struct expr *new = expr_normalize_and(sub);
2164 if (new->type == EXPR_T_BOOLEAN) {
2165 if (new->boolean) {
2166 expr_destroy(expr);
2167 return new;
2168 }
2169 free(new);
2170 } else {
2171 expr_insert_andor(expr, next, new);
2172 }
2173 } else {
2174 ovs_assert(sub->type == EXPR_T_CMP);
2175 }
2176 }
2177 if (list_is_empty(&expr->andor)) {
2178 free(expr);
2179 return expr_create_boolean(false);
2180 }
2181 if (list_is_short(&expr->andor)) {
2182 struct expr *sub = expr_from_node(list_pop_front(&expr->andor));
2183 free(expr);
2184 return sub;
2185 }
2186
2187 return expr;
2188}
2189
2190/* Takes ownership of 'expr', which is either a constant "true" or "false" or
2191 * an expression in terms of only relationals, AND, and OR. Returns either a
2192 * constant "true" or "false" or 'expr' reduced to OR(AND(clause)) where a
2193 * clause is a cmp or a disjunction of cmps on a single field. This form is
2194 * significant because it is a form that can be directly converted to OpenFlow
2195 * flows with the Open vSwitch "conjunctive match" extension.
2196 *
2197 * 'expr' must already have been simplified, with expr_simplify(). */
2198struct expr *
2199expr_normalize(struct expr *expr)
2200{
2201 switch (expr->type) {
2202 case EXPR_T_CMP:
2203 return expr;
2204
2205 case EXPR_T_AND:
2206 return expr_normalize_and(expr);
2207
2208 case EXPR_T_OR:
2209 return expr_normalize_or(expr);
2210
2211 case EXPR_T_BOOLEAN:
2212 return expr;
2213 }
2214 OVS_NOT_REACHED();
2215}
2216\f
2217/* Creates, initializes, and returns a new 'struct expr_match'. If 'm' is
2218 * nonnull then it is copied into the new expr_match, otherwise the new
2219 * expr_match's 'match' member is initialized to a catch-all match for the
2220 * caller to refine in-place.
2221 *
2222 * If 'conj_id' is nonzero, adds one conjunction based on 'conj_id', 'clause',
2223 * and 'n_clauses' to the returned 'struct expr_match', otherwise the
2224 * expr_match will not have any conjunctions.
2225 *
2226 * The caller should use expr_match_add() to add the expr_match to a hash table
2227 * after it is finalized. */
2228static struct expr_match *
2229expr_match_new(const struct match *m, uint8_t clause, uint8_t n_clauses,
2230 uint32_t conj_id)
2231{
2232 struct expr_match *match = xmalloc(sizeof *match);
2233 if (m) {
2234 match->match = *m;
2235 } else {
2236 match_init_catchall(&match->match);
2237 }
2238 if (conj_id) {
2239 match->conjunctions = xmalloc(sizeof *match->conjunctions);
2240 match->conjunctions[0].id = conj_id;
2241 match->conjunctions[0].clause = clause;
2242 match->conjunctions[0].n_clauses = n_clauses;
2243 match->n = 1;
2244 match->allocated = 1;
2245 } else {
2246 match->conjunctions = NULL;
2247 match->n = 0;
2248 match->allocated = 0;
2249 }
2250 return match;
2251}
2252
2253/* Adds 'match' to hash table 'matches', which becomes the new owner of
2254 * 'match'.
2255 *
2256 * This might actually destroy 'match' because it gets merged together with
2257 * some existing conjunction.*/
2258static void
2259expr_match_add(struct hmap *matches, struct expr_match *match)
2260{
2261 uint32_t hash = match_hash(&match->match, 0);
2262 struct expr_match *m;
2263
2264 HMAP_FOR_EACH_WITH_HASH (m, hmap_node, hash, matches) {
2265 if (match_equal(&m->match, &match->match)) {
2266 if (!m->n || !match->n) {
2267 free(m->conjunctions);
2268 m->conjunctions = NULL;
2269 m->n = 0;
2270 m->allocated = 0;
2271 } else {
2272 ovs_assert(match->n == 1);
2273 if (m->n >= m->allocated) {
2274 m->conjunctions = x2nrealloc(m->conjunctions,
2275 &m->allocated,
2276 sizeof *m->conjunctions);
2277 }
2278 m->conjunctions[m->n++] = match->conjunctions[0];
2279 }
2280 free(match->conjunctions);
2281 free(match);
2282 return;
2283 }
2284 }
2285
2286 hmap_insert(matches, &match->hmap_node, hash);
2287}
2288
f386a8a7 2289static bool
f1c16a85
BP
2290constrain_match(const struct expr *expr,
2291 bool (*lookup_port)(const void *aux, const char *port_name,
2292 unsigned int *portp),
2293 const void *aux, struct match *m)
e0840f11
BP
2294{
2295 ovs_assert(expr->type == EXPR_T_CMP);
f386a8a7
BP
2296 if (expr->cmp.symbol->width) {
2297 mf_mask_subfield(expr->cmp.symbol->field, &expr->cmp.value,
2298 &expr->cmp.mask, m);
2299 } else {
f1c16a85
BP
2300 unsigned int port;
2301 if (!lookup_port(aux, expr->cmp.string, &port)) {
f386a8a7
BP
2302 return false;
2303 }
2304
2305 struct mf_subfield sf;
2306 sf.field = expr->cmp.symbol->field;
2307 sf.ofs = 0;
2308 sf.n_bits = expr->cmp.symbol->field->n_bits;
2309
2310 union mf_subvalue x;
2311 memset(&x, 0, sizeof x);
f1c16a85 2312 x.integer = htonll(port);
f386a8a7
BP
2313
2314 mf_write_subfield(&sf, &x, m);
2315 }
2316 return true;
e0840f11
BP
2317}
2318
f386a8a7 2319static bool
f1c16a85
BP
2320add_disjunction(const struct expr *or,
2321 bool (*lookup_port)(const void *aux, const char *port_name,
2322 unsigned int *portp),
2323 const void *aux,
f386a8a7
BP
2324 struct match *m, uint8_t clause, uint8_t n_clauses,
2325 uint32_t conj_id, struct hmap *matches)
e0840f11
BP
2326{
2327 struct expr *sub;
f386a8a7 2328 int n = 0;
e0840f11
BP
2329
2330 ovs_assert(or->type == EXPR_T_OR);
2331 LIST_FOR_EACH (sub, node, &or->andor) {
2332 struct expr_match *match = expr_match_new(m, clause, n_clauses,
2333 conj_id);
f1c16a85 2334 if (constrain_match(sub, lookup_port, aux, &match->match)) {
f386a8a7
BP
2335 expr_match_add(matches, match);
2336 n++;
2337 } else {
2338 free(match->conjunctions);
2339 free(match);
2340 }
e0840f11 2341 }
f386a8a7
BP
2342
2343 /* If n == 1, then this didn't really need to be a disjunction. Oh well,
2344 * that shouldn't happen much. */
2345 return n > 0;
e0840f11
BP
2346}
2347
2348static void
f1c16a85
BP
2349add_conjunction(const struct expr *and,
2350 bool (*lookup_port)(const void *aux, const char *port_name,
2351 unsigned int *portp),
2352 const void *aux, uint32_t *n_conjsp, struct hmap *matches)
e0840f11
BP
2353{
2354 struct match match;
2355 int n_clauses = 0;
2356 struct expr *sub;
2357
2358 match_init_catchall(&match);
2359
2360 ovs_assert(and->type == EXPR_T_AND);
2361 LIST_FOR_EACH (sub, node, &and->andor) {
2362 switch (sub->type) {
2363 case EXPR_T_CMP:
f1c16a85 2364 if (!constrain_match(sub, lookup_port, aux, &match)) {
f386a8a7
BP
2365 return;
2366 }
e0840f11
BP
2367 break;
2368 case EXPR_T_OR:
2369 n_clauses++;
2370 break;
2371 case EXPR_T_AND:
2372 case EXPR_T_BOOLEAN:
2373 OVS_NOT_REACHED();
2374 }
2375 }
2376
2377 if (!n_clauses) {
2378 expr_match_add(matches, expr_match_new(&match, 0, 0, 0));
2379 } else if (n_clauses == 1) {
2380 LIST_FOR_EACH (sub, node, &and->andor) {
2381 if (sub->type == EXPR_T_OR) {
f1c16a85
BP
2382 add_disjunction(sub, lookup_port, aux, &match, 0, 0, 0,
2383 matches);
e0840f11
BP
2384 }
2385 }
2386 } else {
2387 int clause = 0;
2388 (*n_conjsp)++;
2389 LIST_FOR_EACH (sub, node, &and->andor) {
2390 if (sub->type == EXPR_T_OR) {
f1c16a85 2391 if (!add_disjunction(sub, lookup_port, aux, &match, clause++,
f386a8a7
BP
2392 n_clauses, *n_conjsp, matches)) {
2393 /* This clause can't ever match, so we might as well skip
2394 * adding the other clauses--the overall disjunctive flow
2395 * can't ever match. Ideally we would also back out all of
2396 * the clauses we already added, but that seems like a lot
2397 * of trouble for a case that might never occur in
2398 * practice. */
2399 return;
2400 }
e0840f11
BP
2401 }
2402 }
40e07b2a
BP
2403
2404 /* Add the flow that matches on conj_id. */
2405 match_set_conj_id(&match, *n_conjsp);
2406 expr_match_add(matches, expr_match_new(&match, 0, 0, 0));
e0840f11
BP
2407 }
2408}
2409
2410static void
f1c16a85
BP
2411add_cmp_flow(const struct expr *cmp,
2412 bool (*lookup_port)(const void *aux, const char *port_name,
2413 unsigned int *portp),
2414 const void *aux, struct hmap *matches)
e0840f11
BP
2415{
2416 struct expr_match *m = expr_match_new(NULL, 0, 0, 0);
f1c16a85 2417 if (constrain_match(cmp, lookup_port, aux, &m->match)) {
f386a8a7
BP
2418 expr_match_add(matches, m);
2419 } else {
2420 free(m);
2421 }
e0840f11
BP
2422}
2423
2424/* Converts 'expr', which must be in the form returned by expr_normalize(), to
2425 * a collection of Open vSwitch flows in 'matches', which this function
f386a8a7
BP
2426 * initializes to an hmap of "struct expr_match" structures. Returns the
2427 * number of conjunctive match IDs consumed by 'matches', which uses
2428 * conjunctive match IDs beginning with 0; the caller must offset or remap them
2429 * into the desired range as necessary.
2430 *
40e07b2a
BP
2431 * The matches inserted into 'matches' will be of three distinct kinds:
2432 *
2433 * - Ordinary flows. The caller should add these OpenFlow flows with
2434 * its desired actions.
2435 *
2436 * - Conjunctive flows, distinguished by 'n > 0' in the expr_match
2437 * structure. The caller should add these OpenFlow flows with the
2438 * conjunction(id, k/n) actions as specified in the 'conjunctions' array,
2439 * remapping the ids.
2440 *
2441 * - conj_id flows, distinguished by matching on the "conj_id" field. The
2442 * caller should remap the conj_id and add the OpenFlow flow with its
2443 * desired actions.
2444 *
f1c16a85
BP
2445 * 'lookup_port' must be a function to map from a port name to a port number.
2446 * When successful, 'lookup_port' stores the port number into '*portp' and
2447 * returns true; when there is no port by the given name, it returns false.
2448 * 'aux' is passed to 'lookup_port' as auxiliary data. Any comparisons against
2449 * string fields in 'expr' are translated into integers through this function.
2450 * A comparison against a string that is not in 'ports' acts like a Boolean
2451 * "false"; that is, it will always fail to match. For a simple expression,
2452 * this means that the overall expression always fails to match, but an
2453 * expression with a disjunction on the string field might still match on other
2454 * port names.
f386a8a7
BP
2455 *
2456 * (This treatment of string fields might be too simplistic in general, but it
2457 * seems reasonable for now when string fields are used only for ports.) */
e0840f11 2458uint32_t
f1c16a85
BP
2459expr_to_matches(const struct expr *expr,
2460 bool (*lookup_port)(const void *aux, const char *port_name,
2461 unsigned int *portp),
2462 const void *aux, struct hmap *matches)
e0840f11
BP
2463{
2464 uint32_t n_conjs = 0;
2465
2466 hmap_init(matches);
2467 switch (expr->type) {
2468 case EXPR_T_CMP:
f1c16a85 2469 add_cmp_flow(expr, lookup_port, aux, matches);
e0840f11
BP
2470 break;
2471
2472 case EXPR_T_AND:
f1c16a85 2473 add_conjunction(expr, lookup_port, aux, &n_conjs, matches);
e0840f11
BP
2474 break;
2475
2476 case EXPR_T_OR:
2477 if (expr_is_cmp(expr)) {
2478 struct expr *sub;
2479
2480 LIST_FOR_EACH (sub, node, &expr->andor) {
f1c16a85 2481 add_cmp_flow(sub, lookup_port, aux, matches);
e0840f11
BP
2482 }
2483 } else {
2484 struct expr *sub;
2485
2486 LIST_FOR_EACH (sub, node, &expr->andor) {
2487 if (sub->type == EXPR_T_AND) {
f1c16a85 2488 add_conjunction(sub, lookup_port, aux, &n_conjs, matches);
e0840f11 2489 } else {
f1c16a85 2490 add_cmp_flow(sub, lookup_port, aux, matches);
e0840f11
BP
2491 }
2492 }
2493 }
2494 break;
2495
2496 case EXPR_T_BOOLEAN:
2497 if (expr->boolean) {
2498 struct expr_match *m = expr_match_new(NULL, 0, 0, 0);
2499 expr_match_add(matches, m);
2500 } else {
2501 /* No match. */
2502 }
2503 break;
2504 }
2505 return n_conjs;
2506}
f386a8a7
BP
2507
2508/* Destroys all of the 'struct expr_match'es in 'matches', as well as the
2509 * 'matches' hmap itself. */
2510void
2511expr_matches_destroy(struct hmap *matches)
2512{
2513 struct expr_match *m, *n;
2514
2515 HMAP_FOR_EACH_SAFE (m, n, hmap_node, matches) {
2516 hmap_remove(matches, &m->hmap_node);
2517 free(m->conjunctions);
2518 free(m);
2519 }
2520 hmap_destroy(matches);
2521}
2522
2523/* Prints a representation of the 'struct expr_match'es in 'matches' to
2524 * 'stream'. */
2525void
2526expr_matches_print(const struct hmap *matches, FILE *stream)
2527{
2528 if (hmap_is_empty(matches)) {
2529 fputs("(no flows)\n", stream);
2530 return;
2531 }
2532
2533 const struct expr_match *m;
2534 HMAP_FOR_EACH (m, hmap_node, matches) {
2535 char *s = match_to_string(&m->match, OFP_DEFAULT_PRIORITY);
2536 fputs(s, stream);
2537 free(s);
2538
2539 if (m->n) {
2540 for (int i = 0; i < m->n; i++) {
2541 const struct cls_conjunction *c = &m->conjunctions[i];
2542 fprintf(stream, "%c conjunction(%"PRIu32", %d/%d)",
2543 i == 0 ? ':' : ',', c->id, c->clause, c->n_clauses);
2544 }
2545 }
2546 putc('\n', stream);
2547 }
2548}
e0840f11
BP
2549\f
2550/* Returns true if 'expr' honors the invariants for expressions (see the large
2551 * comment above "struct expr" in expr.h), false otherwise. */
2552bool
2553expr_honors_invariants(const struct expr *expr)
2554{
2555 const struct expr *sub;
2556
2557 switch (expr->type) {
2558 case EXPR_T_CMP:
2559 if (expr->cmp.symbol->width) {
2560 for (int i = 0; i < ARRAY_SIZE(expr->cmp.value.be64); i++) {
2561 if (expr->cmp.value.be64[i] & ~expr->cmp.mask.be64[i]) {
2562 return false;
2563 }
2564 }
2565 }
2566 return true;
2567
2568 case EXPR_T_AND:
2569 case EXPR_T_OR:
2570 if (list_is_short(&expr->andor)) {
2571 return false;
2572 }
2573 LIST_FOR_EACH (sub, node, &expr->andor) {
2574 if (sub->type == expr->type || !expr_honors_invariants(sub)) {
2575 return false;
2576 }
2577 }
2578 return true;
2579
2580 case EXPR_T_BOOLEAN:
2581 return true;
2582
2583 default:
2584 OVS_NOT_REACHED();
2585 }
2586}
2587
2588static bool
2589expr_is_normalized_and(const struct expr *expr)
2590{
2591 /* XXX should also check that no symbol is repeated. */
2592 const struct expr *sub;
2593
2594 LIST_FOR_EACH (sub, node, &expr->andor) {
2595 if (!expr_is_cmp(sub)) {
2596 return false;
2597 }
2598 }
2599 return true;
2600}
2601
2602/* Returns true if 'expr' is in the form returned by expr_normalize(), false
2603 * otherwise. */
2604bool
2605expr_is_normalized(const struct expr *expr)
2606{
2607 switch (expr->type) {
2608 case EXPR_T_CMP:
2609 return true;
2610
2611 case EXPR_T_AND:
2612 return expr_is_normalized_and(expr);
2613
2614 case EXPR_T_OR:
2615 if (!expr_is_cmp(expr)) {
2616 const struct expr *sub;
2617
2618 LIST_FOR_EACH (sub, node, &expr->andor) {
2619 if (!expr_is_cmp(sub) && !expr_is_normalized_and(sub)) {
2620 return false;
2621 }
2622 }
2623 }
2624 return true;
2625
2626 case EXPR_T_BOOLEAN:
2627 return true;
2628
2629 default:
2630 OVS_NOT_REACHED();
2631 }
2632}
3b7cb7e1
BP
2633\f
2634/* Action parsing helper. */
2635
a20c96c6
BP
2636/* Expands 'f' repeatedly as long as it has an expansion, that is, as long as
2637 * it is a subfield or a predicate. Adds any prerequisites for 'f' to
2638 * '*prereqs'.
2639 *
2640 * If 'rw', verifies that 'f' is a read/write field.
2641 *
a20c96c6
BP
2642 * Returns true if successful, false if an error was encountered (in which case
2643 * 'ctx->error' reports the particular error). */
5ee054fb 2644static bool
ce57ea75 2645expand_symbol(struct expr_context *ctx, bool rw,
a20c96c6 2646 struct expr_field *f, struct expr **prereqsp)
3b7cb7e1 2647{
a20c96c6
BP
2648 const struct expr_symbol *orig_symbol = f->symbol;
2649
5ee054fb 2650 if (f->symbol->expansion && f->symbol->level != EXPR_L_ORDINAL) {
ce57ea75
BP
2651 expr_error(ctx, "Predicate symbol %s used where lvalue required.",
2652 f->symbol->name);
5ee054fb 2653 return false;
3b7cb7e1
BP
2654 }
2655
3b7cb7e1
BP
2656 for (;;) {
2657 /* Accumulate prerequisites. */
5ee054fb 2658 if (f->symbol->prereqs) {
3b7cb7e1
BP
2659 struct ovs_list nesting = OVS_LIST_INITIALIZER(&nesting);
2660 char *error;
2661 struct expr *e;
5ee054fb 2662 e = parse_and_annotate(f->symbol->prereqs, ctx->symtab, &nesting,
3b7cb7e1
BP
2663 &error);
2664 if (error) {
2665 expr_error(ctx, "%s", error);
2666 free(error);
5ee054fb 2667 return false;
3b7cb7e1 2668 }
5ee054fb 2669 *prereqsp = expr_combine(EXPR_T_AND, *prereqsp, e);
3b7cb7e1
BP
2670 }
2671
2672 /* If there's no expansion, we're done. */
5ee054fb 2673 if (!f->symbol->expansion) {
3b7cb7e1
BP
2674 break;
2675 }
2676
2677 /* Expand. */
2678 struct expr_field expansion;
2679 char *error;
5ee054fb 2680 if (!parse_field_from_string(f->symbol->expansion, ctx->symtab,
3b7cb7e1
BP
2681 &expansion, &error)) {
2682 expr_error(ctx, "%s", error);
2683 free(error);
5ee054fb 2684 return false;
3b7cb7e1 2685 }
5ee054fb
BP
2686 f->symbol = expansion.symbol;
2687 f->ofs += expansion.ofs;
3b7cb7e1
BP
2688 }
2689
a20c96c6
BP
2690 if (rw && !f->symbol->field->writable) {
2691 expr_error(ctx, "Field %s is not modifiable.", orig_symbol->name);
2692 return false;
2693 }
2694
5ee054fb
BP
2695 return true;
2696}
2697
a20c96c6
BP
2698static void
2699mf_subfield_from_expr_field(const struct expr_field *f, struct mf_subfield *sf)
2700{
2701 sf->field = f->symbol->field;
2702 sf->ofs = f->ofs;
2703 sf->n_bits = f->n_bits ? f->n_bits : f->symbol->field->n_bits;
2704}
2705
2706static void
2707init_stack_action(const struct expr_field *f, struct ofpact_stack *stack)
2708{
2709 mf_subfield_from_expr_field(f, &stack->subfield);
2710}
2711
5ee054fb 2712static struct expr *
f1c16a85
BP
2713parse_assignment(struct expr_context *ctx,
2714 bool (*lookup_port)(const void *aux, const char *port_name,
2715 unsigned int *portp),
2716 const void *aux, struct ofpbuf *ofpacts)
5ee054fb
BP
2717{
2718 struct expr *prereqs = NULL;
2719
2720 /* Parse destination and do basic checking. */
2721 struct expr_field dst;
2722 if (!parse_field(ctx, &dst)) {
2723 goto exit;
2724 }
a20c96c6
BP
2725 bool exchange = lexer_match(ctx->lexer, LEX_T_EXCHANGE);
2726 if (!exchange && !lexer_match(ctx->lexer, LEX_T_EQUALS)) {
5ee054fb
BP
2727 expr_syntax_error(ctx, "expecting `='.");
2728 goto exit;
2729 }
2730 const struct expr_symbol *orig_dst = dst.symbol;
ce57ea75 2731 if (!expand_symbol(ctx, true, &dst, &prereqs)) {
5ee054fb 2732 goto exit;
3b7cb7e1
BP
2733 }
2734
a20c96c6 2735 if (exchange || ctx->lexer->token.type == LEX_T_ID) {
5ee054fb
BP
2736 struct expr_field src;
2737 if (!parse_field(ctx, &src)) {
2738 goto exit;
2739 }
2740 const struct expr_symbol *orig_src = src.symbol;
ce57ea75 2741 if (!expand_symbol(ctx, exchange, &src, &prereqs)) {
5ee054fb
BP
2742 goto exit;
2743 }
2744
2745 if ((dst.symbol->width != 0) != (src.symbol->width != 0)) {
a20c96c6
BP
2746 if (exchange) {
2747 expr_error(ctx,
2748 "Can't exchange %s field (%s) with %s field (%s).",
2749 orig_dst->width ? "integer" : "string",
2750 orig_dst->name,
2751 orig_src->width ? "integer" : "string",
2752 orig_src->name);
2753 } else {
2754 expr_error(ctx, "Can't assign %s field (%s) to %s field (%s).",
2755 orig_src->width ? "integer" : "string",
2756 orig_src->name,
2757 orig_dst->width ? "integer" : "string",
2758 orig_dst->name);
2759 }
5ee054fb
BP
2760 goto exit;
2761 }
2762
2763 if (dst.n_bits != src.n_bits) {
a20c96c6
BP
2764 if (exchange) {
2765 expr_error(ctx,
2766 "Can't exchange %d-bit field with %d-bit field.",
2767 dst.n_bits, src.n_bits);
2768 } else {
2769 expr_error(ctx,
2770 "Can't assign %d-bit value to %d-bit destination.",
2771 src.n_bits, dst.n_bits);
2772 }
5ee054fb
BP
2773 goto exit;
2774 } else if (!dst.n_bits
2775 && dst.symbol->field->n_bits != src.symbol->field->n_bits) {
2776 expr_error(ctx, "String fields %s and %s are incompatible for "
a20c96c6
BP
2777 "%s.", orig_dst->name, orig_src->name,
2778 exchange ? "exchange" : "assignment");
5ee054fb 2779 goto exit;
3b7cb7e1
BP
2780 }
2781
a20c96c6
BP
2782 if (exchange) {
2783 init_stack_action(&src, ofpact_put_STACK_PUSH(ofpacts));
2784 init_stack_action(&dst, ofpact_put_STACK_PUSH(ofpacts));
2785 init_stack_action(&src, ofpact_put_STACK_POP(ofpacts));
2786 init_stack_action(&dst, ofpact_put_STACK_POP(ofpacts));
2787 } else {
2788 struct ofpact_reg_move *move = ofpact_put_REG_MOVE(ofpacts);
2789 mf_subfield_from_expr_field(&src, &move->src);
2790 mf_subfield_from_expr_field(&dst, &move->dst);
2791 }
3b7cb7e1 2792 } else {
5ee054fb
BP
2793 struct expr_constant_set cs;
2794 if (!parse_constant_set(ctx, &cs)) {
2795 goto exit;
2796 }
2797
2798 if (!type_check(ctx, &dst, &cs)) {
2799 goto exit_destroy_cs;
2800 }
2801 if (cs.in_curlies) {
2802 expr_error(ctx, "Assignments require a single value.");
2803 goto exit_destroy_cs;
2804 }
2805
2806 union expr_constant *c = cs.values;
2807 struct ofpact_set_field *sf = ofpact_put_SET_FIELD(ofpacts);
2808 sf->field = dst.symbol->field;
2809 if (dst.symbol->width) {
2810 mf_subvalue_shift(&c->value, dst.ofs);
2811 if (!c->masked) {
2812 memset(&c->mask, 0, sizeof c->mask);
2813 bitwise_one(&c->mask, sizeof c->mask, dst.ofs, dst.n_bits);
2814 } else {
2815 mf_subvalue_shift(&c->mask, dst.ofs);
2816 }
2817
2818 memcpy(&sf->value,
2819 &c->value.u8[sizeof c->value - sf->field->n_bytes],
2820 sf->field->n_bytes);
2821 memcpy(&sf->mask,
2822 &c->mask.u8[sizeof c->mask - sf->field->n_bytes],
2823 sf->field->n_bytes);
2824 } else {
f1c16a85
BP
2825 uint32_t port;
2826 if (!lookup_port(aux, c->string, &port)) {
2827 port = 0;
2828 }
5ee054fb
BP
2829 bitwise_put(port, &sf->value,
2830 sf->field->n_bytes, 0, sf->field->n_bits);
b4970837
BP
2831 bitwise_one(&sf->mask, sf->field->n_bytes, 0, sf->field->n_bits);
2832
2833 /* If the logical input port is being zeroed, clear the OpenFlow
2834 * ingress port also, to allow a packet to be sent back to its
2835 * origin. */
2836 if (!port && sf->field->id == MFF_LOG_INPORT) {
2837 sf = ofpact_put_SET_FIELD(ofpacts);
2838 sf->field = mf_from_id(MFF_IN_PORT);
2839 bitwise_one(&sf->mask,
2840 sf->field->n_bytes, 0, sf->field->n_bits);
2841 }
5ee054fb
BP
2842 }
2843
2844 exit_destroy_cs:
2845 expr_constant_set_destroy(&cs);
3b7cb7e1
BP
2846 }
2847
3b7cb7e1
BP
2848exit:
2849 return prereqs;
2850}
2851
2852/* A helper for actions_parse(), to parse an OVN assignment action in the form
a20c96c6
BP
2853 * "field = value" or "field1 = field2", or a "exchange" action in the form
2854 * "field1 <-> field2", into 'ofpacts'. The parameters and return value match
2855 * those for actions_parse(). */
3b7cb7e1
BP
2856char *
2857expr_parse_assignment(struct lexer *lexer, const struct shash *symtab,
f1c16a85
BP
2858 bool (*lookup_port)(const void *aux,
2859 const char *port_name,
2860 unsigned int *portp),
2861 const void *aux,
3b7cb7e1
BP
2862 struct ofpbuf *ofpacts, struct expr **prereqsp)
2863{
2864 struct expr_context ctx;
2865 ctx.lexer = lexer;
2866 ctx.symtab = symtab;
2867 ctx.error = NULL;
2868 ctx.not = false;
2869
f1c16a85 2870 struct expr *prereqs = parse_assignment(&ctx, lookup_port, aux, ofpacts);
3b7cb7e1
BP
2871 if (ctx.error) {
2872 expr_destroy(prereqs);
2873 prereqs = NULL;
2874 }
2875 *prereqsp = prereqs;
2876 return ctx.error;
2877}
0bac7164
BP
2878
2879char *
2880expr_parse_field(struct lexer *lexer, int n_bits, bool rw,
2881 const struct shash *symtab,
2882 struct mf_subfield *sf, struct expr **prereqsp)
2883{
2884 struct expr *prereqs = NULL;
2885 struct expr_context ctx;
2886 ctx.lexer = lexer;
2887 ctx.symtab = symtab;
2888 ctx.error = NULL;
2889 ctx.not = false;
2890
2891 struct expr_field field;
2892 if (!parse_field(&ctx, &field)) {
2893 goto exit;
2894 }
2895
2896 const struct expr_field orig_field = field;
2897 if (!expand_symbol(&ctx, rw, &field, &prereqs)) {
2898 goto exit;
2899 }
2900 ovs_assert(field.n_bits == orig_field.n_bits);
2901
2902 if (n_bits != field.n_bits) {
2903 if (n_bits && field.n_bits) {
2904 expr_error(&ctx, "Cannot use %d-bit field %s[%d..%d] "
2905 "where %d-bit field is required.",
2906 orig_field.n_bits, orig_field.symbol->name,
2907 orig_field.ofs, orig_field.ofs + orig_field.n_bits - 1,
2908 n_bits);
2909 } else if (n_bits) {
2910 expr_error(&ctx, "Cannot use string field %s where numeric "
2911 "field is required.",
2912 orig_field.symbol->name);
2913 } else {
2914 expr_error(&ctx, "Cannot use numeric field %s where string "
2915 "field is required.",
2916 orig_field.symbol->name);
2917 }
2918 }
2919
2920exit:
2921 if (!ctx.error) {
2922 mf_subfield_from_expr_field(&field, sf);
2923 *prereqsp = prereqs;
2924 } else {
2925 memset(sf, 0, sizeof *sf);
2926 expr_destroy(prereqs);
2927 *prereqsp = NULL;
2928 }
2929 return ctx.error;
2930}