From 3572d56f5733592db30f0df2273fe93e731cba2d Mon Sep 17 00:00:00 2001 From: Martin Klozik Date: Tue, 13 Oct 2015 06:35:33 +0100 Subject: Flow Classification extension Flow definition can be changed by testcase setup. By default only ingress ports are used to route traffic, but flow can be extended by src and dst IP addresses used by the traffic generator. Change-Id: I694714537ad2d818192a39f3235d8e6bf0f59a49 JIRA: VSPERF-90 Signed-off-by: Martin Klozik Reviewed-by: Billy O Mahony Reviewed-by: Maryam Tahhan Reviewed-by: Fatih Degirmenci Reviewed-by: Gene Snider Reviewed-by: Al Morton Reviewed-by: Tv Rao Reviewed-by: Brian Castelli --- conf/01_testcases.conf | 8 +++++++- core/component_factory.py | 9 +++++---- core/vswitch_controller_p2p.py | 24 ++++++++++++++++------- core/vswitch_controller_pvp.py | 21 ++++++++++++++------- core/vswitch_controller_pvvp.py | 25 +++++++++++++++--------- testcases/testcase.py | 42 +++++++++++++++++++---------------------- 6 files changed, 78 insertions(+), 51 deletions(-) diff --git a/conf/01_testcases.conf b/conf/01_testcases.conf index 39e924bd..88001459 100755 --- a/conf/01_testcases.conf +++ b/conf/01_testcases.conf @@ -31,9 +31,15 @@ # "MultiStream": 0-65535 # Optional. Defines number of flows simulated # # by traffic generator. Value 0 disables # # MultiStream feature +# "Flow Type": ["port"|"IP"] # Optional. Defines flows complexity. In case +# # it isn't specified, then "port" will be used. +# # Values: +# # "port" - flow is defined by ingress ports +# # "IP" - flow is defined by ingress ports +# # and src and dst IP addresses # "Load": dictionary # Optional. Configures background load # # during testcase execution. -# Descritopn of "Load" dictionary keys, their meanings and available values: +# Description of "Load" dictionary keys, their meanings and available values: # # "tool": "stress" # One of the supported load generators. # "load": 0-100 # percentage of cores which should be diff --git a/core/component_factory.py b/core/component_factory.py index 4da37fb7..21cdd61d 100644 --- a/core/component_factory.py +++ b/core/component_factory.py @@ -47,7 +47,7 @@ def create_traffic(traffic_type, trafficgen_class): return TrafficControllerRFC2544(trafficgen_class) -def create_vswitch(deployment_scenario, vswitch_class, bidir=True): +def create_vswitch(deployment_scenario, vswitch_class, traffic): """Return a new IVSwitchController for the deployment_scenario. The returned controller is configured with the given vSwitch class. @@ -56,15 +56,16 @@ def create_vswitch(deployment_scenario, vswitch_class, bidir=True): :param deployment_scenario: The deployment scenario name :param vswitch_class: Reference to vSwitch class to be used. + :param traffic: Dictionary with traffic specific details :return: IVSwitchController for the deployment_scenario """ deployment_scenario = deployment_scenario.lower() if deployment_scenario.find("p2p") >= 0: - return VswitchControllerP2P(vswitch_class) + return VswitchControllerP2P(vswitch_class, traffic) elif deployment_scenario.find("pvp") >= 0: - return VswitchControllerPVP(vswitch_class, bidir) + return VswitchControllerPVP(vswitch_class, traffic) elif deployment_scenario.find("pvvp") >= 0: - return VswitchControllerPVVP(vswitch_class, bidir) + return VswitchControllerPVVP(vswitch_class, traffic) def create_vnf(deployment_scenario, vnf_class): """Return a new VnfController for the deployment_scenario. diff --git a/core/vswitch_controller_p2p.py b/core/vswitch_controller_p2p.py index 35600e1b..236a443a 100644 --- a/core/vswitch_controller_p2p.py +++ b/core/vswitch_controller_p2p.py @@ -33,7 +33,7 @@ class VswitchControllerP2P(IVswitchController): _deployment_scenario: A string describing the scenario to set-up in the constructor. """ - def __init__(self, vswitch_class): + def __init__(self, vswitch_class, traffic): """Initializes up the prerequisites for the P2P deployment scenario. :vswitch_class: the vSwitch class to be used. @@ -43,6 +43,7 @@ class VswitchControllerP2P(IVswitchController): self._vswitch = vswitch_class() self._deployment_scenario = "P2P" self._logger.debug('Creation using ' + str(self._vswitch_class)) + self._traffic = traffic.copy() def setup(self): """Sets up the switch for p2p. @@ -67,13 +68,22 @@ class VswitchControllerP2P(IVswitchController): # 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 - flow = {'table':'1', 'priority':'1', 'in_port':'1', - 'actions': ['write_actions(output:2)', 'write_metadata:2', - 'goto_table:2']} + + # 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']}) + + flow = flow_template.copy() + flow.update({'table':'1', 'priority':'1', 'in_port':'1', + 'actions': ['write_actions(output:2)', 'write_metadata:2', + 'goto_table:2']}) self._vswitch.add_flow(bridge, flow) - flow = {'table':'1', 'priority':'1', 'in_port':'2', - 'actions': ['write_actions(output:1)', 'write_metadata:1', - 'goto_table:2']} + flow = flow_template.copy() + flow.update({'table':'1', 'priority':'1', 'in_port':'2', + 'actions': ['write_actions(output:1)', 'write_metadata:1', + 'goto_table:2']}) self._vswitch.add_flow(bridge, flow) # Frame modification table. Frame modification flow rules are diff --git a/core/vswitch_controller_pvp.py b/core/vswitch_controller_pvp.py index b2337bd6..0c98cc7f 100644 --- a/core/vswitch_controller_pvp.py +++ b/core/vswitch_controller_pvp.py @@ -34,7 +34,7 @@ class VswitchControllerPVP(IVswitchController): _deployment_scenario: A string describing the scenario to set-up in the constructor. """ - def __init__(self, vswitch_class, bidir=False): + def __init__(self, vswitch_class, traffic): """Initializes up the prerequisites for the PVP deployment scenario. :vswitch_class: the vSwitch class to be used. @@ -43,7 +43,7 @@ class VswitchControllerPVP(IVswitchController): self._vswitch_class = vswitch_class self._vswitch = vswitch_class() self._deployment_scenario = "PVP" - self._bidir = bidir + self._traffic = traffic.copy() self._logger.debug('Creation using ' + str(self._vswitch_class)) def setup(self): @@ -63,17 +63,24 @@ class VswitchControllerPVP(IVswitchController): (_, vport2_number) = self._vswitch.add_vport(bridge) self._vswitch.del_flow(bridge) - flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy1_number, + + # 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']}) + + flow1 = add_ports_to_flow(flow_template, phy1_number, vport1_number) - flow2 = add_ports_to_flow(_FLOW_TEMPLATE, vport2_number, + flow2 = add_ports_to_flow(flow_template, vport2_number, phy2_number) self._vswitch.add_flow(bridge, flow1) self._vswitch.add_flow(bridge, flow2) - if self._bidir: - flow3 = add_ports_to_flow(_FLOW_TEMPLATE, phy2_number, + if self._traffic['bidir']: + flow3 = add_ports_to_flow(flow_template, phy2_number, vport2_number) - flow4 = add_ports_to_flow(_FLOW_TEMPLATE, vport1_number, + flow4 = add_ports_to_flow(flow_template, vport1_number, phy1_number) self._vswitch.add_flow(bridge, flow3) self._vswitch.add_flow(bridge, flow4) diff --git a/core/vswitch_controller_pvvp.py b/core/vswitch_controller_pvvp.py index 43cf8a35..c79ad9a3 100644 --- a/core/vswitch_controller_pvvp.py +++ b/core/vswitch_controller_pvvp.py @@ -34,7 +34,7 @@ class VswitchControllerPVVP(IVswitchController): _deployment_scenario: A string describing the scenario to set-up in the constructor. """ - def __init__(self, vswitch_class, bidir=False): + def __init__(self, vswitch_class, traffic): """Initializes up the prerequisites for the PVVP deployment scenario. :vswitch_class: the vSwitch class to be used. @@ -43,7 +43,7 @@ class VswitchControllerPVVP(IVswitchController): self._vswitch_class = vswitch_class self._vswitch = vswitch_class() self._deployment_scenario = "PVVP" - self._bidir = bidir + self._traffic = traffic.copy() self._logger.debug('Creation using ' + str(self._vswitch_class)) def setup(self): @@ -65,22 +65,29 @@ class VswitchControllerPVVP(IVswitchController): (_, vport4_number) = self._vswitch.add_vport(bridge) self._vswitch.del_flow(bridge) - flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy1_number, + + # 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']}) + + flow1 = add_ports_to_flow(flow_template, phy1_number, vport1_number) - flow2 = add_ports_to_flow(_FLOW_TEMPLATE, vport2_number, + flow2 = add_ports_to_flow(flow_template, vport2_number, vport3_number) - flow3 = add_ports_to_flow(_FLOW_TEMPLATE, vport4_number, + flow3 = add_ports_to_flow(flow_template, vport4_number, phy2_number) self._vswitch.add_flow(bridge, flow1) self._vswitch.add_flow(bridge, flow2) self._vswitch.add_flow(bridge, flow3) - if self._bidir: - flow4 = add_ports_to_flow(_FLOW_TEMPLATE, phy2_number, + if self._traffic['bidir']: + flow4 = add_ports_to_flow(flow_template, phy2_number, vport4_number) - flow5 = add_ports_to_flow(_FLOW_TEMPLATE, vport3_number, + flow5 = add_ports_to_flow(flow_template, vport3_number, vport2_number) - flow6 = add_ports_to_flow(_FLOW_TEMPLATE, vport1_number, + flow6 = add_ports_to_flow(flow_template, vport1_number, phy1_number) self._vswitch.add_flow(bridge, flow4) self._vswitch.add_flow(bridge, flow5) diff --git a/testcases/testcase.py b/testcases/testcase.py index feb264d3..78f65239 100644 --- a/testcases/testcase.py +++ b/testcases/testcase.py @@ -24,6 +24,7 @@ import core.component_factory as component_factory from core.loader import Loader from tools.report import report from conf import settings as S +from tools.pkt_gen.trafficgen.trafficgenhelper import TRAFFIC_DEFAULTS class TestCase(object): """TestCase base class @@ -41,9 +42,7 @@ class TestCase(object): self._logger = logging.getLogger(__name__) self.name = cfg['Name'] self.desc = cfg.get('Description', 'No description given.') - self._traffic_type = cfg['Traffic Type'] self.deployment = cfg['Deployment'] - self._bidir = cfg['biDirectional'] self._frame_mod = cfg.get('Frame Modification', None) # check if test requires background load and which generator it uses @@ -57,7 +56,13 @@ class TestCase(object): if self._frame_mod: self._frame_mod = self._frame_mod.lower() self._results_dir = results_dir - self._multistream = cfg.get('MultiStream', 0) + + # set traffic details, so they can be passed to vswitch and traffic ctls + self._traffic = TRAFFIC_DEFAULTS.copy() + self._traffic.update({'traffic_type': cfg['Traffic Type'], + 'flow_type': cfg.get('Flow Type', 'port'), + 'bidir': cfg['biDirectional'], + 'multistream': cfg.get('MultiStream', 0)}) def run(self): """Run the test @@ -66,10 +71,18 @@ class TestCase(object): """ self._logger.debug(self.name) + # OVS Vanilla requires guest VM MAC address and IPs + # to work + if (self.deployment in ["pvp", "pvvp"] and S.getValue('VSWITCH') == "OvsVanilla"): + self._traffic['l2'] = {'srcmac': S.getValue('GUEST_NET2_MAC')[0], + 'dstmac': S.getValue('GUEST_NET1_MAC')[0]} + self._traffic['l3'] = {'srcip': S.getValue('VANILLA_TGEN_PORT1_IP'), + 'dstip': S.getValue('VANILLA_TGEN_PORT2_IP')} + self._logger.debug("Controllers:") loader = Loader() traffic_ctl = component_factory.create_traffic( - self._traffic_type, + self._traffic['traffic_type'], loader.get_trafficgen_class()) vnf_ctl = component_factory.create_vnf( self.deployment, @@ -77,7 +90,7 @@ class TestCase(object): vswitch_ctl = component_factory.create_vswitch( self.deployment, loader.get_vswitch_class(), - self._bidir) + self._traffic) collector = component_factory.create_collector( loader.get_collector_class(), self._results_dir, self.name) @@ -88,23 +101,6 @@ class TestCase(object): self._logger.debug("Setup:") with vswitch_ctl, loadgen: with vnf_ctl, collector: - traffic = {'traffic_type': self._traffic_type, - 'bidir': self._bidir, - 'multistream': self._multistream} - - # OVS Vanilla requires guest VM MAC address and IPs - # to work - if (self.deployment in ["pvp", "pvvp"] and - S.getValue('VSWITCH') == "OvsVanilla"): - - traffic['l2'] = {'srcmac': S.getValue('GUEST_NET2_MAC')[0], - 'dstmac': S.getValue('GUEST_NET1_MAC')[0]} - - traffic['l3'] = {'srcip': - S.getValue('VANILLA_TGEN_PORT1_IP'), - 'dstip': - S.getValue('VANILLA_TGEN_PORT2_IP')} - vswitch = vswitch_ctl.get_vswitch() # TODO BOM 15-08-07 the frame mod code assumes that the # physical ports are ports 1 & 2. The actual numbers @@ -189,7 +185,7 @@ class TestCase(object): pass with traffic_ctl: - traffic_ctl.send_traffic(traffic) + traffic_ctl.send_traffic(self._traffic) # dump vswitch flows before they are affected by VNF termination vswitch_ctl.dump_vswitch_flows() -- cgit 1.2.3-korg