[ovs-dev] [PATCH] test-classifier: Include classifier.h instead of classifier.c

Thomas Graf tgraf at noironetworks.com
Thu Oct 23 10:04:18 UTC 2014


Exposes the necessary structs and functions in classifier.h to allow
test-classifier.c to use the header and link to the library instead
of including classifier.c directly.

Adds VLOG_DECLARE_THIS_MODULE() which allows to extend the namespace
of a vlog module.

Also adds an assert to VLOG_DEFINE_MODULE() to catch duplicate
definitions with a proper backtrace.

Cc: Scott Mann <smann at noironetworks.com>
Cc: Ben Pfaff <blp at nicira.com>
Cc: Gurucharan Shetty <shettyg at nicira.com>
Signed-off-by: Thomas Graf <tgraf at noironetworks.com>
---
 lib/classifier.c        | 61 +++-------------------------------------------
 lib/classifier.h        | 65 +++++++++++++++++++++++++++++++++++++++++++++++++
 lib/vlog.h              |  7 +++++-
 tests/test-classifier.c |  8 +++---
 4 files changed, 78 insertions(+), 63 deletions(-)

diff --git a/lib/classifier.c b/lib/classifier.c
index 8dc89d9..ff39135 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -39,34 +39,6 @@ struct trie_ctx;
 #define TP_PORTS_OFS32 (offsetof(struct flow, tp_src) / 4)
 BUILD_ASSERT_DECL(TP_PORTS_OFS32 == offsetof(struct flow, tp_dst) / 4);
 
-/* A set of rules that all have the same fields wildcarded. */
-struct cls_subtable {
-    /* The fields are only used by writers and iterators. */
-    struct cmap_node cmap_node; /* Within struct classifier 'subtables_map'. */
-
-    /* The fields are only used by writers. */
-    int n_rules OVS_GUARDED;                /* Number of rules, including
-                                             * duplicates. */
-    unsigned int max_priority OVS_GUARDED;  /* Max priority of any rule in
-                                             * the subtable. */
-    unsigned int max_count OVS_GUARDED;     /* Count of max_priority rules. */
-
-    /* These fields are accessed by readers who care about wildcarding. */
-    tag_type tag;       /* Tag generated from mask for partitioning (const). */
-    uint8_t n_indices;                   /* How many indices to use (const). */
-    uint8_t index_ofs[CLS_MAX_INDICES];   /* u32 segment boundaries (const). */
-    unsigned int trie_plen[CLS_MAX_TRIES];  /* Trie prefix length in 'mask'
-                                             * (runtime configurable). */
-    int ports_mask_len;                     /* (const) */
-    struct cmap indices[CLS_MAX_INDICES];   /* Staged lookup indices. */
-    rcu_trie_ptr ports_trie;                /* NULL if none. */
-
-    /* These fields are accessed by all readers. */
-    struct cmap rules;                      /* Contains "struct cls_rule"s. */
-    struct minimask mask;                   /* Wildcards for fields (const). */
-    /* 'mask' must be the last field. */
-};
-
 /* Associates a metadata value (that is, a value of the OpenFlow 1.1+ metadata
  * field) with tags for the "cls_subtable"s that contain rules that match that
  * metadata value.  */
@@ -77,25 +49,6 @@ struct cls_partition {
     struct tag_tracker tracker OVS_GUARDED; /* Tracks the bits in 'tags'. */
 };
 
-/* Internal representation of a rule in a "struct cls_subtable". */
-struct cls_match {
-    /* Accessed only by writers and iterators. */
-    struct list list OVS_GUARDED; /* List of identical, lower-priority rules. */
-
-    /* Accessed only by writers. */
-    struct cls_partition *partition OVS_GUARDED;
-
-    /* Accessed by readers interested in wildcarding. */
-    unsigned int priority;      /* Larger numbers are higher priorities. */
-    struct cmap_node index_nodes[CLS_MAX_INDICES]; /* Within subtable's
-                                                    * 'indices'. */
-    /* Accessed by all readers. */
-    struct cmap_node cmap_node; /* Within struct cls_subtable 'rules'. */
-    struct cls_rule *cls_rule;
-    struct miniflow flow;       /* Matching rule. Mask is in the subtable. */
-    /* 'flow' must be the last field. */
-};
-
 static struct cls_match *
 cls_match_alloc(struct cls_rule *rule)
 {
@@ -195,7 +148,7 @@ miniflow_get_map_in_range(const struct miniflow *miniflow,
  *
  * The hash values returned by this function are the same as those returned by
  * miniflow_hash_in_minimask(), only the form of the arguments differ. */
-static inline uint32_t
+uint32_t
 flow_hash_in_minimask(const struct flow *flow, const struct minimask *mask,
                       uint32_t basis)
 {
@@ -218,7 +171,7 @@ flow_hash_in_minimask(const struct flow *flow, const struct minimask *mask,
  *
  * The hash values returned by this function are the same as those returned by
  * flow_hash_in_minimask(), only the form of the arguments differ. */
-static inline uint32_t
+uint32_t
 miniflow_hash_in_minimask(const struct miniflow *flow,
                           const struct minimask *mask, uint32_t basis)
 {
@@ -287,7 +240,7 @@ flow_wildcards_fold_minimask_range(struct flow_wildcards *wc,
 }
 
 /* Returns a hash value for 'flow', given 'basis'. */
-static inline uint32_t
+uint32_t
 miniflow_hash(const struct miniflow *flow, uint32_t basis)
 {
     const uint32_t *values = miniflow_get_u32_values(flow);
@@ -1706,14 +1659,6 @@ next_rule_in_list(struct cls_match *rule)
     return next->priority < rule->priority ? next : NULL;
 }
 
-/* A longest-prefix match tree. */
-struct trie_node {
-    uint32_t prefix;           /* Prefix bits for this node, MSB first. */
-    uint8_t  n_bits;           /* Never zero, except for the root node. */
-    unsigned int n_rules;      /* Number of rules that have this prefix. */
-    rcu_trie_ptr edges[2];     /* Both NULL if leaf. */
-};
-
 /* Max bits per node.  Must fit in struct trie_node's 'prefix'.
  * Also tested with 16, 8, and 5 to stress the implementation. */
 #define TRIE_PREFIX_BITS 32
diff --git a/lib/classifier.h b/lib/classifier.h
index c910ac4..75ff7eb 100644
--- a/lib/classifier.h
+++ b/lib/classifier.h
@@ -218,6 +218,8 @@
 #include "meta-flow.h"
 #include "ovs-thread.h"
 #include "pvector.h"
+#include "tag.h"
+#include "list.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -230,6 +232,14 @@ struct cls_match;
 struct trie_node;
 typedef OVSRCU_TYPE(struct trie_node *) rcu_trie_ptr;
 
+/* A longest-prefix match tree. */
+struct trie_node {
+    uint32_t prefix;           /* Prefix bits for this node, MSB first. */
+    uint8_t  n_bits;           /* Never zero, except for the root node. */
+    unsigned int n_rules;      /* Number of rules that have this prefix. */
+    rcu_trie_ptr edges[2];     /* Both NULL if leaf. */
+};
+
 /* Prefix trie for a 'field' */
 struct cls_trie {
     const struct mf_field *field; /* Trie field, or NULL. */
@@ -262,6 +272,53 @@ struct cls_rule {
     struct cls_match *cls_match; /* NULL if rule is not in a classifier. */
 };
 
+/* A set of rules that all have the same fields wildcarded. */
+struct cls_subtable {
+    /* The fields are only used by writers and iterators. */
+    struct cmap_node cmap_node; /* Within struct classifier 'subtables_map'. */
+
+    /* The fields are only used by writers. */
+    int n_rules OVS_GUARDED;                /* Number of rules, including
+                                             * duplicates. */
+    unsigned int max_priority OVS_GUARDED;  /* Max priority of any rule in
+                                             * the subtable. */
+    unsigned int max_count OVS_GUARDED;     /* Count of max_priority rules. */
+
+    /* These fields are accessed by readers who care about wildcarding. */
+    tag_type tag;       /* Tag generated from mask for partitioning (const). */
+    uint8_t n_indices;                   /* How many indices to use (const). */
+    uint8_t index_ofs[CLS_MAX_INDICES];   /* u32 segment boundaries (const). */
+    unsigned int trie_plen[CLS_MAX_TRIES];  /* Trie prefix length in 'mask'
+                                             * (runtime configurable). */
+    int ports_mask_len;                     /* (const) */
+    struct cmap indices[CLS_MAX_INDICES];   /* Staged lookup indices. */
+    rcu_trie_ptr ports_trie;                /* NULL if none. */
+
+    /* These fields are accessed by all readers. */
+    struct cmap rules;                      /* Contains "struct cls_rule"s. */
+    struct minimask mask;                   /* Wildcards for fields (const). */
+    /* 'mask' must be the last field. */
+};
+
+/* Internal representation of a rule in a "struct cls_subtable". */
+struct cls_match {
+    /* Accessed only by writers and iterators. */
+    struct list list OVS_GUARDED; /* List of identical, lower-priority rules. */
+
+    /* Accessed only by writers. */
+    struct cls_partition *partition OVS_GUARDED;
+
+    /* Accessed by readers interested in wildcarding. */
+    unsigned int priority;      /* Larger numbers are higher priorities. */
+    struct cmap_node index_nodes[CLS_MAX_INDICES]; /* Within subtable's
+                                                    * 'indices'. */
+    /* Accessed by all readers. */
+    struct cmap_node cmap_node; /* Within struct cls_subtable 'rules'. */
+    struct cls_rule *cls_rule;
+    struct miniflow flow;       /* Matching rule. Mask is in the subtable. */
+    /* 'flow' must be the last field. */
+};
+
 void cls_rule_init(struct cls_rule *, const struct match *,
                    unsigned int priority);
 void cls_rule_init_from_minimatch(struct cls_rule *, const struct minimatch *,
@@ -304,6 +361,14 @@ struct cls_rule *classifier_find_rule_exactly(const struct classifier *,
 struct cls_rule *classifier_find_match_exactly(const struct classifier *,
                                                const struct match *,
                                                unsigned int priority);
+
+uint32_t miniflow_hash(const struct miniflow *flow, uint32_t basis);
+uint32_t flow_hash_in_minimask(const struct flow *flow,
+                               const struct minimask *mask,
+                               uint32_t basis);
+uint32_t miniflow_hash_in_minimask(const struct miniflow *flow,
+                                   const struct minimask *mask,
+                                   uint32_t basis);
 
 /* Iteration. */
 
diff --git a/lib/vlog.h b/lib/vlog.h
index 974a301..00bbb74 100644
--- a/lib/vlog.h
+++ b/lib/vlog.h
@@ -93,7 +93,8 @@ extern struct list vlog_modules;
 #define VLOG_DEFINE_MODULE(MODULE)                                      \
         VLOG_DEFINE_MODULE__(MODULE)                                    \
         OVS_CONSTRUCTOR(init_##MODULE) {                                \
-                list_insert(&vlog_modules, &VLM_##MODULE.list);         \
+            ovs_assert(!vlog_module_from_name(#MODULE));                \
+            list_insert(&vlog_modules, &VLM_##MODULE.list);             \
         }                                                               \
 
 const char *vlog_get_module_name(const struct vlog_module *);
@@ -177,6 +178,10 @@ void vlog_rate_limit(const struct vlog_module *, enum vlog_level,
         VLOG_DEFINE_MODULE(MODULE);                                     \
         static struct vlog_module *const THIS_MODULE = &VLM_##MODULE
 
+#define VLOG_DECLARE_THIS_MODULE(MODULE)                                \
+        extern struct vlog_module VLM_##MODULE;                         \
+        static struct vlog_module *const THIS_MODULE = &VLM_##MODULE
+
 /* Convenience macros.  These assume that THIS_MODULE points to a "struct
  * vlog_module" for the current module, as set up by e.g. the
  * VLOG_DEFINE_MODULE macro above.
diff --git a/tests/test-classifier.c b/tests/test-classifier.c
index 1726171..87b8cb8 100644
--- a/tests/test-classifier.c
+++ b/tests/test-classifier.c
@@ -36,13 +36,13 @@
 #include "random.h"
 #include "unaligned.h"
 #include "ovstest.h"
+#include "vlog.h"
 #undef NDEBUG
 #include <assert.h>
 
-/* We need access to classifier internal definitions to be able to fully
- * test them.  The alternative would be to expose them all in the classifier
- * API. */
-#include "classifier.c"
+#include "classifier.h"
+
+VLOG_DECLARE_THIS_MODULE(classifier);
 
 /* Fields in a rule. */
 #define CLS_FIELDS                                                  \
-- 
1.9.3




More information about the dev mailing list