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

IPv6 в стеке протоколов

< Лекция 4 || Лекция 5: 123456 || Лекция 6 >

Взаимодействие с вышестоящими протоколами

В стеке TCP/IP на уровень IP непосредственно опираются протоколы нескольких видов: управляющие, то есть ICMP; транспортные, такие как TCP, UDP и SCTP; туннельные, например, IP IP, GRE, EtherIP. О том, как нам быть с ICMP, мы поговорим в §4.3, а сейчас давайте рассмотрим вопрос инкапсуляции IPv6 в целом, сделав ударение на протоколах транспортного уровня.

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

Прежде всего, мы должны сказать, как блок данных протокола (БДП), стоящего над IP, следует инкапсулировать в пакет IPv6. На самом деле, правила этой инкапсуляции мы уже задали, когда говорили в §3.1 о структуре заголовков пакета IPv6. Тогда мы сказали, что пакет IPv6 содержит в своем начале цепочку из одного или более простых заголовков. Каждый простой заголовок содержит поле "следующий заголовок", возможные значения которого хранятся в реестре протоколов IP8 http://www.iana.org/assignments/protocol-numbers/ . Значит, последний заголовок в цепочке может ссылаться на тип полезной нагрузки пакета точно так же, как это делал заголовок IPv4. Например, если пакет IPv6 содержит в себе сегмент TCP, то последнее поле "следующий заголовок" содержит значение 6; если дейтаграмму UDP, то 17; а если пакет IPv4, то 4. Эти примеры иллюстрирует рис. 4.5

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

Рис. 4.5. Примеры инкапсуляции IPv6 (с.з. = следующий заголовок)

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

Кстати, была предпринята попытка составить полный список зависимостей от IPv4 у протоколов, описанных в RFC. Отчет занял восемь (!) документов RFC, 3789–3796.

Главная зависимость TCP и UDP от IPv4 заключается в формате псевдозаголовка, который служит для вычисления контрольной суммы. Этот псевдозаголовок включает в себя адреса IPv4 источника и назначения. Чтобы TCP и UDP смогли работать поверх IPv6, потребуется новый формат псевдозаголовка, который учтет специфику нового протокола [§8.1 RFC 2460], как это показано на рис. 4.6.

