From e947f924af1fbd0012690f535b1e0922e2cb1d20 Mon Sep 17 00:00:00 2001 From: Ross Brattain Date: Thu, 2 Nov 2017 16:54:56 -0700 Subject: NSB TRex: convert DPDK port number to logical TRex port number when we create TRex config we sort based on PCI bus address and create a logical port ordering. We need to save this port ordering and re-use it everywhere. redirect vnfd_helper.port_num() to resource_helper.port_num() to use the logical mapping Change-Id: Ibff628556d5e11e686e15716a66a3210758c4ff0 Signed-off-by: Ross Brattain (cherry picked from commit ce52059f5f78912eeff2d97235c1028c218bf960) --- .../vnf_generic/vnf/test_tg_trex.py | 54 ++++++++++++++++++++++ .../network_services/traffic_profile/rfc2544.py | 4 +- .../network_services/vnf_generic/vnf/sample_vnf.py | 4 ++ .../network_services/vnf_generic/vnf/tg_trex.py | 32 +++++++++++-- 4 files changed, 87 insertions(+), 7 deletions(-) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py index d08c62e0b..a2a5058fc 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py @@ -18,6 +18,8 @@ from __future__ import absolute_import import unittest + +import copy import mock SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' @@ -75,6 +77,8 @@ class TestTrexTrafficGen(unittest.TestCase): 'driver': "i40e", 'dst_ip': '152.16.100.20', 'local_iface_name': 'xe0', + 'vld_id': 'downlink_0', + 'ifname': 'xe0', 'local_mac': '00:00:00:00:00:02'}, 'vnfd-connection-point-ref': 'xe0', 'name': 'xe0'}, @@ -89,6 +93,8 @@ class TestTrexTrafficGen(unittest.TestCase): 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_iface_name': 'xe1', + 'vld_id': 'uplink_0', + 'ifname': 'xe1', 'local_mac': '00:00:00:00:00:01'}, 'vnfd-connection-point-ref': 'xe1', 'name': 'xe1'}]}], @@ -386,6 +392,8 @@ class TestTrexTrafficGen(unittest.TestCase): self.sut._connect_client.get_stats = mock.Mock(return_value="0") self.sut.resource_helper.RUN_DURATION = 0 self.sut.resource_helper.QUEUE_WAIT_TIME = 0 + # must generate cfg before we can run traffic so Trex port mapping is created + self.sut.resource_helper.generate_cfg() self.sut._traffic_runner(mock_traffic_profile) @mock.patch(SSH_HELPER) @@ -396,6 +404,52 @@ class TestTrexTrafficGen(unittest.TestCase): trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock() self.assertIsNone(trex_traffic_gen.resource_helper.generate_cfg()) + @mock.patch(SSH_HELPER) + def test_build_ports_reversed_pci_ordering(self, ssh): + mock_ssh(ssh) + vnfd = copy.deepcopy(self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]) + vnfd['vdu'][0]['external-interface'] = [ + {'virtual-interface': + {'dst_mac': '00:00:00:00:00:04', + 'vpci': '0000:05:00.0', + 'local_ip': '152.16.100.19', + 'type': 'PCI-PASSTHROUGH', + 'netmask': '255.255.255.0', + 'dpdk_port_num': 2, + 'bandwidth': '10 Gbps', + 'driver': "i40e", + 'dst_ip': '152.16.100.20', + 'local_iface_name': 'xe0', + 'vld_id': 'downlink_0', + 'ifname': 'xe0', + 'local_mac': '00:00:00:00:00:02'}, + 'vnfd-connection-point-ref': 'xe0', + 'name': 'xe0'}, + {'virtual-interface': + {'dst_mac': '00:00:00:00:00:03', + 'vpci': '0000:04:00.0', + 'local_ip': '152.16.40.19', + 'type': 'PCI-PASSTHROUGH', + 'driver': "i40e", + 'netmask': '255.255.255.0', + 'dpdk_port_num': 0, + 'bandwidth': '10 Gbps', + 'dst_ip': '152.16.40.20', + 'local_iface_name': 'xe1', + 'vld_id': 'uplink_0', + 'ifname': 'xe1', + 'local_mac': '00:00:00:00:00:01'}, + 'vnfd-connection-point-ref': 'xe1', + 'name': 'xe1'}] + trex_traffic_gen = TrexTrafficGen(NAME, vnfd) + trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock() + trex_traffic_gen.resource_helper.generate_cfg() + trex_traffic_gen.resource_helper._build_ports() + self.assertEqual(sorted(trex_traffic_gen.resource_helper.all_ports), [0, 1]) + # there is a gap in ordering + self.assertEqual(dict(trex_traffic_gen.resource_helper.dpdk_to_trex_port_map), + {0: 0, 2: 1}) + @mock.patch(SSH_HELPER) def test_run_traffic(self, ssh): mock_ssh(ssh) diff --git a/yardstick/network_services/traffic_profile/rfc2544.py b/yardstick/network_services/traffic_profile/rfc2544.py index 16e809b65..b1ca8a345 100644 --- a/yardstick/network_services/traffic_profile/rfc2544.py +++ b/yardstick/network_services/traffic_profile/rfc2544.py @@ -62,7 +62,7 @@ class RFC2544Profile(TrexProfile): self.generator.rfc2544_helper.correlated_traffic: continue for intf in intfs: - port = self.generator.vnfd_helper.port_num(intf) + port = self.generator.port_num(intf) self.ports.append(port) self.generator.client.add_streams(self.get_streams(profile_data), ports=port) @@ -170,7 +170,7 @@ class RFC2544Profile(TrexProfile): self.generator.rfc2544_helper.correlated_traffic: continue for intf in intfs: - port = self.generator.vnfd_helper.port_num(intf) + port = self.generator.port_num(intf) self.ports.append(port) self.generator.client.add_streams(self.get_streams(profile_data), ports=port) diff --git a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py index 08ec44f65..5599c0a3b 100644 --- a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py @@ -433,6 +433,10 @@ class ClientResourceHelper(ResourceHelper): self.vnfd_helper.port_nums(self.vnfd_helper.port_pairs.downlink_ports) self.all_ports = self.vnfd_helper.port_nums(self.vnfd_helper.port_pairs.all_ports) + def port_num(self, intf): + # by default return port num + return self.vnfd_helper.port_num(intf) + def get_stats(self, *args, **kwargs): try: return self.client.get_stats(*args, **kwargs) diff --git a/yardstick/network_services/vnf_generic/vnf/tg_trex.py b/yardstick/network_services/vnf_generic/vnf/tg_trex.py index 458f1b844..93ba8557a 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_trex.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_trex.py @@ -48,27 +48,38 @@ class TrexResourceHelper(ClientResourceHelper): ASYNC_PORT = 4500 SYNC_PORT = 4501 + def __init__(self, setup_helper): + super(TrexResourceHelper, self).__init__(setup_helper) + self.port_map = {} + self.dpdk_to_trex_port_map = {} + def generate_cfg(self): port_names = self.vnfd_helper.port_pairs.all_ports vpci_list = [] port_list = [] + self.port_map = {} + self.dpdk_to_trex_port_map = {} - port_nums = sorted(self.vnfd_helper.port_nums(port_names)) - for port_num in port_nums: - interface = self.vnfd_helper.find_interface_by_port(port_num) + sorted_ports = sorted((self.vnfd_helper.port_num(port_name), port_name) for port_name in + port_names) + for index, (port_num, port_name) in enumerate(sorted_ports): + interface = self.vnfd_helper.find_interface(name=port_name) virtual_interface = interface['virtual-interface'] dst_mac = virtual_interface["dst_mac"] - # why skip?, ordering is based on DPDK port number so we can't skip + # this is to check for unused ports, all ports in the topology + # will always have dst_mac if not dst_mac: continue - # TRex ports must be in DPDK port number, so order of append matters + # TRex ports are in logical order roughly based on DPDK port number sorting vpci_list.append(virtual_interface["vpci"]) local_mac = virtual_interface["local_mac"] port_list.append({ "src_mac": mac_address_to_hex_list(local_mac), "dest_mac": mac_address_to_hex_list(dst_mac), }) + self.port_map[port_name] = index + self.dpdk_to_trex_port_map[port_num] = index trex_cfg = { 'interfaces': vpci_list, 'port_info': port_list, @@ -80,6 +91,17 @@ class TrexResourceHelper(ClientResourceHelper): cfg_str = yaml.safe_dump(cfg_file, default_flow_style=False, explicit_start=True) self.ssh_helper.upload_config_file(os.path.basename(self.CONF_FILE), cfg_str) + def _build_ports(self): + super(TrexResourceHelper, self)._build_ports() + # override with TRex logic port number + self.uplink_ports = [self.dpdk_to_trex_port_map[p] for p in self.uplink_ports] + self.downlink_ports = [self.dpdk_to_trex_port_map[p] for p in self.downlink_ports] + self.all_ports = [self.dpdk_to_trex_port_map[p] for p in self.all_ports] + + def port_num(self, intf): + # return logical TRex port + return self.port_map[intf] + def check_status(self): status, _, _ = self.ssh_helper.execute("sudo lsof -i:%s" % self.SYNC_PORT) return status -- cgit 1.2.3-korg