0%

TRex 教程

TRex 是基于 DPDK 的一个开源、低成本的流量生成器,支持生成 L3~7 流量,提供有状态、无状态两种模式。

TRex 架构

TRex 之所以能够产生相比其他流量生成器更大的流量,原因是使用了 DPDK。

传统的工具,比如 iperf,如果想要生成包,需要走 Linux 内核,经过绑定的 socket API、 TCP/IP 栈、设备驱动这样一套完整的流程,最终才能到达物理网卡。

而 TRex 使用 DPDK,这意味着它可以绕过 Linux 内核态协议栈,直接控制物理网卡,应用单独实现包处理过程,不用经历内核/用户态切换、内存拷贝、冗余的 TCP/IP 协议栈等步骤。

TRex架构

安装

  1. 进入安装目录,比如 /opt/trex

  2. 下载 TRex 压缩包

    1
    wget --no-cache --no-check-certificate https://trex-tgn.cisco.com/trex/release/latest
  3. 解压 TRex 压缩包

    1
    tar -xzvf latest

网卡配置

TRex 需要 DPDK 绑定网卡,通过 TRex 提供的脚本可以查看或修改网卡

查看网卡状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@ubuntu:/opt/trex/v3.05# ./dpdk_setup_ports.py -s

Network devices using DPDK-compatible driver
============================================
<none>

Network devices using kernel driver
===================================
0000:02:01.0 '82545EM Gigabit Ethernet Controller (Copper)' if=ens33 drv=e1000 unused=igb_uio,vfio-pci,uio_pci_generic *Active*
0000:02:05.0 '82545EM Gigabit Ethernet Controller (Copper)' if=ens37 drv=e1000 unused=igb_uio,vfio-pci,uio_pci_generic
0000:02:06.0 '82545EM Gigabit Ethernet Controller (Copper)' if=ens38 drv=e1000 unused=igb_uio,vfio-pci,uio_pci_generic

Other network devices
=====================
<none>
  • 当前三张网卡都绑定在 kernel 下,DPDK 未绑定网卡
  • Active的网卡为 ssh 使用的管理网卡,不可以设置在 TRex 配置文件中,分配给 DPDK

在运行 TRex 时,会自动将 TRex 配置文件中interfaces网卡绑定 DPDK

TRex 配置

官方文档

Yaml 格式配置文件,用来配置 TRex 服务器,包括:

  • 每个网卡的源、目的 IP 和 MAC 地址
  • 屏蔽网卡,保证 TRex 不使用管理网卡作为流量网卡

在运行 TRex 服务器时,通过 --cfg配置,如果未设置,则使用默认路径/etc/trex_cfg.yaml,TRex 提供了一些示例 TRex 配置文件在 $TREX_ROOT/cfg

配置项

  • port_limit:(必选)网卡数量,绑定 DPDK 的网卡数量,必须和interfaces中的网卡数量对应
  • version:(必选)必须是 2
  • interfaces:(必选)TRex 使用的网卡 PCI,顺序有意义,对应port_info中的顺序
    • 必须是偶数个,成对存在,按顺序分别为 clinet 和 server 网卡
    • 如是奇数个网卡,可以使用dummy填充,但每对网卡对必须有非dummy 的网卡
    • 通过 ./dpdk_setup_ports.py -s 查看网卡 PCI
    • 不能填入 ssh 使用的网卡
  • c:分配给每个网卡对的线程数,会被运行时的命令行参数-c覆盖
  • services_core:(非必选)用来跑 scapy、PyBird、Emu 这些 service 的核,如果未设置,则会采用以下逻辑
    • low_end 开启,使用 low_end_core
    • low_end 未开启,使用 master_thread_id
    • low_end 未开启,使用 master_thread_id,使用 core 0
  • port_info:(必选)
    • 网卡信息,每项按顺序对应interfaces中的网卡
    • (必选)对于每张网卡,都必须要设置目的 MAC 地址,有两种设置方式:
      • 直接设置dest_mac
      • 设置default_gw,在未设置dest_mac时,TRex 会对default_gw这个 IP 发送 ARP 请求,使用回复的结果作为目的 MAC 地址
    • dest_mac:目的 MAC 地址,该网卡打流将打往这个 MAC 地址
    • default_gw:默认网关,用于生成目的 MAC 地址
    • src_mac:(非必选)该网卡生成流量的源 MAC 地址,如果未设置,将使用该网卡的 MAC 地址作为源 MAC 地址
  • platform:(非必选)
    • master_thread_id:控制线程使用的线程 id
    • latency_thread_id:RX 线程使用的线程 id,用来计算延迟
    • dual_if
      • interfaces中的网卡对一一对应
      • socket:该网卡对被分配的 NUMA 节点
      • threads:该网卡对用来发包的线程 id

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- port_limit      : 2
version : 2
#List of interfaces. Change to suit your setup. Use ./dpdk_setup_ports.py -s to see available options
interfaces : ["03:00.0","03:00.1"]
port_info : # Port IPs. Change to suit your needs. In case of loopback, you can leave as is.
- ip : 1.1.1.1
default_gw : 2.2.2.2
- ip : 2.2.2.2
default_gw : 1.1.1.1
platform :
master_thread_id : 0
latency_thread_id : 7
dual_if :
- socket : 0
threads : [1,2,3,4,5,6]

