summaryrefslogtreecommitdiffstats
path: root/vswitches
diff options
context:
space:
mode:
Diffstat (limited to 'vswitches')
-rw-r--r--vswitches/__init__.py20
-rw-r--r--vswitches/ovs_dpdk_vhost.py143
-rw-r--r--vswitches/utils.py40
-rw-r--r--vswitches/vswitch.py114
4 files changed, 317 insertions, 0 deletions
diff --git a/vswitches/__init__.py b/vswitches/__init__.py
new file mode 100644
index 00000000..a34475be
--- /dev/null
+++ b/vswitches/__init__.py
@@ -0,0 +1,20 @@
+# Copyright 2015 Intel Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Package for vswitch wrappers for use with VSPERF.
+
+This package contains an interface the VSPERF core uses for controlling
+vSwitches and vSwitch-specific implementation modules of this interface.
+"""
+
diff --git a/vswitches/ovs_dpdk_vhost.py b/vswitches/ovs_dpdk_vhost.py
new file mode 100644
index 00000000..d2e8907f
--- /dev/null
+++ b/vswitches/ovs_dpdk_vhost.py
@@ -0,0 +1,143 @@
+# Copyright 2015 Intel Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""VSPERF VSwitch implementation using DPDK and vhost ports
+"""
+
+from conf import settings
+from vswitches.vswitch import IVSwitch
+from src.ovs import VSwitchd, OFBridge
+from src.dpdk import dpdk
+
+VSWITCHD_CONST_ARGS = ['--', '--log-file']
+
+class OvsDpdkVhost(IVSwitch):
+ """VSwitch implementation using DPDK and vhost ports
+
+ Generic OVS wrapper functionality in src.ovs is maximally used. This
+ class wraps DPDK system configuration along with DPDK specific OVS
+ parameters
+
+ The method docstrings document only considerations specific to this
+ implementation. For generic information of the nature of the methods,
+ see the interface.
+ """
+ def __init__(self):
+ vswitchd_args = ['--dpdk']
+ vswitchd_args += settings.getValue('VSWITCHD_DPDK_ARGS')
+ vswitchd_args += VSWITCHD_CONST_ARGS
+
+ self._vswitchd = VSwitchd(vswitchd_args=vswitchd_args)
+ self._bridges = {}
+
+ def start(self):
+ """See IVswitch for general description
+
+ Activates DPDK kernel modules, ovsdb and vswitchd.
+ """
+ dpdk.init()
+ self._vswitchd.start()
+
+ def stop(self):
+ """See IVswitch for general description
+
+ Kills ovsdb and vswitchd and removes DPDK kernel modules.
+ """
+ self._vswitchd.kill()
+ dpdk.cleanup()
+
+ def add_switch(self, switch_name):
+ """See IVswitch for general description
+ """
+ bridge = OFBridge(switch_name)
+ bridge.create()
+ bridge.set_db_attribute('Open_vSwitch', '.',
+ 'other_config:max-idle', '60000')
+ bridge.set_db_attribute('Bridge', bridge.br_name,
+ 'datapath_type', 'netdev')
+ self._bridges[switch_name] = bridge
+
+ def del_switch(self, switch_name):
+ """See IVswitch for general description
+ """
+ bridge = self._bridges[switch_name]
+ self._bridges.pop(switch_name)
+ bridge.destroy()
+
+ def add_phy_port(self, switch_name):
+ """See IVswitch for general description
+
+ Creates a port of type dpdk.
+ The new port is named dpdk<n> where n is an integer starting from 0.
+ """
+ bridge = self._bridges[switch_name]
+ dpdk_count = self._get_port_count(bridge, 'type=dpdk')
+ port_name = 'dpdk' + str(dpdk_count)
+ params = ['--', 'set', 'Interface', port_name, 'type=dpdk']
+ of_port = bridge.add_port(port_name, params)
+
+ return (port_name, of_port)
+
+ def add_vport(self, switch_name):
+ """See IVswitch for general description
+
+ Creates a port of type dpdkvhost
+ The new port is named dpdkvhost<n> where n is an integer starting
+ from 0
+ """
+ bridge = self._bridges[switch_name]
+ vhost_count = self._get_port_count(bridge, 'type=dpdkvhost')
+ port_name = 'dpdkvhost' + str(vhost_count)
+ params = ['--', 'set', 'Interface', port_name, 'type=dpdkvhost']
+ of_port = bridge.add_port(port_name, params)
+
+ return (port_name, of_port)
+
+ def get_ports(self, switch_name):
+ """See IVswitch for general description
+ """
+ bridge = self._bridges[switch_name]
+ ports = list(bridge.get_ports().items())
+ return [(name, of_port) for (name, (of_port, _)) in ports]
+
+ def del_port(self, switch_name, port_name):
+ """See IVswitch for general description
+ """
+ bridge = self._bridges[switch_name]
+ bridge.del_port(port_name)
+
+ def add_flow(self, switch_name, flow):
+ """See IVswitch for general description
+ """
+ bridge = self._bridges[switch_name]
+ bridge.add_flow(flow)
+
+ def del_flow(self, switch_name, flow=None):
+ """See IVswitch for general description
+ """
+ flow = flow or {}
+ bridge = self._bridges[switch_name]
+ bridge.del_flow(flow)
+
+ @staticmethod
+ def _get_port_count(bridge, param):
+ """Returns the number of ports having a certain parameter
+
+ :param bridge: The src.ovs.ofctl.OFBridge on which to operate
+ :param param: The parameter to search for
+ :returns: Count of matches
+ """
+ port_params = [c for (_, (_, c)) in list(bridge.get_ports().items())]
+ param_hits = [i for i in port_params if param in i]
+ return len(param_hits)
diff --git a/vswitches/utils.py b/vswitches/utils.py
new file mode 100644
index 00000000..7350de31
--- /dev/null
+++ b/vswitches/utils.py
@@ -0,0 +1,40 @@
+# Copyright 2015 Intel Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Utility functions for working with vSwitches and flows
+"""
+
+import copy
+
+def add_ports_to_flow(flow, in_port, out_port):
+ """Creates a new flow based on the given flow and adds in port and out port
+ to it.
+
+ The flow dictionary structure is described in IVswitch
+
+ :param flow: Description of the flow as a dictionary
+ :param in_port: OpenFlow number of the ingress port for the rule
+ :param out_port: OpenFlow number of the eggress port for the rule
+
+ :returns: A new dictionary describing a flow combining the parameters
+ """
+ new_flow = copy.deepcopy(flow)
+ new_flow['in_port'] = in_port
+
+ if 'actions' in new_flow:
+ new_flow['actions'].append('output:' + str(out_port))
+ else:
+ new_flow['actions'] = ['output:' + str(out_port)]
+
+ return new_flow
diff --git a/vswitches/vswitch.py b/vswitches/vswitch.py
new file mode 100644
index 00000000..713974ae
--- /dev/null
+++ b/vswitches/vswitch.py
@@ -0,0 +1,114 @@
+# Copyright 2015 Intel Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Generic interface VSPERF uses for controlling a vSwitch
+"""
+
+class IVSwitch(object):
+ """Interface class that is implemented by vSwitch-specific classes
+
+ Other methods are called only between start() and stop()
+ """
+ def start(self):
+ """Start the vSwitch
+
+ If vSwitch is split to multiple processes, has kernel modules etc.,
+ this is expected to set them all up in correct sequence
+ """
+ raise NotImplementedError()
+
+ def stop(self):
+ """Stop the vSwitch
+
+ If vSwitch is split to multiple processes, has kernel modules etc.,
+ this is expected to terminate and clean all of them in correct sequence
+ """
+ raise NotImplementedError()
+
+ def add_switch(self, switch_name):
+ """Create a new logical switch with no ports
+
+ :param switch_name: The name of the new logical switch
+ :returns: None
+ """
+ raise NotImplementedError()
+
+ def del_switch(self, switch_name):
+ """Destroy the given logical switch
+
+ :param switch_name: The name of the logical switch to be destroyed
+ :returns: None
+ """
+ raise NotImplementedError()
+
+ def add_phy_port(self, switch_name):
+ """Create a new port to the logical switch that is attached to a
+ physical port
+
+ :param switch_name: The switch where the port is attached to
+ :returns: (port name, OpenFlow port number)
+ """
+ raise NotImplementedError()
+
+ def add_vport(self, switch_name):
+ """Create a new port to the logical switch for VM connections
+
+ :param switch_name: The switch where the port is attached to
+ :returns: (port name, OpenFlow port number)
+ """
+ raise NotImplementedError()
+
+ def get_ports(self, switch_name):
+ """Return a list of tuples describing the ports of the logical switch
+
+ :param switch_name: The switch whose ports to return
+ :returns: [(port name, OpenFlow port number), ...]
+ """
+ raise NotImplementedError()
+
+ def del_port(self, switch_name, port_name):
+ """Delete the port from the logical switch
+
+ The port can be either physical or virtual
+
+ :param switch_name: The switch on which to operate
+ :param port_name: The port to delete
+ """
+ raise NotImplementedError()
+
+ def add_flow(self, switch_name, flow):
+ """Add a flow rule to the logical switch
+
+ :param switch_name: The switch on which to operate
+ :param flow: Flow description as a dictionary
+
+ Example flow dictionary:
+ flow = {
+ 'in_port': '1',
+ 'idle_timeout': '0',
+ 'actions': ['output:3']
+ }
+ """
+ raise NotImplementedError()
+
+ def del_flow(self, switch_name, flow=None):
+ """Delete the flow rule from the logical switch
+
+ :param switch_name: The switch on which to operate
+ :param flow: Flow description as a dictionary
+
+ For flow dictionary description, see add_flow
+ For flow==None, all flows are deleted
+ """
+ raise NotImplementedError()