diff mbox series

[ovs-dev,v3] controller/binding: prevent claiming container lport to ovs bridge

Message ID 20220427123834.2693431-1-mheib@redhat.com
State Superseded
Headers show
Series [ovs-dev,v3] controller/binding: prevent claiming container lport to ovs bridge | 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

Mohammad Heib April 27, 2022, 12:38 p.m. UTC
currently ovn-controller allow users to claim lport of type container
to ovs bridge which is invalid use-case.

This patch will prevent such invalid use-cases by ignoring the claiming
requests for container lports and will throw a warning message to the
controller logs.

Signed-off-by: Mohammad Heib <mheib@redhat.com>
---
 controller/binding.c | 34 ++++++++++++++++++++++++++++++++++
 tests/ovn.at         | 11 +++++++++++
 2 files changed, 45 insertions(+)

Comments

Numan Siddique May 17, 2022, 4:13 p.m. UTC | #1
On Wed, Apr 27, 2022 at 8:39 AM Mohammad Heib <mheib@redhat.com> wrote:

> currently ovn-controller allow users to claim lport of type container
> to ovs bridge which is invalid use-case.
>
> This patch will prevent such invalid use-cases by ignoring the claiming
> requests for container lports and will throw a warning message to the
> controller logs.
>
> Signed-off-by: Mohammad Heib <mheib@redhat.com>
>

Hi Mohammad,

Thanks for v3.

Looks like we don't need this patch anymore after your patch -
https://github.com/ovn-org/ovn/commit/cd3b685043fa9758df3665bf3e3fc972048698a6

Also I do have a few concerns with this patch.
lport_lookup_by_name() will be called one extra time for every port binding
claim.  This could be expensive.
Presently when we have an ovs port with external_ids:iface-id set,  we
create a local_binding object for it.
And this patch now skips it.

Can you please test it out and see if the issue is still seen with the
present main branch ?

Thanks
Numan


