diff options
Diffstat (limited to 'scripts')
10 files changed, 186 insertions, 149 deletions
diff --git a/scripts/api/stl/examples/stl_bi_dir_flows.py b/scripts/api/stl/examples/stl_bi_dir_flows.py index 38cb36dd..b7967066 100644 --- a/scripts/api/stl/examples/stl_bi_dir_flows.py +++ b/scripts/api/stl/examples/stl_bi_dir_flows.py @@ -4,51 +4,46 @@ sys.path.insert(0, "../") from trex_stl_api import * -import dpkt import time import json +# simple packet creation +def create_pkt (size, direction): -def simple_burst (): - - # build A side packet - pkt_a = STLPktBuilder() - - pkt_a.add_pkt_layer("l2", dpkt.ethernet.Ethernet()) - pkt_a.add_pkt_layer("l3_ip", dpkt.ip.IP()) - pkt_a.add_pkt_layer("l4_udp", dpkt.udp.UDP()) - pkt_a.set_pkt_payload("somepayload") - pkt_a.set_layer_attr("l3_ip", "len", len(pkt_a.get_layer('l3_ip'))) - - # build B side packet - pkt_b = pkt_a.clone() - - # set IP range for pkt and split it by multiple cores - pkt_a.set_vm_ip_range(ip_layer_name = "l3_ip", - ip_field = "src", - ip_start="10.0.0.1", ip_end="10.0.0.254", - operation = "inc", - split = True) - - pkt_a.set_vm_ip_range(ip_layer_name = "l3_ip", - ip_field = "dst", - ip_start="8.0.0.1", ip_end="8.0.0.254", - operation = "inc") - - - # build B side packet - pkt_b.set_vm_ip_range(ip_layer_name = "l3_ip", - ip_field = "src", - ip_start="8.0.0.1", ip_end="8.0.0.254", - operation = "inc", - split = True) - - pkt_b.set_vm_ip_range(ip_layer_name = "l3_ip", - ip_field = "dst", - ip_start="10.0.0.1", ip_end="10.0.0.254", - operation = "inc") + ip_range = {'src': {'start': "10.0.0.1", 'end': "10.0.0.254"}, + 'dst': {'start': "8.0.0.1", 'end': "8.0.0.254"}} + + if (direction == 0): + src = ip_range['src'] + dst = ip_range['dst'] + else: + src = ip_range['dst'] + dst = ip_range['src'] + + vm = [ + # src + STLVmFlowVar(name="src",min_val=src['start'],max_val=src['end'],size=4,op="inc"), + STLVmWriteFlowVar(fv_name="src",pkt_offset= "IP.src"), + + # dst + STLVmFlowVar(name="dst",min_val=dst['start'],max_val=dst['end'],size=4,op="inc"), + STLVmWriteFlowVar(fv_name="dst",pkt_offset= "IP.dst"), + + # checksum + STLVmFixIpv4(offset = "IP") + ] + + base = Ether()/IP()/UDP() + pad = max(0, len(base)) * 'x' + + return STLPktBuilder(pkt = base/pad, + vm = vm) + + +def simple_burst (): + # create client c = STLClient() passed = True @@ -58,11 +53,11 @@ def simple_burst (): #c.set_verbose("high") # create two streams - s1 = STLStream(packet = pkt_a, + s1 = STLStream(packet = create_pkt(200, 0), mode = STLTXCont(pps = 100)) # second stream with a phase of 1ms (inter stream gap) - s2 = STLStream(packet = pkt_b, + s2 = STLStream(packet = create_pkt(200, 1), isg = 1000, mode = STLTXCont(pps = 100)) diff --git a/scripts/api/stl/examples/stl_simple_burst.py b/scripts/api/stl/examples/stl_simple_burst.py index 2ca71b44..0de4df89 100644 --- a/scripts/api/stl/examples/stl_simple_burst.py +++ b/scripts/api/stl/examples/stl_simple_burst.py @@ -2,49 +2,25 @@ import sys sys.path.insert(0, "../") from trex_stl_api import * -import dpkt +from scapy.all import * import time def simple_burst (): - - # build a simple packet - - pkt_bld = STLPktBuilder() - pkt_bld.add_pkt_layer("l2", dpkt.ethernet.Ethernet()) - # set Ethernet layer attributes - pkt_bld.set_eth_layer_addr("l2", "src", "00:15:17:a7:75:a3") - pkt_bld.set_eth_layer_addr("l2", "dst", "e0:5f:b9:69:e9:22") - pkt_bld.set_layer_attr("l2", "type", dpkt.ethernet.ETH_TYPE_IP) - # set IP layer attributes - pkt_bld.add_pkt_layer("l3_ip", dpkt.ip.IP()) - pkt_bld.set_ip_layer_addr("l3_ip", "src", "21.0.0.2") - pkt_bld.set_ip_layer_addr("l3_ip", "dst", "22.0.0.12") - pkt_bld.set_layer_attr("l3_ip", "p", dpkt.ip.IP_PROTO_TCP) - # set TCP layer attributes - pkt_bld.add_pkt_layer("l4_tcp", dpkt.tcp.TCP()) - pkt_bld.set_layer_attr("l4_tcp", "sport", 13311) - pkt_bld.set_layer_attr("l4_tcp", "dport", 80) - pkt_bld.set_layer_attr("l4_tcp", "flags", 0) - pkt_bld.set_layer_attr("l4_tcp", "win", 32768) - pkt_bld.set_layer_attr("l4_tcp", "seq", 0) - #pkt_bld.set_pkt_payload("abcdefgh") - pkt_bld.set_layer_attr("l3_ip", "len", len(pkt_bld.get_layer('l3_ip'))) - - + + # create client c = STLClient() passed = True - + try: - - #c.set_verbose("high") - # create two bursts and link them - s1 = STLStream(packet = pkt_bld, - mode = STLTXSingleBurst(total_pkts = 5000) - ) + pkt = STLPktBuilder(pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025)/IP()/'a_payload_example') - s2 = STLStream(packet = pkt_bld, + # create two bursts and link them + s1 = STLStream(packet = pkt, + mode = STLTXSingleBurst(total_pkts = 5000)) + + s2 = STLStream(packet = pkt, mode = STLTXSingleBurst(total_pkts = 3000), next_stream_id = s1.get_id()) @@ -53,16 +29,16 @@ def simple_burst (): c.connect() # prepare our ports - c.reset(ports = [0, 1]) + c.reset(ports = [0, 3]) # add both streams to ports - stream_ids = c.add_streams([s1, s2], ports = [0, 1]) + stream_ids = c.add_streams([s1, s2], ports = [0, 3]) # run 5 times for i in xrange(1, 6): c.clear_stats() - c.start(ports = [0, 1], mult = "1gbps") - c.wait_on_traffic(ports = [0, 1]) + c.start(ports = [0, 3], mult = "1gbps") + c.wait_on_traffic(ports = [0, 3]) stats = c.get_stats() ipackets = stats['total']['ipackets'] diff --git a/scripts/api/stl/trex_stl_api.py b/scripts/api/stl/trex_stl_api.py index 0bfd1181..3ef7eaaa 100644 --- a/scripts/api/stl/trex_stl_api.py +++ b/scripts/api/stl/trex_stl_api.py @@ -1,7 +1,8 @@ import os import sys import time - +import json +import math # update the import path to include the stateless client root_path = os.path.dirname(os.path.abspath(__file__)) @@ -11,7 +12,7 @@ sys.path.insert(0, os.path.join(root_path, '../../stl/')) # aliasing import common.trex_streams -from client_utils.packet_builder import CTRexPktBuilder +from client_utils.scapy_packet_builder import * import common.trex_stl_exceptions import client.trex_stateless_client import client.trex_stateless_sim @@ -27,7 +28,12 @@ STLTXSingleBurst = common.trex_streams.STLTXSingleBurst STLTXMultiBurst = common.trex_streams.STLTXMultiBurst # packet builder -STLPktBuilder = CTRexPktBuilder +STLPktBuilder = CScapyTRexPktBuilder + +# VM +STLVmFlowVar = CTRexVmDescFlowVar +STLVmWriteFlowVar = CTRexVmDescWrFlowVar +STLVmFixIpv4 = CTRexVmDescFixIpv4 # simulator STLSim = client.trex_stateless_sim.STLSim diff --git a/scripts/automation/trex_control_plane/client/trex_stateless_client.py b/scripts/automation/trex_control_plane/client/trex_stateless_client.py index 506decfe..ebc9a6ad 100755 --- a/scripts/automation/trex_control_plane/client/trex_stateless_client.py +++ b/scripts/automation/trex_control_plane/client/trex_stateless_client.py @@ -929,7 +929,7 @@ class STLClient(object): def get_stats (self, ports = None, async_barrier = True): # by default use all ports if ports == None: - ports = self.get_all_ports() + ports = self.get_acquired_ports() else: ports = self.__ports(ports) @@ -1306,7 +1306,6 @@ class STLClient(object): try: streams_db = CStreamsDB() stream_list = streams_db.load_yaml_file(filename) - # convert to new style stream object streams = [HACKSTLStream(stream) for stream in stream_list.compiled] except YAMLError: diff --git a/scripts/automation/trex_control_plane/client/trex_stateless_sim.py b/scripts/automation/trex_control_plane/client/trex_stateless_sim.py index d8f6ed92..6dc2eb46 100644 --- a/scripts/automation/trex_control_plane/client/trex_stateless_sim.py +++ b/scripts/automation/trex_control_plane/client/trex_stateless_sim.py @@ -116,8 +116,8 @@ class STLSim(object): return module.register().get_streams() - except (AttributeError, ImportError): - pass + except (AttributeError, ImportError) as e: + print "specific error: {0}".format(e) raise STLError("bad format input file '{0}'".format(input_file)) diff --git a/scripts/automation/trex_control_plane/client_utils/packet_builder.py b/scripts/automation/trex_control_plane/client_utils/packet_builder.py index 5ad6cd7a..f9031436 100755 --- a/scripts/automation/trex_control_plane/client_utils/packet_builder.py +++ b/scripts/automation/trex_control_plane/client_utils/packet_builder.py @@ -14,7 +14,9 @@ from abc import ABCMeta, abstractmethod from collections import namedtuple import base64 -class CTRexPktBuilder(object): +from packet_builder_interface import CTrexPktBuilderInterface + +class CTRexPktBuilder(CTrexPktBuilderInterface): """ This class defines the TRex API of building a packet using dpkt package. Using this class the user can also define how TRex will handle the packet by specifying the VM setting. @@ -480,6 +482,9 @@ class CTRexPktBuilder(object): def get_vm_data(self): return self.vm.dump() + def compile (self): + pass + def dump_pkt(self, encode = True): """ Dumps the packet as a decimal array of bytes (each item x gets value between 0-255) diff --git a/scripts/automation/trex_control_plane/client_utils/packet_builder_interface.py b/scripts/automation/trex_control_plane/client_utils/packet_builder_interface.py new file mode 100644 index 00000000..b6e7c026 --- /dev/null +++ b/scripts/automation/trex_control_plane/client_utils/packet_builder_interface.py @@ -0,0 +1,43 @@ + +# base object class for a packet builder +class CTrexPktBuilderInterface(object): + + def compile (self): + """ + Compiles the packet and VM + """ + raise Exception("implement me") + + + def dump_pkt(self): + """ + Dumps the packet as a decimal array of bytes (each item x gets value between 0-255) + + :parameters: + None + + :return: + + packet representation as array of bytes + + :raises: + + :exc:`CTRexPktBuilder.EmptyPacketError`, in case packet is empty. + + """ + + raise Exception("implement me") + + + def get_vm_data(self): + """ + Dumps the instructions + + :parameters: + None + + :return: + + json object of instructions + + """ + + raise Exception("implement me") + diff --git a/scripts/automation/trex_control_plane/client_utils/scapy_packet_builder.py b/scripts/automation/trex_control_plane/client_utils/scapy_packet_builder.py index d3a5605b..b48b3d7b 100644 --- a/scripts/automation/trex_control_plane/client_utils/scapy_packet_builder.py +++ b/scripts/automation/trex_control_plane/client_utils/scapy_packet_builder.py @@ -8,6 +8,7 @@ import yaml import binascii import base64 +from packet_builder_interface import CTrexPktBuilderInterface from scapy.all import * @@ -482,7 +483,7 @@ def check_for_int (val): class CTRexVmDescFlowVar(CTRexVmDescBase): - def __init__(self, name, init_value=0, min_value=0, max_value=255, size=4, op="inc"): + def __init__(self, name, init_value=None, min_value=0, max_value=255, size=4, op="inc"): super(CTRexVmDescFlowVar, self).__init__() self.name = name; assert type(name)==str, 'type of name is not str' @@ -490,6 +491,11 @@ class CTRexVmDescFlowVar(CTRexVmDescBase): valid_fv_size(size) self.op =op valid_fv_ops (op) + + # choose default value for init val + if init_val == None: + init_val = max_val if op == "dec" else min_val + self.init_value = convert_val (init_value) self.min_value = convert_val (min_value); self.max_value = convert_val (max_value) @@ -581,13 +587,13 @@ class CTRexVmDescTupleGen(CTRexVmDescBase): ################################################################################################ -class CScapyTRexPktBuilder(object): +class CScapyTRexPktBuilder(CTrexPktBuilderInterface): """ This class defines the TRex API of building a packet using dpkt package. Using this class the user can also define how TRex will handle the packet by specifying the VM setting. """ - def __init__(self): + def __init__(self, pkt = None, vm = None): """ Instantiate a CTRexPktBuilder object @@ -596,11 +602,27 @@ class CScapyTRexPktBuilder(object): """ super(CScapyTRexPktBuilder, self).__init__() - self.pkt = None # scapy packet + + self.pkt = None self.vm_scripts = [] # list of high level instructions self.vm_low_level = None self.metadata="" + + # process packet + if pkt != None: + if not isinstance(pkt, Packet): + raise CTRexPacketBuildException(-14, "bad value for variable pkt") + self.set_packet(pkt) + + # process VM + if vm != None: + if not isinstance(vm, (CTRexScRaw, list)): + raise CTRexPacketBuildException(-14, "bad value for variable pkt") + + self.add_command(vm if isinstance(vm, CTRexScRaw) else CTRexScRaw(vm)) + + def dump_vm_data_as_yaml(self): print yaml.dump(self.get_vm_data(), default_flow_style=False) diff --git a/scripts/automation/trex_control_plane/common/trex_streams.py b/scripts/automation/trex_control_plane/common/trex_streams.py index 9b10995b..0766aa7b 100755 --- a/scripts/automation/trex_control_plane/common/trex_streams.py +++ b/scripts/automation/trex_control_plane/common/trex_streams.py @@ -1,7 +1,7 @@ #!/router/bin/python import external_packages -from client_utils.packet_builder import CTRexPktBuilder +from client_utils.packet_builder_interface import CTrexPktBuilderInterface from collections import OrderedDict, namedtuple from client_utils.yaml_utils import * import trex_stl_exceptions @@ -422,7 +422,7 @@ class STLStream(object): if not isinstance(mode, STLTXMode): raise STLArgumentError('mode', mode) - if not isinstance(packet, CTRexPktBuilder): + if not isinstance(packet, CTrexPktBuilderInterface): raise STLArgumentError('packet', packet) if not isinstance(enabled, bool): @@ -452,6 +452,8 @@ class STLStream(object): # mode self.fields['mode'] = mode.to_json() + packet.compile() + # packet and VM self.fields['packet'] = packet.dump_pkt() self.fields['vm'] = packet.get_vm_data() diff --git a/scripts/stl/profiles/imix.py b/scripts/stl/profiles/imix.py index c0305cc3..dcd6f734 100644 --- a/scripts/stl/profiles/imix.py +++ b/scripts/stl/profiles/imix.py @@ -1,31 +1,45 @@ +import sys +import os -from common.trex_streams import * -from client_utils.packet_builder import CTRexPktBuilder +# we need the API path +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) +API_PATH = os.path.join(CURRENT_PATH, "../../api/stl") +sys.path.insert(0, API_PATH) +from trex_stl_api import * +from scapy.all import * +# IMIX profile - involves 3 streams of UDP packets +# 1 - 60 bytes +# 2 - 590 bytes +# 3 - 1514 bytes class STLImix(object): def __init__ (self): - ip_range = {'src' : {}, 'dst': {}} + # default IP range + self.ip_range = {'src': {'start': "10.0.0.1", 'end': "10.0.0.254"}, + 'dst': {'start': "8.0.0.1", 'end': "8.0.0.254"}} - ip_range['src']['start'] = "10.0.0.1" - ip_range['src']['end'] = "10.0.0.254" - ip_range['dst']['start'] = "8.0.0.1" - ip_range['dst']['end'] = "8.0.0.254" + # default IMIX properties + self.imix_table = [ {'size': 60, 'pps': 28}, + {'size': 590, 'pps': 20}, + {'size': 1514, 'pps': 4}] - self.ip_range = ip_range - def get_streams (self, flip = False): + def create_stream (self, size, pps, vm): + # create a base packet and pad it to size + base_pkt = Ether()/IP()/UDP() + pad = max(0, size - len(base_pkt)) * 'x' - # construct the base packet for the profile - base_pkt = CTRexPktBuilder() + pkt = STLPktBuilder(pkt = base_pkt/pad, + vm = vm) - base_pkt.add_pkt_layer("l2", dpkt.ethernet.Ethernet()) - base_pkt.set_layer_attr("l2", "type", dpkt.ethernet.ETH_TYPE_IP) - base_pkt.add_pkt_layer("l3_ip", dpkt.ip.IP()) - base_pkt.add_pkt_layer("l4_udp", dpkt.udp.UDP()) + return STLStream(packet = pkt, + mode = STLTXCont()) + def get_streams (self, flip = False): + if not flip: src = self.ip_range['src'] dst = self.ip_range['dst'] @@ -33,55 +47,30 @@ class STLImix(object): src = self.ip_range['dst'] dst = self.ip_range['src'] - base_pkt.set_vm_ip_range(ip_layer_name = "l3_ip", - ip_field = "src", - ip_start = src['start'], - ip_end = src['end'], - operation = "inc", - split = True) - - base_pkt.set_vm_ip_range(ip_layer_name = "l3_ip", - ip_field = "dst", - ip_start = dst['start'], - ip_end = dst['end'], - operation = "inc") - - - - # pad to 60 bytes - pkt_1 = base_pkt.clone() - payload_size = 60 - len(pkt_1.get_layer('l2')) - pkt_1.set_pkt_payload("a" * payload_size) - - pkt_1.set_layer_attr("l3_ip", "len", len(pkt_1.get_layer('l3_ip'))) + # construct the base packet for the profile + vm =[ + # src + STLVmFlowVar(name="src",min_val=src['start'],max_val=src['end'],size=4,op="inc"), + STLVmWriteFlowVar(fv_name="src",pkt_offset= "IP.src"), - s1 = STLStream(packet = pkt_1, - mode = STLTXCont()) + # dst + STLVmFlowVar(name="dst",min_val=dst['start'],max_val=dst['end'],size=4,op="inc"), + STLVmWriteFlowVar(fv_name="dst",pkt_offset= "IP.dst"), - # stream 2 - pkt_2 = base_pkt.clone() - payload_size = 590 - len(pkt_2.get_layer('l2')) - pkt_2.set_pkt_payload("a" * payload_size) + # checksum + STLVmFixIpv4(offset = "IP") - pkt_2.set_layer_attr("l3_ip", "len", len(pkt_2.get_layer('l3_ip'))) + ] - s2 = STLStream(packet = pkt_2, - mode = STLTXCont()) + # create imix streams + return [self.create_stream(x['size'], x['pps'], vm) for x in self.imix_table] - # stream 3 - pkt_3 = base_pkt.clone() - payload_size = 1514 - len(pkt_3.get_layer('l2')) - pkt_3.set_pkt_payload("a" * payload_size) - pkt_3.set_layer_attr("l3_ip", "len", len(pkt_3.get_layer('l3_ip'))) +# dynamic load - used for trex console or simulator +def register(): + return STLImix() - s3 = STLStream(packet = pkt_3, - mode = STLTXCont()) - return [s1, s2, s3] -# dynamic load -def register(): - return STLImix() |