Traffic 模版配置

官方文档

Stateful 模式时需配置 Traffic 模版,用以生成流量。

运行 TRex 时,通过配置-f <file>参数来设置流量模版 yaml 文件。

配置项

  • duration:测试持续时间,即打多久的流量,单位 s。会被运行时的命令行参数-d覆盖

  • generator

    • 生成流量的 IP 依据clients_startclients_endservers_startservers_enddual_port_mask

      • clients_startclients_endservers_startservers_end 分别设置了 client 和 server 的 IP 池,该范围即限定了 client 和 server 的总数

      • dual_port_mask 设置网卡对的偏移量,使得可以为每个网卡对配置不同的静态路由,如需要发送同样的范围,则设置为0.0.0.0

      • 下面示例中,如果 TRex 配置设置了两个网卡对(4张网卡),则分配 IP 如下

        • ```powershell
          port pair-0 (0,1) —> C (16.0.0.1-16.0.0.128 ) <-> S( 48.0.0.1 - 48.0.0.128)
          port pair-1 (2,3) —> C (17.0.0.129-17.0.0.255 ) <-> S( 49.0.0.129 - 49.0.0.255) + mask (“1.0.0.0”)
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10

          - client 和 server 数量即为设置范围的数量,都是 255,不会因为网卡数量而变化

          - 网卡对偏移量为`dual_port_mask`,第二对网卡对比第一对偏移 `1.0.0.0`

          - 如果 `dual_port_mask` 设置为`0.0.0.0`,依旧设置 TRex 配置两个网卡对(4张网卡),则分配 IP 如下

          - ```powershell
          port pair-0 (0,1) --> C (16.0.0.1-16.0.0.128 ) <-> S( 48.0.0.1 - 48.0.0.128)
          port pair-1 (2,3) --> C (16.0.0.129-16.0.0.255 ) <-> S( 48.0.0.129 - 48.0.0.255)
      • 生成流量的 IP 范围

        • client IP 范围:网卡对中的 client 发送流量的源 IP、网卡对中的 server 发送流量的目的 IP
        • server IP 范围:网卡对中的 client 发送流量的目的 IP、网卡对中的 server 发送流量的源 IP
    • clients_per_gb:已废弃

    • min_clients:已废弃

    • cap_info

      • name:pcap文件,流量模版文件
        • 只允许单数据流
        • 生成流量时使用该流量模版,并将 IP 替换为 client 和 server 的 IP 池中的 IP
      • cps:每秒连接数,实际连接数需乘以运行时设置的 -m
      • ipg:报文间隙,单位 ms
      • rtt:设置与ipg相同的值
      • w:定义一个burst中该template生成几个flow,默认为 1

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- duration : 10.0
generator :
distribution : "seq"
clients_start : "16.0.0.1"
clients_end : "16.0.0.255"
servers_start : "48.0.0.1"
servers_end : "48.0.0.255"
clients_per_gb : 201
min_clients : 101
dual_port_mask : "1.0.0.0"
tcp_aging : 1
udp_aging : 1
cap_info :
- name: cap2/dns.pcap
cps : 1.0
ipg : 10000
rtt : 10000
w : 1

