Skip to content

Commit

Permalink
expr: Make expr_to_flows() include conj_id flows.
Browse files Browse the repository at this point in the history
When I wrote expr_to_flows() originally, I assumed that the caller could
simply add an appropriate conj_id=X flow for each of the conjunctive
matches.  I forgot that the conj_id=X flows also need to include
prerequisites for actions, e.g. if the OpenFlow actions manipulate TCP
fields, then the conj_id=X field must match on eth_type=0x800 and
ip_proto=6.  That's hard for the caller to generate itself, so this commit
changes expr_to_matches() to generate the conj_id=X flows also.

Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Justin Pettit <jpettit@nicira.com>
  • Loading branch information
blp committed Apr 30, 2015
1 parent eb00399 commit 40e07b2
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 11 deletions.
18 changes: 18 additions & 0 deletions ovn/lib/expr.c
Expand Up @@ -2242,6 +2242,10 @@ add_conjunction(const struct expr *and, const struct simap *ports,
}
}
}

/* Add the flow that matches on conj_id. */
match_set_conj_id(&match, *n_conjsp);
expr_match_add(matches, expr_match_new(&match, 0, 0, 0));
}
}

Expand All @@ -2264,6 +2268,20 @@ add_cmp_flow(const struct expr *cmp, const struct simap *ports,
* conjunctive match IDs beginning with 0; the caller must offset or remap them
* into the desired range as necessary.
*
* The matches inserted into 'matches' will be of three distinct kinds:
*
* - Ordinary flows. The caller should add these OpenFlow flows with
* its desired actions.
*
* - Conjunctive flows, distinguished by 'n > 0' in the expr_match
* structure. The caller should add these OpenFlow flows with the
* conjunction(id, k/n) actions as specified in the 'conjunctions' array,
* remapping the ids.
*
* - conj_id flows, distinguished by matching on the "conj_id" field. The
* caller should remap the conj_id and add the OpenFlow flow with its
* desired actions.
*
* 'ports' must be a map from strings (presumably names of ports) to integers.
* Any comparisons against string fields in 'expr' are translated into integers
* through this map. A comparison against a string that is not in 'ports' acts
Expand Down
4 changes: 4 additions & 0 deletions ovn/lib/expr.h
Expand Up @@ -355,7 +355,11 @@ struct expr *expr_normalize(struct expr *);
bool expr_honors_invariants(const struct expr *);
bool expr_is_simplified(const struct expr *);
bool expr_is_normalized(const struct expr *);

/* Converting expressions to OpenFlow flows. */

/* An OpenFlow match generated from a Boolean expression. See
* expr_to_matches() for more information. */
struct expr_match {
struct hmap_node hmap_node;
struct match match;
Expand Down
12 changes: 1 addition & 11 deletions tests/test-ovn.c
Expand Up @@ -880,25 +880,15 @@ test_tree_shape_exhaustively(struct expr *expr, struct shash *symtab,
if (operation >= OP_FLOW) {
struct expr_match *m;
struct test_rule *test_rule;
uint32_t n_conjs;

n_conjs = expr_to_matches(modified, NULL, &matches);
expr_to_matches(modified, NULL, &matches);

classifier_init(&cls, NULL);
HMAP_FOR_EACH (m, hmap_node, &matches) {
test_rule = xmalloc(sizeof *test_rule);
cls_rule_init(&test_rule->cr, &m->match, 0);
classifier_insert(&cls, &test_rule->cr, m->conjunctions, m->n);
}
for (uint32_t conj_id = 1; conj_id <= n_conjs; conj_id++) {
struct match match;
match_init_catchall(&match);
match_set_conj_id(&match, conj_id);

test_rule = xmalloc(sizeof *test_rule);
cls_rule_init(&test_rule->cr, &match, 0);
classifier_insert(&cls, &test_rule->cr, NULL, 0);
}
}
for (int subst = 0; subst < 1 << (n_bits * n_vars); subst++) {
bool expected = evaluate_expr(expr, subst, n_bits);
Expand Down

0 comments on commit 40e07b2

Please sign in to comment.