Продолжаем разбираться в OpenSource генераторе трафика от Cisco - TRex. При разработке и внедрении сетевого оборудования критически важно проводить его тщательное тестирование. Маршрутизаторы и коммутаторы должны выдерживать заявленную нагрузку, правильно обрабатывать трафик на разных уровнях. 

Стандартизированные методики (например, RFC 2544) определяют, как измерять пропускную способность устройства без потерь и другие метрики. Ранее для таких испытаний широко применялись дорогостоящие аппаратные генераторы трафика (Ixia, Spirent и т.д.). Однако в условиях ограниченной доступности коммерческих решений всё более актуальными становятся открытые альтернативы. 

Одной из наиболее доступных и при этом мощных опций является бесплатный Open Source генератор трафика Cisco TRex. В продолжение предыдущей статьи рассмотрим, как с помощью Cisco TRex 3.06 провести комплексное тестирование производительности и функциональности сетевых устройств.

Обзор Cisco TRex (Stateless vs Stateful)

Кратко напомню, тем кто не читал предыдущей статьи. Cisco TRex - это программный комплекс для генерации сетевого трафика, способный работать как в stateless (без сохранения состояний), так и в stateful режимах. TRex разработан на основе DPDK и других оптимизаций пользовательского пространства, что позволяет ему напрямую работать с сетевыми картами и достигать высокой производительности. Инструмент поддерживает генерацию трафика уровня L3-L7 и реализует многие возможности, присущие дорогим аппаратным генераторам (эмуляция множества протоколов, поддержка до 200 Гбит/с и 10-30 млн пакетов/с на ядро CPU, гибкая настройка пакетов и т.д.).

TRex легко масштабируется с ростом вычислительных ресурсов и может использоваться даже в виртуальных средах. Главное его преимущество - это гибкость и программируемость: шаблоны трафика описываются кодом, а сам инструмент имеет API для автоматизации тестов. 

Режимы работы TRex

В stateless-режиме (интерфейс STL) TRex генерирует пакеты по заданным шаблонам без отслеживания каких-либо соединений. Этот режим предназначен для тестирования функций, не зависящих от состояний - например, производительности коммутаторов (L2), маршрутизаторов на уровне IP (L3) или любых устройств, обрабатывающих трафик покадрово (фильтрация, QoS).

В stateful-режиме (интерфейс ASTF) TRex эмулирует полноценные сессии с установлением соединений (например, TCP handshakes) и обменом данными, что необходимо при тестировании продвинутых функций на уровне L4-L7: NAT, Firewall/DPI, VPN и т.п. Stateful-режим поддерживает миллионы одновременных сессий и генерирует трафик сложных протоколов (HTTP, IPSec и др.) с учетом состояний.

Таким образом, выбор режима определяется типом тестируемого устройства: для «простых» L2/L3 пересылок достаточно stateless-пакетов, а для устройств, отслеживающих соединения (маршрутизаторы с NAT, межсетевые экраны, системы DPI), требуется stateful-трафик с поддержкой состояний.

Методика тестирования с учетом особенностей устройств

Каждое сетевое устройство имеет свои особенности, которые нужно учитывать при планировании тестов. Опытные инженеры перед началом испытаний составляют план сценариев, охватывающих ключевые функции оборудования:

  • Производительность L2/L3: базовый тест для коммутаторов и маршрутизаторов - измерение максимальной пропускной способности при различном размере пакета (например, 64, 128, 512, 1500 байт). TRex в stateless-режиме позволяет сформировать непрерывный поток Ethernet/IP-пакетов нужного размера и тем самым оценить предельный throughput без потерь (Non-Drop Rate). Тест проводится на каждом типе интерфейса или порта устройства, с постепенным повышением нагрузки до тех пор, пока не начнется потеря пакетов.

  • Тестирование NAT: для маршрутизаторов и брандмауэров с NAT критично проверить корректность трансляции адресов/портов и емкость NAT-таблицы. Здесь применяется stateful-генерация: TRex создает множество клиентских сессий (TCP/UDP) из «внутренней» сети во «внешнюю». Устройство DUT (Device Under Test) выполняет NAT для этих соединений. Важно убедиться, что все сессии успешно устанавливаются и возвращающийся трафик корректно мапится обратно. TRex способен обнаруживать подстановку адресов NAT на лету - он отслеживает, как DUT изменяет IP/порт первого пакета в потоке, и автоматически подставляет эти значения для ответного трафика, что позволяет тестировать NAT-прозрачность устройства. В ходе теста измеряются максимальное число одновременных сессий, которое поддерживает NAT, а также throughput и задержки при включенном NAT. Например, можно постепенно увеличивать количество новых соединений в секунду (CPS) до тех пор, пока устройство не перестанет справляться.

  • Тестирование DPI/Firewall: для межсетевых экранов с DPI необходимо подать реалистичный микс трафика верхних уровней (L7), чтобы проверить способность устройства распознавать протоколы и фильтровать нежелательные пакеты на высокой скорости. TRex предоставляет две стратегии: либо воспроизводить заранее записанный PCAP-трейс с разнообразным трафиком (Web, DNS, почта, видео и т.д.), либо использовать ASTF-профили, эмулирующие типичную работу клиентов и серверов. Преимущество TRex в том, что он может воспроизводить большие дампы трафика (до 1 ТБ), пригодные для тестирования DPI-систем. В сценарии DPI-теста нужно включить в профиль «вредоносный» или запрещенный трафик (например, сигнатуры атак, запрещённые URL) и убедиться, что устройство правильно идентифицирует и блокирует эти пакеты. Одновременно измеряется максимальная пропускная способность DPI без потерь.

  • Проверка списков доступа (ACL): если на маршрутизаторе/коммутаторе настроены ACL для фильтрации по IP, портам или протоколам, тестовый трафик должен проверить корректность этих правил. Сценарий обычно включает два потока: один должен разрешаться политиками другой - блокироваться. TRex в stateless-режиме упрощает такую проверку: можно настроить отдельные потоковые шаблоны под разрешенный и запрещенный трафик. После прогона сравнивается статистика - пакеты «разрешенного» потока должны успешно пройти через DUT, тогда как по запрещенному потоку не должно ничего поступить на выход. Также замеряется влияние активных ACL на задержки и throughput (как правило, сложные фильтры чуть снижают производительность, и это стоит учесть).

  • Поддержка L2/L3/L4-функций: для устройств с расширенными возможностями тесты нужно адаптировать. Например, для коммутатора L2 важно проверить не только скорость коммутации, но и поддержку VLAN: TRex позволяет генерировать трафик с тегами 802.1Q, проверяя обработку VLAN-тегов. Для маршрутизаторов L3 можно генерировать потоки с разными сетями источника/назначения, чтобы убедиться в правильности маршрутизации (DUT должен отправлять каждый поток в нужный интерфейс согласно своей таблице маршрутов). Для устройств L4 (скажем, балансировщиков нагрузки или прокси) стоит эмулировать множество одновременных подключений к разным портам и мониторить распределение трафика. В целом, методика тестирования должна покрывать все уровни, на которых оперирует устройство, - от проверки линковой связности (ARP, ND) до устойчивости под нагрузкой приложений.

Подготовившись к таким сценариям, можно переходить к развертыванию тестового стенда и непосредственному проведению испытаний.

Проверка производительности: throughput, задержки, потери

Определимся с тем, какие данные можно будет собрать. Одной из главных целей тестирования является определение производительности устройства. То есть используя TRex, можно собрать следующие ключевые метрики:

  • Throughput (пропускная способность): измеряется в Гбит/с или пакетах/с, как максимальная скорость трафика, при которой через устройство не теряется ни одного пакета (или приемлемый процент потерь). Для измерения throughput обычно используют бинарный поиск нагрузки: увеличивают генерируемый TRex трафик ступенчато, пока на принимающей стороне не начнут фиксироваться потери пакетов, затем уточняют границу. TRex предоставляет подробные счетчики по портам: сколько пакетов отправлено (TX) и получено (RX) на каждом интерфейсе. Например, если TRex на порту 0 отправил 1 000 000 пакетов, а на порту 1 принято 990 000, значит, 10 000 потеряны устройством - на такой нагрузке throughput превышает возможности DUT. Чтобы обеспечить чистоту эксперимента, стоит прогонять тесты на нескольких фиксированных размерах пакета (минимальный 64 байта, средние, максимальный 1500 байт) - это позволяет оценить, ограничен ли DUT по PPS (обычно слабое место - обработка мелких пакетов) или по полосе пропускания.

  • Latency (задержка): время прохождения пакета через устройство. TRex имеет встроенные средства измерения latency, но они возможны только при использовании определенных сетевых карт. В stateless-тестах можно включить режим latency stats, и TRex выдаст среднее/макс значение задержки и джиттера. В stateful-тестах TCP задержка часто оценивается по времени установления сессии (RTT 3-way handshake) или отклика на запрос. Например, TRex ASTF может показать, что медианная задержка SYN-SYN/ACK = 1.2 мс, а 99-й перцентиль = 5 мс, что укладывается в требования. 

  • Packet Loss (потери): доля пакетов, потерянных на устройстве при данной нагрузке, обычно выражается в процентах. TRex позволяет непосредственно вычислять потери, сравнив счетчики отправленных и полученных пакетов. В отчетах стоит фиксировать нагрузку, при которой потери = 0%, и нагрузку, при которой потери начинают расти. Это и есть граница производительности устройства. Также важно проверить, нет ли нестабильных потерь при нагрузках ниже максимальных - это может указывать на проблемы в буферизации DUT.

  • Дополнительные метрики: в зависимости от функций устройства, могут измеряться и другие показатели. Например, соединения в секунду (CPS) - особенно актуально для NAT и брандмауэров. TRex ASTF сам по себе генерирует CPS по профилю, и вы можете увидеть максимальное значение CPS, которое смог переварить DUT без обрывов. Одновременные сессии: важно для stateful-девайсов знать, сколько сеансов они выдерживают (TRex покажет, сколько сессий активно в каждый момент). Jitter (джиттер): разброс задержки, тоже выводится TRex как стандартная статистика - актуально для тестирования влияния устройства на время доставки в чувствительных к джиттеру приложениях (голос, видео). Если устройство заявляет поддержку QoS/приоритизации, можно проверить, действительно ли приоритетные потоки имеют меньший джиттер.