运行命令行参数

通过./t-rex-64运行 TRex 服务器,添加参数设置有状态/无状态以及其他选项

1
./t-rex-64 [mode] <options>

使用 ./t-rex-64 -h查看细节

设置 mode:

  • -f <file>:运行有状态模式,需设置流量模版 yaml 文件
  • -i:运行无状态模式

可选参数:

  • --cfg <file>:TRex 配置文件,如果未设置,则使用默认路径/etc/trex_cfg.yaml
  • -c <num>:给每个网卡对分配的线程数,会覆盖 TRex 配置中的c
  • -m <num>:流量放大倍数,生成基础流量大小乘以这个倍数的流量
  • -d:持续时间,单位 s,默认3600s

Stateful 示例

使用下面测试交换机性能示例来理解 Stateful 运行模式。

该示例配置有一台 TRex 机器和一台交换机。

  • Trex 机器有两张网卡绑定 DPDK,port 1 作为模拟 client 的网卡,port 2 作为模拟 server 的网卡
  • 交换机配置有两条静态路由,如下图所示,可以将16.0.0.0/8的包传到 TRex 的 port 0,将48.0.0.0/8的包传到 TRex 的 port 1

TRex-Stateful示例

根据下面配置,运行 TRex 有状态模式 ./t-rex-64 -f traffic.yaml,打流流程如下

  1. Port 0 发包
    • TRex 配置中的interfaces网卡对中的前一张网卡 port 0 作为 client 发包
    • 发包使用 Traffic 模版配置中的 cap_info 中的第一个包,也就是其中的 DNS query 请求
    • 发送的包中的源目的 IP 会随机被替换为 Traffic 模版中的配置的范围,其中,源 IP 范围 16.0.0.1(clients_start) ~ 16.0.0.255(clients_end),目的 IP 范围 48.0.0.1(servers_start) ~ 48.0.255.255(servers_end)
    • 包被发往 TRex 配置中设置的 port 0 网卡的目的 MAC 地址 dest_mac,本示例即通过默认网卡 default_gw 得到的目的 MAC 地址
  2. Port 1 收包
    • 交换机 port 2 收到 TRex 机器 port 1 发来的目的 IP 为48.0.0.1~ 48.0.255.255的包,根据路由,将其通过 port 3 转发到 TRex 机器的 port 1
    • TRex 配置中的interfaces网卡对中的后一张网卡 port 1 作为 server 收包
  3. Port 1 发包
    • TRex 配置中的interfaces网卡对中的后一张网卡 port 1 作为 server 发包
    • 发包使用 Traffic 模版配置中的 cap_info 中的第二个包,也就是其中的 DNS response 回复
    • 发送的包中的源目的 IP 会随机被替换为 Traffic 模版中的配置的范围,其中,源 IP 范围48.0.0.1(servers_start) ~ 48.0.255.255(servers_end),目的 IP 范围 16.0.0.1(clients_start) ~ 16.0.0.255(clients_end)
    • 包被发往 TRex 配置中设置的 port 1 网卡的目的 MAC 地址 dest_mac,本示例即通过默认网卡 default_gw 得到的目的 MAC 地址
  4. Port 0 收包
    • 交换机 port 3 收到 TRex 机器 port 2 发来的目的 IP 为16.0.0.1 ~ 16.0.0.255的包,根据路由,将其通过 port 2 转发到 TRex 机器的 port 0
    • TRex 配置中的interfaces网卡对中的后一张网卡 port 0 作为 server 收包

TRex 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- port_limit : 2  #对应下面的网卡数量
version : 2
interfaces : ["06:00.0","06:00.1"] #port0、port1的PCI,网卡对,前一个为模拟client的网卡,后一个为模拟server的网卡
c : 6 #对应下面的每对网卡几个发包threads
port_info :
#port0的配置
- ip : 11.11.11.11 #port0的IP
default_gw : 11.11.11.1 #port2(port0的网关)的IP,由此推出port0网卡发包时的目的MAC地址
#port1的配置
- ip : 12.12.12.12 #port1的IP
default_gw : 12.12.12.1 #port3(port1的网关)的IP,由此推出port1网卡发包时的目的MAC地址
platform :
master_thread_id : 0
latency_thread_id : 7
dual_if :
- socket : 0
threads : [1,2,3,4,5,6]

