LINUX.ORG.RU
ФорумAdmin

Проблема с фрагментацией IP датаграмм


0

0

Добрый день!

Столкнулся вот с чем. Есть две локальные сети (mtu=1500) разделенные двумя маршрутизаторами с сегментом между маршрутизаторами c mtu=1464. При посылке эхо-запросов с размером в 2000 байт с одного из хостов (версия ядра linux 2.4.2) исходная датаграмма фрагментируется на два фрагмента (1500 байт и 588 байт). Первый фрагмент нормально доходит до хоста назначения в другой локалке, а меньший фрагмент рубиться на перовом же маршрутизаторе. При попытке пинговать с хоста с более свежим ядром (2.6) все ок. Сравнил анализатором меньшие фрагменты с обеих машин - они (насколько это можно просмотреть в ethereal) - идентичны. То есть можно вроде как сказать что виновать рутер (кстати на нем все на пролет в плане фильтрации). Но почему такая избирательность именно к пакетам с машины с ядром 2.4.2 ?

P.S. На рутерах - FreeBSD 4.4

anonymous

>Сравнил анализатором меньшие фрагменты с обеих машин

Посмотрите оба фрагмента.

markevichus ★★★
()

По идее, router должен резать первый фрагмент на два. Почему этого не происходит? Пытается восстановить целый пакет и заново разрезать, а потом рубит свои же обрезки?

AEP ★★★★★
()

что-то странная ситуация с твоим pmtud.
почему фрагментация происходит на хосте отправителе а не на роутере? это говорит о том, что роутер послал айсиэмпи анричибле на пакет с df=1. а зачем ты выставляешь df=1.

а вообще можешь заслать сюда tcpdump сессии (с -vv) с роутеров (по обоим интерфейсам) и с этих машинок.

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

Значит, вот схема:

[192.168.1.2] serv (linux kernel 2.4.2-itc5mdk #30 2002) | mtu 1500 | [192.168.1.1] router1 (freebsd 4.4) | mtu 1464 | [192.168.2.1] router2 (freebsd 4.4) | mtu 1500 | [192.168.2.2] client

Что касается хоста serv (с которого пускаю пинги (#ping -s 2000 192.168.2.2) на хост client): Пробовал с ip.no_pmtu_disc=0, т.е. включенным механизмом pmtud. Тогда router1 присылал icmp-сообщение (тип 3, код 4 - frag needed and DF set) и хост server начинал фрагментировать датаграмму:

06:35:40.586505 192.168.1.2 > 192.168.2.2: (frag 29314:568@1440) (ttl 64, len 588) 06:35:40.586519 192.168.1.2 > 192.168.2.2: icmp: echo request (frag 29314:1440@0+) (ttl 64, len 1460)

Пробовал выключать pmtud (ip.no_pmtu_disc=1), тогда хост server сам фрагментировал датаграмму, руководствуясь mtu своего интерфейса (1500):

06:33:36.155507 192.168.1.2 > 192.168.2.2: (frag 29230:528@1480) (ttl 64, len 548) 06:33:36.155519 192.168.1.2 > 192.168.2.2: icmp: echo request (frag 29230:1480@0+) (ttl 64, len 1500) 06:33:37.146107 192.168.1.2 > 192.168.2.2: (frag 29231:528@1480) (ttl 64, len 548) 06:33:37.146122 192.168.1.2 > 192.168.2.2: icmp: echo request (frag 29231:1480@0+) (ttl 64, len 1500)

Что касается маршрутизатора router1, то это закрытое решение на базе freebsd 4.4. Т.е. все что я могу это через программный интерфейс посмотреть на пакеты пропущенные/отброшенные правилами и интерпретацию заголовков этих пакетов самой программой управления. (грубо говоря, залезть и сделать tcpdump -w не могу). Так вот в обоих случаях (pmtud вкл/выкл на хосте server), на маршрутизаторе router1 вижу, что первый (и больший) фрагмент пропускается на входном (из локальной сети) интерфейсе и выпускается на выходном интерфейсе и нормально доходит до хоста назначения (client). А меньший фрагмент пропускается на внутреннем интерфейсе и рубиться на выходном. Вследствие чего не доходит до хоста назначения, котороый через таймаут начинает слать хосту server icmp-сообщение (тип 11, код 1 - frag reassembly time exceeded), что справедливо - получает-то он только один фрагмент...

Должен заметить, что аналогичного заданного (2000 и более байт) размера пинги нормально проходят по этой схеме если используются машины с linux ядрами 2.4.22 и выше.

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

ну коли роутеры на фре тебе не доступны и посмотреть что там творится нельзя, то остается решение с понижением mtu на linux машинах.

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

Значит, нашел кое чего.. Хост с ядром 2.4.2 фрагментирует исходную дейтаграмму на два фрагмента, больший - который содержит icmp заголовок и флаг More Fragments в IP-заголовке, и меньший фрагмент - остаток данных и IP заголовок с идентификатором таким же как у большего фрагмента и без флага MF.

Но! Почему-то, в отличие от хостов с более свежими версиями ядер, он отсылает сначала меньший фрагмент затем больший. В таком же порядке они и приходят на маршрутизатор.

Я понимаю, что по стандарту IP датаграммы могут приходить в разном порядке (best effort delivery и все такое), очередность их может нарушаться. Но! Это на сети. Почему хост при генерации дейтаграмм сам нарушает очередность - непонятно. Почему маршрутизатор ТАК обрабатывает фрагменты непонятно.

anonymous
()

Каким образом определяется, что пакеты от 2.4.2 (точнее второй фрагмент пакета в 588) вобще выходят с интерфейса?

Я к тому, что для чистоты эксперимента нужно между serv и router'ом втыкать свич с port-mirror, ну или хаб на 10 Мбит, a ethereal запускать на отдельном компьютере.

Ну и можно сделать hex-dump этих пакетов и сравнить для ядра 2.4.2 и для ядра 2.6.х. IP и ICMP простые протоколы, там не сложно по разнице в hex-dump определить различные флаги и т.д.

P.S. 2.4.2 было очень давно и врядли кто вспомнит, были ли там баги с фрагментацией. Я вот помню, что на наших серверах того времени 2.4.2 не испозовалось, сервера переходили 2.0.36 -> 2.4.7 или 2.2.x -> 2.4.10

P.P.S А почему с начала передается пакет в 588 байт, а потом 1460 байт? Вроде обычно сначала передавался первый фрагмент, а потом второй...

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

очень просто: tcpdump -n -v -i eth0

А по поводу hexdump...Я сравнивал пакеты фрагментированные ядром 2.4.2 и 2.6 - смотрел tcpdump'ом с опцией -X. Никакой значимой разницы.

Последнее что я обнаружил и что смущает больше всего - порядок выхода пакетов с интерфейса. Что видимо косвенно и является причиной "зарубания" на маршрутизаторе правилами фильтрации (когда я их выключаю - все проходит). Т.е. для файрвола маршрутизатора имеет значение в каком порядке приходят фрагменты.

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

>Почему хост при генерации дейтаграмм сам нарушает очередность - непонятно.

Ну а тут то чего непонятного, ИМХО баги. Наверное можно из интереса покачать changelog'и ядер Линукса и найти когда исправили эту ошибку...

>Почему маршрутизатор ТАК обрабатывает фрагменты непонятно.

А обработка фрагменов ip-пакетов на маршрутизаторе вобще больная тема. Ведь пакеты могут не только прийти в другом порядке, но и часть может вобще пойти другим маршрутом, следовательно, маршрутизатор не должен "склеивать" фрагменты пакетов, а только дальше фрагментировать их. ЕМНИП именно это и требует RFC.

Но при этом уже не получается настроить firewall для портов UDP и TCP, поэтмоу идут на "хак" по дефрагментации и новой фрагментации пакетов на каждом маршрутизаторе...

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

Хочешь сказать, что маршрутизатор на внутреннем интерфейсе дефрагментирует пакеты относящиеся к одной датаграмме, прогоняет через файрвол затем снова фрагментирует в выходном интерфейсе? Чудно как-то звучит :) И кстати, судя по доступным логам с маршрутизатора приходят фрагменты и уходят именно фрагменты. Т.е. фрагменты проходят независмо через файр, а не собранная из них дейтаграмма.

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

>Хочешь сказать, что маршрутизатор на внутреннем интерфейсе дефрагментирует пакеты относящиеся к одной датаграмме, прогоняет через файрвол затем снова фрагментирует в выходном интерфейсе?

Специально проверял это на Линукс 2.4.18. Там работает именно так. То есть пакет (дейтаграмма) собирается, проходит через iptables (а еще и через conntrac таблицу), маршрутизируется, и только на входе в интерфейс рубится снова, причем уже может на фрагменты другого размера. И дефрагментация пакета под Линуксом в большей степени необходима conntrack'у, а не iptables.

Давно хотел посмотреть что происходит в случае с BSD и маршрутизаторами Cisco, но так пока времени не нашел :(

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