Самостоятельно изучите вопрос, нужно ли задавать новый псевдозаголовок для SCTP. (Подсказка: начните с вводной статьи9 R. Stewart, M. Tüxen, P. Lei. SCTP: What is it, and how to use it? BSDCan 2008. http://www.bsdcan.org/2008/schedule/attachments/44_bsdcan_sctp.pdf .)

Псевдозаголовок IPv6 для вычисления контрольных

Рис. 4.6. Псевдозаголовок IPv6 для вычисления контрольных

Как и раньше, поле длины в этом псевдозаголовке содержит длину дейтаграммы вышестоящего протокола, выраженную в байтах, и не учитывает заголовки IPv6. Например, UDP может взять это значение непосредственно из заголовка UDP. В то же время, TCP явным образом не хранит длину сегмента, так что ему придется вычислить искомую длину.

"В лоб" это вычисление можно провести, вычтя длины всех заголовков расширения IPv6 в данном пакете — не считая основного заголовка! — из значения поля "длина полезной нагрузки" в его основном заголовке IPv6. Альтернативный способ, близкий знатокам языка Си, — это найти разность указателей на конец пакета и заголовок TCP, приведенных к типу char *. Главное — не перепутать при этом конец пакета с последним байтом пакета, потому что их смещения отличаются на один байт.

Что касается поля "следующий заголовок", то оно теперь хранит тип вышестоящего протокола, а не просто копирует такое же поле основного заголовка IP; ведь в пакете могут быть заголовки расширения, а тогда тип вышестоящего протокола будет скрыт в самом последнем из них.

Кроме того, протокол UDP неявно полагается на контрольную сумму IPv4, когда объявляет вычисление контрольной суммы UDP необязательным: он предполагает, что заголовок IP защищает себя от повреждения. Но заголовок IPv6 сам по себе не защищен, и поэтому вычисление контрольной суммы UDP при работе поверх IPv6 становится обязательным [§8.1 RFC 2460]. Если дейтаграмма UDP с нулевым значением в поле "контрольная сумма" получена в пакете IPv6, то ее следует уничтожить.

Освежим нашу память и вспомним несколько фактов. Контрольная сумма TCP/IP вычисляется в 16 битном обратном коде, где есть два арифметически эквивалентных нулевых значения, 0x0000 и 0xFFFF. Значение поля "контрольная сумма" в TCP и UDP — это результат побитовой инверсии вычисленной суммы. (В обратном коде инверсия битов приводит к смене знака числа, так что неудивительно, что сумма всех слов сообщения, включая его контрольную сумму, должна быть нулевой.) Поэтому мы можем отличить нулевую контрольную сумму от неизвестной, задав дополнительное правило. Для этого мы предписываем хранить истинно нулевую сумму только как 0x0000, что после инверсии даст нам 0xFFFF. А значение суммы 0xFFFF, что после инверсии дает 0x0000, мы назначаем особому случаю, когда источник дейтаграммы сумму вообще не посчитал. Просто и изящно, не правда ли?

Трансляцию NAT вполне можно обобщить на обе версии IP и применить, чтобы обеспечить взаимодействие хостов IPv4 с хостами IPv6. Но как быть транслятору NAT46 или NAT64, если со стороны IPv4 он получает дейтаграмму UDP с неопределенной контрольной суммой? В этом случае при ее трансляции в IPv6 придется вычислить значение контрольной суммы и поместить в заголовок UDP. Тем самым транслятор заверит целостность дейтаграммы без достаточных на то оснований, ведь дейтаграмма могла поступить к транслятору на вход уже поврежденной! Вот нам еще один пример, как NAT нарушает сквозной принцип, лежащий в основе архитектуры Internet.

А как появление IPv6 скажется на работе туннельных протоколов? Если такой протокол сконструирован надлежащим образом, то изменений в нем не потребуется. Так, например, протоколу GRE достаточно учесть, что IPv6 получил свой собственный Ether Type 0x86DD. Еще при туннелировании IPv6 будет полезно включить вычисление контрольной суммы GRE, чтобы обеспечить дополнительную защиту пакетов от повреждения.

Туннельный протокол IP IP тоже готов к работе с IPv6 как снаружи [RFC 2473], так и внутри [§3 RFC 3056, §3.1 RFC 4213] туннеля. Достаточно учесть при инкапсуляции, что исходному пакету IPv4 отвечает номер протокола IP 4, а исходному пакету IPv6 — 4110 http://www.iana.org/assignments/protocol-numbers/ [ ]. Вполне можно строить и смешанные туннели "IPv4 внутри IPv6" и "IPv6 внутри IPv4". Сводная таблица таких способов инкапсуляции — Табл. 4.2.

Таблица 4.2. Туннельная инкапсуляция IP-IP после появления IPv6
Заголовки IPv6-в-IPv6 IPv6-в-IPv4 IPv4-в-IPv6
Внешний IPv6: "след. заголовок" = 41 IPv4: "протокол" = 41 IPv6: "след. заголовок" = 4
Внутренний IPv6 IPv6 IPv4

Наконец, у всех типов туннелей есть общая важная деталь — управление фрагментацией. Когда внешний протокол туннеля — IPv4, то узел на входе в туннель (инкапсулятор) может разрешить или запретить транзитную фрагментацию туннельных пакетов с помощью флага DF. Напротив, в среде IPv6 транзитная фрагментация всегда запрещена; это касается и туннельных пакетов, внешний протокол которых — IPv6, а поэтому их длиной обязан управлять сам инкапсулятор. Здесь его поджидает, как минимум, одна сложность: внутренний MTU туннеля обязан быть не меньше 1280 байт, тогда как и внешний MTU трассы (PMTU) туннеля может оказаться равным 1280 байт. Инкапсуляция исходного пакета длиной 1280 байт заведомо даст туннельный пакет длиной более 1280 байт, который не пройдет данную трассу без фрагментации. Это означает, что в среде IPv6 инкапсулятор обязан быть готов к фрагментации туннельных пакетов, потому что в общем случае без нее не обойтись. Самый простой, хотя и не слишком эффективный подход к выбору длины туннельного пакета — это принять нижнюю оценку PMTU туннеля равной 1280 байт и фрагментировать туннельные пакеты исходя из этого. Тогда внутренний MTU туннеля будет ограничен только диапазоном длины пакета IPv6 до фрагментации за вычетом длины туннельных заголовков: 65575 - X. Подход посложнее - это выполнение процедуры PMTUD инкапсулятором.

В RFC 4459 можно найти более обширный анализ теории и практики управления фрагментацией в туннеле.
< Лекция 4 || Лекция 5: 123456 || Лекция 6 >
Сергей Субботин
Сергей Субботин

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

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

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

 

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

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