Задержка Tc qdisc не отображается в записи tcpdump

Задержка Tc qdisc не отображается в записи tcpdump

У меня есть два контейнера linux, соединенных veth-парой. На veth-интерфейсе одного контейнера я настраиваю задержку tc qdisc netem и отправляю трафик с него на другой контейнер. Если я смотрю трафик с обеих сторон с помощью tcpdump/wireshark, то можно увидеть, что временные метки одного и того же пакета у отправителя и получателя не отличаются на выбранную задержку.

Я хотел бы более подробно разобраться, в какой момент libpcap ставит временные метки для исходящего трафика, соответствующего tc qdisc. Я искал схему/изображение в Интернете, но не нашел. Я нашел эту тему (точка захвата пакетов wireshark) но он советует ввести косвенность, имея еще один контейнер/интерфейс. Это не возможное решение в моей ситуации. Есть ли способ решить проблему, не вводя дополнительных промежуточных интерфейсов (то есть не меняя топологию) и только записывая на уже заданный veth-интерфейс, но таким образом, чтобы задержка была видна?

ОБНОВЛЯТЬ:

Я поторопился и ошибся. Ни мое решение, представленное ниже (такое же, как первый вариант решения ответа @AB), ни решение с IFB @AB (я уже проверил) не решают мою проблему. Проблема в переполнении очереди передачи интерфейса a1-eth0отправителя в топологии:

[a1-br0 ---3Gbps---a1-eth0]---100Mbps---r1---100Mbps---r2

Я поторопился и проверил только задержку в 10 мс на соединении между a1-eth0маршрутизатором и r1. Сегодня я попробовал увеличить задержку: 100 мс, 200 мс и результаты (графики задержки и скорости на пакет, которые я получаю) начинают отличаться для топологии выше и для нормальной топологии:

[a1-eth0]---100Mbps---r1---100Mbps---r2

Так что нет, конечно, для точного тестирования я не могу иметь дополнительных связей: ни введенных мостом Linux, ни этим IFB, ни какой-либо другой третьей системой. Я тестирую схемы управления перегрузкой. И я хочу сделать это в определенной топологии. И я не могу изменить топологию только ради построения графика -- я имею в виду, если в то же время мои результаты/графики скорости и задержки изменятся.

ОБНОВЛЕНИЕ 2:

Похоже, решение найдено, как можно увидеть ниже (решение NFLOG).

ОБНОВЛЕНИЕ 3:

Ниже описаны некоторые недостатки решения NFLOG (большие заголовки канального уровня и неправильные контрольные суммы TCP для исходящих TCP-пакетов с нулевой полезной нагрузкой) и предложено лучшее решение с NFQUEUE, которое лишено ни одной из этих проблем:Неверная контрольная сумма TCP для исходящих пакетов нулевой длины (перехвачено с помощью iptables). Однако для моих задач (тестирование схем контроля перегрузки) ни NFLOG, ни NFQUEUE не подходят. Как объясняется по той же ссылке, скорость отправки снижается при захвате пакетов из iptables ядра (я так понимаю). Таким образом, когда вы записываете у отправителя, захватывая с интерфейса (т.е. регулярно), вы получаете дамп в 2 гигабайта, а если вы записываете у отправителя, захватывая из iptables, вы получаете дамп в 1 гигабайт. Грубо говоря.

ОБНОВЛЕНИЕ 4:

Наконец, в своем проекте я использую решение Linux Bridge, описанное в моем собственном ответе ниже.

решение1

СогласноПоток пакетов в Netfilter и общих сетяхсхема, tcpdump захватывает (AF_ПАКЕТ) послевыход (qdisc). Поэтому нормально, что вы не видите задержку в tcpdump: задержка уже присутствовала при первоначальном захвате.

Вам придется сделать это на один шаг раньше, поэтому задействуйте третью систему:

S1: system1, запускает tcpdump на исходящем интерфейсе
R: маршрутизатор (или мост, как вам удобно, это ничего не меняет), запускает qdisc netem
S2: system2, запускает tcpdump на входящем интерфейсе

 __________________     ________________     __________________
