snappi-trex is a snappi plugin that allows executing scripts written using snappi with Cisco's TRex Traffic Generator

Related tags

Networkingsnappi-trex
Overview

snappi-trex

license Project Status: Active – The project has reached a stable, usable state and is being actively developed. Build Total alerts Language grade: Python pypi python

snappi-trex is a snappi plugin that allows executing scripts written using snappi with Cisco's TRex Traffic Generator

Design

snappi-trex converts snappi Open Traffic Generator API configuration into the equivalent TRex STL Client configuration. This allows users to use the TRex Traffic Generator and its useful features without having to write complex TRex scripts.

diagram

The above diagram outlines the overall process of how the snappi Open Traffic Generator API is able to interface with TRex and generate traffic over its network interfaces. snappi-trex is essential to convert snappi scripts into the equivalent TRex STL Client instructions.


snappi-trex usage follows the standard usage of snappi with a few modifications outlined in the Usage document.

Demos

Click here for the Quickstart Guide Video Tutorial

  • This goes over the installation and setup for snappi-trex, and how to run a basic snappi script using snappi-trex

Click here for the snappi-trex P4 PTF Demo

  • This demonstrates snappi-trex being used with the P4 Packet Testing Framework in a 4 Port Mesh configuration

Table of Contents


Quickstart

snappi-trex is a snappi plugin that allows executing scripts written using snappi with Cisco's TRex Traffic Generator


--> Click here for the Quickstart Guide Video Tutorial


Installing and Running TRex

TRex must be installed and running before proceeding

TRex must be installed and configured in order to use snappi-trex. For a quick tutorial on TRex installation, running, and basic usage, check out my TRex Tutorial


Installing snappi-trex

Make sure python-pip3 is installed

sudo apt-get install python3-pip

Install snappi and the snappi-trex extension

pip3 install snappi==0.4.26 snappi[trex]

Start Scripting

Let's run our first script called hello_snappi_trex.py: A basic snappi script that transmits 1000 UDP packets bidirectionally between two ports and verifies that they are received. This file can be found at examples/hello_snappi_trex.py in the snappi-trex Github Repo.

git clone https://github.com/open-traffic-generator/snappi-trex
python3 snappi-trex/examples/hello_snappi_trex.py

You may also just paste the script in from below.

