ebb439
From a0828524dcc90169dc1dde36f1306d6f1921ea85 Mon Sep 17 00:00:00 2001
ebb439
From: Dumitru Ceara <dceara@redhat.com>
ebb439
Date: Sun, 11 Oct 2020 14:05:45 +0200
ebb439
Subject: [PATCH 4/7] ofctrl.c: Do not change flow ordering when merging
ebb439
 opposite changes.
ebb439
ebb439
Instead of removing the old desired flow from the list and inserting the new
ebb439
one at the end we now directly replace the old flow with the new one while
ebb439
maintaining the same ordering.
ebb439
ebb439
For now order of the flows is not relevant but further commits require
ebb439
maintaining the order of desired flows.
ebb439
ebb439
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
ebb439
Signed-off-by: Han Zhou <hzhou@ovn.org>
ebb439
(cherry picked from upstream commit e49ce9a33f38f29c44e3c30afcc189b5f6a9ef8e)
ebb439
ebb439
Change-Id: I83e64763ed63cbc44def69d9ea23259e2035f518
ebb439
---
ebb439
 controller/ofctrl.c | 28 +++++++++++++++++++++-------
ebb439
 1 file changed, 21 insertions(+), 7 deletions(-)
ebb439
ebb439
diff --git a/controller/ofctrl.c b/controller/ofctrl.c
ebb439
index 24b55fc..20cf3ac 100644
ebb439
--- a/controller/ofctrl.c
ebb439
+++ b/controller/ofctrl.c
ebb439
@@ -848,6 +848,26 @@ link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
ebb439
     d->installed_flow = i;
ebb439
 }
ebb439
 
ebb439
+/* Replaces 'old_desired' with 'new_desired' in the list of desired flows
ebb439
+ * that have same match conditions as the installed flow.
ebb439
+ *
ebb439
+ * If 'old_desired' was the active flow, 'new_desired' becomes the active one.
ebb439
+ */
ebb439
+static void
ebb439
+replace_installed_to_desired(struct installed_flow *i,
ebb439
+                             struct desired_flow *old_desired,
ebb439
+                             struct desired_flow *new_desired)
ebb439
+{
ebb439
+    ovs_assert(old_desired->installed_flow == i);
ebb439
+    ovs_list_replace(&new_desired->installed_ref_list_node,
ebb439
+                     &old_desired->installed_ref_list_node);
ebb439
+    old_desired->installed_flow = NULL;
ebb439
+    new_desired->installed_flow = i;
ebb439
+    if (i->desired_flow == old_desired) {
ebb439
+        i->desired_flow = new_desired;
ebb439
+    }
ebb439
+}
ebb439
+
ebb439
 static void
ebb439
 unlink_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
ebb439
 {
ebb439
@@ -1842,21 +1862,15 @@ merge_tracked_flows(struct ovn_desired_flow_table *flow_table)
ebb439
              * removed during track_flow_add_or_modify. */
ebb439
             ovs_assert(del_f->installed_flow);
ebb439
 
ebb439
-            bool del_f_was_active = desired_flow_is_active(del_f);
ebb439
             if (!f->installed_flow) {
ebb439
                 /* f is not installed yet. */
ebb439
-                struct installed_flow *i = del_f->installed_flow;
ebb439
-                unlink_installed_to_desired(i, del_f);
ebb439
-                link_installed_to_desired(i, f);
ebb439
+                replace_installed_to_desired(del_f->installed_flow, del_f, f);
ebb439
             } else {
ebb439
                 /* f has been installed before, and now was updated to exact
ebb439
                  * the same flow as del_f. */
ebb439
                 ovs_assert(f->installed_flow == del_f->installed_flow);
ebb439
                 unlink_installed_to_desired(del_f->installed_flow, del_f);
ebb439
             }
ebb439
-            if (del_f_was_active) {
ebb439
-                desired_flow_set_active(f);
ebb439
-            }
ebb439
             hmap_remove(&deleted_flows, &del_f->match_hmap_node);
ebb439
             ovs_list_remove(&del_f->track_list_node);
ebb439
             desired_flow_destroy(del_f);
ebb439
-- 
ebb439
1.8.3.1
ebb439