aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorMartin Klozik <martin.klozik@tieto.com>2018-05-15 01:42:35 -0700
committerMartin Klozik <martin.klozik@tieto.com>2018-05-28 05:48:23 -0700
commit63b56ed1d74657129006f066a3f118c4c369d23c (patch)
tree33624c57bbf9800668647da82bb9d6edbd1bcd93 /core
parentc79adfe7660ffa43f597af794412c0616a785943 (diff)
connections: Introduction of generic API
Redesign of vSwitch and vSwitch controller classes, to use generic connection methods for configuration of vSwitch. This API is more generic and vSwitch agnostic, thus deployment scenarios like P2P, PVP, PVVP (i.e. PVVPx) can be used for all (currently) supported vSwitches. Usage of new API will simplify an introduction of new vSwitches in the future. This patchset introduces following changes: * OVS: implementation of add_, del_, dump_ connection(s) and their validation methods * VPP: bidir parameter removed - it is up to the deployment scenario implementation to take care about bidirectional connections * P2P and PXP controllers were updated to use connection methods instead of flow related methods. Thus standard TCs will support both OVS and VPP. NOTE, PVPV is not supported for VPP (yet?). * refactoring of vSwitch interfaces and inherited classes * VPP step driven TCs were replaced by standard TCs with appropriate deployment scenarios. This is for backward compatibility with TC reporting. Once reporting of VPP TC results into results DB will be modified, this TCs can be removed. * OVS routing tables support was generalized to support P2P and PXP deployments and step driven TCs. Usage of OVS routing tables is now configurable (turned off by default) for better comparison of results among various vSwitches. * Multistream pre_installed_flows feature was generalized to support P2P and PXP deployments and step driven TCs. * IxNet: TRAFFIC['l4']['dstport'] will be used as a start value for port iteration if L4 multistream feature is enabled. * OVS: default flow template is now configurable via OVS_FLOW_TEMPLATE * OVS: support of TRAFFIC['flow_type']='ip' was generalized to work with connection methods (i.e. with P2P and PXP deployments and step driven TCs) * integration TCs: modification of integration TCs and their macros to utilize new generic connection based API * CI: list of TCs for VERIFY & MERGE jobs was changed to run the same generic tests for both OVS & VPP * documentation update * small fixes and improvements JIRA: VSPERF-579 Change-Id: If4e6e6037929eab9f16c2bbcb8a0fb30e5d6f9b0 Signed-off-by: Martin Klozik <martin.klozik@tieto.com> Reviewed-by: Richard Elias <richard.elias@tieto.com> Reviewed-by: Al Morton <acmorton@att.com> Reviewed-by: Christian Trautman <ctrautma@redhat.com> Reviewed-by: Sridhar Rao <sridhar.rao@spirent.com>
Diffstat (limited to 'core')
-rw-r--r--core/component_factory.py34
-rw-r--r--core/pktfwd_controller.py8
-rw-r--r--core/vswitch_controller.py44
-rw-r--r--core/vswitch_controller_clean.py30
-rw-r--r--core/vswitch_controller_op2p.py56
-rw-r--r--core/vswitch_controller_p2p.py132
-rw-r--r--core/vswitch_controller_ptunp.py60
-rw-r--r--core/vswitch_controller_pxp.py136
8 files changed, 144 insertions, 356 deletions
diff --git a/core/component_factory.py b/core/component_factory.py
index b6bd2677..2c51a060 100644
--- a/core/component_factory.py
+++ b/core/component_factory.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2017 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -66,23 +66,23 @@ def create_vswitch(deployment_scenario, vswitch_class, traffic,
:return: IVSwitchController for the deployment_scenario
"""
# pylint: disable=too-many-return-statements
- deployment_scenario = deployment_scenario.lower()
- if deployment_scenario.startswith("p2p"):
- return VswitchControllerP2P(vswitch_class, traffic)
- elif deployment_scenario.startswith("pvp"):
- return VswitchControllerPXP(deployment_scenario, vswitch_class, traffic)
- elif deployment_scenario.startswith("pvvp"):
- return VswitchControllerPXP(deployment_scenario, vswitch_class, traffic)
- elif deployment_scenario.startswith("pvpv"):
- return VswitchControllerPXP(deployment_scenario, vswitch_class, traffic)
- elif deployment_scenario.startswith("op2p"):
- return VswitchControllerOP2P(vswitch_class, traffic, tunnel_operation)
- elif deployment_scenario.startswith("ptunp"):
- return VswitchControllerPtunP(vswitch_class, traffic)
- elif deployment_scenario.startswith("clean"):
- return VswitchControllerClean(vswitch_class, traffic)
+ deployment = deployment_scenario.lower()
+ if deployment.startswith("p2p"):
+ return VswitchControllerP2P(deployment, vswitch_class, traffic)
+ elif deployment.startswith("pvp"):
+ return VswitchControllerPXP(deployment, vswitch_class, traffic)
+ elif deployment.startswith("pvvp"):
+ return VswitchControllerPXP(deployment, vswitch_class, traffic)
+ elif deployment.startswith("pvpv"):
+ return VswitchControllerPXP(deployment, vswitch_class, traffic)
+ elif deployment.startswith("op2p"):
+ return VswitchControllerOP2P(deployment, vswitch_class, traffic, tunnel_operation)
+ elif deployment.startswith("ptunp"):
+ return VswitchControllerPtunP(deployment, vswitch_class, traffic)
+ elif deployment.startswith("clean"):
+ return VswitchControllerClean(deployment, vswitch_class, traffic)
else:
- raise RuntimeError("Unknown deployment scenario '{}'.".format(deployment_scenario))
+ raise RuntimeError("Unknown deployment scenario '{}'.".format(deployment))
def create_vnf(deployment_scenario, vnf_class, extra_vnfs):
diff --git a/core/pktfwd_controller.py b/core/pktfwd_controller.py
index bdc91822..363302c3 100644
--- a/core/pktfwd_controller.py
+++ b/core/pktfwd_controller.py
@@ -1,4 +1,4 @@
-# Copyright 2016 Intel Corporation.
+# Copyright 2016-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -89,9 +89,9 @@ class PktFwdController(object):
"""
return self._pktfwd
- def dump_vswitch_flows(self):
- """ Dumps flows from vswitch
+ def dump_vswitch_connections(self):
+ """ Dumps connections from vswitch
"""
raise NotImplementedError(
"The PktFwdController does not implement the "
- "\"dump_vswitch_flows\" function.")
+ "\"dump_vswitch_connections\" function.")
diff --git a/core/vswitch_controller.py b/core/vswitch_controller.py
index 855de8b2..889f14bc 100644
--- a/core/vswitch_controller.py
+++ b/core/vswitch_controller.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,33 +13,57 @@
# limitations under the License.
"""Interface for deployment specific vSwitch controllers
"""
+import logging
class IVswitchController(object):
- """Abstract class which defines a vSwitch controller object
+ """Interface class for a vSwitch controller object
This interface is used to setup and control a vSwitch provider for a
particular deployment scenario.
"""
- def __enter__(self):
+ def __init__(self, deployment, vswitch_class, traffic):
+ """Initializes up the generic prerequisites for deployment scenario.
+
+ :deployment: the deployment scenario to configure
+ :vswitch_class: the vSwitch class to be used.
+ :traffic: dictionary with detailed traffic definition
+ """
+ self._logger = logging.getLogger(__name__)
+ self._vswitch_class = vswitch_class
+ self._vswitch = vswitch_class()
+ self._deployment_scenario = deployment
+ self._logger.debug('Creation using %s', str(self._vswitch_class))
+ self._traffic = traffic.copy()
+ self._bridge = None
+
+ def setup(self):
"""Sets up the switch for the particular deployment scenario
"""
raise NotImplementedError(
"The VswitchController does not implement the \"setup\" function.")
- def __exit__(self, type_, value, traceback):
+ def stop(self):
"""Tears down the switch created in setup()
"""
raise NotImplementedError(
"The VswitchController does not implement the \"stop\" function.")
+ def __enter__(self):
+ """Sets up the switch for the particular deployment scenario
+ """
+ self.setup()
+
+ def __exit__(self, type_, value, traceback):
+ """Tears down the switch created in setup()
+ """
+ self.stop()
+
def get_vswitch(self):
"""Get the controlled vSwitch
:return: The controlled IVswitch
"""
- raise NotImplementedError(
- "The VswitchController does not implement the \"get_vswitch\" "
- "function.")
+ return self._vswitch
def get_ports_info(self):
"""Returns a dictionary describing all ports on the vSwitch.
@@ -50,9 +74,9 @@ class IVswitchController(object):
"The VswitchController does not implement the \"get_ports_info\" "
"function.")
- def dump_vswitch_flows(self):
- """ Dumps flows from vswitch
+ def dump_vswitch_connections(self):
+ """ Dumps connections from vswitch
"""
raise NotImplementedError(
"The VswitchController does not implement the "
- "\"dump_vswitch_flows\" function.")
+ "\"dump_vswitch_connections\" function.")
diff --git a/core/vswitch_controller_clean.py b/core/vswitch_controller_clean.py
index 432406a7..7a771226 100644
--- a/core/vswitch_controller_clean.py
+++ b/core/vswitch_controller_clean.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2016 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,9 +14,6 @@
"""VSwitch controller for basic initialization of vswitch
"""
-
-import logging
-
from core.vswitch_controller import IVswitchController
class VswitchControllerClean(IVswitchController):
@@ -28,18 +25,6 @@ class VswitchControllerClean(IVswitchController):
_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 Clean 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 = "Clean"
- self._logger.debug('Creation using %s', str(self._vswitch_class))
- self._traffic = traffic.copy()
-
def setup(self):
"""Sets up the switch for Clean.
"""
@@ -57,23 +42,12 @@ class VswitchControllerClean(IVswitchController):
self._logger.debug('Stop using %s', 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
"""
pass
- def dump_vswitch_flows(self):
+ def dump_vswitch_connections(self):
"""See IVswitchController for description
"""
pass
diff --git a/core/vswitch_controller_op2p.py b/core/vswitch_controller_op2p.py
index 3f879f9f..072a690a 100644
--- a/core/vswitch_controller_op2p.py
+++ b/core/vswitch_controller_op2p.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2017 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,39 +14,19 @@
"""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 as S
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, tunnel_operation=None):
- """Initializes up the prerequisites for the OP2P deployment scenario.
-
- :vswitch_class: the vSwitch class to be used.
+ def __init__(self, deployment, vswitch_class, traffic, tunnel_operation=None):
+ """See IVswitchController for general description
"""
- self._logger = logging.getLogger(__name__)
- self._vswitch_class = vswitch_class
- self._vswitch = vswitch_class()
- self._deployment_scenario = "OP2P"
- self._traffic = traffic.copy()
+ super().__init__(deployment, vswitch_class, traffic)
self._tunnel_operation = tunnel_operation
- self._logger.debug('Creation using %s', str(self._vswitch_class))
def setup(self):
""" Sets up the switch for overlay P2P (tunnel encap or decap)
@@ -118,10 +98,13 @@ class VswitchControllerOP2P(IVswitchController):
# Test is unidirectional for now
self._vswitch.del_flow(bridge)
- flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy1_number,
+ flow1 = add_ports_to_flow(S.getValue('OVS_FLOW_TEMPLATE'), phy1_number,
phy2_number)
self._vswitch.add_flow(bridge, flow1)
-
+ # enable MAC learning mode at external bridge
+ flow_ext = S.getValue('OVS_FLOW_TEMPLATE').copy()
+ flow_ext.update({'actions': ['NORMAL']})
+ self._vswitch.add_flow(bridge_ext, flow_ext)
except:
self._vswitch.stop()
raise
@@ -178,7 +161,7 @@ class VswitchControllerOP2P(IVswitchController):
bridge)
# Test is unidirectional for now
self._vswitch.del_flow(bridge_ext)
- flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy3_number,
+ flow1 = add_ports_to_flow(S.getValue('OVS_FLOW_TEMPLATE'), phy3_number,
phy2_number)
self._vswitch.add_flow(bridge_ext, flow1)
@@ -251,7 +234,7 @@ class VswitchControllerOP2P(IVswitchController):
# Test is unidirectional for now
self._vswitch.del_flow(bridge_ext)
- flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy2_number, 'LOCAL')
+ flow1 = add_ports_to_flow(S.getValue('OVS_FLOW_TEMPLATE'), phy2_number, 'LOCAL')
self._vswitch.add_flow(bridge_ext, flow1)
except:
@@ -264,17 +247,6 @@ class VswitchControllerOP2P(IVswitchController):
self._logger.debug('Stop using %s', 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
"""
@@ -286,8 +258,8 @@ class VswitchControllerOP2P(IVswitchController):
self._vswitch.get_ports(
S.getValue('TUNNEL_EXTERNAL_BRIDGE'))
- def dump_vswitch_flows(self):
+ def dump_vswitch_connections(self):
"""See IVswitchController for description
"""
- self._vswitch.dump_flows(S.getValue('TUNNEL_INTEGRATION_BRIDGE'))
- self._vswitch.dump_flows(S.getValue('TUNNEL_EXTERNAL_BRIDGE'))
+ self._vswitch.dump_connections(S.getValue('TUNNEL_INTEGRATION_BRIDGE'))
+ self._vswitch.dump_connections(S.getValue('TUNNEL_EXTERNAL_BRIDGE'))
diff --git a/core/vswitch_controller_p2p.py b/core/vswitch_controller_p2p.py
index eb1f57f0..d8f22e4c 100644
--- a/core/vswitch_controller_p2p.py
+++ b/core/vswitch_controller_p2p.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2017 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,20 +14,9 @@
"""VSwitch controller for Physical to Physical deployment
"""
-
-import logging
-import netaddr
-
from core.vswitch_controller import IVswitchController
from conf import settings
-_FLOW_TEMPLATE = {
- 'idle_timeout': '0'
-}
-
-_PROTO_TCP = 6
-_PROTO_UDP = 17
-
class VswitchControllerP2P(IVswitchController):
"""VSwitch controller for P2P deployment scenario.
@@ -37,17 +26,11 @@ class VswitchControllerP2P(IVswitchController):
_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 P2P deployment scenario.
-
- :vswitch_class: the vSwitch class to be used.
+ def __init__(self, deployment, vswitch_class, traffic):
+ """See IVswitchController for general description
"""
- self._logger = logging.getLogger(__name__)
- self._vswitch_class = vswitch_class
- self._vswitch = vswitch_class()
- self._deployment_scenario = "P2P"
- self._logger.debug('Creation using %s', str(self._vswitch_class))
- self._traffic = traffic.copy()
+ super().__init__(deployment, vswitch_class, traffic)
+ self._bridge = settings.getValue('VSWITCH_BRIDGE_NAME')
def setup(self):
"""Sets up the switch for p2p.
@@ -57,51 +40,14 @@ class VswitchControllerP2P(IVswitchController):
try:
self._vswitch.start()
- bridge = settings.getValue('VSWITCH_BRIDGE_NAME')
- self._vswitch.add_switch(bridge)
-
- (_, _) = self._vswitch.add_phy_port(bridge)
- (_, _) = self._vswitch.add_phy_port(bridge)
-
- self._vswitch.del_flow(bridge)
-
- # table#0 - flows designed to force 5 & 13 tuple matches go here
- flow = {'table':'0', 'priority':'1', 'actions': ['goto_table:1']}
- self._vswitch.add_flow(bridge, flow)
-
- # table#1 - flows to route packets between ports goes here. The
- # chosen port is communicated to subsequent tables by setting the
- # metadata value to the egress port number
+ self._vswitch.add_switch(self._bridge)
- # configure flows according to the TC definition
- flow_template = _FLOW_TEMPLATE.copy()
- if self._traffic['flow_type'] == 'IP':
- flow_template.update({'dl_type':'0x0800', 'nw_src':self._traffic['l3']['srcip'],
- 'nw_dst':self._traffic['l3']['dstip']})
+ (port1, _) = self._vswitch.add_phy_port(self._bridge)
+ (port2, _) = self._vswitch.add_phy_port(self._bridge)
- flow = flow_template.copy()
- flow.update({'table':'1', 'priority':'1', 'in_port':'1',
- 'actions': ['write_actions(output:2)', 'write_metadata:0x2',
- 'goto_table:2']})
- self.process_flow_template(bridge, flow)
- flow = flow_template.copy()
- flow.update({'table':'1', 'priority':'1', 'in_port':'2',
- 'actions': ['write_actions(output:1)', 'write_metadata:0x1',
- 'goto_table:2']})
- self.process_flow_template(bridge, flow)
+ self._vswitch.add_connection(self._bridge, port1, port2, self._traffic)
+ self._vswitch.add_connection(self._bridge, port2, port1, self._traffic)
- # Frame modification table. Frame modification flow rules are
- # isolated in this table so that they can be turned on or off
- # without affecting the routing or tuple-matching flow rules.
- flow = {'table':'2', 'priority':'1', 'actions': ['goto_table:3']}
- self._vswitch.add_flow(bridge, flow)
-
- # Egress table
- # (TODO) Billy O'Mahony - the drop action here actually required in
- # order to egress the packet. This is the subject of a thread on
- # ovs-discuss 2015-06-30.
- flow = {'table':'3', 'priority':'1', 'actions': ['drop']}
- self._vswitch.add_flow(bridge, flow)
except:
self._vswitch.stop()
raise
@@ -112,65 +58,13 @@ class VswitchControllerP2P(IVswitchController):
self._logger.debug('Stop using %s', 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 %s', str(self._vswitch_class))
- return self._vswitch.get_ports(settings.getValue('VSWITCH_BRIDGE_NAME'))
+ return self._vswitch.get_ports(self._bridge)
- def dump_vswitch_flows(self):
+ def dump_vswitch_connections(self):
"""See IVswitchController for description
"""
- self._vswitch.dump_flows(settings.getValue('VSWITCH_BRIDGE_NAME'))
-
- def process_flow_template(self, bridge, flow_template):
- """Method adds flows into the vswitch based on given flow template
- and configuration of multistream feature.
- """
- if ('pre_installed_flows' in self._traffic and
- self._traffic['pre_installed_flows'].lower() == 'yes' and
- 'multistream' in self._traffic and self._traffic['multistream'] > 0 and
- 'stream_type' in self._traffic):
- # multistream feature is enabled and flows should be inserted into OVS
- # so generate flows based on template and multistream configuration
- if self._traffic['stream_type'] == 'L2':
- # iterate through destimation MAC address
- dst_mac_value = netaddr.EUI(self._traffic['l2']['dstmac']).value
- for i in range(self._traffic['multistream']):
- tmp_mac = netaddr.EUI(dst_mac_value + i)
- tmp_mac.dialect = netaddr.mac_unix_expanded
- flow_template.update({'dl_dst':tmp_mac})
- # optimize flow insertion by usage of cache
- self._vswitch.add_flow(bridge, flow_template, cache='on')
- elif self._traffic['stream_type'] == 'L3':
- # iterate through destimation IP address
- dst_ip_value = netaddr.IPAddress(self._traffic['l3']['dstip']).value
- for i in range(self._traffic['multistream']):
- tmp_ip = netaddr.IPAddress(dst_ip_value + i)
- flow_template.update({'dl_type':'0x0800', 'nw_dst':tmp_ip})
- # optimize flow insertion by usage of cache
- self._vswitch.add_flow(bridge, flow_template, cache='on')
- elif self._traffic['stream_type'] == 'L4':
- # read transport protocol from configuration and iterate through its destination port
- proto = _PROTO_TCP if self._traffic['l3']['proto'].lower() == 'tcp' else _PROTO_UDP
- for i in range(self._traffic['multistream']):
- flow_template.update({'dl_type':'0x0800', 'nw_proto':proto, 'tp_dst':i})
- # optimize flow insertion by usage of cache
- self._vswitch.add_flow(bridge, flow_template, cache='on')
- else:
- self._logger.error('Stream type is set to uknown value %s', self._traffic['stream_type'])
- # insert cached flows into the OVS
- self._vswitch.add_flow(bridge, [], cache='flush')
- else:
- self._vswitch.add_flow(bridge, flow_template)
+ self._vswitch.dump_connections(self._bridge)
diff --git a/core/vswitch_controller_ptunp.py b/core/vswitch_controller_ptunp.py
index 853c7d5c..b10da2a9 100644
--- a/core/vswitch_controller_ptunp.py
+++ b/core/vswitch_controller_ptunp.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2016 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,8 +15,6 @@
"""VSwitch controller for Physical to VxLAN Tunnel Endpoint to Physical
deployment with mod operation.
"""
-
-import logging
from netaddr import EUI, IPNetwork, mac_unix
from core.vswitch_controller import IVswitchController
@@ -24,10 +22,6 @@ from vswitches.utils import add_ports_to_flow
from conf import settings
from tools import tasks
-_FLOW_TEMPLATE = {
- 'idle_timeout': '0'
-}
-
class VswitchControllerPtunP(IVswitchController):
"""VSwitch controller for VxLAN ptunp deployment scenario.
The deployment scenario is to test VxLAN tunneling feature without using an
@@ -40,16 +34,10 @@ class VswitchControllerPtunP(IVswitchController):
_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 ptunp deployment scenario.
-
- :vswitch_class: the vSwitch class to be used.
+ def __init__(self, deployment, vswitch_class, traffic):
+ """See IVswitchController for general description
"""
- self._logger = logging.getLogger(__name__)
- self._vswitch_class = vswitch_class
- self._vswitch = vswitch_class()
- self._deployment_scenario = "ptunp"
- self._traffic = traffic.copy()
+ super().__init__(deployment, vswitch_class, traffic)
self.bridge_phy1 = settings.getValue('TUNNEL_EXTERNAL_BRIDGE1')
self.bridge_phy2 = settings.getValue('TUNNEL_EXTERNAL_BRIDGE2')
self.bridge_mod1 = settings.getValue('TUNNEL_MODIFY_BRIDGE1')
@@ -59,7 +47,6 @@ class VswitchControllerPtunP(IVswitchController):
self.br_mod_ip1 = settings.getValue('TUNNEL_MODIFY_BRIDGE_IP1')
self.br_mod_ip2 = settings.getValue('TUNNEL_MODIFY_BRIDGE_IP2')
self.tunnel_type = settings.getValue('TUNNEL_TYPE')
- self._logger.debug('Creation using %s', str(self._vswitch_class))
def setup(self):
""" Sets up the switch for VxLAN overlay PTUNP (tunnel encap or decap)
@@ -156,23 +143,23 @@ class VswitchControllerPtunP(IVswitchController):
self._vswitch.del_flow(self.bridge_phy2)
self._vswitch.del_flow(self.bridge_mod1)
self._vswitch.del_flow(self.bridge_mod2)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy1_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy1_number,
phy3_number)
self._vswitch.add_flow(self.bridge_phy1, flow)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy3_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy3_number,
phy1_number)
self._vswitch.add_flow(self.bridge_phy1, flow)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy2_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy2_number,
phy4_number)
self._vswitch.add_flow(self.bridge_phy2, flow)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy4_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy4_number,
phy2_number)
self._vswitch.add_flow(self.bridge_phy2, flow)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy5_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy5_number,
'LOCAL')
self._vswitch.add_flow(self.bridge_mod1, flow)
- mod_flow_template = _FLOW_TEMPLATE.copy()
+ mod_flow_template = settings.getValue('OVS_FLOW_TEMPLATE').copy()
mod_flow_template.update({'ip':'',
'actions':
['mod_dl_src:' + str(vxlan_rem_mac2),
@@ -183,10 +170,10 @@ class VswitchControllerPtunP(IVswitchController):
})
flow = add_ports_to_flow(mod_flow_template, 'LOCAL', phy5_number)
self._vswitch.add_flow(self.bridge_mod1, flow)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy6_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy6_number,
'LOCAL')
self._vswitch.add_flow(self.bridge_mod2, flow)
- mod_flow_template = _FLOW_TEMPLATE.copy()
+ mod_flow_template = settings.getValue('OVS_FLOW_TEMPLATE').copy()
mod_flow_template.update({'ip':'',
'actions':
['mod_dl_src:' + str(vxlan_rem_mac1),
@@ -207,17 +194,6 @@ class VswitchControllerPtunP(IVswitchController):
self._logger.debug('Stop using %s', 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
"""
@@ -228,11 +204,11 @@ class VswitchControllerPtunP(IVswitchController):
self._vswitch.get_ports(self.bridge_mod2)
return ports
- def dump_vswitch_flows(self):
+ def dump_vswitch_connections(self):
"""See IVswitchController for description
"""
- self._logger.debug('dump_flows using %s', str(self._vswitch_class))
- self._vswitch.dump_flows(self.bridge_phy1)
- self._vswitch.dump_flows(self.bridge_mod1)
- self._vswitch.dump_flows(self.bridge_phy2)
- self._vswitch.dump_flows(self.bridge_mod2)
+ self._logger.debug('dump_connections using %s', str(self._vswitch_class))
+ self._vswitch.dump_connections(self.bridge_phy1)
+ self._vswitch.dump_connections(self.bridge_mod1)
+ self._vswitch.dump_connections(self.bridge_phy2)
+ self._vswitch.dump_connections(self.bridge_mod2)
diff --git a/core/vswitch_controller_pxp.py b/core/vswitch_controller_pxp.py
index e3c208a3..d36ecdba 100644
--- a/core/vswitch_controller_pxp.py
+++ b/core/vswitch_controller_pxp.py
@@ -1,4 +1,4 @@
-# Copyright 2016 Intel Corporation.
+# Copyright 2016-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,34 +14,18 @@
"""VSwitch controller for multi VM scenarios with serial or parallel connection
"""
-
-import logging
import netaddr
from core.vswitch_controller import IVswitchController
-from vswitches.utils import add_ports_to_flow
from conf import settings
-_FLOW_TEMPLATE = {
- 'idle_timeout': '0'
-}
-
-_PROTO_TCP = 6
-_PROTO_UDP = 17
-
class VswitchControllerPXP(IVswitchController):
"""VSwitch controller for PXP deployment scenario.
"""
def __init__(self, deployment, vswitch_class, traffic):
- """Initializes up the prerequisites for the PXP deployment scenario.
-
- :vswitch_class: the vSwitch class to be used.
- :deployment: the deployment scenario to configure
- :traffic: dictionary with detailed traffic definition
+ """See IVswitchController for general description
"""
- self._logger = logging.getLogger(__name__)
- self._vswitch_class = vswitch_class
- self._vswitch = vswitch_class()
+ super().__init__(deployment, vswitch_class, traffic)
self._pxp_topology = 'parallel' if deployment.startswith('pvpv') else 'serial'
if deployment == 'pvp':
self._pxp_vm_count = 1
@@ -55,9 +39,7 @@ class VswitchControllerPXP(IVswitchController):
self._deployment_scenario = deployment
- self._traffic = traffic.copy()
self._bidir = True if self._traffic['bidir'] == 'True' else False
- self._logger.debug('Creation using %s', str(self._vswitch_class))
self._bridge = settings.getValue('VSWITCH_BRIDGE_NAME')
def setup(self):
@@ -71,8 +53,8 @@ class VswitchControllerPXP(IVswitchController):
self._vswitch.add_switch(self._bridge)
# create physical ports
- (_, phy1_number) = self._vswitch.add_phy_port(self._bridge)
- (_, phy2_number) = self._vswitch.add_phy_port(self._bridge)
+ (phy1, _) = self._vswitch.add_phy_port(self._bridge)
+ (phy2, _) = self._vswitch.add_phy_port(self._bridge)
# create VM ports
# initialize vport array to requested number of VMs
@@ -86,54 +68,42 @@ class VswitchControllerPXP(IVswitchController):
self._logger.debug('Create %s vports for %s. VM with index %s',
nics_nr, vmindex + 1, vmindex)
for _ in range(nics_nr):
- (_, vport) = self._vswitch.add_vport(self._bridge)
+ (vport, _) = self._vswitch.add_vport(self._bridge)
vm_ports[vmindex].append(vport)
- self._vswitch.del_flow(self._bridge)
-
- # configure flows according to the TC definition
+ # configure connections according to the TC definition
if self._pxp_topology == 'serial':
- flow = _FLOW_TEMPLATE.copy()
- if self._traffic['flow_type'] == 'IP':
- flow.update({'dl_type':'0x0800',
- 'nw_src':self._traffic['l3']['srcip'],
- 'nw_dst':self._traffic['l3']['dstip']})
+ # NOTE: all traffic from VMs is sent to other ports directly
+ # without applying traffic options to avoid issues with MAC swapping
+ # and upper layer mods performed inside guests
- # insert flows for phy ports first
+ # insert connections for phy ports first
# from 1st PHY to 1st vport of 1st VM
- self._add_flow(flow,
- phy1_number,
- vm_ports[0][0],
- self._bidir)
+ self._vswitch.add_connection(self._bridge, phy1, vm_ports[0][0], self._traffic)
+ self._vswitch.add_connection(self._bridge, vm_ports[0][0], phy1)
# from last vport of last VM to 2nd phy
- self._add_flow(flow,
- vm_ports[self._pxp_vm_count-1][-1],
- phy2_number,
- self._bidir)
+ self._vswitch.add_connection(self._bridge, vm_ports[self._pxp_vm_count-1][-1], phy2)
+ self._vswitch.add_connection(self._bridge, phy2, vm_ports[self._pxp_vm_count-1][-1], self._traffic)
# add serial connections among VMs and VM NICs pairs if needed
# in case of multiple NICs pairs per VM, the pairs are chained
- # first, before flow to the next VM is created
+ # first, before connection to the next VM is created
for vmindex in range(self._pxp_vm_count):
# connect VMs NICs pairs in case of 4 and more NICs per VM
connections = [(vm_ports[vmindex][2*(x+1)-1],
vm_ports[vmindex][2*(x+1)])
for x in range(int(len(vm_ports[vmindex])/2)-1)]
for connection in connections:
- self._add_flow(flow,
- connection[0],
- connection[1],
- self._bidir)
+ self._vswitch.add_connection(self._bridge, connection[0], connection[1])
+ self._vswitch.add_connection(self._bridge, connection[1], connection[0])
# connect last NICs to the next VM if there is any
if self._pxp_vm_count > vmindex + 1:
- self._add_flow(flow,
- vm_ports[vmindex][-1],
- vm_ports[vmindex+1][0],
- self._bidir)
+ self._vswitch.add_connection(self._bridge, vm_ports[vmindex][-1], vm_ports[vmindex+1][0])
+ self._vswitch.add_connection(self._bridge, vm_ports[vmindex+1][0], vm_ports[vmindex][-1])
else:
- proto = _PROTO_TCP if self._traffic['l3']['proto'].lower() == 'tcp' else _PROTO_UDP
- dst_mac_value = netaddr.EUI(self._traffic['l2']['dstmac']).value
- dst_ip_value = netaddr.IPAddress(self._traffic['l3']['dstip']).value
+ mac_value = netaddr.EUI(self._traffic['l2']['dstmac']).value
+ ip_value = netaddr.IPAddress(self._traffic['l3']['dstip']).value
+ port_value = self._traffic['l4']['dstport']
# initialize stream index; every NIC pair of every VM uses unique stream
stream = 0
for vmindex in range(self._pxp_vm_count):
@@ -146,31 +116,33 @@ class VswitchControllerPXP(IVswitchController):
port_pairs = [(vm_ports[vmindex][0], vm_ports[vmindex][0])]
for port_pair in port_pairs:
- flow_p = _FLOW_TEMPLATE.copy()
- flow_v = _FLOW_TEMPLATE.copy()
-
- # update flow based on trafficgen settings
+ # override traffic options to ensure, that traffic is
+ # dispatched among VMs connected in parallel
+ options = {'multistream':1,
+ 'stream_type':self._traffic['stream_type'],
+ 'pre_installed_flows':'Yes'}
+ # update connection based on trafficgen settings
if self._traffic['stream_type'] == 'L2':
- tmp_mac = netaddr.EUI(dst_mac_value + stream)
+ tmp_mac = netaddr.EUI(mac_value + stream)
tmp_mac.dialect = netaddr.mac_unix_expanded
- flow_p.update({'dl_dst':tmp_mac})
+ options.update({'l2':{'dstmac':tmp_mac}})
elif self._traffic['stream_type'] == 'L3':
- tmp_ip = netaddr.IPAddress(dst_ip_value + stream)
- flow_p.update({'dl_type':'0x0800', 'nw_dst':tmp_ip})
+ tmp_ip = netaddr.IPAddress(ip_value + stream)
+ options.update({'l3':{'dstip':tmp_ip}})
elif self._traffic['stream_type'] == 'L4':
- flow_p.update({'dl_type':'0x0800', 'nw_proto':proto, 'tp_dst':stream})
+ options.update({'l3':{'proto':self._traffic['l3']['proto']}})
+ options.update({'l4':{'dstport':(port_value + stream) % 65536}})
else:
raise RuntimeError('Unknown stream_type {}'.format(self._traffic['stream_type']))
- # insert flow to dispatch traffic from physical ports
+ # insert connection to dispatch traffic from physical ports
# to VMs based on stream type; all traffic from VMs is
# sent to physical ports to avoid issues with MAC swapping
# and upper layer mods performed inside guests
- self._add_flow(flow_p, phy1_number, port_pair[0])
- self._add_flow(flow_v, port_pair[1], phy2_number)
- if self._bidir:
- self._add_flow(flow_p, phy2_number, port_pair[1])
- self._add_flow(flow_v, port_pair[0], phy1_number)
+ self._vswitch.add_connection(self._bridge, phy1, port_pair[0], options)
+ self._vswitch.add_connection(self._bridge, port_pair[1], phy2)
+ self._vswitch.add_connection(self._bridge, phy2, port_pair[1], options)
+ self._vswitch.add_connection(self._bridge, port_pair[0], phy1)
# every NIC pair needs its own unique traffic stream
stream += 1
@@ -185,37 +157,13 @@ class VswitchControllerPXP(IVswitchController):
self._logger.debug('Stop using %s', str(self._vswitch_class))
self._vswitch.stop()
- def _add_flow(self, flow, port1, port2, reverse_flow=False):
- """ Helper method to insert flow into the vSwitch
- """
- self._vswitch.add_flow(self._bridge,
- add_ports_to_flow(flow,
- port1,
- port2))
- if reverse_flow:
- self._vswitch.add_flow(self._bridge,
- add_ports_to_flow(flow,
- port2,
- port1))
-
- 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 %s', str(self._vswitch_class))
return self._vswitch.get_ports(self._bridge)
- def dump_vswitch_flows(self):
+ def dump_vswitch_connections(self):
"""See IVswitchController for description
"""
- self._vswitch.dump_flows(self._bridge)
+ self._vswitch.dump_connections(self._bridge)