Проверка функциональности устройства (корректность обработки)

Помимо «сырой» производительности, важно убедиться, что устройство правильно выполняет заложенные функции. TRex поможет эмулировать различные ситуации и проверить логику работы DUT:

  • Маршрутизация и коммутация: отправьте через устройство несколько потоков с разными сетями назначения и проверьте, что каждый поток вышел через правильный порт (согласно таблице маршрутов). Например, TRex может одновременно генерировать трафик к адресам 10.0.1.0/24 и 10.0.2.0/24 - на двух разных потоках. Маршрутизатор должен направить их на разные интерфейсы. Если у TRex есть порты, соответствующие каждому интерфейсу, можно запустить прием на всех и убедиться, что пакеты пришли куда надо. Для L2-коммутатора полезно проверить изучение MAC‑адресов: TRex может сгенерировать трафик от множества разных MAC‑адресов (с помощью Field Engine - движка изменения полей пакета) и тем самым заполнить CAM-таблицу коммутатора, проверяя её емкость и корректность эвикции старых записей.

  • NAT корректность: в сценариях NAT важно проверить, что все сессии двунаправленно проходят через устройство. TRex Stateful при установлении каждого соединения фиксирует успешность (например, был ли получен ответ SYN-ACK на каждый SYN). Если какие-то сессии не устанавливаются, это сразу видно в статистике - значит, устройство могло исчерпать порты для трансляции или возникла ошибка в прошивке. Также проверяется, правильно ли NAT преобразует адреса в пакетах помимо IP-заголовка - например, протоколы, несущие IP внутри (FTP, SIP), часто требуют ALG. TRex поддерживает популярные клиентские протоколы, но специальные проверки ALG лежат вне его функций - их можно проверять разве что по логам DUT. Однако через TRex можно пустить имитацию FTP-сессий и убедиться, проходят ли они успешно через NAT (что косвенно подтверждает работу ALG на устройстве).

  • ACL и фильтрация: как описывалось, с помощью разделения трафика на несколько потоков можно проверить действие списков доступа. После теста сравните числа: TRex покажет 0 пакетов на выходе по потокам, соответствующим запрещенным правилам, и ненулевые значения - по разрешенным. Дополнительно стоит проверить отсутствие побочных эффектов: например, чтобы блокировка одного типа трафика не влияла на другой. Для этого запускаются одновременно разные протоколы (HTTP, DNS, ICMP) и отключаются/включаются правила - устройство должно блокировать только целевой трафик. TRex, как многофункциональный генератор, способен отправлять разные протоколы параллельно, что облегчает подобные проверки.

  • DPI/Firewall функции: тут проверка выходит за рамки просто «прошёл/не прошёл пакет». Если устройство умеет детектировать атаки или нежелательные сайты, то тестовый набор трафика должен содержать как «чистые», так и «злонамеренные» сессии. TRex, к примеру, может сэмулировать HTTP‑запросы к запрещённым доменам или отправить сигнатуры известных атак (базовые шаблоны можно встроить в полезную нагрузку пакетов). После прогона оценивается, заблокировал ли межсетевой экран именно эти сессии (они не дошли до получателя), и пропустил ли легитимные. Поскольку TRex не знает о решениях DPI на устройстве, результаты придётся сопоставлять вручную: например, смотреть в логах устройства сработавшие сигнатуры или измерять разницу в счётчике принятых пакетов между «чистым» и «вредоносным» трафиком. Тем не менее, возможность прокачать через DUT гигантский объём разнопланового трафика (например, суммарным размером в сотни гигабайт, включая видео, веб, почту и т. д.) очень ценна - она приближает тест к реальным условиям эксплуатации, чего трудно достичь обычными утилитами типа iperf.

  • Стресс-тесты и DDoS-атаки: цель этих тестов - имитация атак типа "отказ в обслуживании" (DoS/DDoS) для проверки устойчивости DUT к аномальному и вредоносному трафику. Это позволяет выявить уязвимости и ограничения устройств (таких как фаерволы, системы IPS/IDS) при высоких нагрузках, которые могут быть вызваны злонамеренными действиями. 

    • UDP Flood: Суть атаки: Отправка большого объема UDP-пакетов на случайные порты целевой системы. DUT вынужден тратить ресурсы на проверку каждого порта и отправку ответного сообщения ICMP «Port Unreachable», что приводит к исчерпанию его ресурсов. Протокол UDP не требует установки соединения и контроля состояния, что делает его идеальным вектором для быстрых и объемных атак, так как не требуется установка соединения или подтверждение доставки. В STL-режиме TRex генерирует UDP-пакеты с рандомизированными исходными IP-адресами и портами, а также целевыми случайными портами. Для увеличения нагрузки возможно использование фрагментации UDP, когда отправляются крупные фрагментированные UDP-пакеты, потребляющие больше пропускной способности и ресурсов DUT на попытки их пересборки.   

    • SYN Flood: Суть атаки: Отправка большого количества SYN-запросов к целевому серверу, но без завершения TCP-рукопожатия (отправки финального ACK). Это приводит к тому, что сервер выделяет ресурсы под «полуоткрытые» соединения, быстро исчерпывая свою таблицу соединений и другие ресурсы. С помощью TRex можно осуществить проверку способности DUT (например, фаервола, балансировщика нагрузки) противостоять атакам, использующим особенности TCP-стека и его механизмов управления соединениями. В STL-режиме TRex используется для создания потоков TCP SYN-пакетов с рандомизированными исходными IP-адресами и портами. 

  • Прочие функции: если устройство поддерживает балансировку нагрузки (ECMP или LACP), можно проверить равномерность распределения: TRex генерирует десятки потоков между одними и теми же узлами, а на выходе (несколько серверов или несколько линков) проверяется, как они распределились. Для устройств с QoS можно отправить трафик с разными DSCP/приоритетами и посмотреть, не превышают ли низкоприоритетные потоки выделенную полосу (TRex благодаря подробной статистике по потокам сразу покажет throughput каждого класса).

C помощью хорошо продуманных сценариев на TRex вы можете протестировать не только «быстродействие», но и правильность работы сетевого устройства в различных ситуациях. Любые обнаруженные отклонения (потери там, где их не должно быть, проход запрещенного трафика, завышенная задержка и т. д.) фиксируются как потенциальные проблемы, требующие доработки конфигурации или прошивки.

Сбор результатов и анализ метрик

После выполнения всех запланированных тестов наступает фаза сбора и анализа результатов. Желательно автоматизировать этот процесс настолько, насколько возможно, чтобы снизить человеческий фактор и ускорить получение отчетов. 

Данные от TRex. Сам генератор предоставляет обширную статистику через несколько интерфейсов. Если вы работали в интерактивной консоли, ключевая информация видна прямо в терминале: таблица по каждому порту (передано/получено пакетов и байт, потери, скорость), а также сводка по потокам (если включена). 

Например, консоль TRex может показывать в режиме реального времени, что порт 0 передаёт 14.88 Mpps, порт 1 принимает 14.7 Mpps, потери 0.5%, задержка средняя 3 мс. Эти цифры стоит записать или выгрузить. TRex позволяет сохранять статистику в JSON-файл через API или периодически по ZMQ-подписке - можно настроить, чтобы раз в N секунд снимались показания. 

Если вы использовали Python API для запуска трафика, то через те же объекты API можно получить итоговые counters. Например, client.get_stats() вернёт структуру с кучей метрик по каждому порту и каждому потоку. Этот вывод можно обработать скриптом: вычислить процент потерь, построить таблицу задержек (TRex даёт гистограмму, её тоже можно запросить). 

Хорошей практикой будет сразу по завершении теста автоматически сохранять эти данные - в лог или файлы CSV/JSON или складывать в БД. Тогда накопится база результатов, с которой удобно строить графики или сравнивать с предыдущими версиями устройства. 

Данные от DUT. Не забывайте проверять и состояние самого тестируемого устройства. Многие сетевые ОС позволяют снять снапшот статистики: количество пакетов на интерфейсах (вход/выход, дропы), загрузку CPU, заполненность аппаратных очередей, размер NAT-таблицы и т.д. В идеале, каждый тест сопровождается командой на DUT, снимающей такие показатели (например, show interface counters, show processes cpu и пр.). Эти сведения помогают интерпретировать результаты TRex. Например, если TRex зафиксировал рост задержки под нагрузкой, а на DUT видно 100% загрузки CPU на софтирутинге - это объясняет ситуацию узким местом в CPU. Или если throughput упёрся в 5 Gbps на 10G линке, и при этом в логах устройства появились дропы «Out of buffers» - значит, мы выявили недостаток буферизации.

Обработка и визуализация. После сбора все цифры надо свести воедино. Обычно делают итоговую таблицу производительности: там для каждого тестового случая (размер пакета, включен/выключен NAT, включены/выключены DPI/ACL) указывают достигнутый throughput (Гбит/с), латентность,% потерь. Отдельно выписываются максимальные CPS, максимальные соединения для stateful‑тестов. Если тестов много, удобно использовать электронную таблицу или написать скрипт генерации отчёта (вплоть до Markdown/LaTeX с таблицами). Графики тоже очень наглядны: к примеру, график «нагрузка vs потери» покажет, при каком уровне трафика кривая потерь резко идёт вверх (точка насыщения устройства).

Диагностика "черного ящика" через гранулированные метрики

Сетевые устройства часто функционируют как «черные ящики», что затрудняет точное определение внутренних причин деградации производительности. TRex устраняет эту проблему, предоставляя не только агрегированные, но и гранулированные статистики. В Stateless режиме это «per stream/group» статистика, а в Stateful режиме - статистика «per client side/per template», а также гистограммы задержки SYN/SYN-ACK и REQ/RES.   

Эта детализация позволяет инженерам точно локализовать источник проблем. Например, если только определенные типы L7-трафика (например, HTTPS) или потоки с конкретными характеристиками (например, очень маленькие пакеты) демонстрируют высокую задержку или потери, это указывает на конкретный компонент или функцию DUT (например, модуль обработки TLS, движок DPI) как на источник проблемы, а не на общую перегрузку устройства. Это несколько преображает процесс отладки из догадок в целенаправленный и высокоэффективный анализ, значительно сокращая время, необходимое для выявления и устранения узких мест в производительности сетевого оборудования.