hello_snappi_trex.py
p2').flow(name='flow p2->p1') # and assign source and destination ports for each f1.tx_rx.port.tx_name, f1.tx_rx.port.rx_name = p1.name, p2.name f2.tx_rx.port.tx_name, f2.tx_rx.port.rx_name = p2.name, p1.name # configure packet size, rate and duration for both flows f1.size.fixed, f2.size.fixed = 128, 256 for f in cfg.flows: # send 1000 packets and stop f.duration.fixed_packets.packets = 1000 # send 1000 packets per second f.rate.pps = 1000 # configure packet with Ethernet, IPv4 and UDP headers for both flows eth1, ip1, udp1 = f1.packet.ethernet().ipv4().udp() eth2, ip2, udp2 = f2.packet.ethernet().ipv4().udp() # set source and destination MAC addresses eth1.src.value, eth1.dst.value = '00:AA:00:00:04:00', '00:AA:00:00:00:AA' eth2.src.value, eth2.dst.value = '00:AA:00:00:00:AA', '00:AA:00:00:04:00' # set source and destination IPv4 addresses ip1.src.value, ip1.dst.value = '10.0.0.1', '10.0.0.2' ip2.src.value, ip2.dst.value = '10.0.0.2', '10.0.0.1' # set incrementing port numbers as source UDP ports udp1.src_port.increment.start = 5000 udp1.src_port.increment.step = 2 udp1.src_port.increment.count = 10 udp2.src_port.increment.start = 6000 udp2.src_port.increment.step = 4 udp2.src_port.increment.count = 10 # assign list of port numbers as destination UDP ports udp1.dst_port.values = [4000, 4044, 4060, 4074] udp2.dst_port.values = [8000, 8044, 8060, 8074, 8082, 8084] print('Pushing traffic configuration ...') api.set_config(cfg) print('Starting packet capture on all configured ports ...') cs = api.capture_state() cs.state = cs.START api.set_capture_state(cs) print('Starting transmit on all configured flows ...') ts = api.transmit_state() ts.state = ts.START api.set_transmit_state(ts) print('Checking metrics on all configured ports ...') print('Expected\tTotal Tx\tTotal Rx') assert wait_for(lambda: metrics_ok(api, cfg)), 'Metrics validation failed!' assert captures_ok(api, cfg), 'Capture validation failed!' print('Test passed !') def metrics_ok(api, cfg): # create a port metrics request and filter based on port names req = api.metrics_request() req.port.port_names = [p.name for p in cfg.ports] # include only sent and received packet counts req.port.column_names = [req.port.FRAMES_TX, req.port.FRAMES_RX] # fetch port metrics res = api.get_metrics(req) # calculate total frames sent and received across all configured ports total_tx = sum([m.frames_tx for m in res.port_metrics]) total_rx = sum([m.frames_rx for m in res.port_metrics]) expected = sum([f.duration.fixed_packets.packets for f in cfg.flows]) print('%d\t\t%d\t\t%d' % (expected, total_tx, total_rx)) return expected == total_tx and total_rx >= expected def captures_ok(api, cfg): import dpkt print('Checking captured packets on all configured ports ...') print('Port Name\tExpected\tUDP packets') result = [] for p in cfg.ports: exp, act = 1000, 0 # create capture request and filter based on port name req = api.capture_request() req.port_name = p.name # fetch captured pcap bytes and feed it to pcap parser dpkt pcap = dpkt.pcap.Reader(api.get_capture(req)) for _, buf in pcap: # check if current packet is a valid UDP packet eth = dpkt.ethernet.Ethernet(buf) if isinstance(eth.data.data, dpkt.udp.UDP): act += 1 print('%s\t\t%d\t\t%d' % (p.name, exp, act)) result.append(exp == act) return all(result) def wait_for(func, timeout=10, interval=0.2): """ Keeps calling the `func` until it returns true or `timeout` occurs every `interval` seconds. """ import time start = time.time() while time.time() - start <= timeout: if func(): return True time.sleep(interval) print('Timeout occurred !') return False if __name__ == '__main__': hello_snappi_trex() ">
import snappi
import sys, os

# Replace v2.90 with the installed version of TRex. 
# Change '/opt/trex' if you installed TRex in another location
trex_path = '/opt/trex/v2.90/automation/trex_control_plane/interactive'
sys.path.insert(0, os.path.abspath(trex_path))


