Cisco TRex Traffic Generator: Starten des Lasttests von Netzwerkgeräten





Bei der Entwicklung eines anderen Routers haben wir die Netzwerkleistung mit einem nützlichen Open-Source-Produkt getestet - dem Cisco TRex-Verkehrsgenerator. Was ist das für ein Tool? Wie benutzt man es? Und wie kann es für Entwicklungsingenieure nützlich sein? Nachfolgend finden Sie die Antworten auf diese Fragen.



1. Was ist Cisco TRex?



Es ist ein Open-Source-Software-Verkehrsgenerator, der auf Standard-Intel DPDK-basierten Prozessoren ausgeführt wird und Stateful / Stateless-Modi unterstützt. Vergleichsweise einfach und vollständig skalierbar.



Die englischsprachige Dokumentation für dieses Tool ist auf der Website verfügbar .



Mit Trex können Sie verschiedene Arten von Datenverkehr generieren und die Daten beim Empfang analysieren. Arbeiten auf MAC- und IP-Ebene werden unterstützt. Sie können die Größe der Pakete und ihre Anzahl einstellen und die Datenübertragungsrate steuern.



Die Arbeit mit dem Generator ist in einer Linux-Umgebung organisiert.



Einer der wichtigen Unterschiede zwischen dem Trex-Generator ist die Verwendung der DPDK-Technologie, mit der Sie die Leistungsengpässe im Linux-Netzwerkstack umgehen können. DPDK oder Data Plane Development Kit ist eine Reihe von Bibliotheken und Treibern für die schnelle Paketverarbeitung, mit denen Sie den Linux-Netzwerkstapel von der Paketverarbeitung ausschließen und direkt mit einem Netzwerkgerät interagieren können.



DPDK verwandelt einen Universalprozessor in einen Paketweiterleitungsserver. Diese Transformation macht teure Switches und Router überflüssig. DPDK legt jedoch Einschränkungen für die Verwendung bestimmter Netzwerkadapter fest. Die Liste der unterstützten Hardware finden Sie auf dem Link - hier ist die beliebteste Plattform von Inteld.h. Es wird Hardware-Unterstützung bereitgestellt, die mit den Linux-Treibern e1000, ixgbe, i40e, ice, fm10k, ipn3ke, ifc, igc funktioniert.



Es ist auch wichtig zu verstehen, dass für einen TRex-Server mit einer Geschwindigkeit von 10 Gbit / s ein Multi-Core-Prozessor erforderlich ist - ab 4 Kernen oder höher, vorzugsweise eine Intel-CPU mit Unterstützung für simultanes Multithreading (Hyper-Threading).



2. Wie Sie TRex erhalten und ausprobieren



1) Laden Sie das Archiv vom Server trex-tgn.cisco.com



herunter : trex-tgn.cisco.com/trex/release/ Entpacken Sie das Archiv in das Home-Verzeichnis des Benutzers "/ home / user", wobei user der Benutzername ist.



[bash]>wget --no-cache https://trex-tgn.cisco.com/trex/release/latest
[bash]>tar -xzvf latest


2) Konfigurieren der Schnittstellen zum Senden und Empfangen von Daten



Führen Sie die Konfiguration mit dem Dienstprogramm "dpdk_setup_ports.py" durch, das im Archiv mit TRex enthalten ist. Sie können die Netzwerkschnittstellen konfigurieren, die TRex auf MAC- oder IP-Ebene verwendet. Zu Beginn müssen Sie dieses Dienstprogramm mit dem interaktiven Einstellungsschlüssel "sudo ./dpdk_setup_ports.py –i" ausführen.



Der erste Schritt besteht darin, die Konfiguration auf MAC-Ebene abzubrechen (Möchten Sie eine MAC-basierte Konfiguration verwenden? (J / N) n).



Der zweite Schritt besteht darin, ein Paar Netzwerkschnittstellen auszuwählen, mit denen wir arbeiten werden. In unserem Fall, wenn die Intel X710-Netzwerkkarte mit 4 Netzwerkschnittstellen arbeitet, verwenden wir den 1. und 4. Sockel der Netzwerkkarte.







Im dritten Schritt bietet das System an, automatisch eine geschlossene Konfiguration zu erstellen - wenn Daten Port 1 verlassen und Port 2 (und zurück) erreichen, alles auf einem PC. Wir mussten dieses Schema aufgeben und das Routing-Schema für 2 PCs konfigurieren.



