summaryrefslogtreecommitdiff
path: root/lib/classifier.c
diff options
context:
space:
mode:
authorJarno Rajahalme <jrajahalme@nicira.com>2014-06-13 10:38:05 -0700
committerJarno Rajahalme <jrajahalme@nicira.com>2014-06-26 08:40:00 -0700
commit386cb9f7715eeae88dedfc6623376578cd06f71d (patch)
treeff6a06b24ba584d9930e57760614a9816e7f238c /lib/classifier.c
parente9319757f1b67c890665033073cfe738bb5bcb5b (diff)
downloadopenvswitch-386cb9f7715eeae88dedfc6623376578cd06f71d.tar.gz
lib/classifier: Clarify find_match_wc().
Reduce the number of goto statements by returning via a new helper fill_range_wc() when no match is found. Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib/classifier.c')
-rw-r--r--lib/classifier.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/lib/classifier.c b/lib/classifier.c
index 9b4a270f1..330cd6779 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -1436,6 +1436,16 @@ miniflow_and_mask_matches_flow_wc(const struct miniflow *flow,
return true;
}
+/* Unwildcard the fields looked up so far, if any. */
+static void
+fill_range_wc(const struct cls_subtable *subtable, struct flow_wildcards *wc,
+ uint8_t to)
+{
+ if (to) {
+ flow_wildcards_fold_minimask_range(wc, &subtable->mask, 0, to);
+ }
+}
+
static struct cls_match *
find_match_wc(const struct cls_subtable *subtable, const struct flow *flow,
struct trie_ctx trie_ctx[CLS_MAX_TRIES], unsigned int n_tries,
@@ -1459,16 +1469,19 @@ find_match_wc(const struct cls_subtable *subtable, const struct flow *flow,
if (check_tries(trie_ctx, n_tries, subtable->trie_plen, ofs, flow,
wc)) {
- goto range_out;
+ /* 'wc' bits for the trie field set, now unwildcard the preceding
+ * bits used so far. */
+ fill_range_wc(subtable, wc, ofs.start);
+ return NULL;
}
hash = flow_hash_in_minimask_range(flow, &subtable->mask, ofs.start,
ofs.end, &basis);
- ofs.start = ofs.end;
inode = hindex_node_with_hash(&subtable->indices[i], hash);
if (!inode) {
- /* No match, can stop immediately, but must fold in the mask
- * covered so far. */
- goto range_out;
+ /* No match, can stop immediately, but must fold in the bits
+ * used in lookup so far. */
+ fill_range_wc(subtable, wc, ofs.end);
+ return NULL;
}
/* If we have narrowed down to a single rule already, check whether
@@ -1484,11 +1497,13 @@ find_match_wc(const struct cls_subtable *subtable, const struct flow *flow,
}
return NULL;
}
+ ofs.start = ofs.end;
}
ofs.end = FLOW_U32S;
/* Trie check for the final range. */
if (check_tries(trie_ctx, n_tries, subtable->trie_plen, ofs, flow, wc)) {
- goto range_out;
+ fill_range_wc(subtable, wc, ofs.start);
+ return NULL;
}
hash = flow_hash_in_minimask_range(flow, &subtable->mask, ofs.start,
ofs.end, &basis);
@@ -1507,20 +1522,15 @@ find_match_wc(const struct cls_subtable *subtable, const struct flow *flow,
((OVS_FORCE ovs_be32 *)&wc->masks)[TP_PORTS_OFS32] |=
mask & htonl(~0 << (32 - mbits));
- ofs.start = TP_PORTS_OFS32;
- goto range_out;
+ /* Unwildcard all bits in the mask upto the ports, as they were used
+ * to determine there is no match. */
+ fill_range_wc(subtable, wc, TP_PORTS_OFS32);
+ return NULL;
}
/* Must unwildcard all the fields, as they were looked at. */
flow_wildcards_fold_minimask(wc, &subtable->mask);
return rule;
-
-range_out:
- /* Must unwildcard the fields looked up so far, if any. */
- if (ofs.start) {
- flow_wildcards_fold_minimask_range(wc, &subtable->mask, 0, ofs.start);
- }
- return NULL;
}
static struct cls_match *