Конфигурация тестового стенда

Успех тестирования во многом зависит от корректной настройки стенда. В минимальном варианте стенд включает сервер с Cisco TRex и устройство, которое нужно тестировать (DUT). TRex-сервер должен иметь в идеале два сетевых порта (порт A и порт B), подключенные к входу и выходу DUT - чтобы генерировать трафик «до» и «после» тестируемого устройства. 

Например, при тестировании домашнего маршрутизатора один порт TRex подключается к интерфейсу маршрутизатора в локальной сети, а второй - к интерфейсу в внешней сети (WAN). Для коммутатора оба порта TRex можно подключить к двум портам коммутатора (в один VLAN) - TRex будет отправлять кадры в коммутатор через порт A, а получать через порт B. В случае тестирования брандмауэра (Firewall) схема аналогична маршрутизатору: порт A имитирует «внутреннюю» сторону, порт B - «внешнюю». 

Важно: никакие другие устройства между TRex и DUT на время теста не должны вносить ограничения пропускной способности, иначе измерения будут неточными.

Аппаратные требования к TRex. Поскольку TRex генерирует трафик на высокой скорости, сервер под него должен быть достаточно мощным. 

  • Рекомендуется современный Intel CPU с поддержкой DPDK. Для 10 Гбит/с нагрузки - минимум 4 ядра (с Hyper-Threading); для 100 Гбит/с - пропорционально больше. 

  • TRex активно использует HugePages (большие страницы памяти) и требует снять ограничение на IOMMU/PCI для прямого доступа к сетевым картам. 

  • Сетевые адаптеры должны поддерживаться DPDK (Intel X710/XL710, Intel E810, Mellanox ConnectX и др., в режиме PCI passthrough или bind to DPDK driver). 

  • Следует отключить энергоэффективные функции и IRQ на тестовых портах, поскольку DPDK-пакетный движок сам управляет портами в режиме опроса (Polling) без прерываний - это снижает задержки и повышает стабильность результатов.

  • Важно изолировать ядра на которых будут работать воркеры TRex от выполнения на них других задач из планировщика ядра.

Настройка TRex. После установки TRex (распаковки архива с версией 3.06) нужно указать, какие порты будет использовать генератор. Для этого редактируется файл конфигурации (обычно /etc/trex_cfg.yaml). В нем задаются PCI-адреса сетевых интерфейсов и число портов. Пример минимальной конфигурации на 2 порта (port_limit: 2) с указанием PCI-адресов может выглядеть так:

- version       : 2 
  interfaces    : ["0000:af:00.0","0000:af:00.1"]  
  port_limit      : 2

В данном примере TRex будет использовать два интерфейса. Если ядер CPU много, TRex позволяет тонко настроить привязку потоков к ядрам (параметры master_thread_id, latency_thread_id, dual_if и threads) для максимальной производительности. В расширенном варианте конфига, в котором определяются номера воркеров по потокам CPU, в особенности для многопроцессорных систем, можно использовать следующий конфиг:

- port_limit         : 4
  version            : 3
  interfaces         : ["0000:af:00.0","0000:af:00.1","0000:af:00.2","0000:af:00.3"]   
  port_bandwidth_gb  : 10
  c                  : 8
  platform :
    master_thread_id  : 0
    latency_thread_id : 25
    dual_if:
      - socket : 1
        threads : [17,18,19,20,21,22,23,24]
      - socket : 1
        threads : [9,10,11,12,13,14,15,16]

Однако для начала можно оставить настройку по умолчанию. После правки конфига TRex запускается командой, например:

sudo ./t-rex-64 -i --cfg /etc/trex_cfg.yaml

Ключ -i переводит TRex в интерактивный режим консоли. При успешном запуске в логах TRex отобразит информацию об инициализации портов (их MAC-адреса, статус Link Up, скорость и т.д.).

Убедитесь, что оба порта Link Up и подключение к DUT действительно установлено (например, индикаторы на сетевых картах и портах устройства горят). 

Далее, необходимо настроить само тестируемое устройство DUT под сценарий. Если это маршрутизатор, сконфигурируйте на нём IP-адреса на двух интерфейсах, соответствующие сетям, которые будет эмулировать TRex. 

Например, TRex может генерировать IPv6-трафик с источниками fd00:1::0/64 и назначениями fd00:2::0/64 - тогда на маршрутизаторе интерфейс A должен иметь адрес в сети fd00:1::1/64, интерфейс B - в сети fd00:2::1/64, и между ними настроен маршрут (или NAT, если требуется). 

Для DPI/Firewall убедитесь, что необходимые политики (правила DPI, ACL) на устройстве включены. В случае коммутатора достаточно, чтобы порты, куда подключен TRex, были в одном VLAN (если тестируем L2 коммутацию) или соответствовали настройкам VLAN-тегов, которые вы будете отправлять. Когда стенд сконфигурирован и TRex запущен, можно переходить к написанию и запуску тестовых сценариев генерации трафика.

Генерация пакетов в Stateless-режиме (STL)

Давайте рассмотрим реальный кейс в котором необходимо протестировать производительность софтового маршрутизатора построенного на базе промышленного ПК со следующей аппаратной конфигурацией:

  • Intel(R) Core(TM) i7-10700TE CPU @ 2GHz, 8 cores с поддержкой HyperThreading.

  • 64 Gb RAM

  • SSD 256 Gb x 2

  • Intel Corporation Ethernet Controller E810-C for SFP

  • 4 ports x 10G

  • Linux Ubuntu 22.04.4 LTS

  • VPP v24.06 stable with DPDK plugin

  • DPDK Driver vfio-pci

В качестве генератора трафика будет использоваться обычный стоечный одноюнитовые сервер с конфигурацией:

  • Intel(R) Xeon(R) Gold 6226R CPU @ 2.90GHz, 16 cores  с поддержкой HyperThreading.

  • 256 Gb RAM

  • 1024 Gb SSD 2 x2

  • Intel Corporation Ethernet Controller X710 for 10GbE SFP+

  • 4 ports x 10G

  • Linux Ubuntu 22.04.4 LTS

  • Cisco TRex v3.06

Сама схема тестирования выглядит следующим образом. В случае с тестированием из порта в порт - левая схема, в случае тестирования при использовании всех 4-х портов - справа: 

Сценарий тестирования предельно прост:

  1. Настраиваем DUT;

  2. Запускаем сервер TRex с нужным нам конфигом, чтобы обеспечить нужный объем пакетов в секунду;

  3. Подготавливаем профиль трафика под нужные сетевые настройки;

  4. Запускаем трафик на необходимое количество времени;

  5. Снимаем результаты теста, при необходимости дебажим тест и начинаем заново.

Перейдем сначала к настройке DUT. Открываем сессию SSH и производим базовую настройку. Проверяем что порты DUT находятся в DPDK:

root@intel-corei7-64:~# python3 /usr/bin/dpdk-devbind.py --status

Network devices using DPDK-compatible driver
============================================
0000:01:00.0 'Ethernet Controller E810-C for SFP 1593' drv=uio_pci_generic unused=ice
0000:01:00.1 'Ethernet Controller E810-C for SFP 1593' drv=uio_pci_generic unused=ice
0000:01:00.2 'Ethernet Controller E810-C for SFP 1593' drv=uio_pci_generic unused=ice
0000:01:00.3 'Ethernet Controller E810-C for SFP 1593' drv=uio_pci_generic unused=ice
0000:02:00.0 'I210 Gigabit Network Connection 1533' drv=uio_pci_generic unused=

Network devices using kernel driver
===================================
0000:00:1f.6 'Ethernet Connection (11) I219-LM 0d4c' if=eth0 drv=e1000e unused=uio_pci_generic *Active*

No 'Baseband' devices detected
==============================

No 'Crypto' devices detected
============================

No 'DMA' devices detected
=========================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
==============================

No 'Misc (rawdev)' devices detected
===================================

No 'Regex' devices detected
===========================

No 'ML' devices detected
========================

После заходим в консоль VPP и производим простую настройку. Сначала перезагружаем VPP чтобы сбросить сетевые настройки:

$ systemctl restart vpp

Далее настраиваем интерфейсы DUT с VLAN:

$ vppctl create sub-interfaces TwentyFiveGigabitEthernet1/0/0 3003 dot1q 3003 exact-match
$ vppctl create sub-interfaces TwentyFiveGigabitEthernet1/0/1 3004 dot1q 3004 exact-match
$ vppctl create sub-interfaces TwentyFiveGigabitEthernet1/0/2 3005 dot1q 3005 exact-match
$ vppctl create sub-interfaces TwentyFiveGigabitEthernet1/0/3 3006 dot1q 3006 exact-match

Поднимаем их:

$ vppctl set interface state TwentyFiveGigabitEthernet1/0/0 up
$ vppctl set interface state TwentyFiveGigabitEthernet1/0/0.3003 up

$ vppctl set interface state TwentyFiveGigabitEthernet1/0/1 up
$ vppctl set interface state TwentyFiveGigabitEthernet1/0/1.3004 up

$ vppctl set interface state TwentyFiveGigabitEthernet1/0/2 up
$ vppctl set interface state TwentyFiveGigabitEthernet1/0/2.3005 up

$ vppctl set interface state TwentyFiveGigabitEthernet1/0/3 up
$ vppctl set interface state TwentyFiveGigabitEthernet1/0/3.3006 up

Прописываем IP-адреса:

$ vppctl set interface ip address TwentyFiveGigabitEthernet1/0/0.3003 fd00:1::1/64
$ vppctl set interface ip address TwentyFiveGigabitEthernet1/0/1.3004 fd00:2::1/64
$ vppctl set interface ip address TwentyFiveGigabitEthernet1/0/2.3005 fd00:3::1/64
$ vppctl set interface ip address TwentyFiveGigabitEthernet1/0/3.3006 fd00:4::1/64

Далее необходимо вручную прописать ND-записи, чтобы маршрутизатор знал своих “соседей”:

$ vppctl set ip neighbor TwentyFiveGigabitEthernet1/0/0.3003 fd00:1::2 {trex_port0_mac}
$ vppctl set ip neighbor TwentyFiveGigabitEthernet1/0/1.3004 fd00:2::2 {trex_port1_mac}
$ vppctl set ip neighbor TwentyFiveGigabitEthernet1/0/2.3005 fd00:3::2 {trex_port2_mac}
$ vppctl set ip neighbor TwentyFiveGigabitEthernet1/0/3.3006 fd00:4::2 {trex_port3_mac}

