Stateful是一般的发包工具所不具备的一项功能,因为它强烈的依赖于协议栈,而要搭一个协议栈本身就很复杂,并且耗CPU,因此TRex支持stateful可谓相当实用
Stateful指的是网络设备对每条流保存其五元组,TRex通常先录制一条流的一组报文,随后以这组报文为模板,在真正测试的时候,更改其src/dst IP和Port,原本需要协议栈做的事情,通过事先录制的报文而得到,而当这个更改了src/dst IP的报文通过网络设备时仍然被认为是一个有效的连接,因为网络设备并不关心它所接的两端到底是不是真实的设备,它关心的是五元组,server作response关心的是IP的checksum,IP包是否完整,关心的是TCP的seq,是否连续,有没有乱序,关心的是TCP的checksum,而这些包都经过之前的录制已经response了,因此TRex巧妙的跳过了这个回答的过程,因此对于被测网络设备来说它接收到了来自于client的request请求,也收到了来自于server的response,因此虽然TRex自身没有协议栈,却让网络设备有了状态,因此它可以测试L4~L7层的应用,重点是提前录制连接的过程。
stateful支持shell,也支持PythonAPI, 它由一个YAML文件组成,其中包含三部分
vi cap2/dns.yaml
1 - duration : 10.0 #持续时间
2 generator :
3 distribution : "seq" #发包顺序是顺序发
4 clients_start : "16.0.0.1" #client地址池范围
5 clients_end : "16.0.1.255"
6 servers_start : "48.0.0.1" #server地址池范围
7 servers_end : "48.0.0.255"
8 clients_per_gb : 201
9 min_clients : 101
10 dual_port_mask : "1.0.0.0" #成对端口的偏移量
11 tcp_aging : 1
12 udp_aging : 1
13 cap_info :
14 - name: cap2/dns.pcap #包模板
15 cps : 1.0 #每秒一个连接(一组包)
16 ipg : 10000 #client与server包间隔10ms
17 rtt : 10000 #往返时间,必需与ipg相同
18 w : 1 #多少个clinet用同一模板
19 loop: 3 #多少个client循环
DNS example
step 1 设置端口跟DUT相连
vi /etc/trex_yaml
1 - port_limit : 2
2 version : 2
3 #List of interfaces. Change to suit your setup. Use ./dpdk_setup_ports.py -s to
see available options
4 interfaces : ["02:01.0","02:02.0"]
5 port_info : # Port IPs. Change to suit your needs. In case of loopback,
you can leave as is.
6 - ip : 192.168.10.33 虚接口地址
7 default_gw : 192.168.10.168 #DUT X0接口地址
8 - ip : 10.10.10.33 虚接口地址
9 default_gw : 10.10.10.1 #DUT X2接口地址
step 2 录制DNS请求与应答包
可见只有两个包,一个包是query,另一个包是resonse,以这组包作为模板,以IP来辨别发包端口,并相应的修改包中的源目的IP为地址池中的IP
step 3 编写 yaml文件就是cap2/dns.yaml
step 4 配置DUT的路由,使得DUT知道16.0.0.0和48.0.0.0的网段怎么走
step 5 执行发包
./t-rex-64 -f cap2/dns.yaml -m 1 -d 10
step 6 抓包
x2 x0 48.0.0.4 16.0.0.4 IP UDP 53,1024 Forward
- x0 48.0.0.4 16.0.0.4 IP UDP 53,1024 Forward
x0 x2 16.0.0.5 48.0.0.5 IP UDP 1024,53 Forward
- x2 16.0.0.5 48.0.0.5 IP UDP 1024,53 Forward
x2 x0 48.0.0.5 16.0.0.5 IP UDP 53,1024 Forward
- x0 48.0.0.5 16.0.0.5 IP UDP 53,1024 Forward
x0 x2 16.0.0.6 48.0.0.6 IP UDP 1024,53 Forward
- x2 16.0.0.6 48.0.0.6 IP UDP 1024,53 Forward
x2 x0 48.0.0.6 16.0.0.6 IP UDP 53,1024 Forward
- x0 48.0.0.6 16.0.0.6 IP UDP 53,1024 Forward
可见真正的发包把“21.0.0.2”认作client端,由“02:01.0”发送,并用自己的地址池“16.0.0.0"代替
同理把 ”22.0.0.12“认作server端,由”02:02.0“发送,并用自己的地址池”48.0.0.0“代替
step 7 统计
port : 0
------------
opackets : 9 #发出9个query包
obytes : 693 #发出9*77=693字节
ipackets : 9 #收到9个response包
ibytes : 837 #收到9*93=837字节
Tx : 303.71 bps #发送速率
port : 1
------------
opackets : 9 #发出9个response包
obytes : 837 #发出837个字节
ipackets : 9 #收到9个query包
ibytes : 693 #收到673字节
Tx : 366.82 bps
Cpu Utilization : 0.1 % 0.0 Gb/core #CPU利用率,每核速率
Platform_factor : 1.0
Total-Tx : 670.53 bps #发送速率
Total-Rx : 670.53 bps #接收速率
Total-PPS : 0.99 pps #发送速率每秒1个包
Total-CPS : 0.49 cps #每2秒一个连接
Expected-PPS : 2.00 pps
Expected-CPS : 1.00 cps
Expected-BPS : 1.36 Kbps
#有511个client,255个server,开启了9条连接
Active-flows : 0 Clients : 511 Socket-util : 0.0000 %
Open-flows : 9 Servers : 255 Socket : 0 Socket/Clients : 0.0
drop-rate : 0.00 bps #丢包率
summary stats
--------------
Total-pkt-drop : 0 pkts
Total-tx-bytes : 1530 bytes #总发包字节 693+837
Total-tx-sw-bytes : 0 bytes
Total-rx-bytes : 1530 byte #总收包字节 837+693
Total-tx-pkt : 18 pkts #总发包数
Total-rx-pkt : 18 pkts #总收包数
Total-sw-tx-pkt : 0 pkts
Total-sw-err : 0 pkts
Total ARP sent : 4 pkts
Total ARP received : 2 pkts
执行命令常用参数解释
mode is one of:
-f <file> : YAML file with traffic template configuration (Will run TRex in 'stateful' mode)
-i : Run TRex in 'stateless' mode
-c <num>> : 用的CPU核数,跟速率有关系
--cfg <file> : 默认是/etc/trex_cfg.yaml,也可以自定义此次测试用的cfg
-d : 该次测试持续时间
-e : Like -p but src/dst IP will be chosen according to the port (i.e. on client port send all packets with client src and server dest, and vice versa on server port
--ipv6 : 起动IPv6模式
-k <num> : 等待k秒后执行测试,为了相互学习ARP,热启动
-l <rate> : 发送时延包的速率
--l-pkt-mode <0-3> : 发送时延包
0 (default) send SCTP packets
1 Send ICMP request packets
2 Send ICMP requests from client side, and response from server side (for working with firewall)
3 Send ICMP requests with sequence ID 0 from both sides
Rate of zero means no latency check
--learn-mode [1-3] : 启动NAT模式
1 根据收到的第一个包判断是否有变动
2 在IP option选项中加入一个NAT的识别
3 server-client的seq不随机,是固定的,速度比1快,但不够真实
--lm : 哪个端口发流
--lo : 只跑时延测试
-m <num> : 模板中的flow的倍数
-p : Send all flow packets from the same interface (choosed randomly between client ad server ports) without changing their src/dst IP
--vlan : Relevant only for stateless mode with Intel 82599 10G NIC
When configuring flow stat and latency per stream rules, assume all streams uses VLAN
-w <num> : 发流之前端口初始化的时间
参考:
http://trex-tgn.cisco.com/trex/doc/trex_manual.html