Всем привет!
В этой статье я хочу рассказать вам про одну полезную фичу, которая есть в сетевой карте Intel 82599.
Речь пойдёт об аппаратном ограничении скорости выходного потока пакетов.
К сожалению, она не доступна в линуксе «из коробки» и требуются некоторые усилия, чтобы её задействовать.
Кому интересно — добро пожаловать под кат.
Началось всё с того, что на днях мы тестировали оборудование, которое занимается фильтрацией трафика.
Девайс MX — это DPI-устройство. Оно разбирает пакет, поступающий из 10G и отправляет его на гигабитный порт, если он попадает под заданный критерий (адреса, порты и прочее). На стороне PC — карта Intel 82599 с драйвером ixgbe. Трафик генерировали при помощи tcpreplay, а собирали при помощи tcpdump. Дамп с тестовым трафиком у нас был (дано по условиям задачи).
Поскольку в общем случае отфильтровать 10G и отослать результат в 1G не представляется возможным (скорости-то разные, а буферы не резиновые), нам пришлось ограничивать скорость генерации пакетов. Тут важно сказать, что мы проводили не нагрузочное тестирование, а функциональное, поэтому нагрузка на 10G была не очень важна и влияла только на длительность теста.
Казалось бы, задача решается просто: открываем man tcpreplay и видим там ключик -M.
Запускаем:
В результате в статистике MX'а появляется следующее:
Столбец overflow pkt означает, что часть пакетов не «влезла» в 1G, т.к. выходной буфер переполнился. А это значит, что до PC не дошло 53 пакета. А они нам очень нужны, ведь мы проверяем правильность функционирования фильтров.
Получается, что сетевая карта 82599 создаёт burst'ы независимо от того, какая скорость выставлена в tcpreplay.
Встал вопрос о том, как можно контролировать нагрузку в 10G на уровне, максимально приближенном к линку. И тут нам в голову пришла мысль, что карта это уже умеет. Так и есть! В datasheet'e нашли подтверждение в разделе 1.4.2 Transmit Rate Limiting. Осталось только научиться этой функцией управлять.
Рычагов для этого (нужных файликов в sysfs) в нашем ядре мы не нашли (мы игрались c 3.2, debian). Порылись в сорцах свежего ядра (3.14) и там тоже не нашли.
Оказалось, что на github'е уже есть проект, который называется tx-rate-limits.
Дальше всё тривиально :) Собрали ядро, поставили на систему:
Перезагрузились, и… в sysfs теперь есть файлики для управления нагрузкой передачи!
Дальше записываем в tx_rate_limit требуемое значение в мегабитах:
В итоге в статистике MX'а видим, что overflow не происходит, т.к. скорость контролируется картой и burst'ов больше нет, весь отфильтрованный трафик попадает в 1G без потерь:
Возможно, для решения данной задачи есть более простой способ.
Буду очень благодарен, если кто-нибудь поделится.
UPD:
Забыл написать, как работает Transmit Rate Limiting.
Он модифицирует IPG (Inner Packet Gap). То есть на канальном уровне контролирует задержки между пакетами.
Таким образом, мы имеем аппаратный контроль за интервалом времени между пакетами и равномерный поток пакетов.
И главное — есть аппаратная гарантия отсутствия burst'ов :)
В этой статье я хочу рассказать вам про одну полезную фичу, которая есть в сетевой карте Intel 82599.
Речь пойдёт об аппаратном ограничении скорости выходного потока пакетов.
К сожалению, она не доступна в линуксе «из коробки» и требуются некоторые усилия, чтобы её задействовать.
Кому интересно — добро пожаловать под кат.
Началось всё с того, что на днях мы тестировали оборудование, которое занимается фильтрацией трафика.
Девайс MX — это DPI-устройство. Оно разбирает пакет, поступающий из 10G и отправляет его на гигабитный порт, если он попадает под заданный критерий (адреса, порты и прочее). На стороне PC — карта Intel 82599 с драйвером ixgbe. Трафик генерировали при помощи tcpreplay, а собирали при помощи tcpdump. Дамп с тестовым трафиком у нас был (дано по условиям задачи).
Поскольку в общем случае отфильтровать 10G и отослать результат в 1G не представляется возможным (скорости-то разные, а буферы не резиновые), нам пришлось ограничивать скорость генерации пакетов. Тут важно сказать, что мы проводили не нагрузочное тестирование, а функциональное, поэтому нагрузка на 10G была не очень важна и влияла только на длительность теста.
Казалось бы, задача решается просто: открываем man tcpreplay и видим там ключик -M.
Запускаем:
$ sudo tcpreplay -M10 -i eth3 dump.cap
В результате в статистике MX'а появляется следующее:
| Name | Packets | Bytes | Overflow pkt |
| EX1 to EG1| 626395| 401276853| 53|
| EX1 to EG2| 0| 0| 0|
| EX1 RX| 19426782| 4030345892| 0|
Столбец overflow pkt означает, что часть пакетов не «влезла» в 1G, т.к. выходной буфер переполнился. А это значит, что до PC не дошло 53 пакета. А они нам очень нужны, ведь мы проверяем правильность функционирования фильтров.
Получается, что сетевая карта 82599 создаёт burst'ы независимо от того, какая скорость выставлена в tcpreplay.
Встал вопрос о том, как можно контролировать нагрузку в 10G на уровне, максимально приближенном к линку. И тут нам в голову пришла мысль, что карта это уже умеет. Так и есть! В datasheet'e нашли подтверждение в разделе 1.4.2 Transmit Rate Limiting. Осталось только научиться этой функцией управлять.
Рычагов для этого (нужных файликов в sysfs) в нашем ядре мы не нашли (мы игрались c 3.2, debian). Порылись в сорцах свежего ядра (3.14) и там тоже не нашли.
Оказалось, что на github'е уже есть проект, который называется tx-rate-limits.
Дальше всё тривиально :) Собрали ядро, поставили на систему:
$ git checkout https://github.com/jrfastab/tx-rate-limits.git
$ cd tx-rate-limits
$ fakeroot make-kpkg --initrd -j 8 kernel-image
$ sudo dpkg -i ../linux-image-3.6.0-rc2+_3.6.0-rc2+-10.00.Custom_amd64.deb
Перезагрузились, и… в sysfs теперь есть файлики для управления нагрузкой передачи!
$ ls /sys/class/net/eth5/queues/tx-0/
byte_queue_limits tx_rate_limit tx_timeout xps_cpus
Дальше записываем в tx_rate_limit требуемое значение в мегабитах:
# RATE=100
# for n in `seq 0 7`; do echo $RATE > /sys/class/net/eth4/queues/tx-$n/tx_rate_limit ; done
В итоге в статистике MX'а видим, что overflow не происходит, т.к. скорость контролируется картой и burst'ов больше нет, весь отфильтрованный трафик попадает в 1G без потерь:
| Name | Packets | Bytes | Overflow pkt |
| EX1 to EG1| 22922532| 14682812077| 0|
| EX1 to EG2| 0| 0| 0|
| EX1 RX| 713312575| 147948837844| 0|
Возможно, для решения данной задачи есть более простой способ.
Буду очень благодарен, если кто-нибудь поделится.
UPD:
Забыл написать, как работает Transmit Rate Limiting.
Он модифицирует IPG (Inner Packet Gap). То есть на канальном уровне контролирует задержки между пакетами.
Таким образом, мы имеем аппаратный контроль за интервалом времени между пакетами и равномерный поток пакетов.
И главное — есть аппаратная гарантия отсутствия burst'ов :)