summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2018-03-19 22:00:34 -0700
committerBen Pfaff <blp@ovn.org>2018-03-31 11:32:10 -0700
commit1dc1ec247e2a7fe126f9c8232a3d42521a8d8291 (patch)
treee078e45ff32146eafdbf4fa9c28b32f71dbc41d3 /lib
parentf825fdd4ff99fda707fb3b73596bf7d6bc7a1389 (diff)
downloadopenvswitch-1dc1ec247e2a7fe126f9c8232a3d42521a8d8291.tar.gz
flow, match, classifier: Add new functions for miniflow and minimatch.
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@ovn.org> Reviewed-by: Yifeng Sun <pkusunyifeng@gmail.com> Reviewed-by: Armando Migliaccio <armamig@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/classifier.c19
-rw-r--r--lib/classifier.h4
-rw-r--r--lib/flow.h27
-rw-r--r--lib/match.c44
4 files changed, 94 insertions, 0 deletions
diff --git a/lib/classifier.c b/lib/classifier.c
index cea9053b6..edb40c89c 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 1263afdfd..d1bd4aa12 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 3331e2068..5e41567b2 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 3eab0fd5d..2e9a80329 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));
+}