Traffic 模版配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- duration : 10.0
generator :
distribution : "seq"
clients_start : "16.0.0.1"
clients_end : "16.0.0.255"
servers_start : "48.0.0.1"
servers_end : "48.0.255.255"
clients_per_gb : 201
min_clients : 101
dual_port_mask : "1.0.0.0"
tcp_aging : 1
udp_aging : 1
cap_info :
- name: cap2/dns.pcap
cps : 1.0
ipg : 10000
rtt : 10000
w : 1

pcap 包模版

1
2
3
4
root@ubuntu:/opt/trex/v3.05# tcpdump -r cap2/dns.pcap
reading from file cap2/dns.pcap, link-type EN10MB (Ethernet)
-7:00:00.000000 IP 21.0.0.2.1030 > 22.0.0.12.domain: 48 A? www.cisco.com. (31)
-7:00:00.020944 IP 22.0.0.12.domain > 21.0.0.2.1030: 48* 1/0/0 A 100.100.100.100 (47)

示例

Stateful

在 Linux 虚拟机上演示 Stateful 模式简单示例,直接将流量从 ens37 打到 ens38,再从 ens38 回复到 ens37,配置如下

初始网卡信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@ubuntu:/opt/trex/v3.05# ./dpdk_setup_ports.py -s

Network devices using DPDK-compatible driver
============================================
<none>

Network devices using kernel driver
===================================
0000:02:01.0 '82545EM Gigabit Ethernet Controller (Copper)' if=ens33 drv=e1000 unused=igb_uio,vfio-pci,uio_pci_generic *Active*
0000:02:05.0 '82545EM Gigabit Ethernet Controller (Copper)' if=ens37 drv=e1000 unused=igb_uio,vfio-pci,uio_pci_generic
0000:02:06.0 '82545EM Gigabit Ethernet Controller (Copper)' if=ens38 drv=e1000 unused=igb_uio,vfio-pci,uio_pci_generic

Other network devices
=====================
<none>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
root@ubuntu:/opt/trex/v3.05# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:f6:9c:9a brd ff:ff:ff:ff:ff:ff
altname enp2s1
inet 192.168.0.106/24 brd 192.168.0.255 scope global dynamic noprefixroute ens33
valid_lft 6304sec preferred_lft 6304sec
inet6 fe80::dbd1:95a:915f:65a7/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:f6:9c:a4 brd ff:ff:ff:ff:ff:ff
altname enp2s5
inet 192.168.45.137/24 brd 192.168.45.255 scope global dynamic noprefixroute ens37
valid_lft 904sec preferred_lft 904sec
inet6 fe80::205c:eff4:8197:d72f/64 scope link noprefixroute
valid_lft forever preferred_lft forever
4: ens38: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:f6:9c:ae brd ff:ff:ff:ff:ff:ff
altname enp2s6
inet 192.168.45.138/24 brd 192.168.45.255 scope global dynamic noprefixroute ens38
valid_lft 903sec preferred_lft 903sec
inet6 fe80::99b1:de77:f189:6869/64 scope link noprefixroute
valid_lft forever preferred_lft forever

TRex 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- port_limit      : 2
version : 2
interfaces : ["02:05.0","02:06.0"]
port_info :
- ip : 192.168.45.137
dest_mac : 00:0c:29:f6:9c:ae
- ip : 192.168.45.138
dest_mac : 00:0c:29:f6:9c:a4
platform :
master_thread_id : 0
latency_thread_id : 1
dual_if :
- socket : 0
threads : [2]

Traffic 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- duration : 10.0
generator :
distribution : "seq"
clients_start : "16.0.0.1"
clients_end : "16.0.0.255"
servers_start : "48.0.0.1"
servers_end : "48.0.0.255"
clients_per_gb : 201
min_clients : 101
dual_port_mask : "1.0.0.0"
tcp_aging : 1
udp_aging : 1
cap_info :
- name: cap2/dns.pcap
cps : 1.0
ipg : 10000
rtt : 10000
w : 1

运行

1
./t-rex-64 -f /opt/trex/config/traffic.yaml -d 10

运行过程中,实时状态显示如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-Per port stats table  #两张网卡当前的状态
ports | 0 | 1
-----------------------------------------------------------------------------------------
opackets | 2 | 2 #当前总发包数
obytes | 154 | 186 #当前总发包比特
ipackets | 2 | 2 #当前总收包数
ibytes | 186 | 154 #当前总收包比特
ierrors | 0 | 0
oerrors | 0 | 0
Tx Bw | 282.57 bps | 341.28 bps

-Global stats enabled
Cpu Utilization : 0.2 % 0.0 Gb/core #CPU占用率
Platform_factor : 1.0
Total-Tx : 623.85 bps #实际发包 byte per second
Total-Rx : 623.85 bps #实际收包 byte per second
Total-PPS : 0.92 pps #实际 packet per second
Total-CPS : 0.46 cps #实际 connect per second

Expected-PPS : 2.00 pps #期望 packet per second
Expected-CPS : 1.00 cps #期望 connect per second
Expected-BPS : 1.36 Kbps #期望 byte per second

# Client 数量
Active-flows : 0 Clients : 255 Socket-util : 0.0000 %
# Server 数量
Open-flows : 2 Servers : 255 Socket : 2 Socket/Clients : 0.0
drop-rate : 0.00 bps #丢包率
current time : 3.9 sec #已测试时间
test duration : 6.1 sec #剩余测试时间

最终结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 ==================
interface sum
==================
------------------------
per core stats core id : 1
------------------------
------------------------
per core per if stats id : 1
------------------------
port 0, queue id :0 - client
----------------------------
port 1, queue id :0 - server
----------------------------
==================
generators
==================


normal
-------------
min_delta : 10 usec
cnt : 0
high_cnt : 0
max_d_time : 0 usec
sliding_average : 0 usec
precent : -nan %
histogram
-----------
m_total_bytes : 1.49 Kbytes
m_total_pkt : 18.00 pkt
m_total_open_flows : 9.00 flows
m_total_pkt : 18
m_total_open_flows : 9
m_total_close_flows : 9
m_total_bytes : 1530
---------------
port : 0
------------
opackets : 9
obytes : 693
ipackets : 9
ibytes : 837
Tx : 290.02 bps
port : 1
------------
opackets : 9
obytes : 837
ipackets : 9
ibytes : 693
Tx : 350.28 bps
Cpu Utilization : 0.4 % 0.0 Gb/core
Platform_factor : 1.0
Total-Tx : 640.30 bps
Total-Rx : 640.30 bps
Total-PPS : 0.94 pps
Total-CPS : 0.47 cps

Expected-PPS : 2.00 pps
Expected-CPS : 1.00 cps
Expected-BPS : 1.36 Kbps

Active-flows : 0 Clients : 255 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
Total-tx-sw-bytes : 0 bytes
Total-rx-bytes : 1530 byte

Total-tx-pkt : 18 pkts
Total-rx-pkt : 18 pkts
Total-sw-tx-pkt : 0 pkts
Total-sw-err : 0 pkts
Total ARP sent : 2 pkts
Total ARP received : 1 pkts

问题记录

初始化 EAL 环境失败

如运行 TRex 遇到下面 EAL 环境报错,则需设置大页

1
2
3
4
5
6
7
8
9
root@ubuntu:/opt/trex/v3.05# ./t-rex-64 -f /opt/trex/config/traffic.yaml
WARNING: tried to configure 2 hugepages for socket 0, but result is: 1
The ports are bound/configured.
Starting TRex v3.04 please wait ...
EAL: FATAL: Cannot get hugepage information.
EAL: Cannot get hugepage information.
You might need to run ./trex-cfg once
EAL: Error - exiting with code: 1
Cause: Invalid EAL arguments

设置 1024 个 2048kB 大页,即写入 1024 到 hugepages-2048kB 下的 nr_hugepages 文件(初始为 0)

1
2
root@ubuntu:/opt/trex/v3.05# echo 1024 | tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
1024

重新运行,即可正常

参考链接

https://trex-tgn.cisco.com

https://blog.csdn.net/shaoyunzhe/article/details/132344878

https://www.youtube.com/watch?v=ginboH5cCyA