Re: Как сделать ipip tunnel mtu > 1480 ? [message #37936 is a reply to message #37933] |
Wed, 04 November 2009 13:53  |
maxx
Messages: 13 Registered: November 2008 Location: Volgograd, Russia
|
Junior Member |
|
|
Да, выставляется - я об этом упоминал в начале задачи. Но, когда у меня большие пакеты через туннель с флагом DF не ходили с такой ошибкой "Frag needed and DF set (mtu = 1480)", то я подумал, что на туннеле не выставляется mtu реально больший, чем mtu физики, через которую уходят пакеты после инкапсуляции, однако был не прав - с туннелями и mtu на них все в порядке. Проблема в другом и теперь, после некоторых опытов, могу ее описать в правильном свете.
То, что я описал в предыдущем своем сообщении про ip-фрагментацию, все верно. Я думал, что проблема в том, что реальный mtu на туннеле в Linux не поднимается более mtu физики - 20, поэтому сделал между HN и VE veth-интерфейс с mtu 1540 (с запасом, на всякий случай). При таком раскладе mtu на туннеле внутри VE должен был бы работать не меньше 1520. Его я и выставил. Тогда на HN с VE должны были приходить бы пакеты большего, чем 1500 размера и фрагментироваться на HN, так как mtu реальных интерфейсов, как и положено - 1500.
Пустил пинг и получил тот же самый ответ:
Frag needed and DF set (mtu = 1480)
И тут меня заинтересовало, кто же мне дает такой ответ, неужели HN, так как это на нем интерфейсы с mtu 1500. И оказалось, что да. С помощью tcpdump внутри VE увидел, что получен ICMP ответ от HN "unreachable - need to frag (mtu 1500)" и проблема на самом деле в том, что когда в контейнере пакет с флагом DF проходит инкапсуляцию, то этот флаг переносится в заголовок IPIP-пакета (капсулы). И уже IPIP пакет с флагом DF и размером большим 1500 благополучно проходит veth от VE до HN, но натыкается на реальный интерфейс с mtu 1500 внутри HN, после чего, как и положено HN отвечает ICMP сообщением в сторону VE "unreachable - need to frag (mtu 1500)".
На всякий случай привожу выкладки эксперимента (VE 102).
На HN:
13: veth102.0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1540 qdisc noqueue
inet 192.168.11.1/30 scope global veth102.0
C HN доступна сеть, куда в том числе будем приземляться туннель (192.168.22.150).
Внутри VE102:
7: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1540 qdisc noqueue
inet 192.168.11.2/30 brd 192.168.11.3 scope global eth0
11: tun0@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1520 qdisc noqueue
link/ipip 192.168.11.2 peer 192.168.22.150
inet 192.168.100.13 peer 192.168.100.14/30 brd 192.168.100.15 scope global tun0
Есть еще 192.168.2.1/30 на eth1 интерфейсе, с которого буду пускать пинг в сеть 192.168.1.0/24, находящуюся на другой стороне туннеля.
[root@vr102 /]# ip ro
192.168.1.0/24 via 192.168.100.14 dev tun0
default via 192.168.11.1 dev eth0
На другом конце настройки аналогичные, ОС только не Linux. Да это и не столь важно...
Теперь сам тест - пускаю пинг с VE на 192.168.1.1.
[root@vr102 /]# ping -s 1452 -M do -I 192.168.2.1 192.168.1.1
Пинги ходят... Смотрю, что происходит...
[root@vr102 /]# tcpdump -nv -i tun0
tcpdump: listening on tun0, link-type RAW (Raw IP), capture size 96 bytes
04:43:08.156747 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: ICMP (1), length: 1480) 192.168.2.1 > 192.168.1.1: ICMP echo request, id 17231, seq 1, length 1460
04:43:08.160526 IP (tos 0x0, ttl 255, id 45198, offset 0, flags [DF], proto: ICMP (1), length: 1480) 192.168.1.1 > 192.168.2.1: ICMP echo reply, id 17231, seq 1, length 1460
...
[root@vr102 /]# tcpdump -nv -i eth0
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
04:43:08.156767 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: IPIP (4), length: 1500) 192.168.11.2 > 192.168.22.150: IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: ICMP (1), length: 1480) 192.168.2.1 > 192.168.1.1: ICMP echo request, id 17231, seq 1, length 1460
04:43:08.160526 IP (tos 0x0, ttl 252, id 45199, offset 0, flags [none], proto: IPIP (4), length: 1500) 192.168.22.150 > 192.168.11.2: IP (tos 0x0, ttl 255, id 45198, offset 0, flags [DF], proto: ICMP (1), length: 1480) 192.168.1.1 > 192.168.2.1: ICMP echo reply, id 17231, seq 1, length 1460
...
Аналогичные пакеты и на HN на интерфейсе veth102.0.
Как видно, флаг DF присутствует не только в IP-заголовке ICMP, но и в IP-заголовке IPIP пакета (капсулы, так сказать).
Увеличил размер пакета на 1:
[root@vr102 /]# ping -s 1453 -M do -I 192.168.2.1 192.168.1.1
[root@vr102 /]# tcpdump -nv -i tun0
04:43:15.777312 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: ICMP (1), length: 1481) 192.168.2.1 > 192.168.1.1: ICMP echo request, id 17487, seq 1, length 1461
04:43:16.777686 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: ICMP (1), length: 1481) 192.168.2.1 > 192.168.1.1: ICMP echo request, id 17487, seq 2, length 1461
(ICMP только в одну сторону, ответа нет)
[root@vr102 /]# tcpdump -nv -i eth0
04:43:15.777321 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: IPIP (4), length: 1501) 192.168.11.2 > 192.168.22.150: IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: ICMP (1), length: 1481) 192.168.2.1 > 192.168.1.1: ICMP echo request, id 17487, seq 1, length 1461
04:43:15.777354 IP (tos 0xc0, ttl 64, id 62606, offset 0, flags [none], proto: ICMP (1), length: 576) 192.168.11.1 > 192.168.11.2: ICMP 192.168.22.150 unreachable - need to frag (mtu 1500), length 556
IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: IPIP (4), length: 1501) 192.168.11.2 > 192.168.22.150: IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: ICMP (1), length: 1481) 192.168.2.1 > 192.168.1.1: ICMP echo request, id 17487, seq 1, length 1461[|icmp]
Собственно, только в этот момент я внимательнее вгляделся в вывод tcpdump и обратил внимание, что флаг DF перетекает из ICMP в заголовок IPIP пакета.
Обратил внимание также и на пакет от 192.168.11.1 (HN).
04:43:15.777354 IP (tos 0xc0, ttl 64, id 62606, offset 0, flags [none], proto: ICMP (1), length: 576) 192.168.11.1 > 192.168.11.2: ICMP 192.168.22.150 unreachable - need to frag (mtu 1500), length 556
Естественно, что он не может отдать пакет без фрагментации через реальный интерфейс. Он отвечает контейнеру "need to frag (mtu 1500)". А команда ping в свою очередь:
From 192.168.2.1 icmp_seq=3 Frag needed and DF set (mtu = 1480)
From 192.168.2.1 icmp_seq=3 Frag needed and DF set (mtu = 1480)
From 192.168.2.1 icmp_seq=3 Frag needed and DF set (mtu = 1480)
...
По этим 1480 байтам из ответа ping я изначально просто сделал неправильное предположение, что mtu туннеля реально не поднялся больше 1480. Ответ-то, якобы, от 192.168.2.1 - то есть от ip на моей стороне.
Так вот, правильные вопросы у меня теперь такие.
1. Как же правильно, переносить этот флаг DF d заголовок IPIP пакета (как в Linux) или не переносить (как в BSD) ?
2. Получается, что в Linux нужно только поправить модуль ipip, а не само ядро. Верно ? И правильно ли будет с этим обратиться к разработчикам OpenVZ ? Может вынести некоторый параметр в sysctl для выбора, как должны пакеты с флагом DF инкапсулироваться ?
P.S. Про использование контейнеров в качестве роутера. Все же есть в этом свои плюсы. Есть и минус - накладные расходы ресурсов. В нашем случае первое сильно перевешивает второе. Так что очень хочется довести проблему до ее решения.
[Updated on: Wed, 04 November 2009 16:02] Report message to a moderator
|
|
|