X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=core%2Fvswitch_controller_p2p.py;h=de3fcc0dfee2396225d585fd2c45326129c58193;hb=ecadcfd29d4228f73d3ec3456d377162b165068a;hp=a1158d4eca71dd8eb1ae909311048c0ec38c41e2;hpb=f8739e7feb9973550ef2fc69e6768b331e0ef28e;p=vswitchperf.git diff --git a/core/vswitch_controller_p2p.py b/core/vswitch_controller_p2p.py index a1158d4e..de3fcc0d 100644 --- a/core/vswitch_controller_p2p.py +++ b/core/vswitch_controller_p2p.py @@ -16,14 +16,17 @@ """ 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' } -BRIDGE_NAME = 'br0' + +_PROTO_TCP = 6 +_PROTO_UDP = 17 class VswitchControllerP2P(IVswitchController): """VSwitch controller for P2P deployment scenario. @@ -34,7 +37,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. @@ -44,6 +47,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. @@ -53,41 +57,51 @@ class VswitchControllerP2P(IVswitchController): try: self._vswitch.start() - self._vswitch.add_switch(BRIDGE_NAME) + bridge = settings.getValue('VSWITCH_BRIDGE_NAME') + self._vswitch.add_switch(bridge) - (_, phy1_number) = self._vswitch.add_phy_port(BRIDGE_NAME) - (_, phy2_number) = self._vswitch.add_phy_port(BRIDGE_NAME) + (_, _) = self._vswitch.add_phy_port(bridge) + (_, _) = self._vswitch.add_phy_port(bridge) - self._vswitch.del_flow(BRIDGE_NAME) + 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_NAME, flow) + 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 - flow = {'table':'1', 'priority':'1', 'in_port':'1', - 'actions': ['write_actions(output:2)', 'write_metadata:2', - 'goto_table:2']} - self._vswitch.add_flow(BRIDGE_NAME, flow) - flow = {'table':'1', 'priority':'1', 'in_port':'2', - 'actions': ['write_actions(output:1)', 'write_metadata:1', - 'goto_table:2']} - self._vswitch.add_flow(BRIDGE_NAME, flow) + + # 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: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) # 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_NAME, flow) + 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_NAME, flow) + self._vswitch.add_flow(bridge, flow) except: self._vswitch.stop() raise @@ -113,4 +127,50 @@ class VswitchControllerP2P(IVswitchController): """See IVswitchController for description """ self._logger.debug('get_ports_info using ' + str(self._vswitch_class)) - return self._vswitch.get_ports(BRIDGE_NAME) + 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')) + + 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(int(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(int(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(int(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)