LINUX.ORG.RU
решено ФорумAdmin

Непонятки с iptables

 ,


0

2

Коллеги, разъясните пожалуйста, что может происходить?

Есть 2 устройства (условно, D63 и D64) - на каждом по одному 1G интерфейсу в общую сеть и по одному 10G интерфейсу, друг на друга. Схема примерно такая:



         D64                                   D63
<=1G=> | eth0 : 172.17.5.202/22    |         | eth1  : 172.17.0.2/16     | <=1G=>
       |                           |         |                           |
       | eth3 : 192.168.100.64/24  | <=10G=> | eth11 : 192.168.100.63/24 |
       |              /            |         |                           |
       |     (tun00e...tun07e)     |
       |              /            |
       |      ping 172.17.0.2      |
              

       # ip route show dev eth3
       172.17.0.0/16  scope link 
       192.168.100.0/24  proto kernel  scope link  src 192.168.100.64

На D64 запускается приложение, которое создаёт 8 (по числу процессоров) TUN-интерфейсов с именами (tun00e..tun07e) после чего происходит хитрая настройка фильтра пакетов так, чтобы локально генерируемый на D64 в сторону D63 (например, с использованием ping) трафик распределялся по tun-устройствам в соответствии с номером обрабатывающего пакет процессора. Пример настройки такой:

	ip link set dev tun00e up
	ip link ...
	ip link set dev tun07e up

	ip route add default dev tun00e table 100
	ip route ...
	ip route add default dev tun07e table 107

	ip rule add fwmark 100 table 100
	ip rule ...
	ip rule add fwmark 107 table 107

	iptables -t mangle -A OUTPUT -o eth3 -m cpu --cpu 0 -j MARK --set-mark 100
	iptables ...
	iptables -t mangle -A OUTPUT -o eth3 -m cpu --cpu 7 -j MARK --set-mark 107

На каждом из tun-устройств сидит поток приложения, который вычитывает оттуда IP-пакет и, далее, инкапсулирует его в UDP-датаграмму (sport:10000, dport=10000, checksum=0) с добавлением нового IP заголовка (saddr:192.168.100.64, daddr:192.168.100.63). После чего заталкивает полученный пакет обратно в стек через это же устройство.

Вот что далее запускается на D64:

	ip route add 172.17.0.2/16 dev eth3
	ping 172.17.0.2

ПРОБЛЕМА в том, что данные через eth3 НЕ ХОДЯТ.

С использованием tcpdump видно, что данные через tun-устройства идут. Более того, tcpdump подтверждает корректность построения новой IP-датаграммы.

Ниже приведу вывод статистики по iptables, из которой видно, что ICMP-пакеты проходят по цепочкам: OUTPUT и POSTROUTING, попадая, очевидно, на tun-устройство. Далее, видно также, что из tun-устройства выходят необходимые UDP-пакеты — цепочка PREROUTING. Но почему-то, далее эти пакеты не идут.

# iptables -t mangle -L -vn
Chain PREROUTING (policy ACCEPT 18685 packets, 1904K bytes)
 pkts bytes target     prot opt in     out     source               destination         
 4278  479K            udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:10000
    0     0            icmp --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain INPUT (policy ACCEPT 14997 packets, 1480K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0            udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:10000

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0            udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:10000
    0     0            icmp --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 5644 packets, 772K bytes)
 pkts bytes target     prot opt in     out     source               destination         
  650 54600 MARK       all  --  *      eth3    0.0.0.0/0            0.0.0.0/0            cpu 0 MARK set 0x64
  ...
  615 51660 MARK       all  --  *      eth3    0.0.0.0/0            0.0.0.0/0            cpu 7 MARK set 0x6b
 3465  291K            icmp --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain POSTROUTING (policy ACCEPT 5644 packets, 772K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0            udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:10000
 3449  290K            icmp --  *      *       0.0.0.0/0            0.0.0.0/0           

Что смотреть, куда копать? ;)

P.S.

net.ipv4.ip_forward = 1

★★

Ответ на: комментарий от i82

Дак посмотрите /proc/interrupts и /proc/softirqs, там ведь указаны счётчики, какой процессор сколько обработал прерываний.

mky ★★★★★
()
Ответ на: комментарий от mky

Прогнал iperf за 60 секунд, обнулив статистику перезагрузкой. Получилось вот что.

