[ovs-dev] [PATCH v5 1/4] classifier: Simplify versioning.

Jarno Rajahalme jrajahalme at nicira.com
Fri Jun 12 21:36:21 UTC 2015


After all, there are some cases in which both the insertion version
and removal version of a rule need to be considered.  This makes the
cls_match a bit bigger, but makes classifier versioning much simpler
to understand.

Also, avoid using type larger than int in an enum, as it is not
portable C.

Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
---
 lib/classifier-private.h     |   50 ++++++++++++-----------------
 lib/classifier.c             |   72 ++++++++++++++++--------------------------
 lib/classifier.h             |   26 ++++++++-------
 ofproto/ofproto-dpif-xlate.c |    4 +--
 ofproto/ofproto-dpif.c       |   17 +++++-----
 ofproto/ofproto-dpif.h       |    5 ++-
 ofproto/ofproto-provider.h   |    7 ++--
 ofproto/ofproto.c            |   15 ++++-----
 tests/test-classifier.c      |   12 +++----
 9 files changed, 92 insertions(+), 116 deletions(-)

diff --git a/lib/classifier-private.h b/lib/classifier-private.h
index a540371..73559c8 100644
--- a/lib/classifier-private.h
+++ b/lib/classifier-private.h
@@ -87,19 +87,16 @@ struct cls_match {
     /* Accessed by all readers. */
     struct cmap_node cmap_node; /* Within struct cls_subtable 'rules'. */
 
-    /* Controls rule's visibility to lookups.
+    /* Rule versioning.
      *
-     * When 'visibility' is:
+     * Special values for 'remove_version' are:
      *
-     * > 0  - rule is visible starting from version 'visibility'
-     * <= 0 - rule is invisible starting from version '-(visibility)'
-     *
-     * The minimum version number used in lookups is 1 (== CLS_NO_VERSION),
-     * which implies that when 'visibility' is:
-     *
-     * 1    - rule is visible in all lookup versions
-     * 0    - rule is invisible in all lookup versions. */
-    atomic_llong visibility;
+     * CLS_NO_VERSION:          Rule is invisible, used when the rule is first
+     *                          created, but before it is fully initialized.
+     * CLS_NOT_REMOVED_VERSION: Rule has been added but not yet removed.
+     */
+    const cls_version_t add_version;        /* Version rule was added in. */
+    ATOMIC(cls_version_t) remove_version;   /* Version rule is removed in. */
 
     const struct cls_rule *cls_rule;
     const struct miniflow flow; /* Matching rule. Mask is in the subtable. */
@@ -110,39 +107,34 @@ struct cls_match {
 void cls_match_free_cb(struct cls_match *);
 
 static inline void
-cls_match_set_visibility(struct cls_match *rule, long long version)
+cls_match_set_remove_version(struct cls_match *rule, cls_version_t version)
 {
-    atomic_store_relaxed(&rule->visibility, version);
+    atomic_store_relaxed(&rule->remove_version, version);
 }
 
 static inline bool
-cls_match_visible_in_version(const struct cls_match *rule, long long version)
+cls_match_visible_in_version(const struct cls_match *rule,
+                             cls_version_t version)
 {
-    long long visibility;
+    cls_version_t remove_version;
 
     /* C11 does not want to access an atomic via a const object pointer. */
-    atomic_read_relaxed(&CONST_CAST(struct cls_match *, rule)->visibility,
-                        &visibility);
-
-    if (OVS_LIKELY(visibility > 0)) {
-        /* Rule is visible starting from version 'visibility'. */
-        return version >= visibility;
-    } else {
-        /* Rule is invisible starting from version '-visibility'. */
-        return version < -visibility;
-    }
+    atomic_read_relaxed(&CONST_CAST(struct cls_match *, rule)->remove_version,
+                        &remove_version);
+
+    return rule->add_version <= version && version < remove_version;
 }
 
 static inline bool
 cls_match_is_eventually_invisible(const struct cls_match *rule)
 {
-    long long visibility;
+    cls_version_t remove_version;
 
     /* C11 does not want to access an atomic via a const object pointer. */
-    atomic_read_relaxed(&CONST_CAST(struct cls_match *, rule)->visibility,
-                        &visibility);
+    atomic_read_relaxed(&CONST_CAST(struct cls_match *, rule)->remove_version,
+                        &remove_version);
 
-    return visibility <= 0;
+    return remove_version <= CLS_MAX_VERSION;
 }
 
 
diff --git a/lib/classifier.c b/lib/classifier.c
index 66a2655..6487426 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -99,7 +99,9 @@ cls_match_alloc(const struct cls_rule *rule,
     ovsrcu_init(&cls_match->next, NULL);
     *CONST_CAST(const struct cls_rule **, &cls_match->cls_rule) = rule;
     *CONST_CAST(int *, &cls_match->priority) = rule->priority;
-    atomic_init(&cls_match->visibility, 0);   /* Initially invisible. */
+    *CONST_CAST(cls_version_t *, &cls_match->add_version) = rule->version;
+    atomic_init(&cls_match->remove_version, CLS_NO_VERSION);  /* Initially
+                                                                 invisible. */
     miniflow_clone_inline(CONST_CAST(struct miniflow *, &cls_match->flow),
                           &rule->match.flow, count);
     ovsrcu_set_hidden(&cls_match->conj_set,
@@ -115,7 +117,7 @@ static struct cls_subtable *insert_subtable(struct classifier *cls,
 static void destroy_subtable(struct classifier *cls, struct cls_subtable *);
 
 static const struct cls_match *find_match_wc(const struct cls_subtable *,
-                                             long long version,
+                                             cls_version_t version,
                                              const struct flow *,
                                              struct trie_ctx *,
                                              unsigned int n_tries,
@@ -128,15 +130,11 @@ static struct cls_match *find_equal(const struct cls_subtable *,
  * versioning is used at most one of them is ever visible for lookups on any
  * given 'version'. */
 static inline const struct cls_match *
-next_visible_rule_in_list(const struct cls_match *rule, long long version)
+next_visible_rule_in_list(const struct cls_match *rule, cls_version_t version)
 {
     do {
         rule = cls_match_next(rule);
-        if (!rule) {
-            /* We have reached the head of the list, stop. */
-            break;
-        }
-    } while (!cls_match_visible_in_version(rule, version));
+    } while (rule && !cls_match_visible_in_version(rule, version));
 
     return rule;
 }
@@ -166,13 +164,13 @@ static bool mask_prefix_bits_set(const struct flow_wildcards *,
 
 static inline void
 cls_rule_init__(struct cls_rule *rule, unsigned int priority,
-                long long version)
+                cls_version_t version)
 {
     ovs_assert(version > 0);
 
     rculist_init(&rule->node);
     *CONST_CAST(int *, &rule->priority) = priority;
-    *CONST_CAST(long long *, &rule->version) = version;
+    *CONST_CAST(cls_version_t *, &rule->version) = version;
     rule->cls_match = NULL;
 }
 
@@ -186,7 +184,7 @@ cls_rule_init__(struct cls_rule *rule, unsigned int priority,
  * 0 and UINT16_MAX, inclusive.) */
 void
 cls_rule_init(struct cls_rule *rule, const struct match *match, int priority,
-              long long version)
+              cls_version_t version)
 {
     cls_rule_init__(rule, priority, version);
     minimatch_init(CONST_CAST(struct minimatch *, &rule->match), match);
@@ -196,7 +194,7 @@ cls_rule_init(struct cls_rule *rule, const struct match *match, int priority,
 void
 cls_rule_init_from_minimatch(struct cls_rule *rule,
                              const struct minimatch *match, int priority,
-                             long long version)
+                             cls_version_t version)
 {
     cls_rule_init__(rule, priority, version);
     minimatch_clone(CONST_CAST(struct minimatch *, &rule->match), match);
@@ -207,7 +205,7 @@ cls_rule_init_from_minimatch(struct cls_rule *rule,
  * The caller must eventually destroy 'dst' with cls_rule_destroy(). */
 void
 cls_rule_clone_in_version(struct cls_rule *dst, const struct cls_rule *src,
-                          long long version)
+                          cls_version_t version)
 {
     cls_rule_init__(dst, src->priority, version);
     minimatch_clone(CONST_CAST(struct minimatch *, &dst->match), &src->match);
@@ -308,28 +306,12 @@ cls_rule_is_catchall(const struct cls_rule *rule)
  *
  * 'rule_' must be in a classifier. */
 void
-cls_rule_make_invisible_in_version(const struct cls_rule *rule_,
-                                   long long version, long long lookup_version)
-{
-    struct cls_match *rule = rule_->cls_match;
-
-    /* XXX: Adjust when versioning is actually used. */
-    ovs_assert(version >= rule_->version && version >= lookup_version);
-
-    /* Normally, we call this when deleting a rule that is already visible to
-     * lookups.  However, sometimes a bundle transaction will add a rule and
-     * then delete it before the rule has ever become visible.  If we set such
-     * a rule to become invisible in a future 'version', it would become
-     * visible to all prior versions.  So, in this case we must set the rule
-     * visibility to 0 (== never visible). */
-    if (cls_match_visible_in_version(rule, lookup_version)) {
-        /* Make invisible starting at 'version'. */
-        atomic_store_relaxed(&rule->visibility, -version);
-    } else {
-        /* Rule has not yet been visible to lookups, make invisible in all
-         * version. */
-        atomic_store_relaxed(&rule->visibility, 0);
-    }
+cls_rule_make_invisible_in_version(const struct cls_rule *rule,
+                                   cls_version_t remove_version)
+{
+    ovs_assert(remove_version >= rule->cls_match->add_version);
+
+    cls_match_set_remove_version(rule->cls_match, remove_version);
 }
 
 /* This undoes the change made by cls_rule_make_invisible_after_version().
@@ -338,14 +320,14 @@ cls_rule_make_invisible_in_version(const struct cls_rule *rule_,
 void
 cls_rule_restore_visibility(const struct cls_rule *rule)
 {
-    atomic_store_relaxed(&rule->cls_match->visibility, rule->version);
+    cls_match_set_remove_version(rule->cls_match, CLS_NOT_REMOVED_VERSION);
 }
 
 /* Return true if 'rule' is visible in 'version'.
  *
  * 'rule' must be in a classifier. */
 bool
-cls_rule_visible_in_version(const struct cls_rule *rule, long long version)
+cls_rule_visible_in_version(const struct cls_rule *rule, cls_version_t version)
 {
     return cls_match_visible_in_version(rule->cls_match, version);
 }
@@ -736,7 +718,7 @@ classifier_replace(struct classifier *cls, const struct cls_rule *rule,
                 /* No change in subtable's max priority or max count. */
 
                 /* Make 'new' visible to lookups in the appropriate version. */
-                cls_match_set_visibility(new, rule->version);
+                cls_match_set_remove_version(new, CLS_NOT_REMOVED_VERSION);
 
                 /* Make rule visible to iterators (immediately). */
                 rculist_replace(CONST_CAST(struct rculist *, &rule->node),
@@ -753,7 +735,7 @@ classifier_replace(struct classifier *cls, const struct cls_rule *rule,
     }
 
     /* Make 'new' visible to lookups in the appropriate version. */
-    cls_match_set_visibility(new, rule->version);
+    cls_match_set_remove_version(new, CLS_NOT_REMOVED_VERSION);
 
     /* Make rule visible to iterators (immediately). */
     rculist_push_back(&subtable->rules_list,
@@ -1047,7 +1029,7 @@ free_conjunctive_matches(struct hmap *matches,
  * 'flow' is non-const to allow for temporary modifications during the lookup.
  * Any changes are restored before returning. */
 static const struct cls_rule *
-classifier_lookup__(const struct classifier *cls, long long version,
+classifier_lookup__(const struct classifier *cls, cls_version_t version,
                     struct flow *flow, struct flow_wildcards *wc,
                     bool allow_conjunctive_matches)
 {
@@ -1307,7 +1289,7 @@ classifier_lookup__(const struct classifier *cls, long long version,
  * 'flow' is non-const to allow for temporary modifications during the lookup.
  * Any changes are restored before returning. */
 const struct cls_rule *
-classifier_lookup(const struct classifier *cls, long long version,
+classifier_lookup(const struct classifier *cls, cls_version_t version,
                   struct flow *flow, struct flow_wildcards *wc)
 {
     return classifier_lookup__(cls, version, flow, wc, true);
@@ -1354,7 +1336,7 @@ classifier_find_rule_exactly(const struct classifier *cls,
 const struct cls_rule *
 classifier_find_match_exactly(const struct classifier *cls,
                               const struct match *target, int priority,
-                              long long version)
+                              cls_version_t version)
 {
     const struct cls_rule *retval;
     struct cls_rule cr;
@@ -1480,7 +1462,7 @@ search_subtable(const struct cls_subtable *subtable,
  * first matching cls_rule via '*pnode', or NULL if there are no matches.
  *
  *     - If 'target' is null, or if the 'target' is a catchall target and the
- *       target's version is CLS_NO_VERSION, the cursor will visit every rule
+ *       target's version is CLS_MAX_VERSION, the cursor will visit every rule
  *       in 'cls' that is not invisible in any version.
  *
  *     - If 'target' is nonnull, the cursor will visit each 'rule' in 'cls'
@@ -1749,7 +1731,7 @@ miniflow_and_mask_matches_flow(const struct miniflow *flow,
 }
 
 static inline const struct cls_match *
-find_match(const struct cls_subtable *subtable, long long version,
+find_match(const struct cls_subtable *subtable, cls_version_t version,
            const struct flow *flow, uint32_t hash)
 {
     const struct cls_match *head, *rule;
@@ -1818,7 +1800,7 @@ fill_range_wc(const struct cls_subtable *subtable, struct flow_wildcards *wc,
 }
 
 static const struct cls_match *
-find_match_wc(const struct cls_subtable *subtable, long long version,
+find_match_wc(const struct cls_subtable *subtable, cls_version_t version,
               const struct flow *flow, struct trie_ctx trie_ctx[CLS_MAX_TRIES],
               unsigned int n_tries, struct flow_wildcards *wc)
 {
diff --git a/lib/classifier.h b/lib/classifier.h
index ef57446..9aec8b2 100644
--- a/lib/classifier.h
+++ b/lib/classifier.h
@@ -326,9 +326,14 @@ struct cls_trie {
     rcu_trie_ptr root;            /* NULL if none. */
 };
 
+typedef uint64_t cls_version_t;
+
+#define CLS_NO_VERSION 0
+#define CLS_MIN_VERSION 1                  /* Default version number to use. */
+#define CLS_MAX_VERSION (UINT64_MAX - 1)
+#define CLS_NOT_REMOVED_VERSION UINT64_MAX
+
 enum {
-    CLS_MIN_VERSION = 1,   /* Default version number to use. */
-    CLS_MAX_VERSION = LLONG_MAX, /* Last possible version number. */
     CLS_MAX_INDICES = 3,   /* Maximum number of lookup indices per subtable. */
     CLS_MAX_TRIES = 3      /* Maximum number of prefix trees per classifier. */
 };
@@ -357,18 +362,18 @@ struct cls_conjunction {
 struct cls_rule {
     struct rculist node;          /* In struct cls_subtable 'rules_list'. */
     const int priority;           /* Larger numbers are higher priorities. */
-    const long long version;      /* Version in which the rule was added. */
+    const cls_version_t version;  /* Version in which the rule was added. */
     struct cls_match *cls_match;  /* NULL if not in a classifier. */
     const struct minimatch match; /* Matching rule. */
 };
 
 void cls_rule_init(struct cls_rule *, const struct match *, int priority,
-                   long long version);
+                   cls_version_t);
 void cls_rule_init_from_minimatch(struct cls_rule *, const struct minimatch *,
-                                  int priority, long long version);
+                                  int priority, cls_version_t);
 void cls_rule_clone(struct cls_rule *, const struct cls_rule *);
 void cls_rule_clone_in_version(struct cls_rule *, const struct cls_rule *,
-        long long version);
+        cls_version_t);
 void cls_rule_move(struct cls_rule *dst, struct cls_rule *src);
 void cls_rule_destroy(struct cls_rule *);
 
@@ -381,10 +386,9 @@ void cls_rule_format(const struct cls_rule *, struct ds *);
 bool cls_rule_is_catchall(const struct cls_rule *);
 bool cls_rule_is_loose_match(const struct cls_rule *rule,
                              const struct minimatch *criteria);
-bool cls_rule_visible_in_version(const struct cls_rule *, long long version);
+bool cls_rule_visible_in_version(const struct cls_rule *, cls_version_t);
 void cls_rule_make_invisible_in_version(const struct cls_rule *,
-                                        long long version,
-                                        long long lookup_version);
+                                        cls_version_t);
 void cls_rule_restore_visibility(const struct cls_rule *);
 
 /* Constructor/destructor.  Must run single-threaded. */
@@ -409,7 +413,7 @@ static inline void classifier_publish(struct classifier *);
 /* Lookups.  These are RCU protected and may run concurrently with modifiers
  * and each other. */
 const struct cls_rule *classifier_lookup(const struct classifier *,
-                                         long long version, struct flow *,
+                                         cls_version_t, struct flow *,
                                          struct flow_wildcards *);
 bool classifier_rule_overlaps(const struct classifier *,
                               const struct cls_rule *);
@@ -418,7 +422,7 @@ const struct cls_rule *classifier_find_rule_exactly(const struct classifier *,
 const struct cls_rule *classifier_find_match_exactly(const struct classifier *,
                                                      const struct match *,
                                                      int priority,
-                                                     long long version);
+                                                     cls_version_t);
 bool classifier_is_empty(const struct classifier *);
 int classifier_count(const struct classifier *);
 
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 337d6f8..f5dc272 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -160,7 +160,7 @@ struct xlate_ctx {
     const struct xbridge *xbridge;
 
     /* Flow tables version at the beginning of the translation. */
-    long long tables_version;
+    cls_version_t tables_version;
 
     /* Flow at the last commit. */
     struct flow base_flow;
@@ -2777,7 +2777,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
         const struct xport *peer = xport->peer;
         struct flow old_flow = ctx->xin->flow;
         bool old_was_mpls = ctx->was_mpls;
-        long long old_version = ctx->tables_version;
+        cls_version_t old_version = ctx->tables_version;
         enum slow_path_reason special;
         struct ofpbuf old_stack = ctx->stack;
         union mf_subvalue new_stack[1024 / sizeof(union mf_subvalue)];
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 55fea0f..369e0b9 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -296,7 +296,7 @@ struct ofproto_dpif {
     struct ofproto up;
     struct dpif_backer *backer;
 
-    atomic_llong tables_version;  /* Version # to use in classifier lookups. */
+    ATOMIC(cls_version_t) tables_version;  /* For classifier lookups. */
 
     uint64_t dump_seq; /* Last read of udpif_dump_seq(). */
 
@@ -1618,7 +1618,7 @@ query_tables(struct ofproto *ofproto,
 }
 
 static void
-set_tables_version(struct ofproto *ofproto_, long long version)
+set_tables_version(struct ofproto *ofproto_, cls_version_t version)
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
 
@@ -3734,10 +3734,10 @@ rule_set_recirc_id(struct rule *rule_, uint32_t id)
     ovs_mutex_unlock(&rule->up.mutex);
 }
 
-long long
+cls_version_t
 ofproto_dpif_get_tables_version(struct ofproto_dpif *ofproto OVS_UNUSED)
 {
-    long long version;
+    cls_version_t version;
 
     atomic_read_relaxed(&ofproto->tables_version, &version);
 
@@ -3751,7 +3751,7 @@ ofproto_dpif_get_tables_version(struct ofproto_dpif *ofproto OVS_UNUSED)
  * 'flow' is non-const to allow for temporary modifications during the lookup.
  * Any changes are restored before returning. */
 static struct rule_dpif *
-rule_dpif_lookup_in_table(struct ofproto_dpif *ofproto, long long version,
+rule_dpif_lookup_in_table(struct ofproto_dpif *ofproto, cls_version_t version,
                           uint8_t table_id, struct flow *flow,
                           struct flow_wildcards *wc, bool take_ref)
 {
@@ -3797,9 +3797,10 @@ rule_dpif_lookup_in_table(struct ofproto_dpif *ofproto, long long version,
  * 'flow' is non-const to allow for temporary modifications during the lookup.
  * Any changes are restored before returning. */
 struct rule_dpif *
-rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto, long long version,
-                            struct flow *flow, struct flow_wildcards *wc,
-                            bool take_ref, const struct dpif_flow_stats *stats,
+rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto,
+                            cls_version_t version, struct flow *flow,
+                            struct flow_wildcards *wc, bool take_ref,
+                            const struct dpif_flow_stats *stats,
                             uint8_t *table_id, ofp_port_t in_port,
                             bool may_packet_in, bool honor_table_miss)
 {
diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h
index aaaf671..bb6df5e 100644
--- a/ofproto/ofproto-dpif.h
+++ b/ofproto/ofproto-dpif.h
@@ -102,11 +102,10 @@ size_t ofproto_dpif_get_max_mpls_depth(const struct ofproto_dpif *);
 bool ofproto_dpif_get_enable_recirc(const struct ofproto_dpif *);
 bool ofproto_dpif_get_enable_ufid(struct dpif_backer *backer);
 
-long long ofproto_dpif_get_tables_version(struct ofproto_dpif *);
+cls_version_t ofproto_dpif_get_tables_version(struct ofproto_dpif *);
 
 struct rule_dpif *rule_dpif_lookup_from_table(struct ofproto_dpif *,
-                                              long long version,
-                                              struct flow *,
+                                              cls_version_t, struct flow *,
                                               struct flow_wildcards *,
                                               bool take_ref,
                                               const struct dpif_flow_stats *,
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index fd66e49..f248f59 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -93,8 +93,8 @@ struct ofproto {
     long long int eviction_group_timer; /* For rate limited reheapification. */
     struct oftable *tables;
     int n_tables;
-    long long tables_version;   /* Controls which rules are visible to
-                                 * table lookups. */
+    cls_version_t tables_version;   /* Controls which rules are visible to
+                                     * table lookups. */
 
     /* Rules indexed on their cookie values, in all flow tables. */
     struct hindex cookies OVS_GUARDED_BY(ofproto_mutex);
@@ -843,8 +843,7 @@ struct ofproto_class {
 
     /* Sets the current tables version the provider should use for classifier
      * lookups. */
-    void (*set_tables_version)(struct ofproto *ofproto,
-                               long long version);
+    void (*set_tables_version)(struct ofproto *ofproto, cls_version_t version);
 /* ## ---------------- ## */
 /* ## ofport Functions ## */
 /* ## ---------------- ## */
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index cb8a941..2e14e8c 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -150,7 +150,7 @@ struct rule_criteria {
 
 static void rule_criteria_init(struct rule_criteria *, uint8_t table_id,
                                const struct match *match, int priority,
-                               long long version,
+                               cls_version_t version,
                                ovs_be64 cookie, ovs_be64 cookie_mask,
                                ofp_port_t out_port, uint32_t out_group);
 static void rule_criteria_require_rw(struct rule_criteria *,
@@ -3725,9 +3725,10 @@ next_matching_table(const struct ofproto *ofproto,
  * supplied as 0. */
 static void
 rule_criteria_init(struct rule_criteria *criteria, uint8_t table_id,
-                   const struct match *match, int priority, long long version,
-                   ovs_be64 cookie, ovs_be64 cookie_mask,
-                   ofp_port_t out_port, uint32_t out_group)
+                   const struct match *match, int priority,
+                   cls_version_t version, ovs_be64 cookie,
+                   ovs_be64 cookie_mask, ofp_port_t out_port,
+                   uint32_t out_group)
 {
     criteria->table_id = table_id;
     cls_rule_init(&criteria->cr, match, priority, version);
@@ -4664,8 +4665,7 @@ replace_rule_start(struct ofproto *ofproto,
     if (old_rule) {
         /* Mark the old rule for removal in the next version. */
         cls_rule_make_invisible_in_version(&old_rule->cr,
-                                           ofproto->tables_version + 1,
-                                           ofproto->tables_version);
+                                           ofproto->tables_version + 1);
     } else {
         table->n_flows++;
     }
@@ -4943,8 +4943,7 @@ delete_flows_start__(struct ofproto *ofproto,
 
         table->n_flows--;
         cls_rule_make_invisible_in_version(&rule->cr,
-                                           ofproto->tables_version + 1,
-                                           ofproto->tables_version);
+                                           ofproto->tables_version + 1);
     }
 }
 
diff --git a/tests/test-classifier.c b/tests/test-classifier.c
index 9e837c3..2fe9a5d 100644
--- a/tests/test-classifier.c
+++ b/tests/test-classifier.c
@@ -975,7 +975,8 @@ test_many_rules_in_one_list (struct ovs_cmdl_context *ctx OVS_UNUSED)
                     tcls_rules[j] = tcls_insert(&tcls, rules[j]);
                     if (versioned) {
                         /* Insert the new rule in the next version. */
-                        *CONST_CAST(long long *, &rules[j]->cls_rule.version)
+                        *CONST_CAST(cls_version_t *,
+                                    &rules[j]->cls_rule.version)
                             = ++version;
 
                         displaced_rule = test_rule_from_cls_rule(
@@ -985,8 +986,7 @@ test_many_rules_in_one_list (struct ovs_cmdl_context *ctx OVS_UNUSED)
                             /* Mark the old rule for removal after the current
                              * version. */
                             cls_rule_make_invisible_in_version(
-                                &displaced_rule->cls_rule, version,
-                                version - 1);
+                                &displaced_rule->cls_rule, version);
                             n_invisible_rules++;
                             removable_rule = &displaced_rule->cls_rule;
                         }
@@ -1011,7 +1011,7 @@ test_many_rules_in_one_list (struct ovs_cmdl_context *ctx OVS_UNUSED)
                         /* Mark the rule for removal after the current
                          * version. */
                         cls_rule_make_invisible_in_version(
-                            &rules[j]->cls_rule, version + 1, version);
+                            &rules[j]->cls_rule, version + 1);
                         ++version;
                         n_invisible_rules++;
                         removable_rule = &rules[j]->cls_rule;
@@ -1131,7 +1131,7 @@ test_many_rules_in_one_table(struct ovs_cmdl_context *ctx OVS_UNUSED)
             if (versioned) {
                 /* Mark the rule for removal after the current version. */
                 cls_rule_make_invisible_in_version(&rules[i]->cls_rule,
-                                                   version + 1, version);
+                                                   version + 1);
                 ++version;
                 n_invisible_rules++;
             } else {
@@ -1219,7 +1219,7 @@ test_many_rules_in_n_tables(int n_tables)
                 if (versioned) {
                     /* Mark the rule for removal after the current version. */
                     cls_rule_make_invisible_in_version(&rule->cls_rule,
-                                                       version + 1, version);
+                                                       version + 1);
                     n_removable_rules++;
                     compare_classifiers(&cls, n_invisible_rules, version,
                                         &tcls);
-- 
1.7.10.4




More information about the dev mailing list