---
>  controller/binding.c | 34 ++++++++++++++++++++++++++++++++++
>  tests/ovn.at         | 11 +++++++++++
>  2 files changed, 45 insertions(+)
>
> diff --git a/controller/binding.c b/controller/binding.c
> index 7281b0485..db0a6f118 100644
> --- a/controller/binding.c
> +++ b/controller/binding.c
> @@ -970,6 +970,32 @@ claim_lport(const struct sbrec_port_binding *pb,
>      return true;
>  }
>
> +/* Validate that "iface_rec:external_ids:iface-id" belongs to a lport
> + * that can be claimed to OVS bridge.
> + *
> + * If the lport type is LP_CONTAINER this function will throw a warning
> + * message to the logs and return "false".
> + *
> + * Otherwise, return "true".
> + */
> +static bool
> +valid_iface_claim(const char *iface_id,
> +                  struct binding_ctx_in *b_ctx_in)
> +{
> +    const struct sbrec_port_binding *pb = NULL;
> +    pb = lport_lookup_by_name(b_ctx_in->sbrec_port_binding_by_name,
> +                              iface_id);
> +    if (pb && (get_lport_type(pb) == LP_CONTAINER)) {
> +        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
> +        VLOG_WARN_RL(&rl, "Can't claim lport %s of type container to"
> +                     " OVS bridge,\nplease remove the lport parent_name"
> +                     " before claiming it.", pb->logical_port);
> +        return false;
> +    }
> +
> +    return true;
> +}
> +
>  /* Returns false if lport is not released due to 'sb_readonly'.
>   * Returns true otherwise.
>   *
> @@ -1497,6 +1523,10 @@ build_local_bindings(struct binding_ctx_in
> *b_ctx_in,
>                  struct local_binding *lbinding =
>                      local_binding_find(local_bindings, iface_id);
>                  if (!lbinding) {
> +                    if (!valid_iface_claim(iface_id, b_ctx_in)) {
> +                        continue;
> +                    }
> +
>                      lbinding = local_binding_create(iface_id, iface_rec);
>                      local_binding_add(local_bindings, lbinding);
>                  } else {
> @@ -2022,6 +2052,10 @@ binding_handle_ovs_interface_changes(struct
> binding_ctx_in *b_ctx_in,
>          int64_t ofport = iface_rec->n_ofport ? *iface_rec->ofport : 0;
>          if (iface_id && ofport > 0 &&
>                  is_iface_in_int_bridge(iface_rec, b_ctx_in->br_int)) {
> +            if (!valid_iface_claim(iface_id, b_ctx_in)) {
> +                continue;
> +            }
> +
>              handled = consider_iface_claim(iface_rec, iface_id, b_ctx_in,
>                                             b_ctx_out, qos_map_ptr);
>              if (!handled) {
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 34b6abfc0..bc59f3f13 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -28535,6 +28535,11 @@ check ovn-nbctl --wait=sb set logical_switch_port
> vm1 parent_name=vm-cont1
>
>  wait_for_ports_up
>
> +# Try to claim container port to ovs
> +check ovn-nbctl set logical_switch_port vm-cont2 parent_name=vm2
> +check as hv1 ovs-vsctl set Interface vm1 external_ids:iface-id=vm-cont2
> +AT_CHECK([test 1 = `cat hv1/ovn-controller.log |grep -c "claim lport
> vm-cont2 of type container"`])
> +
>  # Delete vm1, vm-cont1 and vm-cont2 and recreate again.
>  check ovn-nbctl lsp-del vm1
>  check ovn-nbctl lsp-del vm-cont1
> @@ -28546,6 +28551,12 @@ check ovn-nbctl lsp-add ls vm-cont1 vm1 1
>  check ovn-nbctl lsp-add ls vm-cont2 vm1 2
>
>  wait_for_ports_up
> +check as hv1 ovn-appctl -t ovn-controller debug/pause
> +# Try to claim container port to ovs with recompute
> +check ovn-nbctl set logical_switch_port vm-cont2 parent_name=vm2
> +check as hv1 ovs-vsctl set Interface vm1 external_ids:iface-id=vm-cont2
> +check as hv1 ovn-appctl -t ovn-controller debug/resume
> +AT_CHECK([test 1 = `cat hv1/ovn-controller.log |grep -c "claim lport
> vm-cont2 of type container"`])
>
>  # Make vm1 as a child port of some non existent lport - foo. vm1,
> vm1-cont1 and
>  # vm1-cont2 should be released.
> --
> 2.34.1
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
>
diff mbox series

Patch

diff --git a/controller/binding.c b/controller/binding.c
index 7281b0485..db0a6f118 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -970,6 +970,32 @@  claim_lport(const struct sbrec_port_binding *pb,
     return true;
 }
 
+/* Validate that "iface_rec:external_ids:iface-id" belongs to a lport
+ * that can be claimed to OVS bridge.
+ *
+ * If the lport type is LP_CONTAINER this function will throw a warning
+ * message to the logs and return "false".
+ *
+ * Otherwise, return "true".
+ */
+static bool
+valid_iface_claim(const char *iface_id,
+                  struct binding_ctx_in *b_ctx_in)
+{
+    const struct sbrec_port_binding *pb = NULL;
+    pb = lport_lookup_by_name(b_ctx_in->sbrec_port_binding_by_name,
+                              iface_id);
+    if (pb && (get_lport_type(pb) == LP_CONTAINER)) {
+        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
+        VLOG_WARN_RL(&rl, "Can't claim lport %s of type container to"
+                     " OVS bridge,\nplease remove the lport parent_name"
+                     " before claiming it.", pb->logical_port);
+        return false;
+    }
+
+    return true;
+}
+
 /* Returns false if lport is not released due to 'sb_readonly'.
  * Returns true otherwise.
  *
@@ -1497,6 +1523,10 @@  build_local_bindings(struct binding_ctx_in *b_ctx_in,
                 struct local_binding *lbinding =
                     local_binding_find(local_bindings, iface_id);
                 if (!lbinding) {
+                    if (!valid_iface_claim(iface_id, b_ctx_in)) {
+                        continue;
+                    }
+
                     lbinding = local_binding_create(iface_id, iface_rec);
                     local_binding_add(local_bindings, lbinding);
                 } else {
@@ -2022,6 +2052,10 @@  binding_handle_ovs_interface_changes(struct binding_ctx_in *b_ctx_in,
         int64_t ofport = iface_rec->n_ofport ? *iface_rec->ofport : 0;
         if (iface_id && ofport > 0 &&
                 is_iface_in_int_bridge(iface_rec, b_ctx_in->br_int)) {
+            if (!valid_iface_claim(iface_id, b_ctx_in)) {
+                continue;
+            }
+
             handled = consider_iface_claim(iface_rec, iface_id, b_ctx_in,
                                            b_ctx_out, qos_map_ptr);
             if (!handled) {
diff --git a/tests/ovn.at b/tests/ovn.at
index 34b6abfc0..bc59f3f13 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -28535,6 +28535,11 @@  check ovn-nbctl --wait=sb set logical_switch_port vm1 parent_name=vm-cont1
 
 wait_for_ports_up
 
+# Try to claim container port to ovs
+check ovn-nbctl set logical_switch_port vm-cont2 parent_name=vm2
+check as hv1 ovs-vsctl set Interface vm1 external_ids:iface-id=vm-cont2
+AT_CHECK([test 1 = `cat hv1/ovn-controller.log |grep -c "claim lport vm-cont2 of type container"`])
+
 # Delete vm1, vm-cont1 and vm-cont2 and recreate again.
 check ovn-nbctl lsp-del vm1
 check ovn-nbctl lsp-del vm-cont1
@@ -28546,6 +28551,12 @@  check ovn-nbctl lsp-add ls vm-cont1 vm1 1
 check ovn-nbctl lsp-add ls vm-cont2 vm1 2
 
 wait_for_ports_up
+check as hv1 ovn-appctl -t ovn-controller debug/pause
+# Try to claim container port to ovs with recompute
+check ovn-nbctl set logical_switch_port vm-cont2 parent_name=vm2
+check as hv1 ovs-vsctl set Interface vm1 external_ids:iface-id=vm-cont2
+check as hv1 ovn-appctl -t ovn-controller debug/resume
+AT_CHECK([test 1 = `cat hv1/ovn-controller.log |grep -c "claim lport vm-cont2 of type container"`])
 
 # Make vm1 as a child port of some non existent lport - foo. vm1, vm1-cont1 and
 # vm1-cont2 should be released.