Im vierten und fünften Schritt vereinbaren wir, die Konfiguration in der Datei /etc/trex_cfg.yaml zu speichern.



Betrachten Sie beispielsweise die Konfiguration auf IP-Ebene für das folgende Verbindungsschema:







Die Konfigurationsdatei befindet sich hier: "/etc/trex_cfg.yaml". Im Folgenden wird eine einfache Konfigurationsdatei für eine 2-Port-Netzwerkkarte mit einer CPU gezeigt, die 8 Threads unterstützt:



### Config file generated by dpdk_setup_ports.py ###
- version: 2
  interfaces: ['01:00.0', '01:00.3']
  port_info:
      - ip: 192.168.253.106
        default_gw: 192.168.253.107
      - ip: 192.168.254.106
        default_gw: 192.168.254.107
 
  platform:
      master_thread_id: 0
      latency_thread_id: 1
      dual_if:
    	- socket: 0
      	threads: [2,3,4,5,6,7]


In der Konfiguration:



  • '01: 00.0 ', '01: 00.3' - der Name der Eth-Schnittstellen im verwendeten Linux-System.
  • ip: 192.168.253.106 - Die Adresse des Ports des Server TRex-PCs, von dem Datenverkehr generiert wird.
  • default_gw: 192.168.253.107 - Adresse von 1 Port des PC-Prüflings (zu testendes Gerät).
  • ip: 192.168.254.106 - Die Adresse des Server-TRex-PC-Ports, von dem nach Durchlaufen der QOS-Regeln Datenverkehr zurückgegeben wird.
  • default_gw: 192.168.253.107 - Adresse von 2 Ports des PC-Prüflings.


Beachtung! Das TRex-System verbietet die Verwendung desselben Subnetzes beim Generieren von Streams, die vom System verwendet werden. Beim Generieren von Paketen werden daher die Subnetze 16.0.0.0 und 48.0.0.0 verwendet.



3) Konfigurieren von Schnittstellen auf dem Remote-Computer



Es ist erforderlich, Weiterleitungen und Routen so zu konfigurieren, dass das System (DUT), über das der Datenverkehr weitergeleitet wird, weiß, wo Pakete empfangen und gesendet werden sollen.



Konfigurieren Sie die Flow-Routing-Regeln auf dem Prüfling-PC:



sudo echo 1 > /proc/sys/net/ipv4/ip_forward
sudo route add -net 16.0.0.0 netmask 255.0.0.0 gw 192.168.253.106
sudo route add -net 48.0.0.0 netmask 255.0.0.0 gw 192.168.254.106


4) Starten Sie den TRex-Server im AstF-Modus:



cd v2.XX
sudo ./t-rex-64 -i --astf


Wenn der TRex-Server erfolgreich gestartet wurde, werden Informationen zu den zum Testen verwendeten Ethernet-Ports angezeigt:



The ports are bound/configured.
port : 0 
------------
link         :  link : Link Up - speed 10000 Mbps - full-duplex
promiscuous  : 0 
port : 1 
------------
link         :  link : Link Up - speed 10000 Mbps - full-duplex
promiscuous  : 0 
number of ports         : 2 
max cores for 2 ports   : 1 
tx queues per port      : 3


5) Starten der TRex-Konsole Starten Sie



mithilfe der Konsole in einem separaten Fenster einen Stream aus vorgefertigten Beispielen (der Ordner mit den astf-Beispielen befindet sich im Archiv für TRex):



cd v2.XX
./trex-console
start -f astf/http_simple.py -m 1
 
start (options):
-a (all ports)
-port 1 2 3 (ports 1 2 3)
-d duration (-d 100 -d 10m -d 1h)
-m stream strength (-m 1 -m 1gb -m 40%)
-f load from disk the streams file


Wenn der Start erfolgreich ist, werden die Verkehrsflussstatistiken in der TRex-Serverkonsole angezeigt:



Global stats enabled
Cpu Utilization : 0.3  %  0.6 Gb/core 
Platform_factor : 1.0  
Total-Tx        :     759.81 Kbps  
Total-Rx        :     759.81 Kbps  
Total-PPS       :      82.81  pps  
Total-CPS       :       2.69  cps  
 
Expected-PPS    :       0.00  pps  
Expected-CPS    :       0.00  cps  
Expected-L7-BPS :       0.00  bps  
 
Active-flows    :        2  Clients :        0   Socket-util : 0.0000 %    
Open-flows      :      641


3. Automatisierung der Entwicklung und des Testens mit TRex



