summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scripts/api/stl/examples/stl_bi_dir_flows.py77
-rw-r--r--scripts/api/stl/examples/stl_simple_burst.py52
-rw-r--r--scripts/api/stl/trex_stl_api.py12
-rwxr-xr-xscripts/automation/trex_control_plane/client/trex_stateless_client.py3
-rw-r--r--scripts/automation/trex_control_plane/client/trex_stateless_sim.py4
-rwxr-xr-xscripts/automation/trex_control_plane/client_utils/packet_builder.py7
-rw-r--r--scripts/automation/trex_control_plane/client_utils/packet_builder_interface.py43
-rw-r--r--scripts/automation/trex_control_plane/client_utils/scapy_packet_builder.py30
-rwxr-xr-xscripts/automation/trex_control_plane/common/trex_streams.py6
-rw-r--r--scripts/stl/profiles/imix.py101
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()