def hello_snappi_trex():
    """
    This script does following:
    - Send 1000 packets back and forth between the two ports at a rate of
      1000 packets per second.
    - Validate that total packets sent and received on both interfaces is as
      expected using port metrics.
    - Validate that captured UDP packets on both the ports are as expected.
    """
    # create a new API instance where host points to controller
    api = snappi.api(ext='trex')
    # and an empty traffic configuration to be pushed to controller later on
    cfg = api.config()

    # add two ports where location points to traffic-engine (aka ports)
    p1, p2 = (
        cfg.ports
        .port(name='p1')
        .port(name='p2')
    )

    # add layer 1 property to configure same speed on both ports
    ly = cfg.layer1.layer1(name='ly')[-1]
    ly.port_names = [p1.name, p2.name]
    ly.speed = ly.SPEED_1_GBPS

    # enable packet capture on both ports
    cp = cfg.captures.capture(name='cp')[-1]
    cp.port_names = [p1.name, p2.name]

    # add two traffic flows
    f1, f2 = cfg.flows.flow(name='flow p1->p2').flow(name='flow p2->p1')
    # and assign source and destination ports for each
    f1.tx_rx.port.tx_name, f1.tx_rx.port.rx_name = p1.name, p2.name
    f2.tx_rx.port.tx_name, f2.tx_rx.port.rx_name = p2.name, p1.name

    # configure packet size, rate and duration for both flows
    f1.size.fixed, f2.size.fixed = 128, 256
    for f in cfg.flows:
        # send 1000 packets and stop
        f.duration.fixed_packets.packets = 1000
        # send 1000 packets per second
        f.rate.pps = 1000

    # configure packet with Ethernet, IPv4 and UDP headers for both flows
    eth1, ip1, udp1 = f1.packet.ethernet().ipv4().udp()
    eth2, ip2, udp2 = f2.packet.ethernet().ipv4().udp()

    # set source and destination MAC addresses
    eth1.src.value, eth1.dst.value = '00:AA:00:00:04:00', '00:AA:00:00:00:AA'
    eth2.src.value, eth2.dst.value = '00:AA:00:00:00:AA', '00:AA:00:00:04:00'

    # set source and destination IPv4 addresses
    ip1.src.value, ip1.dst.value = '10.0.0.1', '10.0.0.2'
    ip2.src.value, ip2.dst.value = '10.0.0.2', '10.0.0.1'

    # set incrementing port numbers as source UDP ports
    udp1.src_port.increment.start = 5000
    udp1.src_port.increment.step = 2
    udp1.src_port.increment.count = 10

    udp2.src_port.increment.start = 6000
    udp2.src_port.increment.step = 4
    udp2.src_port.increment.count = 10

    # assign list of port numbers as destination UDP ports
    udp1.dst_port.values = [4000, 4044, 4060, 4074]
    udp2.dst_port.values = [8000, 8044, 8060, 8074, 8082, 8084]

    print('Pushing traffic configuration ...')
    api.set_config(cfg)

    print('Starting packet capture on all configured ports ...')
    cs = api.capture_state()
    cs.state = cs.START
    api.set_capture_state(cs)

    print('Starting transmit on all configured flows ...')
    ts = api.transmit_state()
    ts.state = ts.START
    api.set_transmit_state(ts)

    print('Checking metrics on all configured ports ...')
    print('Expected\tTotal Tx\tTotal Rx')
    assert wait_for(lambda: metrics_ok(api, cfg)), 'Metrics validation failed!'

    assert captures_ok(api, cfg), 'Capture validation failed!'

    print('Test passed !')


def metrics_ok(api, cfg):
    # create a port metrics request and filter based on port names
    req = api.metrics_request()
    req.port.port_names = [p.name for p in cfg.ports]
    # include only sent and received packet counts
    req.port.column_names = [req.port.FRAMES_TX, req.port.FRAMES_RX]

    # fetch port metrics
    res = api.get_metrics(req)
    # calculate total frames sent and received across all configured ports
    total_tx = sum([m.frames_tx for m in res.port_metrics])
    total_rx = sum([m.frames_rx for m in res.port_metrics])
    expected = sum([f.duration.fixed_packets.packets for f in cfg.flows])

    print('%d\t\t%d\t\t%d' % (expected, total_tx, total_rx))

    return expected == total_tx and total_rx >= expected


def captures_ok(api, cfg):
    import dpkt
    print('Checking captured packets on all configured ports ...')
    print('Port Name\tExpected\tUDP packets')

    result = []
    for p in cfg.ports:
        exp, act = 1000, 0
        # create capture request and filter based on port name
        req = api.capture_request()
        req.port_name = p.name
        # fetch captured pcap bytes and feed it to pcap parser dpkt
        pcap = dpkt.pcap.Reader(api.get_capture(req))
        for _, buf in pcap:
            # check if current packet is a valid UDP packet
            eth = dpkt.ethernet.Ethernet(buf)
            if isinstance(eth.data.data, dpkt.udp.UDP):
                act += 1

        print('%s\t\t%d\t\t%d' % (p.name, exp, act))
        result.append(exp == act)

    return all(result)


def wait_for(func, timeout=10, interval=0.2):
    """
    Keeps calling the `func` until it returns true or `timeout` occurs
    every `interval` seconds.
    """
    import time
    start = time.time()

    while time.time() - start <= timeout:
        if func():
            return True
        time.sleep(interval)

    print('Timeout occurred !')
    return False


