[ovs-dev] [PATCH 3/4] flow, match, classifier: Add new functions for miniflow and minimatch.

Ben Pfaff blp at ovn.org
Tue Mar 20 20:46:31 UTC 2018


The miniflow and minimatch APIs lack several of the features of the flow
and match APIs.  This commit adds a few of the missing functions.

These functions will be used for the first time in an upcoming commit.

Signed-off-by: Ben Pfaff <blp at ovn.org>
---
 include/openvswitch/match.h |  4 ++++
 lib/classifier.c            | 19 +++++++++++++++++++
 lib/classifier.h            |  4 ++++
 lib/flow.h                  | 27 +++++++++++++++++++++++++++
 lib/match.c                 | 44 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 98 insertions(+)

diff --git a/include/openvswitch/match.h b/include/openvswitch/match.h
index e5cf1a0d7c14..49333ae8f7a1 100644
--- a/include/openvswitch/match.h
+++ b/include/openvswitch/match.h
@@ -246,6 +246,7 @@ struct minimatch {
 };
 
 void minimatch_init(struct minimatch *, const struct match *);
+void minimatch_init_catchall(struct minimatch *);
 void minimatch_clone(struct minimatch *, const struct minimatch *);
 void minimatch_move(struct minimatch *dst, struct minimatch *src);
 void minimatch_destroy(struct minimatch *);
@@ -253,6 +254,7 @@ void minimatch_destroy(struct minimatch *);
 void minimatch_expand(const struct minimatch *, struct match *);
 
 bool minimatch_equal(const struct minimatch *a, const struct minimatch *b);
+uint32_t minimatch_hash(const struct minimatch *, uint32_t basis);
 
 bool minimatch_matches_flow(const struct minimatch *, const struct flow *);
 
@@ -262,6 +264,8 @@ void minimatch_format(const struct minimatch *, const struct tun_table *,
 char *minimatch_to_string(const struct minimatch *,
                           const struct ofputil_port_map *, int priority);
 
+bool minimatch_has_default_hidden_fields(const struct minimatch *);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/classifier.c b/lib/classifier.c
index cea9053b6f67..edb40c89c608 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -1223,6 +1223,25 @@ classifier_find_match_exactly(const struct classifier *cls,
     return retval;
 }
 
+/* Finds and returns a rule in 'cls' with priority 'priority' and exactly the
+ * same matching criteria as 'target', and that is visible in 'version'.
+ * Returns a null pointer if 'cls' doesn't contain an exact match visible in
+ * 'version'. */
+const struct cls_rule *
+classifier_find_minimatch_exactly(const struct classifier *cls,
+                              const struct minimatch *target, int priority,
+                              ovs_version_t version)
+{
+    const struct cls_rule *retval;
+    struct cls_rule cr;
+
+    cls_rule_init_from_minimatch(&cr, target, priority);
+    retval = classifier_find_rule_exactly(cls, &cr, version);
+    cls_rule_destroy(&cr);
+
+    return retval;
+}
+
 /* Checks if 'target' would overlap any other rule in 'cls' in 'version'.  Two
  * rules are considered to overlap if both rules have the same priority and a
  * packet could match both, and if both rules are visible in the same version.
diff --git a/lib/classifier.h b/lib/classifier.h
index 1263afdfd1a9..d1bd4aa12a78 100644
--- a/lib/classifier.h
+++ b/lib/classifier.h
@@ -406,6 +406,10 @@ const struct cls_rule *classifier_find_match_exactly(const struct classifier *,
                                                      const struct match *,
                                                      int priority,
                                                      ovs_version_t);
+const struct cls_rule *classifier_find_minimatch_exactly(
+    const struct classifier *, const struct minimatch *,
+    int priority, ovs_version_t);
+
 bool classifier_is_empty(const struct classifier *);
 int classifier_count(const struct classifier *);
 
diff --git a/lib/flow.h b/lib/flow.h
index 3331e2068ed8..5e41567b2668 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -728,6 +728,11 @@ static inline ovs_be32 miniflow_get_be32(const struct miniflow *,
 static inline uint16_t miniflow_get_vid(const struct miniflow *, size_t);
 static inline uint16_t miniflow_get_tcp_flags(const struct miniflow *);
 static inline ovs_be64 miniflow_get_metadata(const struct miniflow *);
+static inline uint64_t miniflow_get_tun_metadata_present_map(
+    const struct miniflow *);
+static inline uint32_t miniflow_get_recirc_id(const struct miniflow *);
+static inline uint32_t miniflow_get_dp_hash(const struct miniflow *);
+static inline ovs_be32 miniflow_get_ports(const struct miniflow *);
 
 bool miniflow_equal(const struct miniflow *a, const struct miniflow *b);
 bool miniflow_equal_in_minimask(const struct miniflow *a,
@@ -857,6 +862,27 @@ miniflow_get_metadata(const struct miniflow *flow)
     return MINIFLOW_GET_BE64(flow, metadata);
 }
 
+/* Returns the bitmap that indicates which tunnel metadata fields are present
+ * in 'flow'. */
+static inline uint64_t
+miniflow_get_tun_metadata_present_map(const struct miniflow *flow)
+{
+    return MINIFLOW_GET_U64(flow, tunnel.metadata.present.map);
+}
+
+/* Returns the recirc_id in 'flow.' */
+static inline uint32_t
+miniflow_get_recirc_id(const struct miniflow *flow)
+{
+    return MINIFLOW_GET_U32(flow, recirc_id);
+}
+
+/* Returns the dp_hash in 'flow.' */
+static inline uint32_t
+miniflow_get_dp_hash(const struct miniflow *flow)
+{
+    return MINIFLOW_GET_U32(flow, dp_hash);
+}
 
 /* Returns the 'tp_src' and 'tp_dst' fields together as one piece of data. */
 static inline ovs_be32
@@ -864,6 +890,7 @@ miniflow_get_ports(const struct miniflow *flow)
 {
     return MINIFLOW_GET_TYPE__(flow, ovs_be32, tp_src);
 }
+
 /* Returns the mask for the OpenFlow 1.1+ "metadata" field in 'mask'.
  *
  * The return value is all-1-bits if 'mask' matches on the whole value of the
diff --git a/lib/match.c b/lib/match.c
index 3eab0fd5dec9..2e9a80329bb3 100644
--- a/lib/match.c
+++ b/lib/match.c
@@ -1667,6 +1667,15 @@ minimatch_init(struct minimatch *dst, const struct match *src)
     dst->tun_md = tun_metadata_allocation_clone(&src->tun_md);
 }
 
+/* Initializes 'match' as a "catch-all" match that matches every packet. */
+void
+minimatch_init_catchall(struct minimatch *match)
+{
+    match->flows[0] = xcalloc(2, sizeof *match->flow);
+    match->flows[1] = match->flows[0] + 1;
+    match->tun_md = NULL;
+}
+
 /* Initializes 'dst' as a copy of 'src'.  The caller must eventually free 'dst'
  * with minimatch_destroy(). */
 void
@@ -1718,6 +1727,16 @@ minimatch_equal(const struct minimatch *a, const struct minimatch *b)
         && miniflow_equal(a->flow, b->flow);
 }
 
+/* Returns a hash value for the flow and wildcards in 'match', starting from
+ * 'basis'. */
+uint32_t
+minimatch_hash(const struct minimatch *match, uint32_t basis)
+{
+    size_t n_values = miniflow_n_values(match->flow);
+    size_t flow_size = sizeof *match->flow + MINIFLOW_VALUES_SIZE(n_values);
+    return hash_bytes(match->flow, 2 * flow_size, basis);
+}
+
 /* Returns true if 'target' satisifies 'match', that is, if each bit for which
  * 'match' specifies a particular value has the correct value in 'target'.
  *
@@ -1771,3 +1790,28 @@ minimatch_to_string(const struct minimatch *match,
     minimatch_expand(match, &megamatch);
     return match_to_string(&megamatch, port_map, priority);
 }
+
+static bool
+minimatch_has_default_recirc_id(const struct minimatch *m)
+{
+    uint32_t flow_recirc_id = miniflow_get_recirc_id(m->flow);
+    uint32_t mask_recirc_id = miniflow_get_recirc_id(&m->mask->masks);
+    return flow_recirc_id == 0 && (mask_recirc_id == UINT32_MAX ||
+                                   mask_recirc_id == 0);
+}
+
+static bool
+minimatch_has_default_dp_hash(const struct minimatch *m)
+{
+    return (!miniflow_get_dp_hash(m->flow)
+            && !miniflow_get_dp_hash(&m->mask->masks));
+}
+
+/* Return true if the hidden fields of the match are set to the default values.
+ * The default values equals to those set up by match_init_hidden_fields(). */
+bool
+minimatch_has_default_hidden_fields(const struct minimatch *m)
+{
+    return (minimatch_has_default_recirc_id(m)
+            && minimatch_has_default_dp_hash(m));
+}
-- 
2.16.1



More information about the dev mailing list