log errors from host command
[sliver-openvswitch.git] / lib / classifier.c
index 2d1e50b..556278f 100644 (file)
@@ -25,6 +25,7 @@
 #include "odp-util.h"
 #include "ofp-util.h"
 #include "packets.h"
+#include "ovs-thread.h"
 
 static struct cls_table *find_table(const struct classifier *,
                                     const struct minimask *);
@@ -143,6 +144,7 @@ classifier_init(struct classifier *cls)
     cls->n_rules = 0;
     hmap_init(&cls->tables);
     list_init(&cls->tables_priority);
+    ovs_rwlock_init(&cls->rwlock);
 }
 
 /* Destroys 'cls'.  Rules within 'cls', if any, are not freed; this is the
@@ -157,6 +159,7 @@ classifier_destroy(struct classifier *cls)
             destroy_table(cls, table);
         }
         hmap_destroy(&cls->tables);
+        ovs_rwlock_destroy(&cls->rwlock);
     }
 }
 
@@ -252,9 +255,15 @@ classifier_remove(struct classifier *cls, struct cls_rule *rule)
 
 /* Finds and returns the highest-priority rule in 'cls' that matches 'flow'.
  * Returns a null pointer if no rules in 'cls' match 'flow'.  If multiple rules
- * of equal priority match 'flow', returns one arbitrarily. */
+ * of equal priority match 'flow', returns one arbitrarily.
+ *
+ * If a rule is found and 'wc' is non-null, bitwise-OR's 'wc' with the
+ * set of bits that were significant in the lookup.  At some point
+ * earlier, 'wc' should have been initialized (e.g., by
+ * flow_wildcards_init_catchall()). */
 struct cls_rule *
-classifier_lookup(const struct classifier *cls, const struct flow *flow)
+classifier_lookup(const struct classifier *cls, const struct flow *flow,
+                  struct flow_wildcards *wc)
 {
     struct cls_table *table;
     struct cls_rule *best;
@@ -262,6 +271,10 @@ classifier_lookup(const struct classifier *cls, const struct flow *flow)
     best = NULL;
     LIST_FOR_EACH (table, list_node, &cls->tables_priority) {
         struct cls_rule *rule = find_match(table, flow);
+
+        if (wc) {
+            flow_wildcards_fold_minimask(wc, &table->mask);
+        }
         if (rule) {
             best = rule;
             LIST_FOR_EACH_CONTINUE (table, list_node, &cls->tables_priority) {
@@ -271,6 +284,9 @@ classifier_lookup(const struct classifier *cls, const struct flow *flow)
                     return best;
                 }
                 rule = find_match(table, flow);
+                if (wc) {
+                    flow_wildcards_fold_minimask(wc, &table->mask);
+                }
                 if (rule && rule->priority > best->priority) {
                     best = rule;
                 }