Entendendo tc qdisc e iperf

15

Estou tentando limitar a largura de banda tce verificar os resultados com iperf. Comecei assim:

# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.7 port 35213 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec   830 MBytes   696 Mbits/sec

As duas instâncias são conectadas diretamente através da Ethernet.

Em seguida, configurei um htb qdisccom uma classe padrão para limitar a largura de banda a 1mbit / s:

# tc qdisc add dev bond0 root handle 1: htb default 12
# tc class add dev bond0 parent 1: classid 1:12 htb rate 1mbit

Mas não recebo o que espero:

# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.7 port 35217 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-12.8 sec   768 KBytes   491 Kbits/sec

Se eu dobrar a taxa, a largura de banda medida não será alterada. o que estou perdendo? Por que a largura de banda medida não corresponde ao 1mbit do rateparâmetro? Quais parâmetros eu preciso definir para limitar a largura de banda a uma taxa exata exata?

No entanto, a manpágina diz que tbfdeve ser a qdiscescolha para esta tarefa:

O Token Bucket Filter é adequado para diminuir a velocidade do tráfego para uma taxa configurada com precisão. Escala bem para grandes larguras de banda.

tbfrequer parâmetros rate, burste ( limit| latency). Então, tentei o seguinte sem entender como burste ( limit| latency) afetam a largura de banda disponível:

# tc qdisc add dev bond0 root tbf rate 1mbit limit 10k burst 10k

Isso me proporcionou uma largura de banda medida de 113 Kbits / s. Brincar com esses parâmetros não mudou muito até que notei que adicionar um valor para mtumudar as coisas drasticamente:

# tc qdisc add dev bond0 root tbf rate 1mbit limit 10k burst 10k mtu 5000

resultou em uma largura de banda medida de 1,00 Mbits / s.

Quais parâmetros eu precisaria definir para limitar a largura de banda a uma taxa exata exata?

Devo usar a disciplina htbou tbffila para isso?

EDIT :

Com base nesses recursos, fiz alguns testes:

Eu tentei as seguintes configurações.

Em uma máquina física

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto br0
iface br0 inet dhcp
bridge_ports eth0

Medição com iperf:

# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.4 port 51804 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-11.9 sec  1.62 MBytes  1.14 Mbits/sec

Enquanto o iperfservidor calculou uma largura de banda diferente:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.4 port 51804
[  4]  0.0-13.7 sec  1.62 MBytes   993 Kbits/sec

Em uma máquina virtual sem ligação

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

Medição com iperf:

# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.7 port 34347 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-11.3 sec  1.62 MBytes  1.21 Mbits/sec

Enquanto o iperfservidor calculou uma largura de banda diferente:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.7 port 34347
[  4]  0.0-14.0 sec  1.62 MBytes   972 Kbits/sec

Em uma máquina virtual com ligação (tc configurado em eth0)

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
allow-bond0 eth0
iface eth0 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto eth1
allow-bond0 eth1
iface eth1 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto bond0
iface bond0 inet dhcp
    bond-slaves none
    bond-mode 1
#    bond-arp-interval 250
#    bond-arp-ip-target 192.168.2.1
#    bond-arp-validate 3

Medição com iperf:

# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.9 port 49054 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-11.9 sec  1.62 MBytes  1.14 Mbits/sec

Enquanto o iperfservidor calculou uma largura de banda diferente:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.9 port 49054
[  4]  0.0-14.0 sec  1.62 MBytes   972 Kbits/sec

Em uma máquina virtual com ligação (tc configurado em bond0)

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
allow-bond0 eth0
iface eth0 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto eth1
allow-bond0 eth1
iface eth1 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto bond0
iface bond0 inet dhcp
    bond-slaves none
    bond-mode 1
#    bond-arp-interval 250
#    bond-arp-ip-target 192.168.2.1
#    bond-arp-validate 3

Medição com iperf:

# tc qdisc add dev bond0 root handle 1: htb default 12
# tc class add dev bond0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.9 port 49055 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-13.3 sec   768 KBytes   475 Kbits/sec

Enquanto o iperfservidor calculou uma largura de banda diferente:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.9 port 49055
[  4]  0.0-14.1 sec   768 KBytes   446 Kbits/sec

O resultado não muda se eu remover eth1(a interface passiva) do vínculo.

Conclusão

O controle de tráfego em uma interface de vínculo não funciona, ou pelo menos não como o esperado. Vou ter que investigar mais.

Como solução alternativa, pode-se adicionar as disciplinas de enfileiramento diretamente às interfaces pertencentes ao vínculo.

Matías E. Fernández
fonte
Curiosamente, isso parece ter funcionado para esse cara: blog.tinola.com/?e=22
Matías E. Fernández
1
Eu acho que com o htb, você precisa usar tc filterpara colocar os pacotes em classes. Você também pode precisar alterar alguns dos parâmetros htb (ajuste-o exatamente como tbf). Sugiro pesquisar tcng, que é um front-end para o tc. (Estes são ponteiros rápidos ...)
derobert
Não vi nenhum filtro na sua postagem. Quais comandos você está usando para corresponder ao tráfego para que ele possa ter uma taxa limitada?

Respostas:

2

Quando você não tem certeza de como o tc funciona, você ainda pode monitorar o tc e ver como os pacotes fluem? Você pode usar meu script para monitorar o tc e precisar executá-lo em um terminal com privilégios elevados. Você pode mudar o wlan0 para outra interface e também precisa de grep e awk:

      #!/bin/sh
      INTERVAL=15
      while sleep $INTERVAL
      do
             /usr/sbin/tc -s -d class show dev wlan0

             uptime
             more /proc/meminfo | grep MemFree | grep -v grep
             echo cache-name num-active-objs total-objs obj-size
             SKBUFF=`more /proc/slabinfo | grep skbuff | grep -v grep | awk 
             '{print $2} {print $3} {print $4}'`

             echo skbuff_head_cache: $SKBUFF
      done
Gigamegs
fonte
0

Tente aumentar os valores burst/ limit. Os algoritmos do bucket de tokens escalam bem, mas têm uma relação precisão / velocidade limitada.

A precisão é alcançada usando um pequeno balde, aumentando a velocidade do tamanho dos tokens. Tokens grandes significam que a taxa na qual eles são reabastecidos diminui (tokens por segundo = bytes por segundo / bytes por token).

O rateparâmetro fornece a taxa média que não deve ser excedida, os parâmetros burstou limitfornecem o tamanho da janela de média. Como o envio de um pacote na velocidade da linha excede a taxa definida para o tempo em que o pacote é transferido, a janela de média precisa ser pelo menos grande o suficiente para que o envio de um único pacote não empurre a janela inteira acima do limite; se mais pacotes caberem na janela, o algoritmo terá mais chances de atingir exatamente o alvo.

Simon Richter
fonte
0

execute isso antes de adicionar disciplina de fila na interface de ligação (bond0 neste caso)

ipconfig bond0 txqueuelen 1000

não funciona porque o dispositivo virtual de software, como a interface de ligação, não possui fila padrão.

Ventilador
fonte
0

Como os bonddispositivos não têm fila definida, a definição do qdisctamanho corrige explicitamente o problema para mim.

Aqui está um exemplo para uma folha qdisca ser usada sob HTBestrutura: tc qdisc add dev $dev parent $parent handle $handle pfifo limit 1000

SagiLow
fonte