This commit adds functions that check if the 'struct flow_wildcards'
member is fully masked (exact-match) or fully unmasked (don't care
the entire field at all).  Also, this commit adds a function to
shape a less-masked flow field by a more-masked flow field.

Signed-off-by: Alex Wang <al...@nicira.com>
---
 lib/flow.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 lib/flow.h |    5 +++++
 2 files changed, 48 insertions(+)

diff --git a/lib/flow.c b/lib/flow.c
index e54280a..0608503 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -898,9 +898,52 @@ flow_print(FILE *stream, const struct flow *flow)
     fputs(s, stream);
     free(s);
 }
+
+/* Applies the 'src_field' and 'src_wc' to 'dst_field' and 'dst_wc'
+ * respectively.  This should be used to shape a less-masked field by
+ * a more-masked field. */
+void
+flow_apply_field(void *dst_field, void *dst_wc, const void *src_field,
+                 const void *src_wc, size_t size)
+{
+    const uint8_t *sf = src_field;
+    const uint8_t *sw = src_wc;
+    uint8_t *df = dst_field;
+    uint8_t *dw = dst_wc;
+    size_t i;
+
+    for (i = 0; i < size ; i++) {
+        df[i] = sf[i] | df[i];
+        dw[i] = sw[i] | dw[i];
+    }
+}
 
 /* flow_wildcards functions. */
 
+/* Returns true if the 'field' of 'len' byte long is
+ * all one. */
+bool
+flow_wildcard_is_fully_masked(void *field, size_t len)
+{
+    char cmp[len];
+
+    memset(cmp, 0xff, len);
+
+    return !memcmp(field, cmp, len);
+}
+
+/* Returns true if the 'field' of 'len' byte long is
+ * all zero. */
+bool
+flow_wildcard_is_fully_unmasked(void *field, size_t len)
+{
+    char cmp[len];
+
+    memset(cmp, 0, len);
+
+    return !memcmp(field, cmp, len);
+}
+
 /* Initializes 'wc' as a set of wildcards that matches every packet. */
 void
 flow_wildcards_init_catchall(struct flow_wildcards *wc)
diff --git a/lib/flow.h b/lib/flow.h
index dcb5bb0..77d4609 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -232,6 +232,8 @@ void flow_set_mpls_bos(struct flow *, int idx, uint8_t 
stack);
 void flow_set_mpls_lse(struct flow *, int idx, ovs_be32 lse);
 
 void flow_compose(struct dp_packet *, const struct flow *);
+void flow_apply_field(void *dst_field, void *dst_wc, const void *src_field,
+                      const void *src_wc, size_t size);
 
 static inline uint64_t
 flow_get_xreg(const struct flow *flow, int idx)
@@ -327,6 +329,9 @@ struct flow_wildcards {
 #define WC_UNMASK_FIELD(WC, FIELD) \
     memset(&(WC)->masks.FIELD, 0, sizeof (WC)->masks.FIELD)
 
+bool flow_wildcard_is_fully_masked(void *field, size_t len);
+bool flow_wildcard_is_fully_unmasked(void *field, size_t len);
+
 void flow_wildcards_init_catchall(struct flow_wildcards *);
 
 void flow_wildcards_init_for_packet(struct flow_wildcards *,
-- 
1.7.9.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to