This patch makes miniflow building utilities available to other
modules.  A following patch adds support for classifier lookups on
miniflows, for which a custom-built miniflow key can be more efficient
than building a full struct flow and then converting that to a
miniflow.

Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
---
 lib/flow.c |  117 ------------------------------------------------------------
 lib/flow.h |  117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 117 insertions(+), 117 deletions(-)

diff --git a/lib/flow.c b/lib/flow.c
index 37d6af8..dd27f04 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -108,123 +108,6 @@ data_try_pull(void **datap, size_t *sizep, size_t size)
     return OVS_LIKELY(*sizep >= size) ? data_pull(datap, sizep, size) : NULL;
 }
 
-/* Macros for building miniflows.  Miniflow fields must be pushed in the order
- * they appear in struct flow.  Using a out-of-sync FLOW_WC_SEQ value below
- * will cause runtime assertions to make sure the code complies with the order
- * requirement. */
-
-#if (FLOW_WC_SEQ != 28)
-#define MINIFLOW_ASSERT(X) ovs_assert(X)
-BUILD_MESSAGE("FLOW_WC_SEQ changed: miniflow_extract() will have runtime "
-              "assertions enabled.  Consider updating FLOW_WC_SEQ value "
-              "above MINIFLOW_ASSERT() after testing.")
-#else
-#define MINIFLOW_ASSERT(X)
-#endif
-
-/* This is useful for making sure the buffer is properly aligned. */
-static inline void miniflow_assert_inline(const struct miniflow *mf,
-                                          const uint32_t *buf)
-{
-    ovs_assert(buf == mf->inline_values || buf == (uint32_t *)(mf + 1));
-}
-
-/* Context for pushing data to a miniflow. */
-struct mf_ctx {
-    uint64_t map;
-    uint32_t *data;
-    uint32_t * const end;
-};
-
-#define MF_CTX_INITIALIZER(BUF, COUNT) { 0, (BUF), (BUF) + COUNT }
-#define MF_CTX_FINISH(CTX, MINIFLOW)            \
-do {                                            \
-    (MINIFLOW)->map = (CTX).map;                \
-    (MINIFLOW)->values_inline = true;           \
-} while (0)
-
-/* miniflow_push_* macros allow filling in a miniflow data values in order.
- * Assertions are needed only when the layout of the struct flow is modified.
- * 'ofs' is a compile-time constant, which allows most of the code be optimized
- * away. */
-
-#define miniflow_push_uint32_(CTX, OFS, VALUE)                  \
-do {                                                            \
-    MINIFLOW_ASSERT((CTX).data < (CTX).end);                    \
-    MINIFLOW_ASSERT((OFS) % 4 == 0);                            \
-    MINIFLOW_ASSERT(!((CTX).map & (UINT64_MAX << (OFS) / 4)));  \
-                                                                \
-    *(CTX).data++ = VALUE;                                      \
-    (CTX).map |= UINT64_C(1) << (OFS) / 4;                      \
-} while (0)
-
-#define miniflow_push_be32_(CTX, OFS, VALUE)                        \
-    miniflow_push_uint32_(CTX, OFS, (OVS_FORCE uint32_t)(VALUE))
-
-#define miniflow_push_uint16_(CTX, OFS, VALUE)                          \
-do {                                                                    \
-    MINIFLOW_ASSERT((CTX).data < (CTX).end);                            \
-    MINIFLOW_ASSERT(((OFS) % 4 == 0                                     \
-                     && !((CTX).map & (UINT64_MAX << (OFS) / 4)))       \
-                    || ((OFS) % 4 == 2                                  \
-                        && (CTX).map & (UINT64_C(1) << (OFS) / 4)       \
-                        && !((CTX).map & (UINT64_MAX << ((OFS) / 4 + 1))))); \
-                                                                        \
-    if ((OFS) % 4 == 0) {                                               \
-        *(uint16_t *)(CTX).data = VALUE;                                \
-        (CTX).map |= UINT64_C(1) << (OFS) / 4;                          \
-    } else if ((OFS) % 4 == 2) {                                        \
-        *((uint16_t *)(CTX).data + 1) = VALUE;                          \
-        (CTX).data++;                                                   \
-    }                                                                   \
-} while (0)
-
-#define miniflow_push_be16_(CTX, OFS, VALUE)                    \
-    miniflow_push_uint16_(CTX, OFS, (OVS_FORCE uint16_t)VALUE);
-
-/* Data at 'valuep' may be unaligned. */
-#define miniflow_push_words_(CTX, OFS, VALUEP, N_WORDS)                 \
-do {                                                                    \
-    int ofs32 = (OFS) / 4;                                              \
-                                                                        \
-    MINIFLOW_ASSERT((CTX).data + (N_WORDS) <= (CTX).end);               \
-    MINIFLOW_ASSERT((OFS) % 4 == 0);                                    \
-    MINIFLOW_ASSERT(!((CTX).map & (UINT64_MAX << ofs32)));              \
-                                                                        \
-    memcpy((CTX).data, (VALUEP), (N_WORDS) * sizeof *(CTX).data);       \
-    (CTX).data += (N_WORDS);                                            \
-    (CTX).map |= ((UINT64_MAX >> (64 - (N_WORDS))) << ofs32);           \
-} while (0)
-
-#define miniflow_push_uint32(CTX, FIELD, VALUE)                     \
-    miniflow_push_uint32_(CTX, offsetof(struct flow, FIELD), VALUE)
-
-#define miniflow_push_be32(CTX, FIELD, VALUE)                       \
-    miniflow_push_be32_(CTX, offsetof(struct flow, FIELD), VALUE)
-
-#define miniflow_push_uint32_check(CTX, FIELD, VALUE)                   \
-do {                                                                    \
-    if (OVS_LIKELY(VALUE)) {                                            \
-        miniflow_push_uint32_(CTX, offsetof(struct flow, FIELD), VALUE); \
-    }                                                                   \
-} while (0)
-
-#define miniflow_push_be32_check(CTX, FIELD, VALUE)                     \
-do {                                                                    \
-    if (OVS_LIKELY(VALUE)) {                                            \
-        miniflow_push_be32_(CTX, offsetof(struct flow, FIELD), VALUE);  \
-    }                                                                   \
-} while (0)
-
-#define miniflow_push_uint16(CTX, FIELD, VALUE)                     \
-    miniflow_push_uint16_(CTX, offsetof(struct flow, FIELD), VALUE)
-
-#define miniflow_push_be16(CTX, FIELD, VALUE)                       \
-    miniflow_push_be16_(CTX, offsetof(struct flow, FIELD), VALUE)
-
-#define miniflow_push_words(CTX, FIELD, VALUEP, N_WORDS)                \
-    miniflow_push_words_(CTX, offsetof(struct flow, FIELD), VALUEP, N_WORDS)
-
 /* Pulls the MPLS headers at '*datap' and returns the count of them. */
 static inline int
 parse_mpls(void **datap, size_t *sizep)