if __name__ == '__main__':
    hello_snappi_trex()


Output

If everything is working correctly, you should see a similar output as this.

Pushing traffic configuration ...
Starting packet capture on all configured ports ...
Starting transmit on all configured flows ...
Checking metrics on all configured ports ...
Expected        Total Tx        Total Rx
2000            19              17
2000            445             437
2000            881             881
2000            1325            1325
2000            1761            1761
2000           2000            2000
Checking captured packets on all configured ports ...
Port Name       Expected        UDP packets
p1              1000            1000
p2              1000            1000
Test passed !
You might also like...
These scripts send notifications to a Webex space when a new IP is banned by Expressway, and allow to request more info or change the ban status
These scripts send notifications to a Webex space when a new IP is banned by Expressway, and allow to request more info or change the ban status

Spam Call and Toll Fraud Mitigation Cisco Expressway release X14 is able to mitigate spam calls and toll fraud attempts by jailing the spam IP address

A repository dedicated to IoT(internet of things ) and python scripts
A repository dedicated to IoT(internet of things ) and python scripts

📑 Introduction Week of Learning is a weekly program in which you will get all the necessary knowledge about Circuit-Building, Arduino and Micro-Contr

Repo used to maintain all notes and scripts developed during my DevNet Expert studies

DevNet Expert Studies Exam Date: TBD (Waiting for registration to open) This repository will be used to track my progress and maintain all notes/scrip

 Python Scripts for Cisco Identity Services Engine (ISE)
Python Scripts for Cisco Identity Services Engine (ISE)

A set of Python scripts to configure a freshly installed Cisco Identity Services Engine (ISE) for simple operation; in my case, a basic Cisco Software-Defined Access environment.

DataShare - Simple library for data sharing between scripts and public functions calling

DataShare - Simple library for data sharing between scripts and public functions calling. Installation. Install code, Delete LICENSE, README, readme.t

Python Scrcpy Client - allows you to view and control android device in realtime
Python Scrcpy Client - allows you to view and control android device in realtime

Python Scrcpy Client This package allows you to view and control android device in realtime. Note: This gif is compressed and experience lower quality

InfraGenie is allows you to split out your infrastructure project into separate independent pieces, each with its own terraform state.
InfraGenie is allows you to split out your infrastructure project into separate independent pieces, each with its own terraform state.

🧞 InfraGenie InfraGenie is allows you to split out your infrastructure project into separate independent pieces, each with its own terraform state. T

A simple and lightweight server that allows clients to connect and launch a shell remotely through a browser.

carrotsh A simple and lightweight server that allows clients to connect and launch a shell remotely through a browser. Uses xterm.js for the frontend

A web-based app that allows easy, simple - and if desired high-throughput - analysis of qPCR data
A web-based app that allows easy, simple - and if desired high-throughput - analysis of qPCR data

qpcr-Analyser A web-based GUI for the qpcr package that allows easy, simple and high-throughput analysis of qPCR data. As is described in more detail

Owner
Open Traffic Generator
Open Traffic Generator
ASC - Api Server Controller

ASC - Api Server Controller

Uriel Alves 1 Jan 03, 2022
gRPC typing stubs for Python

gRPC Typing Stubs for Python This is a PEP-561-compliant stub-only package which provides type information of gRPC. Install using pip: pip install grp

Blake Williams 27 Dec 20, 2022
基于多线程快速端口扫描脚本,支持目标批量导入、结果导出。

JWS_portscan 基于多线程快速端口扫描脚本,支持目标批量导入、结果导出。如果扫描公网资产,为了提升扫描的精准性,建议放到服务器运行。 用法 依赖安装:pip3 install -r requriement.txt 支持参数:python3 JWS_portscan.py --help 脚本

jammny 5 Apr 12, 2022
This Python script can be used to bypass IP source restrictions using HTTP headers.

ipsourcebypass This Python script can be used to bypass IP source restrictions using HTTP headers. Features 17 HTTP headers. Multithreading. JSON expo

