Назад | Перейти на главную страницу

Маршрутизатор ADSL с радостью принимает пакеты IPv6 размером 2К

Насколько я понимаю фрагментацию IPv6, маршрутизаторы не выполняют фрагментацию, а выполняют только сквозные узлы. И когда какой-либо маршрутизатор на пути получает пакет, размер которого превышает MTU ссылки на его следующий переход, он отбрасывает его и отвечает на исходный IP-адрес с ICMPv6 «Пакет слишком велик».

В своей настройке я наблюдаю следующее:

Первоначально после того, как мой локальный канал Ethernet установлен, я посещаю страницу HTTP с запросом, который вызывает отправку большого (1965 байт) пакета. Мой маршрутизатор отвечает ICMPv6, говоря, что пакет слишком велик, а мой MTU составляет 1492 (MTU ADSL ATM). Затем моя машина разбивает TCP-пакет на два меньших (1492 и 545 байтов) и пытается снова (вместо добавления заголовков расширения в IPv6 для фрагментации, что, как я ожидал, должно произойти).

Все идет нормально. Что меня озадачивает, так это то, что с этого момента маршрутизатор больше не отправляет обратно ответы «Пакет слишком большой», несмотря на то, что некоторые исходящие пакеты имеют размер более 2 КБ (например, 2399 байт), и все, похоже, в порядке (т.е. повторная передача с использованием меньших пакетов отсутствует) .

Есть идеи, что здесь происходит?

Я использую Linux 3.14.23, а мой маршрутизатор - Tomato. На данный момент у меня нет мониторинга пакетов на моем маршрутизаторе.

Наличие уровня между IPv6 и физическим уровнем с поэтапной фрагментацией разрешено стандартом. Фактически, если MTU физического уровня меньше 1280 байт, такая поэтапная фрагментация даже обязательна. Точная работа такой фрагментации ниже уровня IPv6 выходит за рамки стандарта IPv6. Точная формулировка в RFC 2460 такова:

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

Вы имеете в виду фрагментацию сквозной фрагментации в IPv6. И такого рода фрагментация может быть выполнена только узлом, изначально создавшим пакет. Промежуточному маршрутизатору не разрешается выполнять такого рода фрагментацию пакета, который они пересылают.

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

Если бы вы изначально смогли отправить пакет размером 2 КБ от HTTP-клиента на маршрутизатор, это означало бы, что ваша локальная сеть была настроена для использования jumboframes. Другая возможность состоит в том, что HTTP-клиент работает на хосте с поддержкой разгрузки сегментации TCP. Если это было так, первый пакет может показаться размером 2 КБ при просмотре с помощью tcpdump на отправляющем узле, но на проводе это может быть один пакет с первыми 1500 байтами и другой пакет с остальными.

1500 байтов все равно будут слишком большими для MTU в канале ADSL. Каков был фактический размер пакета, запускающего слишком большое сообщение об ошибке, можно увидеть на клиентском компьютере, проверив сообщение об ошибке с помощью соответствующего инструмента, например, Wireshark.

Что происходит, когда стек TCP клиента получает слишком большую ошибку, зависит от того, какой стек TCP используется. Некоторые будут повторно передавать один и тот же сегмент TCP с использованием фрагментации IPv6, другие разделят сегмент TCP на два меньших сегмента TCP. Стандарт IPv6 гласит:

Чтобы отправить пакет, размер которого превышает MTU пути, узел может использовать заголовок IPv6 Fragment для фрагментации пакета в источнике и его повторной сборки в месте назначения (ах). Однако использование такой фрагментации не рекомендуется в любом приложении, которое может настраивать свои пакеты в соответствии с измеренным значением MTU пути (то есть до 1280 октетов).

Я прочитал это как рекомендацию повторно передавать сегмент TCP как два меньших сегмента, а не использовать фрагментацию IPv6. Существует несколько причин, по которым сегментация TCP предпочтительнее фрагментации.

Маршрутизатор может ограничить скорость слишком больших сообщений об ошибках. Поэтому, если вы отправляете несколько сегментов TCP, каждый из которых превышает 2 КБ, вы можете получить сообщение об ошибке только для первого. Стек TCP должен иметь возможность справиться с этим, используя меньший MTU, когда он повторно передает пакеты, которые превысили MTU в первый раз.

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

После определения первоначального размера фрагментации. Он должен придерживаться ссылки. Первоначальный пакет изначально не сработает. Дальнейшие пакеты перед отправкой будут фрагментированы в стеке IPv6. Сбросьте трафик на клиенте и проверьте размеры пакетов. Вы должны увидеть, как большие пакеты (ответы) перед передачей фрагментируются.

Вы указываете, что все работает после первой фрагментации. Это указывает на то, что пакеты фрагментируются соответствующим образом, поскольку в противном случае они, скорее всего, потерпят неудачу с фрагментацией дальше по маршруту.