[ovs-dev] [batch 4/5] classifier: Add a batched miniflow lookup function.
Ethan Jackson
ethan at nicira.com
Mon Jun 30 04:24:29 UTC 2014
Used in a future patch.
Signed-off-by: Ethan Jackson <ethan at nicira.com>
---
lib/classifier.c | 47 ++++++++++++++++++++++++++++++-----------------
lib/classifier.h | 5 +++--
lib/dpif-netdev.c | 2 +-
3 files changed, 34 insertions(+), 20 deletions(-)
diff --git a/lib/classifier.c b/lib/classifier.c
index f3f4f8e..3f32656 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -1170,33 +1170,46 @@ 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 flow 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;
struct cls_subtable_entry *iter;
+ size_t i, begin = 0;
+ memset(rules, 0, len * sizeof *rules);
CLS_SUBTABLES_FOR_EACH (subtable, iter, &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;
+ for (; begin < len && (rules[begin] || !flows[begin]); begin++);
+ if (begin == len) {
+ break;
+ }
+ }
}
/* Finds and returns a rule in 'cls' with exactly the same priority and
diff --git a/lib/classifier.h b/lib/classifier.h
index 326ca08..602d504 100644
--- a/lib/classifier.h
+++ b/lib/classifier.h
@@ -286,8 +286,9 @@ struct cls_rule *classifier_lookup(const struct classifier *cls,
const struct flow *,
struct flow_wildcards *)
OVS_REQ_RDLOCK(cls->rwlock);
-struct cls_rule *classifier_lookup_miniflow_first(const struct classifier *cls,
- const struct miniflow *)
+void classifier_lookup_miniflow_batch(const struct classifier *cls,
+ const struct miniflow **flows,
+ struct cls_rule **rules, size_t len)
OVS_REQ_RDLOCK(cls->rwlock);
bool classifier_rule_overlaps(const struct classifier *cls,
const struct cls_rule *)
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 9242356..4b5c9e2 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -1077,7 +1077,7 @@ dp_netdev_lookup_flow(const struct dp_netdev *dp, const struct miniflow *key)
struct dp_netdev_flow *netdev_flow;
struct cls_rule *rule;
- rule = classifier_lookup_miniflow_first(&dp->cls, key);
+ classifier_lookup_miniflow_batch(&dp->cls, &key, &rule, 1);
netdev_flow = dp_netdev_flow_cast(rule);
return netdev_flow;
--
1.8.1.2
More information about the dev
mailing list