From bd63922fbd687f7c86655d2095fea340e59c37c5 Mon Sep 17 00:00:00 2001 From: Vyacheslav Ogai Date: Sat, 8 Oct 2016 20:59:07 +0300 Subject: Update field engine defs. Generation vm instrucions from updated model. Signed-off-by: Vyacheslav Ogai --- .../stl/services/scapy_server/field_engine.json | 79 ++++++++++++++-- .../stl/services/scapy_server/scapy_service.py | 103 ++++----------------- .../scapy_server/unit_tests/test_scapy_service.py | 55 +++++++---- 3 files changed, 125 insertions(+), 112 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl/services/scapy_server') diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/field_engine.json b/scripts/automation/trex_control_plane/stl/services/scapy_server/field_engine.json index 9214f4c8..c978e42c 100644 --- a/scripts/automation/trex_control_plane/stl/services/scapy_server/field_engine.json +++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/field_engine.json @@ -2,11 +2,11 @@ "instructions": [ { "id": "STLVmFlowVar", - "parameters": ["max_value","min_value","step","op"] + "parameters": ["name", "max_value","min_value","step", "size","op"] }, { "id": "STLVmWrFlowVar", - "parameters": ["fv_name", "pkt_offset"] + "parameters": ["fv_name", "pkt_offset","offset_fixup","add_val","is_big"] }, { "id": "STLVmFixIpv4", @@ -19,22 +19,38 @@ ], "instruction_params_meta": [ + { + "id": "name", + "name": "Name", + "type": "STRING", + "required": true, + "defaultValue": "Not defined" + }, + { + "id": "init_value", + "name": "Initial value", + "type": "STRING", + "defaultValue": "0" + }, { "id": "max_value", "name": "Maximum value", "type": "STRING", + "required": true, "defaultValue": "0" }, { "id": "min_value", "name": "Minimum value", "type": "STRING", + "required": true, "defaultValue": "0" }, { "id": "step", "name": "Step", "type": "NUMBER", + "required": true, "defaultValue": "1" }, { @@ -46,37 +62,84 @@ "dec": "Decrement", "inc": "Increment", "random": "Random" + }, + "required": true + }, + { + "id": "size", + "name": "Size", + "type": "ENUM", + "defaultValue": "1", + "dict": { + "1": "1", + "2": "2", + "4": "4", + "8": "8" } }, { "id": "fv_name", "name": "Variable name", - "type": "STRING" + "type": "STRING", + "required": true, + "defaultValue": "Not Defined" }, { "id": "pkt_offset", "name": "Offset", - "type": "STRING" + "type": "STRING", + "required": true, + "defaultValue": 0 + }, + { + "id": "offset_fixup", + "name": "offset_fixup", + "type": "NUMBER", + "defaultValue": 0 + }, + { + "id": "add_val", + "name": "add_val", + "type": "NUMBER", + "defaultValue": 0 + }, + { + "id": "is_big", + "name": "is_big", + "type": "ENUM", + "defaultValue": "true", + "dict": { + "true": "true", + "false": "false" + } }, { "id": "offset", "name": "Offset", - "type": "STRING" + "type": "STRING", + "required": true, + "defaultValue": "Not defined" }, { "id": "l3_offset", "name": "L3 offset", - "type": "STRING" + "type": "STRING", + "required": true, + "defaultValue": 0 }, { "id": "l4_offset", "name": "L4 offset", - "type": "STRING" + "type": "STRING", + "required": true, + "defaultValue": 0 }, { "id": "l4_type", "name": "L4 type", - "type": "STRING" + "type": "STRING", + "required": true, + "defaultValue": "Not defined" } ], "protocol_fields": { diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py b/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py index 93ca7502..32b5efbf 100755 --- a/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py +++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py @@ -6,6 +6,7 @@ stl_pathname = os.path.abspath(os.path.join(os.pardir, os.pardir)) sys.path.append(stl_pathname) from trex_stl_lib.api import * +import trex_stl_lib.trex_stl_packet_builder_scapy import tempfile import hashlib import base64 @@ -401,6 +402,7 @@ class Scapy_service(Scapy_service_api): self.field_engine_instruction_expressions = [] self._load_definitions_from_json() self._load_field_engine_meta_from_json() + self._vm_instructions = dict([m for m in inspect.getmembers(trex_stl_lib.trex_stl_packet_builder_scapy, inspect.isclass) if m[1].__module__ == 'trex_stl_lib.trex_stl_packet_builder_scapy']) def _load_definitions_from_json(self): # load protocol definitions from a json file @@ -763,48 +765,14 @@ class Scapy_service(Scapy_service_api): return res def _generate_vm_instructions(self, pkt, field_engine_model_descriptor): - self.field_engine_instruction_expressions = [self._get_instruction_expressions_header()] + self.field_engine_instruction_expressions = [] instructions = [] - protocols_model = field_engine_model_descriptor['instructions'] - for protocol in protocols_model: - protocol_id = protocol['id'] - for field in protocol['fields']: - field_id = field['fieldId'] - var_name = str(protocol_id + "_" + field_id) - parameters = field['parameters'] - min_value = int(parameters['min_value']) if parameters['min_value'].isdigit() else str(parameters['min_value']) - max_value = int(parameters['max_value']) if parameters['max_value'].isdigit() else str(parameters['max_value']) - vm_flow_var = STLVmFlowVar(name=var_name, min_value=min_value, max_value=max_value, - step=int(parameters['step']), op=parameters['op']) - pkt_offset = self._get_pkt_offset_param(protocol_id, field_id) - vm_wr_flow_var = STLVmWrFlowVar(fv_name=var_name, pkt_offset=pkt_offset) - instructions.append(vm_flow_var) - instructions.append(vm_wr_flow_var) - self.field_engine_instruction_expressions += self._generate_vm_instruction_commands(protocol_id, field_id, parameters) - - protocols = [(proto['id']) for proto in protocols_model] - - if "IP" in protocols: - ip_v4_checksum_fixed = False - expression = {} - - if "TCP" in protocols and protocols.index("TCP") - protocols.index("IP") == 1: - instructions.append(STLVmFixChecksumHw(l3_offset="IP",l4_offset="TCP",l4_type=CTRexVmInsFixHwCs.L4_TYPE_TCP)) - expression['name'] = "STLVmFixChecksumHw" - expression['parameters'] = {"l3_offset": '"IP"',"l4_offset": '"TCP"',"l4_type": '"CTRexVmInsFixHwCs.L4_TYPE_TCP"'} - ip_v4_checksum_fixed = True - elif "UDP" in protocols and protocols.index("UDP") - protocols.index("IP") == 1: - instructions.append(STLVmFixChecksumHw(l3_offset="IP", l4_offset="UDP", l4_type=CTRexVmInsFixHwCs.L4_TYPE_UDP)) - expression['name'] = "STLVmFixChecksumHw" - expression['parameters'] = {"l3_offset": '"IP"', "l4_offset": '"UDP"', "l4_type": '"CTRexVmInsFixHwCs.L4_TYPE_UDP"'} - ip_v4_checksum_fixed = True - - if not ip_v4_checksum_fixed: - instructions.append(STLVmFixIpv4(offset="IP")) - expression['name'] = "STLVmFixIpv4" - expression['parameters'] = {"offset": '"IP"'} - - self.field_engine_instruction_expressions.append(expression) + instructions_def = field_engine_model_descriptor['instructions'] + for instruction_def in instructions_def: + instruction_id = instruction_def['id'] + instruction_class = self._vm_instructions[instruction_id] + parameters = {k: self._sanitize_value(v) for (k, v) in instruction_def['parameters'].iteritems()} + instructions.append(instruction_class(**parameters)) fe_parameters = field_engine_model_descriptor['global_parameters'] @@ -812,56 +780,17 @@ class Scapy_service(Scapy_service_api): if "cache_size" in fe_parameters: cache_size = int(fe_parameters['cache_size']) - self.field_engine_instruction_expressions += self._get_instruction_expressions_footer(cache_size) - pkt_builder = STLPktBuilder(pkt=pkt, vm=STLScVmRaw(instructions, cache_size=cache_size)) pkt_builder.compile() return pkt_builder.get_vm_data() - def _get_instruction_expressions_header(self): - return {'free_form': "vm = STLScVmRaw(["} - - def _get_instruction_expressions_footer(self, cache_size): - instructions = [] - footer = ']' - - if cache_size != None and cache_size > 0: - footer += ',{0}={1}'.format("cache_size", cache_size) - - footer += ')' - instructions.append({'free_form': footer}) - return instructions - - def _get_pkt_offset_param(self, protocol_id, field_id): - return str(protocol_id + "." + field_id) if protocol_id != "Ether" else 0 - - def _generate_vm_instruction_commands(self, protocol_id, field_id, parameters): - instructions = [] - instruction = {} - instruction['name'] = "STLVmFlowVar" - var_name = '"'+str(protocol_id + "_" + field_id)+'"' - instruction['parameters'] = {} - instruction['parameters']["name"] = var_name - for param_id in parameters: - instruction['parameters'][param_id] = self._format_vm_instruction_param(param_id, parameters[param_id]) - instructions.append(instruction) - - instruction = {} - instruction['name'] = "STLVmWrFlowVar" - pkt_offset = self._get_pkt_offset_param(protocol_id, field_id) - pkt_offset_val = '"{0}"'.format(pkt_offset) if isinstance(pkt_offset, str) else pkt_offset - instruction['parameters'] = {} - instruction['parameters']["fv_name"] = var_name - instruction['parameters']["pkt_offset"] = pkt_offset_val - instructions.append(instruction) - - return instructions - - def _format_vm_instruction_param(self,param_id, value): - param_meta = self._get_instruction_parameter_meta(param_id) - if param_meta['type'] == "NUMBER" or self._is_int(value): - return value - return '"{0}"'.format(value) + def _sanitize_value(self, val): + if val == "true": + return True + elif val == "false": + return False + else: + return int(val) if val.isdigit() else str(val) def _get_instruction_parameter_meta(self, param_id): for meta in self.instruction_parameter_meta_definitions: diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/test_scapy_service.py b/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/test_scapy_service.py index af3bfb43..2f5dec91 100644 --- a/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/test_scapy_service.py +++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/test_scapy_service.py @@ -119,16 +119,22 @@ def test_get_definitions_all(): assert("TCP" in def_classnames) fe_parameter_metas = defs['feInstructionParameters'] - assert(fe_parameter_metas[0]['id'] == "max_value") - assert(fe_parameter_metas[1]['id'] == "min_value") - assert(fe_parameter_metas[2]['id'] == "step") - assert(fe_parameter_metas[3]['id'] == "op") - assert(fe_parameter_metas[4]['id'] == "fv_name") - assert(fe_parameter_metas[5]['id'] == "pkt_offset") - assert(fe_parameter_metas[6]['id'] == "offset") - assert(fe_parameter_metas[7]['id'] == "l3_offset") - assert(fe_parameter_metas[8]['id'] == "l4_offset") - assert(fe_parameter_metas[9]['id'] == "l4_type") + assert(fe_parameter_metas[0]['id'] == "name") + assert(fe_parameter_metas[1]['id'] == "init_value") + assert(fe_parameter_metas[2]['id'] == "max_value") + assert(fe_parameter_metas[3]['id'] == "min_value") + assert(fe_parameter_metas[4]['id'] == "step") + assert(fe_parameter_metas[5]['id'] == "op") + assert(fe_parameter_metas[6]['id'] == "size") + assert(fe_parameter_metas[7]['id'] == "fv_name") + assert(fe_parameter_metas[8]['id'] == "pkt_offset") + assert(fe_parameter_metas[9]['id'] == "offset_fixup") + assert(fe_parameter_metas[10]['id'] == "add_val") + assert(fe_parameter_metas[11]['id'] == "is_big") + assert(fe_parameter_metas[12]['id'] == "offset") + assert(fe_parameter_metas[13]['id'] == "l3_offset") + assert(fe_parameter_metas[14]['id'] == "l4_offset") + assert(fe_parameter_metas[15]['id'] == "l4_type") # All instructions should have a help description. fe_instructions = defs['feInstructions'] @@ -274,14 +280,29 @@ def test_generate_vm_instructions(): layer_def("Ether"), layer_def("IP", src="16.0.0.1", dst="48.0.0.1") ] - ip_instructions_model = {"field_engine": {'global_parameters': {}, 'instructions': [{'id': "IP", 'fields': [ - {"fieldId": "src", 'parameters': {'min_value': "0", 'max_value': "16.0.0.255", 'step': "1", 'op': "inc"}}, - {"fieldId": "ttl", 'parameters': {'min_value': "1", 'max_value': "17", 'step': "1", 'op': "inc"}}]}]}} + ip_instructions_model = {"field_engine": {"instructions": [{"id": "STLVmFlowVar", + "parameters": {"op": "inc", "min_value": "192.168.0.10", + "size": "1", "name": "ip_src", + "step": "1", + "max_value": "192.168.0.100"}}, + {"id": "STLVmWrFlowVar", + "parameters": {"pkt_offset": "IP.src", "is_big": "true", + "add_val": "0", "offset_fixup": "0", + "fv_name": "ip_src"}}, + {"id": "STLVmFlowVar", + "parameters": {"op": "dec", "min_value": "32", + "size": "1", "name": "ip_ttl", + "step": "4", "max_value": "64"}}, + {"id": "STLVmWrFlowVar", + "parameters": {"pkt_offset": "IP.ttl", "is_big": "true", + "add_val": "0", "offset_fixup": "0", + "fv_name": "ip_ttl"}}], + "global_parameters": {}}} res = build_pkt_ex(ip_pkt_model, ip_instructions_model) src_instruction = res['vm_instructions']['instructions'][0] - assert(src_instruction['min_value'] == 0) - assert(src_instruction['max_value'] == 268435711) + assert(src_instruction['min_value'] == 3232235530) + assert(src_instruction['max_value'] == 3232235620) ttl_instruction = res['vm_instructions']['instructions'][2] - assert(ttl_instruction['min_value'] == 1) - assert(ttl_instruction['max_value'] == 17) \ No newline at end of file + assert(ttl_instruction['min_value'] == 32) + assert(ttl_instruction['max_value'] == 64) -- cgit 1.2.3-korg