Прописываем маршруты: 

$ vppctl ip route add fd00:cafe::/32 via fd00:1::2 TwentyFiveGigabitEthernet1/0/0.3003
$ vppctl ip route add fd00:feed::/32 via fd00:2::2 TwentyFiveGigabitEthernet1/0/1.3004
$ vppctl ip route add fd00:beef::/32 via fd00:3::2 TwentyFiveGigabitEthernet1/0/2.3005
$ vppctl ip route add fd00:deaf::/32 via fd00:4::2 TwentyFiveGigabitEthernet1/0/3.3006

После этого переходим к запуску сервера TRex и первым делом настроим его вручную. Проверим корректность настроек встроенными средствами диагностики и запустим трафик. Проверим, назначены ли порты под управление DPDK:

megalloid@tn2:/opt/trex/v3.06$ sudo ./dpdk_setup_ports.py -t
+----+------+---------+-------------------+-----------------------------------------+----------+----------+--------+
| ID | NUMA |   PCI   |        MAC        |                  Name                   |  Driver  | Linux IF | Active |
+====+======+=========+===================+=========================================+==========+==========+========+
| 0  | 0    | 1c:00.0 | 3c:ec:ef:00:00:00 | Ethernet Connection X722 for 10GBASE-T  | i40e     | eno1     |        |
+----+------+---------+-------------------+-----------------------------------------+----------+----------+--------+
| 1  | 0    | 1c:00.1 | 3c:ec:ef:00:00:00 | Ethernet Connection X722 for 10GBASE-T  | i40e     | eno2     |        |
+----+------+---------+-------------------+-----------------------------------------+----------+----------+--------+
| 2  | 1    | af:00.0 | 6c:b3:11:00:00:00 | Ethernet Controller X710 for 10GbE SFP+ | vfio-pci |          |        |
+----+------+---------+-------------------+-----------------------------------------+----------+----------+--------+
| 3  | 1    | af:00.1 | 6c:b3:11:00:00:00 | Ethernet Controller X710 for 10GbE SFP+ | vfio-pci |          |        |
+----+------+---------+-------------------+-----------------------------------------+----------+----------+--------+
| 4  | 1    | af:00.2 | 6c:b3:11:00:00:00 | Ethernet Controller X710 for 10GbE SFP+ | vfio-pci |          |        |
+----+------+---------+-------------------+-----------------------------------------+----------+----------+--------+
| 5  | 1    | af:00.3 | 6c:b3:11:00:00:00 | Ethernet Controller X710 for 10GbE SFP+ | vfio-pci |          |        |
+----+------+---------+-------------------+-----------------------------------------+----------+----------+--------+

Так. С портами все в порядке. О настройке и подготовке сервера я писал в предыдущей статье. Не буду отдельно на этом акцентировать внимание. 

Далее запускаю TRex-сервер вот таким образом:

megalloid@server:/opt/trex/v3.06$ ./t-rex-64 -i --cfg /opt/trex/v3.06/configs/server_full_config.yaml --arp-refresh-period 30 -v 8

Запускается сервер в интерактивном режиме, с указанием директории в которой хранится конфигурация и указано руками время обновления ARP-записей в 30 секунд и уровень отладочного вывода на отметке DEBUG. После запуска сервера мы получим следующий лог: 

WARNING: tried to configure 2 hugepages for socket 0, but result is: 1
Starting Scapy server.... Scapy server is started
The ports are bound/configured.
Starting  TRex v3.06 please wait  ... 
Using configuration file /opt/trex/v3.06/configs/server_full_config.yaml 
 port limit     :  4 
 port_bandwidth_gb    :  10 
 port_speed           :  0 
 port_mtu             :  0 
 if_mask        : None 
 is low-end : 0 
 stack type :  
 thread_per_dual_if      : 8 
 if        :  0000:af:00.0, 0000:af:00.1, 0000:af:00.2, 0000:af:00.3,
 enable_zmq_pub :  1 
 zmq_pub_port   :  4500 
 m_zmq_rpc_port    :  4501 
 memory per 2x10G ports  
 MBUF_64                                   : 16380 
 MBUF_128                                  : 8190 
 MBUF_256                                  : 8190 
 MBUF_512                                  : 8190 
 MBUF_1024                                 : 8190 
 MBUF_2048                                 : 4095 
 MBUF_4096                                 : 128 
 MBUF_9K                                   : 512 
 TRAFFIC_MBUF_64                           : 65520 
 TRAFFIC_MBUF_128                          : 32760 
 TRAFFIC_MBUF_256                          : 8190 
 TRAFFIC_MBUF_512                          : 8190 
 TRAFFIC_MBUF_1024                         : 8190 
 TRAFFIC_MBUF_2048                         : 32760 
 TRAFFIC_MBUF_4096                         : 128 
 TRAFFIC_MBUF_9K                           : 512 
 MBUF_DP_FLOWS                             : 524288 
 MBUF_GLOBAL_FLOWS                         : 5120 
 master   thread  : 0  
 rx  thread  : 25  
 dual_if : 0 
    socket  : 1  
   [   17   18   19   20   21   22   23   24     ]  
 dual_if : 1 
    socket  : 1  
   [   9   10   11   12   13   14   15   16     ]  
CTimerWheelYamlInfo does not exist  
 set driver name net_i40e 
 driver capability  : TCP_UDP_OFFLOAD  TSO  SLRO 
 set dpdk queues mode to DROP_QUE_FILTER 
 Number of ports found: 4
Loading DDP profile (0) Profile is already loaded 
Loading DDP profile (1) Profile is already loaded 
Loading DDP profile (2) Profile is already loaded 
Loading DDP profile (3) Profile is already loaded 
zmq publisher at: tcp://*:4500
 A workaround is applied for issue #508 
 A workaround is applied for issue #508 
 A workaround is applied for issue #508 
 A workaround is applied for issue #508 
 wait 1 sec .
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 
port : 2 
------------
link         :  link : Link Up - speed 10000 Mbps - full-duplex
promiscuous  : 0 
port : 3 
------------
link         :  link : Link Up - speed 10000 Mbps - full-duplex
promiscuous  : 0 
 number of ports         : 4 
 max cores for 2 ports   : 8 
 tx queues per port      : 10 
 -------------------------------
RX core uses TX queue number 8 on all ports
 core, c-port, c-queue, s-port, s-queue, lat-queue
 ------------------------------------------
 1        0      0       1       0      9  
 2        2      0       3       0      9  
 3        0      1       1       1    255  
 4        2      1       3       1    255  
 5        0      2       1       2    255  
 6        2      2       3       2    255  
 7        0      3       1       3    255  
 8        2      3       3       3    255  
 9        0      4       1       4    255  
 10        2      4       3       4    255  
 11        0      5       1       5    255  
 12        2      5       3       5    255  
 13        0      6       1       6    255  
 14        2      6       3       6    255  
 15        0      7       1       7    255  
 16        2      7       3       7    255  
 -------------------------------

Откроется постоянно обновляющееся меню статистики:

-Per port stats table 
      ports |               0 |               1 |               2 |               3 
 -----------------------------------------------------------------------------------------
   opackets |               0 |               0 |               0 |               0 
     obytes |               0 |               0 |               0 |               0 
   ipackets |               0 |               0 |               0 |               0 
     ibytes |               0 |               0 |               0 |               0 
    ierrors |               0 |               0 |               0 |               0 
    oerrors |               0 |               0 |               0 |               0 
      Tx Bw |       0.00  bps |       0.00  bps |       0.00  bps |       0.00  bps 

-Global stats enabled 
 Cpu Utilization : 0.0  %
 Platform_factor : 1.0  
 Total-Tx        :       0.00  bps  
 Total-Rx        :       0.00  bps  
 Total-PPS       :       0.00  pps  
 Total-CPS       :       0.00  cps  

 Expected-PPS    :       0.00  pps  
 Expected-CPS    :       0.00  cps  
 Expected-BPS    :       0.00  bps  

 Active-flows    :        0  Clients :        0   Socket-util : 0.0000 %    
 Open-flows      :        0  Servers :        0   Socket :        0 Socket/Clients :  -nan 
 drop-rate       :       0.00  bps   
 current time    : 2.0 sec  
 test duration   : 0.0 sec  

Переходим в интерактивную Python-консоль, которая находится в корневой директории с TRex:

megalloid@server:/opt/trex/v3.06$ ./trex-console -f

Using 'python3' as Python interpeter

Connecting to RPC server on localhost:4501                   [SUCCESS]
Connecting to publisher server on localhost:4500             [SUCCESS]
Force acquiring ports [0, 1, 2, 3]:                          [SUCCESS]

*** Warning - Port 0 destination is unresolved ***
*** Warning - Port 1 destination is unresolved ***
*** Warning - Port 2 destination is unresolved ***
*** Warning - Port 3 destination is unresolved ***

Server Info:

Server version:   v3.06 @ STL
Server mode:      Stateless
Server CPU:       16 x Intel(R) Xeon(R) Gold 6226R CPU @ 2.90GHz
Ports count:      4 x 10Gbps @ Ethernet Controller X710 for 10GbE SFP+	

-=TRex Console v3.0=-

Type 'help' or '?' for supported actions

trex>

Сначала проверим, подняты ли линки интерфейсов и необходимо пропинговать соседа:

trex>portattr
Port Status

     port       |          0           |          1           |          2           |          3           
----------------+----------------------+----------------------+----------------------+---------------------
driver          |       net_i40e       |       net_i40e       |       net_i40e       |       net_i40e       
description     | Ethernet Controlle   | Ethernet Controlle   | Ethernet Controlle  | Ethernet Controlle 
link status     |          UP          |          UP          |          UP          |          UP          
link speed      |       10 Gb/s        |       10 Gb/s        |       10 Gb/s        |       10 Gb/s        
port status     |         IDLE         |         IDLE         |         IDLE         |         IDLE         
promiscuous     |         off          |         off          |         off          |         off          
multicast       |         off          |         off          |         off          |         off          
flow ctrl       |         none         |         none         |         none         |         none         
vxlan fs        |          -           |          -           |          -           |          -           
--              |                      |                      |                      |                      
layer mode      |       Ethernet       |       Ethernet       |       Ethernet       |       Ethernet       
src IPv4        |          -           |          -           |          -           |          -           
IPv6            |         off          |         off          |         off          |         off          
src MAC         | 6c:b3:11:00:00:00    | 6c:b3:11:00:00:00    | 6c:b3:11:00:00:00    | 6c:b3:11:00:00:00   
---             |                      |                      |                      |                      
Destination     |     unconfigured     |     unconfigured     |     unconfigured     |     unconfigured     
ARP Resolution  |          -           |          -           |          -           |          -           
----            |                      |                      |                      |                      
VLAN            |          -           |          -           |          -           |          -           
-----           |                      |                      |                      |                      
PCI Address     |     0000:af:00.0     |     0000:af:00.1     |     0000:af:00.2     |     0000:af:00.3     
NUMA Node       |          1           |          1           |          1           |          1           
RX Filter Mode  |    hardware match    |    hardware match    |    hardware match    |    hardware match    
RX Queueing     |         off          |         off          |         off          |         off          
Grat ARP        |         off          |         off          |         off          |         off          
------          |                      |                      |                      |                      

trex>

Далее настроим интерфейсы, для этого необходимо перевести интерфейсы в service mode. Режим service в консоли TRex позволяет временно вернуть контроль над интерфейсом TRex операционной системе Linux (например, чтобы выполнить scan6 для выяснения MAC-адреса соседей):

trex> service
Enabling service mode on port(s): [0, 1, 2, 3]               [SUCCESS]
39.56 [ms]

Присвоим им VLAN-ы:

trex(service)>vlan -p 0 --vlan 3003
Setting port(s) [0] with VLAN '3003':                        [SUCCESS]
13.07 [ms]

trex(service)>vlan -p 1 --vlan 3004
Setting port(s) [1] with VLAN '3004':                        [SUCCESS]
18.49 [ms]

trex(service)>vlan -p 2 --vlan 3005
Setting port(s) [2] with VLAN '3005':                        [SUCCESS]
10.68 [ms]

trex(service)>vlan -p 3 --vlan 3006
Setting port(s) [3] with VLAN '3006':                        [SUCCESS]
10.79 [ms]

Прописываем соседства c MAC-адресами портов DUT:

trex(service)>l2 -p 0 --dst 6c:b3:11:00:00:00
Setting port 0 in L2 mode:                                   [SUCCESS]
15.92 [ms]

trex(service)>l2 -p 1 --dst 6c:b3:11:00:00:00
Setting port 1 in L2 mode:                                   [SUCCESS]
11.52 [ms]

trex(service)>l2 -p 2 --dst 6c:b3:11:00:00:00
Setting port 2 in L2 mode:                                   [SUCCESS]
17.10 [ms]

trex(service)>l2 -p 3 --dst 6c:b3:11:00:00:00
Setting port 3 in L2 mode:                                   [SUCCESS]
12.99 [ms]

Отключаем все ненужные опции:

trex>portattr -p0 --mult off 
Applying attributes on port(s) [0]:                          [SUCCESS]

trex>portattr -p1 --mult off 
Applying attributes on port(s) [1]:                          [SUCCESS]

trex>portattr -p2 --mult off 
Applying attributes on port(s) [2]:                          [SUCCESS]

trex>portattr -p3 --mult off 
Applying attributes on port(s) [3]:                          [SUCCESS]

После необходимо выйти из сервисного режима:

trex(service)> service --off

Создаем на сервере профиль трафика, который описывается простейшим Python-скриптом, в котором с помощью  Scapy описываются заголовки будущих пакетов. В моем случае получился следующий скрипт:

from trex_stl_lib.api import *
from scapy.all import *
from scapy.utils import PcapWriter

class STLS1(object):

    def get_streams(self, **kwargs):

        print(f"     Content of traffic profile: \n\r\n\r{json.dumps(kwargs, indent = 4)}\n\r")

        pkt = Ether(src = '6c:b3:11:00:00:00', dst = '6c:b3:11:00:00:00')/\
              Dot1Q(vlan = 3003)/\
              IPv6(src = 'fd00:1::2', dst = 'fd00:2::2')/\
              UDP(sport = 12345, dport = 12345)/\
              (1*'x')

        pktdump = PcapWriter("packet.pcap", append=True, sync=True)
        pktdump.write(pkt)

        stream = STLStream(name = 's0', packet = STLPktBuilder(pkt = pkt), mode = STLTXCont(pps = 100))

        return stream

def register():

    return STLS1()

Этот пример демонстрирует минимальную настройку. В реальности вы можете добавлять несколько потоков, использовать генератор полей для перебора адресов/портов, и пр. По такой же аналогии, если необходимо, добавляются профили трафика для других портов.

Возвращаемся в консоль TUI и запускаем поток с порта номер 0 (он же 1-й порт на сетевой карте сервера):

tui> start -p0 -f traffic_profiles/vpp_vlan_ipv6_udp_67b.py -m 1mpps -d 60

Команда запустит профиль трафика из директории TRex в количестве 1Mpps на 60 секунд. Если зайти в консоль tui - то можно увидеть как трафик идет из порта в порт:

Если захотелось остановить поток трафика на выбранно порту остановить можно командой:

tui> stop -p0 

После окончания теста сверяем счетчики, количество отправленных пакетов должно совпадать с количеством полученных. Генерация и счетчики работают довольно стабильно и можно доверять результатам тестирования.  

Neighbor Discovery в TRex

Рассмотрим практический пример, как автоматически выполнить Neighbor Discovery и использовать полученные данные. Предположим, TRex должен отправлять трафик с порта 0 к узлу с IPv6-адресом 2001:db8:1::1 (например, маршрутизатору). TRex на своем порту будет “представляться” адресом 2001:db8:1::2.

Вместо ручного указания MAC-адреса соседа, можно воспользоваться плагином ND:


from trex_stl_lib.api import STLClient
from trex_stl_lib.services.trex_stl_service_IPv6ND import STLServiceIPv6ND

# Инициализация клиента и порта
c = STLClient()
c.connect()
c.acquire(ports=[0], force=True)

# Перевод порта 0 в service mode
c.set_service_mode(ports=[0])

try:
    # Создаем контекст сервиса на порту 0
    ctx = c.create_service_ctx(port=0)
    # Определяем сервис IPv6ND с указанием исходного и целевого IPv6
    nd_service = STLServiceIPv6ND(ctx,
                                  src_ip="2001:db8:1::2",
                                  dst_ip="2001:db8:1::1")
    # Запускаем Neighbor Discovery
    ctx.run(nd_service)
    # Получаем результат резолвинга
    result = nd_service.get_record()
    print("Результат ND:", result)
finally:
    # Возвращаем порт из service mode в обычный режим
    c.set_service_mode(ports=[0], enabled=False)

При запуске этот код сформирует и отправит ICMPv6 Neighbor Solicitation от 2001:db8:1::2 на искомый адрес 2001:db8:1::1. Если сосед доступен, TRex получит Neighbor Advertisement с его MAC-адресом. Метод get_record() вернет запись о соседе - в нее входит, в частности, обнаруженный MAC-адрес целевого узла. Например, вывод может быть примерно таким (формат может различаться):

Результат ND:

{
   'dst_ip': '2001:db8:1::1', 
   'dst_mac': '00:11:22:33:44:55', 
   'src_ip': '2001:db8:1::2', ...
}

Далее этот MAC можно программно вставить в Ether-заголовок тестовых пакетов. Например, при генерации потоков через STLPktBuilder укажите Ether(dst=result['dst_mac'], src=<ваш_src_mac>). Теперь потоки TRex будут содержать корректный MAC назначения, полученный автоматически, и доставляться до узла. Обратите внимание: после выполнения ND мы отключаем service mode на порту, чтобы вернуть TRex в режим высокопроизводительной генерации трафика. Service mode предназначен для контрольных операций и работает существенно медленнее обычного режима передачи пакетов поэтому его используют только на этапе подготовки (резолвинг адресов, DHCP-запросы и пр.), а затем выключают перед отправкой основного трафика.

При внедрении автоматического Neighbor Discovery в тесты с TRex учтите следующие моменты:

  • Только для смежных L2-сетей: Плагин ND работает аналогично ARP - он обнаруживает локальных IPv6-соседей в пределах одного L2-домена. Это не решает задачу маршрутизации. Если целевой IPv6-адрес находится за роутером, TRex не сможет напрямую получить его MAC через ND. В таких случаях вам придется либо настроить на TRex отправку трафика на MAC шлюза по умолчанию, либо использовать TRex ASTF/EMU с поддержкой маршрутизации. В stateless-режиме же ND полезен главным образом для резолвинга адреса прямо подключенного соседа (например, следующего hops). Как правило, это используется, чтобы узнать MAC адрес шлюза по умолчанию (роутера) или другого устройства, к которому TRex подключен на канальном уровне.

  • Отсутствие полноценного IPv6-стека: TRex в stateless-режиме не является полноправным IPv6-узлом - он не поддерживает SLAAC, Router Advertisement, и не хранит долговременно IPv6-адреса на интерфейсах. Все операции ND - пользовательские, через сервис. Например, нельзя просто командой настроить IPv6 на порту TRex (попытка через консоль ipv6 -p <port> -s <addr> завершится ошибкой: “IPv6 is not supported with current stack”). Поэтому если ваш сценарий подразумевает, что TRex должен принимать входящий IPv6-трафик, одного ND недостаточно - TRex по-прежнему “без стеков” и ответные пакеты могут не иметь куда доставляться. ND-плагин предназначен именно для исходящего трафика, когда нужно узнать MAC-адреса получателей, чтобы корректно сформировать Ethernet-заголовки.

  • Ручное применение результата: Полученный через ND MAC-адрес не применяется автоматически ко всем потокам - TRex не перезаписывает уже созданные пакеты. В GUI это сделано прозрачно (сканируя соседа, вы фактически настраиваете MAC в профиле), а при использовании Python API или YAML-профилей нужно самостоятельно подставить обнаруженные MAC в описание потоков. Рекомендуется встроить вызов ND-сервиса в подготовительный этап теста: т.е. до запуска генерации трафика получить MAC соседей, скорректировать конфигурацию кадров, и только затем запускать startTraffic. Если у вас множество потоков с разными целевыми IPv6, можно выполнить несколько ND-запросов. Плагин поддерживает параллельный резолвинг - параметр count (-c) позволит запустить несколько NS одновременно, автоматически увеличивая, например, адрес источника. НО помните, что за один запуск ctx.run() можно обработать по умолчанию до 1000 сервис-инстансов. В большинстве практических случаев этого достаточно (сканировать тысячи адресов одновременно обычно не требуется).

  • Производительность и время: Выполнение Neighbor Discovery - сравнительно медленная операция, так как включает обмен ICMPv6 сообщениями и ожидание ответов. Каждый запрос по умолчанию ждет до 2 секунд ответа. Если вы сканируете много адресов или ваш сосед откликается не сразу, это может внести задержку в начало теста. Планируйте это в тайминг тестового прогона. Вы можете настроить timeout и retries по необходимости. Например, если знаете, что устройство может не ответить мгновенно, увеличьте таймаут или количество попыток. Если же хотите ускорить и не ждать лишнего, можете уменьшить таймаут (но есть риск не получить ответ, если сосед не успеет ответить).

  • Совместимость с оборудованием: В целом, плагин IPv6ND работает со всеми сетевыми картами, поддерживаемыми TRex (DPDK-портами). Особых требований к NIC нет - ND посылает обычные Ethernet+IPv6 пакеты. Тем не менее, в виртуальных средах (VF, SR-IOV, виртуальные свичи) убедитесь, что ваш хост/гипервизор не блокирует мультикаст-сообщения ff02::/16. Например, solicited-node multicast адрес, на который TRex отправляет NS, имеет MAC вида 33:33:xx:xx:xx:xx. Обычно DPDK-порт TRex находится в promisc режиме и получит ответ NA, адресованный его собственному MAC. Но если существуют фильтры на уровне vswitch (Open vSwitch, etc.) или политики безопасности (например, отключен IPv6 ND snooping или RA Guard), они могут мешать обмену NDP. Практическая рекомендация - предварительно проверить, проходит ли обычный ping6 между TRex-хостом и соседним устройством вне TRex (например, настроив временно IP на интерфейсе ОС). Это даст уверенность, что на уровне сети ICMPv6 не блокируется.

Пример ограничения: в некоторых ОС/оборудовании ответы на NS для link-local адресов могут отличаться от глобальных. TRex обычно использует global или link-local адрес источника. Если вы столкнулись с тем, что соседи не отвечают на NS, попробуйте использовать link-local адрес TRex как источник (или наоборот, global) - поведение может зависеть от реализации стека соседа. Однако в общем случае, любой NS, пришедший по каналу, должен быть обработан узлом, чей IPv6 равен запрашиваемому (RFC4861 требует отправки NA в ответ на запрос, если целевой адрес сопоставим с одним из адресов узла, вне зависимости от адреса источника, если он на одной связи).

Логирование и отладка: Если ND не удаётся (нет ответа), используйте verbose_level=STLServiceIPv6ND.INFO или флаг -V в консоли. Это покажет, были ли отправлены NS, были ли получены какие-либо NA/NS, таймауты, retries и пр. По этому логу можно понять, дошел ли запрос до соседа и видит ли TRex ответы. Если видите, что NA не приходит, проверяйте сетевое соединение и настройки соседа. Если NA приходит, но TRex его “не засчитывает” - убедитесь, что формат адреса в параметрах точно совпадает (были случаи, когда разный регистр hex-цифр в записи адреса мешал сопоставлению - в новых версиях это исправлено, но на всякий случай пишите IPv6 в нижнем регистре).

Использование плагина IPv6 ND в TRex значительно упрощает настройку тестов в IPv6-сетях. Вы можете автоматически получать актуальные MAC-адреса соседей и избегать ручного конфигурирования, что особенно полезно в динамичных или крупномасштабных тестовых стендах. Главное - правильно интегрировать эту функцию в ваш сценарий (предварительный этап перед отправкой основного трафика) и учитывать описанные нюансы. С учётом этих рекомендаций TRex позволит генерировать IPv6-трафик так же удобно, как и IPv4, не беспокоясь о ручном прописывании L2-адресов устройств.

Ограничения TRex при работе с IPv6

При использовании TRex версии 3.06 для IPv6-трафика нужно учитывать несколько ограничений:

  • IPv6-адреса не назначаются портам TRex: TRex не позволяет напрямую сконфигурировать IPv6 на интерфейсе порта в stateless-режиме (ни через YAML, ни через GUI). Порт может иметь только IPv4 адрес (для служебных целей, ARP). Это означает отсутствие автоматического Neighbor Discovery - TRex не отправляет NS/NA запросы, и MAC-адреса соседей не узнаются динамически. Пользователь должен вручную указать MAC в потоках или настроить окружение (как описано выше).

  • Отсутствие автоматической ND/ARP в Stateless: Даже для IPv4 в stateless-режиме TRex не полностью эмулирует ARP (он может отправить один ARP при старте, но не обновляет динамически). Для IPv6 такой функциональности нет вовсе. Поэтому при любых изменениях топологии или адресов требуется вручную корректировать MAC-адреса в потоках или выполнять service режим и обновлять конфигурацию.

В целом, генерация IPv6-трафика в TRex возможна и поддерживается, но требует более ручной настройки.  Многое нужно делать самостоятельно или в коде, задавать все поля IPv6-пакета, явно указывать MAC-адреса, настраивать статический ND, и помнить о том, что TRex 3.06 (Stateless) не имеет полноценного IPv6 стека. Следуя описанным шагам и примером, вы сможете успешно сгенерировать трафик с заданными IPv6-адресами на нужной скорости. Все приведенные команды и настройки были проверены на TRex v3.06 и применимы к данной версии.

Генерация трафика в Stateful-режиме (ASTF)

Отвлечемся от ограничений связанных с функциональностью IPv6 в TRex и я коротко расскажу о том, что такое тестирование в Statefull-сценарии и как его провести. Stateful режим TRex (ASTF) применяется для тестирования устройств L4-L7, которые поддерживают состояние соединений и обрабатывают прикладной трафик.

Методика тестирования может включать в себя несколько возможных сценариев. 

Первый это тестирование производительности L4-L7 устройств. Цель такого тестирования оценить способность устройств, таких как фаерволы, NAT-устройства, балансировщики нагрузки и DPI-системы, обрабатывать большой объем соединений и прикладного трафика. Производительность этих устройств зависит не только от количества пакетов в секунду (PPS), но и от скорости установки соединений (CPS), общего количества одновременных активных потоков и сложности анализа на уровне L7:   

  • NAT (Network Address Translation): Тестирование способности устройства выполнять трансляцию сетевых адресов под высокой нагрузкой. TRex может генерировать трафик как с клиентской, так и с серверной стороны, имитируя прохождение трафика через NAT-устройство.   

  • DPI (Deep Packet Inspection): Оценка производительности устройств, выполняющих глубокий анализ пакетов. TRex способен импортировать и передавать огромные PCAP-файлы (до 1 ТБ) с реальным трафиком, что позволяет тщательно тестировать функциональность и производительность DPI-систем.   

  • Load Balancer (Балансировщик нагрузки): Тестирование распределения трафика и устойчивости балансировщика при высокой скорости установки соединений и большом количестве активных потоков. ASTF позволяет имитировать множество клиентов, обращающихся к нескольким серверам, проверяя алгоритмы балансировки и способность устройства поддерживать стабильную работу.   

  • Firewalls (Фаерволы) / IPS/IDS (Intrusion Prevention/Detection Systems): Проверка способности фаерволов обрабатывать миллионы соединений, применять сложные политики безопасности и эффективно обнаруживать/предотвращать вторжения без деградации производительности.   

Второй - это эмуляция трафика и приложений. То есть необходимо генерировать трафик, который максимально точно имитирует поведение реальных пользователей и приложений. Это важно, поскольку синтетический трафик не всегда способен выявить проблемы, возникающие в реальных условиях эксплуатации. Реалистичный трафик позволяет более точно оценить производительность и стабильность DUT.

  • L7 Application Emulation: TRex может эмулировать различные L7-приложения, такие как HTTP, HTTPS, Citrix. Это достигается не за счет полной реализации протокола, а путем определения простых операций (send, wait_for_response, delay, close), которые формируют "историю" или "программу" взаимодействия для клиента и сервера. Это позволяет тестировать L7-функциональность без избыточной сложности.   

  • EMIX Traffic Profile: Использование стандартных профилей трафика, таких как EMIX (Enterprise Mix), является эффективным способом имитации реальной сетевой нагрузки. EMIX включает определенное соотношение TCP/UDP трафика, соединений, средний размер пакета и PPS/CPS. Этот профиль часто используется для тестов NBAR/AVC (Network Based Application Recognition/Application Visibility and Control).   

  • PCAP Replay: Воспроизведение захваченного реального трафика из PCAP-файлов позволяет создавать высокореалистичные шаблоны потоков. TRex способен обрабатывать огромные PCAP-файлы размером до 1 ТБ, что критически важно для тестирования устройств DPI или анализа поведения сети под нагрузкой, максимально приближенной к реальной.   

Третий - это тестирование протоколов маршрутизации для того, чтобы проверить способность маршрутизаторов и других сетевых устройств корректно устанавливать соседство, обмениваться маршрутами и обрабатывать изменения в топологии маршрутизации. Протоколы маршрутизации (BGP, OSPF, RIP) являются основой связности сети, и их тестирование под нагрузкой необходимо для обеспечения стабильности и масштабируемости.

TRex интегрирован с Bird Internet Routing Daemon (BIRD), что позволяет эмулировать миллионы маршрутов и до 10K виртуальных интерфейсов с различными конфигурациями VLAN/QinQ.   

  • BGP: Тестирование протокола BGP, включая eBGP/iBGP, RPKI, route reflection, graceful restart и другие расширения.   

  • OSPF: Проверка OSPFv2/v3.   

  • RIP: Тестирование RIPv1/v2/ng.   

Для создания сложных профилей в ASTF-режиме используется Python API, документация и примеры использования которого находятся на официальном сайте и в директории TRex.

Сценарий тестирования

Тип эмуляции L7

Скорость установки соединений (CPS)

Количество активных потоков

Профиль трафика

Цель

HTTP Performance

HTTP (GET/POST запросы, ответы)

Высокая (например, 100K CPS)

Миллионы

Пользовательские HTTP-шаблоны, EMIX

Тестирование производительности веб-серверов, балансировщиков нагрузки, фаерволов при обработке HTTP-трафика.

NAT Throughput

TCP/UDP (произвольные порты)

Высокая (например, 50K CPS)

Миллионы

PCAP-файл с реальным трафиком, EMIX

Оценка пропускной способности и емкости NAT-устройства, проверка корректности трансляций.

DPI Load Testing

Различные L7-приложения (HTTP, FTP, P2P, потоковое видео)

Средняя (например, 10K CPS)

Сотни тысяч

Крупные PCAP-файлы (до 1 ТБ)

Проверка производительности DPI-систем при глубоком анализе пакетов, выявление задержек и потерь.

Firewall Session Scale

TCP (различные флаги, короткие/длинные сессии)

Очень высокая (например, 200K CPS)

Миллионы

Пользовательские профили TCP/UDP

Тестирование максимального количества одновременных сессий, которые может поддерживать фаервол.

EMIX Load

Смешанный TCP/UDP (HTTP, Mail, RTP, DNS)

4K CPS на 1 Гбит/с

50K потоков на 1 Гбит/с

EMIX YAML профиль

Оценка производительности устройства в условиях реалистичного трафика, имитирующего корпоративную сеть.

Routing Protocol Scale (BGP)

BGP-сообщения (UPDATE, KEEPALIVE)

Низкая (сотни CPS)

Миллионы маршрутов

Генерация маршрутов через Bird Integration

Проверка масштабируемости и стабильности маршрутизаторов при большом количестве маршрутов и динамических обновлениях.

Теперь перейдем к сценарию тестирования. В Stateful режиме TRex также использует два интерфейса, но имитирует полноценное взаимодействие между клиентской и серверной сторонами трафика. Тестируемое устройство (DUT), такое как фаервол, NAT-устройство или балансировщик нагрузки, располагается между TRex, выступающим в роли клиента, и TRex, выступающим в роли сервера. Потоки трафика в этом режиме являются двунаправленными и сессионно-ориентированными на уровнях L4-L7. TRex способен выступать как в роли клиента, инициирующего соединения, так и в роли сервера, отвечающего на запросы.   

В Stateful режиме TRex также использует два интерфейса, но имитирует полноценное взаимодействие между клиентской и серверной сторонами трафика. Тестируемое устройство (DUT), такое как фаервол, NAT-устройство или балансировщик нагрузки, располагается между TRex, выступающим в роли клиента, и TRex, выступающим в роли сервера. Потоки трафика в этом режиме являются двунаправленными и сессионно-ориентированными на уровнях L4-L7. TRex способен выступать как в роли клиента, инициирующего соединения, так и в роли сервера, отвечающего на запросы.  

TRex не ограничивается простыми конфигурациями "точка-точка". Он поддерживает создание чрезвычайно сложных и реалистичных тестовых топологий, что позволяет проводить более глубокую и всестороннюю валидацию сетевых устройств.

  • GTP-U тестирование: TRex может быть использован для тестирования GTP-U туннелей, где TRex-клиент инкапсулирует трафик, а TRex-сервер деинкапсулирует его. Это имитирует S/GTPU-интерфейсы в мобильных сетях, позволяя проверять функциональность и производительность устройств, обрабатывающих мобильный трафик.   

  • Многопортовые конфигурации: TRex поддерживает использование более двух портов для тестирования сложных сетевых топологий или устройств с множеством интерфейсов. Это позволяет имитировать трафик, проходящий через различные сегменты сети или взаимодействующий с несколькими точками входа/выхода DUT.   

  • Виртуальные среды: TRex может быть развернут в различных виртуальных средах, таких как Docker, Amazon AWS или Cisco LaaS. Это позволяет тестировать сетевые функции в облачных и виртуализированных инфраструктурах, что является актуальным для современных распределенных систем.   

Поддержка TRex многопортовых конфигураций, виртуальных интерфейсов (veth/tap), интеграции с BIRD для динамической маршрутизации и протокола GTP-U  означает, что инструмент не ограничен базовыми тестами. Он позволяет создавать тестовые среды, которые точно имитируют реальные производственные сети, включая мобильные сети с GTP, крупные корпоративные сети с динамической маршрутизацией или сложные облачные развертывания. 

Тестирование NAT

Проведем реальное тестирование в Statefull-сценарии. Сгенерируем трафик в Stateful-режиме (ASTF) с помощью Cisco TRex через программный маршрутизатор на базе VPP (Vector Packet Processing) и FRR (Free Range Routing) с акцентом на тестирование NAT. Сценарий подразумевает следующее:

  • TRex (ASTF) эмулирует клиентские и серверные сессии (например, TCP);

  • Трафик проходит через софтовый роутер на базе VPP с FRR для динамической маршрутизации;

  • На маршрутизаторе выполняется NAT (например, SNAT или DNAT);

Цель: проверить производительность и корректность NAT и маршрутизации.

Физическая схема стенда остается такой же как была до этого:

TRex генерирует клиентские сессии с одной стороны и серверные с другой. VPP выполняет NAT, а FRR - маршрутизацию между сетями. На выходе проверяется корректность трансляций и производительность (CPS, throughput, latency).

Настроим DUT. В настройках VPP (/etc/vpp/startup.conf) необходимо подключить плагин nat_plugin.so:

plugins {
    plugin dpdk_plugin.so { enable }
    plugin nat_plugin.so { enable }
}

Настраиваем интерфейсы: 

$ systemctl restart vpp
$ vppctl create sub-interfaces TwentyFiveGigabitEthernet1/0/0 3003 dot1q 3003 exact-match
TwentyFiveGigabitEthernet1/0/0.3003

$ vppctl create sub-interfaces TwentyFiveGigabitEthernet1/0/1 3004 dot1q 3004 exact-match
TwentyFiveGigabitEthernet1/0/1.3004

$ vppctl set interface state TwentyFiveGigabitEthernet1/0/0 up
$ vppctl set interface state TwentyFiveGigabitEthernet1/0/0.3003 up

$ vppctl set interface state TwentyFiveGigabitEthernet1/0/1 up
$ vppctl set interface state TwentyFiveGigabitEthernet1/0/1.3004 up

$ vppctl set interface ip address TwentyFiveGigabitEthernet1/0/0.3003 10.0.0.1/24
$ vppctl set interface ip address TwentyFiveGigabitEthernet1/0/1.3004 20.0.0.1/24

Настраиваем source NAT (SNAT) в VPP для трафика из сети 10.0.0.0/24 в сеть 20.0.0.0/24:

$ vppctl nat44 plugin enable sessions 1000000

$ vppctl nat44 add interface address TwentyFiveGigabitEthernet1/0/1.3004
$ vppctl set interface nat44 in TwentyFiveGigabitEthernet1/0/0.3003 out TwentyFiveGigabitEthernet1/0/1.3004

$ vppctl show nat44 sessions

$ vppctl show nat44 interfaces
NAT44 interfaces:
 TwentyFiveGigabitEthernet1/0/0.3003 in
 TwentyFiveGigabitEthernet1/0/1.3004 out

$ vppctl show nat44 addresses
NAT44 pool addresses:
10.0.0.1
  tenant VRF independent
20.0.0.1
  tenant VRF independent
NAT44 twice-nat pool addresses:

$ vppctl show nat44 sessions
NAT44 ED sessions:
-------- thread 0 vpp_main: 0 sessions --------
-------- thread 1 vpp_wk_0: 251900 sessions --------
    i2o 10.0.0.142 proto TCP port 14649 fib 0
    o2i 20.0.0.1 proto TCP port 14649 fib 0
       external host 20.0.0.142:80
       i2o flow: match: saddr 10.0.0.142 sport 14649 daddr 20.0.0.142 dport 80 proto TCP fib_idx 0 rewrite: saddr 20.0.0.1 sport 14649 daddr 20.0.0.142 dport 80 txfib 0 
       o2i flow: match: saddr 20.0.0.142 sport 80 daddr 20.0.0.1 dport 14649 proto TCP fib_idx 0 rewrite: daddr 10.0.0.142 dport 14649 txfib 0 
       index 0
       last heard 559.29
       timeout in 238.55
       total pkts 31, total bytes 1860
       dynamic translation

    i2o 10.0.0.138 proto TCP port 12072 fib 0
    o2i 20.0.0.1 proto TCP port 12072 fib 0
       external host 20.0.0.138:80
       i2o flow: match: saddr 10.0.0.138 sport 12072 daddr 20.0.0.138 dport 80 proto TCP fib_idx 0 rewrite: saddr 20.0.0.1 sport 12072 daddr 20.0.0.138 dport 80 txfib 0 
       o2i flow: match: saddr 20.0.0.138 sport 80 daddr 20.0.0.1 dport 12072 proto TCP fib_idx 0 rewrite: daddr 10.0.0.138 dport 12072 txfib 0 
       index 1
       last heard 559.39
       timeout in 238.65
       total pkts 31, total bytes 1860
       dynamic translation

....

Теперь необходимо перезапустить сервер TRex в ASTF режиме:

$ ./t-rex-64 -i --cfg /opt/trex/v3.06/configs/server_full_config.yaml --astf --learn-mode 1

Создайте файл профиля, например nat_test.py:

from trex.astf.api import *


class Prof1():
    def get_profile(self):
        # ip generator
        ip_gen_c = ASTFIPGenDist(ip_range=["10.0.0.0", "10.0.0.255"],
                                 distribution="seq")
        ip_gen_s = ASTFIPGenDist(ip_range=["20.0.0.0", "20.0.0.255"],
                                  distribution="seq")
        ip_gen = ASTFIPGen(glob=ASTFIPGenGlobal(ip_offset="1.0.0.0"),      
                           dist_client=ip_gen_c,
                           dist_server=ip_gen_s)

        return ASTFProfile(default_ip_gen=ip_gen,
                            cap_list=[ASTFCapInfo(
                                      file="../avl/delay_10_http_browsing_0.pcap"
                                      cps=1)
                                     ])                                    


def register():
    return Prof1()

В консоли TRex ASTF загрузжаем профиль и указываем количество соединений:

Проверяем статистику NAT в VPP увидим огромное количество сессий:

$ vppctl show nat44 sessions
NAT44 ED sessions:
-------- thread 0 vpp_main: 0 sessions --------
-------- thread 1 vpp_wk_0: 251900 sessions --------
    i2o 10.0.0.142 proto TCP port 14649 fib 0
    o2i 20.0.0.1 proto TCP port 14649 fib 0
       external host 20.0.0.142:80
       i2o flow: match: saddr 10.0.0.142 sport 14649 daddr 20.0.0.142 dport 80 proto TCP fib_idx 0 rewrite: saddr 20.0.0.1 sport 14649 daddr 20.0.0.142 dport 80 txfib 0 
       o2i flow: match: saddr 20.0.0.142 sport 80 daddr 20.0.0.1 dport 14649 proto TCP fib_idx 0 rewrite: daddr 10.0.0.142 dport 14649 txfib 0 
       index 0
       last heard 559.29
       timeout in 238.55
       total pkts 31, total bytes 1860
       dynamic translation

    i2o 10.0.0.138 proto TCP port 12072 fib 0
    o2i 20.0.0.1 proto TCP port 12072 fib 0
       external host 20.0.0.138:80
       i2o flow: match: saddr 10.0.0.138 sport 12072 daddr 20.0.0.138 dport 80 proto TCP fib_idx 0 rewrite: saddr 20.0.0.1 sport 12072 daddr 20.0.0.138 dport 80 txfib 0 
       o2i flow: match: saddr 20.0.0.138 sport 80 daddr 20.0.0.1 dport 12072 proto TCP fib_idx 0 rewrite: daddr 10.0.0.138 dport 12072 txfib 0 
       index 1
       last heard 559.39
       timeout in 238.65
       total pkts 31, total bytes 1860
       dynamic translation

....

И наблюдаем статистику TRex ASTF касаемо объема передаваемых данных:

Global Statistics

connection   : localhost, Port 4501                       total_tx_L2  : 89.87 Mbps                     
version      : ASTF @ v3.06                               total_tx_L1  : 112.38 Mbps                    
cpu_util.    : 2.03% @ 16 cores (8 per dual port)         total_rx     : 23.81 Mbps                     
rx_cpu_util. : 0.02% / 0 pps                              total_pps    : 140.72 Kpps                    
async_util.  : 0% / 84.03 bps                             drop_rate    : 0 bps                     
total_cps.   : 27.75 Kcps                                 queue_full   : 0 pkts                         

Port Statistics

   port    |         0         |         1         |         2         |         3         |       total       
-----------+-------------------+-------------------+-------------------+-------------------+------------------
owner      |         megalloid |         megalloid |         megalloid |         megalloid |                   
link       |                UP |                UP |                UP |                UP |                   
state      |      TRANSMITTING |      TRANSMITTING |      TRANSMITTING |      TRANSMITTING |                   
speed      |           10 Gb/s |           10 Gb/s |           10 Gb/s |           10 Gb/s |                   
CPU util.  |             1.77% |             1.77% |             2.28% |             2.28% |                   
--         |                   |                   |                   |                   |                   
Tx bps L2  |        46.05 Mbps |             0 bps |        43.81 Mbps |             0 bps |        89.87 Mbps 
Tx bps L1  |        57.31 Mbps |             0 bps |        55.07 Mbps |             0 bps |       112.38 Mbps 
Tx pps     |        70.35 Kpps |             0 pps |        70.37 Kpps |             0 pps |       140.72 Kpps 
Line Util. |            0.57 % |               0 % |            0.55 % |               0 % |                   
---        |                   |                   |                   |                   |                   
Rx bps     |             0 bps |        23.81 Mbps |             0 bps |             0 bps |        23.81 Mbps 
Rx pps     |             0 pps |             0 pps |             0 pps |             0 pps |             0 pps 
----       |                   |                   |                   |                   |                   
opackets   |          31819854 |                 0 |          31819290 |                 0 |          63639144 
ipackets   |                 0 |                 0 |                 0 |                 0 |                 0 
obytes     |        2603790588 |                 0 |        2476467168 |                 0 |        5080257756 
ibytes     |                 0 |        1258094280 |                 0 |                 0 |        1258094280 
tx-pkts    |       31.82 Mpkts |            0 pkts |       31.82 Mpkts |            0 pkts |       63.64 Mpkts 
rx-pkts    |            0 pkts |            0 pkts |            0 pkts |            0 pkts |            0 pkts 
tx-bytes   |            2.6 GB |               0 B |           2.48 GB |               0 B |           5.08 GB 
rx-bytes   |               0 B |           1.26 GB |               0 B |               0 B |           1.26 GB 
-----      |                   |                   |                   |                   |                   
oerrors    |                 0 |                 0 |                 0 |                 0 |                 0 
ierrors    |                 0 |                 0 |                 0 |                 0 |        20,968,238 

status:  -

browse:     'ESC' - console, 'q' - quit, 'd' - dashboard, 'u' - util, 't' - astf, 'l' - latency, 's' - streams, 
dashboard:  'n' - reset view, 'o' - owned ports, 'a' - all ports, 'c' - clear,

И можно переключаться между разными видами метрик нажатием клавиши Esc и одного из видов метрик:

                   |     client  |        server |
 --------------------------------------------------------------------------------
   m_active_flows  |      39965  |        39966  |  active flows
      m_est_flows  |      39950  |        39952  |  active est flows
     m_tx_bw_l7_r  | 31.14 Mbps  |    4.09 Gbps  |  tx bw
     m_rx_bw_l7_r  |  4.09 Gbps  |   31.14 Mbps  |  rx bw
       m_tx_pps_r  |140.36 Kpps  |  124.82 Kpps  |  tx pps
       m_rx_pps_r  |156.05 Kpps  |  155.87 Kpps  |  rx pps
       m_avg_size  |    1.74 KB  |      1.84 KB  |  average pkt size
                -  |        ---  |          ---  |
              TCP  |        ---  |          ---  |
                -  |        ---  |          ---  |
 tcps_connattempt  |      73936  |            0  |  connections initiated
     tcps_accepts  |          0  |        73924  |  connections accepted
    tcps_connects  |      73921  |        73910  |  connections established
      tcps_closed  |      33971  |        33958  |  conn. closed (includes drops)
   tcps_segstimed  |     213451  |       558085  |  segs where we tried to get rtt
  tcps_rttupdated  |     213416  |       549736  |  times we succeeded
      tcps_delack  |     344742  |            0  |  delayed acks sent
    tcps_sndtotal  |     623780  |       558085  |  total packets sent
     tcps_sndpack  |      73921  |       418569  |  data packets sent
     tcps_sndbyte  |   18406329  |   2270136936  |  data bytes sent
     tcps_sndctrl  |      73936  |            0  |  control (SYN,FIN,RST) packets sent
     tcps_sndacks  |     475923  |       139516  |  ack-only packets sent
     tcps_rcvpack  |     550465  |       139502  |  packets received in sequence
     tcps_rcvbyte  | 2269941776  |     18403590  |  bytes received in sequence
  tcps_rcvackpack  |     139495  |       549736  |  rcvd ack packets
  tcps_rcvackbyte  |   18468679  |   2222057965  |  tx bytes acked by rcvd acks
     tcps_preddat  |     410970  |            0  |  times hdr predict ok for data pkts
   tcps_rcvoopack  |          0  |            0  |  *out-of-order packets received   #(1)
                -  |        ---  |          ---  |
       Flow Table  |        ---  |          ---  |
                -  |        ---  |          ---  |
   redirect_rx_ok  |          0  |            1  |  redirect to rx OK
status:  \

Теперь обращу внимание на основные метрики для этого теста:

  1. Корректность NAT: все TCP-сессии должны успешно открываться и закрываться.

  2. Производительность: количество сессий в секунду (CPS) и общее число активных соединений.

  3. Задержки и потери пакетов.

Такой подход эффективно выявляет слабые места и позволяет улучшать архитектуру программных маршрутизаторов с VPP при интенсивной нагрузке. Данный кейс взят с "потолка" только для того чтобы продемонстрировать возможности. Предлагаю вам самостоятельно поизучать то, как можно было бы использовать его в реальных тестовых кейсах и хотелось бы увидеть еще множество статей описывающих этот инструмент.

Заключение и рекомендации

Вообще многое в TRex реализовано относительно сыро, есть много вариантов решения одной и той же задачи внутри инструмента, разрозненная документация, нет системного и исчерпывающего описания всего что там под капотом. Но при этом он остаётся является мощным, гибким и экономически эффективным решением для всестороннего тестирования сетевых устройств на всех уровнях модели OSI. Его открытый исходный код и поддержка стандартного оборудования делают его доступным для широкого круга инженеров, что способствует улучшению качества сетевых продуктов и стандартизации методик тестирования.

Чтобы выжать из этого продукта весь его теоретический максимум нужно:

  • Взять мощное железо. Для достижения максимальной производительности TRex, соответствующей заявленным характеристикам (до 200 Гбит/с), необходимо инвестировать в рекомендованное аппаратное обеспечение (например, Cisco UCS, специализированные сетевые карты Intel) и правильно настраивать NUMA-топологию системы.

  • Задействовать автомазированное исполнение через Python API: Для автоматизации сложных сценариев тестирования, динамического изменения параметров трафика в процессе выполнения и сбора детализированной статистики, рекомендуется активно использовать мощный Python API TRex.

  • Стремиться применять максимально реалистичные профили трафика: Всегда стремитесь использовать профили трафика, максимально приближенные к реальным условиям вашей сети (например, EMIX или PCAP-файлы, захваченные в производственной среде). Это поможет выявлять проблемы, которые могут не проявляться при использовании синтетического трафика.

  • Использовать в анализе максимум предоставляемых метрик: Не ограничивайтесь анализом одной метрики. Для получения полной картины производительности устройства и выявления корневых причин проблем необходимо проводить комплексный анализ взаимосвязей между пропускной способностью, задержкой, джиттером, потерями пакетов, PPS и CPS. Гранулированные статистики TRex позволяют точно локализовать источник деградации.

Дополнительные источники

  1. https://github.com/cisco-system-traffic-generator/trex-core

  2. https://deepwiki.com/cisco-system-traffic-generator/trex-core/1-trex-overview

  3. https://trex-tgn.cisco.com/trex/doc/

  4. https://trex-tgn.cisco.com/trex/doc/trex_manual.html

Комментарии (0)