Podalirius 322 Dec 28, 2022
Easy-to-setup bot, ChatOps project for handling telegram chat logging over docker-compose services, being runned as one of them.

Easy-to-setup bot, ChatOps project for handling telegram chat logging over docker-compose services, being runned as one of them.

Rashid 7 Aug 08, 2022
Real-time text-editor using python tcp socket

Real-time text-editor using python tcp socket This project does not need any external libraries so you don't need to use virtual environments. All you

MatiYo 3 Aug 05, 2022
Library containing the core modules for the kingdom-python-server.

🏰 Kingdom Core Library containing the core modules for the kingdom-python-server. Installation Use the package manager pip to install kingdom-core. p

T10 4 Dec 27, 2021
DEMO SOCKET AF INET SSL PYTHON

DEMO_SOCKET_AF_INET_SSL_PYTHON Python demo of socket family as AF_INET using TCP with SSL. Compatibility : macOS & GNU/Linux Network Topology style :

Enola 1 Jan 24, 2022
Some files casually made by @AneekBiswas

Python-Tools All Pyhthon Files are created and managed by @AneekBiswas Modules needed to be downloaded 1.CLI bagels.py random guess.py random text-tow

1 Feb 23, 2022
Proxlist - Retrieve proxy servers.

Finding and storing a list of proxies can be taxing - especially ones that are free and may not work only minutes from now. proxlist will validate the proxy and return a rotating random proxy to you

Justin Hammond 2 Mar 17, 2022
Process incoming JSON-RPC requests in Python

August 16, 2021: Version 5 has been released. Read about the changes in version 5, or read the full documentation. Version 5 is for Python 3.8+ only.

Exploding Labs 156 Dec 31, 2022
The module that allows the collection of data sampling, which is transmitted with WebSocket via WIFI or serial port for CSV file.

The module that allows the collection of data sampling, which is transmitted with WebSocket via WIFI or serial port for CSV file.

Nelson Wenner 2 Apr 01, 2022
A vpn that sits in your browser, accessible via a website

VPNInYourBrowser A vpn that sits in your browser, accessible via a website Example setup: https://VPNInBrowser.jaffa42.repl.co Setup Put the code onto

1 Jan 20, 2022
A simple DHCP server and client simulation with python

About The Project This is a simple DHCP server and client simulation. I implemented it for computer network course spring 2021 The client can request

shakiba 3 Feb 08, 2022
Simple client for the Sirah Matisse Commander TCP server.

Simple client for the Sirah Matisse Commander TCP server.

Nelson Darkwah Oppong 1 Nov 02, 2021
This tools just for education only - Layer-7 or HTTP FLOODER

Layer-7-Flooder This tools just for education only - Layer-7 or HTTP FLOODER Require Col1 Before You Run this tools How To Use Download This Source Ex

NumeX 7 Oct 30, 2022
D-dos attack GUI tool written in python using tkinter module

ddos D-dos attack GUI tool written in python using tkinter module #to use this tool on android, do the following on termux. *. apt update *. apt upgra

6 Feb 05, 2022
Fast and configurable script to get and check free HTTP, SOCKS4 and SOCKS5 proxy lists from different sources and save them to files

Fast and configurable script to get and check free HTTP, SOCKS4 and SOCKS5 proxy lists from different sources and save them to files. It can also get geolocation for each proxy and check if proxies a

Almaz 385 Dec 31, 2022
PySocks lets you send traffic through SOCKS proxy servers.

PySocks lets you send traffic through SOCKS proxy servers. It is a modern fork of SocksiPy with bug fixes and extra features. Acts as a drop-i

1.1k Dec 07, 2022
A simple tcpdump sidecar injector to demonstrate Kubernetes's Mutating Webhook

k8s-tcpdump-webhook A simple tcpdump sidecar injector to demonstrate Kubernetes's Mutating Webhook Build and Deploy Build docker image; docker build -

Bilal Ünal 2 Sep 01, 2022