Introduce pending_id map used to store meter_id allocated but not yet
inserted in the desired_table. This is a preliminary patch to add
metering IP engine.

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
 controller/ofctrl.c |  9 +++++
 controller/ofctrl.h |  1 +
 lib/extend-table.c  | 82 +++++++++++++++++++++++++++++++++------------
 lib/extend-table.h  |  7 ++++
 4 files changed, 78 insertions(+), 21 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 08fcfed8b..bf715787e 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -1801,6 +1801,15 @@ add_meter_string(struct ovn_extend_table_info *m_desired,
     free(meter_string);
 }
 
+uint32_t ofctrl_get_meter_id(const char *name, bool new_id)
+{
+    uint32_t id;
+    bool val;
+
+    ovn_extend_table_get_id(meters, name, &id, NULL, &val, new_id);
+    return id;
+}
+
 static void
 add_meter(struct ovn_extend_table_info *m_desired,
           const struct sbrec_meter_table *meter_table,
diff --git a/controller/ofctrl.h b/controller/ofctrl.h
index 014de210d..0efcb2ef5 100644
--- a/controller/ofctrl.h
+++ b/controller/ofctrl.h
@@ -129,5 +129,6 @@ void ofctrl_check_and_add_flow_metered(struct 
ovn_desired_flow_table *,
 bool ofctrl_is_connected(void);
 void ofctrl_set_probe_interval(int probe_interval);
 void ofctrl_get_memory_usage(struct simap *usage);
+uint32_t ofctrl_get_meter_id(const char *name, bool new_id);
 
 #endif /* controller/ofctrl.h */
diff --git a/lib/extend-table.c b/lib/extend-table.c
index c708e24b9..52c8cd62e 100644
--- a/lib/extend-table.c
+++ b/lib/extend-table.c
@@ -37,6 +37,7 @@ ovn_extend_table_init(struct ovn_extend_table *table)
     hmap_init(&table->desired);
     hmap_init(&table->lflow_to_desired);
     hmap_init(&table->existing);
+    shash_init(&table->pending_ids);
 }
 
 static struct ovn_extend_table_info *
@@ -191,6 +192,14 @@ ovn_extend_table_clear(struct ovn_extend_table *table, 
bool existing)
         }
         ovn_extend_table_info_destroy(g);
     }
+
+    struct shash_node *node, *tmp;
+    SHASH_FOR_EACH_SAFE (node, tmp, &table->pending_ids) {
+        uint32_t *id = node->data;
+        shash_delete(&table->pending_ids, node);
+        free(id);
+    }
+    shash_destroy(&table->pending_ids);
 }
 
 void
@@ -282,54 +291,85 @@ ovn_extend_table_sync(struct ovn_extend_table *table)
     }
 }
 
-/* Assign a new table ID for the table information from the bitmap.
- * If it already exists, return the old ID. */
-uint32_t
-ovn_extend_table_assign_id(struct ovn_extend_table *table, const char *name,
-                           struct uuid lflow_uuid)
+bool
+ovn_extend_table_get_id(struct ovn_extend_table *table, const char *name,
+                        uint32_t *meter_id, struct uuid *lflow_uuid,
+                        bool *new_id, bool pending)
 {
-    uint32_t table_id = 0, hash;
     struct ovn_extend_table_info *table_info;
-
-    hash = hash_string(name, 0);
+    uint32_t hash = hash_string(name, 0);
 
     /* Check whether we have non installed but allocated group_id. */
     HMAP_FOR_EACH_WITH_HASH (table_info, hmap_node, hash, &table->desired) {
         if (!strcmp(table_info->name, name)) {
             VLOG_DBG("ovn_externd_table_assign_id: reuse old id %"PRIu32
-                     " for %s, used by lflow "UUID_FMT,
-                     table_info->table_id, table_info->name,
-                     UUID_ARGS(&lflow_uuid));
-            ovn_extend_info_add_lflow_ref(table, table_info, &lflow_uuid);
-            return table_info->table_id;
+                     " for %s", table_info->table_id, table_info->name);
+            if (lflow_uuid) {
+                ovn_extend_info_add_lflow_ref(table, table_info, lflow_uuid);
+            }
+            *meter_id = table_info->table_id;
+            return false;
         }
     }
 
