From: Ondrej Lichtner <olichtne(a)redhat.com>
This commit adds the classes NmConfigDeviceOvsBridge and
NetConfigDeviceOvsBridge that represent the configuration of an Open
vSwitch bridge. The Nm class only defines the is_nm_managed method that
is set to return False and check the devices slaves, since NM does not
support OvS configuration.
The Net class takes care of the OvS configuration by calling appropriate
shell commands, at the moment it can handle the creation and destruction
of an OvS bridge, add/remove ports and set their vlan tags and finally
add/remove bonds. This is sufficient for basic support of Open vSwitch.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Slave/NetConfigDevice.py | 82 ++++++++++++++++++++++++++++++++++++++++++-
lnst/Slave/NmConfigDevice.py | 19 +++++++++-
2 files changed, 99 insertions(+), 2 deletions(-)
diff --git a/lnst/Slave/NetConfigDevice.py b/lnst/Slave/NetConfigDevice.py
index e279d66..c3cf74c 100644
--- a/lnst/Slave/NetConfigDevice.py
+++ b/lnst/Slave/NetConfigDevice.py
@@ -294,13 +294,93 @@ class NetConfigDeviceTeam(NetConfigDeviceGeneric):
dbus_option = "-D" if self._should_enable_dbus() else ""
exec_cmd("teamdctl %s %s port remove %s" % (dbus_option, dev_name,
port_name))
+class NetConfigDeviceOvsBridge(NetConfigDeviceGeneric):
+ _modulename = "openvswitch"
+ _moduleload = True
+
+ @classmethod
+ def type_init(self):
+ super(NetConfigDeviceOvsBridge, self).type_init()
+ exec_cmd("mkdir -p /var/run/openvswitch/")
+ exec_cmd("ovsdb-server --detach --pidfile "\
+ "--remote=punix:/var/run/openvswitch/db.sock",
+ die_on_err=False)
+ exec_cmd("ovs-vswitchd --detach --pidfile", die_on_err=False)
+
+ def _add_ports(self):
+ slaves = self._dev_config["slaves"]
+ vlan_tags = self._dev_config["ovs_conf"]["vlan_tags"]
+
+ br_name = self._dev_config["name"]
+
+ for slave_id in slaves:
+ slave_dev = self._if_manager.get_mapped_device(slave_id)
+ slave_name = slave_dev.get_name()
+
+ if len(vlan_tags[slave_id]) == 0:
+ tags = ""
+ elif len(vlan_tags[slave_id]) == 1:
+ tags = " tag=%s" % vlan_tags[slave_id][0]
+ elif len(vlan_tags[slave_id]) > 1:
+ tags = " trunks=" + ",".join(vlan_tags[slave_id])
+ exec_cmd("ovs-vsctl add-port %s %s%s" % (br_name, slave_name,
tags))
+
+ def _del_ports(self):
+ slaves = self._dev_config["slaves"]
+
+ br_name = self._dev_config["name"]
+
+ for slave_id in slaves:
+ slave_dev = self._if_manager.get_mapped_device(slave_id)
+ slave_name = slave_dev.get_name()
+
+ exec_cmd("ovs-vsctl del-port %s %s" % (br_name, slave_name))
+
+ def _add_bonds(self):
+ br_name = self._dev_config["name"]
+
+ bonds = self._dev_config["ovs_conf"]["bonds"]
+ for bond_id, bond in bonds.iteritems():
+ ifaces = ""
+ for slave in bond["slaves"]:
+ ifaces += " %s" % slave
+ exec_cmd("ovs-vsctl add-bond %s %s %s" % (br_name, bond_id,
ifaces))
+
+ def _del_bonds(self):
+ br_name = self._dev_config["name"]
+
+ bonds = self._dev_config["ovs_conf"]["bonds"]
+ for bond_id, bond in bonds.iteritems():
+ exec_cmd("ovs-vsctl del-port %s %s" % (br_name, bond_id))
+
+ def configure(self):
+ dev_cfg = self._dev_config
+
+ br_name = dev_cfg["name"]
+ exec_cmd("ovs-vsctl add-br %s" % br_name)
+
+ self._add_ports()
+
+ self._add_bonds()
+
+ def deconfigure(self):
+ dev_cfg = self._dev_config
+
+ self._del_bonds()
+
+ self._del_ports()
+
+ br_name = dev_cfg["name"]
+ exec_cmd("ovs-vsctl del-br %s" % br_name)
+
type_class_mapping = {
"eth": NetConfigDeviceEth,
"bond": NetConfigDeviceBond,
"bridge": NetConfigDeviceBridge,
"macvlan": NetConfigDeviceMacvlan,
"vlan": NetConfigDeviceVlan,
- "team": NetConfigDeviceTeam
+ "team": NetConfigDeviceTeam,
+ "ovs_bridge": NetConfigDeviceOvsBridge
}
def NetConfigDevice(dev_config, if_manager):
diff --git a/lnst/Slave/NmConfigDevice.py b/lnst/Slave/NmConfigDevice.py
index 40f4b70..460fd26 100644
--- a/lnst/Slave/NmConfigDevice.py
+++ b/lnst/Slave/NmConfigDevice.py
@@ -781,13 +781,30 @@ class NmConfigDeviceTeam(NmConfigDeviceGeneric):
self._rm_slaves()
self._rm_team()
+class NmConfigDeviceOvsBridge(NmConfigDeviceGeneric):
+ #Not supported by NetworkManager
+ @classmethod
+ def is_nm_managed(cls, dev_config, if_manager):
+ managed = False
+
+ for slave_id in get_slaves(dev_config):
+ slave_dev = if_manager.get_mapped_device(slave_id)
+ slave_config = slave_dev.get_conf_dict()
+ if is_nm_managed(slave_config, if_manager) != managed:
+ msg = "Mixing NM managed and not managed devices in a "\
+ "master-slave relationship is not allowed!"
+ raise Exception(msg)
+
+ return managed
+
type_class_mapping = {
"eth": NmConfigDeviceEth,
"bond": NmConfigDeviceBond,
"bridge": NmConfigDeviceBridge,
"macvlan": NmConfigDeviceMacvlan,
"vlan": NmConfigDeviceVlan,
- "team": NmConfigDeviceTeam
+ "team": NmConfigDeviceTeam,
+ "ovs_bridge": NmConfigDeviceOvsBridge
}
def is_nm_managed(dev_config, if_manager):
--
1.8.5.3