diff mbox series

[ovs-dev,v6,1/2] ovn-controller: Fix releasing wrong vif

Message ID 20221121124046.3980712-2-xsimonar@redhat.com
State Accepted
Headers show
Series ovn-controller: Multiple OVS interfaces bound to same lport | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/github-robot-_ovn-kubernetes fail github build: failed

Commit Message

Xavier Simonart Nov. 21, 2022, 12:40 p.m. UTC
When binding an OVS interface to a logical port, if external_ids:iface-id is
set within the same transaction as adding the interface to a bridge,
ovn-controller is usually initially notified of ovs interface change with
ofport == 0.
If the lport was already bound to a different interface, the ofport=0
notification caused an unexpected release of the interface.

Signed-off-by: Xavier Simonart <xsimonar@redhat.com>
---
 controller/binding.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

Comments

Han Zhou Nov. 22, 2022, 7:35 a.m. UTC | #1
On Mon, Nov 21, 2022 at 4:40 AM Xavier Simonart <xsimonar@redhat.com> wrote:
>
> When binding an OVS interface to a logical port, if external_ids:iface-id
is
> set within the same transaction as adding the interface to a bridge,
> ovn-controller is usually initially notified of ovs interface change with
> ofport == 0.
> If the lport was already bound to a different interface, the ofport=0
> notification caused an unexpected release of the interface.
>
> Signed-off-by: Xavier Simonart <xsimonar@redhat.com>
> ---
>  controller/binding.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>
> diff --git a/controller/binding.c b/controller/binding.c
> index a50379895..db1eb7a40 100644
> --- a/controller/binding.c
> +++ b/controller/binding.c
> @@ -2233,6 +2233,23 @@ consider_iface_release(const struct
ovsrec_interface *iface_rec,
>      struct shash *binding_lports = &b_ctx_out->lbinding_data->lports;
>
>      lbinding = local_binding_find(local_bindings, iface_id);
> +
> +   if (lbinding) {
> +        int64_t ofport = iface_rec->n_ofport ? *iface_rec->ofport : 0;
> +        if (lbinding->iface != iface_rec && !ofport) {
> +            /* If external_ids:iface-id is set within the same
transaction
> +             * as adding an interface to a bridge, ovn-controller is
> +             * usually initially notified of ovs interface changes with
> +             * ofport == 0. If the lport was bound to a different
interface
> +             * we do not want to release it.
> +             */
> +            VLOG_DBG("Not releasing lport %s as %s was claimed "
> +                     "and %s was never bound)", iface_id,
lbinding->iface ?
> +                     lbinding->iface->name : "", iface_rec->name);
> +            return true;
> +        }
> +    }
> +
>      struct binding_lport *b_lport =
>          local_binding_get_primary_or_localport_lport(lbinding);
>      if (is_binding_lport_this_chassis(b_lport, b_ctx_in->chassis_rec)) {
> --
> 2.31.1
>

Acked-by: Han Zhou <hzhou@ovn.org>
diff mbox series

Patch

diff --git a/controller/binding.c b/controller/binding.c
index a50379895..db1eb7a40 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -2233,6 +2233,23 @@  consider_iface_release(const struct ovsrec_interface *iface_rec,
     struct shash *binding_lports = &b_ctx_out->lbinding_data->lports;
 
     lbinding = local_binding_find(local_bindings, iface_id);
+
+   if (lbinding) {
+        int64_t ofport = iface_rec->n_ofport ? *iface_rec->ofport : 0;
+        if (lbinding->iface != iface_rec && !ofport) {
+            /* If external_ids:iface-id is set within the same transaction
+             * as adding an interface to a bridge, ovn-controller is
+             * usually initially notified of ovs interface changes with
+             * ofport == 0. If the lport was bound to a different interface
+             * we do not want to release it.
+             */
+            VLOG_DBG("Not releasing lport %s as %s was claimed "
+                     "and %s was never bound)", iface_id, lbinding->iface ?
+                     lbinding->iface->name : "", iface_rec->name);
+            return true;
+        }
+    }
+
     struct binding_lport *b_lport =
         local_binding_get_primary_or_localport_lport(lbinding);
     if (is_binding_lport_this_chassis(b_lport, b_ctx_in->chassis_rec)) {