TRex
TRexはCisco Systemsが提供する Open Source な Traffic Generator. ライセンスはApache 2.0 .
Networkの検証での切り替わり断時間などの評価を簡易でやるのならまずはPingになるけれど、
- そもそも大量のTrafficを印加できない
- そもそもL3までしか見れない
- そもそもICMP。Statefulな動きは見えない。
- 片方向の断を測定できない
- 通信断時間の測定が難しい(大体秒間10回くらいが限界)
- 遅延測定もラウンドトリップの時間になる
といった限界があり、プロトコルの動作を追いかけるような検証をやろうとすると物足りない。で、Traffic GeneratorというとIXIA や Spirent が有名だけれども、なにせ高い。あっても、ほかの人とリソースの奪い合いになる。そもそも個人では遊べない。
自分の好きなようにTrafficを印加して遊びたい検証したい、と思って調べて目についたのがTRex。 NATへのTraffic印加を一つの目標として調べてみる。
環境構築
- ベース環境はGNS3で、検証実施時に最新版のVersion 2.1.21 を使用。今回利用したGNS3 の VM は ESXi 6.7に構築したUbuntu 18.04 LTS. その上でKVMを使ってUbuntu 16.04を動かし、そこでTrexを動作させる。屋上屋を立てている感じ。オーバーヘッドは酷い。でも、負荷試験をしたいわけではない。Traffic性能の劣化は、やむをえないものとして割り切った。
- TRexサーバにはUbuntu16.04.6 LTSを使用。 18.10で試したら起動しなかった。Ubuntuでは16.04では一部動かない機能があり、14.04が推奨とのこと。ただ、検証した時点でUbuntu 14.04 LTSはすでにサポート終了で選択肢としてあり得ないため、16.04で検証を実施(CentOSでやればよいのだけれど、使い慣れたUbuntuで構築することにした)。
TRexサーバ
- TRexサーバとするUbuntuはここからダウンロード 。
- TRexはGitで公開されている。検証開始時のLatestであったVersion 2.60を使用
物理構成
TRexサーバに割り当てるCPUコアとNICへの条件。
ポイント | 最低条件 |
---|---|
CPU | 3コア以上 |
NIC | 3枚以上 |
- CPU
- 2コア以下だと、TRexの初期設定で怒られる。
1 Interfaceに対して最低1コアを割り当てる必要がある。 - NIC
- TypeにはGNS上の設定画面からParavirtualized Network I/O (vitio-network-pci)を選択。Traffic印加するInterfaceはDPDKでTRexに占有され、SSH接続などが使えなくなる。このため、O&M用とTraffic印加用で分けておく必要がある。
O&M用NICはInternetに接続し、Local PC側からSSHでログインできるようにする。
インストール
必要なツールの用意
sudo apt install linux-headers-`uname -r`
sudo apt install build-essential
コードのダウンロードとインストール
TRexはパッケージがあるわけではない。ダウンロードしてセットアップする必要がある。ここから最新版をダウンロードする。
sudo mkdir -p /opt/trex
cd /opt/trex
sudo wget --no-cache https://trex-tgn.cisco.com/trex/release/latest
tar xvf ./latest.tar
ls -l
初期設定~トラフィック印加
初期状態の確認
まずは利用できるPortを確認する。
sudo ./dpdk_setup_ports.py -s
Network devices using DPDK-compatible driver
============================================
<none>
Network devices using kernel driver
===================================
0000:00:03.0 'Virtio network device' if=ens3 drv=virtio-pci unused=igb_uio,vfio-pci,uio_pci_generic *Active*
0000:00:04.0 'Virtio network device' if=ens4 drv=virtio-pci unused=igb_uio,vfio-pci,uio_pci_generic
0000:00:05.0 'Virtio network device' if=ens5 drv=virtio-pci unused=igb_uio,vfio-pci,uio_pci_generic
0000:00:06.0 'Virtio network device' if=ens6 drv=virtio-pci unused=igb_uio,vfio-pci,uio_pci_generic
Other network devices
=====================
<none>
初期状態であるため、すべての Interface はカーネルドライバで動いている。
Activeが付いている Interface は SSH で利用されていることを示す。この Port はTRexでのTraffic印加には利用できない。
ここでは、ens5 (PCI 00:05) と ens6 (PCI 00:06)を利用することにする。
基本設定ファイルの作成
TRexでの基本設定はデフォルトでは、/etc/trex_cfg.yaml が利用される。
このファイルは対話的に初期設定可能
sudo ./dpdk_setup_ports.py -i
By default, IP based configuration file will be created. Do you want to use MAC based config? (y/N) N
+----+------+---------+-------------------+-----------------------+------------+----------+----------+
| ID | NUMA | PCI | MAC | Name | Driver | Linux IF | Active |
+====+======+=========+===================+=======================+============+==========+==========+
| 0 | -1 | 00:03.0 | 0c:b0:8c:22:90:00 | Virtio network device | virtio-pci | ens3 | *Active* |
+----+------+---------+-------------------+-----------------------+------------+----------+----------+
| 1 | -1 | 00:04.0 | 0c:b0:8c:22:90:01 | Virtio network device | virtio-pci | ens4 | |
+----+------+---------+-------------------+-----------------------+------------+----------+----------+
| 2 | -1 | 00:05.0 | 0c:b0:8c:22:90:02 | Virtio network device | virtio-pci | ens5 | |
+----+------+---------+-------------------+-----------------------+------------+----------+----------+
| 3 | -1 | 00:06.0 | 0c:b0:8c:22:90:03 | Virtio network device | virtio-pci | ens6 | |
+----+------+---------+-------------------+-----------------------+------------+----------+----------+
Please choose even number of interfaces from the list above, either by ID , PCI or Linux IF
Stateful will use order of interfaces: Client1 Server1 Client2 Server2 etc. for flows.
Stateless can be in any order.
Enter list of interfaces separated by space (for example: 1 3) : 2 3
For interface 2, assuming loopback to it's dual interface 3.
Putting IP 1.1.1.1, default gw 2.2.2.2 Change it?(y/N).n
For interface 3, assuming loopback to it's dual interface 2.
Putting IP 2.2.2.2, default gw 1.1.1.1 Change it?(y/N).n
Print preview of generated config? (Y/n)y
### Config file generated by dpdk_setup_ports.py ###
- version: 2
interfaces: ['00:05.0', '00:06.0']
port_info:
- 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: 1
dual_if:
- socket: 0
threads: [2]
Save the config to file? (Y/n)Y
初期設定はこれで完了。
トラフィック印加
印加するトラフィックのシナリオファイルのサンプルは /opt/trex/v2.60/cap2配下にある。
設定のyamlファイルと、テンプレートとなるPCAPファイルがあるため、これを利用して印加テストを行える。
sudo ./t-rex-64 -f ./cap2/dns.yaml -d 10
(10秒経過後)
==================
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 : 0
ibytes : 0
Tx : 300.99 bps
port : 1
------------
opackets : 9
obytes : 837
ipackets : 21
ibytes : 1904
Tx : 363.54 bps
Cpu Utilization : 0.1 %
Platform_factor : 1.0
Total-Tx : 664.53 bps
Total-Rx : 664.75 bps
Total-PPS : 0.98 pps
Total-CPS : 0.49 cps
Expected-PPS : 2.00 pps
Expected-CPS : 1.00 cps
Expected-BPS : 1.36 Kbps
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
Warning : number of rx packets exceeds 101% of tx packets!
Total-tx-bytes : 1530 bytes
Total-tx-sw-bytes : 0 bytes
Total-rx-bytes : 1904 byte
Total-tx-pkt : 18 pkts
Total-rx-pkt : 21 pkts
Total-sw-tx-pkt : 0 pkts
Total-sw-err : 0 pkts
Total ARP sent : 4 pkts
Total ARP received : 2 pkts
-dで指定した秒数を経過すると、その統計情報が得られる。
t-rex-64コマンドのオプション
オプション | 意味 |
---|---|
-f [filename] | シナリオを定義したyamlファイル |
-c | Portあたりに割り当てるCPU Core数 |
--astf | Advanced Stateful モードの有効化。 これを有効にする際は、Profileがpython形式で書かれる必要がある |
-d | シナリオの実行期間。デフォルトは3600秒 |
-l | 各InterfaceでのPPS |
-m | 基本 Rate を何倍して Traffic を印加するか |
--learn-mode [1-3] | NAT環境で使用。DUTで実施されたNATを学習する |
NATオプション
NAT環境での試験はASTFモードの使用が推奨されており、かなり前から --learn-mode オプションは非推奨になっていた。整理すると意味は以下。
モード | 概要 |
---|---|
1 | TCPフロー: 最初のTCP SYNパケットに埋め込まれたACKで識別 UDPフロー: フローの最初のパケットのIdentificationフィールドで識別 このモードはFirewall がある環境でのNATの検証のために開発された。モード2ではだいたい動かない。 このモードではDUTにて行われるTCPシーケンスのランダムに追随して学習する。 Trexは両方向の接続のシーケンスナンバーのランダム化に対応する。 |
2 | 特別なIPv4オプションヘッダ(0x10)を埋め込むことでフロー情報を識別する。 このヘッダはフローの最初のパケットにだけ入れられる。このモードはDUTが IPオプションをドロップさせる場合には動作しない(Cisco ASAとか) |
3 | モード1と同様だが、モード3ではTrexは Server → Client方向のシーケンス番号ランダム化を学習しない。 このモードはモード1と比較してCPS(Connections Per Second)が向上する。しかしFirewallがある場合、モード1のCPS性能が妥当なものになる。 |
NAT装置を挟んで試した場合、--learn-mode 1 を入れることで戻りパケットがyamlファイルで指定されたものではなく、実際にNAPTされて受け取ったPacketに対して応答するようになる。
雑事
Traffic印加をしている最中、Wiresharkでは印加したPortをキャプチャできない。これはDPDKでKernel空間がバイパスされるため。知らなかった最初は驚いた。
arp 解決
TRex は ARP Request を投げても反応しない。どうやっているかというと、試験トラフィックを流す際、最初にG-ARPを投げている。相手先のARP Table にARP Entry がない状態で受けてもARP Tableに乗るのだろうかと思ったのだが、VyOSで試した感じだと乗ってくれていた。