commit aaf369d3aa5f2376a62b289c9c396f68510d18e8 Author: Ondrej Lichtner olichtne@redhat.com Date: Thu Aug 21 14:25:34 2014 +0200
NetTestSlave: add methods {create, deconfigure}_if_pair
These two new methods are used to create paired interfaces, such as veth. Since these devices are created together LNST representation of the devices needs to reflect that. After device creation the method also takes care of moving the devices to the correct network namespaces.
Signed-off-by: Ondrej Lichtner olichtne@redhat.com Signed-off-by: Jiri Pirko jiri@resnulli.us
lnst/Slave/InterfaceManager.py | 36 ++++++++++++++++ lnst/Slave/NetTestSlave.py | 89 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 0 deletions(-) --- diff --git a/lnst/Slave/InterfaceManager.py b/lnst/Slave/InterfaceManager.py index 3695fe2..e30b52a 100644 --- a/lnst/Slave/InterfaceManager.py +++ b/lnst/Slave/InterfaceManager.py @@ -156,6 +156,24 @@ class InterfaceManager(object): self._tmp_mapping[if_id] = device return config["name"]
+ def create_device_pair(self, if_id1, config1, if_id2, config2): + name1, name2 = self.assign_name(config1) + config1["name"] = name1 + config2["name"] = name2 + config1["peer_name"] = name2 + config2["peer_name"] = name1 + + device1 = Device(self) + device2 = Device(self) + + device1.set_configuration(config1) + device2.set_configuration(config2) + device1.create() + + self._tmp_mapping[if_id1] = device1 + self._tmp_mapping[if_id2] = device2 + return name1, name2 + def _is_name_used(self, name): for device in self._devices.itervalues(): if name == device.get_name(): @@ -168,6 +186,16 @@ class InterfaceManager(object): index += 1 return prefix + str(index)
+ def _assign_name_pair(self, prefix): + index1 = 0 + index2 = 0 + while (self._is_name_used(prefix + str(index1))): + index1 += 1 + index2 = index1 + 1 + while (self._is_name_used(prefix + str(index2))): + index2 += 1 + return prefix + str(index1), prefix + str(index2) + def assign_name(self, config): if "name" in config: return config["name"] @@ -193,6 +221,10 @@ class InterfaceManager(object): vlan_tci = get_option(config, "vlan_tci") prefix = "%s.%s_" % (netdev_name, vlan_tci) return self._assign_name_generic(prefix) + elif dev_type == "veth": + return self._assign_name_pair("veth") + else: + return self._assign_name_generic("dev")
class Device(object): def __init__(self, if_manager): @@ -306,6 +338,10 @@ class Device(object): def get_configuration(self): return self._conf
+ def del_configuration(self): + self._conf = None + self._conf_dict = None + def clear_configuration(self): if self._master["primary"]: primary_id = self._master["primary"] diff --git a/lnst/Slave/NetTestSlave.py b/lnst/Slave/NetTestSlave.py index ca714e2..d2f7834 100644 --- a/lnst/Slave/NetTestSlave.py +++ b/lnst/Slave/NetTestSlave.py @@ -166,6 +166,95 @@ class SlaveMethods: dev.configure() return dev_name
+ def create_if_pair(self, if_id1, config1, if_id2, config2): + dev_names = self._if_manager.create_device_pair(if_id1, config1, + if_id2, config2) + dev1 = self._if_manager.get_mapped_device(if_id1) + dev2 = self._if_manager.get_mapped_device(if_id2) + + while dev1.get_if_index() == None and dev2.get_if_index() == None: + msgs = self._server_handler.get_messages_from_con('netlink') + for msg in msgs: + self._if_manager.handle_netlink_msgs(msg[1]["data"]) + + if config1["netns"] != None: + hwaddr = dev1.get_hwaddr() + self.set_if_netns(if_id1, config1["netns"]) + + msg = {"type": "command", "method_name": "map_if_by_hwaddr", + "args": [if_id1, hwaddr]} + self._server_handler.send_data_to_netns(config1["netns"], msg) + result = self._slave_server.wait_for_result(config1["netns"]) + if len(result["result"]) != 1: + raise Exception("Mapping failed.") + + msg = {"type": "command", "method_name": "configure_interface", + "args": [if_id1, config1]} + self._server_handler.send_data_to_netns(config1["netns"], msg) + result = self._slave_server.wait_for_result(config1["netns"]) + if result["result"] != True: + raise Exception("Configuration failed.") + else: + dev1.configure() + if config2["netns"] != None: + hwaddr = dev2.get_hwaddr() + self.set_if_netns(if_id2, config2["netns"]) + + msg = {"type": "command", "method_name": "map_if_by_hwaddr", + "args": [if_id2, hwaddr]} + self._server_handler.send_data_to_netns(config2["netns"], msg) + result = self._slave_server.wait_for_result(config2["netns"]) + if len(result["result"]) != 1: + raise Exception("Mapping failed.") + + msg = {"type": "command", "method_name": "configure_interface", + "args": [if_id2, config2]} + self._server_handler.send_data_to_netns(config2["netns"], msg) + result = self._slave_server.wait_for_result(config2["netns"]) + if result["result"] != True: + raise Exception("Configuration failed.") + else: + dev2.configure() + return dev_names + + def deconfigure_if_pair(self, if_id1, if_id2): + dev1 = self._if_manager.get_mapped_device(if_id1) + dev2 = self._if_manager.get_mapped_device(if_id2) + + if dev1.get_netns() == None: + dev1.deconfigure() + else: + netns = dev1.get_netns() + + msg = {"type": "command", "method_name": "deconfigure_interface", + "args": [if_id1]} + self._server_handler.send_data_to_netns(netns, msg) + result = self._slave_server.wait_for_result(netns) + if result["result"] != True: + raise Exception("Deconfiguration failed.") + + self.return_if_netns(if_id1) + + if dev2.get_netns() == None: + dev2.deconfigure() + else: + netns = dev2.get_netns() + + msg = {"type": "command", "method_name": "deconfigure_interface", + "args": [if_id2]} + self._server_handler.send_data_to_netns(netns, msg) + result = self._slave_server.wait_for_result(netns) + if result["result"] != True: + raise Exception("Deconfiguration failed.") + + self.return_if_netns(if_id2) + + dev1.destroy() + dev2.destroy() + dev1.del_configuration() + dev2.del_configuration() + return True + def deconfigure_interface(self, if_id): device = self._if_manager.get_mapped_device(if_id) device.clear_configuration()
lnst-developers@lists.fedorahosted.org