Atraso Tc qdisc não visto na gravação tcpdump

Atraso Tc qdisc não visto na gravação tcpdump

Eu tenho dois contêineres Linux conectados com um par veth. Na interface veth de um contêiner, configurei o tc qdisc netem delay e enviei o tráfego dele para o outro contêiner. Se eu observar o tráfego em ambos os lados usando tcpdump/wireshark, pode-se ver que os carimbos de data e hora do mesmo pacote no remetente e no destinatário não diferem pelo atraso selecionado.

Eu queria entender mais detalhadamente em que ponto o libpcap coloca carimbos de data e hora para o tráfego de saída correspondente ao tc qdisc. Procurei um esquema/imagem na Internet mas não encontrei. Encontrei este tópico (ponto de captura de pacotes wireshark) mas aconselha introduzir uma indireção tendo mais um container/interface. Esta não é uma solução possível na minha situação. Existe alguma maneira de resolver o problema sem introduzir interfaces intermediárias adicionais (ou seja, sem alterar a topologia) e apenas gravando na interface veth já fornecida, mas de forma que o atraso possa ser visto?

ATUALIZAR:

Fui muito rápido e me enganei. Nem a minha solução presente abaixo (igual à primeira variante de solução da resposta do @AB), nem a solução com IFB do @AB (já verifiquei) resolvem o meu problema. O problema está no estouro da fila de transmissão da interface a1-eth0do remetente na topologia:

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

Fui muito rápido e verifiquei apenas o atraso de 10 ms no link entre o a1-eth0roteador e o roteador r1. Hoje tentei aumentar o atraso: 100ms, 200ms e os resultados (atraso por pacote e gráficos de taxa que obtenho) começam a diferir para a topologia acima e para a topologia normal:

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

Então não, certamente, para testes precisos não posso ter links extras: nem introduzidos pelo Linux bridge, nem por este IFB, nem por qualquer outro terceiro sistema. Eu testo esquemas de controle de congestionamento. E quero fazer isso em uma topologia específica. E não posso alterar a topologia apenas para fins de plotagem - quero dizer, se ao mesmo tempo minha taxa e resultados/parcelas de atraso forem alterados.

ATUALIZAÇÃO 2:

Então parece que a solução foi encontrada, como pode ser visto abaixo (solução NFLOG).

ATUALIZAÇÃO 3:

Aqui são descritas algumas desvantagens da solução NFLOG (cabeçalhos grandes da camada de link e somas de verificação TCP erradas para pacotes TCP de saída com carga útil zero) e proposta uma solução melhor com NFQUEUE que não tem nenhum destes problemas:Soma de verificação TCP errada para pacotes de saída de comprimento zero (capturados com iptables). No entanto, para minhas tarefas (teste de esquemas de controle de congestionamento), nem NFLOG nem NFQUEUE são adequados. Como é explicado pelo mesmo link, a taxa de envio é acelerada quando os pacotes são capturados dos iptables do kernel (é assim que eu entendo). Portanto, quando você grava no remetente capturando da interface (ou seja, regularmente), você obtém um dump de 2 Gigabytes, enquanto se você grava no remetente capturando do iptables você obtém um dump de 1 Gigabyte. A grosso modo.

ATUALIZAÇÃO 4:

Finalmente, em meu projeto eu uso a solução ponte Linux descrita em minha própria resposta abaixo.

Responder1

De acordo comFluxo de pacotes no Netfilter e na rede geralesquemático, capturas tcpdump (AF_PACKET) depoissaída (qdisc). Portanto, é normal que você não veja o atraso no tcpdump: o atraso já estava presente na captura inicial.

Você teria que capturá-lo um passo antes, então envolva um terceiro sistema:

S1: system1, executa tcpdump na interface de saída
R: roteador (ou bridge, conforme sua conveniência, isso não muda nada), executa o qdisc netem
S2: system2, executa tcpdump na interface de entrada

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

Isso significa 3 redespilhasenvolvidos, sejam eles reais, vm, namespace de rede (incluindoredes ip, LXC, ...)


Opcionalmente, também é possível trapacear e mover todas as configurações especiais do roteador (ou bridge) usando umIFBinterface comespelhadotráfego: permite por meio de um truque (dedicado para este caso) inserir netem após a entrada em vez de na saída:

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

Há um exemplo básico de uso do IFB emtc espelhadopágina de manual:

Usando uma interface ifb, é possível enviar tráfego de entrada através de uma instância do 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

Apenas usenetemem ifb0 em vez de sfq (e em namespace de rede não inicial, ip link add name ifbX type ifbfunciona bem, sem modprobe).

Isso ainda requer 3 pilhas de rede para funcionar corretamente.


