ofctl: Improve manpage.
[openvswitch] / xenserver / opt_xensource_libexec_InterfaceReconfigureVswitch.py
index f777b178712179124741aca5df8131ba72e5909a..0d14251bff2b7f615cd9986d4d479de09b42154e 100644 (file)
@@ -36,22 +36,6 @@ def netdev_up(netdev, mtu=None):
 
     run_command(["/sbin/ifconfig", netdev, 'up'] + mtu)
 
-#
-# Bridges
-#
-
-def pif_bridge_name(pif):
-    """Return the bridge name of a pif.
-
-    PIF must be a bridged PIF."""
-
-    pifrec = db().get_pif_record(pif)
-    nwrec = db().get_network_record(pifrec['network'])
-    if nwrec['bridge']:
-        return nwrec['bridge']
-    else:
-        raise Error("PIF %(uuid)s does not have a bridge name" % pifrec)
-
 #
 # PIF miscellanea
 #
@@ -171,12 +155,12 @@ def datapath_modify_config(commands):
 # Toplevel Datapath Configuration.
 #
 
-def configure_datapath(pif, parent=None, vlan=None):
-    """Bring up the datapath configuration for PIF.
-
-    Should be careful not to glitch existing users of the datapath, e.g. other VLANs etc.
-
-    Should take care of tearing down other PIFs which encompass common physical devices.
+def configure_datapath(pif):
+    """Bring up the configuration for 'pif', which must not be a VLAN PIF, by:
+    - Tearing down other PIFs that use the same physical devices as 'pif'.
+    - Ensuring that 'pif' itself is set up.
+    - *Not* tearing down any PIFs that are stacked on top of 'pif' (i.e. VLANs
+      on top of 'pif'.
 
     Returns a tuple containing
     - A list containing the necessary vsctl command line arguments
@@ -187,10 +171,13 @@ def configure_datapath(pif, parent=None, vlan=None):
     vsctl_argv = []
     extra_up_ports = []
 
+    assert not pif_is_vlan(pif)
     bridge = pif_bridge_name(pif)
 
     physical_devices = datapath_get_physical_pifs(pif)
 
+    vsctl_argv += ['## configuring datapath %s' % bridge]
+
     # Determine additional devices to deconfigure.
     #
     # Given all physical devices which are part of this PIF we need to
@@ -260,10 +247,7 @@ def configure_datapath(pif, parent=None, vlan=None):
         vsctl_argv += ['# deconfigure physical port %s' % dev]
         vsctl_argv += datapath_deconfigure_physical(dev)
 
-    if parent and datapath:
-        vsctl_argv += ['--', '--may-exist', 'add-br', bridge, parent, vlan]
-    else:
-        vsctl_argv += ['--', '--may-exist', 'add-br', bridge]
+    vsctl_argv += ['--', '--may-exist', 'add-br', bridge]
 
     if len(physical_devices) > 1:
         vsctl_argv += ['# deconfigure bond %s' % pif_netdev_name(pif)]
@@ -276,31 +260,41 @@ def configure_datapath(pif, parent=None, vlan=None):
         vsctl_argv += ['# add physical device %s' % iface]
         vsctl_argv += ['--', '--may-exist', 'add-port', bridge, iface]
 
+    vsctl_argv += set_br_external_ids(pif)
+    vsctl_argv += ['## done configuring datapath %s' % bridge]
+
     return vsctl_argv,extra_up_ports
 
-def deconfigure_datapath(pif):
+def deconfigure_bridge(pif):
     vsctl_argv = []
 
     bridge = pif_bridge_name(pif)
 
-    physical_devices = datapath_get_physical_pifs(pif)
+    log("deconfigure_bridge: bridge           - %s" % bridge)
 
-    log("deconfigure_datapath: bridge           - %s" % bridge)
-    log("deconfigure_datapath: physical devices - %s" % [pif_netdev_name(p) for p in physical_devices])
+    vsctl_argv += ['# deconfigure bridge %s' % bridge]
+    vsctl_argv += ['--', '--if-exists', 'del-br', bridge]
 
-    for p in physical_devices:
-        dev = pif_netdev_name(p)
-        vsctl_argv += ['# deconfigure physical port %s' % dev]
-        vsctl_argv += datapath_deconfigure_physical(dev)
-        netdev_down(dev)
+    return vsctl_argv
 
-    if len(physical_devices) > 1:
-        vsctl_argv += ['# deconfigure bond %s' % pif_netdev_name(pif)]
-        vsctl_argv += datapath_deconfigure_bond(pif_netdev_name(pif))
+def set_br_external_ids(pif):
+    xs_network_uuids = []
+    for nwpif in db().get_pifs_by_device(db().get_pif_record(pif)['device']):
+        rec = db().get_pif_record(nwpif)
 
-    vsctl_argv += ['# deconfigure bridge %s' % bridge]
-    vsctl_argv += ['--', '--if-exists', 'del-br', bridge]
+        # When state is read from dbcache PIF.currently_attached
+        # is always assumed to be false... Err on the side of
+        # listing even detached networks for the time being.
+        #if nwpif != pif and not rec['currently_attached']:
+        #    log("Network PIF %s not currently attached (%s)" % (rec['uuid'],pifrec['uuid']))
+        #    continue
+        nwrec = db().get_network_record(rec['network'])
+        xs_network_uuids += [nwrec['uuid']]
 
+    vsctl_argv = []
+    vsctl_argv += ['# configure xs-network-uuids']
+    vsctl_argv += ['--', 'br-set-external-id', pif_bridge_name(pif),
+            'xs-network-uuids', ';'.join(xs_network_uuids)]
     return vsctl_argv
 
 #
@@ -329,31 +323,22 @@ class DatapathVswitch(Datapath):
         dprec = db().get_pif_record(self._dp)
 
         ipdev = self._ipdev
-        bridge = pif_bridge_name(self._dp)
-        if pif_is_vlan(self._pif):
-            datapath = pif_datapath(self._pif)
-            c,e = configure_datapath(self._dp, datapath, pifrec['VLAN'])
-        else:
-            c,e = configure_datapath(self._dp)
+        c,e = configure_datapath(self._dp)
+        bridge = pif_bridge_name(self._pif)
         vsctl_argv += c
         extra_ports += e
 
-        xs_network_uuids = []
-        for nwpif in db().get_pifs_by_device(db().get_pif_record(self._pif)['device']):
-            rec = db().get_pif_record(nwpif)
+        if pif_is_vlan(self._pif):
+            # XXX this is only needed on XS5.5, because XAPI misguidedly
+            # creates the fake bridge (via bridge ioctl) before it calls us.
+            vsctl_argv += ['--', '--if-exists', 'del-br', bridge]
 
-            # When state is read from dbcache PIF.currently_attached
-            # is always assumed to be false... Err on the side of
-            # listing even detached networks for the time being.
-            #if nwpif != pif and not rec['currently_attached']:
-            #    log("Network PIF %s not currently attached (%s)" % (rec['uuid'],pifrec['uuid']))
-            #    continue
-            nwrec = db().get_network_record(rec['network'])
-            xs_network_uuids += [nwrec['uuid']]
+            # configure_datapath() set up the underlying datapath bridge.
+            # Stack a VLAN bridge on top of it.
+            vsctl_argv += ['--', '--may-exist', 'add-br',
+                           bridge, pif_bridge_name(self._dp), pifrec['VLAN']]
 
-        vsctl_argv += ['# configure xs-network-uuids']
-        vsctl_argv += ['--', 'br-set-external-id', bridge,
-                'xs-network-uuids', ';'.join(xs_network_uuids)]
+            vsctl_argv += set_br_external_ids(self._pif)
 
         if ipdev != bridge:
             vsctl_argv += ["# deconfigure ipdev %s" % ipdev]
@@ -381,11 +366,12 @@ class DatapathVswitch(Datapath):
         physical_devices = datapath_get_physical_pifs(self._dp)
         
         for p in physical_devices:
-            oc = db().get_pif_record(p)['other_config']
+            prec = db().get_pif_record(p)
+            oc = prec['other_config']
 
             dev = pif_netdev_name(p)
 
-            mtu = mtu_setting(oc)
+            mtu = mtu_setting(prec['network'], "PIF", oc)
 
             netdev_up(dev, mtu)
 
@@ -420,6 +406,9 @@ class DatapathVswitch(Datapath):
         vsctl_argv += datapath_deconfigure_ipdev(ipdev)
 
         if pif_is_vlan(self._pif):
+            # Delete the VLAN bridge.
+            vsctl_argv += deconfigure_bridge(self._pif)
+
             # If the VLAN's slave is attached, leave datapath setup.
             slave = pif_get_vlan_slave(self._pif)
             if db().get_pif_record(slave)['currently_attached']:
@@ -443,5 +432,6 @@ class DatapathVswitch(Datapath):
                 dp = None
 
         if dp:
-            vsctl_argv += deconfigure_datapath(dp)
-            datapath_modify_config(vsctl_argv)
+            vsctl_argv += deconfigure_bridge(dp)
+
+        datapath_modify_config(vsctl_argv)