Bei der Entwicklung eines Netzwerk-Routers haben wir viele Tests für TRex geschrieben, sodass sich die Frage stellte, ob diese im automatischen Modus mit Python ausgeführt werden sollen. So haben wir es organisiert:



Wir haben den TRex-Server im STL-Modus gestartet:



cd v2.XX
sudo ./t-rex-64 -i --stl


Legen Sie die Umgebungsvariable für Python fest, da TRex in Verbindung mit Python arbeitet.



exportiere PYTHONPATH = / home / !!! Benutzer !!! / v2.XX / automation / trex_control_plane / interactive, wobei "!!! Benutzer !!!" - Benutzername und Home-Verzeichnis, v2.XX - Version der TRex-Software, die in diesen Ordner heruntergeladen und entpackt wurde.



Wir haben den Verkehrsgenerator mit Python gestartet. Die Auflistung der Beispielkonfiguration finden Sie unten.



python example_test_2bidirectstream.py



Erwartete Ausgabe:



Transmit: 10000.24576MByte/s Receive: 10000.272384MByte/s
Stream 1 TX: 4487179200 Bit/s RX: 4487179200 Bit/s
Stream 2 TX: 2492873600 Bit/s RX: 2492873600 Bit/s
Stream 3 TX: 1994294400 Bit/s RX: 1994294400 Bit/s
Stream 4 TX: 997147200 Bit/s RX: 997147200 Bit/s


Lassen Sie uns dieses Beispiel analysieren:



c = STLClient (server = '127.0.0.1')



Erstellen Sie eine Verbindung zum TRex-Server. In diesem Fall wird die Verbindung zu demselben Computer wie der Server hergestellt.



  • "Base_pkt_dir_a, base_pkt_dir_b, base_pkt_dir_c, base_pkt_dir_d" - Paketvorlagen, die Quell- und Zieladressen, Quell- und Zielports enthalten. In diesem Beispiel werden 4 Streams erstellt, 2 in einer Richtung und 2 in der entgegengesetzten Richtung.
  • "S1, s2, s3, s4" - fordert die Parameter des generierten Streams von der STLStream-Klasse an, wie z. B. Stream-ID und Bitrate, in unserem Fall ID1 = 4,5 Gbit / s, ID2 = 2,5 Gbit / s, ID3 = 2 Gbit / s, ID4 = 1 Gbit / s.


Auflistung der Stream-Konfigurationsdatei example_test_2bidirectstream.py



# get TRex APIs
from trex_stl_lib.api import *
 
c = STLClient(server = '127.0.0.1')
c.connect()
 