usandoNFLOG

Após uma sugestão de JenyaKh, é possível capturar um pacote comtcpdump,antessaída (portanto, antes do qdisc) e depois na saída (após qdisc): usandotabelas de ip(ounftáveis) para registrar pacotes completos na infraestrutura de log do netlink e ainda lê-los comtcpdump, e novamente usandotcpdumpna interface de saída. Isso requer apenas configurações em S1 (e não precisa mais de roteador/ponte).

Então comtabelas de ipem S1, algo como:

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

Filtros específicos provavelmente devem ser adicionados para corresponder ao teste realizado, porquetcpdumpo filtro é limitado na interface nflog (o wireshark deve lidar melhor com isso).

Caso seja necessária a captura da resposta (aqui feita em grupo diferente, exigindo assim umatcpdump):

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

Dependendo das necessidades também é possível movê-los parabruto/SAÍDAebruto/PREROUTINGem vez de.

Comtcpdump:

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

Se um grupo diferente (= 2) foi usado para entrada:

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

Então, ao mesmo tempo, como sempre:

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

Responder2

ATUALIZAR:

Então finalmente usei essa solução. Está presente na minha solução. Afinal, funcionou bem para mim.


Eu (o iniciador do tópico) resolvi meu problema usando o Linux Bridge. Aqui [https://www.linuxquestions.org/questions/linux-networking-3/transferring-all-traffic-through-an-extra-interface-4175656515] Escrevi que consegui usar o Linux bridge, mas descartei a possibilidade:"Mas esta solução não atende às minhas necessidades, pois na realidade existe um link Ethernet extra entre as interfaces h1-br0 e h1-eth0. Preciso desse material para medições de desempenho, então não posso ter nenhum link Ethernet extra. Quero dizer esta solução com bridge bagunça minha topologia ao introduzir links extras."

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

Por que descartei a solução primeiro? Inicialmente, minha topologia é:

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

No link r1---r2tenho taxa de netem configurada para 100 Mbps, no link a1---r1não há limites de taxa. Como a fila de transmissão do roteador r1que o conecta ao roteador r2é de 1000 pacotes, tive o efeito de estouro de fila (alguns pacotes são descartados) ao enviar tráfego de a1para r2. E estava tudo bem. É assim que acontece no mundo real, com as filas do roteador transbordando em caso de gargalo no link.

Agora faço toda essa pesquisa para adicionar limites de atraso e taxa a1---r1também. Então eu criei essa solução usando ponte Linux. Mas pensei que esta solução não funcionaria. Abaixo você confere a nova topologia com ponte Linux:

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

Portanto, meu problema com a solução era que eu esperava que o estouro da fila estivesse presente agora na fila de transmissão de interface a1-eth0. Ou seja, é da mesma forma que na imagem anterior onde o overflow estava na interface de r1conexão ao r2. Analogamente.

E esse excesso eu não quero. Porque na topologia normal - sem usar ponte Linux para fins de medição de atraso - não temos nenhum overflow de fila de transmissão de a1-eth0:

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

Mas ontem criei novamente a topologia com ponte Linux (a 3ª topologia desenhada acima) e lancei o tráfego na topologia fluindo de a1para r2. Verifiquei o backlog (número atual de pacotes na fila) da fila de transmissão de a1-eth0chamada do comando tc -s qdisc show dev a1-eth0em ciclo com intervalo de 500ms e o backlog da fila de transmissão a1-br0com o comando análogo.

Foi para isso que vi a1-eth0, recebi as mensagens:

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 

Foi para isso que vi a1-br0, recebi as mensagens:

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 

Portanto, pode-se ver que nenhum overflow acontece a1-eth0e na realidade não "parece" que a1-br0envia nada, embora na realidade envie. Portanto, o link entre a1-broe a1-eth0não é como aquele (o quinto par de links) entre a1e roteador r1. Eu não sei por que isso acontece. É estranho porque verifiquei que posso, por exemplo, definir a configuração de atraso do netem como a1-br0- então é como uma interface normal.

De qualquer forma, verifiquei se a solução com ponte atende todas as minhas necessidades. Ainda não explorei por que isso funciona (quero dizer, no sentido do que estava explicando acima - estouro de fila e etc.).


Aqui estão os comandos que executei no host a1para referência. Eu entendo que é difícil entendê-los completamente sem o contexto. Mas, talvez, ajude alguém no futuro:

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

A topologia com endereços IP, à qual apliquei os comandos, também está presente aqui:Executando ping em uma interface do roteador Linux por outra interface deste roteador. Aqui está a topologia:

------                           ------                            ------
| 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)----- 

informação relacionada