Skip to content

OVS addon: configured ovs_options for OVSBridge interfaces disappear after networking reload #344

@PavelAF

Description

@PavelAF

When using OVSBridge network interfaces, additional OVS options can be configured: ovs_options. These are successfully applied to the OVS interface when initially created. BUT: if I reload networking service, these options will be cleared.
A hacky solution: a full network restart or reloading interfaces helps: ifdown vmbrX && ifup vmbrX

Cause of the error: Incorrect bridge creation logic in the openvswitch.py ​​ifupdown2 addon
If you manually run reload in verbose mode (ifreload -avd), you'll see the following (in the example for ovsbr0 with ovs_options other_config:forward-bpdu=true): When reloading, the openvswitch addon generates and executes the following command:

/usr/bin/ovs-vsctl -- --may-exist add-br ovsbr0 \
  -- set bridge ovsbr0 other_config:forward-bpdu=true \
  -- --if-exists clear bridge ovsbr0 auto_attach controller external-ids fail_mode flood_vlans ipfix mirrors netflow other_config protocols sflow \
  -- --if-exists clear interface ovsbr0 mtu_request external-ids other_config options

So, what's happening in the command and in the code itself? First comes the interface creation command, then the ovs_options setup command, and then the parameter clearing command. This means that all previously configured ovs_options are cleared. This happens because the add-on logic first assigns parameters. Only then does it check for the existence of the interface to clear its settings. If the interface already exists (ifreload), it clears the bridge parameters, thereby resetting all previously configured parameters.

Quick fix: in ifupdown2/addons/openvswitch.py:
def _addbridge (self, ifaceobj) , move the interface creation and parameter assignment code below the existence check, which initiates the parameters clearing. This ensures that the existing interface parameters are cleared first and then the desired ovs_options are assigned.

diff --git a/ifupdown2/addons/openvswitch.py b/ifupdown2/addons/openvswitch.py
index 0a124ba..352633a 100644
--- a/ifupdown2/addons/openvswitch.py
+++ b/ifupdown2/addons/openvswitch.py
@@ -155,16 +155,6 @@ class openvswitch(Addon, moduleBase):

         cmd_list = []

-        cmd = "--may-exist add-br %s"%(iface)
-        if ovsparent is not None and ovsoptions:
-            cmd = cmd + " %s" %(ovsoptions)
-
-        cmd_list.append(cmd)
-
-        if ovsparent is None and ovsoptions:
-            cmd = "set bridge %s %s" %(iface, ovsoptions)
-            cmd_list.append(cmd)
-
         #update
         if self.cache.link_exists (iface):
             # on update, delete active ports not in the new port list
@@ -192,6 +182,16 @@ class openvswitch(Addon, moduleBase):
             cmd = "--if-exists clear interface %s mtu_request external-ids other_config options"%(iface)
             cmd_list.append(cmd)

+        cmd = "--may-exist add-br %s"%(iface)
+        if ovsparent is not None and ovsoptions:
+            cmd = cmd + " %s" %(ovsoptions)
+
+        cmd_list.append(cmd)
+
+        if ovsparent is None and ovsoptions:
+            cmd = "set bridge %s %s" %(iface, ovsoptions)
+            cmd_list.append(cmd)
+
         if ovsextra is not None:
             cmd_list.extend(ovsextra)

After this change, the final ovs-vsctl command when reloading the network applies the subcommands in the correct order and looks like this:

/usr/bin/ovs-vsctl \
  -- --if-exists clear bridge ovsbr0 auto_attach controller external-ids fail_mode flood_vlans ipfix mirrors netflow other_config protocols sflow \
  -- --if-exists clear interface ovsbr0 mtu_request external-ids other_config options \
  -- --may-exist add-br ovsbr0 \
  -- set bridge ovsbr0 other_config:forward-bpdu=true

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions