summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--draft_trex_stateless.asciidoc509
-rwxr-xr-ximages/Thumbs.dbbin518144 -> 552960 bytes
-rw-r--r--images/stl_tut_pcap_file1.pngbin0 -> 3800 bytes
3 files changed, 479 insertions, 30 deletions
diff --git a/draft_trex_stateless.asciidoc b/draft_trex_stateless.asciidoc
index a9195d46..7a202c34 100644
--- a/draft_trex_stateless.asciidoc
+++ b/draft_trex_stateless.asciidoc
@@ -7,7 +7,7 @@ TRex
:numbered:
:web_server_url: http://trex-tgn.cisco.com/trex
:local_web_server_url: csi-wiki-01:8181/trex
-:toclevels: 4
+:toclevels: 6
== Stateless support
@@ -19,7 +19,7 @@ TRex
* Interface can configured with multi traffic profiles
* Profile can support multi streams. Scale to 10K streams in parallel
* Each Stream
-** Packet template - ability to build any packet using Scapy (e.g. MPLS/Ipv4/Ipv6/GRE/VXLAN/NSH)
+** Packet template - ability to build any packet using Scapy (e.g. MPLS/IPv4/Ipv6/GRE/VXLAN/NSH)
** Field engine program
*** Ability to change any field inside the packet, for example src_ip = 10.0.0.1-10.0.0.255
*** Ability to change the packet size (e.g. Random packet size 64-9K)
@@ -97,7 +97,7 @@ image::images/stateless_objects.png[title="TRex Objects ",align="left",width=600
This tutorial will walk you through basic but complete TRex Stateless use cases that will show you common concepts as well as slightly more advanced ones.
-==== Tutorial 1: Simple Ipv4/UDP packet - Simulator
+==== Tutorial 1: Simple IPv4/UDP packet - Simulator
The following example demonstrates the most basic use case using our simulator.
@@ -305,7 +305,7 @@ $./stl-sim -f stl/udp_1pkt_simple.py --pkt
0030 78 78 78 78 xxxx
----
-==== Tutorial 2: Simple Ipv4/UDP packet - TRex
+==== Tutorial 2: Simple IPv4/UDP packet - TRex
===== Run TRex as a server mode
@@ -446,7 +446,7 @@ Port Statistics
----
-==== Tutorial 3: Simple Ipv4/UDP packet
+==== Tutorial 3: Simple IPv4/UDP packet
The following example demonstrates
@@ -666,14 +666,14 @@ file: `stl/imix.py`
The following example demonstrates changing packet fields.
The Field Engine (FE) has limited number of instructions/operation for supporting most use cases. There is a plan to add LuaJIT to get 100% flexiable in the cost of performance.
-The FE can allocate variable in Stream context. Write a variable to a packet offset, change packet size etc.
+The FE can allocate stream variable in Stream context. Write a stream variable to a packet offset, change packet size etc.
*Some examples for what can be done:*
* Change ipv4.tos 1-10
* Change packet size to be random in range 64-9K
* Create range of flows (change src_ip,dest_ip,src_port,dest_port)
-* Update Ipv4 checksum
+* Update IPv4 checksum
for more info see link:trex_rpc_server_spec.html#_object_type_em_vm_em_a_id_vm_obj_a[here]
@@ -718,10 +718,10 @@ file: `stl/syn_attack.py`
mode = STLTXCont())
----
<1> Create SYN packet using Scapy
-<2> Define variable name=ip_src, 4 bytes size for IPv4.
-<3> Define variable name=src_port, 2 bytes size for port.
+<2> Define stream variable name=ip_src, 4 bytes size for IPv4.
+<3> Define stream variable name=src_port, 2 bytes size for port.
<4> Write ip_src var into `IP.src` packet offset. Scapy calculate the offset. We could gave `IP:1.src" for second IP header in the packet
-<5> Fix Ipv4 checksum. here we provide the header name `IP` we could gave `IP:1` for second IP
+<5> Fix IPv4 checksum. here we provide the header name `IP` we could gave `IP:1` for second IP
<6> Update TCP src port- TCP checksum is not updated here
WARNING: Original Scapy does not have the capability to calculate offset for a header/field by name. This offset capability won't work for all the cases because there could be complex cases that Scapy rebuild the header. In such cases put offset as a number
@@ -729,22 +729,22 @@ WARNING: Original Scapy does not have the capability to calculate offset for a h
The output pcap file field can be seen here
.Pcap file output
-[format="csv",cols="1^,2^,1^", options="header"]
+[format="csv",cols="1^,2^,2^", options="header",width="40%"]
|=================
pkt,Client IPv4,Client Port
- 1 , 17.152.71.218 , 5814
- 2 , 17.7.6.30 , 26810
- 3 , 17.3.32.200 , 1810
+ 1 , 17.152.71.218 , 5814
+ 2 , 17.7.6.30 , 26810
+ 3 , 17.3.32.200 , 1810
4 , 17.135.236.168 , 55810
- 5 , 17.46.240.12 , 1078
- 6 , 16.133.91.247, 2323
+ 5 , 17.46.240.12 , 1078
+ 6 , 16.133.91.247 , 2323
|=================
==== Tutorial 8: Field Engine, Tuple Generator
The following example demonstrates creating multiply flow from the same packet template.
-The TupleGenerator instructions are used to create two variables with IP, port
+The TupleGenerator instructions are used to create two stream variables with IP, port
file: `stl/udp_1pkt_tuple_gen.py`
@@ -770,12 +770,12 @@ file: `stl/udp_1pkt_tuple_gen.py`
vm = vm)
----
<1> Define struct with two dependent varibles tuple.ip tuple.port
-<2> Write tuple.ip to Ipv4 src field offset
+<2> Write tuple.ip to IPv4 src field offset
<3> Write tuple.port to UDP header. You should set UDP.checksum to zero
.Pcap file output
-[format="csv",cols="1^,2^,1^", options="header"]
+[format="csv",cols="1^,2^,1^", options="header",width="40%"]
|=================
pkt,Client IPv4,Client Port
1 , 16.0.0.1 , 1025
@@ -788,11 +788,11 @@ pkt,Client IPv4,Client Port
* Number of clients are two 16.0.0.1 and 16.0.0.2
* Number of flows is limited to 129020 (2*65535-1025)
-* The variable size should match the size of the FlowVarWr instruction
+* The stream variable size should match the size of the FlowVarWr instruction
==== Tutorial 9: Field Engine, write to a bit-field packet
-The following example demonstrates a way to write a variable to a bit field packet variables.
+The following example demonstrates a way to write a stream variable to a bit field packet variables.
In this example MPLS label field will be changed.
.MPLS header
@@ -832,7 +832,7 @@ file: `stl/udp_1pkt_mpls_vm.py`
----
<1> Define varible size of 2 bytes
-<2> Write the variable label with a shift of 12 bits and with 20bit MSB mask. Cast the variables of 2 bytes to 4 bytes
+<2> Write the stream variable label with a shift of 12 bits and with 20bit MSB mask. Cast the stream variables of 2 bytes to 4 bytes
<3> Second MPLS header should be changed
@@ -882,7 +882,7 @@ file: `stl/udp_rand_len_9k.py`
]
)
----
-<1> Define a random variable with maximum size of the packet
+<1> Define a random stream variable with maximum size of the packet
<2> Trim the packet size to the fv_rand value
<3> fix ip.len
<4> fix udp.len
@@ -969,15 +969,17 @@ To send gratuitous ARP from TRex server side for this server (58.0.0.1)
[source,python]
----
-
def create_stream (self):
# create a base packet and pad it to size
- base_pkt = Ether(src="00:00:dd:dd:00:01",dst="ff:ff:ff:ff:ff:ff")/ARP(psrc="58.0.0.1",hwsrc="00:00:dd:dd:00:01", hwdst="00:00:dd:dd:00:01", pdst="58.0.0.1")
-
+ base_pkt = Ether(src="00:00:dd:dd:00:01",
+ dst="ff:ff:ff:ff:ff:ff")/
+ ARP(psrc="58.0.0.1",
+ hwsrc="00:00:dd:dd:00:01",
+ hwdst="00:00:dd:dd:00:01",
+ pdst="58.0.0.1")
----
-Then we can send the clients traffic from A->C
-
+Then traffic can be sent from client side A->C
file: `stl/udp_1pkt_range_clients_split.py`
@@ -1014,8 +1016,455 @@ class STLS1(object):
return STLStream(packet = STLPktBuilder(pkt = base_pkt/pad,vm = vm),
mode = STLTXCont( pps=10 ))
----
-<1> Write the variable mac_src with offset of 10 (last 2 bytes of src_mac field)
-<2> Write the variable mac_src with `offset_fixup` of 2. beacuse we write it with offset
+<1> Write the stream variable mac_src with offset of 10 (last 2 bytes of src_mac field)
+<2> Write the stream variable mac_src with `offset_fixup` of 2. beacuse we write it with offset
+
+
+==== Tutorial 12: Field Engine, Split to core
+
+The following example demonstrates a way to split generated traffic to a number of threads.
+Using this feature, there is a way to specify by each field to split the traffic to threads.
+Without this feature the traffic is duplicated and all the threads transmits the same traffic.
+
+===== Without Split
+
+Let's assume we have two transmitters DP threads
+
+[source,python]
+----
+ def create_stream (self):
+
+ # TCP SYN
+ base_pkt = Ether()/IP(dst="48.0.0.1")/TCP(dport=80,flags="S")
+
+
+ # vm
+ vm = CTRexScRaw( [ STLVmFlowVar(name="ip_src",
+ min_value="16.0.0.0",
+ max_value="16.0.0.254",
+ size=4, op="inc"), <1>
+
+
+ STLVmWrFlowVar(fv_name="ip_src", pkt_offset= "IP.src" ), <2>
+
+ STLVmFixIpv4(offset = "IP"), # fix checksum
+ ]
+
+ )
+
+----
+<1> Stream variable
+<2> write it to IPv4.src
+
+
+.Variable per thread
+[format="csv",cols="1^,3^,3^", options="header",width="40%"]
+|=================
+pkt, thread-0 ip_src,thread-1 ip_src
+ 1 , 16.0.0.1 , 16.0.0.1
+ 2 , 16.0.0.2 , 16.0.0.2
+ 3 , 16.0.0.3 , 16.0.0.3
+ 4 , 16.0.0.4 , 16.0.0.4
+ 5 , 16.0.0.5 , 16.0.0.5
+ 6 , 16.0.0.6, 16.0.0.6
+|=================
+
+* In this case all the threads transmit the same packets
+
+
+===== With Split feature
+
+Let's assume we have two transmitters DP threads
+
+[source,python]
+----
+ def create_stream (self):
+
+ # TCP SYN
+ base_pkt = Ether()/IP(dst="48.0.0.1")/TCP(dport=80,flags="S")
+
+
+ # vm
+ vm = CTRexScRaw( [ STLVmFlowVar(name="ip_src",
+ min_value="16.0.0.0",
+ max_value="16.0.0.254",
+ size=4, op="inc"),
+
+
+ STLVmWrFlowVar(fv_name="ip_src", pkt_offset= "IP.src" ),
+
+ STLVmFixIpv4(offset = "IP"), # fix checksum
+ ]
+ ,split_by_field = "ip_src" <1>
+ )
+
+----
+<1> The same example but now we with split by `ip_src` stream variable
+
+.Variable per thread
+[format="csv",cols="1^,3^,3^", options="header",width="40%"]
+|=================
+pkt, thread-0 ip_src ,thread-1 ip_src
+ 1 , 16.0.0.1 , 16.0.0.128
+ 2 , 16.0.0.2 , 16.0.0.129
+ 3 , 16.0.0.3 , 16.0.0.130
+ 4 , 16.0.0.4 , 16.0.0.131
+ 5 , 16.0.0.5 , 16.0.0.132
+ 6 , 16.0.0.6, 16.0.0.133
+|=================
+
+* In this case the stream variable is split
+
+To simulate it you can run the following command, let's take the file `stl/udp_1pkt_range_clients_split.py` and simulate it
+
+[source,bash]
+----
+$./stl-sim -f stl/udp_1pkt_range_clients_split.py -o a.pcap -c 2 -l 10 #<1>
+----
+<1> simulate 2 threads -c 2
+
+
+.Variable per thread
+[format="csv",cols="1^,3^,3^", options="header",width="40%"]
+|=================
+pkt, thread-0 ip_src,thread-1 ip_src
+ 1 , 55.55.0.1 , 55.55.58.153
+ 2 , 55.55.0.2 , 55.55.58.154
+ 3 , 55.55.0.3 , 55.55.58.155
+ 4 , 55.55.0.4 , 55.55.58.156
+ 5 , 55.55.0.5 , 55.55.58.157
+ 6 , 55.55.0.6 , 55.55.58.158
+|=================
+
+
+
+===== Some rules about Split stream varibles and burst/multi-burst
+
+* In case of burst/multi-burst the number of packets are split to number of threads in *default* there is no need an explict split
+* When the number of packets in a burst is smaller than the number of threads only one thread will do the work.
+* In case there is stream with burst of *1* packet, only the first DP thread will do the work.
+
+
+==== Tutorial 13: Pcap file to *one* stream
+
+There is a way to load *one* packet data into a stream. There is an assumption that this pcap. only the first packet from this pcap is taken.
+
+file: `stl/udp_1pkt_pcap.py`
+
+[source,python]
+----
+
+ def get_streams (self, direction = 0):
+ return [STLStream(packet =
+ STLPktBuilder(pkt ="stl/yaml/udp_64B_no_crc.pcap"), # path relative to pwd <1>
+ mode = STLTXCont(pps=10)) ]
+
+----
+<1> packet is taken from pcap file relative to pwd of the script you run
+
+
+file: `stl/udp_1pkt_pcap_relative_path.py`
+
+
+[source,python]
+----
+
+ def get_streams (self, direction = 0):
+ return [STLStream(packet = STLPktBuilder(pkt ="yaml/udp_64B_no_crc.pcap",
+ path_relative_to_profile = True), <1>
+ mode = STLTXCont(pps=10)) ]
+
+----
+<1> packet is taken from pcap file relative to *profile* file location
+
+==== Tutorial 14: Pcap file to many streams
+
+The following example demonstrates a way to load pcap with *number* of packets and for each packet create a stream with burst of 1.
+
+file: `stl/pcap.py`
+
+[source,python]
+----
+ def get_streams (self,
+ ipg_usec = 10.0, <1>
+ loop_count = 1): <2>
+
+ profile = STLProfile.load_pcap(self.pcap_file, <3>
+ ipg_usec = ipg_usec,
+ loop_count = loop_count)
+----
+<1> The inter stream gap in usec
+<2> How many times to loop
+<3> the pcap file
+
+
+image::images/stl_tut_pcap_file1.png[title="pcap file",align="left",width=300, link="images/stl_tut_pcap_file1.png"]
+
+This figure illustrates how the streams look like for pcap file with 3 packet.
+* Each stream is configured to burst with one packet
+* Each stream point to the next stream.
+* The last stream point to the first with action_loop=loop_count in case it was asked (>1)
+The profile will run on only one DP thread because it has burst with one packet (see Split example)
+
+Running this example
+
+[source,bash]
+----
+./stl-sim -f stl/pcap.py --yaml
+----
+
+will give this
+
+[source,python]
+----
+csi-kiwi-02]> ./stl-sim -f stl/pcap.py --yaml
+- name: 1
+ next: 2 <1>
+ stream:
+ action_count: 0
+ enabled: true
+ flags: 0
+ isg: 10.0
+ mode:
+ percentage: 100
+ total_pkts: 1
+ type: single_burst
+ packet:
+ meta: ''
+ rx_stats:
+ enabled: false
+ self_start: true
+ vm:
+ instructions: []
+ split_by_var: ''
+- name: 2
+ next: 3
+ stream:
+ action_count: 0
+ enabled: true
+ flags: 0
+ isg: 10.0
+ mode:
+ percentage: 100
+ total_pkts: 1
+ type: single_burst
+ packet:
+ meta: ''
+ rx_stats:
+ enabled: false
+ self_start: false
+ vm:
+ instructions: []
+ split_by_var: ''
+- name: 3
+ next: 4
+ stream:
+ action_count: 0
+ enabled: true
+ flags: 0
+ isg: 10.0
+ mode:
+ percentage: 100
+ total_pkts: 1
+ type: single_burst
+ packet:
+ meta: ''
+ rx_stats:
+ enabled: false
+ self_start: false
+ vm:
+ instructions: []
+ split_by_var: ''
+- name: 4
+ next: 5
+ stream:
+ action_count: 0
+ enabled: true
+ flags: 0
+ isg: 10.0
+ mode:
+ percentage: 100
+ total_pkts: 1
+ type: single_burst
+ packet:
+ meta: ''
+ rx_stats:
+ enabled: false
+ self_start: false
+ vm:
+ instructions: []
+ split_by_var: ''
+- name: 5
+ next: 1 <2>
+ stream:
+ action_count: 1 <3>
+ enabled: true
+ flags: 0
+ isg: 10.0
+ mode:
+ percentage: 100
+ total_pkts: 1
+ type: single_burst
+ packet:
+ meta: ''
+ rx_stats:
+ enabled: false
+ self_start: false <4>
+ vm:
+ instructions: []
+ split_by_var: ''
+----
+<1> each stream point to the next stream
+<2> last point to the first
+<3> the number of loop is given in `action_count: 1`
+<4> self_start is disabled for all the streams except the first one
+
+
+==== Tutorial 15: Pcap file to many streams and Field Engine
+
+The following example demonstrates a way to load pcap file to many stream and attach to each stream a Field Engine program.
+For example change the IP.src of all the streams to a random number
+
+file: `stl/pcap_with_vm.py`
+
+[source,python]
+----
+
+ def create_vm (self, ip_src_range, ip_dst_range):
+ if not ip_src_range and not ip_dst_range:
+ return None
+
+ # until the feature of offsets will be fixed for PCAP use hard coded offsets
+
+ vm = []
+
+ if ip_src_range:
+ vm += [STLVmFlowVar(name="src",
+ min_value = ip_src_range['start'],
+ max_value = ip_src_range['end'],
+ size = 4, op = "inc"),
+ #STLVmWrFlowVar(fv_name="src",pkt_offset= "IP.src")
+ STLVmWrFlowVar(fv_name="src",pkt_offset = 26)
+ ]
+
+ if ip_dst_range:
+ vm += [STLVmFlowVar(name="dst",
+ min_value = ip_dst_range['start'],
+ max_value = ip_dst_range['end'],
+ size = 4, op = "inc"),
+
+ #STLVmWrFlowVar(fv_name="dst",pkt_offset= "IP.dst")
+ STLVmWrFlowVar(fv_name="dst",pkt_offset = 30)
+ ]
+
+ vm += [#STLVmFixIpv4(offset = "IP")
+ STLVmFixIpv4(offset = 14)
+ ]
+
+ return vm
+
+
+ def get_streams (self,
+ ipg_usec = 10.0,
+ loop_count = 5,
+ ip_src_range = None,
+ ip_dst_range = {'start' : '10.0.0.1',
+ 'end': '10.0.0.254'}):
+
+ vm = self.create_vm(ip_src_range, ip_dst_range) <1>
+ profile = STLProfile.load_pcap(self.pcap_file,
+ ipg_usec = ipg_usec,
+ loop_count = loop_count,
+ vm = vm) <2>
+
+ return profile.get_streams()
+----
+<1> Create Field Engine program,
+<2> Apply to all the packets -> convert to streams
+
+.Output
+[format="csv",cols="1^,2^,1^", options="header",width="40%"]
+|=================
+pkt, IPv4 , flow
+ 1 , 10.0.0.1, 1
+ 2 , 10.0.0.1, 1
+ 3 , 10.0.0.1, 1
+ 4 , 10.0.0.1, 1
+ 5 , 10.0.0.1, 1
+ 6 , 10.0.0.1, 1
+ 7 , 10.0.0.2, 2
+ 8 , 10.0.0.2, 2
+ 9 , 10.0.0.2, 2
+ 10 , 10.0.0.2,2
+ 11 , 10.0.0.2,2
+ 12 , 10.0.0.2,2
+|=================
+
+
+==== Tutorial 16: Source and Destination MAC address
+
+Each TRex port has a source MAC configure and destination MAC (DUT) configured in /etc/trex_cfg.yaml
+By default those MAC (source and destination) is taken
+In case a user configures a source or destination MAC explicitly this MAC will override
+
+
+.MAC addrees
+[format="csv",cols="2^,2^,2^", options="header",width="40%"]
+|=================
+Scapy , Source MAC,Destination MAC
+Ether() , trex_cfg,trex_cfg
+Ether(src="00:bb:12:34:56:01"),"00:bb:12:34:56:01",trex_cfg
+Ether(dst="00:bb:12:34:56:01"),trex_cfg,"00:bb:12:34:56:01"
+|=================
+
+For example
+
+file: `stl/udp_1pkt_1mac_override.py`
+
+
+[source,python]
+----
+ def create_stream (self):
+
+ base_pkt = Ether(src="00:bb:12:34:56:01")/ <1>
+ IP(src="16.0.0.1",dst="48.0.0.1")/
+ UDP(dport=12,sport=1025)
+----
+<1> Don't take TRex port src interface MAC
+
+==== Tutorial 17: Teredo tunnel (IPv6 over IPv4)
+
+The following example demonstrates creating IPv6 packet inside IPv4 packet and create a range of IPs
+
+file: `stl/udp_1pkt_ipv6_in_ipv4.py`
+
+[source,python]
+----
+ def create_stream (self):
+ # Teredo Ipv6 over Ipv4
+ pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/
+ UDP(dport=3797,sport=3544)/
+ IPv6(dst="2001:0:4137:9350:8000:f12a:b9c8:2815",
+ src="2001:4860:0:2001::68")/
+ UDP(dport=12,sport=1025)/ICMPv6Unknown()
+
+ vm = CTRexScRaw( [
+ # tuple gen for inner Ipv6
+ STLVmTupleGen ( ip_min="16.0.0.1", ip_max="16.0.0.2",
+ port_min=1025, port_max=65535,
+ name="tuple"), <1>
+
+ STLVmWrFlowVar (fv_name="tuple.ip",
+ pkt_offset= "IPv6.src",
+ offset_fixup=12 ), <2>
+ STLVmWrFlowVar (fv_name="tuple.port",
+ pkt_offset= "UDP:1.sport" ) <3>
+ ]
+ )
+----
+<1> Define stream struct name tuple. it has tuple.ip, tuple.port variables
+<2> Write stream tuple.ip variable into IPv6.src offset and fixup with 12 bytes (only 4 LSB)
+<3> Write stream tuple.port variable into the second UDP header
diff --git a/images/Thumbs.db b/images/Thumbs.db
index 309dd91e..175b366f 100755
--- a/images/Thumbs.db
+++ b/images/Thumbs.db
Binary files differ
diff --git a/images/stl_tut_pcap_file1.png b/images/stl_tut_pcap_file1.png
new file mode 100644
index 00000000..1e4be64e
--- /dev/null
+++ b/images/stl_tut_pcap_file1.png
Binary files differ