Lors du développement d'un autre routeur, nous avons testé les performances du réseau à l'aide d'un élément open-source utile - le générateur de trafic Cisco TRex. Quel est cet outil? Comment l'utiliser? Et comment cela peut-il être utile aux ingénieurs de développement? Voici les réponses à ces questions.
1. Qu'est-ce que Cisco TRex
Il s'agit d'un générateur de trafic logiciel open source qui fonctionne sur des processeurs Intel DPDK standard et prend en charge les modes avec état / sans état. Comparativement simple et entièrement évolutif.
La documentation en anglais de cet outil est disponible sur le site Web .
Trex vous permet de générer différents types de trafic et d'analyser les données lorsqu'elles sont reçues. Le travail au niveau MAC et IP est pris en charge. Vous pouvez définir la taille des paquets et leur nombre, contrôler le taux de transfert de données.
Le travail avec le générateur est organisé dans un environnement Linux.
L'une des différences importantes entre le générateur Trex est l'utilisation de la technologie DPDK, qui vous permet de contourner les goulots d'étranglement des performances dans la pile réseau Linux. DPDK ou Data Plane Development Kit est un ensemble de bibliothèques et de pilotes pour un traitement rapide des paquets qui vous permet d'exclure la pile réseau Linux du traitement des paquets et d'interagir directement avec un périphérique réseau.
DPDK transforme un processeur polyvalent en un serveur de transfert de paquets. Cette transformation élimine le besoin de commutateurs et de routeurs coûteux. Cependant, DPDK impose des restrictions sur l'utilisation d'adaptateurs réseau spécifiques, la liste du matériel pris en charge est indiquée sur le lien - voici la plate-forme la plus populaire d' Intel, c'est à dire. le support matériel est fourni qui fonctionne avec les pilotes linux e1000, ixgbe, i40e, ice, fm10k, ipn3ke, ifc, igc.
Il est également important de comprendre que pour qu'un serveur TRex fonctionne à 10 Gbit / s, un processeur multicœur est nécessaire - à partir de 4 cœurs et plus, de préférence un processeur Intel avec prise en charge du multi-threading simultané (hyper-threading).
2. Comment obtenir et essayer TRex
1) Téléchargez l'archive depuis le serveur trex-tgn.cisco.com: trex-tgn.cisco.com/trex/release/ Décompressez
l'archive dans le répertoire personnel de l'utilisateur "/ home / user", où user est le nom d'utilisateur.
[bash]>wget --no-cache https://trex-tgn.cisco.com/trex/release/latest
[bash]>tar -xzvf latest
2) Configurer les interfaces d'envoi et de réception des données
Effectuons la configuration à l'aide de l'utilitaire "dpdk_setup_ports.py" fourni dans l'archive avec TRex. Vous pouvez configurer les interfaces réseau utilisées par TRex au niveau MAC ou IP. Pour commencer, vous devez exécuter cet utilitaire avec la clé de configuration interactive "sudo ./dpdk_setup_ports.py –i".
La première étape consiste à abandonner la configuration au niveau MAC (Voulez-vous utiliser la configuration basée sur MAC? (O / N) n).
La deuxième étape consiste à sélectionner une paire d'interfaces réseau avec lesquelles nous travaillerons, dans notre cas, la carte réseau Intel X710 fonctionne avec 4 interfaces réseau, nous utiliserons la 1ère et la 4ème prise de la carte réseau.
Dans la troisième étape, le système proposera de créer automatiquement une configuration fermée - lorsque les données quittent le port 1 et arrivent au port 2 (et retour), le tout sur un seul PC. Nous avons dû abandonner ce schéma et configurer le schéma de routage pour 2 PC.
Dans les quatrième et cinquième étapes, nous acceptons de sauvegarder la configuration dans le fichier /etc/trex_cfg.yaml.
Par exemple, considérez la configuration au niveau IP pour le schéma de connexion suivant:
Le fichier de configuration se trouve ici: "/etc/trex_cfg.yaml". Un fichier de configuration simple est illustré ci-dessous pour une carte réseau à 2 ports avec un processeur prenant en charge 8 threads:
### 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]
En configuration:
- '01: 00.0 ', '01: 00.3' - le nom des interfaces Eth dans le système Linux utilisé.
- ip: 192.168.253.106 - l'adresse du port du PC serveur TRex à partir duquel le trafic est généré.
- default_gw: 192.168.253.107 - adresse de 1 port du PC DUT (Device under test).
- ip: 192.168.254.106 - l'adresse du port PC du serveur TRex, à partir de laquelle le trafic est renvoyé après avoir traversé les règles QOS.
- default_gw: 192.168.253.107 - adresse de 2 ports du PC DUT.
Attention! Le système TRex interdit l'utilisation du même sous-réseau lors de la génération de flux utilisés par le système; pour cela, lors de la génération de paquets, les sous-réseaux 16.0.0.0 et 48.0.0.0 sont utilisés.
3) Configurer les interfaces sur la machine distante
Il est nécessaire de configurer le transfert et les routes pour que le système (DUT) par lequel nous passerons le trafic sache où recevoir et où envoyer les paquets.
Configurez les règles de routage de flux sur le PC DUT:
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) Démarrez le serveur TRex en mode astf:
cd v2.XX
sudo ./t-rex-64 -i --astf
Si le serveur TRex est lancé avec succès, nous verrons des informations sur les ports Ethernet utilisés pour les tests:
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) Lancement de la console TRex
À l'aide de la console, dans une fenêtre séparée, commencez à générer un flux à partir d'exemples prêts à l'emploi (le dossier avec les exemples astf se trouve dans l'archive de 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
Si le lancement réussit, nous verrons les statistiques de flux de trafic dans la console du serveur TRex:
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. Automatisation du développement et des tests avec TRex
Dans le processus de développement d'un routeur réseau, nous avons écrit de nombreux tests pour TRex, la question s'est donc posée de les exécuter en mode automatique en utilisant python. Comment nous l'avons organisé:
Nous avons démarré le serveur TRex en mode stl:
cd v2.XX
sudo ./t-rex-64 -i --stl
Définissez la variable d'environnement pour python, car TRex fonctionne en conjonction avec python.
export PYTHONPATH = / home / !!! user !!! / v2.XX / automation / trex_control_plane / interactive, où "!!! user !!!" - nom d'utilisateur et répertoire personnel, v2.XX - version du logiciel TRex téléchargée et décompressée dans ce dossier.
Nous avons démarré le générateur de trafic en utilisant python, la liste de l'exemple de configuration est donnée ci-dessous.
python example_test_2bidirectstream.py
Résultat attendu:
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
Analysons cet exemple:
c = STLClient (server = '127.0.0.1')
Créez une connexion au serveur TRex, dans ce cas, la connexion est créée sur la même machine que le serveur.
- "Base_pkt_dir_a, base_pkt_dir_b, base_pkt_dir_c, base_pkt_dir_d" - modèles de paquets, qui contiennent les adresses source et de destination, les ports source et de destination. Dans cet exemple, 4 flux sont créés, 2 dans un sens et 2 dans le sens opposé.
- "S1, s2, s3, s4" - demande les paramètres du flux généré à partir de la classe STLStream, tels que l'ID de flux et le débit binaire, dans notre cas ID1 = 4,5 Gbps, ID2 = 2,5 Gbps, ID3 = 2 Gbps, ID4 = 1 Gbit / s.
Liste du fichier de configuration de flux 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()
Conclusion
Lors de la préparation de ce guide pour Habr, nous avons lancé et testé le fonctionnement du système DUT avec 4 threads, collecté des informations sur les threads et des statistiques globales.
L'opération décrite ci-dessus est lancée à l'aide de python, ce qui signifie qu'en utilisant TRex, vous pouvez automatiser les tests et le débogage des périphériques réseau et des produits logiciels - en boucle ou lors de l'exécution séquentielle de tests en python.
Alors, pourquoi le TRex de Cisco est-il meilleur ou pire que d'autres générateurs de trafic similaires? Par exemple, le populaire programme client-serveur iperf? Dans le scénario d'utilisation de TRex, nous voyons une description de la configuration et de l'utilisation des flux. Les outils de test et de débogage sont bons: iperf - pour tester rapidement les fonctionnalités en déplacement, et TRex fait un excellent travail d'automatisation des tests et du développement de périphériques et de systèmes réseau complexes, où la capacité de configurer des flux multithreads est importante afin de configurer chaque flux pour une tâche spécifique et d'analyser les résultats de sortie ...
TRex vous permet de créer des modèles pour presque tous les types de trafic et de les amplifier pour générer des attaques DDoS à grande échelle, y compris des flux TCP-SYN, UDP et ICMP. La possibilité de générer des flux de trafic massifs vous permet de simuler des attaques de plusieurs clients sur plusieurs serveurs cibles.
Donc, si vous n'avez pas encore essayé cet outil, vous pouvez en prendre note. Et si vous avez essayé - partagez vos exemples et vos commentaires dans les commentaires. Il est intéressant de savoir ce que TRex pense et utilise par ses collègues ingénieurs.