Что касается обработки прерываний от сетевой карты, то она распределяет обработку очередей по процессорам, как это видно по таблице:

            CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7
 194:       7128          0          0          0          0          0          0          0  IR-PCI-MSI-edge  eth11-TxRx-0
 195:          4       7171          0          0          0          0          0          0  IR-PCI-MSI-edge  eth11-TxRx-1
 196:          4          0        615          0          0          0          0          0  IR-PCI-MSI-edge  eth11-TxRx-2
 197:          4          0          0         44          0          0          0          0  IR-PCI-MSI-edge  eth11-TxRx-3
 198:          4          0          0          0      45763          0          0          0  IR-PCI-MSI-edge  eth11-TxRx-4
 199:          4          0          0          0          0     237906          0          0  IR-PCI-MSI-edge  eth11-TxRx-5
 200:          7          0          0          0          0          0     568355          0  IR-PCI-MSI-edge  eth11-TxRx-6
 201:          4          0          0          0          0          0          0     561565  IR-PCI-MSI-edge  eth11-TxRx-7
 202:          2          0          0          0          0          0          0          0  IR-PCI-MSI-edge  eth11

Однако, здесь бросается в глаза неравномерность количества прерываний на процессорах. Я это связываю с тем, что т.к. в моей схеме тестирования D64 генерит трафик, а D63 его ловит и при этом используются постоянные параметры, то модуль сетевой карты, отвечающий за распределение потока по очередям и раскидывающий его по какому-то критерию, в этой схеме даёт неравномерную загрузку очередей...

Что касается статистики softirq, то тут ситуация такая:

                    CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7       
      NET_TX:        395          1         13          0         40          0          2          2
      NET_RX:     331584      33902      29998        732     248617    9891414    2740006    2687155

И вот что наблюдается в счётчиках iptables:

Chain PREROUTING (policy ACCEPT 14M packets, 16G bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MARK       all  --  eth11  any     anywhere             anywhere             cpu 0 MARK set 0xc8
    0     0 MARK       all  --  eth11  any     anywhere             anywhere             cpu 1 MARK set 0xc9
    0     0 MARK       all  --  eth11  any     anywhere             anywhere             cpu 2 MARK set 0xca
    0     0 MARK       all  --  eth11  any     anywhere             anywhere             cpu 3 MARK set 0xcb
    0     0 MARK       all  --  eth11  any     anywhere             anywhere             cpu 4 MARK set 0xcc
5374K 7846M MARK       all  --  eth11  any     anywhere             anywhere             cpu 5 MARK set 0xcd
    0     0 MARK       all  --  eth11  any     anywhere             anywhere             cpu 6 MARK set 0xce
    0     0 MARK       all  --  eth11  any     anywhere             anywhere             cpu 7 MARK set 0xcf

Chain INPUT (policy ACCEPT 5375K packets, 7738M bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 8943K packets, 8124M bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 3568K packets, 207M bytes)
 pkts bytes target     prot opt in     out     source               destination         
 166K 9465K MARK       all  --  any    eth11   anywhere             anywhere             cpu 0 MARK set 0x64
16890  951K MARK       all  --  any    eth11   anywhere             anywhere             cpu 1 MARK set 0x65
14933  856K MARK       all  --  any    eth11   anywhere             anywhere             cpu 2 MARK set 0x66
  437 25820 MARK       all  --  any    eth11   anywhere             anywhere             cpu 3 MARK set 0x67
 146K 9107K MARK       all  --  any    eth11   anywhere             anywhere             cpu 4 MARK set 0x68
 291K   17M MARK       all  --  any    eth11   anywhere             anywhere             cpu 5 MARK set 0x69
1478K   85M MARK       all  --  any    eth11   anywhere             anywhere             cpu 6 MARK set 0x6a
1454K   84M MARK       all  --  any    eth11   anywhere             anywhere             cpu 7 MARK set 0x6b

Chain POSTROUTING (policy ACCEPT 13M packets, 8330M bytes)
 pkts bytes target     prot opt in     out     source               destination

Как видно, в OUTPUT какое-никакое распределение есть. Однако, в PREROUTING совсем всё печально - обработка в один поток :(

i82 ★★
() автор топика
Последнее исправление: i82 (всего исправлений: 1)
Ответ на: комментарий от i82

Да, с PREROUTING как то всё странно. И счётчики softirq странные. POSTROUTING прошло 14M пакетов, сумма RX счётчиков 15,9М, что как бы близко, но все ваши пакеты 5,3M обработал один проц #5. По хешу заголовка пакета, что-ли они определяют процессор, обрабатывающий sotfirq?

Но и с OUTPUT, ИМХО, беда для вашей схемы. Практически всё легло на #6 и #7. Не знаю, может вам тупо попробовать поочерёдно отправлять пакеты в разные тунели, без cpu, а просто по -m statistic --mode nth.

mky ★★★★★
()
Ответ на: комментарий от mky

Удалось разобраться с тем, что происходило.

Действительно, сетевая карта пихала весь поток в одну и ту же очередь, т.к. её flow-director, основываясь на постоянных значениях их IP/UDP заголовков, выдавал один и тот же номер очереди. Первое, что было сделано - рандомизирован порт отправителя в UDP-дейтаграмме. Что касается OUTPUT, то здесь результат меняется при увеличении числа генерирующих потоков в iperf.

Таким образом, в результате получилось собрать и протестировать схему. Результат теста, по версии iperf, получился:

# iperf -c 172.17.0.2 --mss 1400 -t 60 -P 8
WARNING: attempt to set TCP maximum segment size to 1400, but got 536
WARNING: attempt to set TCP maximum segment size to 1400, but got 536
WARNING: attempt to set TCP maximum segment size to 1400, but got 536
WARNING: attempt to set TCP maximum segment size to 1400, but got 536
WARNING: attempt to set TCP maximum segment size to 1400, but got 536
WARNING: attempt to set TCP maximum segment size to 1400, but got 536
------------------------------------------------------------
Client connecting to 172.17.0.2, TCP port 5001
WARNING: attempt to set TCP maximum segment size to 1400, but got 536
TCP window size: 64.0 KByte (default)
------------------------------------------------------------
WARNING: attempt to set TCP maximum segment size to 1400, but got 536
[ 11] local 192.168.100.64 port 51203 connected with 172.17.0.2 port 5001
[  3] local 192.168.100.64 port 51196 connected with 172.17.0.2 port 5001
[  4] local 192.168.100.64 port 51197 connected with 172.17.0.2 port 5001
[  6] local 192.168.100.64 port 51198 connected with 172.17.0.2 port 5001
[  5] local 192.168.100.64 port 51199 connected with 172.17.0.2 port 5001
[  9] local 192.168.100.64 port 51200 connected with 172.17.0.2 port 5001
[  8] local 192.168.100.64 port 51201 connected with 172.17.0.2 port 5001
[ 10] local 192.168.100.64 port 51202 connected with 172.17.0.2 port 5001
[ ID] Interval       Transfer     Bandwidth
[ 11]  0.0-60.0 sec  2.34 GBytes   336 Mbits/sec
[  3]  0.0-60.0 sec  2.59 GBytes   371 Mbits/sec
[  4]  0.0-60.0 sec  3.10 GBytes   443 Mbits/sec
[  6]  0.0-60.0 sec  5.72 GBytes   819 Mbits/sec
[  5]  0.0-60.0 sec  2.35 GBytes   337 Mbits/sec
[  8]  0.0-60.0 sec  2.46 GBytes   352 Mbits/sec
[ 10]  0.0-60.0 sec  2.44 GBytes   350 Mbits/sec
[  9]  0.0-60.0 sec  2.40 GBytes   344 Mbits/sec
[SUM]  0.0-60.0 sec  23.4 GBytes  3.35 Gbits/sec

То есть, в принципе, есть повышение производительности, однако не линейное, как предполагалось. Не исключено, что это связано с тем, что тестирование включает в себя собственно генерацию трафика, но сейчас нет возможность проверить как изменится результат, если будет чистый «форвардинг», без генерации.

i82 ★★
() автор топика
Ответ на: комментарий от i82

На зубах висит гимнаст -
До чего же он зубаст!
Вот такому бы гимнасту
Выдавать зубную пасту! (Д. Хармс)

Офигенная работа, я не программист, но преклоняюсь перед трудом ТС. Всем бы нам такими быть.

Кстати, что будут делать с готовым продуктом?

pianolender ★★★
()
Ответ на: комментарий от pianolender

На зубах висит гимнаст -
До чего же он зубаст!
Вот такому бы гимнасту
Выдавать зубную пасту! (Д. Хармс)

Очень точно ;)

i82 ★★
() автор топика
Ответ на: комментарий от i82

Шифрация/дефирация траффика увеличивает его латентность, может вам стоит попрбовать tcp-окно побольше 64 кБайт (опция -w).

Хотя, не понятно, почему такая неравномерность в результатах, точнее семь потоков 300-400 Мбит и один 819 Мбит. По счётчикам в iptables распределение равномерное?

mky ★★★★★
()
Ответ на: комментарий от mky

Это результаты, полученные без шифрования: простой туннель — прочитал, инкапсулировал, записал. Что касается неравномерности загрузки, предположу, что один из потоков представляет собой «родителя» всех остальных (главный поток iperf) и ему система даёт больший приоритет, но это лишь предположение. Завтра посмотрю добавлю задержку - timing-имитацию шифрования и счётчики: интересно посмотреть, да.

i82 ★★
() автор топика
Ответ на: комментарий от mky

Какой-то ложный всплеск видимо был. Сейчас прогнал тесты для 32 потоков, распределение трафика примерно равное - около 100 МБит/с для потока, 3.6 GBits/s в сумме.

i82 ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.