From 4145ff0ff4b8fbc9c376ab80cb02a8bab34c28bb Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Sat, 20 Feb 2016 20:00:01 +0200 Subject: hlt updates: split by cores, direction --- .../stl/trex_stl_lib/trex_stl_hltapi.py | 254 +++++++++++---------- .../trex_stl_lib/trex_stl_packet_builder_scapy.py | 23 +- 2 files changed, 154 insertions(+), 123 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py index 5311884d..a3d4e319 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py @@ -22,6 +22,7 @@ cleanup_session_kwargs = { # traffic_config() traffic_config_kwargs = { 'mode': None, # ( create | modify | remove | reset ) + 'split_by_cores': 'split', # ( split | duplicate | single ) TRex extention: split = split traffic by cores, duplicate = duplicate traffic for all cores, single = run only with sinle core (not implemented yet) 'port_handle': None, 'port_handle2': None, # stream builder parameters @@ -32,6 +33,7 @@ traffic_config_kwargs = { 'stream_id': None, 'name': None, 'bidirectional': 0, + 'direction': 0, # ( 0 | 1 ) TRex extention: 1 = exchange sources and destinations 'pkts_per_burst': 1, 'burst_loop_count': 1, 'inter_burst_gap': 12, @@ -327,7 +329,7 @@ class CTRexHltApi(object): # connection successfully created with server, try acquiring ports of TRex try: - port_list = self.parse_port_list(kwargs['port_list']) + port_list = self._parse_port_list(kwargs['port_list']) self.trex_client.acquire(ports = port_list, force = kwargs['break_locks']) except Exception as e: self.trex_client = None @@ -358,7 +360,7 @@ class CTRexHltApi(object): if port_list == 'all': port_list = self.trex_client.get_acquired_ports() else: - port_list = self.parse_port_list(port_list) + port_list = self._parse_port_list(port_list) except Exception as e: return HLT_ERR('Unable to determine which ports to release: %s' % e if isinstance(e, STLError) else traceback.format_exc()) try: @@ -412,10 +414,7 @@ class CTRexHltApi(object): else: stream_id = stream_id[0] - port_handle = kwargs['port_handle'] - if type(port_handle) is not list: - port_handle = [port_handle] - + port_handle = port_list = self._parse_port_list(kwargs['port_handle']) ALLOWED_MODES = ['create', 'modify', 'remove', 'enable', 'disable', 'reset'] if mode not in ALLOWED_MODES: return HLT_ERR('Mode must be one of the following values: %s' % ALLOWED_MODES) @@ -455,13 +454,12 @@ class CTRexHltApi(object): # if stream_id not in self._streams_history: # return HLT_ERR('This stream_id (%s) was not used before, please create new.' % stream_id) # self._streams_history[stream_id].update(kwargs) # <- the modification - if mode == 'modify': # we remove stream and create new one with same stream_id stream_id = kwargs.get('stream_id') if stream_id is None: return HLT_ERR('Please specify stream_id to modify.') - + if len(port_handle) > 1: for port in port_handle: user_kwargs[port_handle] = port @@ -502,12 +500,10 @@ class CTRexHltApi(object): if res1['status'] == 0: raise STLError('Could not create bidirectional stream 1: %s' % res1['log']) streams_per_port.add_streams_from_res(res1) + kwargs['direction'] = 1 - kwargs['direction'] # not + correct_direction(user_kwargs, kwargs) user_kwargs['mac_src'] = kwargs['mac_src2'] user_kwargs['mac_dst'] = kwargs['mac_dst2'] - user_kwargs['ip_src_addr'] = kwargs['ip_dst_addr'] - user_kwargs['ip_dst_addr'] = kwargs['ip_src_addr'] - user_kwargs['ipv6_src_addr'] = kwargs['ipv6_dst_addr'] - user_kwargs['ipv6_dst_addr'] = kwargs['ipv6_src_addr'] if save_to_yaml and type(save_to_yaml) is str: user_kwargs['save_to_yaml'] = save_to_yaml.replace('.yaml', '_bi2.yaml') user_kwargs['port_handle'] = port_handle2 @@ -657,30 +653,15 @@ class CTRexHltApi(object): # Private functions # ########################### - # obsolete @staticmethod - def process_response(port_list, response): - log = response.data() if response.good() else response.err() - if isinstance(port_list, list): - log = CTRexHltApi.join_batch_response(log) - return response.good(), log - - @staticmethod - def parse_port_list(port_list): - if isinstance(port_list, str): - return [int(port) - for port in port_list.split()] - elif isinstance(port_list, list): - return [int(port) - for port in port_list] - else: - return port_list - - @staticmethod - def join_batch_response(responses): - if type(responses) is list(): - return '\n'. join([str(response) for response in responses]) - return responses + def _parse_port_list(port_list): + if type(port_list) is str: + return [int(port) for port in port_list.strip().split()] + elif type(port_list) is list: + return [int(port) for port in port_list] + elif type(port) in (int, long): + return [int(port_list)] + raise STLError('port_list should be string with ports, list, or single number') def STLHltStream(**user_kwargs): kwargs = merge_kwargs(traffic_config_kwargs, user_kwargs) @@ -745,7 +726,6 @@ def STLHltStream(**user_kwargs): #self_start = True, mode = transmit_mode_class, #rx_stats = rx_stats, - #next_stream_id = -1, stream_id = kwargs.get('stream_id'), name = kwargs.get('name'), ) @@ -761,6 +741,7 @@ def STLHltStream(**user_kwargs): def generate_packet(**user_kwargs): correct_macs(user_kwargs) kwargs = merge_kwargs(traffic_config_kwargs, user_kwargs) + correct_direction(kwargs, kwargs) vm_cmds = [] fix_ipv4_checksum = False @@ -772,8 +753,29 @@ def generate_packet(**user_kwargs): # XShortEnumField("type", 0x9000, ETHER_TYPES) ] l2_layer = Ether(src = kwargs['mac_src'], dst = kwargs['mac_dst']) - # TODO: add Eth VM once variable masking will be done + # Eth VM + # WIP!!! Need 8 bytes mask and vars + if kwargs['mac_src_mode'] != 'fixed': + mac_src_count = kwargs['mac_src_count'] + if mac_src_count < 1: + raise STLError('mac_src_count has to be at least 1') + if mac_src_count > 1: + mac_src = mac_str_to_num(mac2str(kwargs['mac_src'])) + if kwargs['mac_src_mode'] == 'increment': + vm_cmds.append(CTRexVmDescFlowVar(name = 'mac_src', size = 4, op = 'inc', step = kwargs['mac_src_step'], + min_value = mac_src, + max_value = mac_src + mac_src_count * kwargs['mac_src_step'] - 1)) + elif kwargs['mac_src_mode'] == 'decrement': + vm_cmds.append(CTRexVmDescFlowVar(name = 'mac_src', size = 4, op = 'dec', step = kwargs['mac_src_step'], + min_value = mac_src - mac_src_count * kwargs['mac_src_step'] + 1, + max_value = mac_src)) + elif kwargs['mac_src_mode'] == 'random': + vm_cmds.append(CTRexVmDescFlowVar(name = 'mac_src', size = 4, op = 'random', min_value = 0, max_value = 0xffffffffffffffff)) + else: + raise STLError('mac_src_mode %s is not supported' % kwargs['mac_src_mode']) + vm_cmds.append(STLVmWrMaskFlowVar(fv_name = 'mac_src', pkt_offset = 'Ethernet.src', pkt_cast_size = 4, mask = 0xffffffff)) + if kwargs['l2_encap'] == 'ethernet_ii_vlan' or (kwargs['l2_encap'] == 'ethernet_ii' and vlan_in_args(user_kwargs)): #fields_desc = [ BitField("prio", 0, 3), # BitField("id", 0, 1), @@ -783,31 +785,35 @@ def generate_packet(**user_kwargs): dot1q_kwargs = {'prio': vlan_kwargs['vlan_user_priority'], 'vlan': vlan_kwargs['vlan_id'], 'id': vlan_kwargs['vlan_cfi']} - if vlan_kwargs['vlan_protocol_tag_id'] is not None: - dot1q_kwargs['type'] = vlan_kwargs['vlan_protocol_tag_id'] + vlan_protocol_tag_id = vlan_kwargs['vlan_protocol_tag_id'] + if vlan_protocol_tag_id is not None: + if type(vlan_protocol_tag_id) is str: + vlan_protocol_tag_id = int(vlan_protocol_tag_id, 16) + dot1q_kwargs['type'] = vlan_protocol_tag_id l2_layer /= Dot1Q(**dot1q_kwargs) + # vlan VM if vlan_kwargs['vlan_id_mode'] != 'fixed': - if vlan_kwargs['vlan_id_count'] < 1: + vlan_id_count = vlan_kwargs['vlan_id_count'] + if vlan_id_count < 1: raise STLError('vlan_id_count has to be at least 1') - if kwargs['vlan_id_count'] > 1: + if vlan_id_count > 1: var_name = 'vlan_id%s' % i - raise STLError('vlan_id VM not supported yet, waiting for bitmask from stateless') if kwargs['vlan_id_mode'] == 'increment': - vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 4, op = 'inc', step = vlan_kwargs['vlan_id_step'], + vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 2, op = 'inc', step = vlan_kwargs['vlan_id_step'], min_value = kwargs['vlan_id'], - max_value = kwargs['vlan_id'] + kwargs['vlan_id_count'] - 1)) + max_value = kwargs['vlan_id'] + vlan_id_count * vlan_kwargs['vlan_id_step'] - 1)) elif kwargs['vlan_id_mode'] == 'decrement': - vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 4, op = 'dec', step = vlan_kwargs['vlan_id_step'], - min_value = kwargs['vlan_id'] - kwargs['vlan_id_count'] + 1, + vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 2, op = 'dec', step = vlan_kwargs['vlan_id_step'], + min_value = kwargs['vlan_id'] - vlan_id_count * vlan_kwargs['vlan_id_step'] + 1, max_value = kwargs['vlan_id'])) elif kwargs['vlan_id_mode'] == 'random': - vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 4, op = 'random', - min_value = kwargs['vlan_id'], - max_value = kwargs['vlan_id'] + kwargs['vlan_id_count'] - 1)) + vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 2, op = 'random', min_value = 0, max_value = 0xffff)) else: raise STLError('vlan_id_mode %s is not supported' % kwargs['vlan_id_mode']) - vm_cmds.append(CTRexVmDescWrFlowVar(fv_name = var_name, pkt_offset = 'Dot1Q:%s.vlan' % i)) + vm_cmds.append(STLVmWrMaskFlowVar(fv_name = var_name, pkt_offset = 'Dot1Q:%s.vlan' % i, + pkt_cast_size = 2, mask = 0x0fff)) + else: raise NotImplementedError("l2_encap does not support the desired encapsulation '%s'" % kwargs['l2_encap']) base_pkt = l2_layer @@ -830,7 +836,7 @@ def generate_packet(**user_kwargs): ip_tos = get_TOS(user_kwargs, kwargs) if ip_tos < 0 or ip_tos > 255: raise STLError('TOS %s is not in range 0-255' % ip_tos) - l3_layer = IP(tos = get_TOS(user_kwargs, kwargs), + l3_layer = IP(tos = ip_tos, len = kwargs['l3_length'], id = kwargs['ip_id'], frag = kwargs['ip_fragment_offset'], @@ -841,45 +847,43 @@ def generate_packet(**user_kwargs): ) # IPv4 VM if kwargs['ip_src_mode'] != 'fixed': - if kwargs['ip_src_count'] < 1: + ip_src_count = kwargs['ip_src_count'] + if ip_src_count < 1: raise STLError('ip_src_count has to be at least 1') - if kwargs['ip_src_count'] > 1: + if ip_src_count > 1: fix_ipv4_checksum = True ip_src_addr_num = ipv4_str_to_num(is_valid_ipv4(kwargs['ip_src_addr'])) if kwargs['ip_src_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'inc', step = kwargs['ip_src_step'], min_value = ip_src_addr_num, - max_value = ip_src_addr_num + kwargs['ip_src_count'] - 1)) + max_value = ip_src_addr_num + ip_src_count * kwargs['ip_src_step'] - 1)) elif kwargs['ip_src_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'dec', step = kwargs['ip_src_step'], - min_value = ip_src_addr_num - kwargs['ip_src_count'] + 1, + min_value = ip_src_addr_num - ip_src_count * kwargs['ip_src_step'] + 1, max_value = ip_src_addr_num)) elif kwargs['ip_src_mode'] == 'random': - vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'random', - min_value = ip_src_addr_num, - max_value = ip_src_addr_num + kwargs['ip_src_count'] - 1)) + vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff)) else: raise STLError('ip_src_mode %s is not supported' % kwargs['ip_src_mode']) vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='ip_src', pkt_offset = 'IP.src')) if kwargs['ip_dst_mode'] != 'fixed': - if kwargs['ip_dst_count'] < 1: + ip_dst_count = kwargs['ip_dst_count'] + if ip_dst_count < 1: raise STLError('ip_dst_count has to be at least 1') - if kwargs['ip_dst_count'] > 1: + if ip_dst_count > 1: fix_ipv4_checksum = True ip_dst_addr_num = ipv4_str_to_num(is_valid_ipv4(kwargs['ip_dst_addr'])) if kwargs['ip_dst_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'inc', step = kwargs['ip_dst_step'], min_value = ip_dst_addr_num, - max_value = ip_dst_addr_num + kwargs['ip_dst_count'] - 1)) + max_value = ip_dst_addr_num + ip_dst_count * kwargs['ip_dst_step'] - 1)) elif kwargs['ip_dst_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'dec', step = kwargs['ip_dst_step'], - min_value = ip_dst_addr_num - kwargs['ip_dst_count'] + 1, + min_value = ip_dst_addr_num - ip_dst_count * kwargs['ip_dst_step'] + 1, max_value = ip_dst_addr_num)) elif kwargs['ip_dst_mode'] == 'random': - vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'random', - min_value = ip_dst_addr_num, - max_value = ip_dst_addr_num + kwargs['ip_dst_count'] - 1)) + vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff)) else: raise STLError('ip_dst_mode %s is not supported' % kwargs['ip_dst_mode']) vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='ip_dst', pkt_offset = 'IP.dst')) @@ -902,6 +906,7 @@ def generate_packet(**user_kwargs): if kwargs['ipv6_next_header'] is not None: ipv6_kwargs['nh'] = kwargs['ipv6_next_header'] l3_layer = IPv6(**ipv6_kwargs) + # IPv6 VM if kwargs['ipv6_src_mode'] != 'fixed': if kwargs['ipv6_src_count'] < 1: @@ -909,20 +914,18 @@ def generate_packet(**user_kwargs): if kwargs['ipv6_src_count'] > 1: ipv6_src_addr_num = ipv4_str_to_num(is_valid_ipv6(kwargs['ipv6_src_addr'])[-4:]) ipv6_src_step = kwargs['ipv6_src_step'] - if type(kwargs['ipv6_src_step']) is str: # convert ipv6 step to number + if type(ipv6_src_step) is str: # convert ipv6 step to number ipv6_src_step = ipv4_str_to_num(is_valid_ipv6(ipv6_src_step)[-4:]) if kwargs['ipv6_src_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_src', size = 4, op = 'inc', step = ipv6_src_step, min_value = ipv6_src_addr_num, - max_value = ipv6_src_addr_num + kwargs['ipv6_src_count'] - 1)) + max_value = ipv6_src_addr_num + kwargs['ipv6_src_count'] * ipv6_src_step - 1)) elif kwargs['ipv6_src_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_src', size = 4, op = 'dec', step = ipv6_src_step, - min_value = ipv6_src_addr_num - kwargs['ipv6_src_count'] + 1, + min_value = ipv6_src_addr_num - kwargs['ipv6_src_count'] * ipv6_src_step + 1, max_value = ipv6_src_addr_num)) elif kwargs['ipv6_src_mode'] == 'random': - vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_src', size = 4, op = 'random', - min_value = ipv6_src_addr_num, - max_value = ipv6_src_addr_num + kwargs['ipv6_src_count'] - 1)) + vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_src', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff)) else: raise STLError('ipv6_src_mode %s is not supported' % kwargs['ipv6_src_mode']) vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='ipv6_src', pkt_offset = 'IPv6.src', offset_fixup = 12)) @@ -933,20 +936,18 @@ def generate_packet(**user_kwargs): if kwargs['ipv6_dst_count'] > 1: ipv6_dst_addr_num = ipv4_str_to_num(is_valid_ipv6(kwargs['ipv6_dst_addr'])[-4:]) ipv6_dst_step = kwargs['ipv6_dst_step'] - if type(kwargs['ipv6_dst_step']) is str: # convert ipv6 step to number + if type(ipv6_dst_step) is str: # convert ipv6 step to number ipv6_dst_step = ipv4_str_to_num(is_valid_ipv6(ipv6_dst_step)[-4:]) if kwargs['ipv6_dst_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_dst', size = 4, op = 'inc', step = ipv6_dst_step, min_value = ipv6_dst_addr_num, - max_value = ipv6_dst_addr_num + kwargs['ipv6_dst_count'] - 1)) + max_value = ipv6_dst_addr_num + kwargs['ipv6_dst_count'] * ipv6_dst_step - 1)) elif kwargs['ipv6_dst_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_dst', size = 4, op = 'dec', step = ipv6_dst_step, - min_value = ipv6_dst_addr_num - kwargs['ipv6_dst_count'] + 1, + min_value = ipv6_dst_addr_num - kwargs['ipv6_dst_count'] * ipv6_dst_step + 1, max_value = ipv6_dst_addr_num)) elif kwargs['ipv6_dst_mode'] == 'random': - vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_dst', size = 4, op = 'random', - min_value = ipv6_dst_addr_num, - max_value = ipv6_dst_addr_num + kwargs['ipv6_dst_count'] - 1)) + vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_dst', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff)) else: raise STLError('ipv6_dst_mode %s is not supported' % kwargs['ipv6_dst_mode']) vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='ipv6_dst', pkt_offset = 'IPv6.dst', offset_fixup = 12)) @@ -986,44 +987,42 @@ def generate_packet(**user_kwargs): urgptr = kwargs['tcp_urgent_ptr'], ) # TCP VM - if kwargs['tcp_src_port_count'] != 1: - if kwargs['tcp_src_port_count'] < 1: + if kwargs['tcp_src_port_mode'] != 'fixed': + tcp_src_port_count = kwargs['tcp_src_port_count'] + if tcp_src_port_count < 1: raise STLError('tcp_src_port_count has to be at least 1') - if kwargs['tcp_src_port_count'] > 1: + if tcp_src_port_count > 1: fix_ipv4_checksum = True if kwargs['tcp_src_port_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_src', size = 2, op = 'inc', step = kwargs['tcp_src_port_step'], min_value = kwargs['tcp_src_port'], - max_value = kwargs['tcp_src_port'] + kwargs['tcp_src_port_count'] - 1)) + max_value = kwargs['tcp_src_port'] + tcp_src_port_count * kwargs['tcp_src_port_step'] - 1)) elif kwargs['tcp_src_port_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_src', size = 2, op = 'dec', step = kwargs['tcp_src_port_step'], - min_value = kwargs['tcp_src_port'] - kwargs['tcp_src_port_count'] +1, + min_value = kwargs['tcp_src_port'] - tcp_src_port_count * kwargs['tcp_src_port_step'] + 1, max_value = kwargs['tcp_src_port'])) elif kwargs['tcp_src_port_mode'] == 'random': - vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_src', size = 2, op = 'random', - min_value = kwargs['tcp_src_port'], - max_value = kwargs['tcp_src_port'] + kwargs['tcp_src_port_count'] - 1)) + vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_src', size = 2, op = 'random', min_value = 0, max_value = 0xffff)) else: raise STLError('tcp_src_port_mode %s is not supported' % kwargs['tcp_src_port_mode']) vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='tcp_src', pkt_offset = 'TCP.sport')) - if kwargs['tcp_dst_port_count'] != 1: - if kwargs['tcp_dst_port_count'] < 1: + if kwargs['tcp_dst_port_mode'] != 'fixed': + tcp_dst_port_count = kwargs['tcp_dst_port_count'] + if tcp_dst_port_count < 1: raise STLError('tcp_dst_port_count has to be at least 1') - if kwargs['tcp_dst_port_count'] > 1: + if tcp_dst_port_count > 1: fix_ipv4_checksum = True if kwargs['tcp_dst_port_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_dst', size = 2, op = 'inc', step = kwargs['tcp_dst_port_step'], min_value = kwargs['tcp_dst_port'], - max_value = kwargs['tcp_dst_port'] + kwargs['tcp_dst_port_count'] - 1)) + max_value = kwargs['tcp_dst_port'] + tcp_dst_port_count * kwargs['tcp_dst_port_step'] - 1)) elif kwargs['tcp_dst_port_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_dst', size = 2, op = 'dec', step = kwargs['tcp_dst_port_step'], - min_value = kwargs['tcp_dst_port'] - kwargs['tcp_dst_port_count'] +1, + min_value = kwargs['tcp_dst_port'] - tcp_dst_port_count * kwargs['tcp_dst_port_step'] + 1, max_value = kwargs['tcp_dst_port'])) elif kwargs['tcp_dst_port_mode'] == 'random': - vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_dst', size = 2, op = 'random', - min_value = kwargs['tcp_dst_port'], - max_value = kwargs['tcp_dst_port'] + kwargs['tcp_dst_port_count'] - 1)) + vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_dst', size = 2, op = 'random', min_value = 0, max_value = 0xffff)) else: raise STLError('tcp_dst_port_mode %s is not supported' % kwargs['tcp_dst_port_mode']) vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='tcp_dst', pkt_offset = 'TCP.dport')) @@ -1037,44 +1036,42 @@ def generate_packet(**user_kwargs): dport = kwargs['udp_dst_port'], len = kwargs['udp_length'], chksum = None) # UDP VM - if kwargs['udp_src_port_count'] != 1: - if kwargs['udp_src_port_count'] < 1: + if kwargs['udp_src_port_mode'] != 'fixed': + udp_src_port_count = kwargs['udp_src_port_count'] + if udp_src_port_count < 1: raise STLError('udp_src_port_count has to be at least 1') - if kwargs['udp_src_port_count'] > 1: + if udp_src_port_count > 1: fix_ipv4_checksum = True if kwargs['udp_src_port_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_src', size = 2, op = 'inc', step = kwargs['udp_src_port_step'], min_value = kwargs['udp_src_port'], - max_value = kwargs['udp_src_port'] + kwargs['udp_src_port_count'] - 1)) + max_value = kwargs['udp_src_port'] + udp_src_port_count * kwargs['udp_src_port_step'] - 1)) elif kwargs['udp_src_port_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_src', size = 2, op = 'dec', step = kwargs['udp_src_port_step'], - min_value = kwargs['udp_src_port'] - kwargs['udp_src_port_count'] +1, + min_value = kwargs['udp_src_port'] - udp_src_port_count * kwargs['udp_src_port_step'] + 1, max_value = kwargs['udp_src_port'])) elif kwargs['udp_src_port_mode'] == 'random': - vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_src', size = 2, op = 'random', - min_value = kwargs['udp_src_port'], - max_value = kwargs['udp_src_port'] + kwargs['udp_src_port_count'] - 1)) + vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_src', size = 2, op = 'random', min_value = 0, max_value = 0xffff)) else: raise STLError('udp_src_port_mode %s is not supported' % kwargs['udp_src_port_mode']) vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='udp_src', pkt_offset = 'UDP.sport')) - if kwargs['udp_dst_port_count'] != 1: - if kwargs['udp_dst_port_count'] < 1: + if kwargs['udp_dst_port_mode'] != 'fixed': + udp_dst_port_count = kwargs['udp_dst_port_count'] + if udp_dst_port_count < 1: raise STLError('udp_dst_port_count has to be at least 1') - if kwargs['udp_dst_port_count'] > 1: + if udp_dst_port_count > 1: fix_ipv4_checksum = True if kwargs['udp_dst_port_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_dst', size = 2, op = 'inc', step = kwargs['udp_dst_port_step'], min_value = kwargs['udp_dst_port'], - max_value = kwargs['udp_dst_port'] + kwargs['udp_dst_port_count'] - 1)) + max_value = kwargs['udp_dst_port'] + udp_dst_port_count * kwargs['udp_dst_port_step'] - 1)) elif kwargs['udp_dst_port_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_dst', size = 2, op = 'dec', step = kwargs['udp_dst_port_step'], - min_value = kwargs['udp_dst_port'] - kwargs['udp_dst_port_count'] +1, + min_value = kwargs['udp_dst_port'] - udp_dst_port_count * kwargs['udp_dst_port_step'] + 1, max_value = kwargs['udp_dst_port'])) elif kwargs['udp_dst_port_mode'] == 'random': - vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_dst', size = 2, op = 'random', - min_value = kwargs['udp_dst_port'], - max_value = kwargs['udp_dst_port'] + kwargs['udp_dst_port_count'] - 1)) + vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_dst', size = 2, op = 'random', min_value = 0, max_value = 0xffff)) else: raise STLError('udp_dst_port_mode %s is not supported' % kwargs['udp_dst_port_mode']) vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='udp_dst', pkt_offset = 'UDP.dport')) @@ -1138,7 +1135,25 @@ def generate_packet(**user_kwargs): if fix_ipv4_checksum and l3_layer.name == 'IP' and kwargs['ip_checksum'] is None: vm_cmds.append(CTRexVmDescFixIpv4(offset = 'IP')) if vm_cmds: - pkt.add_command(CTRexScRaw(vm_cmds)) + split_by_field = None + if kwargs['split_by_cores'] == 'single': + raise STLError("split_by_cores 'single' not implemented yet") + elif kwargs['split_by_cores'] == 'split': + max_length = 0 + for cmd in vm_cmds: + if isinstance(cmd, CTRexVmDescFlowVar): + if cmd.op not in ('inc', 'dec'): + continue + length = float(cmd.max_value - cmd.min_value) / cmd.step + if cmd.name == 'ip_src' and length > 7: # priority is to split by ip_src + split_by_field = 'ip_src' + break + if length > max_length: + max_length = length + split_by_field = cmd.name + elif kwargs['split_by_cores'] != 'duplicate': + raise STLError("split_by_cores '%s' not supported" % kwargs['split_by_cores']) + pkt.add_command(CTRexScRaw(vm_cmds, split_by_field)) # debug (only the base packet, without VM) debug_filename = kwargs.get('save_to_pcap') @@ -1183,10 +1198,6 @@ def split_vlan_args(kwargs): for arg, value in kwargs.items(): if arg.startswith('vlan_'): vlan_args_dict[arg] = split_vlan_arg(value) - if arg == 'vlan_protocol_tag_id': # special case, can be string of hex - print vlan_args_dict[arg] - vlan_args_dict[arg] = [int(x, 16) for x in vlan_args_dict[arg] if type(x) is str] - print vlan_args_dict[arg] dot1q_headers_count = max([len(x) for x in vlan_args_dict.values()]) vlan_args_per_header = [{} for _ in range(dot1q_headers_count)] for arg, value in vlan_args_dict.items(): @@ -1197,4 +1208,17 @@ def split_vlan_args(kwargs): vlan_args_per_header[i][arg] = traffic_config_kwargs[arg] return vlan_args_per_header - +def correct_direction(user_kwargs, kwargs): + if kwargs['direction'] == 0: + return + user_kwargs['mac_src'], user_kwargs['mac_dst'] = kwargs['mac_dst'], kwargs['mac_src'] + if kwargs['l3_protocol'] == 'ipv4': + for arg in kwargs.keys(): + if 'ip_src_' in arg: + dst_arg = 'ip_dst_' + arg[7:] + user_kwargs[arg], user_kwargs[dst_arg] = kwargs[dst_arg], kwargs[arg] + elif kwargs['l3_protocol'] == 'ipv6': + for arg in kwargs.keys(): + if 'ipv6_src_' in arg: + dst_arg = 'ipv6_dst_' + arg[9:] + user_kwargs[arg], user_kwargs[dst_arg] = kwargs[dst_arg], kwargs[arg] diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py index 24a7301b..fc4750c3 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py @@ -28,17 +28,24 @@ class CTRexPacketBuildException(Exception): ################################################################################################ -def ipv4_str_to_num (ipv4_buffer): +def _buffer_to_num(str_buffer): + assert type(str_buffer)==str, 'type of str_buffer is not str' + res=0 + for i in str_buffer: + res = res << 8 + res += ord(i) + return res + +def ipv4_str_to_num (ipv4_buffer): assert type(ipv4_buffer)==str, 'type of ipv4_buffer is not str' assert len(ipv4_buffer)==4, 'size of ipv4_buffer is not 4' - res=0 - shift=24 - for i in ipv4_buffer: - res = res + (ord(i)< Date: Sun, 21 Feb 2016 18:01:36 +0200 Subject: typo in step and min/max_value; support old-type classes in validate_type; assert positive values in python; hlt fix vlan vm + test for it; --- .../functional_tests/hltapi_stream_builder_test.py | 133 ++++++++++++++++----- .../stl/trex_stl_lib/trex_stl_hltapi.py | 125 +++++++++---------- .../trex_stl_lib/trex_stl_packet_builder_scapy.py | 6 +- .../stl/trex_stl_lib/trex_stl_types.py | 5 +- src/stateless/cp/trex_stream_vm.h | 16 +-- 5 files changed, 188 insertions(+), 97 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl') diff --git a/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py b/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py index 1f276cff..df93aba1 100755 --- a/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py +++ b/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py @@ -38,11 +38,10 @@ class CTRexHltApi_Test(unittest.TestCase): with self.assertRaises(Exception): STLHltStream(l2_encap = 'ethernet_sdfgsdfg') # all default values - test_stream = STLHltStream(name = 'stream-0') + test_stream = STLHltStream() self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' -- name: stream-0 - stream: +- stream: action_count: 0 enabled: true flags: 3 @@ -61,10 +60,10 @@ class CTRexHltApi_Test(unittest.TestCase): split_by_var: '' ''' - # Eth/IP/TCP, test L2 fields, wait for masking of variables for MAC + # Eth/IP/TCP, test MAC fields VM, wait for masking of variables for MAC @nottest - def test_l2_basic(self): - test_stream = STLHltStream(name = 'stream-0') + def test_macs_vm(self): + test_stream = STLHltStream(name = 'stream-0', ) self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' TBD @@ -93,10 +92,10 @@ TBD ip_dst_addr = '5.5.5.5', ip_dst_count = 2, ip_dst_mode = 'random', - name = 'stream-0') + name = 'test_ip_ranges') self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' -- name: stream-0 +- name: test_ip_ranges stream: action_count: 0 enabled: true @@ -151,10 +150,10 @@ TBD tcp_dst_port_mode = 'random', tcp_dst_port_count = 10, tcp_dst_port = 1234, - name = 'stream-0') + name = 'test_tcp_ranges') self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' -- name: stream-0 +- name: test_tcp_ranges stream: action_count: 0 enabled: true @@ -228,10 +227,10 @@ TBD udp_dst_port_mode = 'increment', udp_dst_port_count = 10, udp_dst_port = 1234, - name = 'stream-0') + name = 'test_udp_ranges') self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' -- name: stream-0 +- name: test_udp_ranges stream: action_count: 0 enabled: true @@ -288,10 +287,10 @@ TBD test_stream = STLHltStream(length_mode = 'decrement', frame_size_min = 100, frame_size_max = 3000, - name = 'stream-0') + name = 'test_pkt_len_by_framesize') self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' -- name: stream-0 +- name: test_pkt_len_by_framesize stream: action_count: 0 enabled: true @@ -334,10 +333,10 @@ TBD length_mode = 'random', l3_length_min = 100, l3_length_max = 400, - name = 'stream-0') + name = 'test_pkt_len_by_l3length') self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' -- name: stream-0 +- name: test_pkt_len_by_l3length stream: action_count: 0 enabled: true @@ -387,11 +386,11 @@ TBD test_stream = STLHltStream(l2_encap = 'ethernet_ii') assert ':802.1Q:' not in test_stream.get_pkt_type(), 'Default packet should not include dot1q' - test_stream = STLHltStream(name = 'stream-0', l2_encap = 'ethernet_ii_vlan') + test_stream = STLHltStream(name = 'test_vlan_basic', l2_encap = 'ethernet_ii_vlan') assert ':802.1Q:' in test_stream.get_pkt_type(), 'No dot1q in packet with encap ethernet_ii_vlan' self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' -- name: stream-0 +- name: test_vlan_basic stream: action_count: 0 enabled: true @@ -416,12 +415,14 @@ TBD # default frame size should be not enough with self.assertRaises(Exception): STLHltStream(vlan_id = [1, 2, 3, 4]) - test_stream = STLHltStream(name = 'stream-0', frame_size = 100, vlan_id = [1, 2, 3, 4], vlan_protocol_tag_id = '8100 0x8100') + test_stream = STLHltStream(name = 'test_vlan_multiple', frame_size = 100, + vlan_id = [1, 2, 3, 4], # can be either array or string separated by spaces + vlan_protocol_tag_id = '8100 0x8100') pkt_layers = test_stream.get_pkt_type() - assert ':802.1Q:802.1Q:802.1Q:802.1Q:' in pkt_layers, 'No four dot1q layers in packet: %s' % pkt_layers + assert '802.1Q:' * 4 in pkt_layers, 'No four dot1q layers in packet: %s' % pkt_layers self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' -- name: stream-0 +- name: test_vlan_multiple stream: action_count: 0 enabled: true @@ -441,6 +442,84 @@ TBD split_by_var: '' ''' + # Eth/IP/TCP, with 5 vlans and VMs on vlan_id + def test_vlan_vm(self): + test_stream = STLHltStream(name = 'test_vlan_vm', frame_size = 100, + vlan_id = '1 2 1000 4 5', # 5 vlans + vlan_id_mode = 'increment fixed decrement random', # 5th vlan will be default fixed + vlan_id_step = 2, # 1st vlan step will be 2, others - default 1 + vlan_id_count = [4, 1, 10], # 4th independent on count, 5th will be fixed + ) + pkt_layers = test_stream.get_pkt_type() + self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) + assert '802.1Q:' * 5 in pkt_layers, 'No five dot1q layers in packet: %s' % pkt_layers + self.golden_yaml = ''' +- name: test_vlan_vm + stream: + action_count: 0 + enabled: true + flags: 3 + isg: 0.0 + mode: + pps: 1 + type: continuous + packet: + binary: AAAAAAAAAAABAAABgQAwAYEAMAKBADPogQAwBIEAMAUIAEUAAEIAAAAAQAa6tQAAAADAAAABBAAAUAAAAAEAAAABUAAP5SzkAAAhISEhISEhISEhISEhISEhISEhISEhISEhIQ== + meta: '' + rx_stats: + enabled: false + self_start: true + vm: + instructions: + - init_value: 1 + max_value: 7 + min_value: 1 + name: vlan_id0 + op: inc + size: 2 + step: 2 + type: flow_var + - is_big_endian: true + mask: 4095 + name: vlan_id0 + pkt_cast_size: 2 + pkt_offset: 14 + shift: 0 + type: write_mask_flow_var + - init_value: 1000 + max_value: 1000 + min_value: 991 + name: vlan_id2 + op: dec + size: 2 + step: 1 + type: flow_var + - is_big_endian: true + mask: 4095 + name: vlan_id2 + pkt_cast_size: 2 + pkt_offset: 22 + shift: 0 + type: write_mask_flow_var + - init_value: 0 + max_value: 65535 + min_value: 0 + name: vlan_id3 + op: random + size: 2 + step: 1 + type: flow_var + - is_big_endian: true + mask: 4095 + name: vlan_id3 + pkt_cast_size: 2 + pkt_offset: 26 + shift: 0 + type: write_mask_flow_var + split_by_var: vlan_id2 +''' + + # Eth/IPv6/TCP, no VM def test_ipv6_basic(self): # default frame size should be not enough @@ -451,10 +530,10 @@ TBD # error should affect with self.assertRaises(Exception): STLHltStream(l3_protocol = 'ipv6', ipv6_src_addr = 'asdfasdfasgasdf') - test_stream = STLHltStream(name = 'stream-0', l3_protocol = 'ipv6', length_mode = 'fixed', l3_length = 150, ) + test_stream = STLHltStream(name = 'test_ipv6_basic', l3_protocol = 'ipv6', length_mode = 'fixed', l3_length = 150, ) self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' -- name: stream-0 +- name: test_ipv6_basic stream: action_count: 0 enabled: true @@ -476,7 +555,7 @@ TBD # Eth/IPv6/UDP, VM on ipv6 fields def test_ipv6_src_dst_ranges(self): - test_stream = STLHltStream(name = 'stream-0', l3_protocol = 'ipv6', l3_length = 150, l4_protocol = 'udp', + test_stream = STLHltStream(name = 'test_ipv6_src_dst_ranges', l3_protocol = 'ipv6', l3_length = 150, l4_protocol = 'udp', ipv6_src_addr = '1111:2222:3333:4444:5555:6666:7777:8888', ipv6_dst_addr = '1111:1111:1111:1111:1111:1111:1111:1111', ipv6_src_mode = 'increment', ipv6_src_step = 5, ipv6_src_count = 10, @@ -484,7 +563,7 @@ TBD ) self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location()) self.golden_yaml = ''' -- name: stream-0 +- name: test_ipv6_src_dst_ranges stream: action_count: 0 enabled: true @@ -502,7 +581,7 @@ TBD vm: instructions: - init_value: 2004322440 - max_value: 2004322489 + max_value: 2004322485 min_value: 2004322440 name: ipv6_src op: inc @@ -516,7 +595,7 @@ TBD type: write_flow_var - init_value: 286331153 max_value: 286331153 - min_value: 286328604 + min_value: 286328620 name: ipv6_dst op: dec size: 4 diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py index a3d4e319..10c9d725 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py @@ -756,18 +756,18 @@ def generate_packet(**user_kwargs): # Eth VM # WIP!!! Need 8 bytes mask and vars if kwargs['mac_src_mode'] != 'fixed': - mac_src_count = kwargs['mac_src_count'] - if mac_src_count < 1: + mac_src_count = kwargs['mac_src_count'] - 1 + if mac_src_count < 0: raise STLError('mac_src_count has to be at least 1') - if mac_src_count > 1: + if mac_src_count > 0: mac_src = mac_str_to_num(mac2str(kwargs['mac_src'])) if kwargs['mac_src_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'mac_src', size = 4, op = 'inc', step = kwargs['mac_src_step'], min_value = mac_src, - max_value = mac_src + mac_src_count * kwargs['mac_src_step'] - 1)) + max_value = mac_src + mac_src_count * kwargs['mac_src_step'])) elif kwargs['mac_src_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'mac_src', size = 4, op = 'dec', step = kwargs['mac_src_step'], - min_value = mac_src - mac_src_count * kwargs['mac_src_step'] + 1, + min_value = mac_src - mac_src_count * kwargs['mac_src_step'], max_value = mac_src)) elif kwargs['mac_src_mode'] == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = 'mac_src', size = 4, op = 'random', min_value = 0, max_value = 0xffffffffffffffff)) @@ -782,8 +782,9 @@ def generate_packet(**user_kwargs): # BitField("vlan", 1, 12), # XShortEnumField("type", 0x0000, ETHER_TYPES) ] for i, vlan_kwargs in enumerate(split_vlan_args(kwargs)): + vlan_id = int(vlan_kwargs['vlan_id']) dot1q_kwargs = {'prio': vlan_kwargs['vlan_user_priority'], - 'vlan': vlan_kwargs['vlan_id'], + 'vlan': vlan_id, 'id': vlan_kwargs['vlan_cfi']} vlan_protocol_tag_id = vlan_kwargs['vlan_protocol_tag_id'] if vlan_protocol_tag_id is not None: @@ -793,26 +794,28 @@ def generate_packet(**user_kwargs): l2_layer /= Dot1Q(**dot1q_kwargs) # vlan VM - if vlan_kwargs['vlan_id_mode'] != 'fixed': - vlan_id_count = vlan_kwargs['vlan_id_count'] - if vlan_id_count < 1: + vlan_id_mode = vlan_kwargs['vlan_id_mode'] + if vlan_id_mode != 'fixed': + vlan_id_count = int(vlan_kwargs['vlan_id_count']) - 1 + if vlan_id_count < 0: raise STLError('vlan_id_count has to be at least 1') - if vlan_id_count > 1: + if vlan_id_count > 0 or vlan_id_mode == 'random': var_name = 'vlan_id%s' % i - if kwargs['vlan_id_mode'] == 'increment': - vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 2, op = 'inc', step = vlan_kwargs['vlan_id_step'], - min_value = kwargs['vlan_id'], - max_value = kwargs['vlan_id'] + vlan_id_count * vlan_kwargs['vlan_id_step'] - 1)) - elif kwargs['vlan_id_mode'] == 'decrement': - vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 2, op = 'dec', step = vlan_kwargs['vlan_id_step'], - min_value = kwargs['vlan_id'] - vlan_id_count * vlan_kwargs['vlan_id_step'] + 1, - max_value = kwargs['vlan_id'])) - elif kwargs['vlan_id_mode'] == 'random': + step = int(vlan_kwargs['vlan_id_step']) + if vlan_id_mode == 'increment': + vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 2, op = 'inc', step = step, + min_value = vlan_id, + max_value = vlan_id + vlan_id_count * step)) + elif vlan_id_mode == 'decrement': + vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 2, op = 'dec', step = step, + min_value = vlan_id - vlan_id_count * step, + max_value = vlan_id)) + elif vlan_id_mode == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 2, op = 'random', min_value = 0, max_value = 0xffff)) else: - raise STLError('vlan_id_mode %s is not supported' % kwargs['vlan_id_mode']) - vm_cmds.append(STLVmWrMaskFlowVar(fv_name = var_name, pkt_offset = 'Dot1Q:%s.vlan' % i, - pkt_cast_size = 2, mask = 0x0fff)) + raise STLError('vlan_id_mode %s is not supported' % vlan_id_mode) + vm_cmds.append(STLVmWrMaskFlowVar(fv_name = var_name, pkt_offset = '802|1Q:%s.vlan' % i, + pkt_cast_size = 2, mask = 0xfff)) else: raise NotImplementedError("l2_encap does not support the desired encapsulation '%s'" % kwargs['l2_encap']) @@ -847,19 +850,19 @@ def generate_packet(**user_kwargs): ) # IPv4 VM if kwargs['ip_src_mode'] != 'fixed': - ip_src_count = kwargs['ip_src_count'] - if ip_src_count < 1: + ip_src_count = kwargs['ip_src_count'] - 1 + if ip_src_count < 0: raise STLError('ip_src_count has to be at least 1') - if ip_src_count > 1: + if ip_src_count > 0: fix_ipv4_checksum = True ip_src_addr_num = ipv4_str_to_num(is_valid_ipv4(kwargs['ip_src_addr'])) if kwargs['ip_src_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'inc', step = kwargs['ip_src_step'], min_value = ip_src_addr_num, - max_value = ip_src_addr_num + ip_src_count * kwargs['ip_src_step'] - 1)) + max_value = ip_src_addr_num + ip_src_count * kwargs['ip_src_step'])) elif kwargs['ip_src_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'dec', step = kwargs['ip_src_step'], - min_value = ip_src_addr_num - ip_src_count * kwargs['ip_src_step'] + 1, + min_value = ip_src_addr_num - ip_src_count * kwargs['ip_src_step'], max_value = ip_src_addr_num)) elif kwargs['ip_src_mode'] == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff)) @@ -868,19 +871,19 @@ def generate_packet(**user_kwargs): vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='ip_src', pkt_offset = 'IP.src')) if kwargs['ip_dst_mode'] != 'fixed': - ip_dst_count = kwargs['ip_dst_count'] - if ip_dst_count < 1: + ip_dst_count = kwargs['ip_dst_count'] - 1 + if ip_dst_count < 0: raise STLError('ip_dst_count has to be at least 1') - if ip_dst_count > 1: + if ip_dst_count > 0: fix_ipv4_checksum = True ip_dst_addr_num = ipv4_str_to_num(is_valid_ipv4(kwargs['ip_dst_addr'])) if kwargs['ip_dst_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'inc', step = kwargs['ip_dst_step'], min_value = ip_dst_addr_num, - max_value = ip_dst_addr_num + ip_dst_count * kwargs['ip_dst_step'] - 1)) + max_value = ip_dst_addr_num + ip_dst_count * kwargs['ip_dst_step'])) elif kwargs['ip_dst_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'dec', step = kwargs['ip_dst_step'], - min_value = ip_dst_addr_num - ip_dst_count * kwargs['ip_dst_step'] + 1, + min_value = ip_dst_addr_num - ip_dst_count * kwargs['ip_dst_step'], max_value = ip_dst_addr_num)) elif kwargs['ip_dst_mode'] == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff)) @@ -909,9 +912,10 @@ def generate_packet(**user_kwargs): # IPv6 VM if kwargs['ipv6_src_mode'] != 'fixed': - if kwargs['ipv6_src_count'] < 1: + ipv6_src_count = kwargs['ipv6_src_count'] - 1 + if ipv6_src_count < 0: raise STLError('ipv6_src_count has to be at least 1') - if kwargs['ipv6_src_count'] > 1: + if ipv6_src_count > 0: ipv6_src_addr_num = ipv4_str_to_num(is_valid_ipv6(kwargs['ipv6_src_addr'])[-4:]) ipv6_src_step = kwargs['ipv6_src_step'] if type(ipv6_src_step) is str: # convert ipv6 step to number @@ -919,10 +923,10 @@ def generate_packet(**user_kwargs): if kwargs['ipv6_src_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_src', size = 4, op = 'inc', step = ipv6_src_step, min_value = ipv6_src_addr_num, - max_value = ipv6_src_addr_num + kwargs['ipv6_src_count'] * ipv6_src_step - 1)) + max_value = ipv6_src_addr_num + ipv6_src_count * ipv6_src_step)) elif kwargs['ipv6_src_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_src', size = 4, op = 'dec', step = ipv6_src_step, - min_value = ipv6_src_addr_num - kwargs['ipv6_src_count'] * ipv6_src_step + 1, + min_value = ipv6_src_addr_num - ipv6_src_count * ipv6_src_step, max_value = ipv6_src_addr_num)) elif kwargs['ipv6_src_mode'] == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_src', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff)) @@ -931,9 +935,10 @@ def generate_packet(**user_kwargs): vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='ipv6_src', pkt_offset = 'IPv6.src', offset_fixup = 12)) if kwargs['ipv6_dst_mode'] != 'fixed': - if kwargs['ipv6_dst_count'] < 1: + ipv6_dst_count = kwargs['ipv6_dst_count'] - 1 + if ipv6_dst_count < 0: raise STLError('ipv6_dst_count has to be at least 1') - if kwargs['ipv6_dst_count'] > 1: + if ipv6_dst_count > 0: ipv6_dst_addr_num = ipv4_str_to_num(is_valid_ipv6(kwargs['ipv6_dst_addr'])[-4:]) ipv6_dst_step = kwargs['ipv6_dst_step'] if type(ipv6_dst_step) is str: # convert ipv6 step to number @@ -941,10 +946,10 @@ def generate_packet(**user_kwargs): if kwargs['ipv6_dst_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_dst', size = 4, op = 'inc', step = ipv6_dst_step, min_value = ipv6_dst_addr_num, - max_value = ipv6_dst_addr_num + kwargs['ipv6_dst_count'] * ipv6_dst_step - 1)) + max_value = ipv6_dst_addr_num + ipv6_dst_count * ipv6_dst_step)) elif kwargs['ipv6_dst_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_dst', size = 4, op = 'dec', step = ipv6_dst_step, - min_value = ipv6_dst_addr_num - kwargs['ipv6_dst_count'] * ipv6_dst_step + 1, + min_value = ipv6_dst_addr_num - ipv6_dst_count * ipv6_dst_step, max_value = ipv6_dst_addr_num)) elif kwargs['ipv6_dst_mode'] == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_dst', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff)) @@ -988,18 +993,18 @@ def generate_packet(**user_kwargs): ) # TCP VM if kwargs['tcp_src_port_mode'] != 'fixed': - tcp_src_port_count = kwargs['tcp_src_port_count'] - if tcp_src_port_count < 1: + tcp_src_port_count = kwargs['tcp_src_port_count'] - 1 + if tcp_src_port_count < 0: raise STLError('tcp_src_port_count has to be at least 1') - if tcp_src_port_count > 1: + if tcp_src_port_count > 0: fix_ipv4_checksum = True if kwargs['tcp_src_port_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_src', size = 2, op = 'inc', step = kwargs['tcp_src_port_step'], min_value = kwargs['tcp_src_port'], - max_value = kwargs['tcp_src_port'] + tcp_src_port_count * kwargs['tcp_src_port_step'] - 1)) + max_value = kwargs['tcp_src_port'] + tcp_src_port_count * kwargs['tcp_src_port_step'])) elif kwargs['tcp_src_port_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_src', size = 2, op = 'dec', step = kwargs['tcp_src_port_step'], - min_value = kwargs['tcp_src_port'] - tcp_src_port_count * kwargs['tcp_src_port_step'] + 1, + min_value = kwargs['tcp_src_port'] - tcp_src_port_count * kwargs['tcp_src_port_step'], max_value = kwargs['tcp_src_port'])) elif kwargs['tcp_src_port_mode'] == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_src', size = 2, op = 'random', min_value = 0, max_value = 0xffff)) @@ -1008,18 +1013,18 @@ def generate_packet(**user_kwargs): vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='tcp_src', pkt_offset = 'TCP.sport')) if kwargs['tcp_dst_port_mode'] != 'fixed': - tcp_dst_port_count = kwargs['tcp_dst_port_count'] - if tcp_dst_port_count < 1: + tcp_dst_port_count = kwargs['tcp_dst_port_count'] - 1 + if tcp_dst_port_count < 0: raise STLError('tcp_dst_port_count has to be at least 1') - if tcp_dst_port_count > 1: + if tcp_dst_port_count > 0: fix_ipv4_checksum = True if kwargs['tcp_dst_port_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_dst', size = 2, op = 'inc', step = kwargs['tcp_dst_port_step'], min_value = kwargs['tcp_dst_port'], - max_value = kwargs['tcp_dst_port'] + tcp_dst_port_count * kwargs['tcp_dst_port_step'] - 1)) + max_value = kwargs['tcp_dst_port'] + tcp_dst_port_count * kwargs['tcp_dst_port_step'])) elif kwargs['tcp_dst_port_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_dst', size = 2, op = 'dec', step = kwargs['tcp_dst_port_step'], - min_value = kwargs['tcp_dst_port'] - tcp_dst_port_count * kwargs['tcp_dst_port_step'] + 1, + min_value = kwargs['tcp_dst_port'] - tcp_dst_port_count * kwargs['tcp_dst_port_step'], max_value = kwargs['tcp_dst_port'])) elif kwargs['tcp_dst_port_mode'] == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_dst', size = 2, op = 'random', min_value = 0, max_value = 0xffff)) @@ -1037,18 +1042,18 @@ def generate_packet(**user_kwargs): len = kwargs['udp_length'], chksum = None) # UDP VM if kwargs['udp_src_port_mode'] != 'fixed': - udp_src_port_count = kwargs['udp_src_port_count'] - if udp_src_port_count < 1: + udp_src_port_count = kwargs['udp_src_port_count'] - 1 + if udp_src_port_count < 0: raise STLError('udp_src_port_count has to be at least 1') - if udp_src_port_count > 1: + if udp_src_port_count > 0: fix_ipv4_checksum = True if kwargs['udp_src_port_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_src', size = 2, op = 'inc', step = kwargs['udp_src_port_step'], min_value = kwargs['udp_src_port'], - max_value = kwargs['udp_src_port'] + udp_src_port_count * kwargs['udp_src_port_step'] - 1)) + max_value = kwargs['udp_src_port'] + udp_src_port_count * kwargs['udp_src_port_step'])) elif kwargs['udp_src_port_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_src', size = 2, op = 'dec', step = kwargs['udp_src_port_step'], - min_value = kwargs['udp_src_port'] - udp_src_port_count * kwargs['udp_src_port_step'] + 1, + min_value = kwargs['udp_src_port'] - udp_src_port_count * kwargs['udp_src_port_step'], max_value = kwargs['udp_src_port'])) elif kwargs['udp_src_port_mode'] == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_src', size = 2, op = 'random', min_value = 0, max_value = 0xffff)) @@ -1057,18 +1062,18 @@ def generate_packet(**user_kwargs): vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='udp_src', pkt_offset = 'UDP.sport')) if kwargs['udp_dst_port_mode'] != 'fixed': - udp_dst_port_count = kwargs['udp_dst_port_count'] - if udp_dst_port_count < 1: + udp_dst_port_count = kwargs['udp_dst_port_count'] - 1 + if udp_dst_port_count < 0: raise STLError('udp_dst_port_count has to be at least 1') - if udp_dst_port_count > 1: + if udp_dst_port_count > 0: fix_ipv4_checksum = True if kwargs['udp_dst_port_mode'] == 'increment': vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_dst', size = 2, op = 'inc', step = kwargs['udp_dst_port_step'], min_value = kwargs['udp_dst_port'], - max_value = kwargs['udp_dst_port'] + udp_dst_port_count * kwargs['udp_dst_port_step'] - 1)) + max_value = kwargs['udp_dst_port'] + udp_dst_port_count * kwargs['udp_dst_port_step'])) elif kwargs['udp_dst_port_mode'] == 'decrement': vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_dst', size = 2, op = 'dec', step = kwargs['udp_dst_port_step'], - min_value = kwargs['udp_dst_port'] - udp_dst_port_count * kwargs['udp_dst_port_step'] + 1, + min_value = kwargs['udp_dst_port'] - udp_dst_port_count * kwargs['udp_dst_port_step'], max_value = kwargs['udp_dst_port'])) elif kwargs['udp_dst_port_mode'] == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_dst', size = 2, op = 'random', min_value = 0, max_value = 0xffff)) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py index fc4750c3..713769b6 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py @@ -222,12 +222,16 @@ class CTRexVmInsFlowVar(CTRexVmInsBase): self.op = op self.init_value = init_value assert type(init_value)==int, 'type of init_value is not int' + assert init_value >= 0, 'init_value (%s) is negative' % init_value self.min_value=min_value assert type(min_value)==int, 'type of min_value is not int' + assert min_value >= 0, 'min_value (%s) is negative' % min_value self.max_value=max_value - assert type(max_value)==int, 'type of min_value is not int' + assert type(max_value)==int, 'type of max_value is not int' + assert max_value >= 0, 'max_value (%s) is negative' % max_value self.step=step assert type(step)==int, 'type of step should be int' + assert step >= 0, 'step (%s) is negative' % step class CTRexVmInsWrFlowVar(CTRexVmInsBase): def __init__(self, fv_name, pkt_offset, add_value=0, is_big_endian=True): diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py index 0a6e64fb..aa09b0a1 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py @@ -2,6 +2,7 @@ from collections import namedtuple from utils.text_opts import * from trex_stl_exceptions import * +import types RpcCmdData = namedtuple('RpcCmdData', ['method', 'params']) TupleRC = namedtuple('RC', ['rc', 'data', 'is_warn']) @@ -102,7 +103,9 @@ def RC_WARN (warn): def validate_type(arg_name, arg, valid_types): if type(valid_types) is list: valid_types = tuple(valid_types) - if type(valid_types) is type or type(valid_types) is tuple: + if (type(valid_types) is type or # single type, not array of types + type(valid_types) is tuple or # several valid types as tuple + type(valid_types) is types.ClassType): # old style class if isinstance(arg, valid_types): return raise STLTypeError(arg_name, type(arg), valid_types) diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index 13504703..023286d0 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -227,7 +227,7 @@ public: inline void run_inc(uint8_t * flow_var) { uint8_t *p = (flow_var + m_flow_offset); - if (*p >= (m_max_val-m_step)) { + if (*p > (m_max_val-m_step)) { *p = m_min_val; } else { *p = *p + m_step; @@ -236,7 +236,7 @@ public: inline void run_dec(uint8_t * flow_var) { uint8_t *p = (flow_var + m_flow_offset); - if (*p <= (m_min_val+m_step)) { + if (*p < (m_min_val+m_step)) { *p = m_max_val; } else { *p = *p - m_step; @@ -257,7 +257,7 @@ public: inline void run_inc(uint8_t * flow_var) { uint16_t *p = (uint16_t *)(flow_var + m_flow_offset); - if (*p >= (m_max_val-m_step)) { + if (*p > (m_max_val-m_step)) { *p = m_min_val; } else { *p = *p + m_step; @@ -266,7 +266,7 @@ public: inline void run_dec(uint8_t * flow_var) { uint16_t *p = (uint16_t *)(flow_var + m_flow_offset); - if (*p <= (m_min_val+m_step)) { + if (*p < (m_min_val+m_step)) { *p = m_max_val; } else { *p = *p - m_step; @@ -286,7 +286,7 @@ public: inline void run_inc(uint8_t * flow_var) { uint32_t *p = (uint32_t *)(flow_var + m_flow_offset); - if (*p >= (m_max_val-m_step)) { + if (*p > (m_max_val-m_step)) { *p = m_min_val; } else { *p = *p + m_step; @@ -295,7 +295,7 @@ public: inline void run_dec(uint8_t * flow_var) { uint32_t *p = (uint32_t *)(flow_var + m_flow_offset); - if (*p <= (m_min_val+m_step)) { + if (*p < (m_min_val+m_step)) { *p = m_max_val; } else { *p = *p - m_step; @@ -315,7 +315,7 @@ public: inline void run_inc(uint8_t * flow_var) { uint64_t *p = (uint64_t *)(flow_var + m_flow_offset); - if (*p >= (m_max_val-m_step) ) { + if (*p > (m_max_val-m_step) ) { *p = m_min_val; } else { *p = *p + m_step; @@ -324,7 +324,7 @@ public: inline void run_dec(uint8_t * flow_var) { uint64_t *p = (uint64_t *)(flow_var + m_flow_offset); - if (*p <= m_min_val+m_step) { + if (*p < m_min_val+m_step) { *p = m_max_val; } else { *p = *p - m_step; -- cgit 1.2.3-korg From 8fd2c69a3ba37d88949dc487f3851f84b81007a0 Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Sun, 21 Feb 2016 18:28:32 +0200 Subject: hlt: support ipv4 step number or ip --- .../stl/trex_stl_lib/trex_stl_hltapi.py | 38 ++++++++++++++-------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py index 10c9d725..60654f0a 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py @@ -855,15 +855,20 @@ def generate_packet(**user_kwargs): raise STLError('ip_src_count has to be at least 1') if ip_src_count > 0: fix_ipv4_checksum = True - ip_src_addr_num = ipv4_str_to_num(is_valid_ipv4(kwargs['ip_src_addr'])) + ip_src_addr = kwargs['ip_src_addr'] + if type(ip_src_addr) is str: + ip_src_addr = ipv4_str_to_num(is_valid_ipv4(ip_src_addr)) + ip_src_step = kwargs['ip_src_step'] + if type(ip_src_step) is str: + ip_src_step = ipv4_str_to_num(is_valid_ipv4(ip_src_step)) if kwargs['ip_src_mode'] == 'increment': - vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'inc', step = kwargs['ip_src_step'], - min_value = ip_src_addr_num, - max_value = ip_src_addr_num + ip_src_count * kwargs['ip_src_step'])) + vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'inc', step = ip_src_step, + min_value = ip_src_addr, + max_value = ip_src_addr + ip_src_count * ip_src_step)) elif kwargs['ip_src_mode'] == 'decrement': - vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'dec', step = kwargs['ip_src_step'], - min_value = ip_src_addr_num - ip_src_count * kwargs['ip_src_step'], - max_value = ip_src_addr_num)) + vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'dec', step = ip_src_step, + min_value = ip_src_addr - ip_src_count * ip_src_step, + max_value = ip_src_addr)) elif kwargs['ip_src_mode'] == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff)) else: @@ -876,15 +881,20 @@ def generate_packet(**user_kwargs): raise STLError('ip_dst_count has to be at least 1') if ip_dst_count > 0: fix_ipv4_checksum = True - ip_dst_addr_num = ipv4_str_to_num(is_valid_ipv4(kwargs['ip_dst_addr'])) + ip_dst_addr = kwargs['ip_dst_addr'] + if type(ip_dst_addr) is str: + ip_dst_addr = ipv4_str_to_num(is_valid_ipv4(ip_dst_addr)) + ip_dst_step = kwargs['ip_dst_step'] + if type(ip_dst_step) is str: + ip_dst_step = ipv4_str_to_num(is_valid_ipv4(ip_dst_step)) if kwargs['ip_dst_mode'] == 'increment': - vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'inc', step = kwargs['ip_dst_step'], - min_value = ip_dst_addr_num, - max_value = ip_dst_addr_num + ip_dst_count * kwargs['ip_dst_step'])) + vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'inc', step = ip_dst_step, + min_value = ip_dst_addr, + max_value = ip_dst_addr + ip_dst_count * ip_dst_step)) elif kwargs['ip_dst_mode'] == 'decrement': - vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'dec', step = kwargs['ip_dst_step'], - min_value = ip_dst_addr_num - ip_dst_count * kwargs['ip_dst_step'], - max_value = ip_dst_addr_num)) + vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'dec', step = ip_dst_step, + min_value = ip_dst_addr - ip_dst_count * ip_dst_step, + max_value = ip_dst_addr)) elif kwargs['ip_dst_mode'] == 'random': vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff)) else: -- cgit 1.2.3-korg From a88db6885843221757f3cfb4bb3b2e74f57395bb Mon Sep 17 00:00:00 2001 From: imarom Date: Thu, 18 Feb 2016 09:49:26 -0500 Subject: deepcopy for stream per port history --- .../trex_control_plane/stl/trex_stl_lib/trex_stl_port.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py index 838a49ed..29bad041 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py @@ -4,6 +4,7 @@ from collections import namedtuple, OrderedDict import trex_stl_stats from trex_stl_types import * import time +import copy StreamOnPort = namedtuple('StreamOnPort', ['compiled_stream', 'metadata']) @@ -160,8 +161,8 @@ class Port(object): return self.err("Please stop port before attempting to add streams") # listify - streams_list = streams_list if isinstance(streams_list, list) else [streams_list] - + streams_list = copy.deepcopy(streams_list if isinstance(streams_list, list) else [streams_list]) + lookup = {} # allocate IDs @@ -171,10 +172,12 @@ class Port(object): lookup[stream.get_name()] = stream.get_id() - # resolve names + batch = [] + + for stream in streams_list: - next_id = -1 + next_id = -1 next = stream.get_next() if next: if not next in lookup: @@ -183,10 +186,7 @@ class Port(object): stream.set_next_id(next_id) - - - batch = [] - for stream in streams_list: + stream_json = stream.to_json() stream_json['next_stream_id'] = stream.get_next_id() -- cgit 1.2.3-korg From bc7f0b85b85a8deb6bc58bcca32ff11d9289cd92 Mon Sep 17 00:00:00 2001 From: imarom Date: Sun, 21 Feb 2016 08:34:28 -0500 Subject: rate per stream --- .../trex_control_plane/stl/examples/stl_imix.py | 2 +- .../stl/trex_stl_lib/trex_stl_streams.py | 129 +++++++++---- .../stl/trex_stl_lib/trex_stl_types.py | 6 + src/gtest/trex_stateless_gtest.cpp | 96 +++++----- src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 45 +++-- src/rpc-server/commands/trex_rpc_cmds.h | 2 +- src/stateless/cp/trex_stream.cpp | 25 ++- src/stateless/cp/trex_stream.h | 209 ++++++++++++++++++--- src/stateless/cp/trex_streams_compiler.cpp | 36 ++-- src/stateless/cp/trex_streams_compiler.h | 16 +- 10 files changed, 401 insertions(+), 165 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl') diff --git a/scripts/automation/trex_control_plane/stl/examples/stl_imix.py b/scripts/automation/trex_control_plane/stl/examples/stl_imix.py index b9fbbbb6..e3c01ca9 100644 --- a/scripts/automation/trex_control_plane/stl/examples/stl_imix.py +++ b/scripts/automation/trex_control_plane/stl/examples/stl_imix.py @@ -35,7 +35,7 @@ def imix_test (): dir_1 = table['dir'][1] # load IMIX profile - profile = STLProfile.load_py('../../../../stl/profiles/imix.py') + profile = STLProfile.load_py('../../../../stl/imix.py') streams = profile.get_streams() # add both streams to ports diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py index b72b5d35..8a39f96e 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py @@ -1,6 +1,7 @@ #!/router/bin/python from trex_stl_exceptions import * +from trex_stl_types import verify_exclusive_arg, validate_type from trex_stl_packet_builder_interface import CTrexPktBuilderInterface from trex_stl_packet_builder_scapy import CScapyTRexPktBuilder, Ether, IP, UDP, TCP, RawPcapReader from collections import OrderedDict, namedtuple @@ -11,14 +12,51 @@ import yaml import base64 import string import traceback +from types import NoneType + +# handles TX rate for a stream +class STLTXRate(object): + def __init__ (self, pps = None, bps_L1 = None, bps_L2 = None, percentage = None): + + verify_exclusive_arg([pps, bps_L1, bps_L2, percentage]) + + self.fields = {} + + if pps is not None: + validate_type('pps', pps, [float, int]) + + self.fields['type'] = 'pps' + self.fields['value'] = pps + + elif bps_L1 is not None: + validate_type('bps_L1', bps_L1, [float, int]) + + self.fields['type'] = 'bps_L1' + self.fields['value'] = bps_L1 + + elif bps_L2 is not None: + validate_type('bps_L2', bps_L2, [float, int]) + + self.fields['type'] = 'bps_L2' + self.fields['value'] = bps_L2 + + elif percentage is not None: + validate_type('percentage', percentage, [float, int]) + if not (percentage > 0 and percentage <= 100): + raise STLArgumentError('percentage', percentage) + + self.fields['type'] = 'percentage' + self.fields['value'] = percentage + + def to_json (self): + return self.fields -def random_name (l): - return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(l)) # base class for TX mode class STLTXMode(object): def __init__ (self): + self.fields = {} def to_json (self): @@ -28,15 +66,11 @@ class STLTXMode(object): # continuous mode class STLTXCont(STLTXMode): - def __init__ (self, pps = 1): - - if not isinstance(pps, (int, float)): - raise STLArgumentError('pps', pps) + def __init__ (self): super(STLTXCont, self).__init__() self.fields['type'] = 'continuous' - self.fields['pps'] = pps def __str__ (self): return "Continuous" @@ -44,10 +78,7 @@ class STLTXCont(STLTXMode): # single burst mode class STLTXSingleBurst(STLTXMode): - def __init__ (self, pps = 1, total_pkts = 1): - - if not isinstance(pps, (int, float)): - raise STLArgumentError('pps', pps) + def __init__ (self, total_pkts = 1): if not isinstance(total_pkts, int): raise STLArgumentError('total_pkts', total_pkts) @@ -55,7 +86,6 @@ class STLTXSingleBurst(STLTXMode): super(STLTXSingleBurst, self).__init__() self.fields['type'] = 'single_burst' - self.fields['pps'] = pps self.fields['total_pkts'] = total_pkts def __str__ (self): @@ -65,14 +95,10 @@ class STLTXSingleBurst(STLTXMode): class STLTXMultiBurst(STLTXMode): def __init__ (self, - pps = 1, pkts_per_burst = 1, ibg = 0.0, # usec not SEC count = 1): - if not isinstance(pps, (int, float)): - raise STLArgumentError('pps', pps) - if not isinstance(pkts_per_burst, int): raise STLArgumentError('pkts_per_burst', pkts_per_burst) @@ -85,7 +111,6 @@ class STLTXMultiBurst(STLTXMode): super(STLTXMultiBurst, self).__init__() self.fields['type'] = 'multi_burst' - self.fields['pps'] = pps self.fields['pkts_per_burst'] = pkts_per_burst self.fields['ibg'] = ibg self.fields['count'] = count @@ -104,7 +129,8 @@ class STLStream(object): def __init__ (self, name = None, packet = None, - mode = STLTXCont(1), + mode = STLTXCont(), + rate = STLTXRate(pps = 1), enabled = True, self_start = True, isg = 0.0, @@ -117,20 +143,13 @@ class STLStream(object): ): # type checking - if not isinstance(mode, STLTXMode): - raise STLArgumentError('mode', mode) - - if packet and not isinstance(packet, CTrexPktBuilderInterface): - raise STLArgumentError('packet', packet) - - if not isinstance(enabled, bool): - raise STLArgumentError('enabled', enabled) - - if not isinstance(self_start, bool): - raise STLArgumentError('self_start', self_start) - - if not isinstance(isg, (int, float)): - raise STLArgumentError('isg', isg) + validate_type('mode', mode, STLTXMode) + validate_type('rate', rate, STLTXRate) + validate_type('packet', packet, (NoneType, CTrexPktBuilderInterface)) + validate_type('enabled', enabled, bool) + validate_type('self_start', self_start, bool) + validate_type('isg', isg, (int, float)) + validate_type('stream_id', stream_id, (NoneType, int)) if (type(mode) == STLTXCont) and (next != None): raise STLError("continuous stream cannot have a next stream ID") @@ -181,6 +200,10 @@ class STLStream(object): self.fields['mode'] = mode.to_json() self.mode_desc = str(mode) + # rate + self.fields['rate'] = rate.to_json() + + # packet self.fields['packet'] = {} self.fields['vm'] = {} @@ -249,8 +272,6 @@ class STLStream(object): return pkt_len - def get_pps (self): - return self.fields['mode']['pps'] def get_mode (self): return self.mode_desc @@ -316,18 +337,15 @@ class YAMLLoader(object): mode_type = mode_obj.get('type') if mode_type == 'continuous': - defaults = STLTXCont() - mode = STLTXCont(pps = mode_obj.get('pps', defaults.fields['pps'])) + mode = STLTXCont() elif mode_type == 'single_burst': defaults = STLTXSingleBurst() - mode = STLTXSingleBurst(pps = mode_obj.get('pps', defaults.fields['pps']), - total_pkts = mode_obj.get('total_pkts', defaults.fields['total_pkts'])) + mode = STLTXSingleBurst(total_pkts = mode_obj.get('total_pkts', defaults.fields['total_pkts'])) elif mode_type == 'multi_burst': defaults = STLTXMultiBurst() - mode = STLTXMultiBurst(pps = mode_obj.get('pps', defaults.fields['pps']), - pkts_per_burst = mode_obj.get('pkts_per_burst', defaults.fields['pkts_per_burst']), + mode = STLTXMultiBurst(pkts_per_burst = mode_obj.get('pkts_per_burst', defaults.fields['pkts_per_burst']), ibg = mode_obj.get('ibg', defaults.fields['ibg']), count = mode_obj.get('count', defaults.fields['count'])) @@ -338,6 +356,30 @@ class YAMLLoader(object): return mode + def __parse_rate (self, rate_obj): + rate_type = rate_obj.get('type') + if rate_type is None: + raise STLError("'rate' must contain 'type'") + + value = rate_obj.get('value') + if value is None: + raise STLError("'rate' must contain 'value'") + + if rate_type == 'pps': + rate = STLTXRate(pps = value) + elif rate_type == 'bps_L1': + rate = STLTXRate(bps_L1 = value) + elif rate_type == 'bps_L2': + rate = STLTXRate(bps_L2 = value) + elif rate_type == 'percentage': + rate = STLTXRate(percentage = value) + + else: + raise STLError("rate type can be 'pps', 'bps_L1', 'bps_l2' or 'percentage'") + + return rate + + def __parse_stream (self, yaml_object): s_obj = yaml_object['stream'] @@ -356,6 +398,11 @@ class YAMLLoader(object): mode = self.__parse_mode(mode_obj) + rate_obj = s_obj.get('rate') + if not rate_obj: + rate = STLTXRate(pps = 1) + else: + rate = self.__parse_rate(rate_obj) defaults = STLStream() @@ -363,6 +410,7 @@ class YAMLLoader(object): stream = STLStream(name = yaml_object.get('name'), packet = builder, mode = mode, + rate = rate, enabled = s_obj.get('enabled', defaults.fields['enabled']), self_start = s_obj.get('self_start', defaults.fields['self_start']), isg = s_obj.get('isg', defaults.fields['isg']), @@ -536,3 +584,4 @@ class STLProfile(object): def __len__ (self): return len(self.streams) + diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py index aa09b0a1..d4ad8bd2 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py @@ -111,3 +111,9 @@ def validate_type(arg_name, arg, valid_types): raise STLTypeError(arg_name, type(arg), valid_types) else: raise STLError('validate_type: valid_types should be type or list or tuple of types') + +# throws STLError if not exactly one argument is present +def verify_exclusive_arg (args_list): + if not (len(filter(lambda x: x is not None, args_list)) == 1): + raise STLError('exactly one parameter from {0} should be provided'.format(args_list)) + diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp index 3faaedeb..576f7d6e 100644 --- a/src/gtest/trex_stateless_gtest.cpp +++ b/src/gtest/trex_stateless_gtest.cpp @@ -1874,7 +1874,7 @@ TEST_F(basic_stl, basic_pause_resume0) { std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -1937,7 +1937,7 @@ void CBBStartStopDelay2::call_after_init(CBasicStl * m_obj){ std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -1985,7 +1985,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop_delay2) { std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -2063,7 +2063,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop_delay1) { std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -2114,7 +2114,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop3) { std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -2165,7 +2165,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop2) { std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -2218,7 +2218,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop) { std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -2270,7 +2270,7 @@ TEST_F(basic_stl, simple_prog4) { /* stream0 */ TrexStream * stream0 = new TrexStream(TrexStream::stCONTINUOUS, 0,300); - stream0->set_pps(1.0); + stream0->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream0->m_enabled = true; stream0->m_self_start = true; @@ -2283,7 +2283,7 @@ TEST_F(basic_stl, simple_prog4) { /* stream1 */ TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->set_single_burst(5); stream1->m_enabled = true; stream1->m_self_start = true; @@ -2299,7 +2299,7 @@ TEST_F(basic_stl, simple_prog4) { /* stream1 */ TrexStream * stream2 = new TrexStream(TrexStream::stMULTI_BURST, 0,200); - stream2->set_pps(1.0); + stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */ stream2->m_enabled = true; stream2->m_self_start = false; @@ -2351,7 +2351,7 @@ TEST_F(basic_stl, simple_prog3) { /* stream1 */ TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->set_single_burst(5); stream1->m_enabled = true; stream1->m_self_start = true; @@ -2368,7 +2368,7 @@ TEST_F(basic_stl, simple_prog3) { /* stream1 */ TrexStream * stream2 = new TrexStream(TrexStream::stMULTI_BURST, 0,200); - stream2->set_pps(1.0); + stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */ stream2->m_enabled = true; stream2->m_self_start = false; @@ -2418,7 +2418,7 @@ TEST_F(basic_stl, simple_prog2) { /* stream1 */ TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->set_single_burst(5); stream1->m_enabled = true; stream1->m_self_start = true; @@ -2435,7 +2435,7 @@ TEST_F(basic_stl, simple_prog2) { /* stream1 */ TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST, 0,200); - stream2->set_pps(1.0); + stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream2->set_single_burst(5); stream2->m_isg_usec = 2000000; /*time betwean stream 1 to stream 2 */ stream2->m_enabled = true; @@ -2478,7 +2478,7 @@ TEST_F(basic_stl, simple_prog1) { /* stream1 */ TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->set_single_burst(5); stream1->m_enabled = true; stream1->m_self_start = true; @@ -2495,7 +2495,7 @@ TEST_F(basic_stl, simple_prog1) { /* stream1 */ TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST, 0,200); - stream2->set_pps(1.0); + stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream2->set_single_burst(5); stream2->m_enabled = true; stream2->m_self_start = false; @@ -2538,7 +2538,7 @@ TEST_F(basic_stl, single_pkt_burst1) { std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->set_single_burst(5); stream1->m_enabled = true; stream1->m_self_start = true; @@ -2583,7 +2583,7 @@ TEST_F(basic_stl, single_pkt) { std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -2633,7 +2633,7 @@ void test_mac_replace(bool replace_src_by_pkt, stream1->set_override_src_mac_by_pkt_data(replace_src_by_pkt); stream1->set_override_dst_mac_mode((TrexStream::stream_dst_mac_t)replace_dst_mode); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -2707,7 +2707,7 @@ TEST_F(basic_stl, multi_pkt1) { std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -2721,7 +2721,7 @@ TEST_F(basic_stl, multi_pkt1) { streams.push_back(stream1); TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,1); - stream2->set_pps(2.0); + stream2->set_rate(TrexStreamRate::RATE_PPS,2.0); stream2->m_enabled = true; stream2->m_self_start = true; @@ -2773,7 +2773,7 @@ void CEnableVm::run(bool full_packet,double duration=10.0){ TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; stream1->m_self_start = true; @@ -2862,7 +2862,7 @@ TEST_F(basic_stl, multi_pkt2) { TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -2877,7 +2877,7 @@ TEST_F(basic_stl, multi_pkt2) { TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,1); - stream2->set_pps(2.0); + stream2->set_rate(TrexStreamRate::RATE_PPS,2.0); stream2->m_enabled = false; stream2->m_self_start = false; @@ -2919,7 +2919,7 @@ TEST_F(basic_stl, multi_burst1) { std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stMULTI_BURST,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->set_multi_burst(5, 3, 2000000.0); @@ -2962,7 +2962,7 @@ TEST_F(basic_stl, compile_bad_1) { TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,2); stream1->m_enabled = true; - stream1->set_pps(52.0); + stream1->set_rate(TrexStreamRate::RATE_PPS,52.0); stream1->m_next_stream_id = 3; streams.push_back(stream1); @@ -2987,14 +2987,14 @@ TEST_F(basic_stl, compile_bad_2) { TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,1); stream1->m_enabled = true; - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->set_single_burst(200); /* non existant next stream */ stream1->m_next_stream_id = 5; TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,2); - stream1->set_pps(52.0); + stream1->set_rate(TrexStreamRate::RATE_PPS,52.0); streams.push_back(stream1); streams.push_back(stream2); @@ -3026,7 +3026,7 @@ TEST_F(basic_stl, compile_bad_3) { /* stream 1 */ stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 231); stream->m_enabled = true; - stream->set_pps(1.0); + stream->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream->set_single_burst(200); stream->m_next_stream_id = 5481; @@ -3039,7 +3039,7 @@ TEST_F(basic_stl, compile_bad_3) { stream->m_enabled = true; stream->m_next_stream_id = -1; stream->m_self_start = false; - stream->set_pps(52.0); + stream->set_rate(TrexStreamRate::RATE_PPS,52.0); streams.push_back(stream); @@ -3047,7 +3047,7 @@ TEST_F(basic_stl, compile_bad_3) { stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1928); stream->m_enabled = true; - stream->set_pps(1.0); + stream->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream->set_single_burst(200); stream->m_next_stream_id = -1; @@ -3059,7 +3059,7 @@ TEST_F(basic_stl, compile_bad_3) { stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 41231); stream->m_enabled = true; - stream->set_pps(1.0); + stream->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream->set_single_burst(200); stream->m_next_stream_id = 3928; @@ -3071,7 +3071,7 @@ TEST_F(basic_stl, compile_bad_3) { stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 3928); stream->m_enabled = true; - stream->set_pps(1.0); + stream->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream->set_single_burst(200); stream->m_next_stream_id = 41231; @@ -3100,7 +3100,7 @@ TEST_F(basic_stl, compile_with_warnings) { /* stream 1 */ stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 231); stream->m_enabled = true; - stream->set_pps(1.0); + stream->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream->set_single_burst(200); stream->m_next_stream_id = 1928; @@ -3113,7 +3113,7 @@ TEST_F(basic_stl, compile_with_warnings) { stream->m_enabled = true; stream->m_next_stream_id = 1928; stream->m_self_start = true; - stream->set_pps(52.0); + stream->set_rate(TrexStreamRate::RATE_PPS,52.0); streams.push_back(stream); @@ -3121,7 +3121,7 @@ TEST_F(basic_stl, compile_with_warnings) { stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1928); stream->m_enabled = true; - stream->set_pps(1.0); + stream->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream->set_single_burst(200); stream->m_next_stream_id = -1; @@ -3154,7 +3154,7 @@ TEST_F(basic_stl, compile_good_stream_id_compres) { TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,700); stream1->m_self_start = true; stream1->m_enabled = true; - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->set_single_burst(200); /* non existant next stream */ @@ -3162,7 +3162,7 @@ TEST_F(basic_stl, compile_good_stream_id_compres) { TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST,0,800); - stream2->set_pps(52.0); + stream2->set_rate(TrexStreamRate::RATE_PPS,52.0); stream2->m_enabled = true; stream2->m_next_stream_id = 700; stream2->set_single_burst(300); @@ -3231,7 +3231,7 @@ TEST_F(basic_stl, dp_stop_event) { std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,0); - stream1->set_pps(1.0); + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->set_single_burst(100); stream1->m_enabled = true; @@ -3277,7 +3277,7 @@ TEST_F(basic_stl, graph_generator1) { stream->m_self_start = true; stream->m_isg_usec = 42; - stream->set_pps(10); + stream->set_rate(TrexStreamRate::RATE_PPS,10); stream->set_single_burst(43281); stream->m_pkt.len = 512; @@ -3291,7 +3291,7 @@ TEST_F(basic_stl, graph_generator1) { stream->m_enabled = true; stream->m_self_start = false; - stream->set_pps(20); + stream->set_rate(TrexStreamRate::RATE_PPS,20); stream->set_multi_burst(4918, 13, 7); stream->m_next_stream_id = -1; stream->m_pkt.len = 64; @@ -3304,7 +3304,7 @@ TEST_F(basic_stl, graph_generator1) { stream->m_self_start = true; stream->m_isg_usec = 50; - stream->set_pps(30); + stream->set_rate(TrexStreamRate::RATE_PPS,30); stream->m_next_stream_id = -1; stream->m_pkt.len = 1512; @@ -3334,7 +3334,7 @@ TEST_F(basic_stl, graph_generator2) { stream->m_self_start = true; - stream->set_pps(1000); + stream->set_rate(TrexStreamRate::RATE_PPS,1000); /* a burst of 2000 packets with a delay of 1 second */ stream->m_isg_usec = 0; @@ -3352,7 +3352,7 @@ TEST_F(basic_stl, graph_generator2) { stream->m_enabled = true; stream->m_self_start = true; - stream->set_pps(1000); + stream->set_rate(TrexStreamRate::RATE_PPS,1000); stream->m_isg_usec = 1000 * 1000 + 1000; stream->set_multi_burst(1000 - 2, 1000, 1000 * 1000 + 2000); stream->m_pkt.len = 128; @@ -3517,7 +3517,7 @@ TEST_F(basic_stl, vm_split_flow_var_inc) { TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0); stream.set_single_burst(1000); - stream.set_pps(100000); + stream.set_rate(TrexStreamRate::RATE_PPS,100000); split.set_stream(&stream); split.run(8, 4); @@ -3530,7 +3530,7 @@ TEST_F(basic_stl, vm_split_flow_var_small_range) { TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0); stream.set_single_burst(1000); - stream.set_pps(100000); + stream.set_rate(TrexStreamRate::RATE_PPS,100000); split.set_stream(&stream); split.set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_INC, 0, 1, 0); @@ -3544,7 +3544,7 @@ TEST_F(basic_stl, vm_split_flow_var_big_range) { TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0); stream.set_single_burst(1000); - stream.set_pps(100000); + stream.set_rate(TrexStreamRate::RATE_PPS,100000); split.set_stream(&stream); split.set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC, 1, 1000, 1000); @@ -3559,7 +3559,7 @@ TEST_F(basic_stl, vm_split_client_var) { TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0); stream.set_single_burst(1000); - stream.set_pps(100000); + stream.set_rate(TrexStreamRate::RATE_PPS,100000); split.set_stream(&stream); split.set_client_var_as_split(0x10000001, 0x100000fe, 5000, 5050); diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index 920991e2..bcfa7df1 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -60,6 +60,10 @@ TrexRpcCmdAddStream::_run(const Json::Value ¶ms, Json::Value &result) { stream->m_flags = parse_int(section, "flags", result); stream->m_action_count = parse_uint16(section, "action_count", result); + /* parse the rate of the stream */ + const Json::Value &rate = parse_object(section ,"rate", result); + parse_rate(rate, stream.get(), result); + /* inter stream gap */ stream->m_isg_usec = parse_double(section, "isg", result); @@ -138,35 +142,26 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value §ion, uint8_t por const Json::Value &mode = parse_object(section, "mode", result); std::string type = parse_string(mode, "type", result); + if (type == "continuous") { - double pps = parse_double(mode, "pps", result); stream = new TrexStream( TrexStream::stCONTINUOUS, port_id, stream_id); - stream->set_pps(pps); - - if (stream->m_next_stream_id != -1) { - generate_parse_err(result, "continious stream cannot provide next stream id - only -1 is valid"); - } } else if (type == "single_burst") { uint32_t total_pkts = parse_int(mode, "total_pkts", result); - double pps = parse_double(mode, "pps", result); - stream = new TrexStream(TrexStream::stSINGLE_BURST,port_id, stream_id); - stream->set_pps(pps); + stream = new TrexStream(TrexStream::stSINGLE_BURST, port_id, stream_id); stream->set_single_burst(total_pkts); } else if (type == "multi_burst") { - double pps = parse_double(mode, "pps", result); double ibg_usec = parse_double(mode, "ibg", result); uint32_t num_bursts = parse_int(mode, "count", result); uint32_t pkts_per_burst = parse_int(mode, "pkts_per_burst", result); stream = new TrexStream(TrexStream::stMULTI_BURST,port_id, stream_id ); - stream->set_pps(pps); stream->set_multi_burst(pkts_per_burst,num_bursts,ibg_usec); @@ -174,15 +169,33 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value §ion, uint8_t por generate_parse_err(result, "bad stream type provided: '" + type + "'"); } - /* make sure we were able to allocate the memory */ - if (!stream) { - generate_internal_err(result, "unable to allocate memory"); - } - return (stream); } +void +TrexRpcCmdAddStream::parse_rate(const Json::Value &rate, TrexStream *stream, Json::Value &result) { + + double value = parse_double(rate, "value", result); + + auto rate_types = {"pps", "bps_L1", "bps_L2", "percentage"}; + std::string rate_type = parse_choice(rate, "type", rate_types, result); + + if (rate_type == "pps") { + stream->set_rate(TrexStreamRate::RATE_PPS, value); + } else if (rate_type == "bps_L1") { + stream->set_rate(TrexStreamRate::RATE_BPS_L1, value); + } else if (rate_type == "bps_L2") { + stream->set_rate(TrexStreamRate::RATE_BPS_L2, value); + } else if (rate_type == "percentage") { + stream->set_rate(TrexStreamRate::RATE_PERCENTAGE, value); + } else { + /* impossible */ + assert(0); + } + +} + void TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, TrexStream *stream, Json::Value &result) { diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h index 3dc2ce0a..3da1e4fa 100644 --- a/src/rpc-server/commands/trex_rpc_cmds.h +++ b/src/rpc-server/commands/trex_rpc_cmds.h @@ -98,7 +98,7 @@ void parse_vm_instr_checksum(const Json::Value &inst, TrexStream *stream, Json:: void parse_vm_instr_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result); void parse_vm_instr_tuple_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result); void parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexStream *stream, Json::Value &result); - +void parse_rate(const Json::Value &inst, TrexStream *stream, Json::Value &result); void parse_vm_instr_write_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result); void parse_vm_instr_write_mask_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result); diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp index fb0b35d5..f4a8e800 100644 --- a/src/stateless/cp/trex_stream.cpp +++ b/src/stateless/cp/trex_stream.cpp @@ -22,6 +22,7 @@ limitations under the License. #include #include #include +#include /************************************** * stream @@ -91,20 +92,25 @@ void TrexStream::Dump(FILE *fd){ fprintf(fd," type : %s \n",get_stream_type_str(m_type).c_str()); if ( m_type == TrexStream::stCONTINUOUS ) { - fprintf(fd," pps : %f \n",m_pps); } if (m_type == TrexStream::stSINGLE_BURST) { - fprintf(fd," pps : %f \n",m_pps); fprintf(fd," burst : %lu \n",(ulong)m_burst_total_pkts); } if (m_type == TrexStream::stMULTI_BURST) { - fprintf(fd," pps : %f \n",m_pps); fprintf(fd," burst : %lu \n",(ulong)m_burst_total_pkts); fprintf(fd," mburst : %lu \n",(ulong)m_num_bursts); if (m_ibg_usec>0.0) { fprintf(fd," m_ibg_usec : %f \n",m_ibg_usec); } } + + fprintf(fd," rate :\n\n"); + + fprintf(fd," pps : %f\n", get_rate().get_pps()); + fprintf(fd," bps L1 : %f\n", get_rate().get_bps_L1()); + fprintf(fd," bps L2 : %f\n", get_rate().get_bps_L2()); + fprintf(fd," percentage : %f\n", get_rate().get_percentage()); + } @@ -125,7 +131,6 @@ TrexStream::TrexStream(uint8_t type, m_rx_check.m_enable = false; - m_pps=-1.0; m_burst_total_pkts=0; m_num_bursts=1; m_ibg_usec=0.0; @@ -155,6 +160,18 @@ TrexStream::get_stream_json() { return m_stream_json; } +TrexStreamRate & +TrexStream::get_rate() { + + /* lazy calculation of the rate */ + if (!m_rate.is_calculated()) { + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(m_port_id); + double pkt_size = get_pkt_size(); + m_rate.calculate(pkt_size, port->get_port_speed_bps()); + } + + return m_rate; +} /************************************** * stream table diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h index 2ab90c99..f4739569 100644 --- a/src/stateless/cp/trex_stream.h +++ b/src/stateless/cp/trex_stream.h @@ -103,6 +103,151 @@ public: } }; +/** + * describes a stream rate + * + * @author imarom (18-Feb-16) + */ +class TrexStreamRate { + + +public: + + enum rate_type_e { + RATE_INVALID, + RATE_PPS, + RATE_BPS_L1, + RATE_BPS_L2, + RATE_PERCENTAGE + }; + + TrexStreamRate() { + m_base_rate_type = RATE_INVALID; + m_is_calculated = false; + } + + /** + * set the base rate + * other values will be dervied from this value + * + */ + void set_base_rate(rate_type_e type, double value) { + m_base_rate_type = type; + m_value = value; + m_is_calculated = false; + } + + + /** + * calculates all the rates from the base rate + * + */ + void calculate(uint16_t pkt_size, uint64_t line_bps) { + + switch (m_base_rate_type) { + + case RATE_PPS: + calculate_from_pps(m_value, pkt_size, line_bps); + break; + + case RATE_BPS_L1: + calculate_from_bps_L1(m_value, pkt_size, line_bps); + break; + + case RATE_BPS_L2: + calculate_from_bps_L2(m_value, pkt_size, line_bps); + break; + + case RATE_PERCENTAGE: + calculate_from_percentage(m_value, pkt_size, line_bps); + break; + + default: + assert(0); + } + + m_is_calculated = true; + } + + + bool is_calculated() const { + return m_is_calculated; + } + + + /* update the rate by a factor */ + void update_factor(double factor) { + assert(m_is_calculated); + + m_pps *= factor; + m_bps_L1 *= factor; + m_bps_L2 *= factor; + m_percentage *= factor; + } + + double get_pps() { + assert(m_is_calculated); + return (m_pps); + } + + double get_bps_L1() { + assert(m_is_calculated); + return (m_bps_L1); + } + + double get_bps_L2() { + assert(m_is_calculated); + return m_bps_L2; + } + + double get_percentage() { + assert(m_is_calculated); + return m_percentage; + } + +private: + + void calculate_from_pps(double pps, uint16_t pkt_size, uint64_t line_bps) { + m_pps = pps; + m_bps_L1 = m_pps * (pkt_size + 24) * 8; + m_bps_L2 = m_pps * (pkt_size + 4) * 8; + m_percentage = (m_bps_L1 / line_bps) * 100.0; + } + + + void calculate_from_bps_L1(double bps_L1, uint16_t pkt_size, uint64_t line_bps) { + m_bps_L1 = bps_L1; + m_bps_L2 = m_bps_L1 * ( (pkt_size + 4.0) / (pkt_size + 24.0) ); + m_pps = m_bps_L2 / (8 * (pkt_size + 4)); + m_percentage = (m_bps_L1 / line_bps) * 100.0; + } + + + void calculate_from_bps_L2(double bps_L2, uint16_t pkt_size, uint64_t line_bps) { + m_bps_L2 = bps_L2; + m_bps_L1 = m_bps_L2 * ( (pkt_size + 24.0) / (pkt_size + 4.0)); + m_pps = m_bps_L2 / (8 * (pkt_size + 4)); + m_percentage = (m_bps_L1 / line_bps) * 100.0; + } + + void calculate_from_percentage(double percentage, uint16_t pkt_size, uint64_t line_bps) { + m_percentage = percentage; + m_bps_L1 = (m_percentage / 100.0) * line_bps; + m_bps_L2 = m_bps_L1 * ( (pkt_size + 4.0) / (pkt_size + 24.0) ); + m_pps = m_bps_L2 / (8 * (pkt_size + 4)); + + } + + rate_type_e m_base_rate_type; + double m_value; + + bool m_is_calculated; + double m_pps; + double m_bps_L1; + double m_bps_L2; + double m_percentage; + +}; /** * Stateless Stream @@ -151,12 +296,29 @@ public: m_next_stream_id = next_stream_id; } - double get_pps() const { - return m_pps; + + double get_pps() { + return get_rate().get_pps(); + } + + double get_bps_L1() { + return get_rate().get_bps_L1(); + } + + double get_bps_L2() { + return get_rate().get_bps_L2(); + } + + double get_bw_percentage() { + return get_rate().get_percentage(); + } + + void set_rate(TrexStreamRate::rate_type_e type, double value) { + m_rate.set_base_rate(type, value); } - void set_pps(double pps){ - m_pps = pps; + void update_rate_factor(double factor) { + get_rate().update_factor(factor); } void set_type(uint8_t type){ @@ -223,13 +385,14 @@ public: dp->m_expected_pkt_len = m_expected_pkt_len; dp->m_rx_check = m_rx_check; - dp->m_pps = m_pps; dp->m_burst_total_pkts = m_burst_total_pkts; dp->m_num_bursts = m_num_bursts; dp->m_ibg_usec = m_ibg_usec; dp->m_flags = m_flags; dp->m_action_count = m_action_count; + dp->m_rate = m_rate; + return(dp); } @@ -241,19 +404,11 @@ public: } } - double get_burst_length_usec() const { - return ( (m_burst_total_pkts / m_pps) * 1000 * 1000); - } - - double get_bps_l2() { - return get_bps(false); - } - - double get_bps_l1() { - return get_bps(true); + double get_burst_length_usec() { + return ( (m_burst_total_pkts / get_pps()) * 1000 * 1000); } - + void Dump(FILE *fd); StreamVmDp * getDpVm(){ @@ -321,8 +476,6 @@ public: } m_rx_check; - double m_pps; - uint32_t m_burst_total_pkts; /* valid in case of burst stSINGLE_BURST,stMULTI_BURST*/ uint32_t m_num_bursts; /* valid in case of stMULTI_BURST */ @@ -334,8 +487,7 @@ public: private: - double get_bps(bool layer1) { - + double get_pkt_size() { /* lazy calculate the expected packet length */ if (m_expected_pkt_len == 0) { /* if we have a VM - it might have changed the packet (even random) */ @@ -345,17 +497,16 @@ private: m_expected_pkt_len = m_vm.calc_expected_pkt_size(m_pkt.len); } } - - /* packet length + 4 CRC bytes to bits and multiplied by PPS */ - - if (layer1) { - /* layer one includes preamble, frame delimiter and interpacket gap */ - return (m_pps * (m_expected_pkt_len + 4 + 8 + 12) * 8); - } else { - return (m_pps * (m_expected_pkt_len + 4) * 8); - } + return m_expected_pkt_len; } + + + /* get (and calculate if need) the rate of the stream */ + TrexStreamRate & get_rate(); + + /* no access to this without a lazy build method */ + TrexStreamRate m_rate; }; diff --git a/src/stateless/cp/trex_streams_compiler.cpp b/src/stateless/cp/trex_streams_compiler.cpp index 9d048dbd..aca74498 100644 --- a/src/stateless/cp/trex_streams_compiler.cpp +++ b/src/stateless/cp/trex_streams_compiler.cpp @@ -459,7 +459,7 @@ TrexStreamsCompiler::compile_internal(uint8_t por * */ void -TrexStreamsCompiler::compile_stream(const TrexStream *stream, +TrexStreamsCompiler::compile_stream(TrexStream *stream, double factor, uint8_t dp_core_count, std::vector &objs, @@ -500,7 +500,7 @@ TrexStreamsCompiler::compile_stream(const TrexStream *stream, * */ void -TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream, +TrexStreamsCompiler::compile_stream_on_all_cores(TrexStream *stream, double factor, uint8_t dp_core_count, std::vector &objs, @@ -509,7 +509,7 @@ TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream, std::vector core_streams(dp_core_count); - double per_core_rate = (stream->m_pps * (factor / dp_core_count)); + double per_core_factor = (factor / dp_core_count); int per_core_burst_total_pkts = (stream->m_burst_total_pkts / dp_core_count); /* for each core - creates its own version of the stream */ @@ -521,7 +521,7 @@ TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream, /* adjust rate and packets count */ - dp_stream->m_pps = per_core_rate; + dp_stream->update_rate_factor(per_core_factor); dp_stream->m_burst_total_pkts = per_core_burst_total_pkts; core_streams[i] = dp_stream; @@ -547,7 +547,7 @@ TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream, * */ void -TrexStreamsCompiler::compile_stream_on_single_core(const TrexStream *stream, +TrexStreamsCompiler::compile_stream_on_single_core(TrexStream *stream, double factor, TrexStreamsCompiledObj *obj, int new_id, @@ -560,7 +560,7 @@ TrexStreamsCompiler::compile_stream_on_single_core(const TrexStream *stream, /* compile the VM if exists */ if (!stream->m_vm.is_vm_empty()) { - ((TrexStream *)stream)->vm_compile(); + stream->vm_compile(); dp_stream->m_vm_dp = stream->m_vm_dp->clone(); } @@ -581,7 +581,7 @@ TrexStreamsCompiler::compile_stream_on_single_core(const TrexStream *stream, * @param stream */ void -TrexStreamsGraph::add_rate_events_for_stream(double &offset_usec, const TrexStream *stream) { +TrexStreamsGraph::add_rate_events_for_stream(double &offset_usec, TrexStream *stream) { switch (stream->get_type()) { @@ -604,7 +604,7 @@ TrexStreamsGraph::add_rate_events_for_stream(double &offset_usec, const TrexStre * */ void -TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, const TrexStream *stream) { +TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, TrexStream *stream) { TrexStreamsGraphObj::rate_event_st start_event; @@ -613,8 +613,8 @@ TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, const Tre start_event.time = offset_usec + stream->m_isg_usec; start_event.diff_pps = stream->get_pps(); - start_event.diff_bps_l2 = ((TrexStream *)stream)->get_bps_l2(); - start_event.diff_bps_l1 = ((TrexStream *)stream)->get_bps_l1(); + start_event.diff_bps_l2 = stream->get_bps_L2(); + start_event.diff_bps_l1 = stream->get_bps_L1(); m_graph_obj->add_rate_event(start_event); /* no more events after this stream */ @@ -629,7 +629,7 @@ TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, const Tre * */ void -TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, const TrexStream *stream) { +TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, TrexStream *stream) { TrexStreamsGraphObj::rate_event_st start_event; TrexStreamsGraphObj::rate_event_st stop_event; @@ -640,9 +640,9 @@ TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, c /* start event */ start_event.time = offset_usec + stream->m_isg_usec; - start_event.diff_pps = stream->get_pps(); - start_event.diff_bps_l2 = ((TrexStream *)stream)->get_bps_l2(); - start_event.diff_bps_l1 = ((TrexStream *)stream)->get_bps_l1(); + start_event.diff_pps = stream->get_pps(); + start_event.diff_bps_l2 = stream->get_bps_L2(); + start_event.diff_bps_l1 = stream->get_bps_L1(); m_graph_obj->add_rate_event(start_event); /* stop event */ @@ -662,7 +662,7 @@ TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, c * */ void -TrexStreamsGraph::add_rate_events_for_stream_multi_burst(double &offset_usec, const TrexStream *stream) { +TrexStreamsGraph::add_rate_events_for_stream_multi_burst(double &offset_usec, TrexStream *stream) { TrexStreamsGraphObj::rate_event_st start_event; TrexStreamsGraphObj::rate_event_st stop_event; @@ -672,8 +672,8 @@ TrexStreamsGraph::add_rate_events_for_stream_multi_burst(double &offset_usec, co /* for debug purposes */ start_event.diff_pps = stream->get_pps(); - start_event.diff_bps_l2 = ((TrexStream *)stream)->get_bps_l2(); - start_event.diff_bps_l1 = ((TrexStream *)stream)->get_bps_l1(); + start_event.diff_bps_l2 = stream->get_bps_L2(); + start_event.diff_bps_l1 = stream->get_bps_L1(); start_event.stream_id = stream->m_stream_id; stop_event.diff_pps = -(start_event.diff_pps); @@ -714,7 +714,7 @@ TrexStreamsGraph::generate_graph_for_one_root(uint32_t root_stream_id) { double offset = 0; while (true) { - const TrexStream *stream; + TrexStream *stream; /* fetch the stream from the hash - if it is not present, report an error */ try { diff --git a/src/stateless/cp/trex_streams_compiler.h b/src/stateless/cp/trex_streams_compiler.h index a3a1f8f7..b8b0be37 100644 --- a/src/stateless/cp/trex_streams_compiler.h +++ b/src/stateless/cp/trex_streams_compiler.h @@ -123,19 +123,19 @@ private: void add_warning(const std::string &warning); void err(const std::string &err); - void compile_stream(const TrexStream *stream, + void compile_stream(TrexStream *stream, double factor, uint8_t dp_core_count, std::vector &objs, GraphNodeMap &nodes); - void compile_stream_on_single_core(const TrexStream *stream, + void compile_stream_on_single_core(TrexStream *stream, double factor, TrexStreamsCompiledObj *obj, int new_id, int new_next_id); - void compile_stream_on_all_cores(const TrexStream *stream, + void compile_stream_on_all_cores(TrexStream *stream, double factor, uint8_t dp_core_count, std::vector &objs, @@ -245,13 +245,13 @@ private: void generate_graph_for_one_root(uint32_t root_stream_id); - void add_rate_events_for_stream(double &offset, const TrexStream *stream); - void add_rate_events_for_stream_cont(double &offset_usec, const TrexStream *stream); - void add_rate_events_for_stream_single_burst(double &offset_usec, const TrexStream *stream); - void add_rate_events_for_stream_multi_burst(double &offset_usec, const TrexStream *stream); + void add_rate_events_for_stream(double &offset, TrexStream *stream); + void add_rate_events_for_stream_cont(double &offset_usec, TrexStream *stream); + void add_rate_events_for_stream_single_burst(double &offset_usec, TrexStream *stream); + void add_rate_events_for_stream_multi_burst(double &offset_usec, TrexStream *stream); /* for fast processing of streams */ - std::unordered_map m_streams_hash; + std::unordered_map m_streams_hash; /* main object to hold the graph - returned to the user */ TrexStreamsGraphObj *m_graph_obj; -- cgit 1.2.3-korg From d1360da9fbdda884f43400b98c022bbfccf523f4 Mon Sep 17 00:00:00 2001 From: imarom Date: Sun, 21 Feb 2016 11:42:00 -0500 Subject: rate is now backward compatiable to API --- .../stl/trex_stl_lib/trex_stl_streams.py | 111 +++++++++------------ src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 9 +- 2 files changed, 52 insertions(+), 68 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py index 8a39f96e..e890bac6 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py @@ -14,50 +14,46 @@ import string import traceback from types import NoneType -# handles TX rate for a stream -class STLTXRate(object): +# base class for TX mode +class STLTXMode(object): def __init__ (self, pps = None, bps_L1 = None, bps_L2 = None, percentage = None): + args = [pps, bps_L1, bps_L2, percentage] - verify_exclusive_arg([pps, bps_L1, bps_L2, percentage]) + # default + if all([x is None for x in args]): + pps = 1.0 + else: + verify_exclusive_arg(args) - self.fields = {} + self.fields = {'rate': {}} if pps is not None: validate_type('pps', pps, [float, int]) - self.fields['type'] = 'pps' - self.fields['value'] = pps + self.fields['rate']['type'] = 'pps' + self.fields['rate']['value'] = pps elif bps_L1 is not None: validate_type('bps_L1', bps_L1, [float, int]) - self.fields['type'] = 'bps_L1' - self.fields['value'] = bps_L1 + self.fields['rate']['type'] = 'bps_L1' + self.fields['rate']['value'] = bps_L1 elif bps_L2 is not None: validate_type('bps_L2', bps_L2, [float, int]) - self.fields['type'] = 'bps_L2' - self.fields['value'] = bps_L2 + self.fields['rate']['type'] = 'bps_L2' + self.fields['rate']['value'] = bps_L2 elif percentage is not None: validate_type('percentage', percentage, [float, int]) if not (percentage > 0 and percentage <= 100): raise STLArgumentError('percentage', percentage) - self.fields['type'] = 'percentage' - self.fields['value'] = percentage - - def to_json (self): - return self.fields - - - -# base class for TX mode -class STLTXMode(object): - def __init__ (self): + self.fields['rate']['type'] = 'percentage' + self.fields['rate']['value'] = percentage - self.fields = {} + def to_json (self): return self.fields @@ -66,9 +62,9 @@ class STLTXMode(object): # continuous mode class STLTXCont(STLTXMode): - def __init__ (self): + def __init__ (self, pps = None, bps_L1 = None, bps_L2 = None, percentage = None): - super(STLTXCont, self).__init__() + super(STLTXCont, self).__init__(pps, bps_L1, bps_L2, percentage) self.fields['type'] = 'continuous' @@ -78,12 +74,12 @@ class STLTXCont(STLTXMode): # single burst mode class STLTXSingleBurst(STLTXMode): - def __init__ (self, total_pkts = 1): + def __init__ (self, total_pkts = 1, pps = None, bps_L1 = None, bps_L2 = None, percentage = None): if not isinstance(total_pkts, int): raise STLArgumentError('total_pkts', total_pkts) - super(STLTXSingleBurst, self).__init__() + super(STLTXSingleBurst, self).__init__(pps, bps_L1, bps_L2, percentage) self.fields['type'] = 'single_burst' self.fields['total_pkts'] = total_pkts @@ -97,7 +93,11 @@ class STLTXMultiBurst(STLTXMode): def __init__ (self, pkts_per_burst = 1, ibg = 0.0, # usec not SEC - count = 1): + count = 1, + pps = None, + bps_L1 = None, + bps_L2 = None, + percentage = None): if not isinstance(pkts_per_burst, int): raise STLArgumentError('pkts_per_burst', pkts_per_burst) @@ -108,7 +108,7 @@ class STLTXMultiBurst(STLTXMode): if not isinstance(count, int): raise STLArgumentError('count', count) - super(STLTXMultiBurst, self).__init__() + super(STLTXMultiBurst, self).__init__(pps, bps_L1, bps_L2, percentage) self.fields['type'] = 'multi_burst' self.fields['pkts_per_burst'] = pkts_per_burst @@ -129,8 +129,7 @@ class STLStream(object): def __init__ (self, name = None, packet = None, - mode = STLTXCont(), - rate = STLTXRate(pps = 1), + mode = STLTXCont(pps = 1), enabled = True, self_start = True, isg = 0.0, @@ -144,7 +143,6 @@ class STLStream(object): # type checking validate_type('mode', mode, STLTXMode) - validate_type('rate', rate, STLTXRate) validate_type('packet', packet, (NoneType, CTrexPktBuilderInterface)) validate_type('enabled', enabled, bool) validate_type('self_start', self_start, bool) @@ -200,8 +198,6 @@ class STLStream(object): self.fields['mode'] = mode.to_json() self.mode_desc = str(mode) - # rate - self.fields['rate'] = rate.to_json() # packet self.fields['packet'] = {} @@ -287,6 +283,12 @@ class STLStream(object): y['next'] = self.next y['stream'] = self.fields + + # some shortcuts for YAML + rate_type = self.fields['mode']['rate']['type'] + rate_value = self.fields['mode']['rate']['value'] + y['stream']['mode'][rate_type] = rate_value + del y['stream']['mode']['rate'] return y @@ -334,20 +336,29 @@ class YAMLLoader(object): def __parse_mode (self, mode_obj): + rate_parser = set(mode_obj).intersection(['pps', 'bps_L1', 'bps_L2', 'percentage']) + if len(rate_parser) != 1: + raise STLError("'rate' must contain exactly one from 'pps', 'bps_L1', 'bps_L2', 'percentage'") + + rate_type = rate_parser.pop() + rate = {rate_type : mode_obj[rate_type]} + mode_type = mode_obj.get('type') if mode_type == 'continuous': - mode = STLTXCont() + mode = STLTXCont(**rate) elif mode_type == 'single_burst': defaults = STLTXSingleBurst() - mode = STLTXSingleBurst(total_pkts = mode_obj.get('total_pkts', defaults.fields['total_pkts'])) + mode = STLTXSingleBurst(total_pkts = mode_obj.get('total_pkts', defaults.fields['total_pkts']), + **rate) elif mode_type == 'multi_burst': defaults = STLTXMultiBurst() mode = STLTXMultiBurst(pkts_per_burst = mode_obj.get('pkts_per_burst', defaults.fields['pkts_per_burst']), ibg = mode_obj.get('ibg', defaults.fields['ibg']), - count = mode_obj.get('count', defaults.fields['count'])) + count = mode_obj.get('count', defaults.fields['count']), + **rate) else: raise STLError("mode type can be 'continuous', 'single_burst' or 'multi_burst") @@ -356,28 +367,6 @@ class YAMLLoader(object): return mode - def __parse_rate (self, rate_obj): - rate_type = rate_obj.get('type') - if rate_type is None: - raise STLError("'rate' must contain 'type'") - - value = rate_obj.get('value') - if value is None: - raise STLError("'rate' must contain 'value'") - - if rate_type == 'pps': - rate = STLTXRate(pps = value) - elif rate_type == 'bps_L1': - rate = STLTXRate(bps_L1 = value) - elif rate_type == 'bps_L2': - rate = STLTXRate(bps_L2 = value) - elif rate_type == 'percentage': - rate = STLTXRate(percentage = value) - - else: - raise STLError("rate type can be 'pps', 'bps_L1', 'bps_l2' or 'percentage'") - - return rate def __parse_stream (self, yaml_object): @@ -398,11 +387,6 @@ class YAMLLoader(object): mode = self.__parse_mode(mode_obj) - rate_obj = s_obj.get('rate') - if not rate_obj: - rate = STLTXRate(pps = 1) - else: - rate = self.__parse_rate(rate_obj) defaults = STLStream() @@ -410,7 +394,6 @@ class YAMLLoader(object): stream = STLStream(name = yaml_object.get('name'), packet = builder, mode = mode, - rate = rate, enabled = s_obj.get('enabled', defaults.fields['enabled']), self_start = s_obj.get('self_start', defaults.fields['self_start']), isg = s_obj.get('isg', defaults.fields['isg']), diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index bcfa7df1..74985883 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -59,10 +59,7 @@ TrexRpcCmdAddStream::_run(const Json::Value ¶ms, Json::Value &result) { stream->m_self_start = parse_bool(section, "self_start", result); stream->m_flags = parse_int(section, "flags", result); stream->m_action_count = parse_uint16(section, "action_count", result); - - /* parse the rate of the stream */ - const Json::Value &rate = parse_object(section ,"rate", result); - parse_rate(rate, stream.get(), result); + /* inter stream gap */ stream->m_isg_usec = parse_double(section, "isg", result); @@ -169,6 +166,10 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value §ion, uint8_t por generate_parse_err(result, "bad stream type provided: '" + type + "'"); } + /* parse the rate of the stream */ + const Json::Value &rate = parse_object(mode ,"rate", result); + parse_rate(rate, stream, result); + return (stream); } -- cgit 1.2.3-korg From eb899885b5e4c551550275e8aa46061aefd6b37e Mon Sep 17 00:00:00 2001 From: imarom Date: Mon, 22 Feb 2016 11:25:48 -0500 Subject: some mods to the rate --- .../trex_control_plane/stl/console/trex_console.py | 2 +- .../stl/trex_stl_lib/trex_stl_stats.py | 63 +++++++- src/bp_sim.cpp | 5 +- src/main.cpp | 9 ++ src/msg_manager.cpp | 15 +- src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 40 ++--- src/rpc-server/commands/trex_rpc_cmds.h | 21 +-- src/sim/trex_sim.h | 61 +++++++- src/sim/trex_sim_stateless.cpp | 69 ++------ src/stateless/cp/trex_stateless_port.cpp | 12 +- src/stateless/cp/trex_stateless_port.h | 7 +- src/stateless/cp/trex_stream.cpp | 35 +++-- src/stateless/cp/trex_stream.h | 174 ++++++++++++--------- 13 files changed, 318 insertions(+), 195 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl') diff --git a/scripts/automation/trex_control_plane/stl/console/trex_console.py b/scripts/automation/trex_control_plane/stl/console/trex_console.py index 9e9dcf62..0beb10df 100755 --- a/scripts/automation/trex_control_plane/stl/console/trex_console.py +++ b/scripts/automation/trex_control_plane/stl/console/trex_console.py @@ -532,7 +532,7 @@ class TRexConsole(TRexGeneralCmd): info = self.stateless_client.get_connection_info() exe = './trex-console --top -t -q -s {0} -p {1} --async_port {2}'.format(info['server'], info['sync_port'], info['async_port']) - cmd = ['xterm', '-geometry', '111x42', '-sl', '0', '-title', 'trex_tui', '-e', exe] + cmd = ['xterm', '-geometry', '111x47', '-sl', '0', '-title', 'trex_tui', '-e', exe] self.terminal = subprocess.Popen(cmd) return diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py index e5578564..34c7a857 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py @@ -117,8 +117,10 @@ class CTRexInfoGenerator(object): per_field_stats = OrderedDict([("owner", []), ("state", []), ("--", []), - ("Tx bps", []), + ("Tx bps L2", []), + ("Tx bps L1", []), ("Tx pps", []), + ("Line Util.", []), ("---", []), ("Rx bps", []), @@ -313,7 +315,15 @@ class CTRexStats(object): # must be implemented by designated classes (such as port/ global stats) raise NotImplementedError() + def generate_extended_values (self, snapshot): + raise NotImplementedError() + + def update(self, snapshot): + + # some extended generated values (from base values) + self.generate_extended_values(snapshot) + # update self.latest_stats = snapshot @@ -326,6 +336,8 @@ class CTRexStats(object): if (not self.reference_stats) or (diff_time > 3): self.reference_stats = self.latest_stats + + self.last_update_ts = time.time() @@ -439,6 +451,20 @@ class CGlobalStats(CTRexStats): return stats + def generate_extended_values (self, snapshot): + # L1 bps + bps = snapshot.get("m_tx_bps") + pps = snapshot.get("m_tx_pps") + + if pps > 0: + avg_pkt_size = bps / (pps * 8.0) + bps_L1 = bps * ( (avg_pkt_size + 20.0) / avg_pkt_size ) + else: + bps_L1 = 0.0 + + snapshot['m_tx_bps_L1'] = bps_L1 + + def generate_stats(self): return OrderedDict([("connection", "{host}, Port {port}".format(host=self.connection_info.get("server"), port=self.connection_info.get("sync_port"))), @@ -450,8 +476,11 @@ class CGlobalStats(CTRexStats): (" ", ""), - ("total_tx", u"{0} {1}".format( self.get("m_tx_bps", format=True, suffix="b/sec"), - self.get_trend_gui("m_tx_bps"))), + ("total_tx_L2", u"{0} {1}".format( self.get("m_tx_bps", format=True, suffix="b/sec"), + self.get_trend_gui("m_tx_bps"))), + + ("total_tx_L1", u"{0} {1}".format( self.get("m_tx_bps_L1", format=True, suffix="b/sec"), + self.get_trend_gui("m_tx_bps_L1"))), ("total_rx", u"{0} {1}".format( self.get("m_rx_bps", format=True, suffix="b/sec"), self.get_trend_gui("m_rx_bps"))), @@ -532,6 +561,21 @@ class CPortStats(CTRexStats): return stats + def generate_extended_values (self, snapshot): + # L1 bps + bps = snapshot.get("m_total_tx_bps") + pps = snapshot.get("m_total_tx_pps") + + if pps > 0: + avg_pkt_size = bps / (pps * 8.0) + bps_L1 = bps * ( (avg_pkt_size + 20.0) / avg_pkt_size ) + else: + bps_L1 = 0.0 + + snapshot['m_total_tx_bps_L1'] = bps_L1 + snapshot['m_percentage'] = (bps_L1 / self._port_obj.get_speed_bps()) * 100 + + def generate_stats(self): state = self._port_obj.get_port_state_name() if self._port_obj else "" @@ -542,6 +586,7 @@ class CPortStats(CTRexStats): else: state = format_text(state, 'bold') + return {"owner": self._port_obj.user if self._port_obj else "", "state": "{0}".format(state), @@ -550,8 +595,16 @@ class CPortStats(CTRexStats): "----": " ", "-----": " ", - "Tx bps": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps", show_value = False), - self.get("m_total_tx_bps", format = True, suffix = "bps")), + "Tx bps L1": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps_L1", show_value = False), + self.get("m_total_tx_bps_L1", format = True, suffix = "bps")), + + "Tx bps L2": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps", show_value = False), + self.get("m_total_tx_bps", format = True, suffix = "bps")), + + "Line Util.": u"{0} {1}".format(self.get_trend_gui("m_percentage", show_value = False), + format_text( + self.get("m_percentage", format = True, suffix = "%") if self._port_obj else "", + 'bold')), "Rx bps": u"{0} {1}".format(self.get_trend_gui("m_total_rx_bps", show_value = False), self.get("m_total_rx_bps", format = True, suffix = "bps")), diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index a1851b55..88e2c3ad 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -4137,7 +4137,10 @@ void CFlowGenListPerThread::start_generate_stateful(std::string erf_file_name, void CFlowGenList::Delete(){ clean_p_thread_info(); Clean(); - delete CPluginCallback::callback; + if (CPluginCallback::callback) { + delete CPluginCallback::callback; + CPluginCallback::callback = NULL; + } } diff --git a/src/main.cpp b/src/main.cpp index 6ee3a03d..6a6b5721 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -82,6 +82,8 @@ static CSimpleOpt::SOption parser_options[] = SO_END_OF_OPTIONS }; +static TrexStateless *m_sim_statelss_obj; + static int usage(){ printf(" Usage: bp_sim [OPTION] -f cfg.yaml -o outfile.erf \n"); @@ -247,6 +249,13 @@ void set_default_mac_addr(){ } } +TrexStateless * get_stateless_obj() { + return m_sim_statelss_obj; +} + +void set_stateless_obj(TrexStateless *obj) { + m_sim_statelss_obj = obj; +} int main(int argc , char * argv[]){ diff --git a/src/msg_manager.cpp b/src/msg_manager.cpp index 5fe44771..9ade1bfc 100755 --- a/src/msg_manager.cpp +++ b/src/msg_manager.cpp @@ -52,8 +52,6 @@ bool CMessagingManager::Create(uint8_t num_dp_threads,std::string a_name){ } void CMessagingManager::Delete(){ - assert(m_cp_to_dp); - assert(m_dp_to_cp); int i; for (i=0; iDelete(); } - delete []m_dp_to_cp; - delete []m_cp_to_dp; + if (m_dp_to_cp) { + delete [] m_dp_to_cp; + m_dp_to_cp = NULL; + } + + if (m_cp_to_dp) { + delete [] m_cp_to_dp; + m_cp_to_dp = NULL; + } + } CNodeRing * CMessagingManager::getRingCpToDp(uint8_t thread_id){ @@ -83,6 +89,7 @@ void CMsgIns::Free(){ if (m_ins) { m_ins->Delete(); delete m_ins; + m_ins = NULL; } } diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index 74985883..0918ff0e 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -49,7 +49,7 @@ TrexRpcCmdAddStream::_run(const Json::Value ¶ms, Json::Value &result) { string type = parse_string(mode, "type", result); /* allocate a new stream based on the type */ - std::unique_ptr stream( allocate_new_stream(section, port_id, stream_id, result) ); + std::unique_ptr stream = allocate_new_stream(section, port_id, stream_id, result); /* save this for future queries */ stream->store_stream_json(section); @@ -98,7 +98,7 @@ TrexRpcCmdAddStream::_run(const Json::Value ¶ms, Json::Value &result) { /* parse VM */ const Json::Value &vm = parse_object(section ,"vm", result); - parse_vm(vm, stream.get(), result); + parse_vm(vm, stream, result); /* parse RX info */ const Json::Value &rx = parse_object(section, "rx_stats", result); @@ -113,7 +113,7 @@ TrexRpcCmdAddStream::_run(const Json::Value ¶ms, Json::Value &result) { } /* make sure this is a valid stream to add */ - validate_stream(stream.get(), result); + validate_stream(stream, result); TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(stream->m_port_id); @@ -131,10 +131,10 @@ TrexRpcCmdAddStream::_run(const Json::Value ¶ms, Json::Value &result) { -TrexStream * +std::unique_ptr TrexRpcCmdAddStream::allocate_new_stream(const Json::Value §ion, uint8_t port_id, uint32_t stream_id, Json::Value &result) { - TrexStream *stream = NULL; + std::unique_ptr stream; const Json::Value &mode = parse_object(section, "mode", result); std::string type = parse_string(mode, "type", result); @@ -142,13 +142,13 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value §ion, uint8_t por if (type == "continuous") { - stream = new TrexStream( TrexStream::stCONTINUOUS, port_id, stream_id); + stream.reset(new TrexStream( TrexStream::stCONTINUOUS, port_id, stream_id)); } else if (type == "single_burst") { uint32_t total_pkts = parse_int(mode, "total_pkts", result); - stream = new TrexStream(TrexStream::stSINGLE_BURST, port_id, stream_id); + stream.reset(new TrexStream(TrexStream::stSINGLE_BURST, port_id, stream_id)); stream->set_single_burst(total_pkts); @@ -158,7 +158,7 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value §ion, uint8_t por uint32_t num_bursts = parse_int(mode, "count", result); uint32_t pkts_per_burst = parse_int(mode, "pkts_per_burst", result); - stream = new TrexStream(TrexStream::stMULTI_BURST,port_id, stream_id ); + stream.reset(new TrexStream(TrexStream::stMULTI_BURST,port_id, stream_id )); stream->set_multi_burst(pkts_per_burst,num_bursts,ibg_usec); @@ -175,9 +175,14 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value §ion, uint8_t por } void -TrexRpcCmdAddStream::parse_rate(const Json::Value &rate, TrexStream *stream, Json::Value &result) { +TrexRpcCmdAddStream::parse_rate(const Json::Value &rate, std::unique_ptr &stream, Json::Value &result) { - double value = parse_double(rate, "value", result); + double value = parse_double(rate, "value", result); + if (value <= 0) { + std::stringstream ss; + ss << "rate value must be a positive number - got: '" << value << "'"; + generate_parse_err(result, ss.str()); + } auto rate_types = {"pps", "bps_L1", "bps_L2", "percentage"}; std::string rate_type = parse_choice(rate, "type", rate_types, result); @@ -198,7 +203,7 @@ TrexRpcCmdAddStream::parse_rate(const Json::Value &rate, TrexStream *stream, Jso } void -TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, TrexStream *stream, Json::Value &result) { +TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result) { uint16_t pkt_offset = parse_uint16(inst, "pkt_offset", result); stream->m_vm.add_instruction(new StreamVmInstructionFixChecksumIpv4(pkt_offset)); @@ -206,7 +211,7 @@ TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, TrexStream void -TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexStream *stream, Json::Value &result){ +TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result){ std::string flow_var_name = parse_string(inst, "name", result); @@ -215,7 +220,7 @@ TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexS void -TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result){ +TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result){ std::string flow_var_name = parse_string(inst, "name", result); @@ -239,7 +244,7 @@ TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, Trex void -TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result) { +TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result) { std::string flow_var_name = parse_string(inst, "name", result); auto sizes = {1, 2, 4, 8}; @@ -326,7 +331,7 @@ TrexRpcCmdAddStream::parse_vm_instr_write_mask_flow_var(const Json::Value &inst, void -TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result) { +TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result) { std::string flow_var_name = parse_string(inst, "name", result); uint16_t pkt_offset = parse_uint16(inst, "pkt_offset", result); int add_value = parse_int(inst, "add_value", result); @@ -339,7 +344,7 @@ TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, Trex } void -TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::Value &result) { +TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, std::unique_ptr &stream, Json::Value &result) { const Json::Value &instructions = parse_array(vm ,"instructions", result); @@ -386,7 +391,7 @@ TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::V } void -TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &result) { +TrexRpcCmdAddStream::validate_stream(const std::unique_ptr &stream, Json::Value &result) { /* add the stream to the port's stream table */ TrexStatelessPort * port = get_stateless_obj()->get_port_by_id(stream->m_port_id); @@ -395,7 +400,6 @@ TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &resu if (port->get_stream_by_id(stream->m_stream_id)) { std::stringstream ss; ss << "stream " << stream->m_stream_id << " already exists"; - delete stream; generate_execute_err(result, ss.str()); } diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h index 3da1e4fa..d90d880e 100644 --- a/src/rpc-server/commands/trex_rpc_cmds.h +++ b/src/rpc-server/commands/trex_rpc_cmds.h @@ -24,6 +24,7 @@ limitations under the License. #include #include +#include class TrexStream; @@ -91,16 +92,16 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveStream, "remove_stream", 2, tru TREX_RPC_CMD_DEFINE_EXTENDED(TrexRpcCmdAddStream, "add_stream", 3, true, /* extended part */ -TrexStream * allocate_new_stream(const Json::Value §ion, uint8_t port_id, uint32_t stream_id, Json::Value &result); -void validate_stream(const TrexStream *stream, Json::Value &result); -void parse_vm(const Json::Value &vm, TrexStream *stream, Json::Value &result); -void parse_vm_instr_checksum(const Json::Value &inst, TrexStream *stream, Json::Value &result); -void parse_vm_instr_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result); -void parse_vm_instr_tuple_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result); -void parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexStream *stream, Json::Value &result); -void parse_rate(const Json::Value &inst, TrexStream *stream, Json::Value &result); -void parse_vm_instr_write_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result); -void parse_vm_instr_write_mask_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result); +std::unique_ptr allocate_new_stream(const Json::Value §ion, uint8_t port_id, uint32_t stream_id, Json::Value &result); +void validate_stream(const std::unique_ptr &stream, Json::Value &result); +void parse_vm(const Json::Value &vm, std::unique_ptr &stream, Json::Value &result); +void parse_vm_instr_checksum(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result); +void parse_vm_instr_flow_var(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result); +void parse_vm_instr_tuple_flow_var(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result); +void parse_vm_instr_trim_pkt_size(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result); +void parse_rate(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result); +void parse_vm_instr_write_flow_var(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result); +void parse_vm_instr_write_mask_flow_var(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result); ); diff --git a/src/sim/trex_sim.h b/src/sim/trex_sim.h index 8feb7bc0..99bfb28e 100644 --- a/src/sim/trex_sim.h +++ b/src/sim/trex_sim.h @@ -25,6 +25,7 @@ limitations under the License. #include #include #include +#include int gtest_main(int argc, char **argv); @@ -32,12 +33,49 @@ class TrexStateless; class TrexPublisher; class DpToCpHandler; +void set_stateless_obj(TrexStateless *obj); static inline bool in_range(int x, int low, int high) { return ( (x >= low) && (x <= high) ); } +/*************** hook for platform API **************/ +class SimPlatformApi : public TrexPlatformApi { +public: + SimPlatformApi(int dp_core_count) { + m_dp_core_count = dp_core_count; + } + + virtual uint8_t get_dp_core_count() const { + return m_dp_core_count; + } + + virtual void get_global_stats(TrexPlatformGlobalStats &stats) const { + } + + virtual void get_interface_info(uint8_t interface_id, std::string &driver_name, driver_speed_e &speed) const { + driver_name = "TEST"; + speed = TrexPlatformApi::SPEED_10G; + } + + virtual void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const { + } + + virtual void port_id_to_cores(uint8_t port_id, std::vector> &cores_id_list) const { + for (int i = 0; i < m_dp_core_count; i++) { + cores_id_list.push_back(std::make_pair(i, 0)); + } + } + + virtual void publish_async_data_now(uint32_t key) const { + + } + +private: + int m_dp_core_count; +}; + /** * interface for a sim target * @@ -67,12 +105,27 @@ public: * * @author imarom (28-Dec-15) */ -class SimGtest : public SimInterface { +class SimGtest : SimInterface { public: int run(int argc, char **argv) { + TrexStatelessCfg cfg; + + cfg.m_port_count = 1; + cfg.m_rpc_req_resp_cfg = NULL; + cfg.m_rpc_async_cfg = NULL; + cfg.m_rpc_server_verbose = false; + cfg.m_platform_api = new SimPlatformApi(1);; + cfg.m_publisher = NULL; + + set_stateless_obj(new TrexStateless(cfg)); assert( CMsgIns::Ins()->Create(4) ); - return gtest_main(argc, argv); + int rc = gtest_main(argc, argv); + + delete get_stateless_obj(); + set_stateless_obj(NULL); + + return rc; } }; @@ -112,9 +165,6 @@ public: int limit, bool is_dry_run); - TrexStateless * get_stateless_obj() { - return m_trex_stateless; - } void set_verbose(bool enable) { m_verbose = enable; @@ -149,7 +199,6 @@ private: return m_verbose; } - TrexStateless *m_trex_stateless; DpToCpHandler *m_dp_to_cp_handler; TrexPublisher *m_publisher; CFlowGenList m_fl; diff --git a/src/sim/trex_sim_stateless.cpp b/src/sim/trex_sim_stateless.cpp index 897d1fec..a8316034 100644 --- a/src/sim/trex_sim_stateless.cpp +++ b/src/sim/trex_sim_stateless.cpp @@ -54,10 +54,6 @@ static string format_num(double num, const string &suffix = "") { return "NaN"; } -TrexStateless * get_stateless_obj() { - return SimStateless::get_instance().get_stateless_obj(); -} - class SimRunException : public std::runtime_error { @@ -69,41 +65,6 @@ public: } }; -/*************** hook for platform API **************/ -class SimPlatformApi : public TrexPlatformApi { -public: - SimPlatformApi(int dp_core_count) { - m_dp_core_count = dp_core_count; - } - - virtual uint8_t get_dp_core_count() const { - return m_dp_core_count; - } - - virtual void get_global_stats(TrexPlatformGlobalStats &stats) const { - } - - virtual void get_interface_info(uint8_t interface_id, std::string &driver_name, driver_speed_e &speed) const { - driver_name = "TEST"; - speed = TrexPlatformApi::SPEED_10G; - } - - virtual void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const { - } - - virtual void port_id_to_cores(uint8_t port_id, std::vector> &cores_id_list) const { - for (int i = 0; i < m_dp_core_count; i++) { - cores_id_list.push_back(std::make_pair(i, 0)); - } - } - - virtual void publish_async_data_now(uint32_t key) const { - - } - -private: - int m_dp_core_count; -}; /** * handler for DP to CP messages @@ -146,7 +107,6 @@ public: ************************/ SimStateless::SimStateless() { - m_trex_stateless = NULL; m_publisher = NULL; m_dp_to_cp_handler = NULL; m_verbose = false; @@ -198,9 +158,10 @@ SimStateless::run(const string &json_filename, SimStateless::~SimStateless() { - if (m_trex_stateless) { - delete m_trex_stateless; - m_trex_stateless = NULL; + + if (get_stateless_obj()) { + delete get_stateless_obj(); + set_stateless_obj(NULL); } if (m_publisher) { @@ -231,11 +192,11 @@ SimStateless::prepare_control_plane() { cfg.m_platform_api = new SimPlatformApi(m_dp_core_count); cfg.m_publisher = m_publisher; - m_trex_stateless = new TrexStateless(cfg); + set_stateless_obj(new TrexStateless(cfg)); - m_trex_stateless->launch_control_plane(); + get_stateless_obj()->launch_control_plane(); - for (auto &port : m_trex_stateless->get_port_list()) { + for (auto &port : get_stateless_obj()->get_port_list()) { port->acquire("test", 0, true); } @@ -274,7 +235,7 @@ SimStateless::execute_json(const std::string &json_filename) { buffer << test.rdbuf(); try { - rep = m_trex_stateless->get_rpc_server()->test_inject_request(buffer.str()); + rep = get_stateless_obj()->get_rpc_server()->test_inject_request(buffer.str()); } catch (TrexRpcException &e) { throw SimRunException(e.what()); } @@ -321,8 +282,10 @@ static inline bool is_debug() { void SimStateless::show_intro(const std::string &out_filename) { - uint64_t bps = 0; - uint64_t pps = 0; + double pps; + double bps_L1; + double bps_L2; + double percentage; std::cout << "\nGeneral info:\n"; std::cout << "------------\n\n"; @@ -356,10 +319,12 @@ SimStateless::show_intro(const std::string &out_filename) { std::cout << "stream count: " << port->get_stream_count() << "\n"; - port->get_port_effective_rate(bps, pps); + port->get_port_effective_rate(pps, bps_L1, bps_L2, percentage); - std::cout << "max BPS: " << format_num(bps, "bps") << "\n"; - std::cout << "max PPS: " << format_num(pps, "pps") << "\n"; + std::cout << "max PPS : " << format_num(pps, "pps") << "\n"; + std::cout << "max BPS L1 : " << format_num(bps_L1, "bps") << "\n"; + std::cout << "max BPS L2 : " << format_num(bps_L2, "bps") << "\n"; + std::cout << "line util. : " << format_num(percentage, "%") << "\n"; std::cout << "\n\nStarting simulation...\n"; } diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 8ee46d29..75f77cf7 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -631,7 +631,10 @@ TrexStatelessPort::validate(void) { void -TrexStatelessPort::get_port_effective_rate(uint64_t &bps, uint64_t &pps) { +TrexStatelessPort::get_port_effective_rate(double &pps, + double &bps_L1, + double &bps_L2, + double &percentage) { if (get_stream_count() == 0) { return; @@ -641,8 +644,11 @@ TrexStatelessPort::get_port_effective_rate(uint64_t &bps, uint64_t &pps) { generate_streams_graph(); } - bps = m_graph_obj->get_max_bps_l2() * m_factor; - pps = m_graph_obj->get_max_pps() * m_factor; + pps = m_graph_obj->get_max_pps() * m_factor; + bps_L1 = m_graph_obj->get_max_bps_l1() * m_factor; + bps_L2 = m_graph_obj->get_max_bps_l2() * m_factor; + percentage = (bps_L1 / get_port_speed_bps()) * 100.0; + } /************* Trex Port Owner **************/ diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h index b0b0ddf3..a101cef0 100644 --- a/src/stateless/cp/trex_stateless_port.h +++ b/src/stateless/cp/trex_stateless_port.h @@ -316,10 +316,11 @@ public: * * @author imarom (07-Jan-16) * - * @param bps - * @param pps */ - void get_port_effective_rate(uint64_t &bps, uint64_t &pps); + void get_port_effective_rate(double &pps, + double &bps_L1, + double &bps_L2, + double &percentage); private: diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp index f4a8e800..357a2885 100644 --- a/src/stateless/cp/trex_stream.cpp +++ b/src/stateless/cp/trex_stream.cpp @@ -106,16 +106,16 @@ void TrexStream::Dump(FILE *fd){ fprintf(fd," rate :\n\n"); - fprintf(fd," pps : %f\n", get_rate().get_pps()); - fprintf(fd," bps L1 : %f\n", get_rate().get_bps_L1()); - fprintf(fd," bps L2 : %f\n", get_rate().get_bps_L2()); - fprintf(fd," percentage : %f\n", get_rate().get_percentage()); + fprintf(fd," pps : %f\n", m_rate.get_pps()); + fprintf(fd," bps L1 : %f\n", m_rate.get_bps_L1()); + fprintf(fd," bps L2 : %f\n", m_rate.get_bps_L2()); + fprintf(fd," percentage : %f\n", m_rate.get_percentage()); } TrexStream::TrexStream(uint8_t type, - uint8_t port_id, uint32_t stream_id) : m_port_id(port_id), m_stream_id(stream_id) { + uint8_t port_id, uint32_t stream_id) : m_port_id(port_id), m_stream_id(stream_id) , m_rate(*this) { /* default values */ m_type = type; @@ -160,18 +160,6 @@ TrexStream::get_stream_json() { return m_stream_json; } -TrexStreamRate & -TrexStream::get_rate() { - - /* lazy calculation of the rate */ - if (!m_rate.is_calculated()) { - TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(m_port_id); - double pkt_size = get_pkt_size(); - m_rate.calculate(pkt_size, port->get_port_speed_bps()); - } - - return m_rate; -} /************************************** * stream table @@ -253,3 +241,16 @@ int TrexStreamTable::size() { } +/************************************** + * TrexStreamRate + *************************************/ +uint64_t +TrexStreamRate::get_line_speed_bps() { + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(m_stream.m_port_id); + return port->get_port_speed_bps(); +} + +double +TrexStreamRate::get_pkt_size() { + return m_stream.get_pkt_size(); +} diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h index f4739569..66f05b16 100644 --- a/src/stateless/cp/trex_stream.h +++ b/src/stateless/cp/trex_stream.h @@ -103,6 +103,8 @@ public: } }; +class TrexStream; + /** * describes a stream rate * @@ -121,9 +123,21 @@ public: RATE_PERCENTAGE }; - TrexStreamRate() { - m_base_rate_type = RATE_INVALID; - m_is_calculated = false; + TrexStreamRate(TrexStream &stream) : m_stream(stream) { + m_pps = 0; + m_bps_L1 = 0; + m_bps_L2 = 0; + m_percentage = 0; + } + + + TrexStreamRate& operator=(const TrexStreamRate& other) { + m_pps = other.m_pps; + m_bps_L1 = other.m_bps_L1; + m_bps_L2 = other.m_bps_L2; + m_percentage = other.m_percentage; + + return (*this); } /** @@ -132,121 +146,133 @@ public: * */ void set_base_rate(rate_type_e type, double value) { - m_base_rate_type = type; - m_value = value; - m_is_calculated = false; - } - + m_pps = 0; + m_bps_L1 = 0; + m_bps_L2 = 0; + m_percentage = 0; - /** - * calculates all the rates from the base rate - * - */ - void calculate(uint16_t pkt_size, uint64_t line_bps) { + assert(value > 0); - switch (m_base_rate_type) { - + switch (type) { case RATE_PPS: - calculate_from_pps(m_value, pkt_size, line_bps); + m_pps = value; break; - case RATE_BPS_L1: - calculate_from_bps_L1(m_value, pkt_size, line_bps); + m_bps_L1 = value; break; - case RATE_BPS_L2: - calculate_from_bps_L2(m_value, pkt_size, line_bps); + m_bps_L2 = value; break; - case RATE_PERCENTAGE: - calculate_from_percentage(m_value, pkt_size, line_bps); + m_percentage = value; break; default: assert(0); + } - - m_is_calculated = true; - } - - - bool is_calculated() const { - return m_is_calculated; - } - - - /* update the rate by a factor */ - void update_factor(double factor) { - assert(m_is_calculated); - - m_pps *= factor; - m_bps_L1 *= factor; - m_bps_L2 *= factor; - m_percentage *= factor; } double get_pps() { - assert(m_is_calculated); + if (m_pps == 0) { + calculate(); + } return (m_pps); } double get_bps_L1() { - assert(m_is_calculated); + if (m_bps_L1 == 0) { + calculate(); + } return (m_bps_L1); } double get_bps_L2() { - assert(m_is_calculated); + if (m_bps_L2 == 0) { + calculate(); + } return m_bps_L2; } double get_percentage() { - assert(m_is_calculated); + if (m_percentage == 0) { + calculate(); + } return m_percentage; } + + + /* update the rate by a factor */ + void update_factor(double factor) { + /* if all are non zero - it works, if only one (base) is also works */ + m_pps *= factor; + m_bps_L1 *= factor; + m_bps_L2 *= factor; + m_percentage *= factor; + } + + + private: - void calculate_from_pps(double pps, uint16_t pkt_size, uint64_t line_bps) { - m_pps = pps; - m_bps_L1 = m_pps * (pkt_size + 24) * 8; - m_bps_L2 = m_pps * (pkt_size + 4) * 8; - m_percentage = (m_bps_L1 / line_bps) * 100.0; + /** + * calculates all the rates from the base rate + * + */ + void calculate() { + + if (m_pps != 0) { + calculate_from_pps(); + } else if (m_bps_L1 != 0) { + calculate_from_bps_L1(); + } else if (m_bps_L2 != 0) { + calculate_from_bps_L2(); + } else if (m_percentage != 0) { + calculate_from_percentage(); + } else { + assert(0); + } } - void calculate_from_bps_L1(double bps_L1, uint16_t pkt_size, uint64_t line_bps) { - m_bps_L1 = bps_L1; - m_bps_L2 = m_bps_L1 * ( (pkt_size + 4.0) / (pkt_size + 24.0) ); - m_pps = m_bps_L2 / (8 * (pkt_size + 4)); - m_percentage = (m_bps_L1 / line_bps) * 100.0; + uint64_t get_line_speed_bps(); + double get_pkt_size(); + + void calculate_from_pps() { + m_bps_L1 = m_pps * (get_pkt_size() + 24) * 8; + m_bps_L2 = m_pps * (get_pkt_size() + 4) * 8; + m_percentage = (m_bps_L1 / get_line_speed_bps()) * 100.0; } - void calculate_from_bps_L2(double bps_L2, uint16_t pkt_size, uint64_t line_bps) { - m_bps_L2 = bps_L2; - m_bps_L1 = m_bps_L2 * ( (pkt_size + 24.0) / (pkt_size + 4.0)); - m_pps = m_bps_L2 / (8 * (pkt_size + 4)); - m_percentage = (m_bps_L1 / line_bps) * 100.0; + void calculate_from_bps_L1() { + m_bps_L2 = m_bps_L1 * ( (get_pkt_size() + 4.0) / (get_pkt_size() + 24.0) ); + m_pps = m_bps_L2 / (8 * (get_pkt_size() + 4)); + m_percentage = (m_bps_L1 / get_line_speed_bps()) * 100.0; } - void calculate_from_percentage(double percentage, uint16_t pkt_size, uint64_t line_bps) { - m_percentage = percentage; - m_bps_L1 = (m_percentage / 100.0) * line_bps; - m_bps_L2 = m_bps_L1 * ( (pkt_size + 4.0) / (pkt_size + 24.0) ); - m_pps = m_bps_L2 / (8 * (pkt_size + 4)); + void calculate_from_bps_L2() { + m_bps_L1 = m_bps_L2 * ( (get_pkt_size() + 24.0) / (get_pkt_size() + 4.0)); + m_pps = m_bps_L2 / (8 * (get_pkt_size() + 4)); + m_percentage = (m_bps_L1 / get_line_speed_bps()) * 100.0; } - rate_type_e m_base_rate_type; - double m_value; + void calculate_from_percentage() { + m_bps_L1 = (m_percentage / 100.0) * get_line_speed_bps(); + m_bps_L2 = m_bps_L1 * ( (get_pkt_size() + 4.0) / (get_pkt_size() + 24.0) ); + m_pps = m_bps_L2 / (8 * (get_pkt_size() + 4)); + + } - bool m_is_calculated; double m_pps; double m_bps_L1; double m_bps_L2; double m_percentage; + /* reference to the owner class */ + TrexStream &m_stream; }; /** @@ -254,6 +280,7 @@ private: * */ class TrexStream { +friend class TrexStreamRate; public: enum STREAM_TYPE { @@ -298,19 +325,19 @@ public: double get_pps() { - return get_rate().get_pps(); + return m_rate.get_pps(); } double get_bps_L1() { - return get_rate().get_bps_L1(); + return m_rate.get_bps_L1(); } double get_bps_L2() { - return get_rate().get_bps_L2(); + return m_rate.get_bps_L2(); } double get_bw_percentage() { - return get_rate().get_percentage(); + return m_rate.get_percentage(); } void set_rate(TrexStreamRate::rate_type_e type, double value) { @@ -318,7 +345,7 @@ public: } void update_rate_factor(double factor) { - get_rate().update_factor(factor); + m_rate.update_factor(factor); } void set_type(uint8_t type){ @@ -502,9 +529,6 @@ private: } - /* get (and calculate if need) the rate of the stream */ - TrexStreamRate & get_rate(); - /* no access to this without a lazy build method */ TrexStreamRate m_rate; }; -- cgit 1.2.3-korg From a420b4c469c49c01c5de6756e2955beb4c714728 Mon Sep 17 00:00:00 2001 From: imarom Date: Tue, 23 Feb 2016 03:21:07 -0500 Subject: conflicts --- .../trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py | 5 ++++- src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py index e890bac6..f79d25c3 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py @@ -13,6 +13,8 @@ import base64 import string import traceback from types import NoneType +import copy + # base class for TX mode class STLTXMode(object): @@ -282,11 +284,12 @@ class STLStream(object): if self.next: y['next'] = self.next - y['stream'] = self.fields + y['stream'] = copy.deepcopy(self.fields) # some shortcuts for YAML rate_type = self.fields['mode']['rate']['type'] rate_value = self.fields['mode']['rate']['value'] + y['stream']['mode'][rate_type] = rate_value del y['stream']['mode']['rate'] diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index 0918ff0e..50295c7c 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -313,7 +313,7 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, std::uniqu void -TrexRpcCmdAddStream::parse_vm_instr_write_mask_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result) { +TrexRpcCmdAddStream::parse_vm_instr_write_mask_flow_var(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result) { std::string flow_var_name = parse_string(inst, "name", result); uint16_t pkt_offset = parse_uint16(inst, "pkt_offset", result); uint16_t pkt_cast_size = parse_uint16(inst, "pkt_cast_size", result); -- cgit 1.2.3-korg