Возможно ли в linux системными насторйками ограничить пиковую скорость передачи UDP (per-socket)?

Возможно ли в linux'е (ядро 4.19.56) настройками ядра/iptables ограничить скорость отправки udp-пакетов на per-socket основе ? Т.е. чтобы любой отдельно взятый udp socket не мог отправлять пакеты чаще чем раз в n микросекунд, но при этом общая пропускная способность (для всех сокетов) не ограничивалась ? Пакеты, не укладывающиеся в лимит должны не отбрасываться, а буферизироваться.
Ограничение пропускной способности не в пакетах, а в килобайтах так же устроит, но период расчета среднего должен быть коротким (миллисекунды).

Не очень кратенькая предыстория, к прочтению необязательная:
spoiler
Есть железка (Netup Streamer), рассылающая IP multicast video. Фактически это [почти] обычный x86 Linux сервер под Debian Stretch. Подключена к сети по 1Gbps линку.
После обновления прошивки стримера стали наблюдаться проблемы у клиентов:
IPTV-приемники, подключенные к сети по 1Gbps линкам стали безумно сыпать картинку. При этом подключенные по 100Mbps работают нормально. Нет, ничего не перепутано: 100Mbps - полет нормальный, 1Gbps - картинка рассыпается.
При принудительном переводе порта коммутатора в 100Mbps проблема исчезает.
При уменьшении количества транслируемых в сеть каналов (вплоть до одного) проблема усугубляется, т.е. картинка на приемниках 'рвется' сильнее.
Техподдержка кивала на нашу сеть, кабеля, IGMP snooping, просила выключить и снова включить и другими способами изображала дерево.
C кабелями, сетью в целом и IGMP snooping в частности все в порядке: трафик на клиентский порт приходит ровно тот, что нужно. Более того, снятые ноутбуками со встроенной сетевой картой дампы трафика с 100Mbps и 1Gbps портов полностью совпали. Да и VLC на этих ноутах и там и там показывал идеальную картинку. А вот на ноуте с USB сетевой картинка рвалась и обнаружились потери пакетов.

Немного мозгового штурма и была найдена причина: стример принимает тв-сигнал (со спутника), что-то там демуксит-ремуксит, и отправляет UDP- мультикастом в сеть. Битрейт каждого потока ~10Mbps.
НО из-за того, что он 'что-то там ремуксит' эти 10Mbps - не непрерывный поток, а пачки пакетов на полной гигабитной скорости, перемежающиеся ~20 миллисекундными паузами (50 кадров в секунду, потому что). Т.е. каждый кадр выплевывается стримером в сеть так быстро, как он может. Далее просто: опорный кадр может быть достаточно большим, и USB сетевая (а в STB сетевые как правило висят на USB шине) принимая IPTV поток на 1Gbps интерфейсе просто не успевает засунуть все в шину USB и некоторые пакеты из наиболее крупных пачек теряются. Как вы понимаете 'наиболее крупные пачки' это key frames. При работе порта в 100Mbps режиме коммутатор буферизирует пакеты и трафик принимается нормально.

ps: flow control на портах клиентского коммутатора - не решение проблемы.
  • Вопрос задан
  • 644 просмотра
Решения вопроса 1
@Zolg Автор вопроса
Пробы, ошибки и курение манов привели к решению.
Необходимая фича завется packet pacing, реализована в fair queue traffic policer
Что характерно - ощутимая часть нагугленых по теме материалов касалась именно вещания iptv

до:

# tc qdisc show dev eth0
qdisc pfifo_fast 0: root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
#tcpdump --time-stamp-precision=micro -ttt --dont-verify-checksums udp and host 235.1.6.4
spoiler
...
00:00:00.022090 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000024 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000022 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000011 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000010 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000014 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000022 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000014 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000013 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000021 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000014 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000015 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000038 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000020 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000044 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000042 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000012 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000005 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000015 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000026 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000009 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000005 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000005 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000016 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000020 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000007 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000020 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000004 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000032 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000007 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000022 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000005 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000014 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.022102 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
обрезано по пакетам, соответствующим началу кадра h.264

После:
# tc qdisc add dev eth0 root fq pacing maxrate 25Mbit
# tcpdump --time-stamp-precision=micro -ttt --dont-verify-checksums udp and host 235.1.6.4
spoiler
...
00:00:00.016850 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000023 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000524 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000010 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000004 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000929 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000011 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000964 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000013 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000941 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000009 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000960 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000009 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000961 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000007 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000004 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000977 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000011 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000941 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000008 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.001008 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000013 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000910 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000009 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000004 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000954 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000010 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000956 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000008 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000961 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000008 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000962 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.009238 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000036 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000492 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000012 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000976 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000010 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000942 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000009 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000957 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000008 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000958 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000007 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000004 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000963 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000010 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000957 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.000009 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
00:00:00.016154 IP iptv-server.57842 > 235.1.6.4.1234: UDP, length 1316
обрезано по пакетам, соответствующим началу кадра h.264, плотная пачка остальных пакетов кадра теперь размазывается по времени.

работает идеально. какого-либо увеличения нагрузки на стример (суммарный исходящий поток 250+Mbps) не зафиксировано.
параметр maxrate относится не к очереди в целом, а к каждому потоку в отдельности (фактически - задает значение опции сокета SO_MAX_PACING_RATE по умолчанию)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@iddqda
network engineer, netdevops
А вот на ноуте с USB сетевой картинка рвалась и обнаружились потери пакетов.

т.е. потери пакетов обнаружились не на сервере, не на коммутаторах, а уже на конечном устройстве.
Ну и решайте проблему с конечным устройством тогда. Сервера и сети не должны решать проблемы индейцев.

стандарт 1000Base-T это вообще говоря не про скорость, а про принцип кодирования и передачи информации по физической среде (4 медные пары). т.е. это больше про совместимость по уровням сигналов.
Да, используя эту среду теоретически можно передать и получить (одновременно) поток фреймов в 1000Мбит/с.
Но если у ноута тормозной чипсет и он может передать максимум 150Мбит/с, то все равно в характеристиках его сетевухи будет 10/100/1000. Ведь 150 больше 100, а промежуточных от 100 до 1000 форматов нет.
Когда идет TCP поток, то flow control встроен в протокол и там проблем не возникает
с UDP все хуже. тут flow control обычно выносится дальше на уровень приложения.
В случае мальтикаста вроде таких механизмов из коробки нет. Можно только подписаться на канал с худшим качеством.
Кстати, ваш IGMP снупинг действительно может не работать или быть неправильно настроен. Или вы правда вливаете в ноут больше 10 потоков по 10 метров?
Ответ написан
@res2001
Developer, ex-admin
Настройте шейпер для IPTV трафика.
Ответ написан
Комментировать
@MechanID
Админ хостинг провайдера
Я бы попробывал решить проблему через настройку трафик шейпинга внутри тогоже дебиана в сторону каждого отдельного клиента (например если поток 10МБит - ограничить до 15Мбит) при помощи например https://lartc.org/howto/lartc.qdisc.html (начало документации) Если же прям внутри нет такой возможности то между сетью с потребителями железкой поставить чтото что будет шейпить трафик.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы