Опубликован: 30.07.2013 | Доступ: свободный | Студентов: 1880 / 151 | Длительность: 24:05:00
Лекция 4:

Пакет IPv6

Заголовок фрагмента. Фрагментация и сборка в IPv6

Как мы помним, в IPv4 модуль фрагментации был обязательным компонентом стека и в хостах, и в маршрутизаторах, потому что фрагментировать длинный пакет должен был узел, стоящий непосредственно на входе в канал с низким MTU. Это усложняло логику маршрутизаторов IPv4: они не могли рассматривать транзитный пакет как элементарную единицу обмена данными, которую надо или целиком продвинуть дальше, или отбросить. Кроме того, нагрузить маршрутизаторы фрагментацией было не самой лучшей мыслью, потому что они обрабатывают трафик многих хостов, а сами хосты обслуживают только собственные нужды (по крайней мере, на сетевом уровне стека).

Вспоминается пословица: "На одного с сошкой семеро с ложкой".

Теперь, когда у нас есть приятная возможность перевернуть все вверх дном, мы можем "примерить" на каркас IPv6 альтернативные правила фрагментации:

  1. провести фрагментацию пакета может только его источник;
  2. транзитные узлы продвигают фрагменты, не отличая их от цельных пакетов;
  3. собирает пакет из фрагментов по-прежнему конечный адресат.

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

К сожалению, RFC 2460 нигде явно не говорит, что фрагменты собирает именно конечный адресат, хотя это косвенно следует из рекомендованного порядка заголовков расширения [§4.1 RFC 2460], который мы обсудим в §3.3.6.

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

Если длина пакета L (цельного или фрагмента) превращается в сквозную характеристику ,9 Характеристика, которая не меняется на всем пути от источника до конечного адресата. то пакет может достичь конечного адресата только при очевидном условии:

(1) L\leq  PMTU

Здесь PMTU — MTU трассы от данного источника до конечного адресата пакета:

(2)PMTU=\min_{i} MTU_i

где индекс i пробегает все выходные интерфейсы этой трассы.

В новых условиях сквозную величину L задает источник пакета, так что выполнение условия (1) становится его личной заботой, а это связано с поиском значения PMTU, или хотя бы его оценки снизу \underline{PMTU}:

(3)L\leq \underline{PMTU}\leq PMTU \Rightarrow L\leq  PMTU.

Простые арифметические соображения подсказывают нам, что есть две стратегии выполнения условия (3). Первая из них состоит в том, чтобы источник приложил усилия и нашел хорошее приближение PMTU, вплоть до точного значения. Для этого существует процедура PMTUD. Чтобы она работала, источник должен получать извещения, когда его пакеты уничтожаются из-за чрезмерной длины. В IPv4 эту роль выполняли сообщения ICMP "пакет слишком велик"; подобный механизм нам понадобится и в IPv6. Сразу же заметим, что PMTUD сходится быстрее, если каждое извещение подсказывает очередную величину )MTU_i : узел, высылающий это извещение, включает в него значение MTU того интерфейса, куда вышел бы пакет, если бы он не оказался слишком длинным. В IPv4 это было необязательным расширением [§4 RFC 1191], но теперь нам стоит ввести это в стандарт — отметим себе на будущее (§4.3). Далее, PMTUD предполагает, что протокол более высокого уровня устойчив или безразличен к потере пакетов. Это условие не ново, потому что пакеты в сетях TCP/IP теряются по самым разным причинам. Наконец, PMTUD работает надежно только при том условии, что хотя бы часть извещений доходит до источника, или же что вышестоящий протокол предполагает отклик удаленной стороны. В противном случае возникает "черная дыра PMTUD", куда бесследно, с точки зрения источника, пропадают длинные пакеты.

Для образования классической "черной дыры PMTUD" достаточно блокировать извещения ICMP, однако для двунаправленного протокола не все еще потеряно. Отклик удаленной стороны (точнее, его неожиданное отсутствие) позволяет обнаружить и обойти "черную дыру", уменьшив длину пакета. Если же вышестоящий протокол однонаправленный, такой как Syslog или Netflow, то "черная дыра" станет поглощать пакеты до тех пор, пока извещения ICMP не будут разблокированы.

Вторая стратегия значительно проще и потому подходит для источников, которые не хотят или не могут обременять себя процедурой PMTUD. Она заключается в том, чтобы использовать минимальное значение MTU, указанное протоколом IP, как "габаритные ворота" для исходящих пакетов и их фрагментов:

(4) L\leq  MTU_{min} (4)

Этот трюк работает, потому что минимальное значение MTU служит оценкой снизу для MTU любой трассы, пока не нарушен протокол:

(5)\forall i, MTU_{min}\leq MTU_i \Rightarrow MTU_{min}\leq PMTU. (5)

Чтобы при этом не страдала эффективность передачи данных, минимальное значение MTU должно быть разумно большим. Как мы помним, в IPv4 это была микроскопическая величина 68 байт. Теперь же, в IPv6, MTU канала не может опуститься ниже 1280 байт [§5 RFC 2460].

Мы точно не знаем, почему была выбрана именно величина 1280 байт. Из ее очевидных численных свойств можно заметить разве что такое: 1280=2^10+2^8. Но практически важное свойство данного выбора состоит в том, что он оставляет весьма приличный допуск на многоуровневую инкапсуляцию, например, туннели, при распространенном значении MTU физического канала 1500 байт.

А как нам быть с каналом, который по своему устройству неспособен переместить пакет длиной 1280 байт? (Например, см. [RFC 4919]. ) Пусть расширение эффективного MTU такого канала до требуемой величины, например, за счет фрагментации кадров, будет задачей нижележащего уровня. Обычно это часть протокола канальной инкапсуляции (пример см. в [RFC 4944]).

Выше, в §3.2, мы спросили себя, куда из заголовка IPv6 потерялся флаг DF. Теперь мы видим, что необходимость в нем отпала. Можно сказать, что флаг DF неявно установлен в каждом пакете IPv6, потому что транзитные узлы фрагментировать его не могут.

Остальные поля, управляющие сборкой фрагментов, мы решили переместить в отдельный заголовок расширения. Он называется заголовок фрагмента (fragment header). Его код в реестре протоколов IP — 44. Если в пакете IPv6 этот заголовок есть, то перед нами фрагмент, а если нет, то цельный пакет.

Так как собирает пакет только его конечный адресат, каждый фрагмент должны сопровождать служебные сведения, представляющие интерес для транзитных узлов. Это необходимо, потому что каждый фрагмент — это тоже пакет IPv6, путешествующий сквозь сеть независимо от других фрагментов.

Какие это будут сведения? В первую очередь, это основной заголовок IPv6, так как он содержит важнейшие сведения о пакете. Далее, пошаговые опции по самому их смыслу также интересны всем узлам на пути фрагмента. Маршрутный заголовок, если он есть, заведомо нужен промежуточным адресатам, хотя маршрутизаторы его не рассматривают. Наконец, об опциях адресата мы заранее не можем сказать, будут ли они нужны промежуточным адресатам. Возможно, появятся опции двух видов: первые будут интересны всем адресатам подряд, а вторые — только последнему из них, то есть конечному. Тогда будет достаточно снабдить каждый фрагмент опциями первого типа, заключив их в отдельный заголовок расширения "опции адресата". Остальные заголовки и полезная нагрузка нужны только конечному адресату, так что их вполне можно разбить между фрагментами.

Обратите внимание, что конечному адресату интересны все заголовки расширения. Опции для всех адресатов и опции для конечного адресата будут заключены в заголовки расширения одного и того же типа, "опции адресата" (код 60). Отличие будет только в том, как они размещены относительно других заголовков. А именно первые должны предшествовать заголовку фрагмента, а последние — идти за ним.

Мы питаем слабость к обобщениям, так что давайте сначала опишем эту картину в целом, а затем уже перейдем к ее деталям. Итак, исходный пакет IPv6 состоит из двух частей, нефрагментируемой (unfragmentable) и фрагментируемой (fragmentable), как показано на рис. 3.15. Мы уже выяснили, что нефрагментируемая часть состоит из таких заголовков:

  • основной заголовок IPv6;
  • пошаговые опции (если есть);
  • опции адресата, важные для промежуточных адресатов (если есть);
  • маршрутный заголовок (если есть).

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

Структура пакета IPv6 с точки зрения его фрагментации

Рис. 3.15. Структура пакета IPv6 с точки зрения его фрагментации

Пусть читатель подумает, где и в каком виде существует исходный пакет, если по сети передаются только его фрагменты. (Как образ в памяти источника и конечного адресата.)

Первым делом в процессе фрагментации вторую часть делят на фрагменты ненулевой длины, так чтобы окончательная длина каждого фрагмента после инкапсуляции не превысила текущей оценки PMTU, — эта операция схематически представлена на рис. 3.16. Но как связать длины фрагмента до и после инкапсуляции? Ответ на этот вопрос мы получим, рассмотрев следующий шаг процедуры фрагментации.

Деление пакета IPv6 на фрагменты (с.з. = следующий заголовок)

Рис. 3.16. Деление пакета IPv6 на фрагменты (с.з. = следующий заголовок)

Следующим шагом каждый фрагмент превращают в полноценный пакет IPv6. Для этого к нему спереди добавляют заголовок фрагмента, а перед ним — полную копию нефрагментируемой части, как изображено на рис. 3.17. Чтобы такой пакет стал годным, остается скорректировать пару полей в нем, а именно поле "длина полезной нагрузки" в заголовке IPv6 и поле "следующий заголовок" в заголовке перед заголовком фрагмента. Первая корректировка нужна, так как поле "длина полезной нагрузки" всегда относится к текущему пакету, даже если это фрагмент. Второй корректировкой мы учитываем тот факт, что цепочка заголовков изменилась и теперь после нефрагментируемой части идет заголовок фрагмента.

Фрагмент после инкапсуляции                         (с.з. = следующий заголовок)

Рис. 3.17. Фрагмент после инкапсуляции (с.з. = следующий заголовок)

В других стеках встречаются протоколы сетевого уровня, заголовки которых отдельно хранят длины данного фрагмента и исходного пакета. Пример такого протокола — ISO CLNP.

Теперь мы видим, что первоначальная длина фрагмента до инкапсуляции должна быть не больше, чем текущая оценка PMTU за вычетом длин нефрагментируемой части и заголовка фрагмента. Насколько сложно будет провести это вычисление заранее, до начала фрагментации? Длина нефрагментируемой части зависит только от структуры исходного пакета, она не изменяется от фрагмента к фрагменту. Что касается заголовка фрагмента, то в наших силах сделать его длину фиксированной и тем упростить алгоритм фрагментации.

Законопослушный узел на выходе не должен менять состав и содержание нефрагментируемой части от фрагмента к фрагменту. Ведь зачем это ему? Тем не менее, на входе может оказаться, что у разных фрагментов одного исходного пакета разные нефрагментируемые части. Как мы скажем, когда дойдем до процедуры сборки, в этом случае безусловное преимущество у фрагмента со смещением ноль.

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

  • идентификатор исходного пакета;
  • смещение;
  • флаг "еще фрагменты".

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

Сергей Субботин
Сергей Субботин

"Теоретически канал с адресацией EUI 64 может соединить порядка 2^63 "

запись вида 2^63  не понятна и отнимает время на попытку ее осмыслить.

ее можно заменить например на записи вида  264  или 1,8 * 1019

 

Павел Афиногенов
Павел Афиногенов

Курс IPv6, в тексте имеются ссылки на параграфы. Разбиения курса на параграфы нет.