summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conf/integration/01_testcases.conf49
-rw-r--r--conf/integration/02_vswitch.conf24
-rw-r--r--conf/integration/03_traffic.conf20
-rw-r--r--core/component_factory.py7
-rw-r--r--core/vnf_controller.py6
-rw-r--r--core/vswitch_controller_op2p.py140
-rw-r--r--docs/configguide/index.rst1
-rw-r--r--docs/userguide/index.rst1
-rwxr-xr-xdocs/userguide/integration.rst97
-rw-r--r--src/ovs/ofctl.py50
-rw-r--r--testcases/testcase.py19
-rwxr-xr-xvsperf8
-rw-r--r--vswitches/ovs_dpdk_vhost.py50
-rw-r--r--vswitches/ovs_vanilla.py49
-rw-r--r--vswitches/vswitch.py28
15 files changed, 528 insertions, 21 deletions
diff --git a/conf/integration/01_testcases.conf b/conf/integration/01_testcases.conf
new file mode 100644
index 00000000..99154ad3
--- /dev/null
+++ b/conf/integration/01_testcases.conf
@@ -0,0 +1,49 @@
+# Copyright 2015-2016 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.
+
+# The 1st value of SUPPORTED_TUNNELING_PROTO is used as the default
+# tunneling protocol for OP2P tests.
+SUPPORTED_TUNNELING_PROTO = ['vxlan', 'gre', 'geneve']
+
+# Required for OP2P tests
+# "Tunnel Type": ["vxlan"|"gre"|"geneve"] # Tunnel Type defines tunneling protocol to use.
+# # It can be overridden by cli option tunnel_type.
+# # Values:
+# # "vxlan" - iteration of destination MAC address
+# # "gre" - iteration of destination IP address
+# # "geneve" - iteration of destination UDP port
+# # Default value is "vxlan".
+#
+# biDirectional testing for OP2P is not yet supported.
+# biDirectional must be set to False.
+
+INTEGRATION_TESTS = [
+ {
+ "Name": "overlay_p2p_tput",
+ "Traffic Type": "rfc2544",
+ "Deployment": "op2p",
+ "biDirectional": False,
+ "Tunnel Type": SUPPORTED_TUNNELING_PROTO[0],
+ "Description": "Overlay Encapsulation Throughput RFC2544 Test",
+ },
+ {
+ "Name": "overlay_p2p_cont",
+ "Traffic Type": "continuous",
+ "Deployment": "op2p",
+ "biDirectional": False,
+ "Tunnel Type": SUPPORTED_TUNNELING_PROTO[0],
+ "Description": "Overlay Encapsulation Continuous Stream",
+ },
+]
+
diff --git a/conf/integration/02_vswitch.conf b/conf/integration/02_vswitch.conf
new file mode 100644
index 00000000..20cec3e6
--- /dev/null
+++ b/conf/integration/02_vswitch.conf
@@ -0,0 +1,24 @@
+# Copyright 2015-2016 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.
+
+# Tunnel endpoint for Overlay P2P deployment scenario
+VTEP_IP1 = '192.168.0.1/24'
+VTEP_IP2 = '192.168.240.10'
+VTEP_IP2_SUBNET = '192.168.240.0/24'
+TUNNEL_INTEGRATION_BRIDGE = 'br0'
+TUNNEL_EXTERNAL_BRIDGE = 'br-ext'
+TUNNEL_EXTERNAL_BRIDGE_IP = '192.168.240.1/24'
+
+# vxlan|gre|geneve
+TUNNEL_TYPE = 'vxlan'
diff --git a/conf/integration/03_traffic.conf b/conf/integration/03_traffic.conf
new file mode 100644
index 00000000..8bef092a
--- /dev/null
+++ b/conf/integration/03_traffic.conf
@@ -0,0 +1,20 @@
+# Copyright 2015-2016 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.
+
+# For OP2P deployment scenario
+TRAFFICGEN_PORT1_MAC = '02:00:00:00:00:01'
+TRAFFICGEN_PORT2_MAC = '02:00:00:00:00:02'
+TRAFFICGEN_PORT1_IP = '1.1.1.1'
+TRAFFICGEN_PORT2_IP = '90.90.90.90'
+
diff --git a/core/component_factory.py b/core/component_factory.py
index af237e50..1e5f2266 100644
--- a/core/component_factory.py
+++ b/core/component_factory.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Intel Corporation.
+# Copyright 2015-2016 Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ from core.traffic_controller_rfc2544 import TrafficControllerRFC2544
from core.vswitch_controller_p2p import VswitchControllerP2P
from core.vswitch_controller_pvp import VswitchControllerPVP
from core.vswitch_controller_pvvp import VswitchControllerPVVP
+from core.vswitch_controller_op2p import VswitchControllerOP2P
from core.vnf_controller import VnfController
from core.pktfwd_controller import PktFwdController
from tools.load_gen.stress.stress import Stress
@@ -61,12 +62,14 @@ def create_vswitch(deployment_scenario, vswitch_class, traffic):
:return: IVSwitchController for the deployment_scenario
"""
deployment_scenario = deployment_scenario.lower()
- if deployment_scenario.find("p2p") >= 0:
+ if deployment_scenario.find("p2p") == 0:
return VswitchControllerP2P(vswitch_class, traffic)
elif deployment_scenario.find("pvp") >= 0:
return VswitchControllerPVP(vswitch_class, traffic)
elif deployment_scenario.find("pvvp") >= 0:
return VswitchControllerPVVP(vswitch_class, traffic)
+ elif deployment_scenario.find("op2p") >= 0:
+ return VswitchControllerOP2P(vswitch_class, traffic)
def create_vnf(deployment_scenario, vnf_class):
"""Return a new VnfController for the deployment_scenario.
diff --git a/core/vnf_controller.py b/core/vnf_controller.py
index 3313e9e3..e973bc51 100644
--- a/core/vnf_controller.py
+++ b/core/vnf_controller.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Intel Corporation.
+# Copyright 2015-2016 Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -43,10 +43,12 @@ class VnfController(object):
self._deployment_scenario = deployment_scenario.upper()
if self._deployment_scenario == 'P2P':
self._vnfs = []
- if self._deployment_scenario == 'PVP':
+ elif self._deployment_scenario == 'PVP':
self._vnfs = [vnf_class()]
elif self._deployment_scenario == 'PVVP':
self._vnfs = [vnf_class(), vnf_class()]
+ elif self._deployment_scenario == 'OP2P':
+ self._vnfs = []
self._logger.debug('__init__ ' + str(len(self._vnfs)) +
' VNF[s] with ' + ' '.join(map(str, self._vnfs)))
diff --git a/core/vswitch_controller_op2p.py b/core/vswitch_controller_op2p.py
new file mode 100644
index 00000000..69c88c35
--- /dev/null
+++ b/core/vswitch_controller_op2p.py
@@ -0,0 +1,140 @@
+# Copyright 2015-2016 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.
+
+"""VSwitch controller for Physical to Tunnel Endpoint to Physical deployment
+"""
+
+import logging
+
+from core.vswitch_controller import IVswitchController
+from vswitches.utils import add_ports_to_flow
+from conf import settings
+from tools import tasks
+
+_FLOW_TEMPLATE = {
+ 'idle_timeout': '0'
+}
+
+class VswitchControllerOP2P(IVswitchController):
+ """VSwitch controller for OP2P deployment scenario.
+
+ Attributes:
+ _vswitch_class: The vSwitch class to be used.
+ _vswitch: The vSwitch object controlled by this controller
+ _deployment_scenario: A string describing the scenario to set-up in the
+ constructor.
+ """
+ def __init__(self, vswitch_class, traffic):
+ """Initializes up the prerequisites for the OP2P deployment scenario.
+
+ :vswitch_class: the vSwitch class to be used.
+ """
+ self._logger = logging.getLogger(__name__)
+ self._vswitch_class = vswitch_class
+ self._vswitch = vswitch_class()
+ self._deployment_scenario = "OP2P"
+ self._traffic = traffic.copy()
+ self._logger.debug('Creation using ' + str(self._vswitch_class))
+
+ def setup(self):
+ """ Sets up the switch for overlay P2P
+
+ Create 2 bridges br0 (integration bridge) and br-ext and a VXLAN port
+ for encapsulation.
+ """
+ self._logger.debug('Setup using ' + str(self._vswitch_class))
+
+ try:
+ self._vswitch.start()
+ bridge = settings.getValue('TUNNEL_INTEGRATION_BRIDGE')
+ bridge_ext = settings.getValue('TUNNEL_EXTERNAL_BRIDGE')
+ bridge_ext_ip = settings.getValue('TUNNEL_EXTERNAL_BRIDGE_IP')
+ tg_port2_mac = settings.getValue('TRAFFICGEN_PORT2_MAC')
+ vtep_ip2 = settings.getValue('VTEP_IP2')
+ self._vswitch.add_switch(bridge)
+
+ tasks.run_task(['sudo', 'ifconfig', bridge,
+ settings.getValue('VTEP_IP1')],
+ self._logger, 'Assign ' +
+ settings.getValue('VTEP_IP1') + ' to ' + bridge,
+ False)
+
+ tunnel_type = self._traffic['tunnel_type']
+
+ self._vswitch.add_switch(bridge_ext)
+ (_, phy1_number) = self._vswitch.add_phy_port(bridge)
+ (_, phy2_number) = self._vswitch.add_tunnel_port(bridge,
+ vtep_ip2,
+ tunnel_type)
+ self._vswitch.add_phy_port(bridge_ext)
+
+ tasks.run_task(['sudo', 'ip', 'addr', 'add',
+ bridge_ext_ip,
+ 'dev', bridge_ext], self._logger, 'Assign ' +
+ bridge_ext_ip + ' to ' + bridge_ext)
+
+ tasks.run_task(['sudo', 'ip', 'link', 'set', 'dev', bridge_ext,
+ 'up'], self._logger,
+ 'Set ' + bridge_ext + 'status to up')
+
+ self._vswitch.add_route(bridge,
+ settings.getValue('VTEP_IP2_SUBNET'),
+ bridge_ext)
+
+ if settings.getValue('VSWITCH').endswith('Vanilla'):
+ tasks.run_task(['sudo', 'arp', '-s', vtep_ip2, tg_port2_mac],
+ self._logger,
+ 'Set ' + bridge_ext + 'status to up')
+ else:
+ self._vswitch.set_tunnel_arp(vtep_ip2,
+ tg_port2_mac,
+ bridge_ext)
+
+ # Test is unidirectional for now
+ self._vswitch.del_flow(bridge)
+ flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy1_number,
+ phy2_number)
+ self._vswitch.add_flow(bridge, flow1)
+
+ except:
+ self._vswitch.stop()
+ raise
+
+ def stop(self):
+ """Tears down the switch created in setup().
+ """
+ self._logger.debug('Stop using ' + str(self._vswitch_class))
+ self._vswitch.stop()
+
+ def __enter__(self):
+ self.setup()
+
+ def __exit__(self, type_, value, traceback):
+ self.stop()
+
+ def get_vswitch(self):
+ """See IVswitchController for description
+ """
+ return self._vswitch
+
+ def get_ports_info(self):
+ """See IVswitchController for description
+ """
+ self._logger.debug('get_ports_info using ' + str(self._vswitch_class))
+ return self._vswitch.get_ports(settings.getValue('VSWITCH_BRIDGE_NAME'))
+
+ def dump_vswitch_flows(self):
+ """See IVswitchController for description
+ """
+ self._vswitch.dump_flows(settings.getValue('VSWITCH_BRIDGE_NAME'))
diff --git a/docs/configguide/index.rst b/docs/configguide/index.rst
index 3aaf238f..7ea39cd1 100644
--- a/docs/configguide/index.rst
+++ b/docs/configguide/index.rst
@@ -8,3 +8,4 @@ VSPERF Installation Guide
installation.rst
trafficgen.rst
+ integration.rst
diff --git a/docs/userguide/index.rst b/docs/userguide/index.rst
index 1e02eb21..ff4e7b52 100644
--- a/docs/userguide/index.rst
+++ b/docs/userguide/index.rst
@@ -7,3 +7,4 @@ VSPERF User Guide
:maxdepth: 3
quickstart.rst
+ integration.rst
diff --git a/docs/userguide/integration.rst b/docs/userguide/integration.rst
new file mode 100755
index 00000000..65b86468
--- /dev/null
+++ b/docs/userguide/integration.rst
@@ -0,0 +1,97 @@
+Integration tests
+=================
+
+VSPERF includes a set of integration tests defined in conf/integration.
+These tests can be run by specifying --run-integration as a parameter to vsperf.
+Current tests in conf/integration are Overlay tests.
+
+
+Executing Tunnel encapsulation tests
+------------------------------------
+
+VSPERF supports VXLAN, GRE and GENEVE tunneling protocols.
+Testing of these protocols is limited to unidirectional traffic and
+P2P (Physical to Physical scenarios).
+
+The VXLAN OVS DPDK encapsulation tests requires IPs, MAC addresses,
+bridge names and WHITELIST_NICS for DPDK.
+
+Default values are already provided. To customize for your environment, override
+the following variables in you user_settings.py file:
+
+# Variables defined in conf/integration/02_vswitch.conf
+# Tunnel endpoint for Overlay P2P deployment scenario
+# used for br0
+VTEP_IP1 = '192.168.0.1/24'
+
+# Used as remote_ip in adding OVS tunnel port and
+# to set ARP entry in OVS (e.g. tnl/arp/set br-ext 192.168.240.10 02:00:00:00:00:02
+VTEP_IP2 = '192.168.240.10'
+
+# Network to use when adding a route for inner frame data
+VTEP_IP2_SUBNET = '192.168.240.0/24'
+
+# Bridge names
+TUNNEL_INTEGRATION_BRIDGE = 'br0'
+TUNNEL_EXTERNAL_BRIDGE = 'br-ext'
+
+# IP of br-ext
+TUNNEL_EXTERNAL_BRIDGE_IP = '192.168.240.1/24'
+
+# vxlan|gre|geneve
+TUNNEL_TYPE = 'vxlan'
+
+# Variables defined conf/integration/03_traffic.conf
+# For OP2P deployment scenario
+TRAFFICGEN_PORT1_MAC = '02:00:00:00:00:01'
+TRAFFICGEN_PORT2_MAC = '02:00:00:00:00:02'
+TRAFFICGEN_PORT1_IP = '1.1.1.1'
+TRAFFICGEN_PORT2_IP = '192.168.240.10'
+
+
+To run VXLAN encapsulation tests:
+
+ .. code-block:: console
+
+ ./vsperf --conf-file user_settings.py --run-integration --test-param 'tunnel_type=vxlan' overlay_p2p_tput
+
+To run GRE encapsulation tests:
+
+ .. code-block:: console
+
+ ./vsperf --conf-file user_settings.py --run-integration --test-param 'tunnel_type=gre' overlay_p2p_tput
+
+To run GENEVE encapsulation tests:
+
+ .. code-block:: console
+
+ ./vsperf --conf-file user_settings.py --run-integration --test-param 'tunnel_type=geneve' overlay_p2p_tput
+
+To run OVS NATIVE tunnel tests (VXLAN/GRE/GENEVE):
+
+1. Install the OVS kernel modules
+
+ .. code:: console
+
+ cd src/ovs/ovs
+ sudo -E make modules_install
+
+2. Set the following variables:
+
+ .. code-block:: console
+
+ VSWITCH = 'OvsVanilla'
+ VSWITCH_VANILLA_PHY_PORT_NAMES = ['nic1name', 'nic2name']
+ # Specify vport_* kernel module to test.
+ VSWITCH_VANILLA_KERNEL_MODULES = ['vport_vxlan',
+ 'vport_gre',
+ 'vport_geneve',
+ os.path.join(OVS_DIR_VANILLA, 'datapath/linux/openvswitch.ko')]
+
+3. Run tests:
+
+ .. code-block:: console
+
+ ./vsperf --conf-file user_settings.py --run-integration --test-param 'tunnel_type=vxlan' overlay_p2p_tput
+
+
diff --git a/src/ovs/ofctl.py b/src/ovs/ofctl.py
index 9d16ef76..43151d3a 100644
--- a/src/ovs/ofctl.py
+++ b/src/ovs/ofctl.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Intel Corporation.
+# Copyright 2015-2016 Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -31,6 +31,8 @@ _OVS_VSCTL_BIN = os.path.join(settings.getValue('OVS_DIR'), 'utilities',
'ovs-vsctl')
_OVS_OFCTL_BIN = os.path.join(settings.getValue('OVS_DIR'), 'utilities',
'ovs-ofctl')
+_OVS_APPCTL_BIN = os.path.join(settings.getValue('OVS_DIR'), 'utilities',
+ 'ovs-appctl')
_OVS_BRIDGE_NAME = settings.getValue('VSWITCH_BRIDGE_NAME')
@@ -63,6 +65,22 @@ class OFBase(object):
return tasks.run_task(
cmd, self.logger, 'Running ovs-vsctl...', check_error)
+
+ def run_appctl(self, args, check_error=False):
+ """Run ``ovs-appctl`` with supplied arguments.
+
+ :param args: Arguments to pass to ``ovs-appctl``
+ :param check_error: Throw exception on error
+
+ :return: None
+ """
+ cmd = ['sudo', _OVS_APPCTL_BIN,
+ '--timeout',
+ str(self.timeout)] + args
+ return tasks.run_task(
+ cmd, self.logger, 'Running ovs-appctl...', check_error)
+
+
# datapath management
def add_br(self, br_name=_OVS_BRIDGE_NAME, params=None):
@@ -90,6 +108,32 @@ class OFBase(object):
self.logger.debug('delete bridge')
self.run_vsctl(['del-br', br_name])
+ # Route and ARP functions
+
+ def add_route(self, network, destination):
+ """Add route to tunneling routing table.
+
+ :param network: Network
+ :param destination: Gateway
+
+ :return: None
+ """
+ self.logger.debug('add ovs/route')
+ self.run_appctl(['ovs/route/add', network, destination])
+
+
+ def set_tunnel_arp(self, ip_addr, mac_addr, br_name=_OVS_BRIDGE_NAME):
+ """Add OVS arp entry for tunneling
+
+ :param ip: IP of bridge
+ :param mac_addr: MAC address of the bridge
+ :param br_name: Name of the bridge
+
+ :return: None
+ """
+ self.logger.debug('tnl/arp/set')
+ self.run_appctl(['tnl/arp/set', br_name, ip_addr, mac_addr])
+
class OFBridge(OFBase):
"""Control a bridge instance using ``ovs-vsctl`` and ``ovs-ofctl``.
@@ -330,10 +374,10 @@ def flow_key(flow):
field_params.append('%(field)s=%(value)s' %
{'field': key, 'value': default})
- field_params = ','.join(field_params)
+ field_params_str = ','.join(field_params)
_flow_key_param = {
- 'fields': field_params,
+ 'fields': field_params_str,
}
# no actions == delete key
diff --git a/testcases/testcase.py b/testcases/testcase.py
index d470d951..945b8537 100644
--- a/testcases/testcase.py
+++ b/testcases/testcase.py
@@ -28,8 +28,8 @@ from core.loader import Loader
from tools import tasks
from tools import hugepages
from tools.report import report
-from conf import settings as S
from tools.pkt_gen.trafficgen.trafficgenhelper import TRAFFIC_DEFAULTS
+from conf import settings as S
from conf import get_test_param
class TestCase(object):
@@ -64,6 +64,11 @@ class TestCase(object):
self.deployment = cfg['Deployment']
self._frame_mod = cfg.get('Frame Modification', None)
+ tunnel_type = None
+ if 'Tunnel Type' in cfg:
+ tunnel_type = cfg['Tunnel Type']
+ tunnel_type = get_test_param('tunnel_type', tunnel_type)
+
# identify guest loopback method, so it can be added into reports
self.guest_loopback = []
if self.deployment in ['pvp', 'pvvp']:
@@ -102,6 +107,7 @@ class TestCase(object):
self._traffic.update({'traffic_type': traffic_type,
'flow_type': cfg.get('Flow Type', 'port'),
'bidir': bidirectional,
+ 'tunnel_type': tunnel_type,
'multistream': int(multistream),
'stream_type': stream_type,
'pre_installed_flows' : pre_installed_flows,
@@ -130,6 +136,17 @@ class TestCase(object):
# copy sources of l2 forwarding tools into VM shared dir if needed
self._copy_fwd_tools_for_guest()
+ if self.deployment == "op2p":
+ self._traffic['l2'].update({'srcmac':
+ S.getValue('TRAFFICGEN_PORT1_MAC'),
+ 'dstmac':
+ S.getValue('TRAFFICGEN_PORT2_MAC')})
+
+ self._traffic['l3'].update({'srcip':
+ S.getValue('TRAFFICGEN_PORT1_IP'),
+ 'dstip':
+ S.getValue('TRAFFICGEN_PORT2_IP')})
+
self._logger.debug("Controllers:")
loader = Loader()
traffic_ctl = component_factory.create_traffic(
diff --git a/vsperf b/vsperf
index 4b1d86d0..71ca2eb0 100755
--- a/vsperf
+++ b/vsperf
@@ -154,6 +154,7 @@ def parse_arguments():
name contains RFC2544 less those containing "p2p"')
group.add_argument('--verbosity', choices=list_logging_levels(),
help='debug level')
+ group.add_argument('--run-integration', action='store_true', help='run integration tests')
group.add_argument('--trafficgen', help='traffic generator to use')
group.add_argument('--vswitch', help='vswitch implementation to use')
group.add_argument('--fwdapp', help='packet forwarding application to use')
@@ -325,6 +326,10 @@ def main():
settings.load_from_dir('conf')
+ # Load non performance/integration tests
+ if args['run_integration']:
+ settings.load_from_dir('conf/integration')
+
# load command line parameters first in case there are settings files
# to be used
settings.load_from_dict(args)
@@ -455,6 +460,9 @@ def main():
else:
# configure tests
testcases = settings.getValue('PERFORMANCE_TESTS')
+ if args['run_integration']:
+ testcases = settings.getValue('INTEGRATION_TESTS')
+
all_tests = []
for cfg in testcases:
try:
diff --git a/vswitches/ovs_dpdk_vhost.py b/vswitches/ovs_dpdk_vhost.py
index 2c7b81ff..074e15f8 100644
--- a/vswitches/ovs_dpdk_vhost.py
+++ b/vswitches/ovs_dpdk_vhost.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Intel Corporation.
+# Copyright 2015-2016 Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ from vswitches.vswitch import IVSwitch
from src.ovs import VSwitchd, OFBridge
from src.dpdk import dpdk
-_VSWITCHD_CONST_ARGS = ['--', '--log-file']
+_VSWITCHD_CONST_ARGS = ['--', '--pidfile', '--log-file']
class OvsDpdkVhost(IVSwitch):
"""VSwitch implementation using DPDK and vhost ports
@@ -77,7 +77,7 @@ class OvsDpdkVhost(IVSwitch):
'datapath_type=netdev'])
else:
bridge.create(['--', 'set', 'bridge', switch_name,
- 'datapath_type=netdev'] + params)
+ 'datapath_type=netdev'] + params)
bridge.set_db_attribute('Open_vSwitch', '.',
'other_config:max-idle',
@@ -106,7 +106,7 @@ class OvsDpdkVhost(IVSwitch):
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')
+ dpdk_count = self._get_port_count('type=dpdk')
port_name = 'dpdk' + str(dpdk_count)
params = ['--', 'set', 'Interface', port_name, 'type=dpdk']
of_port = bridge.add_port(port_name, params)
@@ -123,11 +123,11 @@ class OvsDpdkVhost(IVSwitch):
bridge = self._bridges[switch_name]
# Changed dpdkvhost to dpdkvhostuser to be able to run in Qemu 2.2
if settings.getValue('VNF').endswith('Cuse'):
- vhost_count = self._get_port_count(bridge, 'type=dpdkvhostcuse')
+ vhost_count = self._get_port_count('type=dpdkvhostcuse')
port_name = 'dpdkvhostcuse' + str(vhost_count)
params = ['--', 'set', 'Interface', port_name, 'type=dpdkvhostcuse']
else:
- vhost_count = self._get_port_count(bridge, 'type=dpdkvhostuser')
+ vhost_count = self._get_port_count('type=dpdkvhostuser')
port_name = 'dpdkvhostuser' + str(vhost_count)
params = ['--', 'set', 'Interface', port_name, 'type=dpdkvhostuser']
@@ -135,6 +135,17 @@ class OvsDpdkVhost(IVSwitch):
return (port_name, of_port)
+ def add_tunnel_port(self, switch_name, remote_ip, tunnel_type='vxlan'):
+ """Creates tunneling port
+ """
+ bridge = self._bridges[switch_name]
+ pcount = str(self._get_port_count('type=' + tunnel_type))
+ port_name = tunnel_type + pcount
+ params = ['--', 'set', 'Interface', port_name, 'type=' + tunnel_type,
+ 'options:remote_ip=' + remote_ip]
+ of_port = bridge.add_port(port_name, params)
+ return (port_name, of_port)
+
def get_ports(self, switch_name):
"""See IVswitch for general description
"""
@@ -167,14 +178,31 @@ class OvsDpdkVhost(IVSwitch):
bridge = self._bridges[switch_name]
bridge.dump_flows()
- @staticmethod
- def _get_port_count(bridge, param):
+ def add_route(self, switch_name, network, destination):
+ """See IVswitch for general description
+ """
+ bridge = self._bridges[switch_name]
+ bridge.add_route(network, destination)
+
+ def set_tunnel_arp(self, ip_addr, mac_addr, switch_name):
+ """See IVswitch for general description
+ """
+ bridge = self._bridges[switch_name]
+ bridge.set_tunnel_arp(ip_addr, mac_addr, switch_name)
+
+ def _get_port_count(self, 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)
+ cnt = 0
+ for k in self._bridges:
+ pparams = [c for (_, (_, c)) in list(self._bridges[k].get_ports().items())]
+ phits = [i for i in pparams if param in i]
+ cnt += len(phits)
+
+ if cnt is None:
+ cnt = 0
+ return cnt
diff --git a/vswitches/ovs_vanilla.py b/vswitches/ovs_vanilla.py
index 3078de02..77d3deaf 100644
--- a/vswitches/ovs_vanilla.py
+++ b/vswitches/ovs_vanilla.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Intel Corporation.
+# Copyright 2015-2016 Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -150,6 +150,22 @@ class OvsVanilla(IVSwitch):
of_port = bridge.add_port(tap_name, [])
return (tap_name, of_port)
+ def add_tunnel_port(self, switch_name, remote_ip, tunnel_type='vxlan',
+ params=None):
+ """Creates tunneling port
+ """
+ bridge = self._bridges[switch_name]
+ pcount = str(self._get_port_count('type=' + tunnel_type))
+ port_name = tunnel_type + pcount
+ local_params = ['--', 'set', 'Interface', port_name,
+ 'type=' + tunnel_type,
+ 'options:remote_ip=' + remote_ip]
+
+ if params is not None:
+ local_params = local_params + params
+
+ of_port = bridge.add_port(port_name, local_params)
+ return (port_name, of_port)
def get_ports(self, switch_name):
"""See IVswitch for general description
@@ -182,3 +198,34 @@ class OvsVanilla(IVSwitch):
"""
bridge = self._bridges[switch_name]
bridge.dump_flows()
+
+ def add_route(self, switch_name, network, destination):
+ """See IVswitch for general description
+ """
+ bridge = self._bridges[switch_name]
+ bridge.add_route(network, destination)
+
+ def set_tunnel_arp(self, ip_addr, mac_addr, switch_name):
+ """See IVswitch for general description
+ """
+ bridge = self._bridges[switch_name]
+ bridge.set_tunnel_arp(ip_addr, mac_addr, switch_name)
+
+ def _get_port_count(self, 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
+ """
+ cnt = 0
+ for k in self._bridges:
+ pparams = [c for (_, (_, c)) in list(self._bridges[k].get_ports().items())]
+ phits = [i for i in pparams if param in i]
+ cnt += len(phits)
+
+ if cnt is None:
+ cnt = 0
+ return cnt
+
+
diff --git a/vswitches/vswitch.py b/vswitches/vswitch.py
index a28c0f6b..73e0a0c3 100644
--- a/vswitches/vswitch.py
+++ b/vswitches/vswitch.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Intel Corporation.
+# Copyright 2015-2016 Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -71,6 +71,14 @@ class IVSwitch(object):
"""
raise NotImplementedError()
+ def add_tunnel_port(self, switch_name, remote_ip, tunnel_type, params=None):
+ """Create a new port to the logical switch for tunneling
+
+ :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
@@ -128,3 +136,21 @@ class IVSwitch(object):
:param switch_name: The switch on which to operate
"""
raise NotImplementedError()
+
+ def add_route(self, switch_name, network, destination):
+ """Add a route for tunneling routing table
+
+ :param switch_name: The switch on which to operate
+ :param network: Target destination network
+ :param destination: Gateway IP
+ """
+ raise NotImplementedError()
+
+ def set_tunnel_arp(self, ip_addr, mac_addr, switch_name):
+ """Add arp entry for tunneling
+
+ :param ip_addr: IP of bridge
+ :param mac_addr: MAC address of the bridge
+ :param switch_name: Name of the bridge
+ """
+ raise NotImplementedError()