+    *new_id = false;
     /* Check whether we already have an installed entry for this
      * combination. */
     HMAP_FOR_EACH_WITH_HASH (table_info, hmap_node, hash, &table->existing) {
         if (!strcmp(table_info->name, name)) {
-            table_id = table_info->table_id;
+            *meter_id = table_info->table_id;
+            return true;
         }
     }
 
-    bool new_table_id = false;
-    if (!table_id) {
-        /* Reserve a new group_id. */
-        table_id = bitmap_scan(table->table_ids, 0, 1, MAX_EXT_TABLE_ID + 1);
-        new_table_id = true;
+    /* Check if a ids has been already allocated for this flow. */
+    uint32_t *id = shash_find_and_delete(&table->pending_ids, name);
+    if (id) {
+        *meter_id = *id;
+        free(id);
+        return true;
     }
 
+    /* Reserve a new group_id. */
+    uint32_t table_id = bitmap_scan(table->table_ids, 0, 1,
+                                    MAX_EXT_TABLE_ID + 1);
     if (table_id == MAX_EXT_TABLE_ID + 1) {
         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
         VLOG_ERR_RL(&rl, "%"PRIu32" out of table ids.", table_id);
-        return EXT_TABLE_ID_INVALID;
+        *meter_id = EXT_TABLE_ID_INVALID;
+        return false;
     }
     bitmap_set1(table->table_ids, table_id);
+    *meter_id = table_id;
+
+    *new_id = true;
+    if (pending) {
+        /* Add the id to pedning map. */
+        id = xmalloc(sizeof *id);
+        *id = table_id;
+        shash_add(&table->pending_ids, name, id);
+    }
+
+    return true;
+}
+
+/* Assign a new table ID for the table information from the bitmap.
+ * If it already exists, return the old ID. */
+uint32_t
+ovn_extend_table_assign_id(struct ovn_extend_table *table, const char *name,
+                           struct uuid lflow_uuid)
+{
+    uint32_t table_id, hash = hash_string(name, 0);
+    struct ovn_extend_table_info *table_info;
+    bool new_table_id;
+
+    if (!ovn_extend_table_get_id(table, name, &table_id,
+                                 &lflow_uuid, &new_table_id, false)) {
+        return table_id;
+    }
 
     table_info = ovn_extend_table_info_alloc(name, table_id, new_table_id,
                                              hash);
-
     hmap_insert(&table->desired,
                 &table_info->hmap_node, table_info->hmap_node.hash);
 
diff --git a/lib/extend-table.h b/lib/extend-table.h
index 4d80cfd80..5c5f65695 100644
--- a/lib/extend-table.h
+++ b/lib/extend-table.h
@@ -21,6 +21,7 @@
 #define EXT_TABLE_ID_INVALID 0
 
 #include "openvswitch/hmap.h"
+#include "openvswitch/shash.h"
 #include "openvswitch/list.h"
 #include "openvswitch/uuid.h"
 
@@ -30,6 +31,8 @@ struct ovn_extend_table {
     unsigned long *table_ids;  /* Used as a bitmap with value set
                                 * for allocated group ids in either
                                 * desired or existing. */
+    struct shash pending_ids;
+
     struct hmap desired;
     struct hmap lflow_to_desired; /* Index for looking up desired table
                                    * items from given lflow uuid, with
@@ -93,6 +96,10 @@ void ovn_extend_table_sync(struct ovn_extend_table *);
 uint32_t ovn_extend_table_assign_id(struct ovn_extend_table *,
                                     const char *name,
                                     struct uuid lflow_uuid);
+bool
+ovn_extend_table_get_id(struct ovn_extend_table *table, const char *name,
+                        uint32_t *meter_id, struct uuid *lflow_uuid,
+                        bool *new_id, bool pending);
 
 /* Iterates 'DESIRED' through all of the 'ovn_extend_table_info's in
  * 'TABLE'->desired that are not in 'TABLE'->existing.  (The loop body
-- 
2.34.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to