diff options
8 files changed, 134 insertions, 94 deletions
diff --git a/yardstick/benchmark/scenarios/networking/vnf_generic.py b/yardstick/benchmark/scenarios/networking/vnf_generic.py index 7a11d3e76..a7557733b 100644 --- a/yardstick/benchmark/scenarios/networking/vnf_generic.py +++ b/yardstick/benchmark/scenarios/networking/vnf_generic.py @@ -64,37 +64,36 @@ class NetworkServiceTestCase(scenario_base.Scenario): self._mq_ids = [] def _get_ip_flow_range(self, ip_start_range): + """Retrieve a CIDR first and last viable IPs - # IP range is specified as 'x.x.x.x-y.y.y.y' + :param ip_start_range: could be the IP range itself or a dictionary + with the host name and the port. + :return: (str) IP range (min, max) with this format "x.x.x.x-y.y.y.y" + """ if isinstance(ip_start_range, six.string_types): return ip_start_range - node_name, range_or_interface = next(iter(ip_start_range.items()), (None, '0.0.0.0')) + node_name, range_or_interface = next(iter(ip_start_range.items()), + (None, '0.0.0.0')) if node_name is None: - # we are manually specifying the range - ip_addr_range = range_or_interface + return range_or_interface + + node = self.context_cfg['nodes'].get(node_name, {}) + interface = node.get('interfaces', {}).get(range_or_interface) + if interface: + ip = interface['local_ip'] + mask = interface['netmask'] else: - node = self.context_cfg["nodes"].get(node_name, {}) - try: - # the ip_range is the interface name - interface = node.get("interfaces", {})[range_or_interface] - except KeyError: - ip = "0.0.0.0" - mask = "255.255.255.0" - else: - ip = interface["local_ip"] - # we can't default these values, they must both exist to be valid - mask = interface["netmask"] - - ipaddr = ipaddress.ip_network(six.text_type('{}/{}'.format(ip, mask)), strict=False) - hosts = list(ipaddr.hosts()) - if len(hosts) > 2: - # skip the first host in case of gateway - ip_addr_range = "{}-{}".format(hosts[1], hosts[-1]) - else: - LOG.warning("Only single IP in range %s", ipaddr) - # fall back to single IP range - ip_addr_range = ip + ip = '0.0.0.0' + mask = '255.255.255.0' + + ipaddr = ipaddress.ip_network( + six.text_type('{}/{}'.format(ip, mask)), strict=False) + if ipaddr.prefixlen + 2 < ipaddr.max_prefixlen: + ip_addr_range = '{}-{}'.format(ipaddr[2], ipaddr[-2]) + else: + LOG.warning('Only single IP in range %s', ipaddr) + ip_addr_range = ip return ip_addr_range def _get_traffic_flow(self): diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py index 85cecc714..83ddbd470 100644 --- a/yardstick/common/utils.py +++ b/yardstick/common/utils.py @@ -335,6 +335,14 @@ def ip_to_hex(ip_addr, separator=''): return separator.join('{:02x}'.format(octet) for octet in address.packed) +def get_mask_from_ip_range(ip_low, ip_high): + _ip_low = ipaddress.ip_address(ip_low) + _ip_high = ipaddress.ip_address(ip_high) + _ip_low_int = int(_ip_low) + _ip_high_int = int(_ip_high) + return _ip_high.max_prefixlen - (_ip_high_int ^ _ip_low_int).bit_length() + + def try_int(s, *args): """Convert to integer if possible.""" try: diff --git a/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py b/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py index cee768dba..9058fa78c 100644 --- a/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py +++ b/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py @@ -33,8 +33,8 @@ PROTO_UDP = 'udp' PROTO_TCP = 'tcp' PROTO_VLAN = 'vlan' -IP_VERSION_4_MASK = '0.0.0.255' -IP_VERSION_6_MASK = '0:0:0:0:0:0:0:ff' +IP_VERSION_4_MASK = 24 +IP_VERSION_6_MASK = 64 TRAFFIC_STATUS_STARTED = 'started' TRAFFIC_STATUS_STOPPED = 'stopped' @@ -424,15 +424,17 @@ class IxNextgen(object): # pragma: no cover raise exceptions.IxNetworkFlowNotPresent(flow_group=fg_id) count = traffic_param['outer_l3']['count'] - srcip4 = str(traffic_param['outer_l3']['srcip4']) - dstip4 = str(traffic_param['outer_l3']['dstip4']) + srcip = str(traffic_param['outer_l3']['srcip']) + dstip = str(traffic_param['outer_l3']['dstip']) + srcmask = traffic_param['outer_l3']['srcmask'] or IP_VERSION_4_MASK + dstmask = traffic_param['outer_l3']['dstmask'] or IP_VERSION_4_MASK self._update_ipv4_address( self._get_stack_item(fg_id, PROTO_IPV4)[0], - 'srcIp', srcip4, 1, IP_VERSION_4_MASK, count) + 'srcIp', srcip, 1, srcmask, count) self._update_ipv4_address( self._get_stack_item(fg_id, PROTO_IPV4)[0], - 'dstIp', dstip4, 1, IP_VERSION_4_MASK, count) + 'dstIp', dstip, 1, dstmask, count) def _build_stats_map(self, view_obj, name_map): return {data_yardstick: self.ixnet.execute( diff --git a/yardstick/network_services/traffic_profile/ixia_rfc2544.py b/yardstick/network_services/traffic_profile/ixia_rfc2544.py index 49bac27e4..c32e9d8c9 100644 --- a/yardstick/network_services/traffic_profile/ixia_rfc2544.py +++ b/yardstick/network_services/traffic_profile/ixia_rfc2544.py @@ -14,6 +14,7 @@ import logging +from yardstick.common import utils from yardstick.network_services.traffic_profile import base as tp_base from yardstick.network_services.traffic_profile import trex_traffic_profile @@ -33,6 +34,14 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile): self.rate = self.config.frame_rate self.rate_unit = self.config.rate_unit + def _get_ip_and_mask(self, ip_range): + _ip_range = ip_range.split('-') + if len(_ip_range) == 1: + return _ip_range[0], None + + mask = utils.get_mask_from_ip_range(_ip_range[0], _ip_range[1]) + return _ip_range[0], mask + def _get_ixia_traffic_profile(self, profile_data, mac=None): mac = {} if mac is None else mac result = {} @@ -50,14 +59,17 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile): port_id = value.get('id', 1) port_index = port_id - 1 - try: - ip = value['outer_l3v6'] - except KeyError: + + if value.get('outer_l3v4'): ip = value['outer_l3v4'] src_key, dst_key = 'srcip4', 'dstip4' else: + ip = value['outer_l3v6'] src_key, dst_key = 'srcip6', 'dstip6' + srcip, srcmask = self._get_ip_and_mask(ip[src_key]) + dstip, dstmask = self._get_ip_and_mask(ip[dst_key]) + result[traffickey] = { 'bidir': False, 'id': port_id, @@ -73,8 +85,10 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile): 'count': ip['count'], 'dscp': ip['dscp'], 'ttl': ip['ttl'], - src_key: ip[src_key].split("-")[0], - dst_key: ip[dst_key].split("-")[0], + 'srcip': srcip, + 'dstip': dstip, + 'srcmask': srcmask, + 'dstmask': dstmask, 'type': key, 'proto': ip['proto'], }, diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py index cdb91f66d..49578b383 100644 --- a/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py @@ -358,35 +358,49 @@ class TestNetworkServiceTestCase(unittest.TestCase): self.assertIsNotNone(self.topology) def test__get_ip_flow_range_string(self): - self.scenario_cfg["traffic_options"]["flow"] = \ - self._get_file_abspath("ipv4_1flow_Packets_vpe.yaml") result = '152.16.100.2-152.16.100.254' self.assertEqual(result, self.s._get_ip_flow_range( '152.16.100.2-152.16.100.254')) - def test__get_ip_flow_range(self): - self.scenario_cfg["traffic_options"]["flow"] = \ - self._get_file_abspath("ipv4_1flow_Packets_vpe.yaml") - result = '152.16.100.2-152.16.100.254' - self.assertEqual(result, self.s._get_ip_flow_range({"tg__1": 'xe0'})) + def test__get_ip_flow_range_no_nodes(self): + self.assertEqual('0.0.0.0', self.s._get_ip_flow_range({})) - @mock.patch('yardstick.benchmark.scenarios.networking.vnf_generic.ipaddress') - def test__get_ip_flow_range_no_node_data(self, mock_ipaddress): - scenario_cfg = deepcopy(self.scenario_cfg) - scenario_cfg["traffic_options"]["flow"] = \ - self._get_file_abspath("ipv4_1flow_Packets_vpe.yaml") + def test__get_ip_flow_range_no_node_data(self): + node_data = {'tg__0': 'xe0'} + self.s.context_cfg['nodes']['tg__0'] = {} + result = self.s._get_ip_flow_range(node_data) + self.assertEqual('0.0.0.2-0.0.0.254', result) - mock_ipaddress.ip_network.return_value = ipaddr = mock.Mock() - ipaddr.hosts.return_value = [] + def test__et_ip_flow_range_ipv4(self): + node_data = {'tg__0': 'xe0'} + self.s.context_cfg['nodes']['tg__0'] = { + 'interfaces': { + 'xe0': {'local_ip': '192.168.1.15', + 'netmask': '255.255.255.128'} + } + } + result = self.s._get_ip_flow_range(node_data) + self.assertEqual('192.168.1.2-192.168.1.126', result) - expected = '0.0.0.0' - result = self.s._get_ip_flow_range({"tg__2": 'xe0'}) - self.assertEqual(result, expected) + def test__get_ip_flow_range_ipv4_mask_30(self): + node_data = {'tg__0': 'xe0'} + self.s.context_cfg['nodes']['tg__0'] = { + 'interfaces': { + 'xe0': {'local_ip': '192.168.1.15', 'netmask': 30} + } + } + result = self.s._get_ip_flow_range(node_data) + self.assertEqual('192.168.1.15', result) - def test__get_ip_flow_range_no_nodes(self): - expected = '0.0.0.0' - result = self.s._get_ip_flow_range({}) - self.assertEqual(result, expected) + def test__get_ip_flow_range_ipv6(self): + node_data = {'tg__0': 'xe0'} + self.s.context_cfg['nodes']['tg__0'] = { + 'interfaces': { + 'xe0': {'local_ip': '2001::11', 'netmask': 64} + } + } + result = self.s._get_ip_flow_range(node_data) + self.assertEqual('2001::2-2001::ffff:ffff:ffff:fffe', result) def test___get_traffic_flow(self): self.scenario_cfg["traffic_options"]["flow"] = \ diff --git a/yardstick/tests/unit/common/test_utils.py b/yardstick/tests/unit/common/test_utils.py index 446afdd38..bf0b5181a 100644 --- a/yardstick/tests/unit/common/test_utils.py +++ b/yardstick/tests/unit/common/test_utils.py @@ -1196,6 +1196,20 @@ class TestUtilsIpAddrMethods(ut_base.BaseUnitTestCase): for value in chain(value_iter, self.INVALID_IP_ADDRESS_STR_LIST): self.assertEqual(utils.ip_to_hex(value), value) + def test_get_mask_from_ip_range_ipv4(self): + ip_str = '1.1.1.1' + for mask in range(8, 30): + ip = ipaddress.ip_network(ip_str + '/' + str(mask), strict=False) + result = utils.get_mask_from_ip_range(ip[2], ip[-2]) + self.assertEqual(mask, result) + + def test_get_mask_from_ip_range_ipv6(self): + ip_str = '2001::1' + for mask in range(8, 120): + ip = ipaddress.ip_network(ip_str + '/' + str(mask), strict=False) + result = utils.get_mask_from_ip_range(ip[2], ip[-2]) + self.assertEqual(mask, result) + class SafeDecodeUtf8TestCase(ut_base.BaseUnitTestCase): diff --git a/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py b/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py index afa4cc3dc..458ea0f12 100644 --- a/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py +++ b/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py @@ -36,25 +36,12 @@ TRAFFIC_PARAMETERS = { 'outer_l3': { 'count': 512, 'dscp': 0, - 'dstip4': '152.16.40.20', 'proto': 'udp', - 'srcip4': '152.16.100.20', - 'ttl': 32 - }, - 'outer_l3v4': { - 'dscp': 0, - 'dstip4': '152.16.40.20', - 'proto': 'udp', - 'srcip4': '152.16.100.20', - 'ttl': 32 - }, - 'outer_l3v6': { - 'count': 1024, - 'dscp': 0, - 'dstip4': '152.16.100.20', - 'proto': 'udp', - 'srcip4': '152.16.40.20', - 'ttl': 32 + 'ttl': 32, + 'dstip': '152.16.40.20', + 'srcip': '152.16.100.20', + 'dstmask': 24, + 'srcmask': 24 }, 'outer_l4': { 'dstport': '2001', @@ -74,26 +61,12 @@ TRAFFIC_PARAMETERS = { 'outer_l3': { 'count': 1024, 'dscp': 0, - 'dstip4': '152.16.100.20', - 'proto': 'udp', - 'srcip4': '152.16.40.20', - 'ttl': 32 - }, - 'outer_l3v4': { - 'count': 1024, - 'dscp': 0, - 'dstip4': '152.16.100.20', - 'proto': 'udp', - 'srcip4': '152.16.40.20', - 'ttl': 32 - }, - 'outer_l3v6': { - 'count': 1024, - 'dscp': 0, - 'dstip4': '152.16.100.20', 'proto': 'udp', - 'srcip4': '152.16.40.20', - 'ttl': 32 + 'ttl': 32, + 'dstip': '2001::10', + 'srcip': '2021::10', + 'dstmask': 64, + 'srcmask': 64 }, 'outer_l4': { 'dstport': '1234', diff --git a/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py b/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py index 4ea19a121..1a33304a5 100644 --- a/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py +++ b/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py @@ -446,6 +446,22 @@ class TestIXIARFC2544Profile(unittest.TestCase): r_f_c2544_profile = ixia_rfc2544.IXIARFC2544Profile(t_profile_data) self.assertEqual(12345678, r_f_c2544_profile.rate) + def test__get_ip_and_mask_range(self): + ip_range = '1.2.0.2-1.2.255.254' + r_f_c2544_profile = ixia_rfc2544.IXIARFC2544Profile( + self.TRAFFIC_PROFILE) + ip, mask = r_f_c2544_profile._get_ip_and_mask(ip_range) + self.assertEqual('1.2.0.2', ip) + self.assertEqual(16, mask) + + def test__get_ip_and_mask_single(self): + ip_range = '192.168.1.10' + r_f_c2544_profile = ixia_rfc2544.IXIARFC2544Profile( + self.TRAFFIC_PROFILE) + ip, mask = r_f_c2544_profile._get_ip_and_mask(ip_range) + self.assertEqual('192.168.1.10', ip) + self.assertIsNone(mask) + def test__get_ixia_traffic_profile_default_args(self): r_f_c2544_profile = ixia_rfc2544.IXIARFC2544Profile( self.TRAFFIC_PROFILE) |