diff --git a/lib/flow.h b/lib/flow.h
index f19f330..f9b577f 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -443,6 +443,123 @@ static inline const ovs_be32 
*miniflow_get_be32_values(const struct miniflow *mf
     return (OVS_FORCE const ovs_be32 *)miniflow_get_values(mf);
 }
 
+/* Macros for building miniflows.  Miniflow fields must be pushed in the order
+ * they appear in struct flow.  Using a out-of-sync FLOW_WC_SEQ value below
+ * will cause runtime assertions to make sure the code complies with the order
+ * requirement. */
+
+#if (FLOW_WC_SEQ != 28)
+#define MINIFLOW_ASSERT(X) ovs_assert(X)
+BUILD_MESSAGE("FLOW_WC_SEQ changed: miniflow_extract() will have runtime "
+              "assertions enabled.  Consider updating FLOW_WC_SEQ value "
+              "above MINIFLOW_ASSERT() after testing.")
+#else
+#define MINIFLOW_ASSERT(X)
+#endif
+
+/* This is useful for making sure the buffer is properly aligned. */
+static inline void miniflow_assert_inline(const struct miniflow *mf,
+                                          const uint32_t *buf)
+{
+    ovs_assert(buf == mf->inline_values || buf == (uint32_t *)(mf + 1));
+}
+
+/* Context for pushing data to a miniflow. */
+struct mf_ctx {
+    uint64_t map;
+    uint32_t *data;
+    uint32_t * const end;
+};
+
+#define MF_CTX_INITIALIZER(BUF, COUNT) { 0, (BUF), (BUF) + COUNT }
+#define MF_CTX_FINISH(CTX, MINIFLOW)            \
+do {                                            \
+    (MINIFLOW)->map = (CTX).map;                \
+    (MINIFLOW)->values_inline = true;           \
+} while (0)
+
+/* miniflow_push_* macros allow filling in a miniflow data values in order.
+ * Assertions are needed only when the layout of the struct flow is modified.
+ * 'ofs' is a compile-time constant, which allows most of the code be optimized
+ * away. */
+
+#define miniflow_push_uint32_(CTX, OFS, VALUE)                  \
+do {                                                            \
+    MINIFLOW_ASSERT((CTX).data < (CTX).end);                    \
+    MINIFLOW_ASSERT((OFS) % 4 == 0);                            \
+    MINIFLOW_ASSERT(!((CTX).map & (UINT64_MAX << (OFS) / 4)));  \
+                                                                \
+    *(CTX).data++ = VALUE;                                      \
+    (CTX).map |= UINT64_C(1) << (OFS) / 4;                      \
+} while (0)
+
+#define miniflow_push_be32_(CTX, OFS, VALUE)                        \
+    miniflow_push_uint32_(CTX, OFS, (OVS_FORCE uint32_t)(VALUE))
+
+#define miniflow_push_uint16_(CTX, OFS, VALUE)                          \
+do {                                                                    \
+    MINIFLOW_ASSERT((CTX).data < (CTX).end);                            \
+    MINIFLOW_ASSERT(((OFS) % 4 == 0                                     \
+                     && !((CTX).map & (UINT64_MAX << (OFS) / 4)))       \
+                    || ((OFS) % 4 == 2                                  \
+                        && (CTX).map & (UINT64_C(1) << (OFS) / 4)       \
+                        && !((CTX).map & (UINT64_MAX << ((OFS) / 4 + 1))))); \
+                                                                        \
+    if ((OFS) % 4 == 0) {                                               \
+        *(uint16_t *)(CTX).data = VALUE;                                \
+        (CTX).map |= UINT64_C(1) << (OFS) / 4;                          \
+    } else if ((OFS) % 4 == 2) {                                        \
+        *((uint16_t *)(CTX).data + 1) = VALUE;                          \
+        (CTX).data++;                                                   \
+    }                                                                   \
+} while (0)
+
+#define miniflow_push_be16_(CTX, OFS, VALUE)                    \
+    miniflow_push_uint16_(CTX, OFS, (OVS_FORCE uint16_t)VALUE);
+
+/* Data at 'valuep' may be unaligned. */
+#define miniflow_push_words_(CTX, OFS, VALUEP, N_WORDS)                 \
+do {                                                                    \
+    int ofs32 = (OFS) / 4;                                              \
+                                                                        \
+    MINIFLOW_ASSERT((CTX).data + (N_WORDS) <= (CTX).end);               \
+    MINIFLOW_ASSERT((OFS) % 4 == 0);                                    \
+    MINIFLOW_ASSERT(!((CTX).map & (UINT64_MAX << ofs32)));              \
+                                                                        \
+    memcpy((CTX).data, (VALUEP), (N_WORDS) * sizeof *(CTX).data);       \
+    (CTX).data += (N_WORDS);                                            \
+    (CTX).map |= ((UINT64_MAX >> (64 - (N_WORDS))) << ofs32);           \
+} while (0)
+
+#define miniflow_push_uint32(CTX, FIELD, VALUE)                     \
+    miniflow_push_uint32_(CTX, offsetof(struct flow, FIELD), VALUE)
+
+#define miniflow_push_be32(CTX, FIELD, VALUE)                       \
+    miniflow_push_be32_(CTX, offsetof(struct flow, FIELD), VALUE)
+
+#define miniflow_push_uint32_check(CTX, FIELD, VALUE)                   \
+do {                                                                    \
+    if (OVS_LIKELY(VALUE)) {                                            \
+        miniflow_push_uint32_(CTX, offsetof(struct flow, FIELD), VALUE); \
+    }                                                                   \
+} while (0)
+
+#define miniflow_push_be32_check(CTX, FIELD, VALUE)                     \
+do {                                                                    \
+    if (OVS_LIKELY(VALUE)) {                                            \
+        miniflow_push_be32_(CTX, offsetof(struct flow, FIELD), VALUE);  \
+    }                                                                   \
+} while (0)
+
+#define miniflow_push_uint16(CTX, FIELD, VALUE)                     \
+    miniflow_push_uint16_(CTX, offsetof(struct flow, FIELD), VALUE)
+
+#define miniflow_push_be16(CTX, FIELD, VALUE)                       \
+    miniflow_push_be16_(CTX, offsetof(struct flow, FIELD), VALUE)
+
+#define miniflow_push_words(CTX, FIELD, VALUEP, N_WORDS)                \
+    miniflow_push_words_(CTX, offsetof(struct flow, FIELD), VALUEP, N_WORDS)
+
 struct pkt_metadata;
 
 /* The 'dst->values' must be initialized with a buffer with space for
-- 
1.7.10.4

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

Reply via email to