5f9769
From 44955fb2395677c9d9bb1afa3985b24317c84431 Mon Sep 17 00:00:00 2001
5f9769
From: Dumitru Ceara <dceara@redhat.com>
5f9769
Date: Mon, 18 Jan 2021 17:50:23 +0100
5f9769
Subject: [PATCH 1/2] binding: Fix container port removal from local bindings.
5f9769
5f9769
When the Port_Binding associated to a container port is removed make
5f9769
sure we also remove it from the parent's 'children' shash.  Container
5f9769
ports don't have any VIFs associated so it's safe to destroy the
5f9769
container port local binding when the SB.Port_Binding is deleted.
5f9769
5f9769
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
5f9769
Signed-off-by: Numan Siddique <numans@ovn.org>
5f9769
(cherry picked from master commit 68cf9fdceba80ce0c03e3ddb3e0a5531f248fa04)
5f9769
5f9769
Change-Id: I65f4bd461f3f94ca90dbcc0646c0037c301c71a1
5f9769
---
5f9769
 controller/binding.c | 18 +++++++++++++++++-
5f9769
 controller/binding.h |  1 +
5f9769
 tests/ovn.at         | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
5f9769
 3 files changed, 71 insertions(+), 1 deletion(-)
5f9769
5f9769
diff --git a/controller/binding.c b/controller/binding.c
5f9769
index e632203..3512a1d 100644
5f9769
--- a/controller/binding.c
5f9769
+++ b/controller/binding.c
5f9769
@@ -688,6 +688,7 @@ local_binding_add_child(struct local_binding *lbinding,
5f9769
                         struct local_binding *child)
5f9769
 {
5f9769
     local_binding_add(&lbinding->children, child);
5f9769
+    child->parent = lbinding;
5f9769
 }
5f9769
 
5f9769
 static struct local_binding *
5f9769
@@ -697,6 +698,13 @@ local_binding_find_child(struct local_binding *lbinding,
5f9769
     return local_binding_find(&lbinding->children, child_name);
5f9769
 }
5f9769
 
5f9769
+static void
5f9769
+local_binding_delete_child(struct local_binding *lbinding,
5f9769
+                           struct local_binding *child)
5f9769
+{
5f9769
+    shash_find_and_delete(&lbinding->children, child->name);
5f9769
+}
5f9769
+
5f9769
 static bool
5f9769
 is_lport_vif(const struct sbrec_port_binding *pb)
5f9769
 {
5f9769
@@ -2062,6 +2070,14 @@ handle_deleted_vif_lport(const struct sbrec_port_binding *pb,
5f9769
      * when the interface change happens. */
5f9769
     if (is_lport_container(pb)) {
5f9769
         remove_local_lports(pb->logical_port, b_ctx_out);
5f9769
+
5f9769
+        /* If the container port is removed we should also remove it from
5f9769
+         * its parent's children set.
5f9769
+         */
5f9769
+        if (lbinding->parent) {
5f9769
+            local_binding_delete_child(lbinding->parent, lbinding);
5f9769
+        }
5f9769
+        local_binding_destroy(lbinding);
5f9769
     }
5f9769
 
5f9769
     handle_deleted_lport(pb, b_ctx_in, b_ctx_out);
5f9769
@@ -2147,7 +2163,7 @@ binding_handle_port_binding_changes(struct binding_ctx_in *b_ctx_in,
5f9769
         enum en_lport_type lport_type = get_lport_type(pb);
5f9769
         if (lport_type == LP_VIF || lport_type == LP_VIRTUAL) {
5f9769
             handled = handle_deleted_vif_lport(pb, lport_type, b_ctx_in,
5f9769
-                                                b_ctx_out);
5f9769
+                                               b_ctx_out);
5f9769
         } else {
5f9769
             handle_deleted_lport(pb, b_ctx_in, b_ctx_out);
5f9769
         }
5f9769
diff --git a/controller/binding.h b/controller/binding.h
5f9769
index c974056..2885971 100644
5f9769
--- a/controller/binding.h
5f9769
+++ b/controller/binding.h
5f9769
@@ -100,6 +100,7 @@ struct local_binding {
5f9769
 
5f9769
     /* shash of 'struct local_binding' representing children. */
5f9769
     struct shash children;
5f9769
+    struct local_binding *parent;
5f9769
 };
5f9769
 
5f9769
 static inline struct local_binding *
5f9769
diff --git a/tests/ovn.at b/tests/ovn.at
5f9769
index 27cb2e4..2cdc036 100644
5f9769
--- a/tests/ovn.at
5f9769
+++ b/tests/ovn.at
5f9769
@@ -22144,6 +22144,59 @@ AT_CHECK_UNQUOTED([grep -c "output:4" offlows_table65_2.txt], [0], [dnl
5f9769
 OVN_CLEANUP([hv1])
5f9769
 AT_CLEANUP
5f9769
 
5f9769
+AT_SETUP([ovn -- Container port Incremental Processing])
5f9769
+ovn_start
5f9769
+
5f9769
+net_add n1
5f9769
+sim_add hv1
5f9769
+as hv1
5f9769
+ovs-vsctl add-br br-phys
5f9769
+ovn_attach n1 br-phys 192.168.0.10
5f9769
+
5f9769
+as hv1
5f9769
+ovs-vsctl \
5f9769
+    -- add-port br-int vif1 \
5f9769
+    -- set Interface vif1 external_ids:iface-id=lsp1 \
5f9769
+    ofport-request=1
5f9769
+
5f9769
+check ovn-nbctl ls-add ls1 \
5f9769
+    -- ls-add ls2 \
5f9769
+    -- lsp-add ls1 lsp1 \
5f9769
+    -- lsp-add ls2 lsp-cont1 lsp1 1
5f9769
+check ovn-nbctl --wait=hv sync
5f9769
+
5f9769
+# Wait for ports to be bound.
5f9769
+wait_row_count Chassis 1 name=hv1
5f9769
+ch=$(fetch_column Chassis _uuid name=hv1)
5f9769
+wait_row_count Port_Binding 1 logical_port=lsp1 chassis=$ch
5f9769
+wait_row_count Port_Binding 1 logical_port=lsp-cont1 chassis=$ch
5f9769
+
5f9769
+AS_BOX([delete OVS VIF and OVN container port])
5f9769
+as hv1 ovn-appctl -t ovn-controller debug/pause
5f9769
+as hv1 ovs-vsctl del-port vif1
5f9769
+
5f9769
+check ovn-nbctl --wait=sb lsp-del lsp-cont1
5f9769
+as hv1 ovn-appctl -t ovn-controller debug/resume
5f9769
+
5f9769
+check ovn-nbctl --wait=hv sync
5f9769
+check_row_count Port_Binding 1 logical_port=lsp1 chassis="[[]]"
5f9769
+
5f9769
+AS_BOX([readd OVS VIF])
5f9769
+as hv1
5f9769
+ovs-vsctl \
5f9769
+    -- add-port br-int vif1 \
5f9769
+    -- set Interface vif1 external_ids:iface-id=lsp1 \
5f9769
+    ofport-request=1
5f9769
+wait_row_count Port_Binding 1 logical_port=lsp1 chassis=$ch
5f9769
+
5f9769
+AS_BOX([readd OVN container port])
5f9769
+check ovn-nbctl lsp-add ls2 lsp-cont1 lsp1 1
5f9769
+check ovn-nbctl --wait=hv sync
5f9769
+check_row_count Port_Binding 1 logical_port=lsp-cont1 chassis=$ch
5f9769
+
5f9769
+OVN_CLEANUP([hv1])
5f9769
+AT_CLEANUP
5f9769
+
5f9769
 # Test dropping traffic destined to router owned IPs.
5f9769
 AT_SETUP([ovn -- gateway router drop traffic for own IPs])
5f9769
 ovn_start
5f9769
-- 
5f9769
1.8.3.1
5f9769