summaryrefslogtreecommitdiff
path: root/lib/classifier.c
diff options
context:
space:
mode:
authorEthan Jackson <ethan@nicira.com>2014-06-23 18:40:47 -0700
committerEthan Jackson <ethan@nicira.com>2014-06-30 13:53:53 -0700
commitb76486349bed813ebc0ef15f78049312d917741b (patch)
tree5614952f461e9b8a385b30626459219a00c1d382 /lib/classifier.c
parent06861deb33021f3d5f56d4b03e8deee5d1f7b58e (diff)
downloadopenvswitch-b76486349bed813ebc0ef15f78049312d917741b.tar.gz
classifier: Add a batched miniflow lookup function.
Used in a future patch. Signed-off-by: Ethan Jackson <ethan@nicira.com> Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
Diffstat (limited to 'lib/classifier.c')
-rw-r--r--lib/classifier.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/lib/classifier.c b/lib/classifier.c
index 330cd6779..8001e383f 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -942,32 +942,47 @@ find_match_miniflow(const struct cls_subtable *subtable,
return NULL;
}
-/* Finds and returns the highest-priority rule in 'cls' that matches
- * 'miniflow'. Returns a null pointer if no rules in 'cls' match 'flow'.
- * If multiple rules of equal priority match 'flow', returns one arbitrarily.
+/* For each miniflow in 'flows' performs a classifier lookup writing the result
+ * into the corresponding slot in 'rules'. If a particular entry in 'flows' is
+ * NULL it is skipped.
*
- * This function is optimized for the userspace datapath, which only ever has
- * one priority value for it's flows!
- */
-struct cls_rule *classifier_lookup_miniflow_first(const struct classifier *cls_,
- const struct miniflow *flow)
+ * This function is optimized for use in the userspace datapath and therefore
+ * does not implement a lot of features available in the standard
+ * classifier_lookup() function. Specifically, it does not implement
+ * priorities, instead returning any rule which matches the flow. */
+void
+classifier_lookup_miniflow_batch(const struct classifier *cls_,
+ const struct miniflow **flows,
+ struct cls_rule **rules, size_t len)
{
struct cls_classifier *cls = cls_->cls;
struct cls_subtable *subtable;
+ size_t i, begin = 0;
+ memset(rules, 0, len * sizeof *rules);
PVECTOR_FOR_EACH (subtable, &cls->subtables) {
- struct cls_match *rule;
+ for (i = begin; i < len; i++) {
+ struct cls_match *match;
+ uint32_t hash;
- rule = find_match_miniflow(subtable, flow,
- miniflow_hash_in_minimask(flow,
- &subtable->mask,
- 0));
- if (rule) {
- return rule->cls_rule;
+ if (OVS_UNLIKELY(rules[i] || !flows[i])) {
+ continue;
+ }
+
+ hash = miniflow_hash_in_minimask(flows[i], &subtable->mask, 0);
+ match = find_match_miniflow(subtable, flows[i], hash);
+ if (OVS_UNLIKELY(match)) {
+ rules[i] = match->cls_rule;
+ }
}
- }
- return NULL;
+ while (begin < len && (rules[begin] || !flows[begin])) {
+ begin++;
+ }
+ if (begin >= len) {
+ break;
+ }
+ }
}
/* Finds and returns a rule in 'cls' with exactly the same priority and