|                  |   |                |   |                  |
| (S1) -- tcpdump -+---+- (R) -- netem -+---+- tcpdump -- (S2) |
|__________________|   |________________|   |__________________|

Это означает 3 сетистекизадействованы ли они, будь то реальные, виртуальные машины, сетевое пространство имен (включаяip netns, LXC, ...)


При желании можно также схитрить и перенести все специальные настройки на маршрутизаторе (или мосте) с помощьюИФБинтерфейс сзеркальныйтрафик: позволяет с помощью трюка (специального для этого случая) вставить netem как бы после входящего трафика, а не на исходящего:

 _______     ______________________________________________     _______
|       |   |                                              |   |       |         
| (S1) -+---+- tcpdump -- ifb0 -- netem -- (R) -- tcpdump -+---+- (S2) |
|_______|   |______________________________________________|   |_______|

Вот базовый пример использования IFB:tc зеркальныйстраница руководства:

Используя интерфейс ifb, можно отправлять входящий трафик через экземпляр sfq:

# modprobe ifb
# ip link set ifb0 up
# tc qdisc add dev ifb0 root sfq
# tc qdisc add dev eth0 handle ffff: ingress
# tc filter add dev eth0 parent ffff: u32 \
  match u32 0 0 \
  action mirred egress redirect dev ifb0

Просто используйтенетемна ifb0 вместо sfq (и в неначальном сетевом пространстве имен, ip link add name ifbX type ifbработает нормально, без modprobe).

Для корректной работы по-прежнему требуется 3 сетевых стека.


с использованиемНФЛОГ

После предложения от JenyaKh, оказалось, что можно перехватить пакет с помощьюtcpdump,доegress (то есть до qdisc), а затем на egress (после qdisc): с помощьюiptables(илиnftables) для регистрации полных пакетов в инфраструктуре журнала netlink и их дальнейшего чтения с помощьюtcpdump, затем снова с помощьюtcpdumpна выходном интерфейсе. Для этого требуются только настройки на S1 (и больше не нужен маршрутизатор/мост).

Так что сiptablesна S1, что-то вроде:

iptables -A OUTPUT -o eth0 -j NFLOG --nflog-group 1

Вероятно, следует добавить специальные фильтры для соответствия проведенному тесту, посколькуtcpdumpФильтр ограничен интерфейсом nflog (Wireshark должен справляться с этим лучше).

Если требуется сбор ответов (здесь это делается в другой группе, поэтому требуется дополнительныйtcpdump):

iptables -A INPUT -i eth0 -j NFLOG --nflog-group 2

В зависимости от потребностей их также можно переместить всырой/ВЫХОДНОЙиraw/ПРЕДВАРИТЕЛЬНАЯ ПЕРЕДАЧАвместо.

Сtcpdump:

# tcpdump -i nflog:1 -n -tt ...

Если для ввода использовалась другая группа (= 2):

# tcpdump -i nflog:2 -n -tt ...

И в то же время, как обычно:

# tcpdump -i eth0 -n -tt ...

решение2

ОБНОВЛЯТЬ:

Итак, я наконец-то использовал это решение. Оно присутствует в моем решении. Оно в конце концов хорошо мне подошло.


Я (автор темы) решил свою проблему с помощью Linux bridge. Здесь [https://www.linuxquestions.org/questions/linux-networking-3/transferring-all-traffic-through-an-extra-interface-4175656515] Я написал, что мне удалось использовать Linux-мост, но отверг такую ​​возможность:«Но это решение не соответствует моим потребностям, так как на самом деле есть дополнительный канал Ethernet между интерфейсами h1-br0 и h1-eth0. Мне это нужно для измерения производительности, поэтому у меня не может быть дополнительных каналов Ethernet. Я имею в виду, что это решение с мостом портит мою топологию, вводя дополнительные каналы».

       a1
-----------------
|a1-br0---a1-eth0|---------local network
------------------

Почему я сначала отклонил решение? Изначально моя топология такая:

a1---3Gbps---r1---100Mbps---r2

На ссылке r1---r2у меня установлена ​​скорость netem 100 Мбит/с, на ссылке a1---r1нет ограничений скорости. Так как очередь передачи маршрутизатора, r1соединяющего его с маршрутизатором, r2составляет 1000 пакетов, у меня был эффект переполнения очереди (некоторые пакеты отбрасывались) при отправке трафика с a1на r2. И это было нормально. Вот как это происходит в реальном мире с переполнением очередей маршрутизатора в случае узкого места в ссылке.

Теперь я провожу все эти исследования, чтобы добавить задержку и ограничения скорости a1---r1. Поэтому я придумал это решение с использованием моста Linux. Но я думал, что это решение не сработает. Ниже вы можете увидеть новую топологию с мостом Linux:

[a1-br0 ---3Gbps---a1-eth0]---100Mbps---r1---100Mbps---r2

Итак, моя проблема с решением заключалась в том, что я ожидал, что переполнение очереди будет присутствовать сейчас в очереди передачи интерфейса a1-eth0. То есть, это то же самое, что и на предыдущей картинке, где переполнение было в интерфейсе r1подключения его к r2. Аналогично.

И это переполнение мне не нужно. Потому что в обычной топологии — без использования моста Linux для измерения задержки — у нас нет переполнения очереди передачи a1-eth0:

[a1-eth0]---100Mbps---r1---100Mbps---r2

Но вчера я снова создал топологию с мостом Linux (третья топология из изображенной выше) и запустил трафик по топологии, текущий из a1в r2. Я проверил отставание (текущее количество пакетов в очереди) очереди передачи a1-eth0вызова команды tc -s qdisc show dev a1-eth0в цикле с интервалом 500 мс и отставание очереди передачи a1-br0с аналогичной командой.

Вот что я увидел a1-eth0, я получил сообщения:

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 9461862 bytes 6393 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 15280534 bytes 10323 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 21110722 bytes 14257 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 118560b 80p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 26952766 bytes 18199 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 32788882 bytes 22137 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 103740b 70p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 38635372 bytes 26082 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 44477416 bytes 30024 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 50332798 bytes 33975 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 56157058 bytes 37905 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 125970b 85p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 61969532 bytes 41828 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 67784900 bytes 45752 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 73600268 bytes 49676 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 79415636 bytes 53600 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 85244342 bytes 57533 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 120042b 81p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 91080458 bytes 61471 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 96923984 bytes 65414 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 102761582 bytes 69353 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 108606590 bytes 73297 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 103740b 70p requeues 0 

Вот что я увидел a1-br0, я получил сообщения:

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

Итак, можно увидеть, что переполнения не происходит, a1-eth0и на самом деле это не "выглядит" как a1-br0отправка чего-либо, хотя на самом деле это отправка. Так что связь между a1-broи a1-eth0не похожа на ту (связь пары veth) между a1и маршрутизатором r1. Я не знаю, почему это так. Это странно, потому что я проверил, что могу, например, установить задержку netem на a1-br0-- так что это как обычный интерфейс.

В любом случае, я проверил, что решение с мостом удовлетворяет всем моим потребностям. Я пока не исследовал, почему оно работает (я имею в виду в том смысле, что я объяснял выше — переполнение очереди и т. д.).


Вот команды, которые я запускал на хосте a1для справки. Я понимаю, что без контекста их трудно полностью понять. Но, возможно, это поможет кому-то в будущем:

brctl addbr a1-br0
brctl addif a1-br0 a1-eth0
ip link set dev a1-br0 up
ip addr add dev a1-br0 11.0.0.1/30
ip addr flush dev a1-eth0
route add default gw 11.0.0.2 dev a1-br0
ifconfig a1-eth0 0.0.0.0 up
ethtool -K a1-br0 tx off sg off tso off ufo off

Топология с IP-адресами, к которым я применил команды, также присутствует здесь:Пинг одного интерфейса маршрутизатора Linux другим интерфейсом этого маршрутизатора. Вот топология:

------                           ------                            ------
| a1 |                           | r1 |                            | r2 |
|    | a1-eth0-----------r1-eth0 |    |r1-eth1--------------r2-eth1|    |
-----(11.0.0.1/30)   (11.0.0.2/30)----(11.0.0.9/30)   (11.0.0.10/30)----- 

Связанный контент