[ovs-dev] [PATCH v6 2/6] ofproto-dpif: Add recirc_id field to struct rule_dpif

Simon Horman horms at verge.net.au
Tue May 20 09:24:17 UTC 2014


This is to allow a recirculation id to be associated with a rule
in the case that its actions cause recirculation.

In such a case if the recirc_id field is non-zero then that value should be
used, otherwise a value should be obtained using
ofproto_dpif_alloc_recirc_id and saved in recirc_id field.

When destructing the rule if the recirc_id field is non-zero then
the associated internal flow should be deleted.

This is in preparation for using the same helper as part of support
for using recirculation in conjunction series of actions including
with MPLS actions that are currently not able to be translated.

Signed-off-by: Simon Horman <horms at verge.net.au>

---
v5
* Rebase

v4
* No change

v3
* Rebase
* Add rule_set_recirc_id()

v2
* No change
---
 ofproto/ofproto-dpif.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 ofproto/ofproto-dpif.h |  2 ++
 2 files changed, 49 insertions(+)

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 0d16295..e7f0ff3 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -87,6 +87,12 @@ struct rule_dpif {
      *   recently been processed by a revalidator. */
     struct ovs_mutex stats_mutex;
     struct dpif_flow_stats stats OVS_GUARDED;
+
+    /* If non-zero then the recirculation id that has
+     * been allocated for use with this rule.
+     * The recirculation id and associated internal flow should
+     * be freed when the rule is freed */
+    uint32_t recirc_id;
 };
 
 /* RULE_CAST() depends on this. */
@@ -3189,6 +3195,39 @@ rule_dpif_get_actions(const struct rule_dpif *rule)
     return rule_get_actions(&rule->up);
 }
 
+/* Sets 'rule''s recirculation id. */
+static void
+rule_dpif_set_recirc_id(struct rule_dpif *rule, uint32_t id)
+    OVS_REQUIRES(rule->up.mutex)
+{
+    ovs_assert(!rule->recirc_id);
+    rule->recirc_id = id;
+}
+
+/* Returns 'rule''s recirculation id. */
+uint32_t
+rule_dpif_get_recirc_id(struct rule_dpif *rule)
+    OVS_REQUIRES(rule->up.mutex)
+{
+    if (!rule->recirc_id) {
+        struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->up.ofproto);
+
+        rule_dpif_set_recirc_id(rule, ofproto_dpif_alloc_recirc_id(ofproto));
+    }
+    return rule->recirc_id;
+}
+
+/* Sets 'rule''s recirculation id. */
+void
+rule_set_recirc_id(struct rule *rule_, uint32_t id)
+{
+    struct rule_dpif *rule = rule_dpif_cast(rule_);
+
+    ovs_mutex_lock(&rule->up.mutex);
+    rule_dpif_set_recirc_id(rule, id);
+    ovs_mutex_unlock(&rule->up.mutex);
+}
+
 /* Lookup 'flow' in table 0 of 'ofproto''s classifier.
  * If 'wc' is non-null, sets the fields that were relevant as part of
  * the lookup. Returns the table_id where a match or miss occurred.
@@ -3445,6 +3484,8 @@ rule_construct(struct rule *rule_)
     rule->stats.n_packets = 0;
     rule->stats.n_bytes = 0;
     rule->stats.used = rule->up.modified;
+    rule->recirc_id = 0;
+
     return 0;
 }
 
@@ -3468,7 +3509,13 @@ static void
 rule_destruct(struct rule *rule_)
 {
     struct rule_dpif *rule = rule_dpif_cast(rule_);
+
     ovs_mutex_destroy(&rule->stats_mutex);
+    if (rule->recirc_id) {
+        struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->up.ofproto);
+
+        ofproto_dpif_free_recirc_id(ofproto, rule->recirc_id);
+    }
 }
 
 static void
diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h
index 7d16056..ed4f547 100644
--- a/ofproto/ofproto-dpif.h
+++ b/ofproto/ofproto-dpif.h
@@ -117,6 +117,8 @@ uint8_t rule_dpif_get_table(const struct rule_dpif *);
 bool table_is_internal(uint8_t table_id);
 
 const struct rule_actions *rule_dpif_get_actions(const struct rule_dpif *);
+uint32_t rule_dpif_get_recirc_id(struct rule_dpif *);
+void rule_set_recirc_id(struct rule *, uint32_t id);
 
 ovs_be64 rule_dpif_get_flow_cookie(const struct rule_dpif *rule);
 
-- 
1.8.4




More information about the dev mailing list