try:
    # create a base packet with scapy
    base_pkt_dir_a = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=5001,sport=50001)
    base_pkt_dir_b = Ether()/IP(src="48.0.0.1",dst="16.0.0.1")/UDP(dport=50001,sport=5001)
 
    base_pkt_dir_c = Ether()/IP(src="16.0.0.2",dst="48.0.0.2")/UDP(dport=5002,sport=50002)
    base_pkt_dir_d = Ether()/IP(src="48.0.0.2",dst="16.0.0.2")/UDP(dport=50002,sport=5002)
 
    # pps : float
    # Packets per second
    #
    # bps_L1 : float
    # Bits per second L1 (with IPG)
    #
    # bps_L2 : float
    # Bits per second L2 (Ethernet-FCS)
    packet_size = 1400
 
    def pad(base_pkt):
        pad = (packet_size - len(base_pkt)) * 'x'
        return pad
 
    s1 = STLStream(packet=STLPktBuilder(base_pkt_dir_a/pad(base_pkt_dir_a)), mode=STLTXCont(bps_L2=4500000000), flow_stats=STLFlowStats(pg_id=1))
    s2 = STLStream(packet=STLPktBuilder(base_pkt_dir_b/pad(base_pkt_dir_b)), mode=STLTXCont(bps_L2=2500000000), flow_stats=STLFlowStats(pg_id=2))
    s3 = STLStream(packet=STLPktBuilder(base_pkt_dir_c/pad(base_pkt_dir_c)), mode=STLTXCont(bps_L2=2000000000), flow_stats=STLFlowStats(pg_id=3))
    s4 = STLStream(packet=STLPktBuilder(base_pkt_dir_d/pad(base_pkt_dir_d)), mode=STLTXCont(bps_L2=1000000000), flow_stats=STLFlowStats(pg_id=4))
 
    my_ports = [0, 1]
 
    c.reset(ports = [my_ports[0], my_ports[1]])
 
    # add the streams
    c.add_streams(s1, ports = my_ports[0])
    c.add_streams(s2, ports = my_ports[1])
    c.add_streams(s3, ports = my_ports[0])
    c.add_streams(s4, ports = my_ports[1])
 
    # start traffic with limit of 10 seconds (otherwise it will continue forever)
    # bi direction
    testduration = 10
    c.start(ports=[my_ports[0], my_ports[1]], duration=testduration)
    # hold until traffic ends
    c.wait_on_traffic()
 
    # check out the stats
    stats = c.get_stats()
 
    # get global stats
    totalstats = stats['global']
    totaltx = round(totalstats.get('tx_bps'))
    totalrx = round(totalstats.get('rx_bps'))
    print('Transmit: {}MByte/s Receive: {}MByte/s'.format((totaltx / 1000000), (totalrx / 1000000)))
    c.clear_stats(ports = [my_ports[0], my_ports[1]])
 
    # get flow stats
    totalstats = stats['flow_stats']
    stream1 = totalstats[1]
 
    stream2 = totalstats[2]
    stream3 = totalstats[3]
    stream4 = totalstats[4]
    totaltx_1 = stream1.get('tx_pkts')
    totalrx_1 = stream1.get('rx_pkts')
    print('Stream 1 TX: {} Bit/s RX: {} Bit/s'.format((totaltx_1['total'] / testduration * packet_size * 8),
                                                               (totalrx_1['total'] / testduration * packet_size * 8)))
    totaltx_2 = stream2.get('tx_pkts')
    totalrx_2 = stream2.get('rx_pkts')
    print('Stream 2 TX: {} Bit/s RX: {} Bit/s'.format((totaltx_2['total'] / testduration * packet_size * 8),
                                                               (totalrx_2['total'] / testduration * packet_size * 8)))
    totaltx_3 = stream3.get('tx_pkts')
    totalrx_3 = stream3.get('rx_pkts')
    print('Stream 3 TX: {} Bit/s RX: {} Bit/s'.format((totaltx_3['total'] / testduration * packet_size * 8),
                                                               (totalrx_3['total'] / testduration * packet_size * 8)))
    totaltx_4 = stream4.get('tx_pkts')
    totalrx_4 = stream4.get('rx_pkts')
    print('Stream 4 TX: {} Bit/s RX: {} Bit/s'.format((totaltx_4['total'] / testduration * packet_size * 8),
                                                               (totalrx_4['total'] / testduration * packet_size * 8)))
except STLError as e:
    print(e)
 
finally:
    c.disconnect()


Fazit



Bei der Vorbereitung dieses Handbuchs für Habr haben wir den Betrieb des Prüflings mit 4 Threads gestartet und getestet, Informationen zu Threads gesammelt und globale Statistiken erstellt.



Der oben beschriebene Vorgang wird mit Python gestartet. Mit TRex können Sie das Testen und Debuggen von Netzwerkgeräten und Softwareprodukten automatisieren - in einer Schleife oder beim sequentiellen Ausführen von Tests in Python.



Warum ist Ciscos TRex besser oder schlechter als andere ähnliche Verkehrsgeneratoren? Zum Beispiel das beliebte Client-Server-Programm iperf? Im TRex-Verwendungsszenario wird eine Beschreibung zum Einrichten und Arbeiten mit Streams angezeigt. Sowohl Test- als auch Debugging-Tools sind gut: iperf - zum schnellen Testen der Funktionalität unterwegs, und TRex automatisiert hervorragend das Testen und Entwickeln komplexer Netzwerkgeräte und -systeme, wobei die Fähigkeit zum Konfigurieren von Multithread-Streams wichtig ist, um jeden Stream für eine bestimmte Aufgabe zu konfigurieren und die Ausgabeergebnisse zu analysieren ...



Mit TRex können Sie Vorlagen für nahezu jede Art von Datenverkehr erstellen und diese erweitern, um umfangreiche DDoS-Angriffe zu generieren, einschließlich TCP-SYN-, UDP- und ICMP-Streams. Durch die Möglichkeit, massive Verkehrsströme zu generieren, können Sie Angriffe von mehreren Clients auf mehrere Zielserver simulieren.



Wenn Sie dieses Tool noch nicht ausprobiert haben, können Sie sich eine Notiz machen. Und wenn Sie es versucht haben - teilen Sie Ihre Beispiele und Ihr Feedback in den Kommentaren mit. Es ist interessant zu wissen, woran TRex von anderen Ingenieuren gedacht und verwendet wird.



All Articles