RFC 5905 Network Time Protocol Version 4: Protocol and Algorithms Specification

Internet Engineering Task Force (IETF)                          D. Mills
Request for Comments: 5905                                   U. Delaware
Obsoletes: 1305, 4330                                     J. Martin, Ed.
Category: Standards Track                                            ISC
ISSN: 2070-1721                                               J. Burbank
                                                                W. Kasch
                                                                 JHU/APL
                                                               June 2010

Network Time Protocol Version 4: Protocol and Algorithms Specification

Протокол сетевого времени NTPv4 — спецификация и алгоритмы

PDF

Аннотация

Протокол сетевого времени (Network Time Protocol или NTP) широко применяется для синхронизации клиентских часов в Internet. Этот документ описывает протокол NTP версии 4 (NTPv4), который совместим с NTP версии 3 (NTPv3, RFC 1305), а также с предыдущими версиями протокола. NTPv4 использует изменённый заголовок для работы с адресами семейства IPv6. В NTPv4 включены фундаментальные улучшения в алгоритмах смягчения и дисциплины, повышающие потенциальную точность до десятков микросекунд для современных рабочих станций и скоростных ЛВС. Протокол включает схему динамического обнаружения серверов, что во многих случаях позволяет избежать специальной настройки. В протоколе исправлены некоторые ошибки в устройстве и реализации NTPv3, а также включён дополнительный механизм расширения.

Статус документа

Документ относится к категории Internet Standards Track.

Документ является результатом работы IETF1 и представляет согласованный взгляд сообщества IETF. Документ прошёл открытое обсуждение и был одобрен для публикации IESG2. Дополнительную информацию о стандартах Internet можно найти в разделе 2 в RFC 5741.

Информацию о текущем статусе документа, ошибках и способах обратной связи можно найти по ссылке http://www.rfc-editor.org/info/rfc5905.

Авторские права

Авторские права (Copyright (c) 2010) принадлежат IETF Trust и лицам, указанным в качестве авторов документа. Все права защищены.

К документу применимы права и ограничения, указанные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включённые в этот документ, распространяются в соответствии с упрощённой лицензией BSD, как указано в параграфе 4.e документа IETF Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

Документ может содержать материалы из IETF Document или IETF Contribution, опубликованных или публично доступных до 10 ноября 2008 года. Лица, контролирующие авторские права на некоторые из таких документов, могли не предоставить IETF Trust права разрешать внесение изменений в такие документы за рамками процессов IETF Standards. Без получения соответствующего разрешения от лиц, контролирующих авторские права этот документ не может быть изменён вне рамок процесса IETF Standards, не могут также создаваться производные документы за рамками процесса IETF Standards за исключением форматирования документа для публикации или перевода с английского языка на другие языки.

1. Введение

Этот документ определяет протокол NTP версии 4 (NTPv4), который широко применяется для синхронизации часов между множеством распределенных серверов и клиентов. Описана базовая архитектура, протокол, конечные автоматы, структуры данных и алгоритмы. NTPv4 расширяет функциональность NTPv3, описанную в [RFC1305], и Simple NTP версии 4 (SNTPv4), описанную в [RFC4330] (SNTPv4 является частью NTPv4). Этот документ отменяет [RFC1305] и [RFC4330]. Хотя в отдельные поля заголовков протокола внесены незначительные изменения, это не влияет на совместимость NTPv4 с предыдущими версиями NTP и SNTP.

Модель подсети NTP включает множество широкодоступных первичных серверов времени, синхронизируемых с национальными стандартами по проводным и радиоканалам. Назначение протокола NTP состоит в передаче сведений о точном времени от этих первичных серверов вторичным серверам и клиентам через частные сети и публичную сеть Internet. Точно настроенные алгоритмы снижают ошибки, которые могут возникать в результате сетевых нарушений, отказов серверов и возможных вредных воздействий. Серверы и клиенты настраиваются так, что значения передаются от первичных серверов в сторону клиентов через разветвлённую сеть вторичных серверов.

В NTPv4 устранены существенные недостатки NTPv3, исправлены некоторые ошибки и добавлены новые возможности. В частности, расширены определения меток времени NTP для использования типа данных с плавающей запятой (точкой) и двойной точностью. В результате разрешение (дискретность счета) времени составляет меньше 1 нсек, а частотное разрешение — меньше 1 нсек. За секунду. Дополнительные улучшения включают алгоритм дисциплины часов, который более стабилен при флуктуациях аппаратных часов системы. Типовые первичные серверы используют современные машины и обеспечивают точность в пределах нескольких десятков мксек. Типовые вторичные серверы и клиенты в быстрых ЛВС обеспечивают точность в несколько сотен микросекунд с интервалами опроса до 1024 секунд, что было максимальным для NTPv3. С помощью NTPv4 клиенты и серверы работают с точностью в несколько десятков миллисекунд, а интервалы опроса составляют до 36 часов.

Основная часть документа описывает ядро протокола и структуры данных, требуемые для взаимодействия разных реализаций. В Приложении A приведён полнофункциональный пример в форме скелета программы, включающий структуры данных и сегменты кода для алгоритмов ядра, а также алгоритмов смягчения, служащих для повышения точности и надёжности. Хотя скелет программы и другие описания в этом документе относятся к конкретной реализации, они не являются единственным способом реализации требуемых функций. Содержимое Приложения A не является нормативным и предназначено для иллюстрации работы протокола, поэтому его не обязательно использовать в реализации. Хотя описанная в документе схема аутентификации NTPv3 с симметричным ключом была скопирована из NTPv3, новая схема аутентификации с открытым ключом Autokey доступна для NTPv4 [RFC5906].

NTP включает режимы работы, описанные в разделе 2, с использованием типов (раздел 6) и структур (раздел 7) данных. Модель реализации в разделе 5 описана на основе многопоточной, многопроцессорной архитектуры, хотя возможны и другие варианты. Протокол в линии (on-wire) описанный в разделе 8, основан на схеме с возвращаемым временем (returnable-time), которая зависит лишь от измеренных сдвигов (offset) часов и не требует надёжной доставки сообщений. Гарантированная доставка, такая как TCP [RFC0793], может сделать доставленный пакет NTP менее надёжным, поскольку повторы передачи увеличивают задержку и другие ошибки. Подсеть синхронизации является самоорганизующейся иерархической сетью «ведущий-ведомый» с путями синхронизации, определяемыми связующим деревом кратчайших путей (shortest-path spanning tree) и заданной метрикой. Хотя может существовать несколько ведущих серверов (primary server), протокол выбора среди них не требуется.

Этот документ включает материалы из [ref9], где содержатся схемы и формулы, не подходящие для формата RFC. Много дополнительных сведений представлено в [ref7], включая обширный технический анализ и оценку производительности протокола и алгоритмов из этого документа. Эталонная реализация доступна на www.ntp.org.

Далее в документе представлено множество численных переменных и математических выражений. Некоторые переменные обозначаются греческими символами, которые представлены полным именем буквы с учётом регистра. Например, DELTA указывает загравную греческую букву «дельта», а delta — строчную. Кроме того, нижние индексы обозначены символом подчёркивания ‘_’, например, theta_i указывает греческую букву theta с нижним индексом i (фонетически i). Время в документе указывается в секундах, частоты указаны значениями FFO (fractional frequency offset). Зачастую FFO удобно указывать в миллионных долях (ppm).

1.1. Уровни требований

Ключевые слова должно (MUST), недопустимо (MUST NOT), требуется (REQUIRED), нужно (SHALL), не следует (SHALL NOT), следует (SHOULD), не нужно (SHOULD NOT), рекомендуется (RECOMMENDED), возможно (MAY), необязательно (OPTIONAL) в данном документе интерпретируются в соответствии с [RFC2119].

2. Режимы работы

Реализация NTP работает как первичный сервер, вторичный сервер или клиент. Первичный сервер синхронизируется с эталонными часами, отслеживаемыми напрямую до UTC (например, GPS, Galileo и т. п.). Клиент синхронизируется с одним или несколькими серверами восходящего направления, но сам не обеспечивает синхронизации зависимым клиентам. Вторичный сервер имеет один или несколько восходящих серверов и один или несколько нисходящих серверов или клиентов. Все серверы и клиенты, полностью совместимые с NTPv4, должны реализовать весь набор алгоритмов, описанных в этом документе. Для поддержки стабильности в больших подсетях NTP вторичным серверам следует быть полностью совместимыми с NTPv4. Можно применять дополнительные алгоритмы, но их вывод должен быть идентичен выводу алгоритмов, описанных в этой спецификации.

3. Режимы протокола

Имеется 3 варианта протокола NTP: симметричный, клиент-сервер и широковещательный. С каждым из них связан режим ассоциации (описание отношения между двумя узлами NTP) как показано на рисунке 1. Кроме того, постоянные ассоциации активируются (mobilize) при старте и никогда не деактивируются (demobilize), а временные (эфемерные — ephemeral) активируются приёмом пакета и деактивируются по ошибке или тайм-ауту.

Режим ассоциации

Значение режима ассоциации

Значение пакетного режима

Симметричный активный

1

1 или 2

Симметричный пассивный

2

1

Клиент

3

4

Сервер

4

3

Широковещательный сервер

5

Широковещательный клиент

6

5

Рисунок 1. Режимы протокола

В варианте клиент-сервер постоянный клиент передаёт пакет пакетного режима 3 серверу, а тот отвечает пакетами пакетного режима 43. Серверы обеспечивают синхронизацию одного или нескольких клиентов, но не принимают синхронизацию от них. Сервер может также быть драйвером эталонных часов, получая время напрямую от стандартного источника, такого как приёмник GPS или телефонная модемная служба. В этом варианте клиент вытягивает синхронизацию у серверов.

В симметричном варианте партнёры выступают сразу клиентами и серверами используя активную или пассивную симметричную ассоциацию. Постоянная активная ассоциация передаёт симметричные активные пакеты (режим 1) активной симметричной ассоциации партнёра. Временная симметричная ассоциация может быть активизирована получением симметричного активного пакета без соответствующей ассоциации. Эта ассоциация передаёт симметричные пассивные пакеты (режим 2) и сохраняется до ошибки или тайм-аута. Партнёры выталкивают и втягивают синхронизацию друг от друга. В этом документе партнёр рассматривается как клиент, поэтому упонимание клиента может относиться и к партнёру.

В широковещательном варианте ассоциация постоянного широковещательного сервера передаёт периодические пакеты широковещательного сервера (режим 5), которые может получить множество клиентов. При получении такого пакета без соответствующей ассоциации ассоциация временного широковещательного клиента (режим 6) активизируется и сохраняется до ошибки или тайм-аута. Полезно обеспечить начальный поток (volley), где клиент, работающий в клиентском режиме обменивается несколькими пакетами с сервером, чтобы откалибровать задержку распространения и запустить протокол защиты Autokey, после чего клиент возвращаетмя в режим широковещательного клиента. Широковещательный сервер выталкивает синхронизацию клиентам и другим серверам.

Следуя в общих чертах принятым в телефонной индустрии соглашениям, уровень каждого сервера в иерархии определяется номером слоя (stratum). Первичным серверам назначается слой 1, вторичным серверам на каждом уровне назначается слой на 1 больше, чем в вышележащего уровня. По мере роста номера слоя точность снижается в зависимости от конкретного сетевого пути и стабильности системных часов. Средние ошибки, измеряемые дальнстью синхронизации, растут пропорционально номеру слоя и измеренной задержке кругового обхода (round-trip delay).

В качестве стандартной практики топологию сети синхронизации следует организовывать так, чтобы не возникало петель синхронизации и минимизировались дистанции синхронизации. В NTP топология подсети определяется с использованием варианта алгоритма распределенной маршрутизации Беллмана-Форда (Bellman-Ford), который рассчитывает связующее дерево кратчайших путей с первичным сервером в качестве корня. В результате алгоритм автоматически реорганизует подсеть, чтобы обеспечить наиболее точное и надёжное время даже при сбоях в сети синхронизации.

3.1. Динамическое обнаружение серверов

Две специальные ассоциации — manycast-клиент и manycast-сервер, — которые обеспечивают функцию динамического обнаружения сервера. Имеется два типа клиентских ассоциаций manycast: постоянные и временные. Постоянный manycast-клиент передаёт клиентские пакеты (режим 3) по назначенному групповому или широковещательному адресу IPv4 или IPv6. Назначенные manycast-серверы в диапазоне срока действия пакета (time-to-live или TTL) в заголовке прослушивают пакеты по этому адресу. Если сервер подходит для синхронизации, он возвращает обычный серверный пакет (режим 4) по индивидуальному адресу клиента. При получении этого пакета клиент активирует временную клиентскую ассоциацию (режим 3), которая сохраняется до ошибки или тайм-аута.

Клиент manycast продолжает передавать пакеты поиска для создания минимального числа ассоциаций. Передача начинается с TTL=1 с увеличением значения, пока не будет создано минимальное число ассоциаций или достигнуто максимальное значение TTL. Если по достижении максимума TTL активировано ещё недостаточно ассоциаций, клиент останавливает передачу на время ожидания для очистки всех ассоциаций, затем повторяет цикл поиска. Если минимальное число ассоциаций активировано, клиент начинает передавать один пакет за время ожидания для поддержки ассоциаций. Значение поля ограничено диапазоном от 1 до 255, но приложения могут менять диапазон.

Временная ассоциации конкурируею мжду собой. При активизации новой временной ассоциации клиент запускает алгоритмы смягчения, описанные в разделе 10 и параграфе 11.2, для выбора наиболее подходящих ассоциаций из числа временных. Остальные временные ассоциации завершаются по тайм-ауту. Таким образом, популяция включает только лучших кандидатов из числа недавно ответивших пакетом NTP, для дисциплины системных часов.

4. Определения

В этом разделе определено множество технических терминов. Шкала времени (timescale) — это система отсчёта, где время выражается монотонно возрастающим двоичным счётчиком с неопределённым числом битов. Счет ведётся в секундах и долях секунды, если используется десятичная точка (запятая). Шкала универсального координированного времени (Coordinated Universal Time или UTC) определена в ITU-R TF.460 [ITU-R_TF.460]. Под эгидой метрической конвенции (Metre Convention) 1865 г. в 1975 году Генеральная конференция мер и весов (CGPM) [CGPM] настоятельно рекомендовала использовать UTC в качестве базы гражданского времени.

Шкала UTC представляет среднее солнечное время, распространяемое национальными органами стандартизации. Системное время представляется часами системы, поддерживаемыми оборудованием и операционной системой. Целью алгоритмов NTP является минимизация разности во времени и частоте (скорости хода) между UTC и системными часами. Когда эта разница ниже номинальных допусков (nominal tolerance), системные часы считаются синхронизированными с UTC.

Датой события считается время UTC, при котором событие произошло. Даты — это эфемерные значения, обозначаемые символом T. Время при работе (running time) — это шкала времени, совпадающая с функцией синхронизации программы NTP.

Метка времени T(t) представляет дату UTC или смещение от UTC в момент t (running time). Какой из двух смыслов применяется должно быть ясно из контекста. Пусть T(t) — смещение по времени (time offset), R(t) — смещение по частоте (frequency offset), D(t) — скорость старения (первая производная R(t) по t). Тогда, если T(t_0) — смещение по времени UTC, определённое в момент t = t_0, смещение по времени UTC в момент t составляет

   T(t) = T(t_0) + R(t_0)(t-t_0) + 1/2 * D(t_0)(t-t_0)^2 + e

где e — стохастическая ошибка (см. ниже). Хотя значение D(t) важно при характеризации точности задающих генераторов, этим значением обычно пренебрегают для компьютерных тактовых генераторов. В этом документе все значения времени даются в секундах, а значения допуска частоты в секундах за секунду (s/s). Иногда удобно выражать частотные сдвиги в миллионных долях 10-6.

В компьютерных хронометрических приложениях важно оценивать производительность хронометрической функции. Модель производительности NTP включает 4 статистических показателя, обновляемые при каждом измерении (корректировке) времени с сервером. Смещение (theta) представляет максимально вероятное смещение часов сервера относительно системных часов. Задержка (delta) представляет круговую (round-trip) задержку между клиентом и сервером. Дисперсия (epsilon) указывает максимальную ошибку, присущую измерению, которая растёт со скоростью, равной максимально допустимому допуску тактовой частоты в дисциплине системных часов (PHI), который обычно составляет 15 ppm. Вариации (jitter, psi) определяются как среднеквадратичное (root-mean-square или RMS) значение последних разностей смещений и указывает номинальную ошибку при оценке смещения.

Параметры theta, delta, epsilon, psi представляют измерения системных часов раздельно по отношению к каждому серверу, а протокол NTP включает механизмы объединения статистики для нескольких серверов, улучшающие дисциплину и точность калибровки системных часов. Смещение системы (THETA) представляет максимально вероятное смещение часов относительно совокупности серверов. Вариации (PSI) представляют номинальную ошибку при оценке смещения системы. Статистика delta и epsilon аккумулируется от эталонных часов для каждого слоя и дают корневую задержку (DELTA) и дисперсию (EPSILON). Дистанция синхронизации (LAMBDA), равная EPSILON + DELTA / 2, указывает максимальную ошибку для всех случаев. Подробное описание этих показателей статистики приведено в параграфе 11.2. Операции системного процесса. Параметры доступны зависимым приложениям для оценки производительности функции синхронизации.

5. Модель реализации

На рисунке 2 показана архитектура типовой многопотоковой реализации. Она включает 2 выделенных процесса на каждый сервер — партнёрский (peer) процесс для получения сообщений от сервера или эталонных часов и процесс опроса (poll) для передачи сообщений серверу или эталонным часам.

.....................................................................
. Удаленные.   Процессы   .              Системный       . Процесс  .
. серверы  .   Peer/Poll  .              процесс         .дисциплины.
.          .              .                              . часов    .
.+--------+. +-----------+. +------------+               .          .
.|        |->|           |. |            |               .          .
.|Сервер 1|  |Peer/Poll 1|->|            |               .          .
.|        |<-|           |. |            |               .          .
.+--------+. +-----------+. |            |               .          .
.          .       ^      . |            |               .          .
.          .       |      . |            |               .          .
.+--------+. +-----------+. |            |  +-----------+.          .
.|        |->|           |. | Алгоритмы  |->|           |. +------+ .
.|Сервер 2|  |Peer/Poll 2|->| выбора и   |  | Алгоритм  |->|Фильтр| .
.|        |<-|           |. | кластера   |  |комбиниров.|. | Loop | .
.+--------+. +-----------+. |            |->|           |. +------+ .
.          .       ^      . |            |  +-----------+.    |     .
.          .       |      . |            |               .    |     .
.+--------+. +-----------+. |            |               .    |     .
.|        |->|           |. |            |               .    |     .
.|Сервер 3|  |Peer/Poll 3|->|            |               .    |     .
.|        |<-|           |. |            |               .    |     .
.+--------+. +-----------+. +------------+               .    |     .
....................^.........................................|......
                    |                                    .    V     .
                    |                                    . +-----+  .
                    +--------------------------------------| VFO |  .
                                                         . +-----+  .
                                                         . Процесс  .
                                                         .корректир..
                                                         .  часов   .
                                                         ............

Рисунок 2. Модель реализации.


Эти процессы работают с общей структурой данных, называемой ассоциацией, которая содержит описанные выше показатели статистики вместе с различными структурами данных, описанными в разделе 9. Клиент передаёт пакеты одному или нескольким серверам, а затем обрабатывает возвращённые пакеты. Сервер меняет местами адреса и номера портов отправителя и получателя, переписывает некоторые поля в пакете и возвращает пакет сразу (в режиме клиент-сервер) или спустя некоторое время (в симметричном режиме). При получении каждого сообщения NTP рассчитывается смещение theta между часами системы и партнёра, а также связанная с статистика delta, epsilon, psi.

Системный процесс включает алгоритмы выбора, кластеризации и комбинирования, смягчающие различия между серверами и эталонными часами для определения наиболее точных и надёжных кандидатов для синхронизации системных часов. Алгоритм выбора использует византийские (Byzantine) принципы обнаружения отказов для отбрасывания предположительно неподходящих кандидатов, называемых «фальшивыми часами» (falsetickers), оставляя лишь хороших кандидатов, называемых «истинными часами» (truechimers). Истинными считаются часы, которые обеспечивают точность хронометража в соответствии с ранее опубликованным и доверенным стандартом, а фальшивыми — часы, которые показывают неверное или несогласованное время. Алгоритм кластеризации использует принципы статистики для выбора наиболее подходящего набора истинных часов. Алгоритм комбинирования рассчитывает итоговое смещение часов путём статистического усреднения оставшихся истинных часов.

Процесс дисциплины часов является системным процессом, контролирующим время и частоту системных часов, представленные генератором переменной частоты (variable frequency oscillator или VFO). Временные метки (тики) от VFO замыкают контур обратной связи, поддерживающей системное время. С процессом дисциплины связан процесс корректировки часов (clock-adjust), запускаемый 1 раз в секунду для внесения расчётного сдвига часов и поддержки постоянной частоты. Значение RMS разностей прошлых смещений времени представляет номинальную ошибку или вариации (jitter) системных часов. RMS разностей прошлых смещений частоты представляет стабильность тактового генератора или дрейф частоты. Точная интерпретация этих терминов представлена в параграфе 11.3.

Клиент передаёт сообщения каждому серверу с интервалом 2tau секунд, определяемому показателем опроса tau. В NTPv4 параметр tau составляет от 4 (16 секунд) до 17 (36 часов). Значение tau определяет алгоритм дисциплины часов, чтобы соответствовать постоянной цикла времени T_c = 2tau. В режиме клиент-сервер серверы отвечают незамедлительно, однако в симметричных режимах каждый из двух партнёров поддерживает tau как функцию текущего смещения и вариаций системы, поэтому партнёры могут не согласовать общее значение. Важно, чтобы динамическое поведение алгоритма дисциплины часов тщательно контролировалось для поддержки стабильности подсети NTP в целом. Это требует от партнёров согласования общего значения tau, равного меньшему из двух показателей опроса среди партнёров. Протокол NTP включает средства надлежащего согласования этого параметра.

Модель реализации включает некоторые средства установки и корректировки системных часов. Предполагается, что операционная система предоставляет две функции — одну для установки времени напрямую (например, функция Unix settimeofday()), другую для корректировки времени на небольшое значение вперёд или назад (например, функция Unix adjtime()). Здесь и далее скобки после имени отличают функцию от простой переменной. В предлагаемом решении процесс дисциплины часов использует adjtime(), если корректировка меньше заданного порога, и settimeofday() — в иных случаях. Способ корректировки и значение порога рассматриваются в разделе 10. Алгоритм фильтрации часов.

6. Типы данных

Все значения времени в NTP представляются в формате дополнение до 2 с порядком битов big-endian (см. Приложение A к [RFC0791]), нумеруемых с 0 для старшего (левого) бита. Имеется 3 формата времени NTP, 128-битовые даны, 64-битовые метки и 32-битовые короткие метки, как показано на рисунке 3. 128-битовые даты применяются в тех случаях, когда имеется достаточно места. Значение включает 64-битовое целое число со знаком для указания целых секунд, что позволяет представить 584 миллиарда лет, и 64-битовое значение дробной части с дисретностью 0,05 аттосек (0,05*10-184). Для удобства сопоставления форматов поле seconds поделено на два поля — 32-битовое значение Era Number и 32-битовое значение Era Offset. Эры не могут создаваться NTP напрямую, да это и не требуется. При необходимости это можно сделать внешними средствами, такими как файловая система или специальное оборудование.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Seconds              |           Fraction            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                        Короткий формат NTP

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Seconds                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Fraction                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     Формат временной метки NTP

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Era Number                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Era Offset                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                           Fraction                            +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                         Формат даты NTP

Рисунок 3. Форматы времени NTP.


64-битовые метки времени применяются в заголовках пакетов и других местах с ограниченным пространством. Они включают 32-битовое целое число без знака для указания секунд, что охватывает интервал в 136 лет, и 32-поле долей секунд с разрешением 232 пикосекунды. 32-битовый короткий формат применяется полях заголовков задержки и дисперсии, где полное разрешение и диапазон других форматов не оправданы. Это формат включает 16-битовое целое число без знака для учёта секунд и 16-битовое поле долей секунд. В форматах даты и временных меток первичной эпохой или базовой датой служит Era 0, начинающаяся в полночь (0 часов) 1 января 1900 г. по часовому поясу UTC, когда все биты имеют значение 0. Следует отметить, что, строго говоря, UTC не существовало до 1 января 1972 г., но удобно предполагать что UTC было всегда, даже если все исторические сведения о високосных секундах были утеряны. Даты исчисляются относительно этой первичной эпохи и отрицательные значения представляют время до начала эпохи. Отметим, что поле Era Offset в формате даты и поле Seconds в формате временных меток интерпретируются одинаково.

Временные метки являются беззнаковыми и операции над ними дают результат из той же или смежной эры. Эра 0 включает даты от начала первичной эпохи до некого момента в 2036 г., когда поле временной метки достигнет максимума и будет создана базовая дата эры 1. В любом формате метка со значением 0 указывает неизвестное или несинхронизированное время. На рисунке 4 приведены знаменательные даты NTP с соответствующими изменёнными юлианскими датами (Modified Julian Day или MJD), эрой и меткой NTP.

Дата

MJD

Эра NTP

Смещение временной метки эры NTP

Эпоха

1 января -4712 г.

-2400001

-49

1795583104

1-й день Юлианского календаря

1 января -1 г.

-679306

-14

139775744

2 BCE

1 января 0 г.

-6789415

-14

171311744

1 BCE

1 января 1 г.

-678575

-14

2029341446

1 CE

4 октября 1582 г.

-100851

-3

2873647488

Последний день Юлианского календаря

15 октября 1582 г.

-100840

-3

2874597888

Первый день Григорианского календаря

31 декабря 1899 г.

15019

-1

4294880896

Последний день NTP Era -1

1 января 1900 г.

15020

0

0

Первый день NTP Era 0

1 января 1970 г.

40587

0

2208988800

Первый день UNIX

1 января 1972 г.

41317

0

2272060800

Первый день современной UTC7

31 декабря 20008 г.

51909

0

3187209600

Последний день XX века

8 февраля 2036 г.

64731

1

63104

Первый день NTP Era 1

Рисунок 4. Интересные исторические даты NTP.

Если p — число значимых битов во второй части, тогда разрешение часов в секундах будет определяться значением 2-p. Чтобы минимизировать смещение и сделать метки времени непредсказуемыми для нарушителя, для незначащих битов следует устанавливать случайную битовую строку без смещения. Точность часов определяется как время на считывание часов. Отметим, что определённая таким образом точность может быть больше или меньше разрешения (дискретности) часов. Элемент rho, представляющий точность в этом протоколе, является большим из этих двух.

Единственной разрешённой для дат и меток времени арифметической операцией является вычитание с дополнением до 2, дающее 126- или 64-битовое значение со знаком. Крайне важно, чтобы в разности первого порядка между двумя датами сохранялось полное 128-битовое значение, а в разности меток — полное 64-битовое. Однако разность обычно мала по сравнению с интервалом секунд, поэтому её можно преобразовать в действительное число с плавающей запятой для дальнейшей обработки без потери точности. Важно отметить, что в арифметике с дополнением до 2 нет различий между значениями со знаком и без него (хотя при сравнении знак учитывается), различия проявляются только при ветвлении. Таким образом, несмотря различие дат со знаком и беззнаковых меток, они обрабатываются одинаково. Опасность при операциях с 64-битовыми метками времени, охватывающими эпоху, может возникать, например, в 2036 г., приводя к переполнению. На деле, если клиент был установлен в интервале 68 лет от сервера до запуска протокола, корректные значения будут получены даже при нахождении клиента и сервера в смежных эрах.

Некоторые значения времени, включая точность, временные константы и интервал опроса, представляются в экспоненциальном формате. Они представляются 8-битовыми целыми числами со знаком для двоичного логарифма от числа секунд. Для таких значений разрешены лишь операции инкремента и декремента. В настоящем документе для упрощения представления указание на такие переменные имени означает значение показателя, например, для интервала опроса в 1024 секунды имя и показатель будут давать фактическое значение (в данном случае показатель составляет 10).

Для преобразования системного времени в любом формате в дату или временную метку NTP требуется определить число секунд от начала первичной эпохи до системного времени. Целочисленный номер эры и метка времени определяются как,

   era = s / 2^(32) 
   timestamp = s - era * 2^(32)

Эти выражения применимы для положительных и отрицательных дат. Для получения метки времени из значений the era и timestamp служит выражение

   s = era * 2^(32) + timestamp.

Преобразование между NTP и системным временем может быть немного запутанным и выходит за рамки этого документа. Отметим, что число дней эры 0 на 1 больше числа дней во многих других эрах и это повторится уже около 2400 г. в эру 3.

В последующих описаниях переменных состояния явное указание целочисленного типа (integer) предполагает 32-битовое целое число без знака. Это урощает проверку границ, поскольку требуется задать лишь верхний предел. Без явного указания предполагается 64-битовое действительное число с плавающей запятой и двойной точностью. Исключения указываются, когда это необходимо.

7. Структуры данных

В последующих параграфах заданы конечные автоматы NTP. Переменные состояния разделены на классы по их функции в заголовках пакетов, процессах опроса и партнёрских процессах, системных процессах и процессах дисциплины часов. Переменные пакетов представляют в NTP значения заголовков в передаваемых и принимаемых пакетах. Переменные партнёра и опросов представляют содержимое ассоциации отдельно для каждого сервера. Системные переменные указывают состояние сервера с точки зрения зависимых от него клиентов. Переменные дисциплины часов показывают внутреннюю работу алгоритма дициплины. Примеры приведены в Приложении A.

7.1. Соглашения о структурах

Чтобы различать одноименные переменные из разных процессов применяются префиксы, показанные на рисунке 5. Переменная принимаемого пакета v, являющаяся членом структуры пакета r, имеет полное обозначение r.v. Аналогично, x.v будет переменной передаваемого пакета, p.v — переменной партнёра, s.v — системной переменной, c.v — переменной дисциплины часов. Имеется набор партнёрских переменных для каждой ассоциации и лишь по одному набору системных переменных и переменных часов.

 

Имя

Описание

r.

Переменная заголовка принимаемого пакета

x.

Переменная заголовка передаваемого пакета

p.

Переменная партнёра/опроса

s.

Системная переменная

c.

Переменная дисциплины часов

 

Рисунок 5. Соглашения о префиксах.

7.2. Глобальные параметры

В дополнение к классам переменных документ определяет глобальные переменные, включая показанные на рисунке 6.

Указаны лишь глобальные переменные требуемые для совместимости и любой реализации потребуется больший набор. В Приложении A.1.1 показаны глобальные переменные используемые в скелете кода для алгоритмов смягчения, дисциплины часов и связанных с ними функций, зависящих от реализации. Некоторые из значений параметров неизменны (например, номер порта NTP, выделенный IANA, и номер версии протокола NTPv4). Другие, например допуск по частоте (PHI), включают допущение о наихудшем поведении системных часов, синхронизированных однократно с последующим дрейфом, когда источник синхронизации становится недоступным. Минимальные и мксимальны значения параметров задают пределы переменных состояния в последующих параграфах документа.

Имя

Значение

Описание

PORT

123

NTP port number

VERSION

4

NTP version number

TOLERANCE

15*10-6

frequency tolerance PHI (s/s)

MINPOLL

4

minimum poll exponent (16 s)

MAXPOLL

17

maximum poll exponent (36 h)

MAXDISP

16

maximum dispersion (16 s)

MINDISP

0,005

minimum dispersion increment (s)

MAXDIST

1

distance threshold (1 s)

MAXSTRAT

16

maximum stratum number

Рисунок 6. Глобальные параметры.

Хотя переменные в этом документе показаны с фиксированными значениями, некоторые реализации могут делать их настраиваемыми в конфигурации. Например, эталонная вычисляет значение PRECISION как двоичный логарифм (log2) минимального времени среди нескольких итераций считывания системных часов.

7.3. Переменные заголовков пакетов

Наиболее важны с внешней точки зрения переменные состояния представлены на рисунке 7 и далее. Заголовок пакета NTP из целого числа 32-битовых (4 октета) слов с сетевым порядком байтов. Пакет включает заголовок, а также может включать одно или несколько полей расширения и код проверки подлинности (message authentication code или MAC). Компоненты заголовка идентичны применяемым в NTPv3 и предыдущих версиях. Необязательные поля расширения применяются криптографическими алгоритмами открытых ключей Autokey, как описано в [RFC5906]. Необязательное поле MAC используется Autokey и криптографическими алгоритмами, описанными в этом RFC.

 

Имя

Формула

Описание

leap

leap

Индикатор високосных секунд (LI)

version

version

Номер версии (VN)

mode

mode

Режим

stratum

stratum

Слой (stratum )

poll

poll

Показатель опроса (poll exponent)

precision

rho

Показатель точности)

rootdelay

delta_r

Корневая задержка (root delay)

rootdisp

epsilon_r

Корневая дисперсия (root dispersion)

refid

refid

Идентификатор эталона (reference ID)

reftime

reftime

Временная метка эталона

org

T1

Временная метка источника (origin)

rec

T2

Временная метка приёма

xmt

T3

Временная метка передачи

dst

T4

Временная метка получателя

keyid

keyid

Идентификатор ключа

dgst

dgst

Дайджест (подпись) сообщения

 

Рисунок 7. Переменные заголовков пакетов.

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |LI | VN  |Mode |    Stratum     |     Poll     |   Precision   |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                         Root Delay                            |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                         Root Dispersion                       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                          Reference ID                         |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 |                     Reference Timestamp (64)                  |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 |                      Origin Timestamp (64)                    |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 |                      Receive Timestamp (64)                   |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 |                      Transmit Timestamp (64)                  |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 .                                                               .
 .                    Extension Field 1 (переменный)             .
 .                                                               .
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 .                                                               .
 .                    Extension Field 2 (переменный)             .
 .                                                               .
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                          Key Identifier                       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 |                      Message Digest (128)                     |
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 8. Формат заголовка пакета.


Пакет NTP передаётся в дейтаграмме UDP [RFC0768]. Некоторые поля используют несколько слов, а иные размещаются в меньших полях внутри слова. Заголовок пакета NTP, показанный на рисунке 8, имеет 12 слов, за которыми могут следовать поля расширения и код аутентификации (MAC), состоящий из полей идентификатора ключа и дайджеста сообщения.

Поля расширения служат для добавления необязательных возможностей, например, протокола безопасности Autokey [RFC5906]. Формат поля расширения предназначен для обеспечения возможности его разбора без знания функций поля. Код MAC применяется в Autokey и схеме симметричного шифрования.

Переменные заголовков пакетов представлены на рисунке 7 и подробно описаны ниже. За исключением небольших изменений, связанных с использованием адресов семейства IPv6, эти поля совместимы с NTPv3. Поля заголовков пакетов применяются для передаваемых (префикс x) и примаемых (префикс r) пакетов. На рисунке 8 размер нескольких многословных полей указан в битах, если он отличается от принятых по умолчанию 32 битов. Базовый заголовок простирается от начала пакета до конца поля Transmit Timestamp. Поля и связанные с ними переменные (в скобках) описаны ниже.

LI Leap Indicator (leap)

2-битовое целочисленное предупреждение о приближающейся високосной секунде, добавляемой или удаляемой в последнюю минуту суток9, как указано на рисунке 9.

 

Значение

Смысл

0

Нет предупреждений

1

Последняя минута суток содержит 61 секунду

2

Последняя минута суток содержит 59 секунд

3

Неизвестно (часы не синхронизированы)

 

Рисунок 9. Индикатор високосной секунды.

VN Version Number (version)

3-битовое целое число, представляющее номер версии NTP. Текущее значение — 4.

Mode (mode)

3-битовое целое число, представляющее режим. Значения режима приведены на рисунке 10.

 

Значение

Смысл

0

Резерв

1

Симмеричная активная

2

Симмеричная пассивная

3

Клиент

4

Сервер

5

Широковещательная

6

Управляющее сообщение NTP

7

Резерв для приватного использования

 

Рисунок 10. Режимы ассоциаций.

Stratum (stratum)

8-битовое целое число, представляющее слой (Рисунок 11).

 

Значение

Смысл

0

Не задан или недействителен

1

Первичный сервер (например, оборудованный приемником GPS)

2-15

Вторичный сервер (через NTP)

16

Не синхронизирован

17-255

Резерв

 

Рисунок 11. Слой пакета.

Обычно значение 0 в полученных пакетах сопоставляется со значением MAXSTRAT (16) в переменной партнёра p.stratum, а значения p.stratum = MAXSTRAT и выше сопоставляются с 0 в передаваемых пакетах. Это позволяет удобно умещать эталонные часы, которые обычно относятся к слою 0, с использованием того же лагоритма выбора чассов, который применяется для внешних источников (см. для примера Приложение A.5.5.1).

Poll

8-битовое целое число, представляющее максимальный интервал между последовательными сообщениями двоисным логарифмом числа секунд. По умолчанию для минимального и максимального интервалов опроса предложены значения 6 и 10, соответственно.

Precision

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

Root Delay (rootdelay)

Суммарная круговая задержка для эталонных часов в коротком формате NTP.

Root Dispersion (rootdisp)

Суммарная дисперсия для эталонных часов в коротком формате NTP.

Reference ID (refid)

32-битовый код, указывающий конкретный сервер или эталонные часы. Интерпретация значения зависит от поля stratum. При stratum=0 (не задано или недействительно) это 4-символьная строка ASCII [RFC1345], называемая kiss-кодом и служащая для отладки и мониторинга. При stratum=1 (эталонные часы) это 4-октетная, выровненная слева и дополненная справа нулями строка ASCII, назначенная эталонным часам. Полномочный список идентификаторов эталонных часов поддерживается IANA (Рисунок 12), а строки, начинающиеся символом ASCII X зарезервированы для нерегистрируемых значений, применяемых в экспериментах и разработке.

 

ID

Источник времени

GOES

Geosynchronous Orbit Environment Satellite

GPS

Global Position System

GAL

Galileo Positioning System

PPS

Generic pulse-per-second

IRIG

Inter-Range Instrumentation Group

WWVB

LF Radio WWVB Ft. Collins, CO 60 кГц

DCF

LF Radio DCF77 Mainflingen, DE 77.5 кГц

HBG

LF Radio HBG Prangins, HB 75 кГц

MSF

LF Radio MSF Anthorn, UK 60 кГц

JJY

LF Radio JJY Fukushima, JP 40 кГц, Saga, JP 60 кГц

LORC

MF Radio LORAN C station, 100 кГц

TDF

MF Radio Allouis, FR 162 кГц

CHU

HF Radio CHU Ottawa, Ontario

WWV

HF Radio WWV Ft. Collins, CO

WWVH

HF Radio WWVH Kauai, HI

NIST

Телефонный модем NIST

ACTS

Телефонный модем NIST

USNO

Телефонный модем USNO

PTB

Европейский телефонный модем

 

Рисунок 12. Идентификаторы источников точного времени.

Для stratum > 1 (вторичные серверы и клиенты) указывает сервер и может служить для обнаружения петель синхронизации. При использовании адресов семейства IPv4 идентификатором служит 4-октетный адрес IPv4, при использовании IPv6 — первые 4 октета хэш-значения MD5 для адреса IPv6. Отметим, что при использовании семейства IPv6 на сервере NTPv4 с клиентом NTPv3 поле Reference Identifier будет случайным значением и не сможет применяться для обнаружения петель синхронизации.

Reference Timestamp

Время, когда системные часы последний раз устанавливались или корректировались (метка NTP).

Origin Timestamp (org)

Время клиента в момент отправки запроса серверу (метка NTP).

Receive Timestamp (rec)

Время сервера в момент прибытия запроса от клиента (метка NTP).

Transmit Timestamp (xmt)

Время сервера в момент отправки отклика клиенту (метка NTP).

Destination Timestamp (dst)

Время клиента в момент прибытия отклика от сервера (метка NTP).

Примечание. Поле Destination Timestamp не включается как поле заголовка, оно определяется по прибытии пакета и становится доступным в структуре данных буфера пакетов.

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

Поле MAC состоит из идентификатора ключа (Key Identifier), за которым следует дайджест сообщения. Дайджест или криптографическая сумма вычисляется в соответствии с [RFC1321] для заголовка NTP и полей расширения без MAC.

Extension Field n

Формат поля описан в параграфе 7.5. Формат поля расширения NTP.

Key Identifier (keyid)

32-битовое целое число без знака, используемое клиентом и сервером для обозначения секретного 128-битового ключа MD5.

Message Digest (digest)

128-битовое хэш-значение MD5, вычисляемое для ключа, за которым следует заголовок пакета NTP и поля расширения (без учёта Key Identifier и Message Digest).

Следует отметить, что описанный здесь расчёт MAC отличается от заданного в [RFC1305] и [RFC4330], но совместим с генерацией MAC в имеющихся реализациях.

7.4. Пакет Kiss-o’-Death

Если Stratum = 0 (незаданный или недействительный слой), поле Reference Identifier может служить для передачи сообщений, полезных для отчётов о состоянии и контроля доступа. Такие пакеты называются «поцелуем смерти» Kiss-o’-Death или KoD), а сообщения ASCII в них — кодами kiss. Пакеты KoD получили своё имя потому, что сначала их применяли для указания клиенту прекратить передачу пакетов, нарушающих правила доступа к серверу. Коды kiss могут предоставить полезные сведения клиентам NTPv4 и SNTPv4. Kiss-коды представляются 4-символьными строками ASCII (Рисунок 13) с выравниванием по левому краю и дополнением нулями справа. Строки предназначены для символьных дисплеев и log-файлов. Получатель kiss-кода должен проверить его и в указанных ниже случаях выполнить действия.

  1. Для DENY и RSTR клиент должен деактивировать все ассоциации с этим сервером и прекратить отправку пакетов ему.

  2. Для kiss-кода RATE клиент должен незамедлительно увеличить свой интервал опроса для этого сервера и продолжать увеличение при каждом получении кода RATE11.

  3. Коды, начинающиеся с символа ASCII X, предназначены для экспериментов и разработки и неизвестные значения должны игнорироваться.

  4. В остальных случаях пакеты KoD не имеют значения для протокола и отбрасываются после проверки.

Код

Значение

ACST

Ассоциация относится к unicast-серверу.

AUTH

Отказ при аутентификации сервера.

AUTO

Отказ последовательности Autokey.

BCST

Ассоциация относится к broadcast-серверу.

CRYP

Отказ при криптографической идентификации или аутентификации.

DENY

Отклонение доступа удаленным сервером.

DROP

Потеря партнёра в симметричном режиме.

RSTR

Отклонение доступа в соответствии с локальными правилами.

INIT

Ассоциация ещё не синхронизирована (в первый раз).

MCST

Ассоциация относится к динамически обнаруженному серверу.

NKEY

Ключ не найден (не был установлен или не является доверенным).

RATE

Превышение скорости. Сервер временно отклонил доступ по причине превышения клиентом порога скорости.

RMOT

Изменение ассоциации с удалённого хоста, где работает ntpdc.

STEP

Выполнен шаг изменения системного времени, но ассоциация ещё не ресинхронизирована.

Рисунок 13. Kiss-коды.

Receive Timestamp и Transmit Timestamp (задаёт сервер) не определены для пакетов KoD, на из значения недопустимо полагаться и они должны отбрасываться.

7.5. Формат поля расширения NTP12

В NTPv4 могут включаться поля расширения после заголовка и перед кодом MAC (если MAC присутствует).

Этот документ определяет лишь формат поля, не задавая его использования. Поле расширения содержит сообщение запроса или отклика в формате, показанном на рисунке 14.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Field Type           |            Length             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                                                               .
.                            Value                              .
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                   Padding (при необходимости)                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 14. Формат поля расширения.


Все поля расширения дополняются нулями до границы слова (4 октета).

Поля Field Type, Value, Padding зависят от заданной функции и не рассматриваются здесь. Значения Field Type заданы в ррестре IANA, а значения Length, Value, Padding определяются указанным в этом реестре документом. Если хост получает поле расширения с неизвестным Field Type, ему следует игнорировать это поле расширения и можно отбросить пакет совсем, если правила требуют этого.

Хотя минимальный размер поля, содержащего обязательные компоненты, составляет 4 слова (16 октетов), максимальный размер не может превышать 65532 октетов по причине ограниченного размера поля Length.

Length содержит 16-битовое целое число без знака, задающее размер поля расширения в октетах, включая Padding.

7.5.1. Поля расширения и коды MAC

7.5.1.1. Поля расширения при наличии MAC

Поле расширения может использоваться в пакете NTP с кодом MAC, например, как задано в [Autokey]. Спецификация, определяющая новое поле расширения, должна указывать, требует ли это поле наличия MAC. Если поле расширения требует MAC, спецификация поля должна указывать алгоритм создания и размер MAC. Поле расширения может разрешать применение нескольких алгоритмов и в этом случае сведения об использованном алгоритме должны включаться в само поле расширения.

7.5.1.2. Несколько полей расширения с MAC

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

Недопустимо передавать пакет NTP с несколькими полями расширения, требующими различные алгоритмы MAC. Если пакет NTP принят с несколькими полями расширения, распознанными получателем и требующими MAC с разными алгоритмами, пакет должен отбрасываться.

7.5.1.3. MAC без полей расширения

Размер MAC более 24 октетов недопустим без поля расширения, если длинный код MAC не согласован клиентом и сервером. Согласование может быть выполнено в предыдущем обмене пакетами с полем расширения, задающим размер и алгоритм кодов MAC передаваемых в пакетах NTP.

7.5.1.4. Поля расширения без MAC

При отсутствии MAC одно или несколько полей расширения могут вставляться после заголовка, как указано ниже.

  • При одном поле расширения размер этого поля должен быть не менее 7 слов (28 октетов).

  • При наличии нескольких полей расширения размер последнего поля должен быть не менее 28 октетов, размер других полей расширения должен быть не менее 16 октетов для каждого.

8. Протокол в линии

Основой NTP является протокол on-wire, обеспечивающий ядро механизма обмена значениями времени между серверами, партнёрами и клиентами. Протокол по своей природе устойчив к потере и дублированию пакетов. Целостность данных обеспечивается контрольными суммами IP и UDP. Механизмы управления потоком данных и повторной передачи не требуются и не применяются. Протокол использует метки времени, извлекаемые из заголовков пакетов или системных часов в момент прибытия или отправки пакета. Метки являются прецизионными данными и их следует получать заново в случае повтора передачи на канальном уровне с поправкой на время расчёта MAC.

Сообщения NTP могут использовать два режима связи — «один с одним» или «один со многими», обычно называемые одноадресными (unicast) или широковещательными (broadcast). В этом документе широковещательным считается любой механизм, обеспечивающий передачу от одного ко многим. Для IPv4 это соответствует широковещательной или групповой передаче IPv4, для IPv6 — групповой передаче IPv6. Для этого агентство IANA выделило групповой адрес IPv4 224.0.1.1 и групповой адрес IPv6 с суффиксом :101 и префиксом, определяемым локальными правилами для области действия. Могут применяться также иные групповые адреса в дополнение к указанным.

Протокол в линии (on-wire) использует 4 метки времени с номерами от t1 до t4 и 3 переменных состояния org, rec и xmt, как показано на рисунке 15. Рисунок представляет общий случай, где каждый из двух партнёров (A и B) независимо измеряет смещение и задержку относительно другого. На рисунке метки указаны строчными буквами, а переменные состояния — прописными. Переменные состояния копируются из меток в пакетах при отправке и получении.

          t2            t3           t6            t7
     +---------+   +---------+   +---------+   +---------+
     |    0    |   |    t1   |   |   t3    |   |    t5   |
     +---------+   +---------+   +---------+   +---------+
     |    0    |   |    t2   |   |   t4    |   |    t6   | Метки
     +---------+   +---------+   +---------+   +---------+ пакета
     |   t1    |   |t3=clock |   |   t5    |   |t7=clock |
     +---------+   +---------+   +---------+   +---------+
     |t2=clock |                 |t6=clock |
     +---------+                 +---------+
                                                          Партнёр B
     +---------+   +---------+   +---------+   +---------+
org  |   T1    |   |    T1   |   | t5<>T1? |   |    T5   |
     +---------+   +---------+   +---------+   +---------+ Переменные  
rec  |   T2    |   |    T2   |   |   T6    |   |    T6   | состояния
     +---------+   +---------+   +---------+   +---------+
xmt  |    0    |   |    T3   |   |  t3=T3? |   |    T7   |
     +---------+   +---------+   +---------+   +---------+

               t2      t3                 t6          t7
     ---------------------------------------------------------
              /\         \                 /\            \
              /           \                /              \
             /             \              /                \
            /               \/           /                 \/
     ---------------------------------------------------------
          t1                t4         t5                  t8

         t1            t4            t5             t8
     +---------+   +---------+   +---------+   +---------+
     |    0    |   |    t1   |   |   t3    |   |    t5   |
     +---------+   +---------+   +---------+   +---------+
     |    0    |   |    t2   |   |   t4    |   |    t6   | Метки
     +---------+   +---------+   +---------+   +---------+ пакета
     |t1=clock |   |    t3   |   |t5=clock |   |    t7   |
     +---------+   +---------+   +---------+   +---------+
                   |t4=clock |                 |t8=clock |
                   +---------+                 +---------+
                                                          Партнёр A
     +---------+   +---------+   +---------+   +---------+
org  |    0    |   |  t3<>0? |   |   T3    |   | t7<>T3? |
     +---------+   +---------+   +---------+   +---------+ Переменные
rec  |    0    |   |    T4   |   |   T4    |   |    T8   | состояния
     +---------+   +---------+   +---------+   +---------+
xmt  |   T1    |   |  t1=T1? |   |   T5    |   |  t5=T5? |
     +---------+   +---------+   +---------+   +---------+

Рисунок 15. Протокол в линии.


На рисунке первый пакет, переданный A, содержит лишь метку источника t1, которая копируется в T1. Партнёр B принимает пакет в момент t2 и копирует t1 в T1 а метку приёма t2 — в T2. В этот момент или несколько позже в t3 партнёр B передаёт A пакет, содержащий t1, t2 и метку отправки t3. Все три метки копируются в соответствующие переменные состояния. A получает в момент t4 пакет с метками t1, t2, t3 и меткой получателя t4. Эти четыре метки служат для расчёта смещения и задержки B относительно A, как описано ниже.

До обновления значений xmt и org выполняются две проверки пригодности для защиты от дубликатов, подделок и повторов. В приведённом выше обмене пакет является дубликатом или повтором, если t3 в нем совпадает с переменной состояния org T3. Пакет является фиктивным, если метка источника t1 в нем не совпадает с переменной состояния xmt T1. В обоих случаях переменные состояния обновляются, а пакет отбрасывается. Для защиты от повторного использования (replay) переданного последним пакета в переменной состояния xmt устанавливает 0 сразу же после обнаружения подделки.

Для 4 наиболее свежих меток времени переменные T1 — T4 служат для расчёта смещения B относительно A

   theta = T(B) - T(A) = 1/2 * [(T2-T1) + (T4-T3)]13

и круговой задержки

   delta = T(ABA) = (T4-T1) - (T3-T2).

Отметим, что выражения в круглых скобках рассчитываются по 64-битовым меткам без знака и будут давать 63 бита значения и бит знака. Это позволяет представлять даты от 68 лет в прошлом до 68 в будущем, но смещение и задержка считаются как сумма и разность величин и дают 62 бита значения и 2 бита знаков, поэтому могут однозначно представлять время от 34 дет в прошлом до 34 в будущем. Иными словами, клиент должен быть установлен в интервале 34 до запуска сервера. Это фундаментальное ограничение 64-битовой арифметики целых чисел.

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

В некоторых случаях, где начальный сдвиг частоты клиента сравнительно велик, а реальное время распространения мало, результат расчёта задержки может быть отрицательным. Например, если разница частот составляет 100 ppm а интервал T4-T1 — 64 секунды, задержка будет равна -6,4 мсек. Поскольку отрицательные значения в последующих расчётах вводят в заблуждение, значение delta следует фиксировать не меньше s.rho, где s.rho — точность системы в секундах, как описано в параграфе 11.1.

Приведённое выше обсуждение предполагает наиболее общий случай, где два симметричных партнёра независимо измеряют смещения и задержки между собой. В случае сервера, не хранящего состояний протокол можно упростить. Такой сервер копирует T3 и T4 из клиентского пакета в T1 и T2 серверного пакета и присоединяет метку отправки T3 до передачи пакета клиенту. Сведения о заполнении других полей протокола приведены в разделе 9 и Приложении.

Отметим, что описанный протокол on-wire устойчив к повторному использованию пакетов отклика от сервера. Однако он не стоек к повторному использованию клиентских запросов, которые будут вынуждать сервер повторить пакет с новыми значениями T2 и T3, дающими некорректные результаты для смещения и задержки. Этой уязвимости можно избежать, установив значение 0 для переменной состояния xmt после расчёта смещения и задержки.

9. Партнёрский процесс

Последующие описания процессов включают важные переменные состояния и обзор операций, реализованных в подпрограммах. В тексте часто указываются ссылки на скелет программы в приложении, включающий фрагменты кода C, более подробно описывающие функции. Код включает параметры, переменные и объявления, требуемые для соответствующей спецификации реализации NTPv4. Однако в работающей реализации может потребоваться ещё много переменных.

Партнерский процесс вызывается прибытием пакета от сервера или партнёра. Процесс запускает протокол on-wire для определения смещения часов и круговой задержки, а также рассчитывает статистику, применяемую системным процессом и процессом опроса. Переменные партнёра создаются в структуре данных ассоциации, когда та инициализируется, и обновляются при получении пакетов. Для каждого сервера имеется партнёрский процесс, процесс опроса и процесс ассоциации.

9.1. Переменные партнёрского процесса

На рисунках 16 — 19 приведены базовые имена, имена формул и краткие описания переменных партнёра. Базовые имена и имена формул взаимозаменяемы, имена формул предназначены для удобочитаемости уравнений в спецификации. Если явно не указано иное, для партнёрских переменных применяется префикс p.

Имя

Формула

Описание

srcaddr

srcaddr

Адрес источника

srcport

srcport

Порт источника

dstaddr

dstaddr

Адрес получателя

dstport

destport

Порт получателя

keyid

keyid

Идентификатор ключа

Рисунок 16. Переменные конфигурации партнёрского процесса.

Имя

Формула

Описание

leap

leap

Индикатор високосных секунд

version

version

Номер версии

mode

mode

Режим

stratum

stratum

Слой

ppoll

ppoll

Показатель опроса

rootdelay

delta_r

Корневая задержка

rootdisp

epsilon_r

Корневая дисперсия

refid

refid

Идентификатор источника (эталона)

reftime

reftime

Аременная метка эталона

Рисунок 17. Переменные партнёрского процесса.

Имя

Формула

Описание

org

T1

Временная метка источника

rec

T2

Временная метка приёма

xmt

T3

Временная метка передачи

t

t

Время пакета

Рисунок 18. Переменные метки времени партнёрского процесса.

Имя

Формула

Описание

offset

theta

Смещение часов

delay

delta

Круговая задержка

disp

epsilon

Дисперсия

jitter

psi

Вариации (jitter)

filter

filter

Фильтр часов

tp

t_p

Время фильтра

Рисунок 19. Статистические переменные партнёрского процесса.

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

srcaddr

IP-адрес удалённого сервера или эталонных часов. Он будет адресом получателя для пакетов из ассоциации.

srcport

Номер порта UDP на сервере или эталонных часах. Он будет портом получателя для пакетов из ассоциации. При работе в симметричных режимах (1 и 2), это поле должно содержать номер порт NTP PORT (123), выделенный IANA. В иных режимах номер порта определяется локальными правилами.

dstaddr

IP-адрес клиента. Он будет адресом отправителя для пакетов из ассоциации.

dstport

Номер порта UDP на клиенте, исходно порт NTP PORT (123), выделенный IANA. Он будет портом отправителя для пакетов из ассоциации.

keyid

Идентификатор симметричного ключа для 128-битового ключа MD5, служащий для генерации и проверки MAC. Клиент и сервер или партнёр могут использовать разные значения, но они должны указывать один ключ.

Переменные с рисунка 17 обновляются из заголовка каждого прибывающего пакета и интерпретируются так же, как одноименные переменные пакета. Для последующей обработки удобно преобразовать короткий формат NTP для r.rootdelay и r.rootdisp в переменные партнёра с форматом floating double.

Переменные с рисунка 18 включают временные метки, передаваемые протоколом (раздел 8). Переменная t указывает счётчик секунд c.t, связанный с этими значениями. Переменная c.t поддерживается процессом корректировки часов, описанным в разделе 12. Она учитывает секунды с момента запуска службы. Переменные с рисунка 19 включают статистику, рассчитываемую подпрограммой clock_filter(), описанной в разделе 10. Переменная tp содержит число секунд, связанное с этими значениями.

9.2. Операции партнёрского процесса

Процедура приёма определяет поток процессов по прибытию пакета, как показано функцией receive() в Приложении A.5.1. Для управления доступом не нужен специальный метода, хотя реализациям рекомендуется включать схему, аналогичныю многим широко применяемым. Функция access() в Приложении A.5.4 описывает метод реализации ограничений на основе списка контроля доступа (access control list или ACL). Проверка формата требует корректного размера и выравнивания полей, приемлемого номера версии (1-4) и корректного синтаксиса полей расширения при их наличии.

Конкретные требования по проверке подлинности не задаются, однако при поддержке аутентификации требуется реализация алгоритма хэширования MD5, описанного в [RFC1321].

Затем выполняется поиск в таблице ассоциаций по адреса и порту источника, например, с помощью функции find_assoc() из Приложения A.5.1. На рисунке 20 приведена таблица диспетчеризации, где столбцы соответствуют режиму пакетов, а строки — режиму ассоциации. Ячейка на пересечении указывает один из описанных ниже шагов.

 

Пакетный режим

Режим ассоциации

1

2

3

4

5

Нет ассоциации

0

NEWPS

DSCRD

FXMIT

MANY

NEWBC

Симметричная активная

1

PROC

PROC

DSCRD

DSCRD

DSCRD

Симметричная пассивная

2

PROC

ERR

DSCRD

DSCRD

DSCRD

Клиент

3

DSCRD

DSCRD

DSCRD

PROC

DSCRD

Сервер

4

DSCRD

DSCRD

DSCRD

DSCRD

DSCRD

Широковещательная

5

DSCRD

DSCRD

DSCRD

DSCRD

DSCRD

Широковещательный клиент

6

DSCRD

DSCRD

DSCRD

DSCRD

PROC

 

Рисунок 20. Таблица диспетчеризации партнёров.

DSCRD

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

ERR

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

FXMIT

Клиентский пакет (режим 3) не соответствует ассоциации (режим 0). Если адрес получателя не является широковещательным, сервер создаёт серверный пакет (режим 4) и возвращает его клиенту без сохранения состояния. Создаётся заголовок серверного пакета, пример описан в функции fast_xmit() Приложения A.5.3. Заголовок собирается из полученного пакета и системных переменных, как показано на рисунке 21. Если системные переменные хранятся в форме floating double, они должны преобразовываться в короткие метки NTP.

Переменная пакета -->     Переменная
r.leap            -->     p.leap
r.mode            -->     p.mode
r.stratum         -->     p.stratum
r.poll            -->     p.ppoll
r.rootdelay       -->     p.rootdelay
r.rootdisp        -->     p.rootdisp
r.refid           -->     p.refid
r.reftime         -->     p.reftime
r.keyid           -->     p.keyid

Рисунок 21. Приём заголовка пакета.

Отметим, что при отказе аутентификации сервер возвращает специальное сообщение crypto-NAK, включающее обычные данные заголовка NTP (Рисунок 8), но с кодом MAC, содержащим 4 октета нулей. Клиент может принять или отвергнуть данные сообщения. После этого партнёрский процесс завершается.

Если адрес получателя является групповым, отправитель работает в клиентском режиме manycast. Если пакет действителен и слой сервера меньше слоя клиента, сервер передаёт обычный среверный пакет (режим 4), но с одним из индивидуальных (unicast) адресов получателя. При отказе аутентификации crypto-NAK не передаётся. После этого партнёрский процесс завершается.

MANY

Серверный пакет (режим 4) не соответствует ассоциации. Обычно это происходит при отклике manycast-сервера на переданный ранее групповой пакет клиента. Если пакет действителен, активируется обычная ассоциация клиента (режим 3) и работа продолжается как при активации ассоциации по конфигурационному файлу.

NEWBC

Широковещательный пакет (режим 5) не соответствует ассоциации. Клиент активирует обычную (режим 3) или широковещательную (режим 6) ассоциацию. Примеры показаны в функциях mobilize() и clear() Приложения A.2. Затем пакет проверяется и инициализируются переменные партнёра, как показано в функции packet() Приложения A.5.1.1.

Если реализация не поддерживает дополнительных функций защиты или калибровки, ассоциация устанавливается в режим широковещательного клиента (режим 6) и процесс партнёра завершается. Реализации с аутентификацией на основе открытых ключей может применять Autokey или эквивалентный протокол защиты. Реализациям следует устанавливать режим ассоциации 3 и запускать короткий обмен клиент-сервер для определения задержки расппространения. После обмена устанавливается режим ассоциации 6 и процесс партнёра продолжается в режиме «только прослушивание». Отметим, различие между пакетом режима 6, зарезервированным для функций мониторинга и управления NTP, и режимом 6 в ассоциации.

NEWPS

Пакет симметричного активного режима (режим 1) не соответствует ассоциации. Клиент активирует симметричныую пассивную ассоциацию (режим 2). Пример приведён в функциях mobilize() и clear() Приложения A.2. Обработка продолжается, как описано ниже для PROC.

PROC

Пакет соответствует имеющейся ассоциации. Метки времени в пакете аккупатно проверяются для обнаружения недействительных, дублированных и фиктивных пакетов. Дополнительные проверки показаны на рисунке 22. Отметим, что все пакеты, включая crypto-NAK, считаются действительными лишь после прохождения этих тестов.

Тип пакета

Описание

1

Дубликат пакета

В лучшем случае пакет является дубликатом, в худшем — повтором (replay) от хакера. Это возможно в симметричном режиме при неравномерных интервалах опроса.

2

Фиктивный пакет

3

Недействительный пакет

Одно или несколько полей меток времени недействительно. Это обычно происходит в симметричном режиме, когда один партнёр передал пакет другому, а тот ещё не получил свой первый отклик.

4

Доступ отвергнут

Адрес источникам запрещён контролем доступа.

5

Отказ аутентификации

Криптографический дайджест сообщения на соответствует MAC.

6

Нет синхронизации

Сервер не синхронизирован с действительным источником.

7

Неверные данные в заголовке

Одно или несколько полей заголовка недействительно.

Рисунок 22. Проверка ошибок пакета.

Обработка продолжается копированием переменных пакета в переменные партнёра, как показано на рисунке 21. Пример этого приведён в функции packet() Приложения A.5.1.1. Функция receive() реализует тесты 1-5 (Рисунок 22), packet() — тесты 6-7. При обнаружении ошибки пакет отбрасывается и процесс партнёра завершается.

Протокол on-wire вычисляет смещение часов theta и круговую задержку delta по 4 наиболее свежим меткам времени, как описано в разделе 8. Хотя, в принципе, можно выполнить все расчёты, кроме разности первого порядка для временных меток, в арифметике с фиксированной запятой, много проще преобразовать разности первого порядка в floating double и выполнить оставшиеся расчёты в этой арифметике, как предполагается ниже.

Затем используется 8-битовый регистр сдвига p.reach (раздел 13) для определения доступности сервера и актуальности данных. Регистр сдвигается на 1 бит влево при передаче пакета с установкой правого бита в 0. При поступлении действительного пакета правый бит устанавливается (1). При наличии в регистре отличных от 0 битов сервер считается доступным, в ином случае — недоступным. Поскольку интервал опроса у партнёра мог измениться с последнего пакета, интервал опроса у хоста пересматривается. Пример представлен в функции poll_update() Приложения A.5.7.2.

Статистика дисперсии epsilon(t) представляет максимальную ошибку в результате допуска частоты и времени с момента передачи последнего пакета. Она инициализируется значением epsilon(t_0) = r.rho + s.rho + PHI * (T4-T1), когда измерение выполняется в момент t_0 согласно счетчику секунд. Здесь r.rho — точность пакета (параграф 7.3), а s.rho — точность системы (параграф 11.1), выраженные в секундах. Эти элементы требуются для учёта погрешности при считывании системных часов сервера и клиента.

Затем дисперсия растёт с постоянной скоростью PHI, т. е. в момент t будет epsilon(t) = epsilon(t_0) + PHI * (t-t_0). С принятым по умолчанию допуском PHI = 15 ppm это составляет около 1,3 сек/сутки. При таком подходе аргумент t отбрасывается и дисперсия представляется просто как epsilon. Остальная статистика рассчитывается алгоритмом фильтрации часов, описанным в следующем параграфе.

10. Алгоритм фильтрации часов

Алгоритм фильтра часов является частью процесса партнёра и обрабатывает поток данных для выбора образцов, представляющих наиболее точное время. Алгоритм создаёт переменные, показанные на рисунке 19, включая смещение (theta), задержку (delta), дисперсию (epsilon), вариации (psi) и время прибытия (t). Эти данные применяются алгоритмами смягчения для определения лучшего и окончательного смещения, применяемого дисциплиной системных часов, а также для определения работоспособности сервера и его пригодности для синхронизации.

Алгоритм фильтра часов сохраняет наиболее свежие квартеты выборки (theta, delta, epsilon, t) в структуре фильтра, служащей 8-ступенчатым регистром сдвига. Квартеты сохраняются в порядке прибытия пакетов, t указывает время прибытия по счётчику секунд и его не следует путать с партнёрской переменной tp.

Для обеспечения фильтру достаточного числа выборок и удаления старых данных применяется описанная далее схема. Исходно для квартетов всех ступеней устанавливаются фиктивные значения (0, MAXDISP, MAXDISP, 0), по мере прибытия новых пакетов квартеты сдвигаются в регистре с отбрасыванием старых и в результате остаются лишь действительные квартеты. Если 3 младших бита регистра охвата имеют значение 0, показывающее, что истекли 3 интервала опроса без приёма новых действительных пакетов, процесс опроса вызывает алгоритм фильтра часов с фиктивным квартетом, как будто тот прибыл из сети. Если это сохраняется в течение 8 интервалов опроса, регистр возвращается в исходное состояние. На следующем этапе ступени регистра сдвига копируются во временный список с сортировкой по возрастанию delta. Путь i — индекс ступени, начинающейся с минимального значения delta. Если первая эпоха квартета t_0 не позднее эпохи последней действительной выборки tp, программа завершается без изменения текущих переменных партнёра. В ином случае для дисперсии i-й записи epsilon_i — выражение

                     i=n-1
                     ---     epsilon_i
      epsilon =       \     ----------
                      /        (i+1)
                     ---     2
                     i=0

задаёт дисперсию партнёра p.disp. Отметим, что при переполнении epsilon на входе или выходе фильтра часов смысл должен быть ясен из контекста.

Наблюдатель следует отметить: (a) если все все ступени содержат фиктивные квартеты с дисперсией MAXDISP, рассчитанная дисперсия составит чуть меньше 16 сек, (b) при каждом сдвиге действительного квартета в регистр дисперсия падает чуть меньше, чем на половину в зависимости от дисперсии действительного квартета, (c) после четвёртого действительного квартета дисперсия обычно будет чуть меньше 1 сек, что является предполагаемым значением параметра MAXDIST по которому алгоритм выбора определяет приемлемость переменных партнёра.

Пусть смещение первой ступени в сортированном списке будет theta_0. Тогда для других ступеней в любом порядке вариация будет определяться средним значением RMS14

              +-----                             -----+^1/2
              |              n-1                      |
              |              ---                      |
              |    1         \                     2  |
      psi   = | -------- *   /    (theta_0-theta_j)   |
              |  (n-1)       ---                      |
              |              j=1                      |
              +-----                             -----+

где n — число действительных квартетов в фильтре (n > 1). Для обеспечения согласованности и предотвращения исключений при делении в других расчётах значение psi ограничивается снизу точностью системы s.rho, выраженной в секундах. Хотя обычно вариации не считаются основным фактором ранжирования качества серверов, это важный индикатор работы хронометража и состояний перегрузки в сети. Особое значение для алгоритмов смягчения имеет дистанция синхронизации с партнёром, которая вычисляется по задержке и дисперсии.

   lambda = (delta / 2) + epsilon

Отметим, что epsilon и, следовательно, lambda растёт со скоростью PHI. Переменная lambda не является переменной состояния, поскольку она рассчитывается при каждом применении. Это часть корневой дистанции синхронизации, применяемая алгоритмами смягчения как показатель качества времени, доступного от каждого сервера.

Важно отметить, что, в отличие от NTPv3, ассоциации NTPv4 не указывают тайм-аут установкой слоя 16 и индикатора високосных секунд 3. Переменные ассоциации сохраняют значения, полученные при поступлении последнего пакета. В NTPv4 значение lambda растёт со временем, поэтому в конечном итоге дистанция синхронизации превышает порог MAXDIST, после чего ассоциация считается не пригодной для синхронизации.

Пример реализации алгоритма фильтра часов содержится в функции clock_filter() из Приложения A.5.2.

11. Системный процесс

При получении каждой новой выборки (theta, delta, epsilon, jitter, t) алгоритмом фильтра часов все процессы партнёров сканируются алгоритмами смягчения, состоящими из алгоритмов выбора, кластера, комбинирования и дисциплины часов в системном процессе. Алгоритм выбора сканирует все ассоциации и отбрасывает фальшивые часы, которые указывают неверное время, оставляя лишь истинные. В серии раундов алгоритм кластера отбрасывает ассоциации, наиболее удалённые статистически от центроида, пока не останется заданное минимальное их число. Алгоритм комбинирования даёт лучшую и окончательную статистику на основе средневзвешенного значения. Окончательное смещение передаётся алгоритму дисциплины часов для корректировки времени системных часов.

Алгоритм кластера выбирает одного из оставшихся в качестве партнёра системы. Связанная с ним статистика (theta, delta, epsilon, jitter, t) служит для создания системных переменных, наследуемых зависимыми серверами и клиентами, доступными для других приложений на той же машине.

11.1. Переменные системного процесса

На рисунке 23 приведены базовые имена, формулы и краткие описания каждой системной переменной. Если явно не указано иное, все переменные имеют суффикс s.

 

Имя

Формула

Описание

t

t

Время обновления

p

p

Идентификатор партнёра системы

leap

leap

Индикатор високосной секунды

stratum

stratum

Слой (stratum)

precision

rho

Точность

offset

THETA

Комбинированное смещение

jitter

PSI

Комбинированные вариации

rootdelay

DELTA

Корневая задержка

rootdisp

EPSILON

Корневая дисперсия

v

v

Список оставшихся

refid

refid

Идентификатор эталона

reftime

reftime

Эталонное время

NMIN

3

Минимальное число остающихся

CMIN

1

Минимальное число кандидатов

 

Рисунок 23. Переменные системного процесса.

За исключением переменных t, p, offset, jitter и констант NMIN и CMIN, для переменных системы применяется тот же формат и интерпретация, что и для одноимённых переменных партнёра. Параметры NMIN и CMIN, используемые алгоритмами выбора и кластера, описаны в следующем параграфе.

Переменная t указывает счётчик секунд в момент последнего обновления, пример приведён в функции clock_update() (Приложение A.5.5.4). Переменная p содержит идентификатор партнёра системы, определяемый функцией cluster() (параграф 11.2.2). Переменная precisionс имеет такой же формат, что и одноимённая переменная партнёра. Точность определяется как двоичных логарифм большего из значений разрешения и времени считывания. Например, точность тактового генератора от сети переменного тока 60 Гц составляет 16 мсек, даже если аппаратные часы представляются с точностью в наносекунду. Переменные offset и jitter определяет алгоритм комбинирования (параграф 11.2.3). Они представляют лучшее и окончательное смещение и вариацию, используемые дисциплиной системных часов.

Исходно все переменные сбрасываются в 0, затем устанавливается leap = 3 (не синхронизировано) и stratum = MAXSTRAT (16). Помните, что MAXSTRAT в передаваемых пакетах указывается значением 0.

11.2. Операции системного процесса

На рисунке 24 показаны операции системного процесса, выполняемые программой выбора часов. Описанный в параграфе 11.2.1 алгоритм выдаёт набор основных предполагаемых кандидатов (истинные часы) на основе принципов соглашения. Алгоритм кластера (параграф 11.2.2) отбрасывает лишних кандидатов для создания более узкого набора. Алгоритм комбинирования (11.2.3) выдаёт наилучшее и окончательное смещение для алгоритма дисциплины часов. Пример представлен в Приложении A.5.5.6. Если алгоритм выбора не может создать набор кандидатов (majority clique) или не возможно выдать хотя бы CMIN оставшихся, системный процесс завершается без дисциплины системных часов. При успешном выполнении алгоритм кластера выбирает статистически оучшего кандидата как партнёра системы и его переменные наследуются как переменные системы.

                       +-----------------+
                       | clock_select()  |
                       +-----------------+
................................|...........
.                               V          .
.      yes +---------+ +-----------------+ .
.       +--| accept? | |  сканирование   | .
.       |  +---------+ |   кандидатов    | .
.       V        no |  |                 | .
.  +---------+      |  |                 | .
.  | add peer|      |  |                 | .
.  +----------      |  |                 | .
.       |           V  |                 | .
.       +---------->-->|                 | .
.                      |                 | .
. Алгоритм выбора      +-----------------+ .
.................................|..........
                                 V
                    no +-------------------+
         +-------------|     остались?     |
         |             +-------------------+
         |                       | yes
         |                       V
         |             +-------------------+
         |             | Алгоритм кластера |
         |             +-------------------+
         |                       |
         |                       V
         V         yes +-------------------+
         |<------------|     n < CMIN?     |
         |             +-------------------+
         V                       |
  +-----------------+            V no
  |   s.p = NULL    |  +-------------------+
  +-----------------+  |   s.p = v_0.p     |
         |             +-------------------+
         V                       |
  +-----------------+            V
  | return (UNSYNC) |  +-------------------+
  +-----------------+  |   return (SYNC)   |
                       +-------------------+

Рисунок 24. Процедура выбора часов.


11.2.1. Алгоритм выбора

Алгоритмы выбора и кластера описаны по отдельности, но в скелете кода объединены. Алгоритм выбора ищет пересечение интервалов, содержащее основные истинные часы, по принципам византийского алгоритма, исходно предложенного Marzullo [ref6], но изменённого для повышения точности. Обзор алгоритма приведён ниже, а код представлен в первой половине функции clock_select() в Приложении A.5.5.1.

Сначала серверы, не подходящие по правилам протокола обнаруживаются и отбрасываются, как показано в функции accept() Приложения A.5.215. Затем создаётся набор триплетов (p, type, edge) для оставшихся кандидатов. Здесь p — идентификатор ассоциации, type указывает верхнюю (+1), среднюю (0) и нижнюю (-1) конечные точки интервала корректности кандидата с центром theta. Это даёт 3 триплета lowpoint (p, -1, theta — lambda), midpoint (p, 0, theta), highpoint (p, +1, theta + lambda), где lambda — корневая дистанция синхронизации. Пример расчёта показан в функции root_dist() Приложения A.5.1.216. Этапы алгоритма приведены ниже.

  1. Для каждой из m ассоциаций 3 триплета помещаются в список кандидатов, как указано выше.

  2. Триплеты списка сортируются по краевым компонентам в порядке lowpoint, midpoint, highpoint. Для числа фальшивых часов устанавливается значение f = 0.

  3. Устанавливается число средних точек d = 0, а также c = 0 и выполняется сканирование от низшей точки к высшей. Значение c увеличивается на 1 для каждой lowpoint, снижается на 1 для каждой highpoint и добавляется 1 к каждой midpoint. Если c >= m — f, выполнение завершается и в качестве l устанавливается текущая нижняя точка.

  4. Устанавливается c = 0 и выполняется сканирование от верхней точки к нижней. К c добавляется 1 для каждой highpoint и вычитается 1 для каждой lowpoint, к d добавляется 1 для каждой . Если c >= m — f, выполнение завершается и в качестве u устанавливается текущая верхняя точка.

  5. Проверяется выполнение условий d <= f17 и l < u. При соблюдении выполняется 5A, иначе — 5B.

    1. Интервалом пересечения будет [l, u].

    2. К f добавляется 1 и проверяется условие f < (m / 2). При выполнении возврат к п. 3, иначе — 6.

  6. Отказ — набор кандидатов не найден, поскольку они не подходят для дисциплины системных часов.

Алгоритм подробно описан в Приложении A.5.5.1. Отметим, что он начинается с допущения отсутствия фальшивых часов (f = 0) и попытки еайти непустой интервал пересечения со средними точками всех корректных серверов (истинные часы). Если такой интервал не найден, число предполагаемых ложных часов увеличивается на 1 и попытка повторяется. Если интервал найден и число ложных часов меньше числа истинных, набор кандидатов найден и midpoint каждых истинных часов (theta) представляет кандидатов, доступных для алгоритма кластера.

Если набор кандидатов не найден или число истинных часов меньше CMIN, кандидатов для дисциплины системных часов не достаточно. CMIN задаёт минимальное число серверов, соответствующих требованиям корректности. Сомнительные операторы будут устанавливать CMIN для обеспечения множества избыточных серверов, доступных для надлежащего смягчения. Однако по историческим причинам для CMIN по умолчанию установлено значение 1.

11.2.2. Алгоритм кластера

Кандидаты из набора помещаются в список оставшихся v в форме триплетов (p, theta_p, psi_p, lambda_p), где p — идентификатор ассоциации, theta_p, psi_p и stratum_p — текущее смещение, вариации (jitter) и слой ассоциации p, соответственно, а lambda_p — показатель качества, равный stratum_p * MAXDIST + lambda, где lambda — корневая дистанция синхронизации для p. Список обрабатывается алгоритмом кластера, как описано ниже, а пример можно найти во второй половине алгоритма clock_select() из Приложения A.5.5.1.

  1. Пусть (p, theta_p, psi_p, lambda_p) представляет сохранившегося кандидата.

  2. Кандидаты сортируются по росту lambda_p. Пусть n — число кандидатов, а NMIN — минимально требуемое число оставшихся.

  3. Для каждого кандидата рассчитывается вариация выбора как

             +-----                       -----+^1/2
             |        n-1                      |
             |        ---                      |
             |   1    \                     2  |
     psi_s = | ---- * /  (theta_s - theta_j)   |
             |  n-1   ---                      |
             |        j=1                      |
             +-----                       -----+
  1. Выбирается psi_max как кандидат с наибольшим значением psi_s.

  2. Выбирается psi_min как кандидат с наименьшим значением psi_p.

  3. Если psi_max < psi_min или n <= NMIN, выполняется 6A, иначе — 6B.

    1. Алгоритм завершён, оставшиеся в списке кандидаты ранжируются в порядке предпочтения. Первый элемент списка представляет партнёра системы, переменные которого позже служат для обновления системных переменных.

    2. Удаляется кандидат с psi_max, значение n уменьшается на 1 и алгоритм возвращается к п. 3.

Алгоритм работает с серией раундов, в каждом из которых отбрасывается статистический выброс с максимальной вариацией выбора psi_s. Однако, если psi_s меньше минимальной вариации партнёра psi_p, отбрасывание выбросов уже не даст улучшения. Это минимальное число оставшихся даёт условие завершения алгоритма. По завершении финальное значение psi_max сохраняется как вариация выбора системы PSI_s для последующего применения.

11.2.3. Алгоритм комбинирования

Маршрут комбинирования часов обрабатывает оставшихся кандидатов для создания лучших и окончательных данных для алгоритма дисциплины часов. Программа обрабатывает статистику смещения и вариаций партнёра для создания комбинированного смещения THETA и вариаций PSI_p, где статистика каждого сервера «взвешивается» обратной величиной корневой дистанции синхронизации и результат нормализуется (см. функцию clock_combine() в Приложении A.5.5.5)

Комбинированное значение THETA передаётся программе обновления часов. Первый кандидат из списка оставшихся назначается партнёром системы с идентификатором p. Его значение является компонентом вариаций системы PSI и применяется вместе с PSI_s для расчёта, как показано ниже.

   PSI = [(PSI_s)^2 + (PSI_p)^2]^1/2

При каждом обновлении, полученном от партнёра системы вызывается программа обновления часов. По правилу обновление отбрасывается, если время прибытия p.t не строго позже последнего принятого обновления s.t. Метки IGNOR, PANIC, ADJ, STEP указывают коды возврата локальной программы часов, описанной в следующем параграфе.

IGNORE указывает, что обновление проигнорировано, как выброс, PANIC означает смещение, превышающее порог PANICT (1000 сек) и по нему следует завершать программу с диагностическим сообщением для журнала системы (log). STEP указывает, что смещение меньше PANICT, но больше порога ступени STEPT (125 мсек). В этом случае часы переводятся на корректное смещение, но, поскольку это означает недействительность всех данных партнёра, все ассоциации должны быть сброшены, а клиент начинает заново как при исходном запуске.

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

Системная переменная <-- Системная переменная партнёра 
         s.leap      <-- p.leap
         s.stratum   <-- p.stratum + 1
         s.offset    <-- THETA
         s.jitter    <-- PSI
         s.rootdelay <-- p.delta_r + delta
         s.rootdisp  <-- p.epsilon_r + p.epsilon + 5* p.psi + PHI * (t_s - p.t) + |THETA|
         s.refid     <-- p.refid
         s.reftime   <-- p.reftime
         s.t         <-- p.t

Рисунок 25. Обновление системных переменных.


Переменная t_s указывает время обновления системных переменных. На рисунке не показана важная деталь. Инкремент дисперсии (p.epsilon + 5 * p.psi + PHI * (t_s — p.t) + |THETA|) ограничен снизу значением MINDISP. В подсетях с очень быстрыми процессорами и скоростью, а также очень малой задержкой и дисперсией это ведёт к монотонно-определённому росту s.rootdisp (EPSILON), что предотвращает петли между партнёрами, работающими в одном слое18.

Системные переменные доступны зависимым прикладным программам как номинальная статистика производительности. Системное смещение THETA — смещение часов относительно источников синхронизации, системные вариации PSI — оценка ошибки при определении значения, иногда называемая ожидаемой ошибкой. Корневая задержка DELTA — суммарная круговая задержка до первичного сервера. Корневая дисперсия EPSILON — дисперсия аккумулированная в сети от первичного сервера. Дистанция синхронизации определяется выражением

   LAMBDA = EPSILON + DELTA / 2

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

Пример программы обновления часов представлен в Приложении A.5.5.4.

11.3. Алгоритм дисциплины часов

Алгоритм дисциплины часов NTPv4, сокращенно называемый дисциплиной, работает как комбинация двух достаточно различающихся систем обратной связи. В схеме фазовой автоподстройки частоты (phase-locked loop или PLL) периодически обновляется фаза с интервалами в несколько микросекунд для минимизации временной ошибки напрямую и ошибки частоты — опосредованно. В контуре автоподстройки частоты (frequency-locked loop или FLL) периодически обновляется частота с микросекундными интервалами для минимизации ошибки частоты напрямую и ошибки времени — опосредованно. Как показано в [ref7], PLL работает лучше при доминировании сетевых вариаций, а FLL — при доминировании дрейфа тактового генератора. В этом разделе описана работа NTPv4, подробное описание принципов устройства дано в [ref7] вместе с анализом производительности.

Дисциплина реализована как система управления с обратной связью (Рисунок 26). Переменная theta_r представляет смещение алгоритма комбинирования (опорная фаза), а theta_c — смещение VFO (фаза управления). Каждое обновление создаёт сигнал V_d, представляющий мгновенную разность фаз theta_r — theta_c. Фильтр часов для каждого сервера работает как линия задержки с ответвлениями, при этом вывод берётся с ответвления, выбранного алгоритмом фильтра часов. Алгоритмы выбора, кластера и комбинирования объединяют данные нескольких фильтров для создания сигнала V_s. Кольцевой фильтр с импульсным откликом F(t) создаёт сигнал V_c, управляющий частотой VFO omega_c и, таким образом, фазой theta_c, замыкая контур. Сигнал V_c генерируется процессом корректировки часов (раздел 12). Уравнения, реализующие эти функции, представлены в Приложениях A.5.5.6 и A.5.6.1.

    theta_r + +---------\        +----------------+
NTP --------->| Детектор \  V_d  |                | V_s
    theta_c - |   фазы    ------>|  Фильтр часов  |----+
    +-------->|          /       |                |    |
    |         +---------/        +----------------+    |
    |                                                  |
  -----                                                |
 /     \                                               |
 | VFO |                                               |
 \     /                                               |
  -----    .......................................     |
    ^      .         Кольцевой фильтр            .     |
    |      . +---------+   x  +-------------+    .     |
    | V_c  . |         |<-----|             |    .     |
    +------.-|Корректир|   y  |Предсказание |<---------+
           . |  часов  |<-----|фазы/частоты |    .
           . |         |      |             |    .
           . +---------+      +-------------+    .
           .......................................

Рисунок 26. Контуры обратной связи дисциплины часов.


Исходно описанный выше псевдолинейный контур обратной связи работает для дисциплины системных часов. Однако в некоторых случаях нелинейный алгоритм обеспечивает существенное улучшение. Одним из таких случаев является запуск дисциплины без знания частоты внутренних часов. Псевдолинейному контуру нужно несколько часов для точного измерения и в большую часть этого времени интервал измерений нельзя увеличить. Описанный ниже нелинейный контур делает это за 15 минут. Другим случаем являются случайные пики вариаций при наличии перегрузки в каналах сети. Описанный ниже конечный автомат устойчив к пикам ошибок длительностью менее 55 минут.

На рисунке 27 приведены переменные и параметры, имена формул и краткие описания. Если явно не указано иное, для всех переменных предполагается префикс c. Переменные t, tc, state, hyster, count являются целочисленными, остальные — floating double. Назначение каждой переменной приведено ниже в описании алгоритма.

 

Имя

Формула

Описание

t

timer

Счётчик секунд

offset

theta

Комбинированное смещение

resid

theta_r

Оставшееся смещение

freq

phi

Частота часов

jitter

psi

Вариации смещения часов

wander

omega

Дрейф частоты часов

tc

tau

Постоянная времени (log2)

state

state

Состояние

adj

adj

Корректировка частоты

hyster

hyster

Счётчик гистерезиса

STEPT

125

Порог ступени (0,125 сек)

WATCH

900

Порог шага (сек)

PANICT

1000

Порог «паники» (1000 сек)

LIMIT

30

Предел гистерезиса

PGATE

4

Порог гистерезиса (hysteresis gate)

TC

16

Масштаб постоянной времени

AVG

8

Постоянная усреднения

 

Рисунок 27. Переменные и параметры дисциплины часов.

Процесс прерывается незамедлительно, если смещение превышает порог PANICT (1000 сек). Программа смены состояния rstclock() представлена в Приложении A.5.5.7, а на рисунке 28 показаны используемые в ней функции смены состояний. В столбцах таблицы приведены имена состояний, условие и действие для случаев, кода смещение theta меньше порога ступени и больше этого порога, а также комментарии.

 

Статус

theta < STEP

theta > STEP

Комментарий

 NSET
 ->FREQ
 adjust time 
 ->FREQ
 step time 

Нет файла частоты

 FSET
 ->SYNC
 adjust time 
 ->SYNC
 step time 

Файл частоты

 SPIK
 ->SYNC
 adjust freq 
 adjust time 
 if < 900 s ->SPIK 
 else ->SYNC 
 step freq 
 step time 

Обнаружен выброс (пик)

 FREQ
 if < 900 s ->FREQ 
 else ->SYNC 
 step freq 
 adjust time 
 if < 900 s ->FREQ 
 else ->SYNC 
 step freq 
 adjust time 

Исходная частота

 SYNC
 ->SYNC
 adjust freq 
 adjust time 
 if < 900 s ->SPIK 
 else ->SYNC 
 step freq 
 step time 

Нормальная работа

 

Рисунок 28. Функции смены состояния.

В таблице следующее состояние указывается стрелкой ->, а далее приведены действия. Такие операции как корректировка времени и частоты реализуются контуром обратной связи PLL/FLL в функции local_clock(). Операция «сдвига часов на шаг» (step clock) реализуется установкой часов напрямую, но это происходит лишь после порога порога WATCH (900 сек), когда смещение превышает порог шага STEPT (0,125 сек). Это позволяет избежать ненужных корректировок в случае перегрузки в сети.

Статистика вариаций (psi) и дрейфа (omega) рассчитывается с использованием экспоненциального среднего значения с весовым коэффициентом AVG. Показатель постоянной времени (tau) определяется сравнением psi с величиной текущего смещения theta. Если смещение больше PGATE (4), умноженного на вариации часов, счётчик гистерезиса hyster уменьшается на 2, а ином случае — увеличивается на 1. Если hyster увеличивается до верхнего предела LIMIT (30), tau увеличивается на 1, при снижении до нижнего предела -LIMIT (-30) значение tau уменьшается на 1. Обычно tau колеблется около MAXPOLL, но быстро снижается, если скачок температуры вызывает всплеск частоты.

12. Процесс корректировки часов

Фактический процесс корректировки часов выполняется с интервалом в 1 секунду для учёта корректировки частоты и фиксированного процента оставшегося смещения theta_r. По сути, theta_r представляет экспоненциальное затухание значения theta, создаваемого фильтром контура обратной связи при каждом обновлении. Параметр TC для удобства масштабирует постоянную времени в соответствии с интервалом опроса. Отметим, что дисперсия EPSILON растёт на величину PHI каждую секунду.

Процесс корректировки часов включает прерывание по таймеру, управляющее счётчиком секунд c.t. Отсчёт начинается с 0 при запуске службы и значение инкрементируется 1 раз в секунду. При каждом прерывании вызывается функция clock_adjust() для включения времени дисциплины часов и корректировки частоты, затем ассоциации сканируются, чтобы сравнить значение счётчика секунд с переменной состояния p.next, определённой в следующем параграфе. Если значение счётчика не меньше p.next, вызывается процесс опроса и рассчитывается следующее значение p.next.

Пример процесса корректировки часов содержится в функции clock_adjust() Приложения A.5.6.1.

13. Процесс опроса

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

13.1. Переменные процесса опроса

На рисунке 29 приведены имена, формулы и краткие описания переменных и параметров процесса опроса. Если явно не указано иное, для переменных предполагается суффикс p.

 

Имя

Формула

Описание

hpoll

hpoll

Показатель опроса

last

last

Время последнего опроса

next

next

Время следующего опроса

reach

reach

Регистр доступа

unreach

unreach

Счётчик недоступности

UNREACH

24

Предел недоступности

BCOUNT

8

Счётчик пиков

BURST

flag

Флаг режима burst

IBURST

flag

Флаг разрешения iburst

 

Рисунок 29. Переменные и параметры процесса опроса.

Переменные процесса опроса выделяются в структуре данных вместе с переменными процесса партнёра. Ниже приведены описания переменных, а параметры рассматриваются позднее.

hpoll

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

last

Целочисленное значение счётчика секунд с момент передачи последнего пакета.

next

Целое число секунд до момента передачи следующего пакета.

reach

8-битовый целочисленный регистр сдвига, совместно используемые процессами партнёра и опроса.

unreach

Целое число секунд, в течение которых сервер был недоступен.

13.2. Операции процесса опроса

Как описано выше, процесс корректировки часов вызывается 1 раз в секунду и сам вызывает процедуру опроса для каждой ассоциации. Если время отправки следующего опросного сообщения больше значения счётчика секунд, программа сразу же завершается. Симметричные (режимы 1, 2), клиентские (режим 3) и широковещательные серверный (режим 5) ассоциации регулярно отправляют пакеты. Широковещательные ассоциации клиентов (режим 6) запускают процедуру для обновления переменных reach и unreach, но не передают пакеты. Процесс опроса вызывает процесс передачи для отправки пакета. В случае burst > 0 ничего не делается, кроме вызова процедуры обновления опроса для установки интервала следующего опроса. В ином случае переменная reach сдвигается влево на 1 бит с установкой для правого бита значения 0. Если сервер не был слышен в течение трёх последних интервалов опроса, вызывается программа фильтра часов для увеличения дисперсии (Приложение A.5.7.3).

Если флаг BURST установлен, сервер доступен и имеется действительный источник синхронизации, клиент передаёт блок (burst) из BCOUNT (8) пакетов за каждый интервал опроса. Интервал между пакетами в блоке составляет 2 секунды. Это полезно для точного измерения вариаций с длинными интервалами опроса. Если флаг IBURST установлен и это первый пакет, переданный с момента недоступности сервера, клиент передаёт блок пакетов. Это полезно для быстрого сокращения дистанции синхронизации до значения ниже порога и синхронизации часов.

Если флаг P_MANY установлен в слове ассоциации p.flags, это ассоциация является клиентской многоадресной (manycast). Такая ассоциация передаёт клиентские пакеты по назначенному групповому адресу с интервалом MINPOLL, начиная работу с TTL = 1. Если к моменту следующего опроса активировано (mobilized) менее MINCLOCK серверов, значение TTL увеличивается на 1. Если значение достигло TTLMAX и не найдено MINCLOCK серверов, интервал опроса увеличивается до достижения BEACON, после чего процесс возобновляется с начала.

Функция poll() включает увеличение интервала опроса, если сервер становится недоступным. Если reach имеет ненулевое значение, сервер доступен и устанавливается unreach = 0, в ином случае значение unreach увеличивается на 1 для каждого опроса вплоть до UNREACH. После этого hpoll для каждого опроса увеличивается на 1, что удваивает интервал опроса, вплоть до значения MAXPOLL, определяемого функцией poll_update(). Когда сервер снова становится доступным, устанавливается unreach = 0, для hpoll устанавливается значение системной переменной tc и работа возобновляется в обычном режиме.

Пакет передаётся процессом отправки. Некоторые поля заголовка копируются из системных переменных, оставленных предыдущим пакетом, а другие — из системных переменных. На рисунке 30 показано, какие значения копируются в каждое поле заголовка. В реализациях, применяющих данные типа floating double для корневой задержки и дисперсии, эти значения должны преобразовываться в короткий формат NTP. Остальные поля копируются без изменения из переменных партнёра и системы или извлекаются как метки из часов системы.

Переменная пакета <--     Переменная
x.leap            <--     s.leap
x.version         <--     s.version
x.mode            <--     s.mode
x.stratum         <--     s.stratum
x.poll            <--     s.poll
x.precision       <--     s.precision
x.rootdelay       <--     s.rootdelay
x.rootdisp        <--     s.rootdisp
x.refid           <--     s.refid
x.reftime         <--     s.reftime
x.org             <--     p.xmt
x.rec             <--     p.dst
x.xmt             <--     clock
x.keyid           <--     p.keyid
x.digest          <--     md5 digest

Рисунок 30. Заголовок xmit_packet.


Процедура обновления опроса вызывается при получении действительного пакета и сразу же после отправки опросного сообщения. В блочном (burst) режиме фиксируется интервал опроса 2 сек, в ином случае для показателя hpoll устанавливается меньшее из значений ppoll для последнего полученного пакета и hpoll из функции опроса, но не меньше MINPOLL и не больше MAXPOLL. Таким образом дисциплина часов может применяться излишне часто (oversampled) но не слишком редко. Это нужно для сохранения динамики подсети и защиты от ошибок протокола.

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

14. Простой протокол сетевого времени (SNTP)

Первичным серверам и клиентам, соответствующим подмножеству NTP, называемому простым протоколом сетевого времени (Simple Network Time Protocol или SNTPv4) [RFC4330], не требуется реализовать алгоритмы смягчения, описанные в разделе 9 и последующих разделах этого документа. Протокол SNTP предназначен для первичных серверов, оборудованных одними эталонными часами, и клиентов с одним восходящим сервером без зависимых клиентов. Полная реализация NTPv4 предназначена для вторичных серверов с несколькими восходящими серверами и множеством нисходящих серверов или клиентов. За исключением этого, серверы и клиенты NTP и SNTP полностью совместимы и могут перемешиваться в подсетях NTP.

Первичный сервер SNTP, реализующий протокол on-wire, описанный в разделе 8 , не имеет восходящих серверов за исключением одних эталонных часов. В принципе, он неотличим от первичного сервера NTP, имеющего алгоритмы смягчения и за счёт этого способного смягчать различия между несколькими эталонными часами.

При получении запроса от клиента первичный сервер SNTP создаёт и отправляет пакет отклика, показанный на рисунке 31. Отметим, что поле дисперсии в заголовке должно обновляться в соответствии с разделом 5.

Переменная пакета <--     Переменная
x.leap            <--     s.leap
x.version         <--     r.version
x.mode            <--     4
x.stratum         <--     s.stratum
x.poll            <--     r.poll
x.precision       <--     s.precision
x.rootdelay       <--     s.rootdelay
x.rootdisp        <--     s.rootdisp
x.refid           <--     s.refid
x.reftime         <--     s.reftime
x.org             <--     r.xmt
x.rec             <--     r.dst
x.xmt             <--     clock
x.keyid           <--     r.keyid
x.digest          <--     md5 digest

Рисунок 31. Заголовок fast_xmit.


Клиент SNTP, реализующий протокол on-wire, имеет 1 сервер и не имеет зависимых клиентов. Он может работать с любым подмножеством протокола NTP on-wire, а самый простой подход использует лишь метку времени передачи от сервера и игнорирует прочие поля. Однако добавочные сложности полной реализации протокола on-wire минимальны и такая реализация приветствуется.

15. Вопросы безопасности

Требования безопасности для NTP более строги, чем для большинства распределенных служб. Во-первых, операции механизмов проверки подлинности и синхронизации времени неразрывно связаны между собой. Для надёжной синхронизации времени требуются криптографические ключи, которые действительны лишь в течение заданного срока, но временные интервалы можно применять лишь при надёжной синхронизации участвующих клиентов и серверов с UTC. Кроме того, подсеть NTP по своей природе имеет иерархию, поэтому время и доверие передаются от первичных серверов в корне иерархии к клиентам (листьям) через вторичные серверы.

Клиент NTP может заявлять наличие истинного времени зависимым приложениям лишь в том случае, когда все серверы на пути к первичным аутентифицированы. В NTP каждый сервер аутентифицирует серверы слоя (stratum) с меньшим номером и (по индукции) серверы с наименьшим значением stratum (первичные). Важно отметить, что проверка подлинности в контексте NTP не обязательно предполагает корректность времени. Клиент NTP активирует множество одновременных ассоциаций с разными серверами и использует специально созданный алгоритм согласования для выбора истинных часов (truechimer) из популяции, возможно включающей ложные часы (falseticker).

Спецификация NTP предполагает, что цель злоумышленника состоит во внедрении ложных значений времени, нарушении работы протокола и засорение сети, серверов или клиентов фиктивными пакетами, которые истощают ресурсы и препятствуют обслуживанию легитимных приложений. В архитектуру, протокол и алгоритмы NTP уже включено множество механизмов защиты. Схема обмена метками времени в линии по своей природе устойчива к подменам, потерям и повторному использованию пакетов в атаках. Фильтр часов, алгоритмы выбора и кластеризации разработаны для защиты от ложных кандидатов (evil clique) в византийских атаках. Хотя алгоритмы и сопутствующие проверки работоспособности не предназначены специально для борьбы со злоумышленниками, они хороши работают в течение многих лет, отклоняя некорректно работающие, но предположительно дружественные варианты. Однако эти механизмы не обеспечивают безопасной идентификации и аутентификации серверов для клиента. Без дополнительной защиты злоумышленник может организовать любую из указанных ниже атак.

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

  2. Атакующий может создавать пакеты быстрее, чем сервер, сеть или клиент способны обрабатывать их, особенно при использовании ресурсоёмких криптографических расчётов.

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

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

Модель безопасности NTP предполагает ряд ограничений, указанных ниже.

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

  2. В некоторых режимах работы серверу нереально сохранять переменные состояния для каждого клиента. Однако возможно создать их заново по прибытии пакета от этого клиента.

  3. Срок действия криптографических значений должен соблюдаться, для чего требуется надёжность системных часов. Однако источники синхронизации для системных часов должны быть доверенными. Такая циклическая зависимость функций хронометража требует особого внимания.

  4. Функции защиты клиенты должны включать лишь открытые значения, передаваемые через сеть. Секретный значения не должны покидать машину, где они созданы, за исключением случаев использования специальных доверенных агентов (trusted agent или TA), предназначенных для таких целей.

В отличие от модели безопасности Secure Shell (SSH), где клиент должен пройти безопасную аутентификацию на сервере, в NTP сервер должен пройти проверку подлинности у клиента. В SSH каждый адрес интерфейса можно связать со своим именем, возвращаемым запросом reverse-DNS. В этой схеме могут требоваться разные пары ключей «открытый-секретный» для каждого интерфейса со своим именем. Очевидным преимуществом такого подхода является возможность организации своего «отсека» безопасности для каждого интерфейса. Это позволяет межсетевому экрану, например, требовать аутентификацию клиента на одних интерфейсах, не требуя на других.

В случае NTP, как указано здесь, широковещательные клиенты NTP уязвимы из-за некорректного поведения или враждебности широковещательных серверов SNTP и NTP в сети Internet. Такая опасность может быть сведена к минимуму несколькими способами. Можно организовать фильтрацию, чтобы клиенты NTP получали доступ лишь к доверенным серверам NTP, что предотвратит попадание вредоносного трафика к клиентам NTP. Криптографическая аутентификация у клиента позволит применять при синхронизации часов лишь должным образом подписанные сообщения NTP. Более надёжную аутентификацию может обеспечить механизм Autokey [RFC5906].

В разделе 8 рассмотрены возможные угрозы, связанные с повторным использованием клиентских запросов. Соблюдение рекомендаций этого раздела поможет защититься от таких атак.

Следует отметить, что эта спецификация описывает имеющуюся реализацию. Хотя недостатки защиты алгоритма MD5 хорошо известны, его применение в спецификации NTP согласуется с широким применением в сообществе Internet.

16. Взаимодействие с IANA

Порт UDP/TCP 123 был ранее выделен IANA для этого протокола. Агентство IANA выделило групповой адрес IPv4 224.0.1.1 и групповой адрес IPv6, заканчивающийся на :101 для протокола NTP. Этот документ добавляет поля расширения NTP, позволяющие разработку будущих расширений протокола, где конкретное расширение задаётся субполем Field Type в поле расширения. Агенство IANA создало и поддерживает реестр для типов полей расширения (Extension Field Types), связанных с этим протоколом, который исходно пуст. По мере необходимости у будущем могут определяться новые типы полей расширения, регистрируемые по процедуре IETF Review [RFC5226].

Агентство IANA создало новый реестр для кодов идентификации эталогов NTP (NTP Reference Identifier codes), включающий значения, заданные в параграфе 7.3. Новые коды могут добавляться по процедуре First-Come-First-Serve (FCFS). Формат реестра показан ниже.

 

ID

Источник времени

GOES

Geosynchronous Orbit Environment Satellite

GPS

Global Position System

 

Рисунок 32. Коды идентификации эталонных источников.

Агентство IANA создало новый реестр для кодов NTP Kiss-o’-Death. Реестр включает коды, заданные в параграфе 7.4, и может расширяться по процедуре FCFS. Формат реестра показан ниже.

 

Код

Значение

ACST

Ассоциация относится к unicast-серверу.

AUTH

Отказ при аутентификации сервера.

 

Рисунок 33. Коды Kiss.

Для идентификаторов эталонов и кодов Kiss-o’-Death, начинающихся с символа X (эксперименты и разработка) запрашивать IANA не требуется.

17. Благодарности

Авторы благодарны Karen O’Donoghue, Brian Haberman, Greg Dowd, Mark Elliot, Harlan Stenn, Yaakov Stein, Stewart Bryant, Danny Mayer за технические рецензии и текстовый вклад в этот документ.

18. Литература

18.1. Нормативные документы

[RFC0768] Postel, J., «User Datagram Protocol», STD 6, RFC 768, August 1980.

[RFC0791] Postel, J., «Internet Protocol», STD 5, RFC 791, September 1981.

[RFC0793] Postel, J., «Transmission Control Protocol», STD 7, RFC 793, September 1981.

[RFC1321] Rivest, R., «The MD5 Message-Digest Algorithm», RFC 1321, April 1992.

[RFC2119] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, March 1997.

18.2. Дополнительная литература

[CGPM] Bureau International des Poids et Mesures, «Comptes Rendus de la 15e CGPM», 1976.

[ITU-R_TF.460] International Telecommunications Union, «ITU-R TF.460 Standard-frequency and time-signal emissions», February 2002.

[RFC1305] Mills, D., «Network Time Protocol (Version 3) Specification, Implementation and Analysis», RFC 1305, March 1992.

[RFC1345] Simonsen, K., «Character Mnemonics and Character Sets», RFC 1345, June 1992.

[RFC4330] Mills, D., «Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI», RFC 4330, January 2006.

[RFC5226] Narten, T. and H. Alvestrand, «Guidelines for Writing an IANA Considerations Section in RFCs», BCP 26, RFC 5226, May 2008.

[RFC5906] Haberman, B., Ed. and D. Mills, «Network Time Protocol Version 4: Autokey Specification», RFC 5906, June 2010.

[ref6] Marzullo and S. Owicki, «Maintaining the time in a distributed system», ACM Operating Systems Review 19, July 1985.

[ref7] Mills, D.L., «Computer Network Time Synchronization — the Network Time Protocol», CRC Press, 304 pp, 2006.

[ref9] Mills, D.L., Electrical and Computer Engineering Technical Report 06-6-1, NDSS, June 2006, «Network Time Protocol Version 4 Reference and Implementation Guide», 2006.

Приложение A. Скелет кода

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

Здесь включено большинство возможностей эталонной реализации, но нет предоставления эталонных часов и криптографии с открытым ключом (Autokey). Отсутствует фильтр huff-n’-puff filter, гистерезис anti-clockhop и процедуры мониторинга. Многие из значений, которые могут меняться в эталонной реализации, здесь предполагаются константами. Пакеты kiss-o’-death представлены минимально и без соответствующего кода.

Программа не обеспечивает компактности и скорости, она предназначена лишь для демонстрации алгоритмов с достаточной для понимания их работы точностью. Скелет кода состоит из 8 сегментов — сегмент заголовка, включаемый во все остальные сегменты, сегмент кода основной программы, интерфейсы с ядром, системой ввода-вывода и системными часами, а также процессы партнёра, системы, опроса и clock_adjust. Они представлены вместе с определениями и переменными, характерными для каждого процесса.

A.1. Глобальные определения

A.1.1. Определения, константы, параметры

#include <math.h>               /* избегать жалоб на sqrt() */
#include <sys/time.h>           /* для gettimeofday() и т. п. */
#include <stdlib.h>             /* для malloc() и т. п. */
#include <string.h>             /* для memset() */

/*
 * Типы данных
 *
 * Эта программа предполагает тип int размеров 32 бита и long - 64 бита.
 * В большинстве расчётов применяется естественный тип floating double.
 * Типы данных в некоторых полях заголовков требуют преобразования.
 * Некоторые поля заголовков делятся по октетам и представлены здесь
 * октетами.
 *
 * 64-битовый формат меток времени NTP, применяемый в расчётах меток,
 * является беззнаковым числом секунд слева от бита 32. Для этих значений
 * разрешена лишь операция вычитания, дающая значения со знаком и размером
 * 31 бит. Короткий формат 32-битовых меток NTP применяется при расчёте 
 * задержки и дисперсии. Значение целых секунд указывается слева от бита
 * 16. Для этих значений разрешено лишь сложение и умножение на константу.
 *
 * Адреса IPv4 задаются 32 битами, IPv6 - 128 битами. Поле дайджеста
 * сообщения содержит 128 битов результата расчёта MD5. Поля точности и
 * интервала опроса задаются двоичным логарифмом (log2) числа секунд.
 */
typedef unsigned long long tstamp;   /* Формат метки времени NTP */
typedef unsigned int tdist;     /* Короткий формат NTP */
typedef unsigned long ipaddr;   /* Адрес IPv4 или IPv6 */
typedef unsigned long digest;   /* Дайджест md5 */
typedef signed char s_char;     /* Точность или интервал опроса (log2) */

/*
 * Макросы преобразования меток времени
 */
#define FRIC        65536.                  /* 2^16 как double */
#define D2FP(r)     ((tdist)((r) * FRIC))   /* короткая метка NTP */
#define FP2D(r)     ((double)(r) / FRIC)

#define FRAC       4294967296.             /* 2^32 как double */
#define D2LFP(a)   ((tstamp)((a) * FRAC))  /* метка NTP */
#define LFP2D(a)   ((double)(a) / FRAC)
#define U2LFP(a)   (((unsigned long long) \
                       ((a).tv_sec + JAN_1970) << 32) + \
                       (unsigned long long) \
                       ((a).tv_usec / 1e6 * FRAC))

/*
 * Арифметические преобразования
 */
#define LOG2D(a)        ((a) < 0 ? 1. / (1L << -(a)) : \
                            1L << (a))          /* опрос и т. п. */
#define SQUARE(x)       ((x) * (x))19
#define SQRT(x)         (sqrt(x))

/*
 * Глобальные константы. Часть их может конвертироваться в переменные,
 * которые можно менять в конфигурации или рассчитывать «на лету».
 * Например, эталонная реализация рассчитывает PRECISION на лету и
 * обеспечивает настройку для определений, помеченных %.
 */
#define VERSION         4       /* номер версии */
#define MINDISP         .01     /* % минимальная дисперсия (s) */
#define MAXDISP         16      /* максимальная дисперсия (s) */
#define MAXDIST         1       /* % порог дистанции (s) */
#define NOSYNC          0x3     /* високосные секунды не синхронизированы */
#define MAXSTRAT        16      /* Максимальный номер слоя (бесконечность) */
#define MINPOLL         6       /* % минимальный интервал опроса (64 сек)*/
#define MAXPOLL         17      /* % максимальный интервал опроса (36,4 час) */
#define MINCLOCK        3       /* минимальное число оставшихся manycast */
#define MAXCLOCK        10      /* максимальное число кандидатов manycast */
#define TTLMAX          8       /* max ttl manycast */
#define BEACON          15      /* максимальный интервал между beacon */

#define PHI             15e-6   /* % допуск частоты (15 ppm) */
#define NSTAGE          8       /* ступени регистра часов */
#define NMAX            50      /* максимальное число партнёров */
#define NSANE           1       /* % минимальное пересечение оставшихся */
#define NMIN            3       /* % минимум оставшихся для кластера */

/*
 * Глобальные значения возврата
 */
#define TRUE            1       /* boolean true */
#define FALSE           0       /* boolean false */

/*
 * Коды возврата локального процесса часов
 */
#define IGNORE          0       /* игнорировать */
#define SLEW            1       /* настройка поправки */
#define STEP            2       /* настройка шага */
#define PANIC           3       /* паника - нет корректировки */

/*
 * Флаги системы
 */
#define S_FLAGS         0       /* любые системные флаги */
#define S_BCSTENAB      0x1     /* включение широковещательного клиента */

/*
 * Флаги партнёра 
 */
#define P_FLAGS         0       /* любые флаги партнёра */
#define P_EPHEM         0x01    /* ассоциация временна */
#define P_BURST         0x02    /* блоки (burst) разрешены */
#define P_IBURST        0x04    /* начальный блок разрешён */
#define P_NOTRUST       0x08    /* аутентифицированный доступ */
#define P_NOPEER        0x10    /* аутентифицированная активизация */
#define P_MANY          0x20    /* manycast-клиент */

/*
 * Коды проверки подлинности
 */
#define A_NONE          0       /* без аутентификации */
#define A_OK            1       /* успешная аутентификация */
#define A_ERROR         2       /* ошибка аутентификации */
#define A_CRYPTO        3       /* crypto-NAK */

/*
 * Коды состояния ассоциаций
 */
#define X_INIT          0       /* инициализация */
#define X_STALE         1       /* тайм-аут */
#define X_STEP          2       /* шаг времени */
#define X_ERROR         3       /* ошибка аутентификации */
#define X_CRYPTO        4       /* получено сообщение crypto-NAK */
#define X_NKEY          5       /* недоверенный ключ */

/*
 * Определения режимов протокола
 */
#define M_RSVD          0       /* резерв */
#define M_SACT          1       /* симметричный активный */
#define M_PASV          2       /* симметричный пассивный */
#define M_CLNT          3       /* клиент */
#define M_SERV          4       /* сервер */
#define M_BCST          5       /* широковещательный сервер */
#define M_BCLN          6       /* широковещательный клиент */

/*
 * Определения состояний часов
 */
#define NSET            0       /* часы не устанавливались */
#define FSET            1       /* частота установлена из файла */
#define SPIK            2       /* обнаружен всплеск (spike) */
#define FREQ            3       /* режим частоты */
#define SYNC            4       /* часы синхронизированы */

#define min(a, b)   ((a) < (b) ? (a) : (b))
#define max(a, b)   ((a) < (b) ? (b) : (a))

A.1.2. Структуры данных пакета

/*
 * Принимаемые и передаваемые пакеты могут включать необязательный код
 * MAC, состоящий из идентификатора ключа keyid и дайджеста сообщения
 * (mac в принимаемой структуре и dgst - в передаваемой). NTPv4 
 * поддерживает необязательные поля расширения между заголовком и MAC, 
 * но здесь это не описано.
 *
 * Приёмный пакет.
 *
 * Отметим, что метка времени dst не является частью самого пакета. Она
 * извлекается по прибытии и возвращается в приёмный буфер вместе с его
 * размером и данными. Некоторые из полей char сжимаются в заголовке, но
 * здесь это не рассматривается.
 */
struct r {
        ipaddr  srcaddr;        /* Адрес источника (удалённый) */
        ipaddr  dstaddr;        /* Адрес получателя (локальный) */
        char    version;        /* Номер версии */
        char    leap;           /* Индикатор високосных секунд */
        char    mode;           /* Режим */
        char    stratum;        /* Слой (stratum) */
        char    poll;           /* Интервал опроса */
        s_char  precision;      /* Точность */
        tdist   rootdelay;      /* Корневая задержка */
        tdist   rootdisp;       /* Корневая дисперсия */
        char    refid;          /* Идентификатор эталона */
        tstamp  reftime;        /* Время эталона */
        tstamp  org;            /* Метка времени источника */
        tstamp  rec;            /* Метка времени приёма */
        tstamp  xmt;            /* Метка времени передачи */
        int     keyid;          /* Идентификатор ключа */
        digest  mac;            /* Дайджест сообщения */
        tstamp  dst;            /* Метка времени получателя */
} r;

/*
 * Передаваемый пакет
 */
struct x {
        ipaddr  dstaddr;        /* Адрес источника (локальный) */
        ipaddr  srcaddr;        /* Адрес получателя (удалённый) */
        char    version;        /* Номер версии */
        char    leap;           /* Индикатор високосных секунд */
        char    mode;           /* Режим */
        char    stratum;        /* Слой (stratum) */
        char    poll;           /* Интервал опроса */
        s_char  precision;      /* Точность */
        tdist   rootdelay;      /* Корневая задержка */
        tdist   rootdisp;       /* Корневая дисперсия */
        char    refid;          /* Идентификатор эталона */
        tstamp  reftime;        /* Время эталона */
        tstamp  org;            /* Метка времени источника */
        tstamp  rec;            /* Метка времени приёма */
        tstamp  xmt;            /* Метка времени передачи */
        int     keyid;          /* Идентификатор ключа */
        digest  dgst;           /* Дайджест сообщения */
} x;

A.1.3. Структуры данных ассоциации

   /*
    * Структура ступени фильтра. Отметим, что t в этой и других структурах
    * указывает время процесса, а не реальное время. Время процесса 
    * увеличивается на 1 каждую секунду реального времени.
    */
   struct f {
           tstamp  t;              /* Время обновления */
           double  offset;         /* Смещение часов */
           double  delay;          /* Круговая задержка */
           double  disp;           /* Дисперсия */
   } f;

   /*
    * Структура ассоциации используемая процессами партнёра и опроса.
    */
   struct p {

           /*
            * Переменные, задаваемые в конфигурации.
            */
           ipaddr  srcaddr;        /* Адрес источника (удалённый) */
           ipaddr  dstaddr;        /* Адрес получателя (локальный) */
           char    version;        /* Номер версии */
           char    hmode;          /* Режим хоста */
           int     keyid;          /* Идентификатор ключа */
           int     flags;          /* Флаги опций */

           /*
            * Переменные, устанавливаемые принятым пакетом.
            */
           char    leap;           /* Индикатор високосных секунд */
           char    pmode;          /* Режим партнёра */
           char    stratum;        /* Слой (stratum) */
           char    ppoll;          /* Интервал опроса партнёра */
           double  rootdelay;      /* Корневая задержка */
           double  rootdisp;       /* Корневая дисперсия */
           char    refid;          /* Идентификатор эталона */
           tstamp  reftime;        /* Время эталона */
   #define begin_clear org         /* Начало чистой области */
           tstamp  org;            /* Метка времени источника */
           tstamp  rec;            /* Метка времени приёма */
           tstamp  xmt;            /* Метка времени передачи */

           /*
            * Расчётные данные
            */
           double  t;              /* Время обновления */
           struct f f[NSTAGE];     /* Фильтр часов */
           double  offset;         /* Смещение партнёра */
           double  delay;          /* Задержка партнёра */
           double  disp;           /* Дисперсия партнёра */
           double  jitter;         /* RMS для вариаций */

           /*
            * Переменные процесса опроса
            */
           char    hpoll;          /* Интервал опроса для хоста */
           int     burst;          /* Счётчик блоков (burst) */
           int     reach;          /* Регистр доступа */
           int     ttl;            /* ttl (manycast) */
   #define end_clear unreach       /* Конец чистой области */
           int     unreach;        /* Счётчик недоступности */
           int     outdate;        /* Время последнего опроса */
           int     nextdate;       /* Время следующего опроса */
   } p;

A.1.4. Структуры данных системы

   /*
    * Список, применяемый алгоритмом пересечения.
    */
   struct m {                      /* m применяется для Marzullo */
           struct p *p;            /* Указатель на структуру партнёра */
           int     type;           /* high +1, mid 0, low -1 */
           double  edge;           /* Граница интервала корректности */
   } m;

   /*
    * Список оставшихся, применяемый алгоритмом кластера.
    */
   struct v {
           struct p *p;            /* Указатель на структуру партнёра */
           double  metric;         /* Показатель сортировки */
   } v;

   /*
    * Системная структура
    */
   struct s {
           tstamp  t;              /* Время обновления */
           char    leap;           /* Индикатор високосных секунд */
           char    stratum;        /* Слой (stratum) */
           char    poll;           /* Интервал опроса */
           char    precision;      /* Точность */
           double  rootdelay;      /* Корневая задержка */
           double  rootdisp;       /* Корневая дисперсия */
           char    refid;          /* Идентификатор эталона */
           tstamp  reftime;        /* Время эталона */
           struct m m[NMAX];       /* Список кандидатов */
           struct v v[NMAX];       /* Список оставшихся */
           struct p *p;            /* Идентификатор ассоциации */
           double  offset;         /* Комбинированное смещение */
           double  jitter;         /* Комбинированные вариации */
           int     flags;          /* Флаги опций */
           int     n;              /* Число оставшихся */
   } s;

A.1.5. Структуры данных локальных часов

   /*
    * Структура локальных часов
    */
   struct c {
           tstamp  t;              /* Время обновления */
           int     state;          /* Текущее состояние*/
           double  offset;         /* Текущее смещение */
           double  last;           /* Предыдущее смещение*/
           int     count;          /* Счётчик качаний (jiggle) */
           double  freq;           /* Частота */
           double  jitter;         /* RMS для вариаций */
           double  wander;         /* RMS для дрейфа */
   } c;

A.1.6. Прототипы функций

  /*
   * Процесс партнёра 
   */
  void    receive(struct r *);    /* Приём пакета */
  void    packet(struct p *, struct r *); /* Обработка пакета */
  void    clock_filter(struct p *, double, double, double); /* Фильтр */
  double  root_dist(struct p *);  /* Расчёт корневой дистанции */
  int     fit(struct p *);        /* Определение пригодности сервера */
  void    clear(struct p *, int); /* Очистка ассоциации */
  int     access(struct r *);     /* Определение ограничений для доступа */

  /*
   * Системный процесс
   */
  int     main();                 /* Основная программа */
  void    clock_select();         /* Поиск лучших часов */
  void    clock_update(struct p *); /* Обновление системных часов */
  void    clock_combine();        /* Комбинирование смещений */

  /*
   * Процесс локальных часов
   */
  int     local_clock(struct p *, double); /* Дисциплина часов */
  void    rstclock(int, double, double); /* Смена состояния часов */

  /*
   * Процесс корректировки часов
   */
  void    clock_adjust();         /* Процесс 1-секундного таймера */

  /*
   * Процесс опроса
   */
  void    poll(struct p *);               /* Процесс опроса */
  void    poll_update(struct p *, int); /* Обновление интервала опроса */
  void    peer_xmit(struct p *);  /* Передача пакета */
  void    fast_xmit(struct r *, int, int); /* Передача пакета отклика */

  /*
   * Вспомогательные функции
   */
  digest  md5(int);               /* Создание дайджеста сообщения */
  struct p *mobilize(ipaddr, ipaddr, int, int, int, int); /* Активация */
  struct p *find_assoc(struct r *); /* Поиск в таблице ассоциаций */

  /*
   * Интерфейс с ядром
   */
  struct r *recv_packet();        /* Ожидание пакета */
  void    xmit_packet(struct x *); /* Передача пакета */
  void    step_time(double);      /* Шаг времени */
  void    adjust_time(double);    /* Корректировка (slew) времени */
  tstamp  get_time();             /* Считывание времени */

A.2. Основная программа и утилиты

/*
 * определения
 */
#define PRECISION       -18     /* Точность (log2 s)  */
#define IPADDR          0       /* Любой адрес IP */
#define MODE            0       /* Любой режим NTP */
#define KEYID           0       /* Любой идентификатор ключа */

/*
 * main() - основная программа
 */
int
main()
{
        struct p *p;            /* Указатель на структуру партнёра */
        struct r *r;            /* Указатель на принятый пакет */

        /*
         * Чтение опций команды и инициализация переменных системы. 
         * Эталонная реализация оценивает точность каждой машины, измеряя
         * приращение времени при считывании системных часов.
         */
        memset(&s, sizeof(s), 0);
        s.leap = NOSYNC;
        s.stratum = MAXSTRAT;
        s.poll = MINPOLL;
        s.precision = PRECISION;
        s.p = NULL;

        /*
         * Инициализация переменных локальных часов.
         */
        memset(&c, 0, sizeof(c));20
        if (/* файл частоты */ 0) {
                c.freq = /* freq */ 0;
                rstclock(FSET, 0, 0);
        } else {
                rstclock(NSET, 0, 0);
        }
        c.jitter = LOG2D(s.precision);

        /*
         * Чтение файла конфигурации и активация постоянных ассоциаций
         * с заданными адресами, версией, режимом, ключами и флагами.
         */
        while (/* активация настроенной ассоциации */ 0) {
                p = mobilize(IPADDR, IPADDR, VERSION, MODE, KEYID,
                    P_FLAGS);
        }

        /*
         * Запуск системного таймера, увеличивающегося 1 раз в секунду,
         * чтение прибывающих пакетов, создание меток приёма и вызов 
         * функции receive().
         */
        while (0) {
                r = recv_packet();
                r->dst = get_time();
                receive(r);
        }

        return(0);
}

/*
 * mobilize() - активация и инициализация ассоциации.
 */
struct p
*mobilize(
        ipaddr  srcaddr,        /* IP-адрес отправителя */
        ipaddr  dstaddr,        /* IP-адрес получателя */
        int     version,        /* Версия */
        int     mode,           /* Режим хоста */
        int     keyid,          /* Идентификатор ключа */
        int     flags           /* Флаги партнёра */
        )
{
        struct p *p;            /* Указатель на процесс партнёра */

        /*
         * Выделение и инициализация памяти для ассоциации.
         */
        p = malloc(sizeof(struct p));
        p->srcaddr = srcaddr;
        p->dstaddr = dstaddr;
        p->version = version;
        p->hmode = mode;
        p->keyid = keyid;
        p->hpoll = MINPOLL;
        clear(p, X_INIT);
        p->flags = flags;
        return (p);
}

/*
 * find_assoc() - найти соответствующую ассоциацию.
 */
struct p                        /* Указатель на структуру партнёра или NULL */
*find_assoc(
        struct r *r             /* Указатель на принятый пакет */
        )
{
        struct p *p;            /* Указатель на «фиктивную» (dummy) структуру партнёра */

        /*
         * Таблица поиска ассоциаций для сопоставления адреса и порта 
         * отправителя, а также режима.
         */
        while (/* все ассоциации */ 0) {
                if (r->srcaddr == p->srcaddr && r->mode == p->hmode)
                        return(p);
        }
        return (NULL);
}

/*
 * md5() - расчёт дайджеста сообщения.
 */
digest
md5(
       int     keyid           /* идентификатор ключа */
       )
{
       /*
        * Расчёт криптографического дайджеста сообщения с ключом. 
        * Идентификатор связывается с ключом в локальном кэше ключей. Ключ
        * помещается перед заголовком пакета и полями расширения, результат
        * хэшируется по алгоритму MD5, как указано в RFC 1321. Возвращается
        * код MAC, состоящий из 32-битового идентификатора ключа, 
        * объединённого (конкатенация) со 128-битовым дайджестом сообщения.
        */
       return (/* дайджест MD5 */ 0);
}

A.3. Интерфейс ввода-вывода ядра

   /*
    * Интерфейс с ядром для передачи и приёма пакетов, детали которого
    * зависят от операционной системы.
    *
    * recv_packet — получение пакета из сети.
    */
   struct r                        /* указатель на принятый пакет */
   *recv_packet() {
           return (/* принятый пакет r */ 0);
   }


   /*
    * xmit_packet — передача пакета в сеть.
    */
   void
   xmit_packet(
           struct x *x             /* указатель на передаваемый пакет */
           )
   {
           /* передача пакета x */
   }

A.4. Интерфейс системных часов ядра

/*
 * Утилиты системных часов
 *
 * Имеется 3 формата времени: native (Unix), NTP, floating double.
 * Функция get_time() возвращает время в формате NTP. Программы
 * Unix ожидают аргументов в виде структуры из двух 32-битовых слов
 * со знаком в секундах и микросекундах (timeval) или наносекундах
 * (timespec). Функции step_time() и adjust_time() ожидают аргументов
 * floating double со знаком. Упрощённый код здесь показан лишь для
 * иллюстрации и не проверялся.
 */
#define JAN_1970        2208988800UL /* 1970 - 1900 в секундах */

/*
 * get_time — чтение системного времени и преобразование в формат NTP.
 */
tstamp
get_time()
{
        struct timeval unix_time;

        /*
         * Функция вызывается в программе лишь дважды - один раз по
         * прибытии пакета из сети, другой - при включении в очередь на
         * передачу. Вызывает функцию ядра для времени суток (такую как
         * gettimeofday()) и преобразует значение в формат NTP.
         */
        gettimeofday(&unix_time, NULL);
        return (U2LFP(unix_time));
}

/*
 * step_time() - сдвиг системного времени на указанное смещение.
 */
void
step_time(
        double  offset          /* смещение часов */
        )
{
        struct timeval unix_time;
        tstamp  ntp_time;

        /*
         * Преобразование из формата double в native (со знаком) и
         * добавление к текущему времени. Отметим, что добавление 
         * происходит в естественном формате, чтобы избежать 
         * переполнения и потери точности.
         */
        gettimeofday(&unix_time, NULL);
        ntp_time = D2LFP(offset) + U2LFP(unix_time);
        unix_time.tv_sec = ntp_time >> 32;
        unix_time.tv_usec = (long)(((ntp_time - unix_time.tv_sec) <<
            32) / FRAC * 1e6);
        settimeofday(&unix_time, NULL);
}


/*
 * adjust_time() - сдвиг системных часов на указанное смещение.
 */
void
adjust_time(
        double  offset          /* смещение часов */
        )
{
        struct timeval unix_time;
        tstamp  ntp_time;

        /*
         * Преобразование из формата double в native (со знаком) и
         * добавление к текущему времени.
         */
        ntp_time = D2LFP(offset);
        unix_time.tv_sec = ntp_time >> 32;
        unix_time.tv_usec = (long)(((ntp_time - unix_time.tv_sec) <<
            32) / FRAC * 1e6);
        adjtime(&unix_time, NULL);
}

A.5. Партнёрский процесс

   /*
    * Пакет crypto-NAK включает заголовок NTP, за которым следует код MAC,
    * состоящий лишь из идентификатора ключа со значением 0. Это говорит 
    * получателю, что предыдущий запрос не был должным образом
    * аутентифицирован, но поля заголовка NTP корректны.
    *
    * Пакет kiss-o'-death содержит заголовок NTP с leap 0x3 (NOSYNC) и
    * stratum 16 (MAXSTRAT). Он говорит получателю, что произошло нечто
    * серьёзное, о чем говорит код kiss в поле refid. Другие поля
    * заголовка NTP могут быть некорректными.
    */
   /*
    * Параметры и константы процесса партнёра.
    */
   #define SGATE           3       /* spike gate (фильтр часов) */
   #define BDELAY          .004    /* широковещательная задержка (s) */

   /*
    * Dispatch codes
    */
   #define ERR             -1      /* Ошибка */
   #define DSCRD           0       /* Отбросить пакет */
   #define PROC            1       /* Обработать пакет */
   #define BCST            2       /* Широковещательный пакет */
   #define FXMIT           3       /* Пакет клиента */
   #define MANY            4       /* Пакет manycast */
   #define NEWPS           5       /* Новый симметричный пассивный клиент */
   #define NEWBC           6       /* Новый широковещательный клиент */

   /*
    * Матрица диспетчеризации
    *              active  passv  client server bcast */
   int table[7][5] = {
   /* nopeer  */   { NEWPS, DSCRD, FXMIT, MANY, NEWBC },
   /* active  */   { PROC,  PROC,  DSCRD, DSCRD, DSCRD },
   /* passv   */   { PROC,  ERR,   DSCRD, DSCRD, DSCRD },
   /* client  */   { DSCRD, DSCRD, DSCRD, PROC,  DSCRD },
   /* server  */   { DSCRD, DSCRD, DSCRD, DSCRD, DSCRD },
   /* bcast   */   { DSCRD, DSCRD, DSCRD, DSCRD, DSCRD },
   /* bclient */   { DSCRD, DSCRD, DSCRD, DSCRD, PROC}
   };

   /*
    * Прочие макросы
    *
    * Этот макрос определяет статус аутентификации. Значение x = 0 говорит
    * о  её необязательности, в иных случаях аутентификация требуется.
    */
   #define AUTH(x, y)      ((x) ? (y) == A_OK : (y) == A_OK || \
                               (y) == A_NONE)

   /*
    * Макросы для функции clear()
    */
   #define BEGIN_CLEAR(p)  ((char *)&((p)->begin_clear))
   #define END_CLEAR(p)    ((char *)&((p)->end_clear))
   #define LEN_CLEAR       (END_CLEAR((struct p *)0) - \
                               BEGIN_CLEAR((struct p *)0))

A.5.1. receive()

/*
 * receive() - приём пакета и декодирование режима.
 */
void
receive(
        struct r *r             /* Указатель на полученный пакет */
        )
{
        struct p *p;            /* Указатель на структуру партнёра */
        int     auth;           /* Код аутентификации */
        int     has_mac;        /* Размер MAC */
        int     synch;          /* Состояние синхронизации */

        /*
         * Проверяет списки контроля доступа, служащего для поддержки
         * списка разрешённых или запрещённых адресов IP. Могут быть
         * разные списки для аутентифицированных и неаутентифицированных
         * клиентов.
         */
        if (!access(r))
                return;                 /* Доступ отклонён */

        /*
         * Версия не должна быть в будущем. Проверка формата включает 
         * размера пакета, MAC и полей заголовка при их наличии.
         */
        if (r->version > VERSION /* или ошибка формата */)
                return;                 /* ошибка формата */

        /*
         * Условие аутентификации задаётся двумя параметрами на уровне
         * клиента
         * P_NOPEER     не активировать ассоциацию до аутентификации.
         * P_NOTRUST    не разрешать доступ  до аутентификации 
         *              (предполагает P_NOPEER).
         *
         * Выходные значения
         * A_NONE       пакет не включает MAC.
         * A_OK         пакет содержит MAC и аутентификация успешна.
         * A_ERROR      пакет имеет MAC, но проверка не прошла.
         * A_CRYPTO     crypto-NAK. MAC содержит лишь 4 октета.
         *
         * Примечание. Макрос AUTH (x, y) служит для фильтрации вывода. 
         * При x=0 приемлемыми результатами будут NONE и OK, при x=1 - OK.
         */

        has_mac = /* размер поля MAC */ 0;
        if (has_mac == 0) {
                auth = A_NONE;          /* не требуется */
        } else if (has_mac == 4) {
                auth = A_CRYPTO;       /* crypto-NAK */
        } else {
                if (r->mac != md5(r->keyid))
                        auth = A_ERROR; /* ошибка аутентификации */
                else
                        auth = A_OK;    /* проверка прошла */
        }

        /*
         * Поиск ассоциации и диспетчеризация кода. Если ассоциации не
         * найдено, предполагается p->hmode = NULL.
         */
        p = find_assoc(r);
        switch(table[(unsigned int)(p->hmode)][(unsigned int)(r->mode)])
        {

        /*
         * Пакет клиента без ассоциации. Передача отклика сервера без 
         * сохранения состояния.
         */
        case FXMIT:

                /*
                 * Для unicast-адреса получателя передача пакета сервера.
                 * При отказе аутентификации передача пакета crypto-NAK.
                 */

                /* Адрес получателя не групповой */21
                if (0) {
                        if (AUTH(p->flags & P_NOTRUST, auth))
                                fast_xmit(r, M_SERV, auth);
                        else if (auth == A_ERROR)
                                fast_xmit(r, M_SERV, A_CRYPTO);
                        return;         /* M_SERV packet sent */
                }

                /*
                 * Должно быть manycast. Отклик не передаётся, если нет
                 * синхронизации или stratum больше чем у manycast.
                 */
                if (s.leap == NOSYNC || s.stratum > r->stratum)
                        return;

                /*
                 * Отклик лишь при успешной аутентификации. Применяется
                 * адрес unicast, а не multicast.
                 */
                if (AUTH(p->flags & P_NOTRUST, auth))
                        fast_xmit(r, M_SERV, auth);
                return;

        /*
         * Новая временная ассоциация клиента manycast. Активизируется с
         * указанной в пакете версией. При отказе аутентификации пакет
         * игнорируется. Серверный пакет проверяется сравнением метки
         * r->org в пакете с меткой p->xmt в групповой клиентской 
         * ассоциации. При совпадении пакет сервера аутентичен.
         */

        case MANY:
                if (!AUTH(p->flags & (P_NOTRUST | P_NOPEER), auth))
                        return;         /* Ошибка аутентификации */

                p = mobilize(r->srcaddr, r->dstaddr, r->version, M_CLNT,
                    r->keyid, P_EPHEM);
                break;

       /*
        * Новая симметричная пассивная ассоциация.  Активизируется с
        * указанной в пакете версией. При отказе аутентификации передаётся 
        * пакет crypto-NAK. Если активация не разрешена, передаётся 
        * пакет симметричный активной ассоциации.
        */
        case NEWPS:
                if (!AUTH(p->flags & P_NOTRUST, auth)) {
                        if (auth == A_ERROR)
                                fast_xmit(r, M_SACT, A_CRYPTO);
                        return;         /* передача crypto-NAK */
                }
                if (!AUTH(p->flags & P_NOPEER, auth)) {
                        fast_xmit(r, M_SACT, auth);
                        return;         /* передача M_SACT */
                }
                p = mobilize(r->srcaddr, r->dstaddr, r->version, M_PASV,
                    r->keyid, P_EPHEM);
                break;

        /*
         * Новая широковещательная клиентская ассоциация. Активизируется с
         * указанной в пакете версией. При отказе аутентификации пакет
         * игнорируется. Отметим, что этот код не поддерживает начальный
         * блок передач (volley) в эталонной реализации.
         */
        case NEWBC:
                if (!AUTH(p->flags & (P_NOTRUST | P_NOPEER), auth))
                        return;         /* Ошибка аутентификации */

                if (!(s.flags & S_BCSTENAB))
                        return;         /* Широковещание не разрешено */

                p = mobilize(r->srcaddr, r->dstaddr, r->version, M_BCLN,
                    r->keyid, P_EPHEM);
                break;                  /* Обработка продолжается */

        /*
         * Обработка пакета (заглушка).
         */
        case PROC:
                break;                  /* Обработка продолжается */

        /*
         * Недействительная комбинация режимов. Это возникает лишь
         * для временных ассоциаций, поэтому корректно просто бросить.
         */
        case ERR:
                clear(p, X_ERROR);
                return;          /* Недействительная комбинация режимов */

        /*
         * Нет совпадения, пакет просто отбрасывается.
         */
        case DSCRD:
                return;                 /* Брошенный сирота */
        }

        /*
         * Далее выполняется строгое планирование проверки меток. Если
         * метка передачи имеет значение 0, сервер просто повреждён. 
         */
        if (r->xmt == 0)
                return;                 /* Недействительная метка */

        /*
         * Если метка дублирует предыдущую, пакет использован повторно.
         */
        if (r->xmt == p->xmt)
                return;                 /* Дубликат пакета */

        /*
         * Если это пакет широковещательного режима, проверка завершается.
         * Если метка источника 0, отправитель ещё не слышал нас. Иначе,
         * если метка не совпадает с меткой передачи, пакет фальшивый.
         */
        synch = TRUE;
        if (r->mode != M_BCST) {
                if (r->org == 0)
                        synch = FALSE;  /* Не синхронизировано */
                else if (r->org != p->xmt)
                        synch = FALSE;  /* фиктивный пакет */
        }

        /*
         * Обновление меток источника и получателя. Если нет
         * синхронизации или пакет фиктивный, доставка прерывается.
         */
        p->org = r->xmt;
        p->rec = r->dst;
        if (!synch)
                return;                 /* нет синхронизации */

        /*
         * Метка действительная и принятый пакет соответствует последнему
         * переданному. Пакет crypto-NAK может говорить о смене ключей
         * сервером. Ассоциация деактивируется до лучших времён.
         */
        if (auth == A_CRYPTO) {
                clear(p, X_CRYPTO);
                return;                 /* crypto-NAK */
        }

        /*
         * Если ассоциация аутентифицирована, key ID отличен от 0 и 
         * принятый должен аутентифицироваться. Это предназначено для
         * предотвращения атак bait-and-switch (заманить и подменить),
         * возможных в прежних версиях.
         */
        if (!AUTH(p->keyid || (p->flags & P_NOTRUST), auth))
                return;                 /* bad auth */

        /*
         * Сделано всё возможное для проверки меток времени и 
         * предотвращения возможности нарушить работу протокола или
         * внедрить фиктивные данные.
         */
        packet(p, r);
}
A.5.1.1. packet()
/*
 * packet() - обработка пакета и расчёт смещения, задержки и дисперсии.
 */
void
packet(
        struct p *p,            /* Указатель на структуру партнёра */
        struct r *r             /* Указатель на полученный пакет */
        )
{
        double  offset;         /* Смещение выборки */
        double  delay;          /* Задержка выборки */
        double  disp;           /* Дисперсия выборки */

        /*
         * Пакет действителен, рассматриваются остальные поля заголовка.
         * Отметим, что stratum 0 (не задано) отображается на MAXSTRAT
         * для упрощения сравнения слоёв и обеспечения естественного
         * интерфейса с драйверами радиочасов, работающими со stratum 0.
         */
        p->leap = r->leap;
        if (r->stratum == 0)
                p->stratum = MAXSTRAT;
        else
                p->stratum = r->stratum;
        p->pmode = r->mode;
        p->ppoll = r->poll;
        p->rootdelay = FP2D(r->rootdelay);
        p->rootdisp = FP2D(r->rootdisp);
        p->refid = r->refid;
        p->reftime = r->reftime;

        /*
         * Проверка синхронизации сервера с действительным слоем и того,
         * что время эталона не позднее времени передачи.
         */
        if (p->leap == NOSYNC || p->stratum >= MAXSTRAT)
                return;                 /* нет синхронизации */

        /*
         * Проверка пригодности корневой дистанции.22
         */
        if (p->rootdelay / 2 + p->rootdisp >= MAXDISP || p->reftime >
            r->xmt)
                return;                 /* Непригодные значения заголовка */

        poll_update(p, p->hpoll);
        p->reach |= 1;

        /*
         * Расчёт смещения, задержки и дисперсии и передача их фильтру
         * часов. Отметим подразумеваемую обработку. Разность первого
         * порядка определяется напрямую в 64-битовой арифметике и
         * результат преобразуется в floating double. Дальнейшая обработка
         * использует арифметику floating double с аппаратным округлением.
         * Это нужно для предотвращения переполнений и потери точности.
         *
         * Расчёт задержки является особым случаем. Если часы сервера и
         * клиента работают с разной скоростью, а сеть очень быстрая,
         * задержка может стать отрицательной. Для предотвращения проблем
         * задержка должна быть не меньше точности системы23.
         */
        if (p->pmode == M_BCST) {
                offset = LFP2D(r->xmt - r->dst);
                delay = BDELAY;
                disp = LOG2D(r->precision) + LOG2D(s.precision) + PHI *
                    2 * BDELAY;
        } else {
                offset = (LFP2D(r->rec - r->org) + LFP2D(r->xmt -
                    r->dst)) / 2;
                delay = max(LFP2D(r->dst - r->org) - LFP2D(r->xmt -
                    r->rec), LOG2D(s.precision));
                disp = LOG2D(r->precision) + LOG2D(s.precision) + PHI *
                    LFP2D(r->dst - r->org);
        }
        clock_filter(p, offset, delay, disp);
}

A.5.2. clock_filter()

/*
 * clock_filter(p, offset, delay, dispersion) — выбор лучшей из 8 последних 
 * выборок задержка/смещения.
 */
void
clock_filter(
        struct p *p,            /* Указатель на структуру партнёра */
        double  offset,         /* Смещение часов */
        double  delay,          /* Круговая задержка */
        double  disp            /* Дисперсия */
        )
{
        struct f f[NSTAGE];     /* Сортированный список */
        double  dtemp;
        int     i;

        /*
         * Фильтр часов включает 8 квартетов (offset, delay, dispersion,
         * time). Выполняется сдвиг на 1 квартет влево с отбрасыванием
         * левого квартета. При сдвиге каждого квартета дисперсия растёт 
         * поскольку обновляется последний фильтр. Одновременно каждый
         * квартет копируется во временный список, а потом offset, delay,
         * disp, time) помещается в пустую позицию справа.
         */
        for (i = 1; i < NSTAGE; i++) {
                p->f[i] = p->f[i - 1];
                p->f[i].disp += PHI * (c.t - p->t);
                f[i] = p->f[i];
        }
        p->f[0].t = c.t;
        p->f[0].offset = offset;
        p->f[0].delay = delay;
        p->f[0].disp = disp;
        f[0] = p->f[0];

        /*
         * Сортировка временного списка по росту f[].delay. Первая запись
         * сортированного списка указывает лучшую выборку, но может быть
         * старой.
         */
        dtemp = p->offset;
        p->offset = f[0].offset;
        p->delay = f[0].delay;
        for (i = 0; i < NSTAGE; i++) {
                p->disp += f[i].disp / (1 << (i + 1));24
                p->jitter += SQUARE(f[i].offset - f[0].offset);
        }
        p->jitter = max(SQRT(p->jitter), LOG2D(s.precision));

        /*
         * Применять выборку лишь один раз и никогда не применять выборку
         * старше последней, но сделанной до синхронизации.
         */
        if (f[0].t - p->t <= 0 && s.leap != NOSYNC)
                return;

        /*
         * Сравниваются разность последнего и текущего смещения с текущим
         * значением jitter). Если разность больше SGATE (3) и интервал с
         * момента получения последнего смещения меньше удвоенного
         * интервала опроса, всплеск отбрасывается. Иначе, если не в режиме
         * burst, выбираются истинные часы.
         */
        if (fabs(p->offset - dtemp) > SGATE * p->jitter && (f[0].t -
            p->t) < 2 * s.poll)
                return;

        p->t = f[0].t;
        if (p->burst == 0)
                clock_select();
        return;
}

/*
 * fit() - проверка пригодности ассоциации p для синхронизации.
 */
int
fit(
        struct p *p             /* Указатель на структуру партнёра */
        )
{
        /*
         * Ошибка stratum, если (1) сервер не был синхронизирован, 
         * (2) слой сервера недействителен.
         */
        if (p->leap == NOSYNC || p->stratum >= MAXSTRAT)
                return (FALSE);

        /*
         * Ошибка дистанции возникает, если корневая дистанция 
         * превышает порог плюс один интервал опроса.
         */
        if (root_dist(p) > MAXDIST + PHI * LOG2D(s.poll))
                return (FALSE);

        /*
         * Петля (ошибка), если удалённый партнёр синхронизирован с
         * локальным или с текущим партнёром системы. Отметим, что это
         * относится к IPv4, а для IPv6 применяется хэш MD5.
         */
        if (p->refid == p->dstaddr || p->refid == s.refid)
                return (FALSE);

        /*
         * Ошибка доступности возникает, если сервер недоступен.
         */
        if (p->reach == 0)
                return (FALSE);

        return (TRUE);
}

/*
 * clear() - повторная инициализация ассоциации, деактивация
 * временной ассоциации.
 */
void
clear(
        struct p *p,            /* Указатель на структуру партнёра */
        int     kiss            /* kiss-код */
        )
{
        int i;

        /*
         * Сначала возвращаются все ресурсы. Типовые ресурсы не указаны
         * здесь, но включают динамически созданные структуры для ключей,
         * сертификатов и т. п. Если ассоциация временная и нет  
         * повторной инициализации, просто возвращается память ассоциации.
         */
        /* Возврат ресурсов */
        if (s.p == p)
                s.p = NULL;
        if (kiss != X_INIT && (p->flags & P_EPHEM)) {
                free(p);
                return;
        }

        /*
         * Инициализация полей ассоциации для общего сброса.
         */
        memset(BEGIN_CLEAR(p), LEN_CLEAR, 0);
        p->leap = NOSYNC;
        p->stratum = MAXSTRAT;
        p->ppoll = MAXPOLL;
        p->hpoll = MINPOLL;
        p->disp = MAXDISP;
        p->jitter = LOG2D(s.precision);
        p->refid = kiss;
        for (i = 0; i < NSTAGE; i++)
                p->f[i].disp = MAXDISP;

        /*
         * Первый опрос делается случайным на случай одновременного
         * возникновения тысяч широковещательных клиентов после 
         * долгого отсутствия широковещательного сервера.
         */
        p->outdate = p->t = c.t;
        p->nextdate = p->outdate + (random() & ((1 << MINPOLL) - 1));
}

A.5.3. fast_xmit()

/*
 * fast_xmit() - передача отклика на принятый пакет r
 */
void
fast_xmit(
        struct r *r,            /* Указатель на полученный пакет */
        int     mode,           /* Режим ассоциации */
        int     auth            /* Код аутентификации */
        )
{
        struct x x;

        /*
         * Инициализация заголовка и метки времени передачи. Отметим, что
         * поле version копируется из принятого пакета для совместимости
         * с прежними версиями.
         */
        x.version = r->version;
        x.srcaddr = r->dstaddr;
        x.dstaddr = r->srcaddr;
        x.leap = s.leap;
        x.mode = mode;
        if (s.stratum == MAXSTRAT)
                x.stratum = 0;
        else
                x.stratum = s.stratum;
        x.poll = r->poll;
        x.precision = s.precision;
        x.rootdelay = D2FP(s.rootdelay);
        x.rootdisp = D2FP(s.rootdisp);
        x.refid = s.refid;
        x.reftime = s.reftime;
        x.org = r->xmt;
        x.rec = r->dst;
        x.xmt = get_time();

        /*
         * Если код аутентификации имеет значение A.NONE, включается лишь
         * заголовок, при A.CRYPTO передаётся crypto-NAK, для A.OK -
         * действительный код MAC. Используется key ID из принятого пакета
         * и ключ из локального кэша.
         */
        if (auth != A_NONE) {
                if (auth == A_CRYPTO) {
                        x.keyid = 0;
                } else {
                        x.keyid = r->keyid;
                        x.dgst = md5(x.keyid);
                }
        }
        xmit_packet(&x);
}

A.5.4. access()

 /*
  * access() - задаёт ограничения при доступе.
  */
 int
 access(
         struct r *r             /* Указатель на полученный пакет */
         )
 {
         /*
          * Список контроля доступа — это неупорядоченный набор кортежей
          * из адреса, маски и слова ограничения, содержащего определённые  
          * биты. В списке отыскивается первое совпадение по адресу
          * отправителя (r->srcaddr) и возвращаются заданные ограничения.
          */
         return (/* биты доступа */ 0);
 }

A.5.5. Системный процесс

A.5.5.1. clock_select()
/*
 * clock_select() - поиск лучших часов
 */
void
clock_select() {
       struct p *p, *osys;     /* Указатели на структуры партнёров */
       double  low, high;      /* Протяжённость интервалов корректности */
       int     allow, found, chime; /* Применяется алгоритмом пересечения */
       int     n, i, j;

        /*
         * Сначала исключаются из набора серверов ложные часы и остаются
         * лишь истинные. Интервалом корректности для ассоциации p служит
         * интервал от offset - root_dist() до offset + root_dist(). 
         * Задача состоит в отборе кандидатов, т. е. поиске пересечения 
         * интервалов корректности числом более половины набора серверов.
         *
         * Сначала создаётся список триплетов (p, type, edge), как показано
         * ниже, затем список сортируется по росту edge.25
         */
        osys = s.p;
        s.p = NULL;
        n = 0;
        while (fit(p)) {
                s.m[n].p = p;
                s.m[n].type = +1;
                s.m[n].edge = p->offset + root_dist(p);
                n++;
                s.m[n].p = p;
                s.m[n].type = 0;
                s.m[n].edge = p->offset;
                n++;
                s.m[n].p = p;
                s.m[n].type = -1;
                s.m[n].edge = p->offset - root_dist(p);
                n++;
        }

        /*
         * Поиск наибольшего непрерывного пересечения интервалов 
         * корректности. Значение allow указывает число разрешённых 
         * ложных часов, found - число найденных midpoint. Отметим, что
         * значения edge ограничены диапазоном +-(2 ^ 30) < +-2e9 
         * расчётами меток времени.
         */
        low = 2e9; high = -2e9;
        for (allow = 0; 2 * allow < n; allow++) {

                /*
                 * Сканирование списка кандидатов от низшего в высшему
                 * для поиска низшей конечной точки.26
                 */
                found = 0;
                chime = 0;
                for (i = 0; i < n; i++) {
                        chime -= s.m[i].type;
                        if (chime >= n - allow) {
                                low = s.m[i].edge;
                                break;
                        }
                        if (s.m[i].type == 0)
                                found++;
                }

                /*
                 * Сканирование списка кандидатов от высшего к низшему 
                 * для поиска высшей конечной точки.
                 */
                chime = 0;
                for (i = n - 1; i >= 0; i--) {
                        chime += s.m[i].type;
                        if (chime >= n - allow) {
                                high = s.m[i].edge;
                                break;
                        }
                        if (s.m[i].type == 0)
                                found++;
                }

                /*
                 * Если число midpoint больше числа разрешённых ложных
                 * часов, пересечение включает хотя бы одни истинные часы
                 * без midpoint. В этом случае инкрементируется число
                 * разрешённых ложных часов и процесс повторяется. Если это
                 * не так и пересечение не пусто, заявляется успех.
                 */
                if (found > allow)
                        continue;

                if (high > low)
                        break;
        }

        /*
         * Алгоритм кластеризации, создающий список оставшихся пар (p,
         * metric) из списка кандидатов, где metric определяется первым
         * по stratum, затем по корневой дистанции. При прочих равных это
         * задаёт порядок предпочтения.
         */
        s.n = 0;
        for (i = 0; i < n; i++) {
                if (s.m[i].edge < low || s.m[i].edge > high)
                        continue;

                p = s.m[i].p;
                s.v[n].p = p;
                s.v[n].metric = MAXDIST * p->stratum + root_dist(p);
                s.n++;
        }

        /*
         * Для соблюдения утверждений о корректности должно остаться 
         * хотя бы NSANE кандидатов. Исходно византийский критерий 
         * требует 4 оставшихся, но для демонстрации достаточно 1.
         */
        if (s.n < NSANE)
                return;

        /*
         * Для каждой ассоциации p поочередно рассчитывается выбор
         * jitter p->sjitter как квадратного корня из суммы квадратов
         * (p->offset - q->offset) для всех q ассоциаций. Идея состоит в
         * повторяющемся отбрасывании оставшихся с максимальной вариацией, 
         * пока не будут выполнены условия завершения.
         */
        while (1) {
                struct p *p, *q, *qmax; /* Указатели на структуры партнёров */
                double  max, min, dtemp;

                max = -2e9; min = 2e9;
                for (i = 0; i < s.n; i++) {
                        p = s.v[i].p;
                        if (p->jitter < min)
                                min = p->jitter;
                        dtemp = 0;
                        for (j = 0; j < n; j++) {
                                q = s.v[j].p;
                                dtemp += SQUARE(p->offset - q->offset);
                        }
                        dtemp = SQRT(dtemp);
                        if (dtemp > max) {
                                max = dtemp;
                                qmax = q;
                        }
                }

                /*
                 * Если максимальная вариация выбора меньше минимальной
                 * вариации партнёра, дополнительное отбрасывание не 
                 * повысит минимальную вариацию партнёра, поэтому можно
                 * остановиться. Для уверенности в сохранении достаточного
                 * для алгоритма кластеризации числа оставшихся процесс
                 * завершается, если их число не превышает NMIN (3).
                 */
                if (max < min || n <= NMIN)
                        break;

                /*
                 * Удаление оставшегося с qmax и повтор процесса.
                 */
                s.n--;
        }

        /*
         * Выбор лучших часов. Если прежний партнёр системы имеется в
         * списке с тем же слоем, что и у первого в списке, часы не 
         * обновляются. Иначе выбирается первый оставшийся как новый
         * партнёр системы.
         */
        if (osys->stratum == s.v[0].p->stratum)
                s.p = osys;
        else
                s.p = s.v[0].p;
        clock_update(s.p);
}
A.5.5.2. root_dist()
/*
 * root_dist() - расчёт корневой дистанции.
 */
double
root_dist(
        struct p *p             /* Указатель на структуру партнёра */
        )
{

        /*
         * Корневой дистанцией синхронизации служит максимальная ошибка
         * из-за всех причин локальных часов относительно первичного
         * сервера. Она определяется как половина суммы общей задержки,
         * общей дисперсии и вариации партнера.
         */
        return (max(MINDISP, p->rootdelay + p->delay) / 2 +
            p->rootdisp + p->disp + PHI * (c.t - p->t) + p->jitter);
}
A.5.5.3. accept()
/*
 * accept() - проверка пригодности ассоциации p для синхронизации.
 */
int
accept(
        struct p *p             /* Указатель на структуру партнёра */
        )
{
        /*
         * Ошибка stratum возникает, если (1) сервер не синхронизирован,
         * (2) слой сервера не действителен.
         */
        if (p->leap == NOSYNC || p->stratum >= MAXSTRAT)
                return (FALSE);

        /*
         * Ошибка дистанции возникает, если корневая дистанция 
         * превышает порог плюс один интервал опроса.
         */
        if (root_dist(p) > MAXDIST + PHI * LOG2D(s.poll))
                return (FALSE);

        /*
         * Петля (ошибка), если удалённый партнёр синхронизирован с
         * локальным или с текущим партнёром системы. Отметим, что это
         * относится к IPv4, а для IPv6 применяется хэш MD5.
         */
        if (p->refid == p->dstaddr || p->refid == s.refid)
                return (FALSE);

        /*
         * Ошибка доступности возникает, если сервер недоступен.
         */
        if (p->reach == 0)
                return (FALSE);

        return (TRUE);
}
A.5.5.4. clock_update()
/*
 * clock_update() - обновление системных часов.
 */
void
clock_update(
        struct p *p             /* Указатель на структуру партнёра */
        )
{
        double dtemp;

        /*
         * Старое обновление, например, в результате смены партнёра системы
         * не выполняется. Старые и совпадающие выборки не применяются.
         */
        if (s.t >= p->t)
                return;

        /*
         * Объединение оставшихся смещения и обновление системных часов,
         * функция local_clock() будет указывать результат.
         */
        s.t = p->t;
        clock_combine();
        switch (local_clock(p, s.offset)) {

        /*
         * Смещение слишком велико и может быть фиктивным. Это вносится в
         * журнал системы и оператор оповещается для установки часов 
         * вручную в диапазоне PANIC. Эталонная реализация включает опции
         * команды для отключения этой проверки и смены порога паники,
         * принятого по умолчанию (1000 секунд).
         */
        case PANIC:
                exit (0);

        /*
         * Смещение больше шага ступени (0,125 сек по умолчанию). После 
         * применения шага все ассоциации будут иметь несогласованные 
         * значения времени, поэтому они сбрасываются и запускаются снова.
         * Порог шага можно изменить в эталонной реализации для снижения
         * вероятности того, что часы могут быть переведены обратно.
         * Однако возможны серьёзные последствия, как отмечено в 
         * публикации на сайте проекта NTP.
         */
        case STEP:
                while (/* all associations */ 0)
                        clear(p, X_STEP);
                s.stratum = MAXSTRAT;
                s.poll = MINPOLL;
                break;

        /*
         * Смещение меньше порога шага, что является обычным делом. 
         * Системные переменные обновляются по переменным партнёра. 
         * Нижний предел роста дисперсии служит для предотвращения
         * петель и скачков часов при вступлении в игру прецизионных
         * источников. Предел можно сменить с принятого по умолчанию 
         * значения 0,01 сек в эталонной реализации.
         */
        case SLEW:
                s.leap = p->leap;
                s.stratum = p->stratum + 1;
                s.refid = p->refid;
                s.reftime = p->reftime;
                s.rootdelay = p->rootdelay + p->delay;
                dtemp = SQRT(SQUARE(p->jitter) + SQUARE(s.jitter));
                dtemp += max(p->disp + PHI * (c.t - p->t) +
                    fabs(p->offset), MINDISP);
                s.rootdisp = p->rootdisp + dtemp;
                break;

        /*
         * некоторые выборки отбрасываются, хотя, например, прямое
         * измерение частоты происходит.
         */
        case IGNORE:
                break;
        }
}
A.5.5.5. clock_combine()
/*
 * clock_combine() - объединение смещений.
 */
void
clock_combine()
{
        struct p *p;            /* Указатель на структуру партнёра */
        double x, y, z, w;
        int     i;

        /*
         * Объединение смещений, оставшихся после алгоритма кластеризации,
         * с использованием взвешенного среднего по весу, определяемому
         * корневой дистанцией. Расчёт вариаций выбора как взвешенная RMS
         * разница между первым и остальными кандидатами. В некоторых
         * случаях наследуемые вариации часов можно снизить, отказавшись от
         * этого алгоритма, особенно при частом переводе часов. Эталонную
         * реализацию можно настроить на отказ от этого алгоритма указанием
         * предпочтительного партнёра. 
         */
        y = z = w = 0;
        for (i = 0; s.v[i].p != NULL; i++) {
                p = s.v[i].p;
                x = root_dist(p);
                y += 1 / x;
                z += p->offset / x;
                w += SQUARE(p->offset - s.v[0].p->offset) / x;
        }
        s.offset = z / y;
        s.jitter = SQRT(w / y);
}
A.5.5.6. local_clock()
/*
 * Параметры и константы дисциплины часов.
 */
#define STEPT           .128    /* Порог шага (s) */
#define WATCH           900     /* Порог ступени (stepout) (s) */
#define PANICT          1000    /* Порог паники (s) */
#define PLL             65536   /* Усиление контура PLL */
#define FLL             MAXPOLL + 1 /* Усиление контура FLL */
#define AVG             4       /* Константа усреднения параметров */
#define ALLAN           1500    /* Компрометация перехвата Allan (s) */
#define LIMIT           30      /* Порог корректировки опроса */
#define MAXFREQ         500e-6  /* Допуск частоты (500 ppm) */
#define PGATE           4       /* Диапазон корректировки опроса */

/*
 * local_clock() - дисциплина локальных часов.
 */
int                             /* код завершения */
local_clock(
        struct p *p,            /* Указатель на структуру партнёра */
        double  offset          /* Смещение часов из combine() */
        )
{
        int     state;          /* Статус дисциплины часов */
        double  freq;           /* Частота */
        double  mu;             /* Интервал с последнего обновления */
        int     rval;
        double  etemp, dtemp;

        /*
         * Отказ и возврат при слишком большом смещении.
         */
        if (fabs(offset) > PANICT)
                return (PANIC);

        /*
         * Функция смены состояния конечного автомата. Именно здесь 
         * выполняется действие и определяется реакция системы на 
         * слишком большие ошибки времени и частоты. Есть 2 основных
         * режима в зависимости от превышения порога шага (ступени).
         */
        rval = SLEW;
        mu = p->t - s.t;
        freq = 0;
        if (fabs(offset) > STEPT) {
                switch (c.state) {

                /*
                 * В состоянии S_SYNC игнорируется первый всплеск и статус
                 * меняется на S_SPIK.
                 */
                case SYNC:
                        state = SPIK;
                        return (rval);

                /*
                 * В состоянии S_FREQ игнорируются всплески и провалы. При
                 * первом всплеске после порога stepout рассчитывается 
                 * коррекция частоты и шаг времени.
                 */
                case FREQ:
                        if (mu < WATCH)
                                return (IGNORE);

                        freq = (offset - c.offset) / mu;
                        /* переход в S_SPIK */

                /*
                 * В состоянии S_SPIK игнорируются последующие всплески, 
                 * пока не будет найден выступ или превышен порог stepout.
                 */
                case SPIK:
                        if (mu < WATCH)
                                return (IGNORE);

                        /* Возврат к принятому по умолчанию */

                /*
                 * По умолчанию сюда попадают в состоянии S_NSET и S_FSET,
                 * в также сверху в состоянии S_FREQ. Применяется шаг 
                 * времени и снижается интервал опроса.
                 *
                 * В S_NSET исходная корректировка частоты недоступна
                 * обычно по причине того, что файл частоты ещё не записан.
                 * Поскольку время не попадает в диапазон захвата,
                 * применяется шаг часов. Частота устанавливается напрямую
                 * после интервала stepout.
                 *
                 * В S_FSET исходная корректировка частоты выполняется из
                 * файла. Поскольку время не попадает в диапазон захвата,
                 * часы переводятся незамедлительно, а не по истечении
                 * интервала stepout. Если первый перевод часов занимает
                 * 17 минут, люди начинают нервничать.
                 *
                 * В S_SPIK превышен порог stepout и фаза остаётся выше
                 * порога шага. Отметим, что один пик выше порога шага
                 * всегда подавляется даже при более длинных интервалах
                 * опроса.
                 */
                default:

                        /*
                         * Функция установки времени ядра обычно 
                         * через системный вызов Unix settimeofday().
                         */
                        step_time(offset);
                        c.count = 0;
                        s.poll = MINPOLL;
                        rval = STEP;
                        if (state == NSET) {
                                rstclock(FREQ, p->t, 0);
                                return (rval);
                        }
                        break;
                }
                rstclock(SYNC, p->t, 0);
        } else {

                /*
                 * Расчёт вариаций часов как RMS экспоненциально взвешенных
                 * разностей смещения. Применяется кодом настройки опроса.
                 */
                etemp = SQUARE(c.jitter);
                dtemp = SQUARE(max(fabs(offset - c.last),
                    LOG2D(s.precision)));
                c.jitter = SQRT(etemp + (dtemp - etemp) / AVG);
                switch (c.state) {

                /*
                 * В S_NSET это первое полученное обновление и частота ещё
                 * не инициализирована. Первым делом напрямую измеряется
                 * частота тактового генератора.
                 */
                case NSET:
                        rstclock(FREQ, p->t, offset);
                        return (IGNORE);

                /*
                 * В S_FSET это первое полученное обновление и частота ещё
                 * не инициализирована. Настраивается фаза, но частота не
                 * настраивается до следующего обновления.
                 */
                case FSET:
                        rstclock(SYNC, p->t, offset);
                        break;

                /*
                 * В S_FREQ обновления игнорируются до достижения порога
                 * stepout. После этого корректировка фазы и частоты с
                 * переходом в S_SYNC.
                 */
                case FREQ:
                        if (c.t - s.t < WATCH)
                                return (IGNORE);

                        freq = (offset - c.offset) / mu;
                        break;

                /*
                 * Сюдя по умолчанию попадают в состоянии S_SYNC и S_SPIK.
                 * Рассчитывается обновление частоты по данным PLL и FLL.
                 */
                default:

                        /*
                         * Константы FLL и PLL для изменения частоты 
                         * зависят от интервала опроса и перехвата Allan
                         * FLL не применяется ниже половины перехвата 
                         * Allan. Выше него усиление контура растёт с
                         * шагом 1 / AVG.
                         */
                        if (LOG2D(s.poll) > ALLAN / 2) {
                                etemp = FLL - s.poll;
                                if (etemp < AVG)
                                        etemp = AVG;
                                freq += (offset - c.offset) / (max(mu,
                                    ALLAN) * etemp);
                        }

                        /*
                         * Для PLL интервалом интеграции (numerator)  
                         * служит минимальное из значений интервалов
                         * обновления и опроса. Это разрешает более частые
                         * избыток выборок, но не их недостаток.
                         */
                        etemp = min(mu, LOG2D(s.poll));
                        dtemp = 4 * PLL * LOG2D(s.poll);
                        freq += offset * etemp / (dtemp * dtemp);
                        rstclock(SYNC, p->t, offset);
                        break;
                }
        }

        /*
         * Расчёт новой частоты и её стабильности (дрейф). Расчёт дрейфа
         * часов как RMS экспоненциально взвешенных разностей частот. Это
         * не применяется напрямую, но вместе с вариациями может быть очень
         * полезно для мониторинга и отладки.
         */
        freq += c.freq;
        c.freq = max(min(MAXFREQ, freq), -MAXFREQ);
        etemp = SQUARE(c.wander);
        dtemp = SQUARE(freq);
        c.wander = SQRT(etemp + (dtemp - etemp) / AVG);

        /*
         * Настраивается интервал опроса путём сравнения текущего смещения
         * с вариациями часов. Если смещение меньше, значения вариаций 
         * часов, умноженного на константу, средний интервал увеличивается,
         * иначе снижается. Небольшой гистерезис повысит стабильность.
         * лучше всего это работает в режиме burst.
         */
        if (fabs(c.offset) < PGATE * c.jitter) {
                c.count += s.poll;
                if (c.count > LIMIT) {
                        c.count = LIMIT;
                        if (s.poll < MAXPOLL) {
                                c.count = 0;
                                s.poll++;
                        }
                }
        } else {
                c.count -= s.poll << 1;
                if (c.count < -LIMIT) {
                        c.count = -LIMIT;
                        if (s.poll > MINPOLL) {
                                c.count = 0;
                                s.poll--;
                        }
                }
        }
        return (rval);
}
A.5.5.7. rstclock()
  /*
   * rstclock() - конечный автомат часов.
   */
  void
  rstclock(
          int     state,          /* Новое состояние */
          double  offset,         /* Новое смещение */
          double  t               /* Новое время обновления */
          )
  {
          /*
           * Переход в новое состояние и установка переменных состояния.
           * Отметим, что применяется время последней выборки фильтра 
           * часов, которое должно быть раньше текущего времени.
           */
          c.state = state;
          c.last = c.offset = offset;
          s.t = t;
  }

A.5.6. Процесс корректировки часов

A.5.6.1. clock_adjust()
 /*
  * clock_adjust() - запускается с интервалом в 1 секунду.
  */
 void
 clock_adjust() {
         double  dtemp;

         /*
          * Обновление времени процесса c.t и увеличение дисперсии с
          * момента последнего обновления. В отличие от NTPv3, NTPv4 не
          * заявляет отсутствие синхронизации по истечении суток, 
          * поскольку для этого служит порог дисперсии. Когда дисперсия
          * превышает MAXDIST (1 s), сервер считается неподходящим
          * для синхронизации.
          */
         c.t++;
         s.rootdisp += PHI;

         /*
          * Настройка фазы и частоты. Коэффициент усиления (denominator)
          * не разрешается увеличивать сверх перехвата Allan. Не имеет 
          * смысла усреднять фазовый шум за пределами этой точки и это
          * помогает демпфировать остаточное смещение при больших
          * интервалах опроса.
          */
         dtemp = c.offset / (PLL * min(LOG2D(s.poll), ALLAN));
         c.offset -= dtemp;

         /*
          * Функция корректировки времени ядра, обычно реализуемая 
          * системным вызовом Unix adjtime().
          */
         adjust_time(c.freq + dtemp);

         /*
          * Таймер партнёра, вызывающий функцию poll() по завершении.
          */
         while (/* all associations */ 0) {
                 struct p *p;/* Фиктивный указатель на структуру партнёра */

                 if (c.t >= p->nextdate)
                         poll(p);
         }

         /*
          * Один раз в час записывает частоту часов в файл.
          */
         /*
          * if (c.t % 3600 == 3599)
          *   запись c.freq в файл
          */
 }

A.5.7. Процесс опроса

   /*
    * Параметры и константы процесса опроса.
    */
   #define UNREACH         12      /* Порог счётчика недоступности */
   #define BCOUNT          8       /* Число пакетов в блоке (burst) */
   #define BTIME           2       /* Интервал между блоками (s) */
A.5.7.1. poll()
/*
 * poll() - определяет момент передачи пакета для ассоциации p
 */
void
poll(
        struct p *p     /* Указатель на структуру партнёра */
        )
{
        int     hpoll;
        int     oreach;

        /*
         * Эта функция вызывается, когда текущее время c.t догоняет время
         * следующего опроса p->nextdate. Значение p->outdate указывает
         * время последнего вызова функции. Время следующего выполнения 
         * p->nextdate задаёт функция poll_update().
         *
         * В широковещательном режиме просто вызывается функция, но
         * только при наличии синхронизации.
         */
        hpoll = p->hpoll;
        if (p->hmode == M_BCST) {
                p->outdate = c.t;
                if (s.p != NULL)
                        peer_xmit(p);
                poll_update(p, hpoll);
                return;
        }

        /*
         * Для manycast начинается с ttl = 1 и значение ttl увеличивается
         * на 1 для каждого опроса, пока не будет найдено MAXCLOCK серверов
         * или ttl не достигнет TTLMAX. При достижении MAXCLOCK опрос
         * прекращается, пока число серверов не упадёт ниже MINCLOCK, после
         * чего процесс повторяется.
         */
        if (p->hmode == M_CLNT && p->flags & P_MANY) {
                p->outdate = c.t;
                if (p->unreach > BEACON) {
                        p->unreach = 0;
                        p->ttl = 1;
                        peer_xmit(p);
                } else if (s.n < MINCLOCK) {
                        if (p->ttl < TTLMAX)
                                p->ttl++;
                        peer_xmit(p);
                }
                p->unreach++;
                poll_update(p, hpoll);
                return;
        }
        if (p->burst == 0) {

                /*
                 * Режим не burst. Регистр доступности сдвигается влево.
                 * Надеемся, что до следующего опроса поступит пакет и
                 * заполнится правый бит регистра.
                 */
                oreach = p->reach;
                p->outdate = c.t;
                p->reach = p->reach << 1;
                if (!(p->reach & 0x7))
                        clock_filter(p, 0, 0, MAXDISP);
                if (!p->reach) {

                        /*
                         * Сервер недоступен, поэтому увеличивается счётчик
                         * unreach. По достижении порога недоступности 
                         * интервал опроса удваивается для минимизации
                         * сетевого трафика. Блок пакетов (burst) 
                         * передаётся, если это разрешено и 
                         * достигнут порог недоступности.
                         */
                        if (p->flags & P_IBURST && p->unreach == 0) {
                                p->burst = BCOUNT;
                        } else if (p->unreach < UNREACH)
                                p->unreach++;
                        else
                                hpoll++;
                        p->unreach++;
                } else {

                        /*
                         * Сервер доступен. Для интервала опроса задаётся 
                         * значение системного интервала опроса. Блок
                         * (burst) передаётся , если это разрешено и 
                         * партнёр подходит.
                         */
                        p->unreach = 0;
                        hpoll = s.poll;
                        if (p->flags & P_BURST && fit(p))
                                p->burst = BCOUNT;
                }
        } else {

                /*
                 * В случае значение снижается. При получении отклика 
                 * функция clock_filter() вызывает clock_select() для
                 * обработки результатов передачи блока пакетов.
                 */
                p->burst--;
        }
        /*
         * Не передавать в режиме широковещательного клиента.
         */
        if (p->hmode != M_BCLN)
                peer_xmit(p);
        poll_update(p, hpoll);
}
A.5.7.2. poll_update()
/*
 * poll_update() - обновление интервала опроса для ассоциации p.
 *
 * Эту функцию вызывают packet() и poll(). Поскольку packet() вызывается
 * при получении пакета из сети, а poll() - по тайм-ауту, может возникать
 * «конфликт», который способен сделать некорректным следующий интервал
 * опроса. Такие ситуации считаются пренебрежимо редкими.
 */
void
poll_update(
        struct p *p,            /* Указатель на структуру партнёра */
        int     poll            /* Интервал опроса (log2 s) */
        )
{
        /*
         * Эту функцию вызывают poll() и packet() для определения времени
         * следующего опроса. В блочном (burst) режиме интервал опроса
         * составляет 2 секунды, в ином случае определяется меньшим из
         * значений интервалов опроса хоста и партнёра, но не более MAXPOLL
         * и не менее MINPOLL. Это позволяет заменить долгий интервал более
         * коротким, если требуется быстрый отклик.
         */
        p->hpoll = max(min(MAXPOLL, poll), MINPOLL);
        if (p->burst > 0) {
                if (p->nextdate != c.t)
                        return;
                else
                        p->nextdate += BTIME;
        } else {

                /*
                 * Хотя здесь это не показано, эталонная реализация вносит
                 * интервал опроса небольшой случайный фактор.
                 */
                p->nextdate = p->outdate + (1 << max(min(p->ppoll,
                    p->hpoll), MINPOLL));
        }

        /*
         * Может случиться так, что заданное время уже прошло. В этом
         * случае задаётся время на 1 секунду в будущее.
         */
        if (p->nextdate <= c.t)
                p->nextdate = c.t + 1;
}
A.5.7.3. peer_xmit()
/*
 * transmit() - передача пакета для ассоциации p
 */
void
peer_xmit(
        struct p *p             /* Указатель на структуру партнёра */
        )
{
        struct x x;             /* Передаваемый пакет */

        /*
         * Инициализация заголовка и метки времени передачи.
         */
        x.srcaddr = p->dstaddr;
        x.dstaddr = p->srcaddr;
        x.leap = s.leap;
        x.version = p->version;
        x.mode = p->hmode;
        if (s.stratum == MAXSTRAT)
                x.stratum = 0;
        else
                x.stratum = s.stratum;
        x.poll = p->hpoll;
        x.precision = s.precision;
        x.rootdelay = D2FP(s.rootdelay);
        x.rootdisp = D2FP(s.rootdisp);
        x.refid = s.refid;
        x.reftime = s.reftime;
        x.org = p->org;
        x.rec = p->rec;
        x.xmt = get_time();
        p->xmt = x.xmt;

        /*
         * Если идентификатор ключа отличен от 0, передаётся MAC с 
         * использованием key ID ассоциации и ключа из локального кэша. 
         * Если что-то пошло не так, например, нет доверенного ключа,
         * пакет не передаётся, а ассоциация сбрасывается и прекращает
         * работу до устранения проблем.
         */
        if (p->keyid)
                if (/* p->keyid invalid */ 0) {
                        clear(p, X_NKEY);
                        return;
                }
                x.dgst = md5(p->keyid);
        xmit_packet(&x);
}

Адреса авторов

Dr. David L. Mills

University of Delaware

Newark, DE 19716

US

Phone: +1 302 831 8247

EMail: mills@udel.edu

Jim Martin (editor)

Internet Systems Consortium

950 Charter Street

Redwood City, CA 94063

US

Phone: +1 650 423 1378

EMail: jrmii@isc.org

Jack Burbank

The Johns Hopkins University Applied Physics Laboratory

11100 Johns Hopkins Road

Laurel, MD 20723-6099

US

Phone: +1 443 778 7127

EMail: jack.burbank@jhuapl.edu

William Kasch

The Johns Hopkins University Applied Physics Laboratory

11100 Johns Hopkins Road

Laurel, MD 20723-6099

US

Phone: +1 443 778 7463

EMail: william.kasch@jhuapl.edu


Перевод на русский язык

Николай Малых

nmalykh@protokols.ru

1Internet Engineering Task Force — комиссия по решению инженерных задач Internet.

2Internet Engineering Steering Group — комиссия по инженерным разработкам Internet.

3В оригинале это предложение и 2 последних строки таблицы содержат ошибки. См. https://www.rfc-editor.org/errata/eid3126. Прим. перев.

4В оригинале ошибочно указано 0.5e-18. См. https://www.rfc-editor.org/errata/eid2826. Прим. перев.

5В оригинале ошибочно указано -678491. См. https://www.rfc-editor.org/errata/eid4025. Прим. перев.

6В оригинале ошибочно указано 202939144. См. https://www.rfc-editor.org/errata/eid6524. Прим. перев.

7В оригинале слово «современной» отсутствовало. См. https://www.rfc-editor.org/errata/eid6423. Прим. перев.

8В оригинале ошибочно указан 1999 год и числа строки привязаны к нему. См. https://www.rfc-editor.org/errata/eid5189. Прим. перев.

9В оригинале ошибочно сказано «месяца». См. https://www.rfc-editor.org/errata/eid4504. Прим. перев.

10В оригинале ошибочно сказано -18. См. https://www.rfc-editor.org/errata/eid2476. Прим. перев.

11В оригинале ошибочно сказано о снижении интервала. См. https://www.rfc-editor.org/errata/eid3007. Прим. перев.

12В оригинале этот параграф содержал ряд ошибок. См. https://www.rfc-editor.org/errata/eid3627. Приведённый здесь текст соответствует корректировке, внесённой RFC 7822. Прим. перев.

13В оригинале это уравнение содержало ошибку. См. https://www.rfc-editor.org/errata/eid5020. Прим. перев.

14В оригинале приведённое ниже выражение содержало ошибку. См. https://www.rfc-editor.org/errata/eid5600. Прим. перев.

15В оригинале ошибочно указано A.5.5.3. См. https://www.rfc-editor.org/errata/eid3132. Прим. перев.

16В оригинале это предложение содержало ошибки. См. https://www.rfc-editor.org/errata/eid4019. Прим. перев.

17В оригинале ошибочно указано d = f. См. https://www.rfc-editor.org/errata/eid4366. Прим. перев.

18В оригинале этот абзац и рисунок 25 содержали ошибки. См. https://www.rfc-editor.org/errata/eid5601 и https://www.rfc-editor.org/errata/eid5604. Прим. перв.

19В оригинале ошибочно указано (x * x). См. https://www.rfc-editor.org/errata/eid3404. Прим. перев.

20В оригинале ошибочно указано memset(&c, sizeof(c), 0);. См. https://www.rfc-editor.org/errata/eid3608. Прим. перев.

21Ошибка, см. https://www.rfc-editor.org/errata/eid2514. Прим. перев.

22В оригинале приведённое ниже условие содержало ошибки. https://www.rfc-editor.org/errata/eid5978. Прим. перев.

23В оригинале приведённый ниже код содержал ошибки. См. https://www.rfc-editor.org/errata/eid3125. Прим. перев.

24В оригинале эта строка содержит ошибку. См. https://www.rfc-editor.org/errata/eid6550. Прим. перев.

25См. https://www.rfc-editor.org/errata/eid6280. Прим. перев.

26В оригинале циклы for содержали ошибки. См. https://www.rfc-editor.org/errata/eid6207 и https://www.rfc-editor.org/errata/eid3127. Прим. перев.

Рубрика: RFC | Оставить комментарий

RFC 5871 IANA Allocation Guidelines for the IPv6 Routing Header

Internet Engineering Task Force (IETF)                      J. Arkko
Request for Comments: 5871                                  Ericsson
Updates: 2460                                             S. Bradner
Category: Standards Track                         Harvard University
ISSN: 2070-1721                                             May 2010

Рекомендации IANA по распределению значений IPv6 Routing Header

IANA Allocation Guidelines for the IPv6 Routing Header

PDF

Аннотация

В этом документе приведены рекомендации IANA для выделения новых значений поля Routing Type в заголовках расширения IPv6 Routing Header.

Статус документа

Этот документ относится к проектам стандартов Internet.

Документ является результатом работы IETF1 и представляет согласованную точку зрения сообщества IETF. Документ был представлен на публичное обсуждение и одобрен для публикации IESG2. Дополнительную информацию о стандартах Internet можно найти в RFC 5741 (раздел 2).

Сведения о текущем статусе данного документа, ошибках и способах обратной связи доступна по ссылке http://www.rfc-editor.org/info/rfc5871.

Авторские права

Авторские права (c) 2010 принадлежат IETF Trust и лицам, указанным в качестве авторов документа. Все права защищены.

К этому документу применимы права и ограничения, перечисленные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включенные в этот документ, распространяются в соответствии с упрощенной лицензией BSD, как указано в параграфе 4.e документа Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

1. Введение

Этот документ содержит рекомендации для агентства IANA [RFC5226] по выделению новых значений для поля Routing Type в заголовке расширения IPv6 Routing [RFC2460]. Ранее рекомендаций для IANA по этому вопросы не существовало.

2. Взаимодействие с IANA

Новые значения Routing Type выделяются в соответствии с процедурой IETF Review3 или IESG Approval4 [RFC5226].

Отметим, что два экспериментальных значения (253 и 254) уже выделены для использования [RFC4727].

3. Вопросы безопасности

Данная спецификация не меняет связанных с безопасностью свойств заголовка Routing Header. Однако имеющийся опыт показывает возможность и простоту создания заголовков маршрутизации, которые могут создавать серьезные проблемы [RFC5095].

4. Литература

4.1. Нормативные документы

[RFC2460] Deering, S. and R. Hinden, «Internet Protocol, Version 6 (IPv6) Specification», RFC 2460, December 1998.

[RFC5226] Narten, T. and H. Alvestrand, «Guidelines for Writing an IANA Considerations Section in RFCs», BCP 26, RFC 5226, May 2008.

4.2. Дополнительная литература

[RFC4727] Fenner, B., «Experimental Values In IPv4, IPv6, ICMPv4, ICMPv6, UDP, and TCP Headers», RFC 4727, November 2006.

[RFC5095] Abley, J., Savola, P., and G. Neville-Neil, «Deprecation of Type 0 Routing Headers in IPv6», RFC 5095, December 2007.

Приложение A. Изменения в RFC 2460

Этот документ только задает для IANA правила выделения значений для поля Routing Type.

Адреса авторов

Jari Arkko

Ericsson

Jorvas 02420

Finland

EMail: jari.arkko@piuha.net

Scott Bradner

Harvard University

Cambridge, MA 02138

US

Phone: +1 617 495 3864

EMail: sob@harvard.edu


Перевод на русский язык

Николай Малых

nmalykh@gmail.com

1Internet Engineering Task Force.

2Internet Engineering Steering Group.

3Рецензия IETF.

4Одобрение IESG.

Рубрика: RFC | Оставить комментарий

RFC 5857 IKEv2 Extensions to Support Robust Header Compression over IPsec

Internet Engineering Task Force (IETF)                    E. Ertekin
Request for Comments: 5857                               C. Christou
Category: Standards Track                                  R. Jasani
ISSN: 2070-1721                                  Booz Allen Hamilton
                                                          T. Kivinen
                                                     AuthenTec, Inc.
                                                          C. Bormann
                                             Universitaet Bremen TZI
                                                            May 2010

 

Расширения IKEv2 для поддержки компрессии ROHC с IPsec

IKEv2 Extensions to Support Robust Header Compression over IPsec

PDF

Аннотация

Для интеграции ROHC1 с Ipsec требуется сигнальный механизм для передачи параметров канала ROHC между конечными точками. Механизм IKE2 подходит для решения этой задачи. В этом документе предложены расширения IKEv2, позволяющие передавать сигнализацию ROHC и канальные параметры для защищенных связей IPsec.

Статус документа

Этот документ является проектом стандарта Internet (Internet Standards Track)..

Документ подготовлен IETF3 и содержит согласованный взгляд сообщества IETF. Документ обсуждался публично и одобрен для публикации IESG4. Дополнительная информация о стандартах Internet приведена в разделе 2 RFC 5741.

Информацию о текущем состоянии данного документа, обнаруженных ошибках и способах обратной связи можно найти по ссылке http://www.rfc-editor.org/info/rfc5795.

Авторские права

Авторские права ((c) 2010) принадлежат IETF Trust и лицам, являющимся авторами документа. Все права защищены.

К этому документу применимы права и ограничения, перечисленные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включенные в этот документ, распространяются в соответствии с упрощенной лицензией BSD, как указано в параграфе 4.e документа Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

Документ может содержать материалы из IETF Document или IETF Contribution, опубликованных или публично доступных до 10 ноября 2008 года. Лица, контролирующие авторские права на некоторые из таких документов, могли не предоставить IETF Trust права разрешать внесение изменений в такие документы за рамками процессов IETF Standards. Без получения соответствующего разрешения от лиц, контролирующих авторские права этот документ не может быть изменен вне рамок процесса IETF Standards, не могут также создаваться производные документы за рамками процесса IETF Standards за исключением форматирования документа для публикации или перевода с английского языка на другие языки.

1. Введение

Увеличение размера заголовков в результате использования IPsec [IPSEC] может приводить к неэффективному использованию полосы каналов. Объединение модели ROHC [ROHC] с IPsec обеспечивает эффективный способ передачи защищенного трафика IP.

ROHCoIPsec [ROHCOIPSEC] требует инициализации конфигурационных параметров на компрессоре и декомпрессоре. В современных спецификациях для поэтапного (hop-by-hop) сжатия ROHC эти параметры согласуются с использованием протоколов канального уровня типа PPP5 (т. е. ROHC через PPP [ROHC-PPP]). Поскольку для динамического обмена параметрами между партнерами IPsec можно использовать протоколы обмена ключами (например, IKEv2 [IKEV2]), в этом документе определяются расширения IKEv2 для передачи параметров ROHC в ROHCoIPsec.

2. Уровни требований

Ключевые слова необходимо (MUST), недопустимо (MUST NOT), требуется (REQUIRED), нужно (SHALL), не нужно (SHALL NOT), следует (SHOULD), не следует (SHOULD NOT), рекомендуется (RECOMMENDED), возможно (MAY), необязательно (OPTIONAL) в данном документе должны интерпретироваться в соответствии с RFC 2119 [BRA97].

3. Инициализация канала ROHC для ROHCoIPsec

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

3.1. Сообщение ROHC_SUPPORTED Notify

Параметры канала ROHC должны передаваться раздельно для каждой поддерживающей ROHC связи IPsec SA. В частности, должен быть включен новый тип сообщений Notify в обмены IKE_AUTH и CREATE_CHILD_SA при каждой организации IPsec SA с поддержкой ROHC или смене ключей в существующих связях.

Данные Notify, передаваемые инициатором, должны включать параметры канала для сессии ROHC. Эти параметры показывают возможности декомпрессора ROHC на стороне инициатора. При получении запроса от инициатора ответчик будет игнорировать эти данные (если он не поддерживает ROHC или предлагаемые параметры) или отвечать на них данными Notify, содержащими его параметры для канала ROHC.

Отметим, что для переноса параметров ROHC используется только одно поле Notify. При получении множества Notify с параметрами ROHC все такие данные Notify, кроме первых, должны быть отброшены. Если инициатор не получил данных Notify с параметрами канала ROHC у ответчика, включать ROHC для Child SA недопустимо.

Новое значение Notify Message Type, обозначаемое ROHC_SUPPORTED, показывает, что данные Notify передают параметры канала ROHC (параграф 3.1.26).

Формат данных Notify (определен в 4306 [IKEV2]) показан на рисунке 1.

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   ! Next Payload  !C!  RESERVED   !         Payload Length        !
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   !  Protocol ID  !   SPI Size    !      Notify Message Type      !
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   !                                                               !
   ~                Security Parameter Index (SPI)                 ~
   !                                                               !
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   !                                                               !
   ~                       Notification Data                       ~
   !                                                               !
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 1: Формат Notify Payload

Поля Notify Payload описаны ниже.

Next Payload (1 октет)

Идентификатор типа следующих данных в сообщении. Дополнительная информация в RFC 4306 [IKEV2].

Critical (1 бит)

Поскольку все реализации IKEv2 поддерживают данные Notify, это поле должно иметь значение 0.

Payload Length (2 октета)

В соответствии с определением RFC 4306 [IKEV2] это поле показывает размер данных (payload) вместе с их базовым заголовком.

Protocol ID (1 октет)

Поскольку эти сообщения используются в процессе создания Child SA, данное поле должно иметь значение 0.

SPI Size (1 октет)

Это поле должно иметь значение 0, поскольку применимых SPI нет (параметры ROHC задаются при создании SA, когда SPI не определены).

Notify Message Type (2 октета)

В это поле должно помещаться значение ROHC_SUPPORTED.

Security Parameter Index (SPI)

Поскольку поле SPI Size = 0, передавать данное поле недопустимо.

Notification Data (переменный размер)

В этом поле должно содержаться не менее трех атрибутов ROHC (см. параграф 3.1.1).

3.1.1. Атрибуты ROHC

Сообщение ROHC_SUPPORTED Notify используется для передачи канальных параметров между компрессором и декомпрессором ROHCoIPsec. Сообщение содержит список атрибутов ROHC, включающих параметры, требуемые для сеанса ROHCoIPsec.

Формат сигнальных атрибутов ROHC похож на формат атрибутов преобразования, описанных в параграфе 3.3.5 документа RFC 4306 [IKEV2]. Формат атрибута ROHC показан на рисунке 2.

                         1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    !A!     ROHC Attribute Type     !  AF=0  ROHC Attribute Length  !
    !F!                             !  AF=1  ROHC Attribute Value   !
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    !                   AF=0  ROHC Attribute Value                  !
    !                   AF=1  Not Transmitted                       !
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 2: Формат атрибута ROHC

  • Attribute Format (AF) (1 бит) — если AF=0, атрибут ROHC представляется в формате TLV7. При AF=1 атрибут указывается в формате TV (тип/значение).
  • ROHC Attribute Type (15 битов) — уникальный идентификатор для каждого типа атрибутов ROHC (см. параграф 3.1.2).
  • ROHC Attribute Length (2 октета) — размер Attribute Value в октетах. Если AF=1, значение атрибута ROHC занимает 2 октета и поле ROHC Attribute Length отсутствует.
  • ROHC Attribute Value (переменный размер) — значение атрибута ROHC, связанное с ROHC Attribute Type. Если AF=0, размер этого поля определяется значением поля ROHC Attribute Length. При AF=1 размер поля ROHC Attribute Value составляет 2 октета.

3.1.2. Типы атрибутов ROHC

В этом параграфе описаны типы атрибутов ROHC: MAX_CID, ROHC_PROFILE, ROHC_INTEG, ROHC_ICV_LEN и MRRU. Связанные с каждым из типов значения рассмотрены в разделе 58.

MAX_CID (Максимальное значение идентификатора контекста, AF = 1)

Атрибут MAX_CID является обязательным и должен передаваться в единственном экземпляре. Поле MAX_CID указывает максимальное значение идентификатора контекста, поддерживаемое декомпрессором ROHCoIPsec. Значение атрибута имеет размер 2 октета и должно находиться в диапазоне от 0 до 16383, включительно. Поскольку идентификаторы CID могут принимать значения от 0 до MAX_CID, число контекстов, которые могут использоваться реально, составляет MAX_CID+1. Значение MAX_CID = 0 говорит о единственном контексте. Получатель атрибута MAX_CID должен использовать для компрессии только контексты, номера атрибутов для которых не превышают MAX_CID.

Отметим, что параметр MAX_CID является односторонним уведомлением (т. е.,отправитель атрибута показывает свои возможности другой стороне), поэтому в каждом направление может использоваться свое значение MAX_CID.

ROHC_PROFILE (профиль ROHC, AF = 1)

Атрибут ROHC_PROFILE является обязательным. Каждый атрибут ROHC_PROFILE имеет фиксированный размер в 4 октета, а значением атрибута является 2-октетный идентификатор профиля ROHC [ROHCPROF]. В сообщение ROHC_SUPPORTED Notify должен включаться по крайней мере один атрибут ROHC_PROFILE. При передаче множества атрибутов ROHC_PROFILE они могут размещаться в произвольном порядке. Получатель атрибутов ROHC_PROFILE должен использовать для компрессии только предложенные этими атрибутами профили.

Некоторые профили общего назначения определены в RFC 3095 [ROHCV1] и RFC 5225 [ROHCV2]. Следует отметить, что передавать в атрибутах две версии одного профиля недопустимо. Например, если декомпрессор ROHCoIPsec поддерживает ROHCv1 UDP (0x0002) и ROHCv2 UDP (0x0102), недопустимо указывать оба профиля. Это ограничение обусловлено тем, что пакеты, сжатые с использованием ROHC, содержат только 8 младших битов идентификатора профиля, а они совпадают для профилей ROHCv1 и ROHCv2, поэтому декомпрессор не сможет определить версию профиля, использованного для сжатия пакета.

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

ROHC_INTEG (Алгоритм контроля целостности для проверки заголовков после декомпрессии, AF = 1)

Атрибут ROHC_INTEG является обязательным и в каждом сообщении ROHC_SUPPORTED Notify должно указываться не менее одного атрибута ROHC_INTEG. Значение атрибута содержит идентификатор алгоритма контроля целостности, используемого для обеспечения целостности декомпрессированных пакетов (т. е., гарантии совпадения заголовка пакета после декомпрессии с заголовком исходного пакета до сжатия).

Алгоритмы аутентификации, которые должны поддерживаться, заданы в таблице «Алгоритмы аутентификации» параграфа 3.1.1 (Алгоритмы шифрования и аутентификации ESP) RFC 4835 [CRYPTO-ALG] (или его замены).

Алгоритм контроля целостности представляется 2-октетным значением, соответствующим значению из реестра параметров IKEv2 [IKEV2-PARA], раздел Transform Type 3 — Integrity Algorithm Transform IDs9. При получении атрибутов ROHC_INTEG ответчик должен выбрать единственный из предложенных алгоритмов и передать свой выбор в сообщении ROHC_SUPPORTED Notify, адресованном инициатору. Выбранный алгоритм контроля целостности должен использоваться для обоих направлений. Если ответчик не принимает ни одного из предложенных алгоритмов, включать ROHC для данной SA недопустимо.

Использование алгоритма контроля целостности включает ряд перечисленных ниже аспектов.

  1. Ключи (по одному для каждого направления) для алгоритма контроля целостности создаются из IKEv2 KEYMAT (см. [IKEV2], параграф 2.17). При создании ключей ROHC рассматривается, как протокол IPsec. При смене ключей для поддерживающей ROHC связи CHILD_SA меняются и ключи, связанные с этим алгоритмом контроля целостности.

  2. Инициатор ROHCoIPsec может передать в атрибуте ROHC_INTEG нулевое значение (0x0000). Это соответствует значению NONE из реестра IKEv2 Integrity Algorithm Transform IDs. Ответчик ROHCoIPsec может выбрать это значение, отвечая инициатору атрибутом ROHC_INTEG = 0x0000. В этом случае для обоих направлений алгоритм контроля целостности не применяется.

  3. ROHC_INTEG является параметром, согласуемым обеими сторонами. Иными словами, инициатор показывает поддерживаемые им алгоритмы, а ответчик выбирает одно из предложенных значений ROHC_INTEG и передает свой выбор инициатору.

ROHC_ICV_LEN (Размер алгоритма контроля целостности, AF = 1)

Атрибут ROHC_ICV_LEN относится к числу необязательных. В сообщения ROHC_SUPPORTED Notify может включаться множество атрибутов ROHC_ICV_LEN. Атрибут задает число октетов значения ICV10, которые отправитель сообщения ожидает получить во входящих пакетах ROHC. Значение ICV согласованного алгоритма ROHC_INTEG должно сокращаться до ROHC_ICV_LEN байтов, путем отбрасывания лишних октетов в конце. Инициатор и ответчик анонсируют свои значения размера ICV. Получатель атрибута ROHC_ICV_LEN должен уменьшить размер ICV до величины, указанной в сообщении. Если ROHC_ICV_LEN = 0, передача ICV недопустима. Если атрибут ROHC_ICV_LEN не был задан совсем или его значение превышает размер ICV для выбранного алгоритма, должно использоваться полное значение ICV соответствующего алгоритма ROHC_INTEG .

Отметим, что атрибут ROHC_ICV_LEN служит односторонним уведомлением и в каждом направлении может анонсироваться свое значение ROHC_ICV_LEN.

MRRU (Максимальный восстанавливаемый блок для приема, AF = 1)

Атрибут MRRU относится к числу необязательных. В сообщения ROHC_SUPPORTED Notify может включаться не более одного атрибута MRRU. Размер атрибута составляет 2 октета. Атрибут задает размер (в октетах) максимального блока, который декомпрессор ROHCoIPsec ожидает для восстановления из сегментов ROHC (см. параграф 5.2.5 [ROHCV1]). Этот размер включает поля контрольной суммы (CRC) и ROHC ICV. Если MRRU = 0 или значение MRRU не задано, сегменты заголовков недопустимо передавать в канал ROHCoIPsec.

Отметим, что атрибут MRRU служит односторонним уведомлением и в каждом направлении может анонсироваться свое значение MRRU.

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

3.2. Неявно устанавливаемые канальные параметры ROHC

Перечисленные ниже параметры каналов ROHC недопустимо передавать в сигнализации.

  • LARGE_CIDS. Это значение неявно определяется значением MAX_CID (т. е., при MAX_CID <= 15, принимается LARGE_CIDS = 0).
  • FEEDBACK_FOR. При создании пары SA (по одной для каждого направления) параметр FEEDBACK_FOR для канала ROHC должен неявно задаваться для другой SA в паре (т. е., SA в обратном направлении).

4. Вопросы безопасности

Возможность согласования размера ROHC ICV может создавать уязвимость для протокола ROHCoIPsec. В частности, возможность задать малый размер может приводить к ситуациям, когда в защищенный домен будут пересылаться ошибочные пакеты. Более детально эта проблема рассмотрена в параграфе 6.1.4 документа [ROHCOIPSEC] и в разделе 5 [IPSEC-ROHC].

Проблему можно смягчить за счет использования больших ICV, но это приведет к добавочным издержкам и снизит эффективность, обеспечиваемую ROHCoIPsec.

5. Согласование с IANA

В этом документе определено новое сообщение Notify (Status Type). Следовательно, агентство IANA выделило одно значение из реестра «IKEv2 Notify Message Types» для индикации поддержки ROHC (ROHC_SUPPORTED).

В дополнение к этому агентство IANA создало новый субреестр ROHC Attribute Types в рамках реестра Internet Key Exchange Version 2 (IKEv2) Parameters [IKEV2-PARA]. В реестре ROHC Attribute Types этот документ выделяет значения, перечисленные в таблице.

Значение в реестре Тип атрибута ROHC Формат Документ
0 Резерв [RFC5857]
1 Максимальный идентификатор контекста MAX_CID TV [RFC5857]
2 Профиль ROHC (ROHC_PROFILE) TV [RFC5857]
3 Алгоритм контроля целостности ROHC (ROHC_INTEG) TV [RFC5857]
4 Размер ROHC ICV в байтах (ROHC_ICV_LEN) TV [RFC5857]
5 Максимальный восстанавливаемый блок на приеме (MRRU) TV [RFC5857]
6-16383 Не распределены TV [RFC5857]
16384-32767 Для приватного использования TV [RFC5857]

В соответствии с [IANA-CONSIDERATIONS] выделение IANA новых значений для типов атрибутов ROHC должно осуществляться после рецензии эксперта (Expert Review).

Для регистрационных запросов ответственный руководитель направления IESG (IESG Area Director) будет назначать эксперта (Designated Expert), который будет направлять запрос в списки рассылки ROHC и IPsec (или заменяющие их списки, указанные руководителем направления) для получения комментариев и рецензий. После этого назначенный эксперт будет принимать или отвергать запрос на регистрацию, направляя свое решение в оба списка рассылки и информируя IANA. Отказ от регистрации должен быть мотивирован.

6. Благодарности

Авторы благодарят Sean O’Keeffe, James Kohler, и Linda Noone из Министерства Обороны11, а также Rich Espy из OPnet за их вклад и поддержку при разработке этого документа.

Авторы также благодарны Yoav Nir и Robert A Stangarone Jr., которые выступили рецензентами данной спецификации.

Кроме того, авторы рады поблагодарить перечисленных ниже людей за их рецензии и комментарии к документу:

  • Magnus Westerlund
  • Stephen Kent
  • Lars-Erik Jonsson
  • Pasi Eronen
  • Jonah Pezeshki
  • Carl Knutsson
  • Joseph Touch
  • David Black
  • Glen Zorn

В заключение авторы выражают свою признательность Tom Conkle, Michele Casey и Etzel Brower.

7. Литература

7.1. Нормативные документы

[IPSEC] Kent, S. and K. Seo, «Security Architecture for the Internet Protocol», RFC 4301, December 2005.

[ROHC] Sandlund, K., Pelletier, G., and L-E. Jonsson, «The RObust Header Compression (ROHC) Framework», RFC 5795, March 2010.

[IKEV2] Kaufman, C., «Internet Key Exchange (IKEv2) Protocol», RFC 4306, December 2005.

[BRA97] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, March 1997.

[ROHCV1] Bormann, C., Burmeister, C., Degermark, M., Fukushima, H., Hannu, H., Jonsson, L-E., Hakenberg, R., Koren, T., Le, K., Liu, Z., Martensson, A., Miyazaki, A., Svanbro, K., Wiebke, T., Yoshimura, T., and H. Zheng, «Robust Header Compression (ROHC): Framework and four profiles: RTP, UDP, ESP, and uncompressed», RFC 3095, July 2001.

[ROHCV2] Pelletier, G. and K. Sandlund, «RObust Header Compression Version 2 (ROHCv2): Profiles for RTP, UDP, IP, ESP and UDP-Lite», RFC 5225, April 2008.

[IPSEC-ROHC] Ertekin, E., Christou, C., and C. Bormann, «IPsec Extensions to Support Robust Header Compression over IPsec», RFC 5858, May 2010.

[IANA-CONSIDERATIONS] Narten, T. and H. Alvestrand, «Guidelines for Writing an IANA Considerations Section in RFCs», BCP 26, RFC 5226, May 2008.

7.2. Дополнительная литература

[ROHCOIPSEC] Ertekin, E., Jasani, R., Christou, C., and C. Bormann, «Integration of Header Compression over IPsec Security Associations», RFC 5856, May 2010.

[ROHC-PPP] Bormann, C., «Robust Header Compression (ROHC) over PPP», RFC 3241, April 2002.

[ROHCPROF] IANA, «RObust Header Compression (ROHC) Profile Identifiers», <http://www.iana.org>.

[CRYPTO-ALG] Manral, V., «Cryptographic Algorithm Implementation Requirements for Encapsulating Security Payload (ESP) and Authentication Header (AH)», RFC 4835, April 2007.

[IKEV2-PARA] IANA, «Internet Key Exchange Version 2 (Kev2) Parameters», <http://www.iana.org>.

Адреса авторов

Emre Ertekin

Booz Allen Hamilton

5220 Pacific Concourse Drive, Suite 200

Los Angeles, CA 90045

US

EMail: ertekin_emre@bah.com

Chris Christou

Booz Allen Hamilton

13200 Woodland Park Dr.

Herndon, VA 20171

US

EMail: christou_chris@bah.com

Rohan Jasani

Booz Allen Hamilton

13200 Woodland Park Dr.

Herndon, VA 20171

US

EMail: ro@breakcheck.com

Tero Kivinen

AuthenTec, Inc.

Fredrikinkatu 47

HELSINKI

FI

EMail: kivinen@iki.fi

Carsten Bormann

Universitaet Bremen TZI

Postfach 330440

Bremen D-28334

Germany

EMail: cabo@tzi.org


Перевод на русский язык

Николай Малых

nmalykh@gmail.com

1Robust Header Compression — отказоустойчивое сжатие заголовков.

2Internet Key Exchange.

3Internet Engineering Task Force.

4Internet Engineering Steering Group.

5Point-to-Point Protocol — протокол «точка-точка».

6В оригинале ошибочно приведена ссылка на раздел 4. См. http://www.rfc-editor.org/errata_search.php?rfc=5857&rec_status=15&presentation=records. Прим. перев.

7Type/Length/Value — тип — размер — значение.

8В оригинале ошибочно приведена ссылка на раздел 4. См. http://www.rfc-editor.org/errata_search.php?rfc=5857&rec_status=15&presentation=records. Прим. перев.

9Тип преобразования 3 — Идентификаторы преобразования для алгоритмов контроля целостности.

10Integrity Check Value — значение для проверки целостности.

11США. Прим. перев.

Рубрика: RFC | Оставить комментарий

RFC 5812 Forwarding and Control Element Separation (ForCES) Forwarding Element Model

Internet Engineering Task Force (IETF)                        J. Halpern
Request for Comments: 5812                                          Self
Category: Standards Track                                  J. Hadi Salim
ISSN: 2070-1721                                            Znyx Networks
                                                              March 2010

Модель элемента пересылки ForCES

Forwarding and Control Element Separation (ForCES) Forwarding Element Model

PDF

Аннотация

Этот документ определяет модель элемента пересылки (FE1), используемую протоколом ForCES2. Модель представляет возможности, состояние и конфигурацию элементов пересылки в контексте протокола ForCES так, что элементы управления CE3 могут должным образом управлять элементами FE. Более конкретно, модель описывает логические функции, присутствующие в FE, поддерживаемые этими функциями возможности и способы взаимодействия между функциями. Эта модель FE предназначена для выполнения требований, заданных в RFC 3654.

Статус документа

Документ относится к категории Internet Standards Track.

Документ является результатом работы IETF4 и представляет согласованный взгляд сообщества IETF. Документ прошел открытое обсуждение и был одобрен для публикации IESG5. Дополнительную информацию о стандартах Internet можно найти в разделе 2 в RFC 5741.

Информацию о текущем статусе документа, ошибках и способах обратной связи можно найти по ссылке http://www.rfc-editor.org/info/rfc5812.

Авторские права

Авторские права (Copyright (c) 2010) принадлежат IETF Trust и лицам, указанным в качестве авторов документа. Все права защищены.

К этому документу применимы права и ограничения, перечисленные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включенные в этот документ, распространяются в соответствии с упрощенной лицензией BSD, как указано в параграфе 4.e документа Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

1. Введение

В RFC 3746 [RFC3746] задана схема, с помощью которой элементы управления CE могут настраивать и управлять одним или множеством раздельных элементов пересылки FE внутри элемента сети NE6 с помощью протокола ForCES. Архитектура ForCES позволяет элементам пересылки с различной функциональностью принимать участие в работе сетевого элемента ForCES. Вследствие различной функциональности элементы CE могут принимать лишь минимальные допущения о функциях FE в NE. До того, как CE смогут настраивать и контролировать поведение элементов пересылки FE, и требуется запросить и определить возможности и состояния своих FE. В RFC 3654 [RFC3654] указано, что эти характеристики, состояния и конфигурационные данные выражаются в форме модели FE.

В RFC 3444 [RFC3444] показано, что информационные модели (IM7) и модели данных (DM8) различаются целями. «Основной целью IM является моделирование управляемых объектов на концептуальном уровне независимо от конкретной реализации или используемого протокола». «DM, напротив, определяются на нижнем уровне абстракции и включают множество деталей. Они предназначены для разработчиков и включают зависимые от протокола конструкции». Иногда сложно провести четкую границу между этими моделями. Описанная в этом документе модель FE является прежде всего информационной моделью, но она также включает некоторые аспекты модели данных типа явных определений схемы класса логических функциональных блоков LFB9 и схемы FE. Предполагается, что эта модель FE будет служить для определения содержимого (payload) информационного обмена между CE и FE в протоколе ForCES.

1.1. Требования к модели FE

В RFC 3654 [RFC3654] приведены требования к модели ForCES FE, которые должна определять перечисленное ниже.

  • Логически разделяемые и отчетливые операции пересылки пакетов в пути данных FE (логические функциональные блоки или LFB).

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

  • Операционные возможности (например, пределы емкости, ограничения, операционные свойства, детализация настройки) каждого типа LFB.

  • Возможные конфигурационные параметры (например, компоненты) каждого типа LFB.

  • Метаданные, которые могут передаваться между LFB.

1.2. Модель FE и реализации FE

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

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

1.3. Модель FE и протокол ForCES

Базовый протокол ForCES [RFC5810] используется элементами CE и FE для поддержки коммуникационного канала между собой. Протокол ForCES может служить для запроса и раскрытия внутренней топологии FE. Детали конкретной реализации пути данных внутри FE, включая топологию LFB, а также возможности и атрибуты каждого LFB, передаются CE в информационных элементах протокола ForCES. Модели класса LFB следует определять всю информацию, требуемую для обмена между FE и CE с целью подходящей настройки и управления данным LFB.

Спецификация разных данных (payload) сообщений ForCES систематизированным путем затруднена без формального определения объектов для настройки и управления (FE и LFB в нем). Документ для модели FE определяет набор классов и компонент для описания и манипуляций с состояниями LFB внутри элемента FE. Эти определения классов сами по себе обычно не появляются в протоколе ForCES. Вместо этого операции протокола ForCES ссылаются на определенные в этой модели классы, которые включают нужные компоненты и определяют операции.

В разделе 7 приведено более подробное рассмотрение способов использования модели FE протоколом ForCES.

1.4. Язык моделирования FE

Хотя это и не обязательно, будет полезно использование формального языка моделирования для представления концептуальной модели FE, описываемой в этом документе. Использование формального языка позволит обеспечить согласованность и логическую совместимость разных LFB. Полная спецификация будет написана с использованием такого языка моделирования данных. Формальное определение классов LFB может облегчить возможную автоматизацию того или иного процесса генерации кода и функциональную проверку пригодности произвольных топологий LFB. Это определения классов формируют библиотеку LFB. Документы, описывающие классы LFB называются документами библиотеки LFB.

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

Для этого документа в качестве языка спецификации был выбран XML, поскольку этот язык понятен человеку и удобен для машинного анализа, поддерживаемого множеством доступных инструментов. В этом документе применяется схема XML для определения структуры документов библиотеки LFB в соответствии с определениями [RFC3470], [Schema1] и [Schema2]. Хотя эти определения классов LFB не передаются в протоколе ForCES, они соответствуют рекомендациям RFC 3470 [RFC3470] по использованию XML в протоколах IETF.

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

1.5. Структура документа

В разделе 3 приведен концептуальный обзор модели FE, являющийся основой для более подробного рассмотрения и спецификации в последующих разделах. Разделы 4 и 5 описывают ядро модели FE, с подробным рассмотрением двух основных аспектов — общей модели LFB и определения FE Object LFB с компонентами, включая возможности FE и топологическую информацию LFB. Раздел 6 посвящен требованиям к модели в соответствии с приведенными в RFC 3654 [RFC3654] требованиями к протоколу ForCES, а в разделе 7 разъясняется как модель FE следует применять в протоколе ForCES.

2. Определения

Уровни требований (должно, следует, может, недопусимо) указываются в соответствии с RFC 2119 [RFC2119]. Эти уровни применяются при описании требуемого поведения элементов пересылки или управления ForCES для поддержки или манипуляций с описываемой в этой модели информацией.

Термины, связанные с требованиями к ForCES, определены в RFC 3654 [RFC3654] и не дублируются здесь. Набор терминов, относящихся к модели FE, приведен ниже.

FE Model — модель элемента пересылки

Модель, описывающая функции логической обработки в FE. Модель FE, предлагаемая в документе, включает три компоненты — модель отдельного логического функционального блока (модель LFB10), логическое соединение между LFB (топология LFB) и атрибуты уровня FE, включая возможности FE. Модель FE служит основой для определения информационных элементов, передаваемых между CE и FE в протоколе ForCES [RFC5810].

Data Path — путь (передачи) данных

Концептуальный путь, по которому пакеты проходят через уровень пересылки в FE. Отметим, что в FE может быть более одного пути данных.

LFB (Logical Functional Block) Class (или type)

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

LFB Instance — экземпляр LFB

При перемещении потоков по пути данных FE эти потоки проходя через один или множество LFB, каждый из которых является экземпляров конкретного класса LFB. В пути данных FE может присутствовать множество экземпляров одного класса LFB. Этмети, что в документе термин LFB часто упоминается безотносительно класса или экземпляра, если контекст позволяет различить их.

LFB Model — модель LFB

Модель LFB описывает содержимое и структуры LFB, а также дает определения связанных с блоком данных. Для формальных определений требуемых при моделировании структур используется язык XML. В модели LFB определены четыре типа информации. Ядром модели являются определения классов LFB, а три оставшихся типа определяют конструкции, связанные с определениями классов или используемые в них, — это типы данных многократного использования, поддерживаемые форматы кадров (пакетов) и метаданные.

Element — элемент

Термин «элемент» в документе применяется в соответствии с практикой XML и указывает на помеченную тегом XML часть документа XML. Точное определение можно найти в спецификациях XML от W3C. Термин включен в этот список для полноты, поскольку формальная модель ForCES использует XML.

Attribute — атрибут

Атрибуты используются в формальной модели ForCES в соответствии с принятой в XML практикой, т. е. для обозначения свойств, включенных в тег XML.

LFB Meta Data — метаданные LFB

Метаданные служат для передачи информации о состоянии на уровне отдельного пакета из одного блока LFB в другой, но без передачи через сеть. Модель FE определяет для таких данных идентификацию, обработку, и восприятие (потребление) другими LFB, но не на реализацию состояния отдельных пакетов в реальном оборудовании. Метаданные передаются между FE и CE в перенаправляемых пакетах.

ForCES Component — компонента ForCES

Компонентой ForCES называют четко определенный, однозначно идентифицируемый и адресуемый блок модели ForCES. Компонента имеет 32-битовый идентификатор, имя, тип и необязательное описание, которые зачастую называют просто компонентами.

LFB Component — компонента LFB

Компонентами LFB являются компоненты ForCES, определяющие рабочие параметры LFB, которые должны быть видны CE.

Structure Component — компонента структуры

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

Property — свойство

Компоненты ForCES имеют связанные с ними свойства типа читабельности. Другим примером является длина компонент переменного размера. Эти свойства доступны CE для чтения, а в некоторых случаях и для записи. Подробное описание свойств ForCES приведено в параграфе 4.8.

LFB Topology — топология LFB

Представление логических связей между экземплярами LFB и их размещения в пути данных внутри одного элемента FE. Иногда используется термин «внутренняя топология FE», но не следует путать ее с топологией соединений между FE (inter-FE topology). Топология LFB не входит в модель LFB, но является частью модели FE.

FE Topology — топология FE

Представление соединений между множеством FE в одном NE. Иногда это называют внешней топологией FE, чтобы отличать от внутренней топологии FE (т. е. топологии LFB). Отдельный элемент FE может не иметь информации о всей топологии FE, но локальное представление его соединений с другими FE считается частью модели FE. Топология FE раскрывается базовым протоколом ForCES или иным способом.

Inter-FE Topology — внешняя топология FE

См. FE Topology.

Intra-FE Topology — внутренняя топология FE

См. LFB Topology.

LFB Class Library — библиотека классов LFB

Библиотека классов LFB представляет собой набор классов LFB, которые отмечены как наиболее общие функции в большинстве FE, и поэтому рабочей группе ForCES следовало определить их в первую очередь.

3. Концепции модели ForCES

В этом разделе вводятся некоторые важные концепции ForCES, которые используются на протяжении всего документа. К ним относятся абстракции возможностей и состояния, конструкция моделей FE и LFB, а также однозначная адресация различных структур модели. Детали этих аспектов рассмотрены в разделах 4 и 5. Назначение данного раздела состоит в обсуждении этих концепций на верхнем уровне и создание основы для подробного рассмотрения в следующих разделах.

Модель ForCES FE включает абстракции возможностей и состояния.

  • Модель возможностей FE/LFB описывает «способности и емкость» FE/LFB путем задания вариаций, поддерживаемых функциями, и всех ограничений. «Емкость» описывает пределы конкретных компонент (например, предельный размер таблиц).

  • Модель состояния описывает текущее состояние FE/LFB, т. е. мгновенные значения или рабочее поведение FE/LFB.

В параграфе 3.1 рассмотрены различия между моделями возможностей и состояния, а также описано их объединение в модель FE.

Конструкция модели ForCES описанная в этом документе, позволяет элементу FE предоставить информацию о своей структуре для работы. Ее можно рассматривать как информацию уровня FE и информацию об отдельных экземплярах LFB, обеспечиваемых FE.

  • Модель ForCES включает конструкции для определения классов логических функциональных блоков (LFB), которые FE может поддерживать. Классы определены в этом и других документах. Определение такого класса обеспечивает информационное содержимое экземпляров класса LFB для мониторинга и управления в целях ForCES. Каждый класс модели LFB формально определяет операционные компоненты LFB, возможности и события LFB. В параграфе 3.2 представлена концепция LFB как базовых функциональных блоков для построения модели ForCES.

  • Модель FE также предоставляет конструкции, требуемые для мониторинга и управления элементом FE в целом для протокола ForCES. Для согласованности операций и простоты эта информация представляется как LFB — класс FE Object LFB и одиночный экземпляр LFB данного класса, определенные с использованием модели LFB. Класс FE Object определяет компоненты для предоставления информации на уровне FE, в частности, возможности FE на грубом уровне, без их полного перечисления и детализации. Частью информации уровня FE является топология LFB, которая показывает логические соединения между экземплярами LFB на пути данных внутри элемента FE. Эта топология рассматривается в параграфе 3.3. FE Object также включает информацию о классах LFB, которые FE может поддерживать.

Модель ForCES позволяет однозначно указывать различные конструкции, которые она определяет. Это включает идентификацию классов LFB и экземпляров LFB внутри класса, а также идентификацию компонент экземпляра.

Протокол ForCES [RFC5810] инкапсулирует целевые адреса, чтобы получать доступ к объектам, указываемым CE. Иерархия адресации показана ниже.

  • Элементы FE однозначно указываются 32-битовыми идентификаторами FEID.

  • Каждый класс LFB имеет уникальный 32-битовый идентификатор LFB ClassID, который является глобальным для элемента сети и может быть выделенным IANA значением.

  • Внутри FE может присутствовать множество экземпляров каждого класса LFB. Эти классы указываются 32-битовыми идентификаторами, уникальными в рамках отдельного класса LFB в данном FE.

  • Для всех компонент экземпляра LFB используются свои 32-битовые идентификаторы.

Адресация более подробно рассматривается в параграфе 3.3.

3.1. Модели возможностей и состояний ForCES

Моделирование возможностей и состояний применимо к абстракциям FE и LFB.

На рисунке 1 показаны возможности, состояние и конфигурация FE в контексте коммуникаций CE-FE по протоколу ForCES.

+-------+                                          +-------+
|       | Возможности FE - что может и не может.   |       |
|       |<-----------------------------------------|       |
|       |                                          |       |
|   CE  | Состояние FE - что сейчас.               |  FE   |
|       |<-----------------------------------------|       |
|       |                                          |       |
|       | Конфигурация FE - чему следует быть.     |       |
|       |----------------------------------------->|       |
+-------+                                          +-------+

Рисунок 1. Обмен возможностями, состоянием и конфигурацией FE в контексте коммуникаций CE-FE по протоколу ForCES.


3.1.1. Модели возможностей и состояний FE

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

3.1.1.1. Модель возможностей FE

Модель возможностей FE может быть использована для описания FE без детализации. Например, FE можно определить следующим образом:

  • FE может обслуживать пересылку IPv4 и IPv6;

  • FE может выполнять классификацию на основе IP-адресов отправителя и получателя, портов отправителя и получателя и т.п.;

  • FE может выполнять измерения;

  • FE может обслуживать до N очередей (емкость);

  • FE может добавлять и удалять заголовки инкапсуляции, включая IPsec, GRE, L2TP.

Хотя можно было попытаться построить объектную модель для полного представления возможностей FE, требуемые для реализации такого подхода усилия оказались слишком велики. Основная сложность связана с описанием подробных ограничений типа максимального числа классификаторов, очередей, буферных пулов и измерителей, которые FE может обеспечивать. Мы надеемся, что баланс между простотой и гибкостью может быть достигнут для модели FE путем объединения достаточно грубого описания возможностей с механизмом информирования об ошибках. Т. е. при попытке CE задать для элемента FE поведение, которое тот не способен реализовать, FE будет возвращать ошибку, указывающую проблему. Примерами такого подхода служат Diffserv PIB [RFC3317] и схема PIB [RFC3318].

3.1.1.2. Модель состояний FE

Модель состояний FE представляет мгновенное состояние FE для элемента CE. Например, с помощью модели состояния FE можно описать элемент FE соответствующему CE следующим образом:

  • на данном порту пакеты классифицируются с использованием данного фильтра;

  • данный классификатор приводит к «измерению» и маркировке пакетов определенными способами;

  • пакеты от конкретных маркировщиков доставляются в общую очередь для обработки, тогда как другие пакеты доставляются в иную очередь;

  • конкретный планировщик с определенным поведением и параметрами будет обслуживать собранные очереди.

3.1.1.3. Модели возможностей и состояний LFB

Информация о возможностях и состоянии LFB формально определяется с использованием схемы XML.

Информация о возможностях на уровне LFB является неотъемлемой частью модели LFB и обеспечивает развитую семантику. Например, когда некоторые функции класса LFB являются необязательными, CE требуется возможность определить какие из необязательных функций поддерживаются данным экземпляром LFB. Схема для определения классов LFB обеспечивает способы идентификации таких компонент.

Информация о состоянии формально определяется с использованием компонент LFB.

3.1.2. Связи между моделями возможностей и состояний LFB и FE

Информация о возможностях FE описывает классы LFB, которые FE может создавать, число экземпляров каждого класса, которые могут быть созданы, топологические ограничения (связность) для экземпляров LFB и т. п. В разделе 5 определены компоненты уровня FE, включающие информацию о возможностях. Поскольку вся информация представляется в виде LFB, это обеспечивается одним экземпляром класса FE Object LFB. Благодаря использованию известного класса LFB с известным идентификатором экземпляра, протокол ForCES обеспечивает элементам CE доступ к этой информации при возникновении потребности в ней в любой момент, включая организацию соединения между CE и FE.

После того, как возможности FE описаны элементу CE, информация о состоянии FE может быть представлена на двух уровнях. Первый уровень представляют разные логически разделяемые функции, которые называют логическими функциональными блоками или LFB. Второй уровень информации описывает порядок и расположение отдельных LFB в пути данных для обеспечения работы уровня пересылки. Соединения и порядок блоков LFB называются топологией LFB. В параграфе 3.2 рассмотрены связанные с LFB концепции верхнего уровня, а параграф 3.3 посвящен топологии LFB. Эта топологическая информация представляется компонентами экземпляра FE Object LFB, чтобы позволить CE извлекать информацию и манипулировать ею.

3.2. Моделирование логического функционального блока (LFB)

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

Имеются также случаи, когда LFB могут применяться для обеспечения набора компонент управления работой FE со стороны CE (т. е., предназначены для управления), без связывания этого управления с конкретными пакетами или частями пути данных. Примером такого LFB является FE Object, который обеспечивает CE информацией о FE в целом, и позволяет CE11 управлять некоторыми аспектами FE типа самого пути данных. Такие LFB не имеют ориентированных на пакеты свойств, описываемых в этом параграфе.

В общем случае FE включает множество LFB, как показано на рисунке 2, и все этил LFB используют общую точку завершения (интерфейс) протокола ForCES (Fp), которая реализует логику протокола ForCES и обеспечивает коммуникационный канал с элементом CE.

                     +-----------+
                     |    CE     |
                     +-----------+
                           ^
                           | Интерфейс (опорная точка) Fp
                           |
+--------------------------|-----------------------------------+
| FE                       |                                   |
|                          v                                   |
| +----------------------------------------------------------+ |
| |                Точка завершения                          | |
| |                   протокола ForCES                       | |
| +----------------------------------------------------------+ |
|           ^                            ^                     |
|           :                            : Внутренний контроль |
|           :                            :                     |
|       +---:----------+             +---:----------|          |
|       |   :LFB1      |             |   :     LFB2 |          |
| =====>|   v          |============>|   v          |======>...|
| Ввод  | +----------+ |Вывод        | +----------+ |          |
| (P,M) | |Компоненты| |(P',M')      | |Компоненты| |(P",M")   |
|       | +----------+ |             | +----------+ |          |
|       +--------------+             +--------------+          |
|                                                              |
+--------------------------------------------------------------+

Рисунок 2. Базовая диаграмма LFB.


LFB, как показано на рисунке 2, может иметь входы, выходы и компоненты, которые мугкт запрашиваться и управляться CE через интерфейс Fp (определен в RFC 3746 [RFC3746]), и точку завершения протокола ForCES. Горизонтальные стрелки на рисунке показывает уровень пересылки для соединения входов и выходов LFB внутри одного FE. P (с маркировкой изменений) показывает пакет данных, а M (с маркерами изменений) показывает связанные с пакетом метаданные. Вертикальная линия между CE и FE указывает опорную точку Fp где происходит двухсторонний обмен между CE и FE — от CE к FE передается конфигурация, управления и вставка пакетов, а от FE к CE происходит перенаправление пакетов на уровень управления, передаются данные мониторинга и учета, сообщения об ошибках и т. п. Отметим, что взаимодействие между CE и LFB является лишь абстрактным и опосредованным. Результатом такого взаимодействия являются манипуляции CE с компонентами экземпляров LFB.

LFB может иметь один или множество входов. Каждый вход принимает пары из пакета и связанных с ним метаданных. В зависимости от определения входного порта LFB пакет или метаданные могут быть пустыми (не представляется на вход). Когда данные приходят на вход LFB, пакет или метаданные должны быть не пусты (иначе это просто отсутствие ввода). Операции LFB в общем случае могут инициироваться поступлением данных на вход, таймером или другим состоянием системы. Когда целью является ввод данных, входные данные не должны быть пустыми.

LFB обрабатывает ввод и дает один или множество выводов в форме пар из пакета и связанных с ним метаданных. В зависимости от определения порта LFB пакет или метаданные могут быть пусты (отсутствовать). Присоединенные к пакеты на выходе метаданные могут быть полученными раньше или содержать информацию об обработке пакета , которая может применяться последующими LFB при обработке пакета в FE.

Пространство имен служит для связывания уникального имени и идентификатора с каждым классом LFB. Пространство должно быть расширяемым для обеспечения возможности определять новые LFB по мере развития уровня пересылки.

Операция LFB задается в модели для того, что CE мог понимать поведение пересылки в пути данных. Например, CE нужно понимать, в какой точке пути данных FEбудет декрементироваться поле TTL заголовка IPv4. Т. е. CE нужно знать может ли пакет быть доставлен ему до или после данной точки в пути данных. Кроме того, CE нужно понимать где и какие изменения заголовков (например, добавление или исключение заголовка туннеля) могут выполняться элементами FE. CE проверяет совместимость между собой разных LFB на пути данных FE для предотвращения присутствия несовместимых экземпляров LFB, которые нарушать работу пути данных. Поэтому модель разработана с учетом предоставления CE требуемой информации.

Выбор уровня детализации для описания функций LFB является важным аспектом этой модели. Для производителей важна возможность выразить операции классов LFB с уровнем детализации, который позволит объединить физические устройства, реализующие разные функции LFB в один элемент FE. Однако модель и связанная с ней библиотека LFB не должны быть детализированы так, что это будет ограничивать реализации. Поэтому нужна полуформальная спецификация — текстовое описание работы LFB (для человека) с достаточной конкретизацией и однозначностью, который сделают возможными проверку соответствия и эффективное проектирование, чтобы обеспечить взаимодействие между разными CE и FE.

Модель класса LFB среди прочей информации задает:

  • число входов и выходов (а также возможность его настройки);

  • метаданные, считываемые и потребляемые на входах;

  • метаданные, создаваемые на выходах;

  • типы пакетов, приемлемые на входах и передаваемые на выходах;

  • изменения содержимого пакетов (включая инкапсуляцию и декапсуляцию);

  • критерии маршрутизации пакетов (при наличии в LFB множества выходов);

  • временные изменения пакетов;

  • изменение порядка в потоке пакетов

  • компоненты информации о возможностях LFB;

  • события, которые могут детектироваться LFB с передачей уведомлений CE;

  • рабочие компоненты LFB.

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

3.2.1. Выход LFB

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

Один выход LFB может быть подключен только к одному входу LFB. Это требуется для обеспечения однозначности пути потока через топологию LFB.

Некоторые LFB будут иметь один вывод, как показано на рисунке 3.a.

+---------------+               +-----------------+
|               |               |                 |
|               |               |             OUT +-->
...          OUT +-->           ...               |
|               |               |    EXCEPTIONOUT +-->
|               |               |                 |
+---------------+               +-----------------+
a. Один выход                   b. Два одиночных выхода

+---------------+               +-----------------+
|               |               |    EXCEPTIONOUT +-->
|         OUT:1 +-->            |                 |
...       OUT:2 +-->           ...          OUT:1 +-->
|         ...   +...            |           OUT:2 +-->
|         OUT:n +-->            |           ...   +...
+---------------+               |           OUT:n +-->
                                +-----------------+
c. Одна выходная группа         d. Один выход и одна 
                                   выходная группа

Рисунок 3. Примеры LFB с разными выходными комбинациями.


Для создания нетривиальной топологии LFB требуются блоки LFB со множеством выходов, которые позволят классу LFB организовать ветвление в пути данных. Для ветвления предоставляются два механизма — множество одиночных выходов и выходные группы, которые могут сосуществовать в одном классе LFB.

Множество одиночных выходов определяется в классе LFB для моделирования предопределенного числа семантически различающихся выходов. Т. е. определение класса LFB должно включать число выходов и это предполагает, что информация о количестве выходов доступна в момент определения класса LFB. При создании экземпляра LFB или использовании этого экземпляра добавление выходов невозможно.

Например IPv4 LPM12 LFB может иметь один выход (OUT) для отправки пакетов после успешного поиска LPM с передачей одновременно метаданных META_ROUTEID, а другой (EXCEPTIONOUT) для исключительных ситуаций, когда поиск LPM завершился отказом. Этот пример показан на рисунке 3.b. Пакеты на этих выходах не только требуют разных трактовок нисходящего направления, но и приводят к двум разным условиям в LFB и каждый выход передает свои метаданные. Эта концепция предполагает, что число выходов известно в момент определения LFB. Для каждого одиночного выходя определение класса LFB указывает типы передаваемых кадров (пакетов) и метаданные.

Выходная группа, с другой стороны, используется для моделирования случаев когда поток похожих пакетов с идентичным набором разрешенных метаданных расщепляется на несколько путей. В таком случае число путей не известно в момент определения класса LFB, поскольку оно не является неотъемлемым свойством класса. Выходная группа состоит из множества выходов, которые используют общие определения для передачи кадров (пакетов) и метаданных (см. рисунок 3.c). Каждый экземпляр выхода может быть соединен со своим нисходящим LFB, как это делается для одиночных выходов, но число экземпляров выходов может быть разным у разных экземпляров одного класса LFB. Определение класса может включать нижний и/или верхний предел числа выходов. Кроме того, для настраиваемых FE информация о возможностях FE может задавать свои пределы для числа экземпляров в конкретных выходных группах для определенных LFB. Реальное число выходов в группе является компонентой экземпляра LFB, которая доступна только для чтения в статической топологии и может быть изменена в динамической. Экземпляры выходов в группе нумеруются с 0 до N-1 и доступны по номерам в рамках LFB. Для использования групп выходных портов LFB имеет встроенный механизм выбора конкретного экземпляра выхода для каждого пакета. Этот механизм описывается в тестовом определении класса и обычно может быть настроен с помощью тех или иных атрибутов LFB.

В качестве примера рассмотрим LFB редиректора, единственной задачей которого является направлять пакеты в один из N нисходящих путей на основе метаданных, связанных с каждым прибывающим пакетом. Такой LFB достаточно универсален и может использоваться в разных точках топологии. Например, рассмотрим LFB, которые записывают типа пакета в метаданные FRAMETYPE или класс скорости для пакета в COLOR и эти метаданные могут использоваться для пересылки. Редиректор может служить для разделения путей IPv4 и IPv6 на основе FRAMETYPE (N=2) или для разделения путей по скорости на основе метаданных COLOR (red, yellow, green; N=3) и т. п..

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

Отметим, что концепцию выходных групп для адаптивного ветвления могут применять и другие LFB. Например, LFB классификатора с одним входом и N выходов легко определить с помощью концепции выходной группы. Такой же результат может быть обеспечен с помощью LFB классификатора с одиночным выходом и LFB редиректора с явно заданными N выходами. Выбор решения об использовании выходной группы остается за разработчиками определения класса LFB.

Модель позволяет комбинировать выходную группу с одиночными выходами в одном классе, как показано на рисунке 3.d. Здесь LFB имеет два типа выходов — OUT для обычного вывода пакетов и EXCEPTIONOUT для пакетов, с которыми связаны исключительные ситуации. Обычный выход OUT имеет множество экземпляров, т. е. является выходной группой.

Таким образом, класс LFB может определять один выход, множество одиночных выходов, одну или несколько выходных групп или комбинацию перечисленных вариантов. Множество одиночных выходов следует использовать в тех случаях, когда нужно ветвление пути данных и выполняется хотя бы одно из двух указанных ниже условий.

  • Число нисходящих направлений наследуется из определения класса (фиксировано).

  • Тип кадров и разрешенных для отправки метаданных любого из выходов отличается от аналогичных параметров других выходов (т. е. разные выходы не могут использоваться для однотипных пакетов и метаданных).

Выходная группа подходит в тех случаях, когда нужно ветвление и выполняется хотя бы одно из условий:

  • число нисходящих направлений не было известно при определении класса LFB;

  • тип кадров и набор метаданных для этих выходов достаточно похожи (в идеале одинаковы) и для них может применяться одно определение выхода.

3.2.2. Вход LFB

Вход LFB представляет собой концептуальный порт, через который данный LFB может принимать информацию от других LFB. Эта информация обычно состоит из пар «пакет-метаданные». Любая из компонент пары может отсутствовать, а отсутствие обеих означает просто отсутствие ввода.

Для экземпляров LFB, принимающих пакеты от множества других экземпляров LFB (fan-in), имеется три варианта моделирования fan-in, которые поддерживаются моделью и могут комбинироваться в одном LFB:

  • неявное мультиплексирование через один вход;

  • явное мультиплексирование через множество одиночных входов;

  • явное мультиплексирование через входную группу.

Простейший вариант мультиплексирования использует одиночный вход (рисунок 4.a). Большинство LFB имеют лишь один одиночный вход. Мультиплексирование в такой порт возможно за счет того, что модель позволяет подключать к одному входу множество выходов LFB. Это свойство применимо ко всем входам LFB без каких-либо особых требований к классу LFB. Мультиплексирование в один порт применимо, когда пакеты из восходящих LFB похожи по типам кадров и сопровождающим их метаданным и для них требуется похожая обработка. Отметим, что этот вариант не решает вопросов «конкуренции» между одновременно прибывающими пакетами. Если такая обработка требуется, следует воспользоваться одним из двух других вариантов мультиплексирования.

Во втором варианте используются отдельные одиночные порты (рисунок 4.b). Этот вариант подходит для ситуаций, когда LFB нужно обрабатывать разнотипные потоки пакетов, требующие определяемой входом обработки внутри LFB, и число разных входов известно в момент определения класса LFB. Например, LFB, способных выполнять декапсуляцию L2 (в L3) и инкапсуляцию L3 (в L2), может иметь два входа — один будет принимать кадры L2 для декапсуляции, а второй — L3 для инкапсуляции. Этот тип LFB ожидает разные кадры (L2 и L3) на своих входах, имеющие свои наборы метаданных, и будет применять к этим кадрам разную обработку. Эта модель может явно решать проблему «конкуренции» пакетов путем определения их обработки в классе LFB.

+--------------+       +------------------------+
| LFB X        +---+   |                        |
+--------------+   |   |                        |
                   |   |                        |
+--------------+   v   |                        |
| LFB Y        +---+-->|вход     Meter LFB      |
+--------------+   ^   |                        |
                   |   |                        |
+--------------+   |   |                        |
| LFB Z        |---+   |                        |
+--------------+       +------------------------+

(a) LFB соединен с множеством восходящих LFB через один вход.

+--------------+       +------------------------+
| LFB X        +---+   |                        |
+--------------+   +-->|layer2                  |
+--------------+       |                        |
| LFB Y        +------>|layer3     LFB          |
+--------------+       +------------------------+

(b) LFB соединен с множеством восходящих LFB через два раздельных входа.

+--------------+       +------------------------+
| Queue LFB #1 +---+   |                        |
+--------------+   |   |                        |
                   |   |                        |
+--------------+   +-->|in:0   \                |
| Queue LFB #2 +------>|in:1   | Входная группа |
+--------------+       |...    |                |
                   +-->|in:N-1 /                |
...                |   |                        |
+--------------+   |   |                        |
| Queue LFB #N |---+   |     Scheduler LFB      |
+--------------+       +------------------------+

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

Рисунок 4. Примеры LFB с разными комбинациями входов.


Треться модель мультиплексирования использует концепцию входной группы. Это похоже на описанную выше концепцию выходной группы и показано на рисунке 4.c. Входная группа включает множество входов с общими свойствами (ожидание однотипных кадров и метаданных). Экземпляры входов нумеруются от 0 до N-1. Извне эти входы выглядят обычными, т. е. совместимый восходящий LFB может подключить свой выход к одному из этих входов. Когда пакет представляется в LFB через конкретный экземпляр входа, индекс этого входа известен LFB и может использоваться при внутренней обработке. Например, индекс входа может служить селектором таблицы или явным селектором предпочтений при возникновении «конкуренции» Как и для выходных групп, число экземпляров входов не определяется классом LFB. Однако определение класса может включать ограничения на диапазон возможных значений. Кроме того, если FE поддерживает настройку топологии, это может вносить дополнительные ограничесние на число экземпляров входов для конкретной группы определенного класса LFB. С учетом этих ограничений разные экземпляры одного класса могут иметь разное число входов.

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

В качестве примера входной группы рассмотрим Scheduler LFB на рисунке 4.c. LFB получает пакеты от множества Queue LFB через экземпляры входов и использует индекс входа для разрешения конфликтов и планирования.

Таким образом, класс LFB может определять один вход, множество одиночных входов, одну или множество входных групп, а также комбинации перечисленного. Любой вход позволяет неявно мультиплексировать потоки похожих пакетов при подключении множества выходов к одному входу. Явное мультиплексирование одиночных входов полезно в тех случаях, когда нужно явно предотвратить «конкуренцию» или класс LFB должен принимать и обрабатывать известное число потоков разнотипных пакетов. Входные группы подходят при необходимости явного предотвращения конфликтов, но число портов не наследуется от класса (и не было известно в момент определения класса) или когда для работы LFB критично знать через какой из входов был получен пакет.

3.2.3. Тип пакета

Когда классы LFB определены, должны быть заданы форматы входных и выходных пакетов (например, IPv4, IPv6, Ethernet). Это типы пакетов, которые вход данного LFB способен принимать и обрабатывать или выход LFB способен выдавать. Модель требует однозначно указывать разные типы пакетов именами и/или идентификаторами.

Отметим, что каждый LFB имеет набор пакетов, с которыми он работает, но не имеет значения, передает ли нижележащая (базовая) реализация большую часть пакета. Например, IPv4 LFB может работать только с пакетами IPv4, но нижележащая (базовая) реализация может вырезать или не вырезать заголовок L2 из пакета. Наличие или отсутствие такой обработки «непрозрачно» для CE.

3.2.4. Метаданные

Метаданные представляют собой состояние, которое передается от одного LFB к другому вместе с пакетом. Метаданные помогают последующим блокам LFB обрабатывать этот пакет.

Модель ForCES определяет метаданные как неделимые элементы в форме пар «имя-значение».

Модель ForCES предоставляет разработчикам классов LFB способы формального определения процедур создания, изменения, чтения и потребления (удаления) метаданных.

Метаданные Inter-FE, пересекающие границу FE, выходят за рамки этого документа, хотя семантически они похожи на обычные метаданные.

Неформальное описание метаданных приведено в разделе 4.

3.2.4.1. Жизненный цикл метаданных в модели ForCES

Каждый элемент метаданных представляется в виде пары <label, value>, где метка (label) указывает тип информации (например, color), а ее значение (value) задает реальную информацию (например, red). Здесь метка представлена в текстовой форме, но для протокольной обработки она связывается с числовым идентификатором.

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

3.2.4.2. Создание и потребление метаданных

Для данного элемента метаданных в данном пути пакета должен быть хотя бы один создающий метаданные LFB, а также на этом пути следует иметь хотя бы один потребляющий LFB, которому нужны эти метаданные.

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

Метаданные, которые производит LFB, задаются определением класса LFB на уровне группы выходных портов. Производитель может генерировать метаданные в группе портов всегда или при некоторых условиях. В первом случае мы называем метаданные безусловными, а во втором — условными. Например, LFB глубокой проверки пакетов производит несколько частей метаданных для пакета. Первым типом метаданных может быть протокол IP (TCP, UDP, SCTP, …), а вторым — номера портов отправителя и получателя. Эти дополнительные элементы метаданных являются условными и зависят от первого элемента (протокол IP), поскольку они имеют смысл лишь для протоколов, использующих порты. Для условных метаданных в определении LFB следует обеспечивать возможность понять, когда эти метаданные создаются. Поведение потребляющего метаданные LFB, т. е. метаданные, требующиеся для работы LFB, задается в определении класса LFB на уровне группы входных портов. Группа может «требовать» определенных метаданных, а может считать их дополнительной информацией. В последнем случае определение класса LFB должно явно указывать, что произойдет, если необязательные метаданные не будут предоставлены. Одним из вариантов является задание принятых по умолчанию значений для каждого необязательного элемента метаданных и использование таких значений в случаях когда метаданные не представлены с пакетом.

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

3.2.4.3. Операции LFB над метаданными

Когда пакет обрабатывается в LFB (т. е. после получения но до пересылки пакета), этот LFB может выполнять операции чтения, записи и/или поглощения активных метаданных, связанных с пакетом. Если рассматривать LFB как черный ящик, с каждым активным элементом метаданных выполняется одна из перечисленных операций.

  • IGNORE — игнорирование и пересылка.

  • READ — считывание и пересылка.

  • READ/RE-WRITE — считывание, запись нового значения и пересылка.

  • WRITE — запись и пересылка (это может служить для создания нового элемента метаданных).

  • READ-AND-CONSUME — считывание и поглощение.

  • CONSUME — поглощение (удаление) метаданных без считывания.

Две последних операции завершают жизненный цикл элемента метаданных, который не уже пересылается вместе с пакетом следующему LFB.

В модели ForCES новый элемент метаданных создается LFB путем выполнения операции WRITE к типу метаданных, которого не было при получении пакета блоком LFB. Такое неявное создание может быть непреднамеренным для LFB, который может применять операцию WRITE, не задаваясь вопросом о наличии такого элемента метаданных, Если этот тип уже присутствует, он будет переписан, а в случае отсутствия будет создан заново.

Для LFB, вставляющих пакеты в модель, имеет смысл лишь операция WRITE.

LFB, удаляющие пакет из модели, могут выполнять операцию READ-AND-CONSUME (считывание) или CONSUME (игнорирование) каждого активного элемента метаданных, связанного с пакетом.

3.2.5. События LFB

В процессе работы могут возникать различные условия, которые будут детектироваться LFB. Примерами могут служить отказы каналов или перезапуск по таймеру LFB специального назначения. CE может захотеть уведомлений о таких событиях. Описание передачи таких сообщений и их формата является частью спецификации протокола ForCES [RFC5810]. Очевидно, что указание условий, при которых могут передаваться уведомления относится к модели.

События указываются в определении класса LFB. Декларация события LFB включает:

  • уникальный 32-битовый идентификатор;

  • указание компоненты LFB, используемой для активизации события, которую называют сигналом события;

  • условия, при которых сигнал события будет приводить к генерации сообщения о событии для CE (примерами могут служить создание или удаление объекта, изменение конфигурации и т. п.);

  • что элементу FE следует передать CE при выполнении условий.

Объявление событий внутри класса LFB по существу определяет, для каких компонент LFB нужен мониторинг применительно к событию, какие условия должны должен обнаружить элемент FE для констатации события и что следует сообщать CE в ответ на событие.

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

Свойства событий также обеспечивают семантику фильтрации в процессе работы. CE может установить свойства для дополнительного подавления событий, на которые он уже подписан. Модель LFB определяет фильтры, включающие пороговые значения, гистерезис, временные интервалы, число событий и т. п.

Содержимое отчетов о событиях обеспечивает получение простой информации, которая может потребоваться CE для реакции на событие. Уведомления не предназначены для передачи сведений, которые уже имеются у CE, больших объемов информации или данных, относящихся к сложным формам.

С концептуальной точки зрения в процессе работы обслуживание событий делится на 4 части.

  1. Детектирование сигнала о событии (объявленного в определении класса LFB). Если CE подписан (во время работы) на событие, выполняется следующий этап.

  2. Проверка условий (заданы при определении класса LFB) генерации события. Если условия выполняются, переход к следующему этапу.

  3. Проверка установленных (во врекя работы) фильтров событий для определения дальнейшей судьбы события. Если о событии нужно уведомлять, выполняется следующий этап.

  4. Представления отчета (уведомления) элементу CE.

Более подробное описание событий приведено в параграфе 4.7.6.

3.2.6. Свойства компонент

Блоки LFB и структуры состоят из компонент, содержащих информацию о функционировании LFB, которую CE нужно просматривать и/или менять. Эти компоненты, как описано в параграфе 4.7, могут быть базовыми значениями, комплексными структурами (содержат множество компонент, которые могут быть значениями, структурами и таблицами) или таблицами (которые содержат значения, структуры или таблицы). Компоненты могут быть определены так, что их присутствие в экземплярах LFB будет не обязательно. Доступ к чтению и записи для компонент определяется реализацией FE. Элемент CE должен знать эти свойства. Кроме того, некоторые типы компонент (массивы и таблицы, псевдонимы, события) имеют дополнительную информацию о свойствах, которую элементу CE может потребоваться считывать или записывать. Модель задает структуру информации о свойствах для всх определяемых типов данных.

Более подробное описание свойств дано в параграфе 4.8.

3.2.7. Версии LFB

Версии классов LFB обеспечивают возможность поэтапного изменения этих классов. Обычно элементам FE не разрешается включать экземпляры LFB разных версий того или иного класса. Наследование (см. параграф 3.2.8) имеет некоторые правила. Если модель пути данных FE содержит экземпляр LFB некого класса C, а также экземпляр LFB другого класса C’, который является «наследником» C, классы C и C’ будут иметь разные версии.

Для поддержки версий класса LFB в определение класса нужно включать строку версии. Элементы CE могут поддерживать множество версий определенного класса LFB для обеспечения совместимости, однако FE недопустимо поддерживать более одной версии данного класса.

Использование версий не ограничивается обеспечением совместимости с ранними версиями. Предполагается, что они будут служить для внесения изменений, которые не могут быть представлены наследованием. Часто это будет исправление ошибок и совместимости со старыми версиями просто не может быть обеспечено. Версии могут также применяться при удалении компонент, которые признаны бесполезными (особенно в тех случаях, когда удаляемая компонента считалась обязательной).

3.2.8. Наследование LFB

Наследование класса LFB поддерживается в модели FE как метод определения новых классов LFB. Это также позволяет разработчикам FE добавлять фирменные расширения в стандартизованные LFB. Спецификация класса LFB должна указывать базовый класс и номер версии класса, которому она наследует (по умолчанию базовый класс LFB). Множественное наследование не поддерживается в целях предотвращения неоправданных сложностей.

Наследование следует применять лишь при использовании значительной части определения родительского класса LFB. При малом объеме или отсутствии повторно используемых определений следует определять новый класс LFB.

Интересным вопросом, связанным с наследованием, является совместимость наследника с классом-предком. Предположим существование некого стандартизованного класса LFB L1. Предположим также, что компания A создает FE, который реализует LFB L1, а компания B создает CE, который может распознавать и взаимодействовать с LFB L1. Пусть новый класс LFB L2 является наследником L1 и расширяет его возможности. Рассмотрим вопрос совместимости FE с прежней версией в контексте того, что производитель A обновил свой FE с версии L1 до версии L2, а B не обновил свой элемент CE. Основанный на старом L1 элемент CE сможет взаимодействовать с FE версии L2, если производный класс LFB L2 действительно совместим с базовым классом L1.

Обратный случай (переход CE на LFB L2 без обновления FE) вызывает гораздо меньше проблем. Отметим, что пока CE способен работать со старыми классами LFB, это не оказывает влияния на модель, поэтому термин «совместимость со старыми версиями» (backward compatibility) относится только к элементам FE.

Совместимость со старыми версиями может быть встроена в модель наследования путем ограничения наследования LFB требованием включения родительского класса в производный как подмножества (т. е. производный класс может только добавлять функции к базовому классу, но не может удалять имеющиеся в том функции). В дополнение к этому FE должен поддерживать перечисленные ниже механизмы для обеспечения совместимсоти со старыми версиями.

  1. При обнаружении экземпляра LFB неизвестного элементу CE типа CE должен быть способен запросить базовый класс этого типа LFB у элемента FE.

  2. Экземплярам LFB на FE следует поддерживать режим совместимости со старыми версиями (это означает возврат экземпляра LFB к базовому классу), а элементам CE следует поддерживать возможность настройки LFB для работы в таком режиме.

3.3. Адресация модели ForCES

На рисунке 5 показана абстракция двух разных объектов модели ForCES. Протокол ForCES обеспечивает механизмы однозначного указания компонент экземпляра класса LFB.

FE Address = FE01
+--------------------------------------------------------------+
|                                                              |
| +--------------+             +--------------+                |
| | LFB ClassID 1|             |LFB ClassID 91|                |
| | InstanceID 3 |============>|InstanceID 3  |======>...      |
| | +----------+ |             | +----------+ |                |
| | |Компоненты| |             | |Компоненты| |                |
| | +----------+ |             | +----------+ |                |
| +--------------+             +--------------+                |
|                                                              |
+--------------------------------------------------------------+

Рисунок 5. Иерархия FE Object.


На верхнем уровне иерархии адресации размещается идентификатор FE. В приведенном выше примере 32-битовый идентификатор FE обозначен FE01. Следующим 32-битовым селектором элемента является LFB ClassID. В нашем примере идентификаторы классов LFB имеют значения 1 и 91. далее на рисунке показано по одному экземпляру каждого класса. 32-битовые идентификаторы экземпляров класса LFB имеют значение только внутри данного класса LFB. Чтобы подчеркнуть это, на рисунке показаны экземпляры разных классов 1 и 91 с одним идентификатором 3.

Используя описанную схему адресации, сообщение можно отправить по адресу FE01, LFB ClassID 1, LFB InstanceID 3, с помощью протокола ForCES. Однако для повышения эффективности, такому сообщению следовало вы указывать также объекты внутри LFB. Эти объекты могут содержать состояния, возможности и т. п. Иллюстрация таких приведена на рисунке 6.

Показанные на рисунке 6 компоненты относятся к LFB Class ID 1, LFB InstanceID 3 на рисунке 5.

Компоненты LFB Class ID 1,InstanceID 3 
+-------------------------------------+
|                                     |
| LFB ComponentID 1                   |
| +----------------------+            |
| |                      |            |
| +----------------------+            |
|                                     |
| LFB ComponentID 31                  |
| +----------------------+            |
| |                      |            |
| +----------------------+            |
|                                     |
| LFB ComponentID 51                  |
| +----------------------+            |
| | LFB ComponentID 89   |            |
| | +-----------------+  |            |
| | |                 |  |            |
| | +-----------------+  |            |
| +----------------------+            |
|                                     |
|                                     |
+-------------------------------------+

Рисунок 6. Иерархия LFB.


LFB ComponentID 51 может представлять таблицу (массив). В этом случае для выбора компоненты LFB с ID 89 из седьмой записи в таблице можно использовать путь 51.7.89. В дополнение к поддержке явного выбора элемента таблицы путем включения индекса в разделенный точками путь модель позволяет указывать элементы таблиц по содержимому. Это называется использованием ключа или индексацией по ключу. Например, если ComponentID 51 представляет собой таблицу с поддержкой индексации по ключу, описывающий содержимое ключ также может передаваться элементом CE вместе и идентификатором таблицы 51 для выбора таблицы, а за ним будет следовать путь 89 для выбора элемента структуры в таблице, который после расчета в FE будет преобразовываться в LFB ComponentID 89 внутри заданной строки таблицы.

3.4. Моделирование пути данных FE

Пакеты, приходящие в FE из входных портов, обычно проходят через один или множество LFB прежде, чем попадут в выходные порты. Трактовка пакета элементом FE зависит от типа пакета (например, IPv4, IPv6, MPLS), значений заголовков, времени прибытия и других факторов. Результат обработки LFB может влиять на трактовку пакета нисходящими LFB. Эти различия можно концептуально рассматривать как наличие нескольких путей данных в FE. Например результат классификации по 6 элементами в LFB классификатора может влиять на выбор диапазона скорости в LFB измерителя на дальнейшем пути пакета.

Топология LFB представляется в форме направленного графа логических путей данных в FE, где узлы представляют экземпляры LFB, а направленные ребра — направление потока пакетов от одного LFB к следующему. В параграфе 3.4.1 рассмотрено моделирование путей данных FE с помощью топологии LFB, а в параграфе 3.4.2 рассматриваются вопросы, связанные с реконфигурацией топологии LFB.

3.4.1. Другие подходы к моделированию пути данных FE

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

  • Топологический подход

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

  • Кодирование состояний

    Другим вариантом разделения трактовки является применение метаданных. Результат операции LFB может быть представлен элементом метаданных, передаваемым вместе с пакетом нисходящим LFB. Такой LFB может использовать полученные метаданные и их значение (например, индекс некой таблицы) для определения способа обработки пакета.

Теоретически эти два подхода взаимозаменяемы, поэтому можно было бы рассмотреть один вариант описания всех путей данных в FE. Однако ни одна из этих моделей сама по себе не дает лучшего представления для практически важных случаев. Для конкретного FE с некими логическими путями данных применение двух разных вариантов моделирования будет приводить к существенно различающимся представлениям графа топологии LFB. Модель, использующая лишь топологический подход, будет требовать очень большого графа с множеством каналов или путей и узлов (экземпляры LFB) для представления всех возможных путей данных. С другой стороны, модель, использующая лишь кодированные состояния, будет ограничена строками LFB, которые не обеспечат интуитивно понятного описания разных путей данных (таких как MPLS и IPv4). Поэтому на практике скорей всего будет применяться сочетание этих подходов. Как будет показано ниже, эти два подхода можно комбинировать даже в одном LFB.

Используя простой пример классификатора с N выходами, подключенными к другим LFB, рисунок 7.a показывает, как выглядит топология LFB при использовании «чистого» топологического подхода. Каждый выход классификатора подключен к одному из N блоков LFB и метаданные не требуются. Топологический подход прост и интуитивно понятен. Однако, если число N велико и N узлов, следующих за классификатором (LFB#1, LFB#2, …, LFB#N), относятся к одному типу LFB (например, измеритель), но каждый из них имеет свои независимые компоненты, подход с кодированием состояний обеспечивает более простое представление топологии, как показано на рисунке 7.b. Этот подход требует таблицы из N строк с компонентами измерителей, обеспеченными узлами Meter, где каждая строка представляет атрибуты одного экземпляра измерителя. Нужны также метаданные M, которые передаются вместе с пакетом P от классификатора к измерителю, чтобы тот мог использовать M в качестве ключа поиска (индекса) нужной строки атрибутов, для конкретного пакета P.

Что же будет в случае N разнотипных узлов (LFB#1, LFB#2, …, LFB#N)? Например, если LFB#1 является очередью, а остальные — измерителями? Хотя и в этом случае можно использовать один из двух описанных вариантов, лучше будет объединить их. На рисунке 7.c показаны два функционально различающихся пути с использованием обеих моделей.

                                +----------+
                         P      |   LFB#1  |
                     +--------->|(Compon-1)|
+-------------+      |          +----------+
|            1|------+   P      +----------+
|            2|---------------->|   LFB#2  |
| classifier 3|                 |(Compon-2)|
|          ...|...              +----------+
|            N|------+          ...
+-------------+      |   P      +----------+
                     +--------->|   LFB#N  |
                                |(Compon-N)|
                                +----------+

(a) Использование «чистого» топологического подхода

+-------------+                 +-------------+
|            1|                 |   Meter     |
|            2|   (P, M)        | (Compon-1)  |
|            3|---------------->| (Compon-2)  |
|          ...|                 |   ...       |
|            N|                 | (Compon-N)  |
+-------------+                 +-------------+

(b) Использование состояний для представления топологии LFB (a) с однотипными LFB#1, LFB#2, …, LFB#N (например, измерители).

                             +-------------+
+-------------+ (P, M)       | queue       |
|            1|------------->| (Compon-1)  |
|            2|              +-------------+
|            3| (P, M)       +-------------+
|          ...|------------->|   Meter     |
|            N|              | (Compon-2)  |
+-------------+              |   ...       |
                             | (Compon-N)  |
                             +-------------+

(c) Использование комбинированного подхода при разнотипных LFB#1, LFB#2, …, LFB#N (например, очереди и измерители).

Рисунок 7. Пример моделирования путей данных FE.


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

Для комплексных топологий более гибкое решение обеспечивает комбинированный подход. Топологический подход следует применять в основном для случаев когда путь пакетов данных разветвляется в разные классы LFB (не просто различающиеся параметрами экземпляры одного класса LFB) и не требуются изменений типа добавления и удаления выходов LFB или такие изменения редки.

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

                   +---------------------------------------------+
                   |                                             |
     +----------+  V      +----------+           +------+        |
     |          |  |      |          |if IP-in-IP|      |        |
---->| входные  |->+----->|classifier|---------->|Decap.|---->---+
     |  порты   |         |          |---+       |      |
     +----------+         +----------+   |others +------+
                                         |
                                         V

(a) Топология LFB с логической петлей.

    +-------+   +-----------+            +------+   +-----------+
    |       |   |           |if IP-in-IP |      |   |           |
--->|входные|-->|classifier1|----------->|Decap.|-->+classifier2|->
    | порты |   |           |----+       |      |   |           |
    +-------+   +-----------+    |others +------+   +-----------+
                                 |
                                 V

(b) Топология LFB без петель с двумя независимыми экземплярами классификатора.

Рисунок 8. Пример топологии LFB.


Важно отметить, что описанная здесь топология LFB является логической и не связана с топологией физических соединений оборудования FE. Тем не менее, реальная реализация может оказывать влияние на отображение ее функциональности на топологию LFB. На рисунке 8 представлен пример FE, где пакет IP-in-IP от приложения IPsec (типа VPN) может сначала проходить через классификатор, который будет принимать во внимание внешний заголовок IP. После классификации пакета как IP-in-IP он будет передан в декапсулятор для удаления внешнего заголовка IP, а затем будет снова классифицироваться по внутреннему заголовку IP. При использовании одного программного или аппаратного модуля классификации для внутреннего и внешнего заголовка IP с общим набором правил фильтрации в логической топологии LFB естественным образом возникает петля, показанная на рисунке 8.a. Однако при использовании двух разных наборов фильтров (например, один набор для внешних заголовков IP, другой для внутренних) более естественным будет применение двух разных экземпляров LFB классификатора (рисунок 8.b).

3.4.2. Настройка топологии LFB

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

Почему пути данных в FE меняются динамически? Эти пути создаются элементами CE для предоставления неких услуг уровня данных (например, Diffserv, VPN) сетевым элементам (NE) потребителей. Целью изменения конфигурации путей данных является обеспечение элементам CE возможности настройки услуг, предоставляемых NE, в процессе работы. CE нужно менять пути данных при изменении требований к сервису типа добавления нового потребителя или изменении потребностей имеющегося заказчика. Однако следует отметить, что не все изменения путей данных меняют граф топологии LFB. Изменения графа зависят от подхода, используемого при отображении путей данных на топологию LFB. Как было отмечено в параграфе 3.4.1, топологический подход и подход, основанный на кодировании состояний приводят к существенно разным представлениям топологии LFB для одних и тех же путей данных. В общем случае топология LFB, основанная на чистом топологическом подходе, скорей всего будет приводить к более частым изменениям по сравнению с использованием подхода с кодированием состояний. Однако даже для топологии, основанной только на представлении состояний, время от времени может потребоваться изменение (например, для обхода некоторых LFB или добавления LFB). Поскольку для моделирования путей данных используется комбинация обоих подходов, изменение топологии LFB является важным аспектом модели FE.

Мы хотим отметить, что поддержка настраиваемой топологии LFB в модели FE не требует от всех FE реализации такой возможности. Если даже FE поддерживает настраиваемую топологию LFB, он может вносить ограничения для такой настройки. Оптимизированные по производительности аппаратные реализации могут не иметь возможностей такой настройки или сильно ограничивать их, а реализации FE на базе сетевых процессоров могут обеспечивать значительную гибкость и настраиваемость. Разработчики FE могут самостоятельно принимать решение о возможности настройки топологии и ограничениях для нее. Выбор простого решения для включения или отключения (обхода) некоторых LFB или более гибкой программной настройки конфигурации определяется внутренним устройством FE и выходит за рамки модели FE. В любом случае элементы CE должны быть способны определить возможности настройки FE. Поэтому модель FE должна обеспечивать механизм для описания возможностей настройки топологии LFB внутри элементов FE. Эти возможности могут включать (см. раздел 5):

  • указание классов LFB, экземпляры которых может создавать FE;

  • максимальное число экземпляров одного класса LFB;

  • топологические ограничения:

  • максимальное число экземпляров одного или разных классов, которые могут быть созданы в данной ветви графа;

  • ограничения по упорядочению LFB (например, любой экземпляр LFB класса A всегда должен быть нисходящим для любого экземпляра LFB класса B).

     +----------+     +-----------+
---->| Ingress  |---->|classifier |--------------+
     |          |     |chip       |              |
     +----------+     +-----------+              |
                                                 v
                     +-------------------------------------------+
       +--------+    |   Network Processor                       |
  <----| Egress |    |   +------+    +------+   +-------+        |
       +--------+    |   |Meter |    |Marker|   |Dropper|        |
             ^       |   +------+    +------+   +-------+        |
             |       |                                           |
  +----------+-------+                                           |
  |          |                                                   |
  |    +---------+       +---------+   +------+    +---------+   |
  |    |Forwarder|<------|Scheduler|<--|Queue |    |Counter  |   |
  |    +---------+       +---------+   +------+    +---------+   |
  +--------------------------------------------------------------+

Рисунок 9. Представление возможностей FE элементу CE.


Элементам CE нужна некоторая программная поддержка, чтобы справиться с рядом сложностей. Иными словами, даже при возможности CE настраивать топологию LFB для элемента FE, не предполагается возможность CE интерпретировать произвольную топологию LFB и определить конкретные услуги или приложения (например, VPN, Diffserv), поддерживаемые FE. Однако, если CE может грубо оценить возможности FE, элемент CE должен настроить топологию LFB для реализации сетевого сервиса, который требуется от NE. Таким образом, отображение, которое должно быть понятно CE, относится к сервису NE верхнего уровня для конкретной топологии LFB, а не наоборот. Не предполагается наличие у CE интеллектуальных возможностей трансляции политики сервиса на верхнем уровне в данные конфигурации для элементов FE. Однако можно предположить, что внутри данного домена сетевого сервиса некоторый интеллект может быть запрограммирован в CE, чтобы позволить тому понять какие LFB вовлечены в процесс для трансляции политики верхнего уровня в конфигурацию нижнего уровня для FE, задаваемую автоматически. Отметим, что это относится к внутренней реализации уровня управления и выходит за рамки модели FE, поэтому подробно в этом документе не рассматривается.

На рисунке 9 приведен пример, где маршрутизатор с поддержкой QoS13 имеет несколько интерфейсных плат с небольшим числом входных и выходных портов, специализированный контроллер классификатора и сетевой процессор с кодом блоков FE типа измерителей, маркировщиков, отбрасывателей, счетчиков, очередей, планировщиков и модулей пересылки IPv4. Часть топологии LFB уже зафиксирована и остается неизменной в соответствии с физическими соединениями интерфейсных плат. Например, все входные порты могут быть жестко соединены с контроллером классификации, чтобы все входящие пакеты сначала классифицировались. С другой стороны, блоки LFB на сетевом процессоре и порядок их применения являются программируемыми. Однако имеются некоторые ограничения возможностей и соединений между этими LFB. Ограничения возможностей могут включать:

  • 8 измерителей;

  • 16 очередей в одном FE;

  • планировщик не может обслуживать больше 16 очередей;

  • канальные ограничения могут включать:

  • после классификатора может следовать:

  • измеритель;

  • маркировщик;

  • отбрасыватель;

  • счетчик;

  • очередь или модуль пересылки IPv4но не планировщик;

  • за очередью может следовать только планировщик;

  • за планировщиком должен следовать модель пересылки IPv4;

  • последним LFB в пути данных перед отправкой в выходной порт должен быть модуль пересылки IPv4.

       +-----+    +-------+                      +---+
       |    A|--->|Queue1 |--------------------->|   |
------>|     |    +-------+                      |   |  +---+
       |     |                                   |   |  |   |
       |     |    +-------+      +-------+       |   |  |   |
       |    B|--->|Meter1 |----->|Queue2 |------>|   |->|   |
       |     |    |       |      +-------+       |   |  |   |
       |     |    |       |--+                   |   |  |   |
       +-----+    +-------+  |   +-------+       |   |  +---+
     classifier              +-->|Dropper|       |   |  IPv4
                                 +-------+       +---+  Fwd.
                                              Scheduler

Рисунок 10. Топология LFB, настроенная CE и воспринятая FE.

                                          Queue1
                  +---+                    +--+
                  |  A|------------------->|  |--+
               +->|   |                    |  |  |
               |  |  B|--+  +--+   +--+    +--+  |
               |  +---+  |  |  |   |  |          |
               | Meter1  +->|  |-->|  |          |
               |            |  |   |  |          |
               |            +--+   +--+          |          IPv4
               |         Counter1 Dropper1 Queue2|    +--+  Fwd.
       +---+   |                           +--+  +--->|A |  +-+
       |  A|---+                           |  |------>|B |  | |
------>|  B|------------------------------>|  |   +-->|C |->| |->
       |  C|---+                           +--+   | +>|D |  | |
       |  D|-+ |                                  | | +--+  +-+
       +---+ | |    +---+                  Queue3 | |Scheduler
   Classifier1 | |  |  A|------------>       +--+ | |
               | +->|   |                    |  |-+ |
               |    |  B|--+  +--+ +-------->|  |   |
               |    +---+  |  |  | |         +--+   |
               |  Meter2   +->|  |-+                |
               |              |  |                  |
               |              +--+           Queue4 |
               |            Marker1          +--+   |
               +---------------------------->|  |---+
                                             |  |
                                             +--+

Рисунок 11. Топология LFB, настроенная CE и воспринятая FE.


Когда FE сообщил о своих возможностях и ограничениях элементу CE, тот может транслировать правила QoS в желаемую конфигурацию для FE. На рисунке 9 показаны возможности FE, а рисунки 10 и 11 показывают две разных топологии, которые CE может настроить в FE. Отметим, что рисунок 11 неполон, поскольку каналы между LFB не указаны.

Отметим также, что на рисунках 10 и 11 для упрощения не показаны входы и выходы. Топология на рисунке 11 существенно сложнее, чем на рисунке 10, но оба варианта реализуемы в рамках возможностей FE и элемент FE может воспринять запрос такой конфигурации от CE.

4. Модель и схема для классов LFB

Основной целью модели FE является предоставление абстрактного базового модульного представления FE, не зависящего от реализации. Эта задача облегчается использованием блоков LFB, создаваемых из классов LFB. Классы LFB и связанные с ними определения будут представлены в наборе документов XML. Этот набор документов XML называется библиотекой классов LFB, а каждый из документов называется документом библиотеки классов LFB (или документом библиотеки для краткости). Каждый документ библиотеки должен соответствовать схеме, представленной в этом разделе. Схема и правила соответствия ей определяются консорциумом W3C в определениях схемы XML [Schema1] и типов данных схемы XML [Schema2]. Корневым элементом документа библиотеки является <LFBLibrary>.

Обмен документами библиотек «по проводу» между элементами FE и CE не предполагается. Однако модель служит основой для проектирования и разработки элементов CE (программы) и FE (в основном программная часть). Она будет также служить основой спецификации элементов протокола ForCES для коммуникаций между CE и FE.

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

4.1. Пространство имен

Пространство имен требуется для однозначной идентификации типа LFB в библиотеке классов LFB. Ссылки на определение пространства имен приведены в разделе 9. Взаимодействие с IANA.

4.2. Элемент <LFBLibrary>

Элемент <LFBLibrary> является корнем всех библиотечных документом. Документ библиотеки содержит последовательность элементов верхнего уровня. Ниже приведен список всех элементов, которые могут присутствовать непосредственно в <LFBLibrary> (имеющиеся элементы должны располагаться в указанном порядке.

  • <description> содержит текстовое описание назначения библиотечного документа;

  • <load> задает загрузку информации из других библиотечных документов;

  • <frameDefs> служит для объявления кадров;

  • <dataTypeDefs> служит для определения типов данных общего назначения;

  • <metadataDefs> служит для определения метаданных;

  • <LFBClassDefs> служит для определения классов LFB.

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

Документ библиотеки может импортировать другие библиотечные документы, если ему нужно ссылаться на содержащиеся в них определения. Это походе на директиву #include в языке программирования C. Импорт указывается с помощью элементов <load>, которые должны предшествовать в документе перечисленным выше элементам. Для однозначных ссылок каждый экземпляр документа LFBLibrary имеет уникальную метку, определенную в атрибуте provide элемента LFBLibrary. Отметим, что это включение относится к протоколу ForCES, а не к XML. Включается семантика содержимого библиотеки, указанной элементом <load>, а не содержимое XML. Кроме того, с точки зрения концептуальной обработки элементов <load> полный набор загружаемых документов считается одним документом. Указанный документ включается в этот набор лишь однократно, даже если он указан в нескольких элементах <load> (даже в разных файлах). Поскольку обработка информации LFBLibrary не зависит от порядка документов, порядок обработки загружаемых элементов определяется разработчиком и общий эффект будет определяться общим набором информации во всех указанных ссылками документах. Отметим, что такая компьютерная обработка библиотечных документов модели ForCES может быть полезна для различных реализаций, но не требуется для определения библиотек или реальных операций самого протокола.

Ниже приведен шаблон библиотечного документа.

       <?xml version="1.0" encoding="UTF-8"?>
       <LFBLibrary xmlns="urn:ietf:params:xml:ns:forces:lfbmodel:1.0"
         provides="this_library">

         <description>

         </description>

         <!-- Загрузка внешних библиотек (необязательно) -->
         <load library="another_library"/>
          ...
         <!-- Определения типов кадров (необязательно) -->
         <frameDefs>
          ...
         </frameDefs>

         <!-- Определения типов данных (необязательно) -->
         <dataTypeDefs>
          ...
         </dataTypeDefs>

         <!-- Определения метаданных (необязательно) -->
         <metadataDefs>
          ...
         </metadataDefs>

         <!--
           -
           -
            Определения классов LFB (необязательно) -->
         <LFBCLassDefs>

         </LFBCLassDefs>
         </LFBLibrary>

4.3. Элемент <load>

Этот элемент применяется для ссылки на другой документ библиотеки LFB. Подобно директиве #include в языке C, он делает объекты (типы метаданных и данных и т. п.), определенные в указанном документе библиотеки, доступными в текущем документе.

Элемент должен содержать метку библиотечного документа для включения и может включать идентификатор URL для указания места хранения документа. Элемент <load> может повторяться неограниченное число раз. Ниже представлены три примера элемента <load>.

   <load library="a_library"/>
   <load library="another_library" location="another_lib.xml"/>
   <load library="yetanother_library"
    location="http://www.example.com/forces/1.0/lfbmodel/lpm.xml"/>

4.4. Элемент <frameDefs> для определения типа кадра

Имена кадров используются в определении LFB для указания типов кадров, которые LFB ожидает на входных портах и выдает в выходные порты. Необязательный элемент <frameDefs> в документе библиотеки содержит один или множество элементов <frameDef> каждый из которых указывает один тип кадров.

Каждое указание типа кадра должно включать уникальное имя (NMTOKEN) и краткое описание. Дополнительно может представляться более подробное описание.

Уникальность имен типов должна обеспечиваться в рамках библиотечного документа и всех включенных в него (напрямую или опосредованно) библиотечных документов.

Приведенный ниже пример указывает два типа кадров.

   <frameDefs>
     <frameDef>
      <name>ipv4</name>
      <synopsis>IPv4 packet</synopsis>
      <description>
       Этот тип кадров относится к пакетам IPv4.
     </description>
    </frameDef>
     <frameDef>
     <name>ipv6</name>
     <synopsis>IPv6 packet</synopsis>
     <description>
       Этот тип кадров относится к пакетам IPv6.
     </description>
    </frameDef>
     ...
   </frameDefs>

4.5. Элемент <dataTypeDefs> для определения типа данных

Необязательный элемент <dataTypeDefs> может служить для определения типов данных общего пользования. Он содержит один или множество элементов <dataTypeDef>, каждый из которых определяет тип данных с уникальным именем. Такие типы данных могут затем использоваться в разных местах файла библиотеки, включая:

  • определения других типов данных;

  • определения компонент классов LFB.

Это похоже на концепцию общего заголовочного файла с типами данных общего пользования.

Каждый элемент <dataTypeDef> должен включать уникальное имя (NMTOKEN), краткое описание и элемент определения типа. Уникальность имен типов должна обеспечиваться в рамках библиотечного документа и всех включенных в него (напрямую или опосредованно) библиотечных документов. Элемент <dataTypeDef> может также включать дополнительное, более подробное описание.

   <dataTypeDefs>
     <dataTypeDef>
       <name>ieeemacaddr</name>
        <synopsis>48-битовый адрес IEEE MAC</synopsis>
         ... определение типа ...
     </dataTypeDef>
     <dataTypeDef>
       <name>ipv4addr</name>
        <synopsis>Адрес IPv4</synopsis>
        ... определение типа ...
     </dataTypeDef>
     ...
   </dataTypeDefs>

Существует два типа данный — неделимые (atomic) и композитные (compound). Неделимые типы данных подходят для переменных с одним значением (например, integer, string, byte array).

Ниже приведен список встроенных типов atomic, но можно определеить другие неделимые типы с помощью элементов <typeRef> и <atomic>.

Имя <name>

Значение

char

8-битовое целое число со знаком.

uchar

8-битовое целое число без знака.

int16

16-битовое целое число со знаком.

uint16

16-битовое целое число без знака.

int32

32-битовое целое число со знаком.

uint32

32-битовое целое число без знака.

int64

64-битовое целое число со знаком.

uint64

64-битовое целое число без знака.

boolean

Значение true (1) или false (0).

string[N]

Строка символов UTF-8 размером не более N октетов.

string

Строка символов UTF-8 без заданного ограничения размера.

byte[N]

Массив из N байтов.

octetstring[N]

Буфер размером N октетов, который может бы заполнен не до конца. Поэтому кодированное значение всегда включает размер.

float32

32-битовое число с плавающей запятой в формате IEEE.

float64

4-битовое число с плавающей запятой в формате IEEE.

Эти встроенные типы данных готовы для использования при определении метаданных или атрибутов LFB, но могут также служить для определения новых типов данных. Тип boolean определен здесь по причине его широкого использования, хотя его можно создать путем сужения типа uchar, как делается в типах atomic (параграф 4.5.2).

Композитные типы данных можно создавать или неделимых типов и других композитных типов. Для определения композитных типов имеется четыре способа. Их можно определять как массив компонент некого композитного или неделимого типа, как структуру именованных компонент неделимых или композитных типов (аналог структур C), как объединение (union) именованных компонент неделимых или структурных типов (аналог C union), а также как дополнения существующих композитных типов (см. параграф 4.5.7).

С учетом того, что протокол ForCES будет принимать и устанавливать значения компонент, все используемые здесь неделимые типы должны передаваться протоколом ForCES. Кроме того, для протокола ForCES нужен механизм передачи композитных типов. Однако детали таких представления относятся к документу, определяющему протокол ForCES [RFC5810], а не к данной модели. Типы string и octetstring должны передаваться протоколом вместе с полем размера, поскольку их фактический размер не задается определением.

Для строковых типов модель задает небольшой набор ограничений и определений способов структурирования. Ограничения размера для string и octetstring могут быть указаны в определениях классов LFB. Свойства компонент string и octetstring также включают действительные размеры и ограничения размера. Дублирование ограничений позволяет реализациям сократить максимальные размеры переменных, заданные в определении класса LFB. В любом случае ограничения задаются числом октетов, а не символов. При работе протокола если указанный размер не превосходит возможности FE, элемент FE полностью сохраняет содержимое строки, представленной CE, и возвращает такие строки по запросу. Элемент FE не выполняет преобразований строк. Компоненты типа string или string[n] могут применяться для хранения идентификаторов сопоставляемых с компонентами других LFB. В таких случаях должно проверяться пооктетное соответствие ьез каких-либо преобразований. Протокол ForCES [RFC5810] не проверяет и не требует проверки пригодности содержимого строк UTF-8. Однако строки UTF-8 следует кодировать в кратчайшей форме для предотвращения возможных проблем безопасности, описанных в [UNICODE]. Предполагается, что любой объект, отображающий такие строки, сам проверяет их пригодность (например, для корректировки многобайтовых символов или гарантии того, что строка не завершается в середине многобайтовой последовательности). Определения конкретных классов LFB могут ограничивать содержимое строк с учетом их применения (например, компоненты с именами DNS могут быть ограничены использованием лишь допустимых в таких именах октетов). Элементам FE следует проверять содержимое запросов SET для компонент с такими ограничениями при установке запрошенных значений путем простого сравнения с диапазоном разрешенных для компоненты символов. Протокол ForCES определяет нормативную обработку для используемых протоколом запросов.

Для задания типа в элементах <dataTypeDef> доступны элементы <typeRef>, <atomic>, <array>, <struct> и <union>.

Предопределенный псевдоним (alias) типа занимает промежуточное положение между типами данных atomic и compound. Псевдонимы служат для того, чтобы компоненты внутри LFB могли опосредованно ссылаться на другие компоненты внутри того же или другого класса или экземпляра LFB. Компонента alias ведет себя подобно структуре, в которой одна компонента имеет специальное назначение. Учетом того, что особое поведение связано с другими частями структуры, результат считается предопределенной конструкцией.

4.5.1. Элемент <typeRef> для переименования имеющихся типов данных

Элемент <typeRef> указывает на существующий тип данных по его имени. Упомянутый тип данных должен быть определен в том же документе или в одном из включенных в него библиотечных документов. Если указанный тип данных является неделимым, определенный заново тип так же будет относится к числу типов atomic. Если указанный тип является композитным, вновь определенный тип также будет композитным. Пример использования показан ниже.

   <dataTypeDef>
     <name>short</name>
     <synopsis>Псевдоним для int16</synopsis>
     <typeRef>int16</typeRef>
   </dataTypeDef>
   <dataTypeDef>
     <name>ieeemacaddr</name>
     <synopsis>48-битовый адрес IEEE MAC</synopsis>
     <typeRef>byte[6]</typeRef>
   </dataTypeDef>

4.5.2. Элемент <atomic> для создания производных неделимых типов

Элемент <atomic> позволяет определить новый неделимый тип на основе существующего типа atomic, задавая ограничения диапазона и/или представляя специальные перечисляемые значения. Отметим, что элемент <atomic> в качестве базовых может использовать только неделимые типы и результатом должен быть другой неделимый тип.

Например, приведенный ниже фрагмент определяет новый неделимый тип данных dscp.

   <dataTypeDef>
     <name>dscp</name>
     <synopsis>Код Diffserv.</synopsis>
     <atomic>
       <baseType>uchar</baseType>
       <rangeRestriction>
         <allowedRange min="0" max="63"/>
       </rangeRestriction>
       <specialValues>
         <specialValue value="0">
           <name>DSCP-BE</name>
           <synopsis>Best Effort</synopsis>
         </specialValue>
          ...
       </specialValues>
     </atomic>
    </dataTypeDef>

4.5.3. Элемент <array> для определения массивов

Элемент <array> может служить для создания новых композитных типов данных в форме массива композитных или неделимых типов. В зависимости от контекста этот и другие документы считают такие массивы и таблицы взаимозаменяемыми без учета синтаксиса и семантики. Тип элементов массива может быть задан ссылкой на имеющийся тип (с помощью элемента <typeRef>) или определением неименованного типа внутри элемента <array> с помощью элементов <atomic>, <array>, <struct> или <union>.

Массив может иметь фиксированный или переменный размер, что указывается атрибутом type элемента <array>. По умолчанию размер считается переменным и для него может указываться необязательный атрибут maxlength, задающий максимальный размер. Этот атрибут следует применять для задания семантических ограничений, а не ограничений реализации. Последнее (поддержка ограничений реализации) следует задавать с помощью возможностей компонент классов LFB и никогда не следует включать максимальный размер в тип данных array, размер которого считается неограниченным.

Для массивов фиксированного размера должен указываться атрибут length, задающий постоянный размер массива.

Результатом этой конструкции всегда является композитный тип, даже если массив имеет постоянный размер 1.

Массивы должны индексироваться только целыми числами и предполагается начало отсчета 0.

В дополнение к индексам массив может быть объявлен с использованием ключей. Это дает несколько эффектов:

  • лшюбой объявленный ключ может применяться в контексте протокола ForCES при выборе компонент для операций (см. спецификацию протокола ForCES [RFC5810]);

  • в любом экземпляре массива каждый объявленный ключ должен быть уникальным в рамках этого экземпляра, т. е. две компоненты массива не могут иметь одинаковых значений во всех полях, образующих ключ.

Каждый ключ объявляется с идентификатором keyID для использования в протоколе ForCES [RFC5810], где уникальный идентификатор формируется из одного или множества заданных полей ключа. Для поддержки случаев где массив неделимого типа с уникальными значениями может быть указан этими значениями в качестве идентификатора ключевого поля может применяться шаблон (т. е. элемент массива является ключом). Если типом значения массива является структура или массив, ключом служит одна или множество компонент значения, указываемых именами. Поскольку поле может быть компонентой включенной в массив структуры, компонентой компоненты структуры и т. д., имя поля на практике является конкатенацией идентификаторов компонент, разделенных точками. Синтаксис для идентификации полей ключа показан в приведенных ниже примерах массивов.

Этот пример показывает определение массива фиксированного размера с предопределенным типом данных.

     <dataTypeDef>
           <name>dscp-mapping-table</name>
           <synopsis>
              Таблица из 64 значений DSCP, используемая для переотображения кодов.
           </synopsis>
           <array type="fixed-size" length="64">
              <typeRef>dscp</typeRef>
           </array>
         </dataTypeDef>

Пример массива переменного размера с указанием верхнего предела.

         <dataTypeDef>
           <name>mac-alias-table</name>
           <synopsis>Таблица, содержащая до 8 адресов IEEE MAC</synopsis>
           <array type="variable-size" maxlength="8">
               <typeRef>ieeemacaddr</typeRef>
           </array>
         </dataTypeDef>

Пример массива с локальным (неименованным) определением типа содержимого.

         <dataTypeDef>
           <name>classification-table</name>
           <synopsis>Таблица правил классификации и кодов результата.</synopsis>
           <array type="variable-size">
             <struct>
               <component componentID="1">
                 <name>rule</name>
                 <synopsis>Правило для сопоставления</synopsis>
                 <typeRef>classrule</typeRef>
               </component>
               <component componentID="2">
                 <name>opcode</name>
                 <synopsis>Код результата</synopsis>
                 <typeRef>opcode</typeRef>
               </component>
            </struct>
           </array>
         </dataTypeDef>

В приведенном выше примере каждый элемент массива является структурой с двумя компонентами (rule и opcode).

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

      <dataTypeDef>
        <name>ipPrefixInfo_table</name>
        <synopsis>Таблица данных об известных префиксах</synopsis>
        <array type="variable-size">
          <struct>
            <component componentID="1">
              <name>address-prefix</name>
              <synopsis>Префикс, который будет описан</synopsis>
              <typeRef>ipv4Prefix</typeRef>
            </component>
            <component componentID="2">
              <name>source</name>
              <synopsis>Протокол или процесс, обеспечивший эту информацию</synopsis>
              <typeRef>uint16</typeRef>
            </component>
            <component componentID="3">
              <name>prefInfo</name>
              <synopsis>Информация, о которой мы заботимся</synopsis>
              <typeRef>hypothetical-info-type</typeRef>
            </component>
          </struct>
          <contentKey contentKeyID="1">
            <contentKeyField> address-prefix.ipv4addr</contentKeyField>
            <contentKeyField> address-prefix.prefixlen</contentKeyField>
            <contentKeyField> source</contentKeyField>
          </contentKey>
        </array>
      </dataTypeDef>

Отметим, что элементами keyField могут также быть просто address-prefix и source, поскольку они включают все поля.

4.5.3.1. Ссылки на поля ключа

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

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

Допустимая строка для одного идентификатора поля в keyField зависит от текущего контекста. Изначально в объявлении ключа массива контекстом служит тип массива. Далее контекстом может стать любой тип, выбранный идентификаторами полей, которые к тому моменту были обработаны в текущем объявлении поля ключа.

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

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

При использовании в ссылках массивой и структур возможно создать keyFields, которого не существует. В ссылках keyField не следует указывать необязательные компоненты структуры. Для ссылок на элементы массива следует соблюдать осторожность, чтобы обеспечить наличие элементов массива при создании или изменении элемента массива в целом. Несоблюдение этого будет приводить к ошибке FE при попытке создания и возврату соответствующего сообщения.

4.5.4. Элемент <struct> для определения структур

Структура состоит из набора компонент с данными. Каждая компонента имеет тип (неделимый или композитный) и имя, которое должно быть уникальным в области действия определения композитного типа. Это похоже на struct в языке C. Компоненты определяются с помощью элементов <component>. Элемент <struct> может содержать элемент <derivedFrom>, указывающий базовую структуру. Определение структуры должно включать не менее одного элемента <component>.

Фактический тип компоненты может определяться ссылкой на имеющийся тип (элемент <typeRef>) или задаваться локальным (неименованным) типом, созданным с использованием элементов <atomic>, <array>, <struct> или <union>.

Элемент <component> должен включать атрибут componentID, обеспечивающий числовой идентификатор компоненты для использования протоколом. В элемент <component> должны включаться также имя и краткое описание компоненты, дополнительно может включаться элемент <description> с более подробным описанием. Определение может также включать элемент <optional>, указывающий, что определяемая компонента не является обязательной. Определение должно содержать элементы, определяющие тип компоненты, как описано выше.

Для dataTypeDef определение структуры может быть унаследовано от ранее определенного структурированного типа и дополнено. Это указывается включением необязательного атрибута derivedFrom в объявление структуры до определения дополнений или замены компонент (см. параграф 4.5.7).

Атрибуты componentID для разных компонент структуры (или LFB) должны различаться. Задавать какой-либо порядок идентификаторов не требуется. Для удобочитаемости и упрощения обслуживания обычно определяется набор последовательных значений, но это не является требованием протокола.

Результатом этой конструкции всегда будет композитный тип, даже при наличии в <struct> лишь одного поля.

Пример определения структуры приведен ниже.

   <dataTypeDef>
    <name>ipv4prefix</name>
    <synopsis>Префикс IPv4, определяемый адресом и размером префикса</synopsis>
    <struct>
     <component componentID="1">
      <name>address</name>
      <synopsis>Адресная часть префикса</synopsis>
      <typeRef>ipv4addr</typeRef>
     </component>
     <component componentID="2">
      <name>prefixlen</name>
      <synopsis>Размер префикса</synopsis>
      <atomic>
       <baseType>uchar</baseType>
       <rangeRestriction>
        <allowedRange min="0" max="32"/>
       </rangeRestriction>
      </atomic>
     </component>
    </struct>
   </dataTypeDef>

4.5.5. Элемент <union> для определения типов объединений

Подобно объявлению union в языке C, эта конструкция позволяет определять оверлейные типы. Формат аналогичен формату элемента <struct>.

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

4.5.6. Элемент <alias>

Иногда в LFB или структуре нужна компонента, ссылающаяся на информацию (или компоненту) в другом LFB. Это может позволять, например, использовать в ARP LFB таблицу трансляции адресов IP->MAC совместно с LFB локальной передачи без дублирования информации. Аналогично можно позволить LFB измеритель трафика разделять информацию с LFB формирования трафика. Для создания таких конструкций служит элемент <alias>. Конструкция позволяет сказать элементам CE и FE, что любые манипуляции с определенными данными на деле применяются к данным, находящимся в некой заданной части другого указанного экземпляра LFB. Содержимое элемента <alias> должно быть именованным типом. Независимо от того, на какую компоненту указывает псевдоним (это определяется описанными ниже свойствами компоненты псевдонима), эта компонента должна иметь такой же тип, какой был заявлен для псевдонима. Таким образом, когда CE или FE разыменовывает компоненту псевдонима, тип возвращаемой информации известен. Этим типом может быть как базовый, так и производный тип. Когда операция GET или SET указывает на псевдоним, возвращается или изменяется значение, на которое этот псевдоним указывает (цель). Запись в псевдоним будет разрешена, если имеется возможность записи в цель псевдонима.

Цель компоненты, объявленной элементом <alias>, определяется информацией в свойствах компоненты. Подобно другим компонентам, ее свойства включают поддержку разрешений на считывание и запись для псевдонима. В дополнение к этому в свойствах псевдонима имеется несколько полей (компонент), определяющих цель. Этими компонентами являются идентификаторы класса и экземпляра для LFB, а также последовательность целых чисел, представляющая пути в целевом LFB к целевой компоненте. Тип целевого элемента должен совпадать с объявленным типом псевдонима. Подробности структуры псевдонима описаны в параграфе 4.8.

Отметим, что свойства чтения и записи для псевдонима указывают на значения. CE может проверить возможность записи, лишь предприняв попытку выполнения такой операции (компоненты свойств сами не имеют свойств).

4.5.7. Дополнения

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

Дополнения недопустимо применять к объединению (union).

Одним из следствий этого является совместимость дополнений с базовым типом, из которого дополнение создано. Таким образом, дополнения полезны для определения компонент субклассов LFB, совместимых со своими «прародителями». Кроме добавления в класс новых компонент типы данных существующих компонент могут быть заменены их дополнениями и при этом будут соответствовать правилам совместимости для субклассов. Именно это служит причиной неприменимости дополнений к типу union.

Рассмотрим, например, простой базовый блок LFB класса A, имеющий одну компоненту (comp1) типа X. Одним из способов создать класс A1 из A является простое добавление второй компоненты (любого типа). Другим способом создать класс A2 из A является замена в A исходной компоненты (comp1) типа X на тип Y, который является дополнением (расширением) X. Оба класса A1 и A2 совместимы с классом A.

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

4.6. Элемент <metadataDefs> для определения метаданных

Необязательный элемент <metadataDefs> в библиотечном документе содержит один или множество элементов <metadataDef>, определяющих метаданные.

Каждый элемент <metadataDef> должен содержать уникальное имя (NMTOKEN). Уникальность определяется среди всех метаданных в масштабе библиотечного документа и всех включенных в него (напрямую или косвенно) библиотечных документов. Элемент <metadataDef> должен также включать краткое описание (synopsis), значение тега, используемое для этих метаданных и информацию об определении типа значения. В качестве значений метаданных могут применяться лишь неделимые (atomic) типы данных. Элемент <metadataDef> может содержать элемент с подробным описанием.

Разрешены две формы определения типа. Первая форма использует элемент <typeRef> для указания имеющегося неделимого типа данных, определенного в элементе <dataTypeDefs> того же библиотечного документа или включенного в него документа. Использование элемента <typeRef> идентично использованию элементов <dataTypeDef>, за исключением того, что они могут указывать лишь неделимые типы. Последнее ограничение не проверяется схемой XML.

Вторая форма использует явное определение типа с помощью элемента <atomic>, который используется здесь так же, как в элементах <dataTypeDef>.

Ниже приведен пример использования обеих форм.

   <metadataDefs>
    <metadataDef>
     <name>NEXTHOPID</name>
     <synopsis>Указывает элемент Next Hop в NH LFB</synopsis>
     <metadataID>17</metadataID>
     <typeRef>int32</typeRef>
    </metadataDef>
    <metadataDef>
     <name>CLASSID</name>
     <synopsis>Результат классификации (0 говорит о несоответствии).</synopsis>
     <metadataID>21</metadataID>
     <atomic>
      <baseType>int32</baseType>
      <specialValues>
       <specialValue value="0">
        <name>NOMATCH</name>
        <synopsis>Классификация не нашла соответствия.</synopsis>
       </specialValue>
      </specialValues>
     </atomic>
    </metadataDef>
   </metadataDefs>

4.7. Элемент <LFBClassDefs> для определения классов LFB

Необязательный элемент <LFBClassDefs> можно использовать для определения одного или множества классов LFB с помощью элементов <LFBClassDef>. Каждый элемент <LFBClassDef> должен определять класс LFB и включать перечисленные ниже элементы.

  • <name> указывает символьное имя класса LFB (например ipv4lpm).

  • <synopsis> содержит краткое описание класса LFB (например, IPv4 Longest Prefix Match Lookup LFB).

  • <version> указывает номер версии.

  • <derivedFrom> указывает предка.

  • <inputPorts> перечисляет входные порты и их спецификации.

  • <outputPorts> перечисляет выходные порты и их спецификации.

  • <components> определяет рабочие компоненты LFB.

  • <capabilities> определяет компоненты возможностей (capability) LFB.

  • <description> содержит операционную спецификацию LFB.

  • Атрибут LFBClassID элемента LFBClassDef определяет идентификатор класса, который должен быть уникальным в глобальном масштабе.

  • <events> определяет события, которые могут генерироваться экземплярами этого класса LFB.

Имена классов LFB должны быть уникальными, чтобы другие документы могли указывать классы по имени, а читатели могли понимать ссылки на классы по именам. Комплексное именование но возбраняется, но приветствуется простота. Как указано в разделе 9. Взаимодействие с IANA, агентство IANA поддерживает реестр имен и идентификаторов классов LFB со ссылками на определяющие классы документы.

Ниже приведена структура определения класса LFB. Отметим, что в целях упрощения схемы XML порядок размещения элементов в определении класса фиксирован. Имеющиеся в определении элементы должны размещаться в указанном ниже порядке.

   <LFBClassDefs>
    <LFBClassDef LFBClassID="12345">
     <name>ipv4lpm</name>
     <synopsis>LFB поиска максимального размера соответствия префикса IPv4</synopsis>
     <version>1.0</version>
     <derivedFrom>baseclass</derivedFrom>

     <inputPorts>
      ...
     </inputPorts>

     <outputPorts>
      ...
     </outputPorts>

     <components>
      ...
     </components>

     <capabilities>
      ...
     </capabilities>

     <events>
      ...
     </events>

     <description>
      Этот класс LFB представляет операцию поиска префикса IPv4 с 
      максимальной длиной совпадения.
      Моделируемым поведением является ...
     </description>

    </LFBClassDef>
    ...
   </LFBClassDefs>

Отдельные компоненты и возможности имеют идентификаторы для использования протоколом ForCES. Эти componentID используются в структурах, подобно именам. Значения componentID для компонент и возможностей должны быть уникальными в рамках определения класса LFB.

Отметим, что элементы <name>, <synopsis> и <version> являются обязательными, а все остальные элементы могут отсутствовать в <LFBClassDef>. Однако при наличии необязательных элементов они должны размещаться в указанном выше порядке.

Атрибуты componentID для разных элементов в определении класса LFB (или компонент в структуре) должны различаться. Для них не требуется упорядоченности или последовательного выделения. Для удобства читателей и упрощения поддержки значения обычно выделяют последовательно, но этого не требует ни модель, ни протокол.

4.7.1. Элемент <derivedFrom> для выражения наследования LFB

Необязательный элемент <derivedFrom> может служить для указания того, что данный класс происходит от другого класса. Содержимым этого элемента должно быть уникальное имя (<name>) другого класса LFB, который должен быть определен в том же библиотечном документе или во включенном в него документе. При отсутствии элемента <derivedFrom> класс концептуально выводится из пустого базового класса.

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

4.7.2. Элемент <inputPorts> для определения входов LFB

Необязательный элемент <inputPorts> служит для определения входных портов. Класс LFB может не иметь входов или иметь один или более вход. Если у класса LFB нет входных портов, элемент <inputPorts> должен отсутствовать. Элемент <inputPorts> может содержать один или множество элементов <inputPort>, по одному для каждого порта или группы портов. Предполагается, что большинство LFB будет иметь один вход. Множество входов одного типа моделируется как входная группа. Группы определяются так же, как входные порты с помощью элемента <inputPort>, отличаясь лишь атрибутом group.

Следует избегать множества разнотипных портов (см. параграф 4.7.3). Некоторые LFB специального назначения совсем не имеют входов. Например, LFB генератора пакетов входы не требуются.

Отдельные входные порты и группы входных портов определяются элементами <inputPort> и различаются лишь необязательным атрибутом group.

Элемент <inputPort> должен включать перечисленные ниже элементы.

  • <name> указывает символьное имя входного порта (например, in). Отметим, что имя должно быть уникальным в рамках класса LFB.

  • <synopsis> содержит краткое описание входа (например, Normal packet input).

  • <expectation> перечисляет все разрешенные форматы кадров (например, {ipv4 и ipv6}. Отметим, что в список следует включать имена, заданные в элементе <frameDefs> того же библиотечного документа или включенных в него документов. Элемент <expectation> может также содержать список требуемых метаданных (например, {classid, vpnid}. В список следует включать имена, заданные в элементе <metadataDefs> того же библиотечного документа или включенных в него документов. Для каждого элемента метаданных должно быть указано, является он обязательным или опциональным. Для необязательных метаданных должно быть указано значение, которое LFB будет использовать при отсутствии соответствующих метаданных у пакета.

В дополнение к этому необязательный атрибут group в элементе <inputPort> может указывать, что порт может вести себя как группа портов, т. е позволяет создавать экземпляры. Это указывается значением атрибута true (по умолчанию создание экземпляров запрещено — false).

Пример элемента <inputPorts>, определяющего два входных порта, из которых второй является группой, показан ниже.

   <inputPorts>
    <inputPort>
     <name>in</name>
     <synopsis>Обычный вход</synopsis>
     <expectation>
      <frameExpected>
       <ref>ipv4</ref>
       <ref>ipv6</ref>
      </frameExpected>
      <metadataExpected>
       <ref>classid</ref>
       <ref>vifid</ref>
       <ref dependency="optional" defaultValue="0">vrfid</ref>
      </metadataExpected>
     </expectation>
    </inputPort>
    <inputPort group="true">
     ... другой входной порт ...
    </inputPort>
   </inputPorts>

Для каждого элемента <inputPort> ожидаемые типы кадров определяются элементом <frameExpected> с одним или несколькими элементами <ref> (см. пример выше). При указании нескольких типов кадров ожидается один из перечисленных. Пакеты всех остальных типов считаются несовместимыми с этим входным портом в данном классе LFB. В приведенном выше примере ожидаемыми типами кадров являются ipv4 и ipv6.

Ожидаемые метаданные указываются элементом <metadataExpected>. В простейшей форме этот элемент может содержать список элементов <ref>, каждый из которых указывает элемент метаданных. При указании множества экземпляров метаданных в элементах <ref> это означает, что каждый принятый пакет должен сопровождаться всеми этими метаданными (за исключением метаданных, помеченных как optional в атрибуте dependency соответствующего элемента <ref>). Для необязательных (optional) метаданных должно указываться принятое по умолчанию значение с помощью атрибута defaultValue. В приведенном выше примере указаны три ожидаемых элемента метаданных, два из которых обязательны (classid и vifid), а один не обязателен (vrfid).

Схема также позволяет более сложные определения ожидаемых метаданных. Например, с помощью элемента <one-of> можно указать список метаданных, из которого с пакетом должен быть представлен один элемент. Например,

   <metadataExpected>
    <one-of>
     <ref>prefixmask</ref>
     <ref>prefixlen</ref>
    </one-of>
   </metadataExpected>

Здесь метаданные prefixmaskили prefixlen должны сопровождать каждый пакет.

Две формы указания метаданных можно комбинировать, как показано ниже.

   <metadataExpected>
    <ref>classid</ref>
    <ref>vifid</ref>
    <ref dependency="optional" defaultValue="0">vrfid</ref>
    <one-of>
     <ref>prefixmask</ref>
     <ref>prefixlen</ref>
    </one-of>
   </metadataExpected>

Хотя схема позволяет определять и более сложные конструкции для ожидаемых метаданных, здесь они не рассматриваются.

4.7.3. Элемент <outputPorts> для определения выходов LFB

Необязательный элемент <outputPorts> служит для определения выходных портов. Класс LFB может совсем не иметь выходов или содержать один или несколько выходных портов. Если у класса LFB нет выходных портов, элемент <outputPorts> должен отсутствовать. Элемент <outputPorts> должен включать один или несколько элементов <outputPort>, по одному для каждого порта или группы портов. При наличии множества однотипных выходов они моделируются как группа выходных портов. Некоторые LFB специального назначения не имеют выходных портов (например, Dropper).

Одиночные выходные порты и отдельные группы определяются элементами <outputPort> и различаются лишь необязательным атрибутом group.

Элемент <outputPort> должен содержать перечисленные ниже элементы.

  • <name> указывает символьное имя выходного порта (например, out). Отметим, что имя должно быть уникальным в рамках класса LFB.

  • <synopsis> содержит краткое описание входа (например, Normal packet output).

  • <product> перечисляет все разрешенные форматы кадров (например, {ipv4 и ipv6}. Отметим, что в список следует включать имена, заданные в элементе <frameDefs> того же библиотечного документа или включенных в него документов. Элемент <product> может также содержать список выдаваемых (генерируемых) метаданных (например, {classid, color}. В список следует включать имена, заданные в элементе <metadataDefs> того же библиотечного документа или включенных в него документов. Для каждого генерируемого элемента метаданных следует указать, создается он всегда или при заданных условиях. Эта информация нужна при оценке совместимости LFB.

В дополнение к этому необязательный атрибут group в элементе <outputPort> может указывать, что порт может вести себя как группа портов, т. е позволяет создавать экземпляры. Это указывается значением атрибута true (по умолчанию создание экземпляров запрещено — false).

Пример элемента <outputPort>, определяющего 2 выходных порта, из которых второй является группой, показан ниже.

   <outputPorts>
    <outputPort>
     <name>out</name>
     <synopsis>Обычный вывод</synopsis>
     <product>
      <frameProduced>
       <ref>ipv4</ref>
       <ref>ipv4bis</ref>
      </frameProduced>
      <metadataProduced>
       <ref>nhid</ref>
       <ref>nhtabid</ref>
      </metadataProduced>
     </product>
    </outputPort>
    <outputPort group="true">
     <name>exc</name>
     <synopsis>Группа портов для вывода в исключительных случаях</synopsis>
     <product>
      <frameProduced>
       <ref>ipv4</ref>
       <ref>ipv4bis</ref>
      </frameProduced>
      <metadataProduced>
       <ref availability="conditional">errorid</ref>
      </metadataProduced>
     </product>
    </outputPort>
   </outputPorts>

Типы кадров и метаданных, выдаваемых портом определяются в элементе <product> каждого <outputPort>. Внутри <product> список производимых портом типов кадров указывается в элементе <frameProduced>. При указании нескольких типов это значит, что порт будет выдавать один из указанных типов.

Список метаданных, выдаваемых портом указывается в необязательном элементе <metadataProduced> внутри <product>. В простейшей форме этот элемент содержит список элементов <ref>, каждый из которых задает тип метаданных. При наличии списка все метаданные из него выдаются с каждым пакетом (за исключением помеченных необязательным атрибутом availability со значением conditional). Подобно элементу <metadataExpected> в <inputPort>, элемент <metadataProduced> поддерживает более сложные формы, которые здесь не рассматриваются.

4.7.4. Элемент <components> для определения рабочих компонент LFB

Рабочие параметры LFB, которые должны быть видимыми для CE, собираются в модели как компоненты LFB. Это включает, например, флаги, аргументы с одним параметром, составные аргументы и таблицы. Отметим, что компонентами здесь называются лишь рабочие параметры LFB, которые должны быть видимыми для CE. Другие переменные, которые являются внутренними для реализации LFB, не считаются компонентами LFB и не указываются здесь.

Ниже перечислены некоторые из компонент LFB.

  • Настраиваемые флаги и переключатели рабочих режимов LFB.

  • Число входов или выходов в группе портов.

  • Настраиваемые таблицы поиска, включа таблицы интерфейсов, префиксов, классификаци, отображения DSCP, MAC-адресов и т. п.

  • Счетчики пакетов и байтов.

  • Счетчики событий.

  • Текущее число входов или выходов для каждой группы входов или выходов.

Модель ForCES поддерживает определение ограничений доступа, указывающих, что может делать CE с компонентами LFB. Ниже перечислены поддерживаемые моделью категории доступа.

  • No-access — нет доступа. Применяется для полноты и позволяет определять объекты, используемые другими, но не указываемые непосредственно элементами управления CE. Это полезно также для FE, сообщающих, что для некоторых определенных и обычно доступных компонент не поддерживается доступ со стороны CE.

  • Read-only — только чтение.

  • Read-write — чтение и запись.

  • Write-only — только запись. Это могут быть любые настраиваемые данные, чтение которых не разрешено для CE (например, ключи защиты).

  • Read-reset — чтение и сброс. CE может считывать и сбрасывать этот ресурс, но не может установить для него произвольное значение. Примером могут служить счетчики.

  • Firing-only — инициирование. Попытка записи в этот ресурс будет вызывать в LFB крнкретные действия, но записанное значение игнорируется.

Класс LFB должен определять для данной компоненты лишь один из возможных режимов доступа.

Компоненты класса LFB перечисляются в элементе <components>, где для каждой компоненты используется элемент <component>, содержащий все или некоторые из перечисленных ниже элементов, часть которых обязательна.

  • <name> определяет имя компоненты, которое должно присутствовать. Имя должно быть уникальным среди компонент класса LFB (например, version).

  • <synopsis> обеспечивает краткое описание назначения компоненты и является обязательным.

  • <optional/> является необязательным элементом, наличие которого указывает необязательность компоненты.

  • Тип данных компоненты может быть указан ссылкой на предопределенный тип данных или локальным определением типа. Ссылка на определение задается с помощью элемента <typeRef>, который должен указывать уникальное имя имеющегося типа данных, который определен элементом <dataTypeDefs> в этом же библиотечном документе или в любом из включенных в него документов. При локальном определении данных (безымянный тип) используется один из элементов <atomic>, <array>, <struct> или <union>. Их использование аналогично использованию внутри элементов <dataTypeDef> (параграф 4.5). В определении компоненты должна быть включена та или иная форма определения типа данных.

  • <defaultValue> является необязательным элементов и при наличии указывает принятое по умолчанию значение компоненты. Если принятое по умолчанию значение задано, элемент FE должен обеспечить установку этого значения компоненты при инициализации или сбросе LFB. Если принятое по умолчанию значение для компоненты не задано, элементу CE недопустимо принимать какие-либо допущения о значении компоненты при инициализации. Элемент CE должен считать или установить значение, если хочет знать его.

  • <description> может включаться в определение для более детального описания назначения или использования определяемой компоненты.

Элемент <component> должен иметь атрибут componentID, числовое значение которого используется протоколом ForCES.

В дополнение к перечисленным элементам <component> включает необязательный атрибут access, который может принимать значение read-only, read-write (используется по умолчанию), write-only, read-reset или trigger-only.

Поддержка необязательных компонент и возможность реальной записи в компоненты read-write может быть определена для данного экземпляра LFB элементом CE путем считывания информации о свойствах компоненты. Установка режима доступа trigger-only означает включение компоненты для использования лишь в качестве детектора событий.

Приведенный ниже пример определяет две компоненты для LFB.

   <components>
    <component access="read-only" componentID="1">
     <name>foo</name>
     <synopsis>число объектов</synopsis>
     <typeRef>uint32</typeRef>
    </component>
    <component access="read-write" componentID="2">
     <name>bar</name>
     <synopsis>число других объектов</synopsis>
     <atomic>
      <baseType>uint32</baseType>
      <rangeRestriction>
       <allowedRange min="10" max="2000"/>
      </rangeRestriction>
     </atomic>
     <defaultValue>10</defaultValue>
    </component>
   </components>

Первая компонента (foo) является доступным лишь для чтения 32-битовым целым числом без знака, определяемым ссылкой на встроенный неделимый тип uint32. Вторая компонента (bar) также является целым числом, но использует элемент <atomic> для задания дополнительных ограничений диапазона. Эта компонента доступна для чтения и записи. По умолчанию для нее задано значение 10. Хотя доступ разрешен для чтения и записи, некоторые реализации могут дополнительно ограничивать доступ и это будет указано в свойствах компоненты.

Отметим, что не все компоненты обязательно присутствуют в каждой реализации. Хотя возможности зачастую указывают отсутствие, элементы CE могут ссылаться на отсутствующие или неразрешенные компоненты. Следует предусматривать механизмы протокола ForCES для индикации таких ошибок.

Определенный выше механизм для неподдерживаемых компонент может также применяться для ссылок на отсутствующие элементы массива или попытки записи в компоненты, для которых разрешено лиш чтение.

4.7.5. Элемент <capabilities> для определения возможностей LFB

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

Такая информация выражается компонентами возможностей класса LFB, которые всегда являются доступными лишь для чтения атрибутами и указываются в отдельном элементе <capabilities> определения <LFBClassDef>. Элемент <capabilities> содержит один или множество элементов <capability>, кажый из которых определяет одну возможность. Формат элемента <capability> похож на формат <component> и отличается лишь отсутствием атрибута режима доступа (всегда read-only) и элемента <defaultValue> (принятое по умолчанию значение не применимо к атрибутам read-only).

Ниже приведены некоторые примеры возможностей.

  • Версия класса LFB с которой был собран экземпляр LFB.

  • Поддерживаемые необязательные возможности класса LFB.

  • Максимальное число настраиваемых выходов в выходной группе.

  • Ограничения LFB на передачу метаданных.

  • Дополнительные ограничения диапазона рабочих компонент.

Ниже приведен пример с двумя атрибутами возможностей.

   <capabilities>
    <capability componentID="3">
     <name>version</name>
     <synopsis>
      Версия класса LFB, которой соответствует экземпляр.
     </synopsis>
     <typeRef>version</typeRef>
    </capability>
    <capability componentID="4">
     <name>limitBar</name>
     <synopsis>
      Максимальное значение атрибута bar.
     </synopsis>
     <typeRef>uint16</typeRef>
    </capability>
   </capabilities>

4.7.6. Элемент <events> для генерации уведомлений LFB

Элемент <events> содержит информацию о событиях, для которых экземпляры этого класса LFB могут генерировать уведомления для CE. Общее описание объявления и работы с событиями LFB приведено в параграфе 3.2.5.

Элемент <events> может (но не обязан) содержать элементы <event>, каждый из которых описывает одно событие и имеет атрибут eventID с уникальным (для класса LFB) идентификатором события и включает элементы:

  • <eventTarget>, указывающий поле (компоненту) LFB, проверяемую для генерации события;

  • <condition>, указывающий для поля условие генерации события из списка определенных условий;

  • <eventReports>, указывает значения, включаемые в уведомление о событии.

В приведенном ниже примере показано несколько разных конструкций.

Элемент <events> имеет атрибут baseID, который обычно имеет форму <events baseID=»number»>. Значением baseID является стартовый идентификатор componentID для пути, указывающего события. Он должен отличаться от componentID всех компонент верхнего уровня (включая возможности) класса LFB. В производных LFB (т. е. имеющих элемент <derivedFrom>), у которых родительский класс LFB имеет объявления для событий, значению baseID недопустимо присутствовать в элементе <events> производного LFB и взамен используется значение baseID из родительского класса LFB. В приведенном примере baseID имеет значение 7.

   <events baseID="7">
    <event eventID="7">
      <name>Foochanged</name>
      <synopsis>Пример события для скаляра</synopsis>
      <eventTarget>
        <eventField>foo</eventField>
      </eventTarget>
      <eventChanged/>
      <eventReports>
        <!-- Отчет о новом состоянии -->
        <eventReport>
          <eventField>foo</eventField>
        </eventReport>
      </eventReports>
    </event>

    <event eventID="8">
      <name>Goof1changed</name>
      <synopsis>
          Пример события для составной структуры
      </synopsis>
      <eventTarget>
        <!-- Целью служит goo.f1 -->
        <eventField>goo</eventField>
        <eventField>f1</eventField>
      </eventTarget>
      <eventChanged/>
      <eventReports>
        <!-- Отчет о новом состоянии goo.f1 -->
        <eventReport>
        <eventField>goo</eventField>
        <eventField>f1</eventField>
        </eventReport>
      </eventReports>
    </event>

    <event eventID="9">
      <name>NewbarEntry</name>
      <synopsis>
          Событие для новой записи, созданной в таблице bar
      </synopsis>
      <eventTarget>
        <eventField>bar</eventField>
        <eventSubscript>_barIndex_</eventSubscript>
      </eventTarget>
      <eventCreated/>
      <eventReports>
        <eventReport>
         <eventField>bar</eventField>
         <eventSubscript>_barIndex_</eventSubscript>
       </eventReport>
       <eventReport>
        <eventField>foo</eventField>
       </eventReport>
      </eventReports>
    </event>

    <event eventID="10">
      <name>Gah11changed</name>
      <synopsis>
          Событие для таблицы gah изменена запись с индексом 11
      </synopsis>
      <eventTarget>
        <eventField>gah</eventField>
        <eventSubscript>11</eventSubscript>
      </eventTarget>
      <eventChanged/>
      <eventReports>
        <eventReport>
         <eventField>gah</eventField>
         <eventSubscript>11</eventSubscript>
       </eventReport>
      </eventReports>
    </event>

    <event eventID="11">
      <name>Gah10field1</name>
      <synopsis>
          Событие для таблицы gah изменена запись с индексом 10, 
          колонка field1
      </synopsis>
      <eventTarget>
        <eventField>gah</eventField>
        <eventSubscript>10</eventSubscript>
        <eventField>field1</eventField>
      </eventTarget>
      <eventChanged/>
      <eventReports>
        <eventReport>
         <eventField>gah</eventField>
         <eventSubscript>10</eventSubscript>
        </eventReport>
      </eventReports>
    </event>
   </events>
4.7.6.1. Элемент <eventTarget>

Элемент <eventTarget> содержит информацию, указывающую поле в LFB, которое отслеживается для событий.

Элемент <eventTarget> содержит одно или множество элементов <eventField, за каждым из которых может следовать один или множество элементов <eventSubscript>. Каждый из этих двух элементов представляет текстовый эквивалент компоненты выбора пути в LFB.

Элемент <eventField> содержит имя компоненты в LFB или компоненты, встроенной в массив или структуру внутри LFB. Имя, используемое в <eventField>, должно указывать действительную компоненту в содержащем LFB контексте. Первым в элементе <eventTarget> должен быть элемент <eventField>. В приведенном ниже примере в качестве <eventField> используются 4 компоненты LFB — foo, goo, bar и gah.

В простом случае <eventField> указывает компоненту atomic. Этот случай показан в событии Foochanged. Элемент <eventField> служит также для указания сложных компонент, таких как массивы или структуры.

Определенное в примере первым событие Foochanged показывает, как скалярная компонента LFB (foo) может отслеживаться для инициирования событий.

Второе событие Goof1changed показывает отслеживание элемент составной структуры для генерации события.

События NewbarEntry, Gah11changed и Gah10field1 представляют мониторинг массивов bar и gah с разными деталями.

Если <eventField> указывает составную компоненту, может применяться дополнительный элемент <eventField> для уточнения пути к целевому элементу. Событие Goof1changed показывает применение второго <eventField> для указания на элемент f1 в структуре goo.

Если <eventField> указывает массив, применимы приведенные ниже правила.

  • Элемент <eventSubscript> должен быть представлен как следующий элемент XML после <eventField>, указывающего элемент массива. Элементу <eventSubscript> недопустимо появляться иначе как после ссылки на массив, поскольку он имеет смысл только в этом контексте.

  • Элемент <eventSubscript> содержит один из двух приведенных ниже вариантов.

    • Численное значение для указания применимости события к конкретному элементу массива (по индексу). Например, событие Gah11changed задает мониторинг элемента таблицы gah с индексом 11.

    • Предполагается, что наиболее вероятным будет использование событий, определенных для всех элементов массива (т. е. шаблон для всех значений индекса). В этом случае значением <eventSubscript> должно быть имя, а не число. Это же имя может использоваться в качестве значения <eventSubscript> в элементах <eventReport>, как описано ниже. An example of a wild card table index is shown in event NewBarentry where the <eventSubscript> value is named _barIndex_

  • За элементом <eventField> может следовать <eventSubscript> для уточнения пути к целевому элементу (это похоже на использование <eventField> для уточнения пути в составной структуре, показанное в событии Goof1changed). Событие Gah10field1 в примере отслеживает изменения столбца field1 в таблице gah.

Следует подчеркнуть, что элемент <eventSubscript> в событии NewbarEntry не является именем компоненты. Это имя переменной для использования в элементах <eventReport> (параграф 4.7.6.3) определения данного класса LFB. Это имя должно отличаться от всех имен компонент, которые докустиму в <eventReport>.

4.7.6.2. Элемент <eventCondition>

Элемент условия для событий указывает, при каких условиях создаются уведомления. Список условий приведен ниже.

<eventCreated/>

Целью должен быть массив, завершающийся указанным индексом. Событие генерируется при создании элемента в массиве, даже если это происходит по указанию CE. Условие <eventCreated/> показано в примере NewbarEntry.

<eventDeleted/>

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

<eventChanged/>

Событие генерируется при любом изменении целевой компоненты. Для двоичных компонент, таких как включение/выключение (up/down) это отражает смену состояния. Условие может применяться и с цифровыми атрибутами, когда триггером служит смена значения. Условие <eventChanged/> показано в примерах Foochanged, Gah11changed и Gah10field1.

<eventGreaterThan/>

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

<eventLessThan/>

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

4.7.6.3. Элемент <eventReports>

Элемент <eventReports> в <event> заявляет информацию, доставляемую элементом FE с уведомлением о событии.

Элемент <eventReports> содержит один или несколько элементов <eventReport>, содержащих части данных, сообщаемых классом LFB. Уведомление переносит данные как набор элементов <eventReport>, определенных в структуре. Синтаксис совпадает с синтаксисом <eventTarget> и использует элементы <eventField> и <eventSubscript> с применением тех же правил. Каждый элемент <eventReport> должен указывать компоненту класса LFB. Элементы <eventSubcript> могут содержать целые числа. Если они содержат имена, это должны быть имена из элементов <eventSubscript> цели события <eventTarget>. При выборе используется значение индекса, который указывает конкретный элемент, вызвавший событие. Это может служить для указания компоненты, вызвавшей событие, или ссылки на связанную информацию в параллельных таблицах.

В приведенном примере для события Foochanged отчет будет содержать значение foo. Для события NewbarEntry, связанного с компонентой LFB bar, которая является массивом, будут сообщаться два элемента, указанные двумя объявлениями <eventReport>.

  • Первый элемент <eventReport> указывает добавление новой записи в таблицу bar. Напомним, что _barIndex_ объявлен как <eventTarget> <eventSubcript> для события и можно использовать имя вместо числа. Элемент <eventSubcript> предполагается шаблоном, которому соответствует любой индекс новой записи.

  • Второй элемент <eventReport> включает значение компоненты LFB foo в момент создания новой записи в bar. Указание foo в этом случае приведено для демонстрации гибкости отчетов о событиях.

Структура отчетов о события создана для того, чтобы позволить разработчикам LFB задавать информацию, которая вероятно не известна заранее CE и вероятно потребуется CE для обработки события. Хотя структура позволяет указывать большие блоки информации (массив или составная структура целиком), делать это не рекомендуется. Кроме того, переменная ссылки/подписки в отчете содержит лишь малуя часть связанной с событием информации. Например, цепочки через поля индексов в таблице не поддерживаются. В общем случае механизм <eventReports> является оптимизацией для базовых ситуаций, позволяющей CE избавиться от необходимости запрашивать информацию, требуемую для того, чтобы понять событие. Он не представляет всю возможную информацию.

Если какая-либо из компонент, указанных eventReport, является необязательной, отчет должен использовать формат протокола, поддерживающий необязательные элементы и разрешающий им отсутствовать. Отсутствующие компоненты не указываются в отчете.

4.7.6.4. Управление событиями во время работы

Базовый обзор объявления событий LFB и работы с ними приведен в параграфе 3.2.5.

Элемент <eventTarget> обеспечивает дополнительные компоненты используемые в пути для ссылки на событие. Путь содержит baseID для событий, далее следует идентификатор конкретного события, а затем значения для каждого элемента <eventSubscript>, если они имеются в <eventTarget>.

Путь к событию будет однозначно указывать конкретный факт события в уведомлении о событии для CE. В приведенном выше примере (конец параграфа 4.7.6) уведомление с путем 7.7 однозначно указывает событие, вызванное изменением foo, а путь 7.9.100 однозначно указывает событие, вызванное созданием записи в таблице bar с индексом 100.

Как описано в параграфе 4.8.5, с элементами событий связаны определенные свойства. Эти свойства включают информацию о подписке, указывающую элементы CE, желающие получать уведомления о событиях FE для события в целом, пороги, связанные с пересечением уровней, и условия фильтрации, которые могут снизить число уведомлений, генерируемых FE. Детали применимых условий фильтрации рассмотрены в этом параграфе. Условия фильтрации позволяют элементу FE предотвратить лавинную рассылку уведомлений, котороя может возникать при колебаниях около порога условия. Для FE, не желающих поддерживать фильтрацию, свойства фильтра могут быть доступны лишь для чтения или не поддерживаться совсем.

В дополнение к идентификации источников событий CE использует путь к событиям для активации во время работы элементов управления на основании свойств событий (параграф 4.8.5) с использованием операции SET-PROP, определенной в протоколе ForCES [RFC5810].

Для того, чтобы активизировать генерацию событий на FE устройство CE передает FE сообщение SET-PROP, указывающее событие и его регистрационное свойство с любым префиксом пути к событию. Таким образом, для события NewbarEntry, определенного выше сообщение SET-PROP с путем 7.9 будет подписывать CE на все факты событий, связанных с любй записью в таблице bar. Это особенно полезно для условий <eventCreated/> и <eventDestroyed/> в таблицах. События, использующие эти условия, обычно будут определяться с последовательностью полей/индексов, указывающей массив и завершающейся елементом <eventSubscript>. Таким образом, уведомление о событии будет указывать созданный или уничтоженный элемент массива. Обычно подписка будет выполняться для массива, а не для его конкретноо элемента, поэтому будет применяться более короткий путь.

В приведенном примере подписка 7.8 предполагает получение всех объявленных событий из таблицы bar, подписка 7.8.100 означает получение уведомлений о создании в таблице записи с индексом 100.

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

4.7.7. Элемент <description> для рабочей спецификации LFB

Элемент <description> в <LFBClass> содержит неструктурированный (в смысле XML) текст, описывающий LFB для человека.

4.8. Свойства

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

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

4.8.1. Базовые свойства

Определение базовых свойств вместе со скаляром dataTypeDef для доступности приведено ниже. Отметим, что доступ к информации о свойствах обычно разрешен лишь в режиме read-only.

                <dataTypeDef>
                  <name>accessPermissionValues</name>
                  <synopsis>
                    Возможные значения прав доступа к компоненте
                  </synopsis>
                  <atomic>
                    <baseType>uchar</baseType>
                    <specialValues>
                      <specialValue value="0">
                        <name>None</name>
                        <synopsis>Доступ запрещен</synopsis>
                      </specialValue>
                       <specialValue value="1">
                        <name> Read-Only </name>
                        <synopsis>Доступ только для чтения</synopsis>
                      </specialValue>
                      <specialValue value="2">
                        <name>Write-Only</name>
                        <synopsis>
                          Компонента МОЖЕТ записываться, но чтение недоступно
                        </synopsis>
                      </specialValue>
                      <specialValue value="3">
                        <name>Read-Write</name>
                        <synopsis>
                          ВОЗМОЖНО чтение и запись компоненты
                        </synopsis>
                      </specialValue>
                    </specialValues>
                  </atomic>
                </dataTypeDef>
                <dataTypeDef>
                  <name>baseElementProperties</name>
                  <synopsis>Базовые свойства, доступность</synopsis>
                  <struct>
                    <component componentID="1">
                      <name>accessibility</name>
                      <synopsis>
                          Компоненты не существует, чтение и
                          запись невозможны
                      </synopsis>
                      <typeRef>accessPermissionValues</typeRef>
                    </component>
                  </struct>
                </dataTypeDef>

4.8.2. Свойства массива

Свойства массива содержат много дополнительной информации и доступны лишь для чтения.

         <dataTypeDef>
           <name>arrayElementProperties</name>
           <synopsis>Определение свойств элементов массива</synopsis>
           <struct>
             <derivedFrom>baseElementProperties</derivedFrom>
             <component componentID="2">
               <name>entryCount</name>
               <synopsis>Число элементов в массиве</synopsis>
               <typeRef>uint32</typeRef>
             </component>
             <component componentID="3">
               <name>highestUsedSubscript</name>
               <synopsis>Последний использованный индекс в массиве</synopsis>
               <typeRef>uint32</typeRef>
             </component>
             <component componentID="4">
               <name>firstUnusedSubscript</name>
               <synopsis>
                 Индекс первого неиспользуемого элемента массива
               </synopsis>
               <typeRef>uint32</typeRef>
             </component>
           </struct>
         </dataTypeDef>

4.8.3. Свойства строки

Свойства строки задают реальный размер в октетах и максимальную длину элемента. Максимальный размер включен потому, что реализации FE могут ограничивать размер строк сверх заданного классом LFB предела.

           <dataTypeDef>
             <name>stringElementProperties</name>
             <synopsis>Определение свойств строкового элемента</synopsis>
             <struct>
               <derivedFrom>baseElementProperties</derivedFrom>
               <component componentID="2">
                 <name>stringLength</name>
                 <synopsis>Число октетов в строке</synopsis>
                 <typeRef>uint32</typeRef>
               </component>
               <component componentID="3">
                 <name>maxStringLength</name>
                 <synopsis>
                   Максимальное число октетов в строке
                   </synopsis>
                 <typeRef>uint32</typeRef>
               </component>
             </struct>
           </dataTypeDef>

4.8.4. Свойства строки октетов

Свойства octetstring задают реальный и максимальный размер, посокольку реализации FE могут ограничивать сверх заданного определением класса LFB предела.

              <dataTypeDef>
                <name>octetstringElementProperties</name>
                <synopsis>Определеение свойств элемента octetstring
                </synopsis>
                <struct>
                  <derivedFrom>baseElementProperties</derivedFrom>
                  <component componentID="2">
                    <name>octetstringLength</name>
                    <synopsis>Число октетов в octetstring</synopsis>
                    <typeRef>uint32</typeRef>
                  </component>
                  <component componentID="3">
                    <name>maxOctetstringLength</name>
                    <synopsis>
                      Максимальное число октетов в octetstring
                    </synopsis>
                    <typeRef>uint32</typeRef>
                  </component>
                </struct>
              </dataTypeDef>

4.8.5. Свойства событий

Свойства событий (обычно) добавляют 3 доступных для записи поля. Одно из них является полем подписки, значение 0 в котором указывает, что уведомление не создается. Отличное от 0 значение (обычно 1) задает генерацию уведомлений. Поле гистерезиса служит для подавления уведомлений в результате колебаний около условного значения, как описано ниже (параграф 4.8.5.2). Поле порога используется в условиях <eventGreaterThan/> и <eventLessThan/>, задавая значение для сравнений с целью события. Использование свойства позволяет CE задать интересующий уровень. Элементы FE, не поддерживающие порогов для событий, будут делать поле read-only.

            <dataTypeDef>
              <name>eventElementProperties</name>
              <synopsis>Определение свойств события</synopsis>
              <struct>
                <derivedFrom>baseElementProperties</derivedFrom>
                <component componentID="2">
                  <name>registration</name>
                  <synopsis>
                    Имеется CE, зарегистрированный для уведомлений о событии
                  </synopsis>
                  <typeRef>uint32</typeRef>
                </component>
                <component componentID="3">
                  <name>threshold</name>
                  <synopsis>Значение для сравнения в условии</synopsis>
                  <optional/>
                  <typeRef>uint32</typeRef>
                </component>
                <component componentID="4">
                  <name>eventHysteresis</name>
                  <synopsis>Зона подавления рекурсивных уведомлений</synopsis>
                  <optional/>
                  <typeRef>uint32</typeRef>
                </component>
                <component componentID="5">
                  <name>eventCount</name>
                  <synopsis>Число уведомлений для подавления</synopsis>
                  <optional/>
                  <typeRef>uint32</typeRef>
                </component>
                <component componentID="6">
                  <name>eventInterval</name>
                  <synopsis>Интервал между уведомлениями в мсек</synopsis>
                  <optional/>
                  <typeRef>uint32</typeRef>
                </component>
              </struct>
            </dataTypeDef>
4.8.5.1. Базовая фильтрация событий

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

В настоящее время определены три разных переменных для условий фильтрации — eventCount, eventInterval и eventHysteresis. Установка значения 0 (принято по умолчанию) отключает проверку соответствующего условия.

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

Примером взаимодействия условий может служить событие с eventCount = 5 и eventInterval = 500 мсек. Предположим, что элемент FE обнаружил всплеск генерации таких уведомлений. Первое событие вызвало передачу уведомления CE. Затем, если быстро (менее 0,5 сек) произошли еще 4 события, они не вызовут уведомлений. Если обнаружены 2 дополнительных события, второе приведет к передаче уведомления. Если прошло более 500 мсек после уведомления и обнаружено событие, это приведет к передаче уведомления. В любом случае счетчик и временной интервал подавления сбрасываются, независимо от условия, вызвавшего генерацию уведомления.

4.8.5.2. Фильтрация гистерезиса событий

События с численными условиями могут иметь фильтр гистерезиса. Уровень гистерезиса определяется свойством события. Это позволяет элементу FE уведомлять CE о применении гистерезиса и в случае выбора FE может разрешать CE менять гистерезис. Это применимо для <eventChanged/> с численным полем, а также для <eventGreaterThan/> и <eventLessThan/>. Содержимым элемента <variance> является число. При поддержке гистерезиса элемент FE должен отслеживать значение элемента и гарантировать, что условие не выполняется по крайней мере в части гистерезиса из свойства события. Для гистерезиса V выполняется указанное ниже.

  • Если при условии <eventChanged/> последнее уведомление было для значения X, то уведомление <changed/> недопустимо создавать, пока значение не достигнет X +/- V.

  • Для условия <eventGreaterThan/> с порогом T после генерации хотя бы одного уведомления недопустимо создавать новые, пока поле сначала не станет меньше или равно T — V, а затем снова превысит T.

  • Для условия <eventLessThan/> с порогом T после генерации хотя бы одного уведомления недопустимо создавать новые, пока поле сначала не станет больше или равно T + V, а затем снова меньше T.

4.8.5.3. Фильтрация счета событий

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

Концептуальной реализацией (не обязательной) этого фильтра может быть внутренний счетчик подавления. Всякий раз при возникновении события значение счетчика проверяет и при нлевом значении генерируется уведомление. Счечик инкрементируется при каждом событии независимо от передачи уведомления и при достижении заданного значения сбрасывается в 0.

4.8.5.4. Фильтрация времени событий

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

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

4.8.6. Свойства псевдонимов

В свойства для псевдонимов (обычно) добавляются три открытых для записи поля, которые объединяются для идентификации целевой компоненты, на которую указывает псевдоним.

          <dataTypeDef>
            <name>aliasElementProperties</name>
            <synopsis>Определение свойств псевдонима</synopsis>
            <struct>
              <derivedFrom>baseElementProperties</derivedFrom>
              <component componentID="2">
                <name>targetLFBClass</name>
                <synopsis>Идентификатор класса для цели псевдонима</synopsis>
                <typeRef>uint32</typeRef>
              </component>
              <component componentID="3">
                <name>targetLFBInstance</name>
                <synopsis>Идентификатор экземпляра для цели псевдонима</synopsis>
                <typeRef>uint32</typeRef>
              </component>
              <component componentID="4">
                <name>targetComponentPath</name>
                <synopsis>
                  Путь к составной цели. Каждые 4 элемента
                  считываются как 1 элемент пути с использованием
                  конструкции path протокола ForCES [RFC5810].
                </synopsis>
                <typeRef>octetstring[128]</typeRef>
              </component>
            </struct>
          </dataTypeDef>

4.9. Схема XML для документов LFB Class Library

      <?xml version="1.0" encoding="UTF-8"?>
      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
       xmlns="urn:ietf:params:xml:ns:forces:lfbmodel:1.0"
       xmlns:lfb="urn:ietf:params:xml:ns:forces:lfbmodel:1.0"
       targetNamespace="urn:ietf:params:xml:ns:forces:lfbmodel:1.0"
       attributeFormDefault="unqualified"
       elementFormDefault="qualified">
      <xsd:annotation>
        <xsd:documentation xml:lang="en">
        Schema for Defining LFB Classes and associated types (frames,
        data types for LFB attributes, and metadata).
        </xsd:documentation>
      </xsd:annotation>
      <xsd:element name="description" type="xsd:string"/>
      <xsd:element name="synopsis" type="xsd:string"/>
      <!-- Корневой элемент документа: LFBLibrary -->
      <xsd:element name="LFBLibrary">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element ref="description" minOccurs="0"/>
            <xsd:element name="load" type="loadType" minOccurs="0"
                      maxOccurs="unbounded"/>
         <xsd:element name="frameDefs" type="frameDefsType"
                      minOccurs="0"/>
         <xsd:element name="dataTypeDefs" type="dataTypeDefsType"
                      minOccurs="0"/>
         <xsd:element name="metadataDefs" type="metadataDefsType"
                      minOccurs="0"/>
         <xsd:element name="LFBClassDefs" type="LFBClassDefsType"
                      minOccurs="0"/>
       </xsd:sequence>
       <xsd:attribute name="provides" type="xsd:Name" use="required"/>
     </xsd:complexType>
     <!-- Ограничения уникальности -->
     <xsd:key name="frame">
      <xsd:selector xpath="lfb:frameDefs/lfb:frameDef"/>
       <xsd:field xpath="lfb:name"/>
     </xsd:key>
     <xsd:key name="dataType">
      <xsd:selector xpath="lfb:dataTypeDefs/lfb:dataTypeDef"/>
       <xsd:field xpath="lfb:name"/>
     </xsd:key>
     <xsd:key name="metadataDef">
       <xsd:selector xpath="lfb:metadataDefs/lfb:metadataDef"/>
       <xsd:field xpath="lfb:name"/>
     </xsd:key>
     <xsd:key name="LFBClassDef">
       <xsd:selector xpath="lfb:LFBClassDefs/lfb:LFBClassDef"/>
       <xsd:field xpath="lfb:name"/>
     </xsd:key>
   </xsd:element>
   <xsd:complexType name="loadType">
     <xsd:attribute name="library" type="xsd:Name" use="required"/>
     <xsd:attribute name="location" type="xsd:anyURI" use="optional"/>
   </xsd:complexType>
   <xsd:complexType name="frameDefsType">
     <xsd:sequence>
       <xsd:element name="frameDef" maxOccurs="unbounded">
         <xsd:complexType>
        <xsd:sequence>
             <xsd:element name="name" type="xsd:NMTOKEN"/>
             <xsd:element ref="synopsis"/>
             <xsd:element ref="description" minOccurs="0"/>
           </xsd:sequence>
         </xsd:complexType>
       </xsd:element>
     </xsd:sequence>
   </xsd:complexType>
   <xsd:complexType name="dataTypeDefsType">
     <xsd:sequence>
          <xsd:element name="dataTypeDef" maxOccurs="unbounded">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="name" type="xsd:NMTOKEN"/>
                <xsd:element ref="synopsis"/>
                <xsd:element ref="description" minOccurs="0"/>
                <xsd:group ref="typeDeclarationGroup"/>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
        </xsd:sequence>
      </xsd:complexType>
      <!--
         Предопределенными (встроенными) неделимыми типа данных являются
             char, uchar, int16, uint16, int32, uint32, int64, uint64,
             string[N], string, byte[N], boolean, octetstring[N],
             float32, float64
      -->
      <xsd:group name="typeDeclarationGroup">
        <xsd:choice>
          <xsd:element name="typeRef" type="typeRefNMTOKEN"/>
          <xsd:element name="atomic" type="atomicType"/>
          <xsd:element name="array" type="arrayType"/>
          <xsd:element name="struct" type="structType"/>
          <xsd:element name="union" type="structType"/>
          <xsd:element name="alias" type="typeRefNMTOKEN"/>
        </xsd:choice>
      </xsd:group>
      <xsd:simpleType name="typeRefNMTOKEN">
        <xsd:restriction base="xsd:token">
          <xsd:pattern value="\c+"/>
          <xsd:pattern value="string\[\d+\]"/>
          <xsd:pattern value="byte\[\d+\]"/>
          <xsd:pattern value="octetstring\[\d+\]"/>
        </xsd:restriction>
      </xsd:simpleType>
      <xsd:complexType name="atomicType">
        <xsd:sequence>
          <xsd:element name="baseType" type="typeRefNMTOKEN"/>
          <xsd:element name="rangeRestriction"
                       type="rangeRestrictionType" minOccurs="0"/>
          <xsd:element name="specialValues" type="specialValuesType"
                       minOccurs="0"/>
        </xsd:sequence>
      </xsd:complexType>
      <xsd:complexType name="rangeRestrictionType">
        <xsd:sequence>
          <xsd:element name="allowedRange" maxOccurs="unbounded">
            <xsd:complexType>
            <xsd:attribute name="min" type="xsd:integer" use="required"/>
            <xsd:attribute name="max" type="xsd:integer" use="required"/>
         </xsd:complexType>
       </xsd:element>
     </xsd:sequence>
   </xsd:complexType>
   <xsd:complexType name="specialValuesType">
     <xsd:sequence>
       <xsd:element name="specialValue" maxOccurs="unbounded">
         <xsd:complexType>
           <xsd:sequence>
             <xsd:element name="name" type="xsd:NMTOKEN"/>
             <xsd:element ref="synopsis"/>
           </xsd:sequence>
           <xsd:attribute name="value" type="xsd:token"/>
         </xsd:complexType>
       </xsd:element>
     </xsd:sequence>
   </xsd:complexType>
   <xsd:complexType name="arrayType">
     <xsd:sequence>
       <xsd:group ref="typeDeclarationGroup"/>
       <xsd:element name="contentKey" minOccurs="0"
                    maxOccurs="unbounded">
         <xsd:complexType>
           <xsd:sequence>
             <xsd:element name="contentKeyField" maxOccurs="unbounded"
                          type="xsd:string"/>
           </xsd:sequence>
           <xsd:attribute name="contentKeyID" use="required"
                          type="xsd:integer"/>
         </xsd:complexType>
         <!-- Заявление уникальных идентификаторов ключей -->
         <xsd:key name="contentKeyID">
           <xsd:selector xpath="lfb:contentKey"/>
           <xsd:field xpath="@contentKeyID"/>
         </xsd:key>
       </xsd:element>
     </xsd:sequence>
     <xsd:attribute name="type" use="optional"
                    default="variable-size">
       <xsd:simpleType>
         <xsd:restriction base="xsd:string">
           <xsd:enumeration value="fixed-size"/>
           <xsd:enumeration value="variable-size"/>
         </xsd:restriction>
       </xsd:simpleType>
        </xsd:attribute>
        <xsd:attribute name="length" type="xsd:integer" use="optional"/>
        <xsd:attribute name="maxLength" type="xsd:integer"
                       use="optional"/>
      </xsd:complexType>
      <xsd:complexType name="structType">
        <xsd:sequence>
          <xsd:element name="derivedFrom" type="typeRefNMTOKEN"
                       minOccurs="0"/>
          <xsd:element name="component" maxOccurs="unbounded">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="name" type="xsd:NMTOKEN"/>
                <xsd:element ref="synopsis"/>
                <xsd:element ref="description" minOccurs="0"/>
                <xsd:element name="optional" minOccurs="0"/>
                <xsd:group ref="typeDeclarationGroup"/>
              </xsd:sequence>
              <xsd:attribute name="componentID" use="required"
                             type="xsd:unsignedInt"/>
            </xsd:complexType>
            <!-- Объявление ключей для уникальности componentID в структуре
            -->
            <xsd:key name="structComponentID">
              <xsd:selector xpath="lfb:component"/>
              <xsd:field xpath="@componentID"/>
            </xsd:key>
          </xsd:element>
        </xsd:sequence>
      </xsd:complexType>
      <xsd:complexType name="metadataDefsType">
        <xsd:sequence>
          <xsd:element name="metadataDef" maxOccurs="unbounded">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="name" type="xsd:NMTOKEN"/>
                <xsd:element ref="synopsis"/>
                <xsd:element name="metadataID" type="xsd:integer"/>
                <xsd:element ref="description" minOccurs="0"/>
                <xsd:choice>
                  <xsd:element name="typeRef" type="typeRefNMTOKEN"/>
                  <xsd:element name="atomic" type="atomicType"/>
                </xsd:choice>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
        </xsd:sequence>
      </xsd:complexType>
      <xsd:complexType name="LFBClassDefsType">
        <xsd:sequence>
          <xsd:element name="LFBClassDef" maxOccurs="unbounded">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="name" type="xsd:NMTOKEN"/>
                <xsd:element ref="synopsis"/>
                <xsd:element name="version" type="versionType"/>
                <xsd:element name="derivedFrom" type="xsd:NMTOKEN"
                             minOccurs="0"/>
                <xsd:element name="inputPorts" type="inputPortsType"
                             minOccurs="0"/>
                <xsd:element name="outputPorts" type="outputPortsType"
                             minOccurs="0"/>
                <xsd:element name="components" type="LFBComponentsType"
                             minOccurs="0"/>
                <xsd:element name="capabilities"
                             type="LFBCapabilitiesType" minOccurs="0"/>
                <xsd:element name="events"
                             type="eventsType" minOccurs="0"/>
                <xsd:element ref="description" minOccurs="0"/>
              </xsd:sequence>
              <xsd:attribute name="LFBClassID" use="required"
                             type="xsd:unsignedInt"/>
            </xsd:complexType>
            <!-- Ограничение ключей для обеспечения уникальности имен
                 атрибутов в классе
            -->
            <xsd:key name="components">
              <xsd:selector xpath="lfb:components/lfb:component"/>
              <xsd:field xpath="lfb:name"/>
            </xsd:key>
            <xsd:key name="capabilities">
              <xsd:selector xpath="lfb:capabilities/lfb:capability"/>
              <xsd:field xpath="lfb:name"/>
            </xsd:key>
            <xsd:key name="componentIDs">
              <xsd:selector xpath="lfb:components/lfb:component"/>
              <xsd:field xpath="@componentID"/>
            </xsd:key>
            <xsd:key name="capabilityIDs">
              <xsd:selector xpath="lfb:capabilities/lfb:capability"/>
              <xsd:field xpath="@componentID"/>
            </xsd:key>
          </xsd:element>
        </xsd:sequence>
      </xsd:complexType>
    <xsd:simpleType name="versionType">
      <xsd:restriction base="xsd:NMTOKEN">
        <xsd:pattern value="[1-9][0-9]*\.([1-9][0-9]*|0)"/>
      </xsd:restriction>
    </xsd:simpleType>
    <xsd:complexType name="inputPortsType">
      <xsd:sequence>
        <xsd:element name="inputPort" type="inputPortType"
                     maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="inputPortType">
      <xsd:sequence>
        <xsd:element name="name" type="xsd:NMTOKEN"/>
        <xsd:element ref="synopsis"/>
        <xsd:element name="expectation" type="portExpectationType"/>
        <xsd:element ref="description" minOccurs="0"/>
      </xsd:sequence>
      <xsd:attribute name="group" type="xsd:boolean" use="optional"
                     default="0"/>
    </xsd:complexType>
    <xsd:complexType name="portExpectationType">
      <xsd:sequence>
        <xsd:element name="frameExpected" minOccurs="0">
          <xsd:complexType>
            <xsd:sequence>
            <!-- Ссылка ref должна указывать определенный тип кадра -->
            <xsd:element name="ref" type="xsd:string"
                           maxOccurs="unbounded"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
        <xsd:element name="metadataExpected" minOccurs="0">
          <xsd:complexType>
            <xsd:choice maxOccurs="unbounded">
              <!-- Ссылка ref должна указывать имя определенных метаданных -->

              <xsd:element name="ref" type="metadataInputRefType"/>
              <xsd:element name="one-of"
                           type="metadataInputChoiceType"/>
            </xsd:choice>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="metadataInputChoiceType">
      <xsd:choice minOccurs="2" maxOccurs="unbounded">
        <!-- Ссылка ref должна указывать имя определенных метаданных -->
        <xsd:element name="ref" type="xsd:NMTOKEN"/>
        <xsd:element name="one-of" type="metadataInputChoiceType"/>
        <xsd:element name="metadataSet" type="metadataInputSetType"/>
      </xsd:choice>
    </xsd:complexType>
    <xsd:complexType name="metadataInputSetType">
      <xsd:choice minOccurs="2" maxOccurs="unbounded">
        <!-- Ссылка ref должна указывать имя определенных метаданных -->
        <xsd:element name="ref" type="metadataInputRefType"/>
        <xsd:element name="one-of" type="metadataInputChoiceType"/>
      </xsd:choice>
    </xsd:complexType>
    <xsd:complexType name="metadataInputRefType">
      <xsd:simpleContent>
        <xsd:extension base="xsd:NMTOKEN">
          <xsd:attribute name="dependency" use="optional"
                         default="required">
            <xsd:simpleType>
              <xsd:restriction base="xsd:string">
                <xsd:enumeration value="required"/>
                <xsd:enumeration value="optional"/>
              </xsd:restriction>
            </xsd:simpleType>
          </xsd:attribute>
          <xsd:attribute name="defaultValue" type="xsd:token"
                         use="optional"/>
        </xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
    <xsd:complexType name="outputPortsType">
      <xsd:sequence>
        <xsd:element name="outputPort" type="outputPortType"
                     maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="outputPortType">
      <xsd:sequence>
        <xsd:element name="name" type="xsd:NMTOKEN"/>
        <xsd:element ref="synopsis"/>
        <xsd:element name="product" type="portProductType"/>
        <xsd:element ref="description" minOccurs="0"/>
      </xsd:sequence>
      <xsd:attribute name="group" type="xsd:boolean" use="optional"
                     default="0"/>
    </xsd:complexType>
    <xsd:complexType name="portProductType">
      <xsd:sequence>
        <xsd:element name="frameProduced">
         <xsd:complexType>
            <xsd:sequence>
              <!-- Ссылка ref должна указывать определенный тип кадра
                   -->
                  <xsd:element name="ref" type="xsd:NMTOKEN"
                             maxOccurs="unbounded"/>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="metadataProduced" minOccurs="0">
            <xsd:complexType>
              <xsd:choice maxOccurs="unbounded">
                <!-- Ссылка ref должна указывать имя определенных метаданных
                -->
                <xsd:element name="ref" type="metadataOutputRefType"/>
                <xsd:element name="one-of"
                             type="metadataOutputChoiceType"/>
              </xsd:choice>
            </xsd:complexType>
          </xsd:element>
        </xsd:sequence>
      </xsd:complexType>
      <xsd:complexType name="metadataOutputChoiceType">
        <xsd:choice minOccurs="2" maxOccurs="unbounded">
          <!-- Ссылка ref должна указывать имя определенных метаданных -->
          <xsd:element name="ref" type="xsd:NMTOKEN"/>
          <xsd:element name="one-of" type="metadataOutputChoiceType"/>
          <xsd:element name="metadataSet" type="metadataOutputSetType"/>
        </xsd:choice>
      </xsd:complexType>
      <xsd:complexType name="metadataOutputSetType">
        <xsd:choice minOccurs="2" maxOccurs="unbounded">
          <!-- Ссылка ref должна указывать имя определенных метаданных -->
          <xsd:element name="ref" type="metadataOutputRefType"/>
          <xsd:element name="one-of" type="metadataOutputChoiceType"/>
        </xsd:choice>
      </xsd:complexType>
      <xsd:complexType name="metadataOutputRefType">
        <xsd:simpleContent>
          <xsd:extension base="xsd:NMTOKEN">
            <xsd:attribute name="availability" use="optional"
                           default="unconditional">
              <xsd:simpleType>
                <xsd:restriction base="xsd:string">
                  <xsd:enumeration value="unconditional"/>
                  <xsd:enumeration value="conditional"/>
                </xsd:restriction>
              </xsd:simpleType>
            </xsd:attribute>
          </xsd:extension>
        </xsd:simpleContent>
      </xsd:complexType>
      <xsd:complexType name="LFBComponentsType">
        <xsd:sequence>
          <xsd:element name="component" maxOccurs="unbounded">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="name" type="xsd:NMTOKEN"/>
                <xsd:element ref="synopsis"/>
                <xsd:element ref="description" minOccurs="0"/>
                <xsd:element name="optional" minOccurs="0"/>
                <xsd:group ref="typeDeclarationGroup"/>
                <xsd:element name="defaultValue" type="xsd:token"
                             minOccurs="0"/>
              </xsd:sequence>
              <xsd:attribute name="access" use="optional"
                             default="read-write">
                <xsd:simpleType>
                  <xsd:list itemType="accessModeType"/>
                </xsd:simpleType>
              </xsd:attribute>
              <xsd:attribute name="componentID" use="required"
                             type="xsd:unsignedInt"/>
            </xsd:complexType>
          </xsd:element>
        </xsd:sequence>
      </xsd:complexType>
      <xsd:simpleType name="accessModeType">
        <xsd:restriction base="xsd:NMTOKEN">
          <xsd:enumeration value="read-only"/>
          <xsd:enumeration value="read-write"/>
          <xsd:enumeration value="write-only"/>
          <xsd:enumeration value="read-reset"/>
          <xsd:enumeration value="trigger-only"/>
        </xsd:restriction>
      </xsd:simpleType>
      <xsd:complexType name="LFBCapabilitiesType">
        <xsd:sequence>
          <xsd:element name="capability" maxOccurs="unbounded">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="name" type="xsd:NMTOKEN"/>
                <xsd:element ref="synopsis"/>
                <xsd:element ref="description" minOccurs="0"/>
                <xsd:element name="optional" minOccurs="0"/>
                <xsd:group ref="typeDeclarationGroup"/>
              </xsd:sequence>
              <xsd:attribute name="componentID" use="required"
                             type="xsd:integer"/>
            </xsd:complexType>
          </xsd:element>
        </xsd:sequence>
      </xsd:complexType>
      <xsd:complexType name="eventsType">
        <xsd:sequence>
          <xsd:element name="event" maxOccurs="unbounded">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="name" type="xsd:NMTOKEN"/>
                <xsd:element ref="synopsis"/>
                <xsd:element name="eventTarget" type="eventPathType"/>
                <xsd:element ref="eventCondition"/>
                <xsd:element name="eventReports" type="eventReportsType"
                             minOccurs="0"/>
                <xsd:element ref="description" minOccurs="0"/>
              </xsd:sequence>
              <xsd:attribute name="eventID" use="required"
                             type="xsd:integer"/>
            </xsd:complexType>
          </xsd:element>
        </xsd:sequence>
        <xsd:attribute name="baseID" type="xsd:integer"
                       use="optional"/>
      </xsd:complexType>
      <!-- Группа подстановки для условий события -->
      <xsd:element name="eventCondition" abstract="true"/>
      <xsd:element name="eventCreated"
                  substitutionGroup="eventCondition"/>
      <xsd:element name="eventDeleted"
                  substitutionGroup="eventCondition"/>
      <xsd:element name="eventChanged"
                  substitutionGroup="eventCondition"/>
      <xsd:element name="eventGreaterThan"
                  substitutionGroup="eventCondition"/>
      <xsd:element name="eventLessThan"
                  substitutionGroup="eventCondition"/>
      <xsd:complexType name="eventPathType">
        <xsd:sequence>
          <xsd:element ref="eventPathPart" maxOccurs="unbounded"/>
        </xsd:sequence>
      </xsd:complexType>
      <!-- Группа подстановки для частей пути к событию -->
      <xsd:element name="eventPathPart" type="xsd:string"
                   abstract="true"/>
      <xsd:element name="eventField" type="xsd:string"
                   substitutionGroup="eventPathPart"/>
      <xsd:element name="eventSubscript" type="xsd:string"
                   substitutionGroup="eventPathPart"/>
      <xsd:complexType name="eventReportsType">
        <xsd:sequence>
          <xsd:element name="eventReport" type="eventPathType"
                       maxOccurs="unbounded"/>
        </xsd:sequence>
      </xsd:complexType>
      <xsd:simpleType name="booleanType">
        <xsd:restriction base="xsd:string">
          <xsd:enumeration value="0"/>
          <xsd:enumeration value="1"/>
        </xsd:restriction>
      </xsd:simpleType>
      </xsd:schema>

5. Компоненты и возможности FE

Элемент пересылки ForCES обрабатывает трафик от имени управляющего элемента ForCES. Хотя стандарты будут описывать протокол и механизмы для этого управления, разные реализации и разные экземпляры будут отличаться возможностями. Элемент CE должен быть способен определить, за что отвечает каждый экземпляр и что он реально может делать. Как отмечено выше, это будет аппроксимацией. Предполагается, что элемент CE будет готов справляться с ошибками в запросах и изменениями в деталях, не отраженными в информации о возможностях FE.

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

Чтобы сделать информацию FE легкодоступной, она представлена в LFB. Этот блок LFB имеет класс FEObject с идентификатором LFBClassID = 1. В FE будет присутствовать лишь один экземпляр этого класса и идентификатор экземпляра в протоколе будет иметь значение 1. таким образом, ссылаясь на компоненты class:1, instance:1, CE может получить общую инормацию о FE. Класс LFB FEObject описан в этом разделе.

Будет также класс LFB FEProtocol, для которого зарезервирован идентификатор LFBClassID = 2. Этот класс также будет иметь единственный экземпляр, а его детали определены в спецификации протокола ForCES [RFC5810].

5.1. XML для определения класса FEObject

          <?xml version="1.0" encoding="UTF-8"?>
          <LFBLibrary xmlns="urn:ietf:params:xml:ns:forces:lfbmodel:1.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            provides="FEObject">
            <dataTypeDefs>
              <dataTypeDef>
                <name>LFBAdjacencyLimitType</name>
                <synopsis>Описание Adjacent LFB</synopsis>
                <struct>
                  <component componentID="1">
                    <name>NeighborLFB</name>
                    <synopsis>Идентификатор для данного класса LFB</synopsis>
                    <typeRef>uint32</typeRef>
                  </component>
                  <component componentID="2">
                    <name>ViaPorts</name>
                    <synopsis>
                      Порты, к которым можно подключаться
                    </synopsis>
                    <array type="variable-size">
                      <typeRef>string</typeRef>
                    </array>
                  </component>
                </struct>
              </dataTypeDef>
              <dataTypeDef>
                <name>PortGroupLimitType</name>
                <synopsis>
                  Предельное число портов в данной группе
                </synopsis>
                <struct>
                  <component componentID="1">
                    <name>PortGroupName</name>
                    <synopsis>Имя группы</synopsis>
                    <typeRef>string</typeRef>
                  </component>
                  <component componentID="2">
                    <name>MinPortCount</name>
                    <synopsis>Минимальное число портов</synopsis>
                    <optional/>
                    <typeRef>uint32</typeRef>
                  </component>
                  <component componentID="3">
                    <name>MaxPortCount</name>
                    <synopsis>Максимальное число портов</synopsis>
                    <optional/>
                    <typeRef>uint32</typeRef>
                  </component>
                </struct>
              </dataTypeDef>
              <dataTypeDef>
                <name>SupportedLFBType</name>
                <synopsis>запись таблицы для поддерживаемых LFB</synopsis>
                <struct>
                  <component componentID="1">
                    <name>LFBName</name>
                    <synopsis>Имя поддерживаемого класса LFB</synopsis>
                    <typeRef>string</typeRef>
                  </component>
                  <component componentID="2">
                    <name>LFBClassID</name>
                    <synopsis>Идентификатор поддерживаемого класса LFB</synopsis>
                    <typeRef>uint32</typeRef>
                  </component>
                  <component componentID="3">
                    <name>LFBVersion</name>
                    <synopsis>Версия класса LFB, используемого этим FE.</synopsis>
                    <typeRef>string</typeRef>
                  </component>
                  <component componentID="4">
                    <name>LFBOccurrenceLimit</name>
                    <synopsis>
                      Максимальое число экземпляров данного класса LFB
                    </synopsis>
                    <optional/>
                    <typeRef>uint32</typeRef>
                  </component>
                  <!-- Для каждой группы указывается допустимое число портов
                  -->
                  <component componentID="5">
                    <name>PortGroupLimits</name>
                    <synopsis>Таблица пределов групп портов</synopsis>
                    <optional/>
                    <array type="variable-size">
                      <typeRef>PortGroupLimitType</typeRef>
                    </array>
                  </component>
        <!-- Классы LFB, за которыми может следовать именованный LFB Class -->
                  <component componentID="6">
                    <name>CanOccurAfters</name>
                    <synopsis>
                      Список классов LFB, за которыми может следовать этот класс
                    </synopsis>
                    <optional/>
                    <array type="variable-size">
                      <typeRef>LFBAdjacencyLimitType</typeRef>
                    </array>
                  </component>
        <!-- Классы LFB, которые могут следовать за именованным LFB Class -->
                  <component componentID="7">
                    <name>CanOccurBefores</name>
                    <synopsis>
                      Список классов LFB, которые могут следовать за этим классом
                    </synopsis>
                    <optional/>
                    <array type="variable-size">
                      <typeRef>LFBAdjacencyLimitType</typeRef>
                    </array>
                  </component>
                  <component componentID="8">
                    <name>UseableParentLFBClasses</name>
                    <synopsis>
                      Список классов LFB, из которых унаследован этот класс
                      и которые FE разрешает для ссылок на экземпляры этого
                      класса.
                    </synopsis>
                    <optional/>
                    <array type="variable-size">
                      <typeRef>uint32</typeRef>
                    </array>
                  </component>
                </struct>
              </dataTypeDef>
              <dataTypeDef>
                <name>FEStateValues</name>
                <synopsis>Возможные значения статуса</synopsis>
                <atomic>
                  <baseType>uchar</baseType>
                  <specialValues>
                    <specialValue value="0">
                      <name>AdminDisable</name>
                      <synopsis>FE административно запрещен</synopsis>
                    </specialValue>
                    <specialValue value="1">
                      <name>OperDisable</name>
                      <synopsis>FE исключен из работы</synopsis>
                    </specialValue>
                    <specialValue value="2">
                      <name>OperEnable</name>
                      <synopsis>FE работает</synopsis>
                    </specialValue>
                  </specialValues>
                </atomic>
              </dataTypeDef>
              <dataTypeDef>
                <name>FEConfiguredNeighborType</name>
                <synopsis>Детали соседей FE</synopsis>
                <struct>
                  <component componentID="1">
                    <name>NeighborID</name>
                    <synopsis>FEID соседа</synopsis>
                    <typeRef>uint32</typeRef>
                  </component>
                  <component componentID="2">
                    <name>InterfaceToNeighbor</name>
                    <synopsis>Интерфейс FE к этому соседу</synopsis>
                    <optional/>
                    <typeRef>string</typeRef>
                  </component>
                  <component componentID="3">
                    <name>NeighborInterface</name>
                    <synopsis>
                      Имя интерфейса соседам с которым данных FE 
                      является смежным. Это нужно при наличии более
                      одного смежного FE на интерфейсе.
                    </synopsis>
                    <optional/>
                    <typeRef>string</typeRef>
                  </component>
                </struct>
              </dataTypeDef>
              <dataTypeDef>
                <name>LFBSelectorType</name>
                <synopsis>Уникальное имя экземпляра класса LFB</synopsis>
                <struct>
                  <component componentID="1">
                    <name>LFBClassID</name>
                    <synopsis>Идентификатор класса LFB</synopsis>
                    <typeRef>uint32</typeRef>
                  </component>
                  <component componentID="2">
                    <name>LFBInstanceID</name>
                    <synopsis>Идентификатор экземпляра LFB</synopsis>
                    <typeRef>uint32</typeRef>
                  </component>
                </struct>
              </dataTypeDef>
              <dataTypeDef>
                <name>LFBLinkType</name>
                <synopsis>
                  Канал между двумя экземплярами LFB в топологии
                </synopsis>
                <struct>
                  <component componentID="1">
                    <name>FromLFBID</name>
                    <synopsis>Источник LFB</synopsis>
                    <typeRef>LFBSelectorType</typeRef>
                  </component>
                  <component componentID="2">
                    <name>FromPortGroup</name>
                    <synopsis>Группа портов источника</synopsis>
                    <typeRef>string</typeRef>
                  </component>
                  <component componentID="3">
                    <name>FromPortIndex</name>
                    <synopsis>Индекс порта-источника</synopsis>
                    <typeRef>uint32</typeRef>
                  </component>
                  <component componentID="4">
                    <name>ToLFBID</name>
                    <synopsis>LFBID назначения</synopsis>
                    <typeRef>LFBSelectorType</typeRef>
                  </component>
                  <component componentID="5">
                    <name>ToPortGroup</name>
                    <synopsis>Группа портов назначения</synopsis>
                    <typeRef>string</typeRef>
                  </component>
                  <component componentID="6">
                    <name>ToPortIndex</name>
                    <synopsis>Индекс порта назначения</synopsis>
                    <typeRef>uint32</typeRef>
                  </component>
                </struct>
              </dataTypeDef>
            </dataTypeDefs>
            <LFBClassDefs>
              <LFBClassDef LFBClassID="1">
                <name>FEObject</name>
                <synopsis>Core LFB: FE Object</synopsis>
                <version>1.0</version>
                <components>
                  <component access="read-write" componentID="1">
                    <name>LFBTopology</name>
                    <synopsis>Таблица известных топологий</synopsis>
                    <array type="variable-size">
                      <typeRef>LFBLinkType</typeRef>
                    </array>
                  </component>
                  <component access="read-write" componentID="2">
                    <name>LFBSelectors</name>
                    <synopsis>
                       Таблица известных активных классов и экземпляров LFB
                    </synopsis>
                    <array type="variable-size">
                      <typeRef>LFBSelectorType</typeRef>
                    </array>
                  </component>
                  <component access="read-write" componentID="3">
                    <name>FEName</name>
                    <synopsis>Имя данного FE</synopsis>
                    <typeRef>string[40]</typeRef>
                  </component>
                  <component access="read-write" componentID="4">
                    <name>FEID</name>
                    <synopsis>Идентификатор данного FE</synopsis>
                    <typeRef>uint32</typeRef>
                  </component>
                  <component access="read-only" componentID="5">
                    <name>FEVendor</name>
                    <synopsis>Производитель FE</synopsis>
                    <typeRef>string[40]</typeRef>
                  </component>
                  <component access="read-only" componentID="6">
                    <name>FEModel</name>
                    <synopsis>Модель FE</synopsis>
                    <typeRef>string[40]</typeRef>
                  </component>
                  <component access="read-write" componentID="7">
                    <name>FEState</name>
                    <synopsis>Состояние данного FE</synopsis>
                    <typeRef>FEStateValues</typeRef>
                  </component>
                  <component access="read-write" componentID="8">
                    <name>FENeighbors</name>
                    <synopsis>таблица известных соседей</synopsis>
                    <optional/>
                    <array type="variable-size">
                      <typeRef>FEConfiguredNeighborType</typeRef>
                    </array>
                  </component>
                </components>
                <capabilities>
                  <capability componentID="30">
                    <name>ModifiableLFBTopology</name>
                    <synopsis>Поддержка изменяемых LFB</synopsis>
                    <optional/>
                    <typeRef>boolean</typeRef>
                  </capability>
                  <capability componentID="31">
                    <name>SupportedLFBs</name>
                    <synopsis>Список всех поддерживаемых LFB</synopsis>
                    <optional/>
                    <array type="variable-size">
                      <typeRef>SupportedLFBType</typeRef>
                    </array>
                  </capability>
                </capabilities>
              </LFBClassDef>
            </LFBClassDefs>
          </LFBLibrary>

5.2. Возможности FE

Информация о возможностях FE содержится в элементе <capabilities> определения класса. Как уже было сказано, информация о возможностях доступна лишь для чтения.

В настоящее время определены возможности ModifiableLFBTopology и SupportedLFBs. Информация о поддерживаемых компонентах LFB FEObject доступна из свойств этих компонент.

5.2.1. ModifiableLFBTopology

Компонента относится к логическому типу (boolean) и показывает, может ли CE изменить топологию LFB для FE. При отсутствии компоненты предполагается значение true и CE считает, что топологию LFB можно изменить. Если присутсвует значение false, топология LFB для FE является фиксированной. В таких случаях элемент SupportedLFBs может быть опущен и список поддерживаемых LFB выводится CE из топологической информации LFB. Если список поддерживаемых LFB представлен и ModifiableLFBTopology = false, информацию CanOccurBefore и CanOccurAfter следует опускать.

5.2.2. SupportedLFBs и SupportedLFBType

Одной из возможностей, которую FE следует включать, является список поддерживаемых классов LFB. Компонента SupportedLFBs является массивом, содержащим информацию о каждом поддерживаемом классе LFB. Структура массива определена как SupportedLFBType dataTypeDef.

Каждый элемент массива SupportedLFBs описывает класс LFB, поддерживаемый FE. В дополнение к указанию поддерживаемых классов FE с изменяемой топологией LFB следует включать информацию о том, как LFB указанного класса могут соединяться с другими LFB. В этой информации следует описывать, порядок размещения классов LFB в топологии LFB. FE следует указывать, к какой группе портов может быть подключен данный смежный класс LFB. Если информация о группе портов опущена, предполагается возможность использования всех портов группы. Эта информация о приемлемом порядке и соединениях LFB может быть опущена если разработчик считает, что фактические ограничения будут вводить CE в заблуждение.

5.2.2.1. LFBName

Значением этой компоненты является имя описываемого класса LFB.

5.2.2.2. LFBClassID

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

5.2.2.3. LFBVersion

LFBVersion содержит строку, указывающую версию класса LFB, поддерживаемую этим FE. Как указано выше, FE может поддерживать лишь одну версию данного класса LFB.

5.2.2.4. LFBOccurrenceLimit

При наличии этой компоненты она указывает максимальное число экземпляров данного класса LFB, которые FE может поддерживать. Для FE, не имеющих возможности создавать или уничтожать экземпляры LFB, эта компонента может быть опущена или совпадать с числом экземпляров LFB этого класса в атрибуте списка LFB.

5.2.2.5. PortGroupLimits и PortGroupLimitType

Компонента PortGroupLimits является массивом информации о группах портов, поддерживаемых этим классом LFB. Структура информации об ограничении числа портов в группе определяется PortGroupLimitType dataTypeDef.

Каждый элемент массива PortGroupLimits содержит информацию об одной группе портов класса LFB, включающую имя группы портов в компоненте PortGroupName, наименьшее число портов группы в компоненте MinPortCount и наибольшее число портов группы в компоненте MaxPortCount.

5.2.2.6. CanOccurAfters и LFBAdjacencyLimitType

Компонента CanOccurAfters является массивом, содержащим список LFB, после которых может размещаться описываемый класс. Элементы массива определены в LFBAdjacencyLimitType dataTypeDef.

Элементы массива описывают разрешенное размещение данного класса LFB, называемого здесь SupportedLFB. В частности, каждый элемент именует LFB, который может топологически предшествовать данному классу LFB. То есть SupportedLFB может иметь входной порт, соединенный с выходным портом LFB, указанного в массиве CanOccurAfters. Класс LFB, за которым может следовать SupportedLFB, указывается компонентой NeighborLFB (LFBAdjacencyLimitType dataTypeDef) в массиве CanOccurAfters. Если сосед может быть подключен лишь к определенному набору групп входных портов, включается компонента viaPort, являющаяся массивом с элементом для каждой группы входных портов в SupportedLFB, который может быть соединен с выходным портом NeighborLFB.

Например, взаписи SupportedLFBs, каждый элемент массива CanOccurAfters должен иметь уникального соседа NeighborLFB, а в каждом таком элементе массива кажая компонента viaPort должна представлять свою действительную группу входных портов SupportedLFB. Схема определения класса LFB не включает этих требований к уникальности.

5.2.2.7. CanOccurBefores и LFBAdjacencyLimitType

Массив CanOccurBefores содержит информацию о классах LFB, которые могут следовать за описываемым классом. Структурно элемент похож на CanOccurAftersи использует такое же определение типа для элементов массива.

Элементы массива указывают классы LFB, которым SupportedLFB может предшествовать в топологии. В этой компоненте записи viaPort указывают группы выходных портов SupportedLFB, которые могут быть подключены к NeighborLFB. Как и в CanOccurAfters, viaPort может иметь множество записей если многим группам портов разрешено соединение с данным классом NeighborLFB.

Приведенные выше требования к уникальности для CanOccurAfter применимы и к CanOccurBefore, даже если класс LFB указан сразу в CanOccurAfter и CanOccurBefore.

5.2.2.8. UseableParentLFBClasses

При наличии массива UseableParentLFBClasses он используется для хранения списка идентификаторов родительских классов LFB. Все элементы массива должны быть идентификаторами классов, для которых класс SupportedLFB class является наследником14 (напрямую или через промежуточного предка). Кроме того, включая данный класс в список, FE указывает CE, что данный родительский класс может использовать для манипуляций с экземпляром этого поддерживаемого класса LFB.

Разрешая такое замещение, FE допускает случай, когда созданный экземпляр LFB может относиться к классу, не известному CE, но доступному для манипуляций. Есть надежда, что такие ситуации будут редкими, желательно, чтобы это поддерживалось. Это может произойти, если FE локально определяет некоторые экземпляры LFB или более ранний элемент CE настроил некоторые экземпляры LFB. Также это может происходить, когда FE предпочтет создать более новый и более подходящий экземпляр LFB.

Чтобы разрешить это, элемент FE должен быть более сдержанным при назначении идентификаторов экземпляров LFB. Обычно идентификаторы экземпляров определяются классом LFB. Однако, если два класса LFB имеют общего родителя и этот родитель включен в UseableParentLFBClasses для обоих классов LFB, все экземпляры обоих классов (или всех, если много классов имеет общего родителя) должны использовать разные экземпляры. Это позволяет FE определить, какой из экземпляров LFB предназначен для манипуляций CE даже при использовании родительского класса.

5.2.2.9. LFBClassCapabilities

Информация об уровне возможностей класса желательна, но модель ее не включает. Хотя такая информация относится к FE Object в таблице поддерживаемых классов, содержимое ее зависит от класса. Ожидаемые в настоящее время структуры кодирования при передаче информации между CE и FE таковы, что размещение совершенно не описанной информации может приводить к ошибкам при ее анализе. Можно было бы выбрать для этой информации тип octetstring, но это требует определения внутреннего формата строки октетов.

Поскольку в настоящее время отсутствуют какие-либо определения возможностей LFB на уровне класса, о которых FE требуется сообщать, такая информация здесь не представлена, но может быть добавлена в будущих версиях объекта FE (этот то случай, когда требуется управления версиями, а не наследование, поскольку объект FE должен иметь идентификаторы оъекта и класса со значением 1, чтобы протокол мог начинать работу с поиска этого объекта).

5.3. Компоненты FE

Элемент <components> включается, если определение класса содержит определение компонент объекта FE, которы не считаются «возможностями» (capabilities). Некоторые из этих компонент доступны для записи, а другие — лишь для чтения, что можно проверить путем просмотра информации компонент.

5.3.1. FEState

Эта компонента передает общее состояние FE и может принимать значение AdminDisable, OperDisable или OperEnable. Начальным состояние является OperDisable, а переход в OperEnable управляется FE. Элемент CE контролирует переходы между состояниями OperEnable и AdminDisable. Дополнительная информация приведена в спецификации протокола ForCES [RFC5810].

5.3.2. LFBSelectors и LFBSelectorType

LFBSelectors представляет собой массив информации LFB, доступных в данный момент по протоколу ForCES в FE. Структура информации LFB определена LFBSelectorType dataTypeDef.

Каждый элемент массива описывает один экземпляр LFB в элементе FE. Запись содержит числовые идентификаторы класса экземпляра LFB и данного экземпляра.

5.3.3. LFBTopology и LFBLinkType

Необязательная компонента LFBTopology содержит информацию о соединениях между LFB внутри FE, описывая каждое такое соединение в LFBLinkType dataTypeDef. Компонента LFBLinkType содержит информацию, достаточную для точного указания конечных точек соединения. Компоненты FromLFBID и ToLFBID задают экземпляры LFB на каждой стороне соединения и должны указывать LFB из таблицы экземпляров LFB. Компоненты FromPortGroup и ToPortGroup должны указывать входную и выходную группу портов, определенные в классах LFB экземпляров LFB, указанных в FromLFBID и ToLFBID. Компоненты FromPortIndex и ToPortIndex выбирают из групп порты, к которым это соединение подключено. Все соединения однозначно указываются полями FromLFBID, FromPortGroup и FromPortIndex. Множество соединений может иметь одинаковые значения ToLFBID, ToPortGroup и ToPortIndex, поскольку эта модель поддерживает входное (но не выходное) разветвление.

5.3.4. FENeighbors и FEConfiguredNeighborType

FENeighbors — это массив информации о настроенных вручную отношениях смежности между данным FE и другими элементами FE. Содержимое массива определяется FEConfiguredNeighborType dataTypeDef.

Массив предназначен для сбора информации, которая может быть задана на FE и нужна CE. Каждый элемент массива соответствует одному соседу. Отметим, что массив не отражает результатов автоматического обнаружения, поскольку они будут указывать свои LFB. Эта компонента не обязательна.

Существует много способов указания соседей, но для сопоставления в CE наиболее эффективно применять FE-ID. Идентификатор интерфейса (строка имени) является лучшим коррелятором. CE сможет получить IP-адрес и данные уровня среды напрямую от соседа. Отсутствие этой информации в таблице позволяет предотвратить риск некорректной «двойной настройки».

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

5.3.4.1. NeighborID

Это идентификатор в неком пространстве имен, значимый для CE применительно к соседу.

5.3.4.2. InterfaceToNeighbor

Идентификатор интерфейса, через который доступен сосед.

5.3.4.3. NeighborInterface

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

6. Выполнение требований к модели FE

В этом разделе рассматривается выполнение предложенной моделью FE требований, заданных в разделе 5 RFC 3654 [RFC3654]. Требования разделены на общую часть (раздел 5, параграфы 5.1 — 5.4) и требования к минимальному набору логических функций, которые должна поддерживать модель FE (параграф 5.5).

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

Основной компонентой предложенной модели FE является логический функциональный блок LFB. Каждая логическая функция в FE моделируется как LFB. Рабочие параметры LFB, которые должны быть видимы CE, называются компонентами LFB. Эти компоненты указывают возможности FE и поддерживают гибкость реализаций, позволяя FE указать поддерживаемые дополнительные возможности. Компоненты также указывают возможность настройки класса LFB элементами CE. Настраиваемые компоненты обеспечивают CE некоторую гибкость при задании поведения LFB. При создании множества экземпляров LFB одного класса LFB в элементе FE каждый из экземпляров LFB может быть настроен с разными параметрами компонент. Запрашивая настройки компонент экземпляров LFB, элемент CE может определить состояние LFB.

Созданные экземпляры LFB соединяются в направленный граф, который описывает упорядочение функций в FE. Этот граф описывается топологической моделью. Комбинация компонент экземпляров LFB и топологии описывает функции обработки пакетов, доступные в FE (текущее состояние).

Другими важными компонентами модели FE являются компоненты FE, которые служат в основном для описания возможностей FE, а также передают информацию о состоянии FE.

Модель FE включает лишь определение самого FE Object LFB. Для выполнения полного набора требований рабочей группы нужны дополнительные LFB. Определение классов для этих LFB будет дано в других документах.

7. Использование модели FE в протоколе ForCES

Фактическая модель уровня пересылки в данном NE заключается в том, что элемент CE должен изучать и контролировать, взаимодействуя с элементами FE (или иными способами). Большая часть таких коммуникаций будет происходить после создания ассоциации с использованием протокола ForCES. Ниже перечислены данные, которыми элементы CE и FE должны обмениваться по протоколу ForCES [RFC5810].

  1. Запрос топологии FE.

  2. Объявление возможностей FE.

  3. Запрос топологии LFB (на уровне FE) и настройки возможностей.

  4. Объявление возможностей LFB.

  5. Запрос состояния компонент LFB.

  6. Манипуляции с компонентами LFB.

  7. Изменение топологии LFB.

В пп. 1 — 5 основной поток информации идет от FE к CE. Пп. 1 — 4 обычно запрашиваются элементами CE на начальном этапе фазы PA15, хотя они могут повторяться в фазе PA (в любой момент). П. 5 (запрос состояния) используется в начале фазы PA и часто повторяется в этой фазе (особенно запросы счетчиков статистики).

Пп. 6 и 7 представляют собой «команды» и основной поток информации идет от CE к FE. Сообщения п. 6 (команды изменения конфигурации LFB) предполагаются достаточно частыми. П. 7 (изменение топологии LFB ) нужно использовать ли при поддержке FE динамического изменения топологии LFB и они предполагаются нечастыми.

Топология соединений между FE (п. 1) может быть определена CE разными способами. Ни данный документ, ни спецификация ForCES [RFC5810] не задают конкретных механизмов. Определение класса LFB включает возможность настройки идентификации соседей на FE или предоставление этой информации по запросу CE. Могут быть также определены специальные классы LFB и протоколы для обнаружения соседей. CE может применять протоколы маршрутизации для определения отношений смежности. Соответствующая конфигурация может быть задана в CE.

Связи между моделью FE и семью сообщениями фазы PA показаны на рисунке 12.

                                    +--------+
                       ..........-->|   CE   |
  /----\               .            +--------+
  \____/ Модель FE     .              ^    |
  |    |................        (1),2 |    | 6, 7
  |    |  (off-line)   .      3, 4, 5 |    |
  \____/               .              |    v
                       .            +--------+
Например, RFC          ..........-->|   FE   |
                                    +--------+

Рисунок 12. Связь между моделью FE и сообщениями протокола ForCES, где (1) — часть базового протокола ForCES, а остальное определено моделью FE


Кодирование этих сообщений определяется протоколом ForCES protocol [RFC5810] и выходит за рамки модели FE. Тем не менее важно рассмотреть этот вопрос здесь в силу перечисленных ниже причин.

  • Компоненты модели PA оказывают существенное влияние на модель FE. Например, часть упомянутой выше информации может быть представлена в виде компонент LFB, которые в этом случае должны определяться в классах LFB.

  • Знание типа информации, которая может передаваться между FE и CE может помочь при выборе подходящего протокольного формата и метода кодирования (такого как XML, TLV).

  • Знание частоты этого типа сообщений должно влиять на выбор протокольного формата (эффективность).

Оставшиеся параграфы этого раздела посвящены каждому из семи типов сообщений.

7.1. Запрос топологии FE

FE может (не обязательно) иметь один или несколько внешних входных портов, а также может (не обязательно) иметь один или несколько внешних выходных портов. Иными словами, не каждый элемент FE имеет внешние входные и/или выходные интерфейсы. Например, на рисунке 13 показан каскад из двух FE. FE #1 имеет внешний входной интерфейс, но не имеет внешнего выходного, а FE #2 — наоборот. Можно соединить эти два FE через их внутренние интерфейсы для обеспечения входной и выходной обработки. Это позволяет гибко распределять функции между множеством FE, а затем соединять их в соответствии с задачами.

   +-----------------------------------------------------+
   |  +---------+   +------------+   +---------+         |
 Вход |         |   |            |   |         | Выход   |
---+->| Входной |-->|Сжатие      |-->|Пересылка|---------+--->+
   |  | порт    |   |заголовков  |   |IPv4     | FE      |    |
   |  +---------+   +------------+   +---------+ #1      |    |
   +-----------------------------------------------------+    V
                                                              |
        +-----------------------<-----------------------------+
        |
        |    +----------------------------------------+
        V    |  +------------+   +----------+         |
        | Вход  |            |   |          | Выход   |
        +->--+->|Декомпрессия|-->| Выходной |---------+-->
             |  |заголовков  |   | порт     | FE      |
             |  +------------+   +----------+ #2      |
             +----------------------------------------+

Рисунок 13. Пример двух соединенных вместе FE.


Хотя протокол взаимодействия между FE выходит за рамки ForCES, элементам CE нужно понимать, как соединены между собой FE для полной реализации функций входной и выходной обработки, например, как показано на рисунке 13. Топологию соединений могут предоставлять устройства FEs, она может быть жестко закодирована в CE или предоставляться иным путем (например, менеджером шины) независимо от FE. Поэтому, хотя протокол ForCES [RFC5810] и позволяет запросить у FE топологические данные, CE не обязательно использовать это при наличии у CE других способов получения этой информации.

Когда топология соединений между FE получена CE по запросу, далее она считается статичной. Однако элемент FE может быть отключен в процессе работы NE или может быть установлена новая плата и активизирован новый элемент FE и топология соединений между FE может измениться. Протокол ForCES должен обеспечивать для CE механизм детектирования таких событий и обработки изменений в топологии FE, однако топология FE выходит за рамки модели FE.

7.2. Объявление возможностей FE

FE может иметь разные типы ограничений, часть которых может быть представлена CE как часть модели возможностей. Элементы CE должны быть способны запрашивать у отдельного FE:

  • возможности передачи метаданных (понимание этих возможностей поможет CE пригодность топологии LFB и определить доступность некоторых служб);

  • глобальные ограничения на запрос ресурсов (применимо ко всем LFB в FE);

  • LFB, поддерживаемые FE;

  • пределы числа экзепляров классов LFB;

  • топологические ограничения LFB (соединения, порядок и т. п.).

7.3. Запрос топологии LFB и возможности ее настройки

Протокол ForCES должен обеспечивать CE способ определить текущий набор экземпляров LFB в FE и соединения между LFB внутри FE. В дополнение к этому следует обеспечивать информацию, достаточную для определения FE, поддерживающих любые инициированные CE (динамические) изменения топологии LFB, и определения для них разрешенных топологий. Возможность настройки топологии может также рассматриваться как часть запроса возможностей FE, как описано в параграфе 7.2.

7.4. Объявления возможностей LFB

Спецификации классов LFB задают базовый набор возможностей. Когда экземпляры LFB реализованы (созданы) на FE производителя, могут вводиться дополнительные ограничения. Отметим, что здесь рассматриваются лишь ограничения в пределах гибкости спецификации класса LFB. Т. е. экземпляр LFB остается соответствующим спецификации класса LFB, несмотря на эти ограничения. Например, некоторые свойства класса LFB могут быть необязательными и в таких случаях нужно давать CE возможность решения вопроса о поддержке этих свойств данным экземпляром LFB. Кроме того, определения классов LFB будут вероятно включать немного количественных ограничения (например, размер таблиц), поскольку такие ограничения обычно вносятся реализацией. Поэтому количественные ограничения следует всегда выражать как аргументы возможностей.

Экземпляры LFB в модели конкретной реализации FE будут следовать ограничениям возможностей, определенным в соответствующем классе LFB. Спецификации классов LFB должны определять набор аргументов возможностей а элемент CE должен быть способен узнать фактические возможности экземпляра LFB, запрашивая значения таких аргументов. Запросы возможностей обычно будут выполняться при обнаружении LFB элементом CE. Возможности не требуется запрашивать снова в случае статических ограничений. Однако в некоторых случаях (например при добавлении или удалении других LFB, а также настройке компонент в других LFB при использовании блоками LFB общих физических ресурсов) возможности могут изменяться и тогда нужны механизмы информирования об этом CE.

Ниже перечислены два имеющихся типа ограничений.

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

  • Количественные ограничения, такие как размер таблиц и т. п.

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

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

В предположении достаточно редкого изменения возможностей эффективность протокола/схемы/кодирования отходит на второй план.

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

7.5. Запрос состояния компонент LFB

Это свойство должно поддерживаться всеми FE. Протокол ForCES и схема/кодирование данных протокола должны совместно выполнять приведенные ниже требования для упрощения запроса состояния компонентLFB.

  • Должен поддерживаться выбор FE. Это относится прежде всего к указанию одного FE, но может поддерживаться и указание группы или всех FE.

  • Должен разрешаться выбор экземпляра LFB. Это относится прежде всего к указанию одного экземпляра LFB, но может поддерживаться и указание группы или всех экземпляров LFB.

  • Должна поддерживаться адресация отдельных компонент LFB.

  • Должно поддерживаться эффективное кодирование и декодирование адресной информации и настроенных данных.

  • Должна обеспечиваться эффективная передача данных состояния компонент через «провод» для минимизации загрузки канала между CE и FE.

7.6. Манипуляции компонентами LFB

Модель FE обеспечивает определения для классов LFB, каждый из которых имеет глобально уникальный идентификатор. Информация внутри класса представляется как компоненты и назначенные идентификаторы в области действия этого класса. Модель также указывает, что экземпляры классов LFB имеют идентификаторы. Комбинация идентификатора класса, идентификатора экземпляра и идентификатора компоненты используется протоколом для доступа к информации LFB в протокольных операциях.

7.7. Изменение топологии LFB

Операции, которые требуются для перенастройки топологии LFB, включают:

  • создание нового экземпляра данного класса LFB в данном FE;

  • подключение данного выхода LFB x к данному входу LFB y;

  • отключение путем удаления канала между данным выходом одного LFB и данным входом другого;

  • удаление данного LFB (автоматически удаляются все его соединения с другими LFB).

8. Пример определения LFB

В этом разделе приведен пример определения LFB. Хотя некоторые свойства LFB показаны блоком FE Object LFB, здесь показано, как может строиться LFB уровня данных. Этот пример является вымышленным случаем интерфейса, поддерживающего CWDM и передающего трафик Frame Relay. Статистическая информация (включая ошибки) не включена.

Последняя часть этого примера включает ссылки на протокольные операции. Формат и поля здесь указаны исключительно для иллюстрации, поскольку точный синтаксис и семантику операций определяет протокол ForCES [RFC5810].

  <?xml version="1.0" encoding="UTF-8"?>
        <LFBLibrary xmlns="urn:ietf:params:xml:ns:forces:lfbmodel:1.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         provides="LaserFrameLFB">
          <frameDefs>
            <frameDef>
              <name>FRFrame</name>
              <synopsis>
                  Кадр Frame Relay с DLCI без «прокладки»</synopsis>
            </frameDef>
            <frameDef>
              <name>IPFrame</name>
               <synopsis>Пакет IP</synopsis>
            </frameDef>
          </frameDefs>
          <dataTypeDefs>
            <dataTypeDef>
              <name>frequencyInformationType</name>
              <synopsis>Информация об одной частоте CWDM</synopsis>
              <struct>
                <component componentID="1">
                  <name>LaserFrequency</name>
                  <synopsis>Кодированная частота (канал)</synopsis>
                  <typeRef>uint32</typeRef>
                </component>
                <component componentID="2">
                  <name>FrequencyState</name>
                  <synopsis>Состояние частоты</synopsis>
                  <typeRef>PortStatusValues</typeRef>
                </component>
                <component componentID="3">
                  <name>LaserPower</name>
                  <synopsis>Текущая наблюдаемая мощность</synopsis>
                  <typeRef>uint32</typeRef>
                </component>
                <component componentID="4">
                  <name>FrameRelayCircuits</name>
                  <synopsis>
                      Информация об устройствах на этой частоте
                  </synopsis>
                  <array>
                    <typeRef>frameCircuitsType</typeRef>
                  </array>
                </component>
              </struct>
            </dataTypeDef>
            <dataTypeDef>
              <name>frameCircuitsType</name>
              <synopsis>
                  Информация об одном устройстве (канале) Frame Relay
              </synopsis>
              <struct>
                <component componentID="1">
                  <name>DLCI</name>
                  <synopsis>DLCI of the circuit</synopsis>
                  <typeRef>uint32</typeRef>
                </component>
                <component componentID="2">
                  <name>CircuitStatus</name>
                  <synopsis>Состояние устройства</synopsis>
                  <typeRef>PortStatusValues</typeRef>
                </component>
                <component componentID="3">
                  <name>isLMI</name>
                  <synopsis>Является ли устройство LMI16</synopsis>
                  <typeRef>boolean</typeRef>
                </component>
                <component componentID="4">
                  <name>associatedPort</name>
                  <synopsis>
                      Какой входной/выходной порт связан с устройством
                  </synopsis>
                  <typeRef>uint32</typeRef>
              </struct>
            </dataTypeDef>
            <dataTypeDef>
              <name>PortStatusValues</name>
              <synopsis>
                  Возможные значения состояния (рабочего и административного)
              </synopsis>
              <atomic>
                <baseType>uchar</baseType>
                <specialValues>
                  <specialValue value="0">
                    <name>Disabled </name>
                    <synopsis>Компонента отключена</synopsis>
                  </specialValue>
                  <specialValue value="1">
                    <name>Enabled</name>
                    <synopsis>Элемент FE оперативно включен</synopsis>
                  </specialValue>
                </specialValues>
              </atomic>
            </dataTypeDef>
          </dataTypeDefs>
          <metadataDefs>
            <metadataDef>
              <name>DLCI</name>
              <synopsis>DLCI прибывшего кадра</synopsis>
              <metadataID>12</metadataID>
              <typeRef>uint32</typeRef>
            </metadataDef>
            <metadataDef>
              <name>LaserChannel</name>
              <synopsis>Индекс канала лазера</synopsis>
              <metadataID>34</metadataID>
              <typeRef>uint32</typeRef>
            </metadataDef>
          </metadataDefs>
          <LFBClassDefs>
              <!-- Фиктивный идентификатор класса с действительным значением -->
            <LFBClassDef LFBClassID="255">
              <name>FrameLaserLFB</name>
              <synopsis>Фиктивный блок LFB для демонстрации</synopsis>
              <version>1.0</version>
              <inputPorts>
                <inputPort group="true">
                  <name>LMIfromFE</name>
                  <synopsis>Порты для передачи трафика LMI</synopsis>
                  <expectation>
                    <frameExpected>
                      <ref>FRFrame</ref>
                    </frameExpected>
                    <metadataExpected>
                      <ref>DLCI</ref>
                      <ref>LaserChannel</ref>
                    </metadataExpected>
                  </expectation>
                </inputPort>
                <inputPort>
                  <name>DatafromFE</name>
                  <synopsis>
                      Порты для данных, передаваемых в каналы (устройства)
                  </synopsis>
                  <expectation>
                    <frameExpected>
                      <ref>IPFrame</ref>
                    </frameExpected>
                    <metadataExpected>
                      <ref>DLCI</ref>
                      <ref>LaserChannel</ref>
                    </metadataExpected>
                  </expectation>
                </inputPort>
              </inputPorts>
              <outputPorts>
                <outputPort group="true">
                  <name>LMItoFE</name>
                  <synopsis>Порты для обрабатываемого трафика LMI</synopsis>
                  <product>
                    <frameProduced>
                      <ref>FRFrame</ref>
                    </frameProduced>
                    <metadataProduced>
                      <ref>DLCI</ref>
                      <ref>LaserChannel</ref>
                    </metadataProduced>
                  </product>
                </outputPort>
                <outputPort group="true">
                  <name>DatatoFE</name>
                  <synopsis>Порты для обрабатываемого трафика данных</synopsis>
                  <product>
                    <frameProduced>
                      <ref>IPFrame</ref>
                    </frameProduced>
                    <metadataProduced>
                      <ref>DLCI</ref>
                      <ref>LaserChannel</ref>
                    </metadataProduced>
                  </product>
                </outputPort>
              </outputPorts>
              <components>
                <component access="read-write" componentID="1">
                  <name>AdminPortState</name>
                  <synopsis>Разрешена ли работа этого порта</synopsis>
                  <typeRef>PortStatusValues</typeRef>
                </component>
                <component access="read-write" componentID="2">
                  <name>FrequencyInformation</name>
                  <synopsis>Таблица информации для частоты CWDM</synopsis>
                  <array type="variable-size">
                    <typeRef>frequencyInformationType</typeRef>
                  </array>
                </component>
              </components>
              <capabilities>
                <capability componentID="31">
                  <name>OperationalState</name>
                  <synopsis>Работает ли порт всегда</synopsis>
                  <typeRef>PortStatusValues</typeRef>
                </capability>
                <capability componentID="32">
                  <name>MaximumFrequencies</name>
                  <synopsis>Число имеющихся длин волн</synopsis>
                  <typeRef>uint16</typeRef>
                </capability>
                <capability componentID="33">
                  <name>MaxTotalCircuits</name>
                  <synopsis>
                      Общее число поддерживаемых устройств Frame Relay 
                      на всех длинах волн
                  </synopsis>
                  <optional/>
                  <typeRef>uint32</typeRef>
                </capability>
              </capabilities>
              <events baseID="61">
                <event eventID="1">
                  <name>FrequencyState</name>
                  <synopsis>
                      Состояние лазерной частоты изменилось
                  </synopsis>
                  <eventTarget>
                    <eventField>FrequencyInformation</eventField>
                    <eventSubscript>_FrequencyIndex_</eventSubscript>
                    <eventField>FrequencyState</eventField>
                  </eventTarget>
                  <eventChanged/>
                  <eventReports>
                      <!-- Отчет о новом состоянии -->
                    <eventReport>
                      <eventField>FrequencyInformation</eventField>
                      <eventSubscript>_FrequencyIndex_</eventSubscript>
                      <eventField>FrequencyState</eventField>
                    </eventReport>
                  </eventReports>
                </event>
                <event eventID="2">
                  <name>CreatedFrequency</name>
                  <synopsis>Обнаружена новая частота</synopsis>
                  <eventTarget>
                    <eventField>FrequencyInformation></eventField>
                    <eventSubscript>_FrequencyIndex_</eventSubscript>
                  </eventTarget>
                  <eventCreated/>
                  <eventReports>
                    <eventReport>
                      <eventField>FrequencyInformation</eventField>
                      <eventSubscript>_FrequencyIndex_</eventSubscript>
                      <eventField>LaserFrequency</eventField>
                    </eventReport>
                  </eventReports>
                </event>
                <event eventID="3">
                  <name>DeletedFrequency</name>
                  <synopsis>
                      Удалена запись в таблице частот
                  </synopsis>
                  <eventTarget>
                    <eventField>FrequencyInformation</eventField>
                    <eventSubscript>_FrequencyIndex_</eventSubscript>
                  </eventTarget>
                  <eventDeleted/>
                 </event>
                <event eventID="4">
                  <name>PowerProblem</name>
                  <synopsis>Проблемы с уровнем мощности лазера</synopsis>
                  <eventTarget>
                    <eventField>FrequencyInformation</eventField>
                    <eventSubscript>_FrequencyIndex_</eventSubscript>
                    <eventField>LaserPower</eventField>
                  </eventTarget>
                  <eventLessThan/>
                  <eventReports>
                    <eventReport>
                      <eventField>FrequencyInformation</eventField>
                      <eventSubscript>_FrequencyIndex_</eventSubscript>
                      <eventField>LaserPower</eventField>
                    </eventReport>
                    <eventReport>
                      <eventField>FrequencyInformation</eventField>
                      <eventSubscript>_FrequencyIndex_</eventSubscript>
                      <eventField>LaserFrequency</eventField>
                    </eventReport>
                  </eventReports>
                </event>
                <event eventID="5">
                  <name>FrameCircuitChanged</name>
                  <synopsis>
                      Изменилось состояние устройства FR на частоте
                  </synopsis>
                  <eventTarget>
                    <eventField>FrequencyInformation</eventField>
                    <eventSubscript>_FrequencyIndex_</eventSubscript>
                    <eventField>FrameRelayCircuits</eventField>
                    <eventSubscript>FrameCircuitIndex</eventSubscript>
                    <eventField>CircuitStatus</eventField>
                  </eventTarget>
                  <eventChanged/>
                  <eventReports>
                    <eventReport>
                      <eventField>FrequencyInformation</eventField>
                      <eventSubscript>_FrequencyIndex_</eventSubscript>
                      <eventField>FrameRelayCircuits</eventField>
                      <eventSubscript>FrameCircuitIndex</eventSubscript>
                      <eventField>CircuitStatus</eventField>
                    </eventReport>
                    <eventReport>
                      <eventField>FrequencyInformation</eventField>
                      <eventSubscript>_FrequencyIndex_</eventSubscript>
                      <eventField>FrameRelayCircuits</eventField>
                      <eventSubscript>FrameCircuitIndex</eventSubscript>
                      <eventField>DLCI</eventField>
                    </eventReport>
                  </eventReports>
                </event>
              </events>
            </LFBClassDef>
          </LFBClassDefs>
        </LFBLibrary>

8.1. Обработка данных

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

Пакеты, прибывшие без ошибок из физического интерфейса, попадают в Frame Relay DLCI на лазерном канале. Эти два значения используются LFB для поиска при обработке пакета. Если обработка показывает, что пакет относится к LMI, используется выходной индекс для выбора порта LFB в группе LMItoFE. Пакет передается в виде полного кадра FR (без вставки битов или байтов) в выбранный порт. Лазерный канал и DLCI передаются как метаданные, хотя DLCI имеется и в пакете.

Пакеты без ошибок, не относящиеся к LMI и имеющие индикатор типа IP, передаются как пакеты IP в порт группы DatatoFE с использованием того же поля индекса из таблицы на основе лазерного канала и DLCI, которые передаются как метаданные для последующего применения (например, классификации).

Текущее определение не указывает поведения для кадров, тип которых не является IP.

Пакеты, приходящие на входные порты сопровождаются метаданными для лазерного канала и DLCI. Поэтому может использоваться один входной порт. Со структурой, которая определена (параллельно выходной структуре) выбор канала и DLCI может быть ограничен группой входного порта (LMI и данные) и индексом порта. При другом устройстве LFB структура может требовать взаимно-однозначного соответствия между DLCI и портом LFB, когда метаданные станут ненужными. Однако это приведет к усложнению. Промежуточный уровень структуры здесь обеспечивает параллелизм между входом и выходом, не требуя избыточных портов.

8.1.1. Организация DLCI

Когда элемент CE решает организовать DLCI на определенном лазерном канале, он передает запрос SET, направленный этому блоку LFB. Запрос имеет вид

      T = SET
        T = PATH-DATA
          Path: flags = none, length = 4, path = 2, channel, 4, entryIdx
          DataRaw: DLCI, Enabled(1), false, out-idx

Это будет создавать DLCI с трафиком, идущим в конкретный порт выходной группы DatatoFE (CE будет гарантировать подключение этого порта к нужному месту до отправки запроса).

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

Можно представить, что FE имеет LMI LFB. Такие LFB будут подключаться к группам портов LMItoFE и LMIfromFE и обрабатывать информацию LMI. Задачей LFB может быть организация устройств Frame Relay. LMI LFB будет иметь псевдоним, указывающий на поддерживаемую таблицу устройств Frame Relay и сможет манипулировать этими записями.

8.1.2. Обработка ошибок

LFB будет иногда получать из линии непригодные пакеты. Многие из них будут просто увеличивать значения соответствующих счетчиков. Разработчик LFB может задать некоторые меры частоты ошибок. Это добавит работы FE, но сделает сигналы более осмысленными.

При некоторых ошибках может потребоваться передача части пакета элементу CE. Ошибка сама по себе не вызывает события в LFB. Имеется два способа решить задачу отправки информации CE.

Одним способом является определение специальной компоненты для учета ошибок и компоненты LFB для хранения нужной части пакета. Можно определить компоненту для хранения части последнего пакета с ошибкой, затем определить событие, которое происходит при изменении счетчика ошибок и объявить, что сообщение о событии включает поле LFB с частью пакета. Для редких, но критически важных ошибок это будет эффективным решением, поскольку обеспечивается гарантия доставки уведомлений, а CE может указать, нужны ли ему эти уведомления.

Другой подход заключается в создании LFB с портом, подключенным к приемнику перенаправления. LFB будет добавлять метаданные лазерного канала, DLCI и индикации ошибок, а затем доставлять пакет CE.

Другие аспекты обработки ошибок рассмотрены ниже.

8.2. Компоненты LFB

Этот блок LFB определен с компонентами верхнего уровня, отражающими административное состояние LFB, что позволяет элементу CE полностью отключить LFB.

Другой компонентой является таблица информации о лазерных каналах в виде массива с переменным размером. Каждый элемент массива содержит идентификатор длины волны, с которой связан этот элемент, рабочее состояние этой длины волны, мощность лазера на данном канале и таблицу устройств Frame Relay на этой длине волны. Здесь нет административного состояния, поскольку CE может отключить запись путем ее удаления (длиы волн и мощность лазера в неиспользуемых каналах практического интереса не представляют, информация о поддерживаемых длинах волн доступна в разделе возможностей).

Информация об устройстве (канале) Frame Relay содержит DLCI, рабочее состояние канала, использование канала для передачи информации LMI и и порт выходной группы LFB, в который передается трафик. Как отмечено выше, индекс устройства может в некоторых случаях комбинироваться с DLCI.

8.3. Возможности

Информация о возможностях для этого LFB включает рабочее состояние базового интерфеса, число поддерживаемых длин волн, число разрешенных локальных устройств для всех каналов. Максимальное число устройств для данного лазерного канала можно определить из таблицы FrameRelayCircuits. GET-PROP для пути 2.channel.4 будет давать CE свойства данного массива FrameRelayCircuits, которые включают число используемых элементов, первый доступный элемент и максимально разрешенное число элементов.

8.4. События

Этот блок LFB определен с возможностью генерации нескольких событий, которые могут быть интересны CE. Это уведомления об изменении рабочего состояния лазерных частот, а также создании и удалении частот (длин волн). Кроме того, поддерживаются уведомления о смене состояний отдельных устройств Frame Relay. Например, уведомление 61.5.3.11 будет говорить об изменении статуса устройства с индексом 11 в текущей таблице с индексом 3 таблицы длин волн. Уведомление о событии будет также указывать новое состояние устройства и DLCI. Возможно, DLCI является избыточным, поскольку CE предположительно знает DLCI по индексу устройства. Это поле указано здесь для демонстрации включения в отчет о событии двух информационных элементов.

Как сказано выше, объявление события определяет его получателя, условия и содержимое уведомления. Свойства события показывают, подписан ли на него элемент CE, порого события и фильтры для этого события.

Другим типом событий являются проблемы с мощностью лазера. Эти события генерируются при падении мощности ниже заданного порога. Таким образом, CE может регистрировать событие потери мощности лазера на всех устройствах. Это может иметь вид

         T = SET-PROP
           Path-TLV: flags=0, length = 2, path = 61.4
             Path-TLV: flags = property-field, length = 1, path = 2
               Content = 1 (register)
             Path-TLV: flags = property-field, length = 1, path = 3
               Content = 15 (threshold)

Это будет регистрировать событие для всех записей в таблице, а также устанавливать порог, в соответствии с которым событие будет генерироваться при падении мощности ниже 15 (предполагается, что CE знает единицы измерения мощности и поймет это значение).

Если мощность лазера колеблется около значения 15, может возникать множество уведомлений (например при переходе между 14 и 15 каждый переход будет создавать уведомление). Предположим, что CE решает подавить эти осцилляции на канале 5. Это можно сделать путем задания гистерезиса, как показано ниже.

         T = SET-PROP
           Path-TLV: flags=0, length = 3, path = 61.4.5
             Path-TLV: flags = property-field, length = 1, path = 4
               Content = 2 (hysteresis)

Установка гистерезиса 2 подавляет множество ненужных уведомлений. Когда уровень первый раз упадет ниже 10, будет создано уведомление. Если мощность возрастет до 10 или 11, а затем снова упадет ниже 10, уведомления не будет. Если мощность поднимется по меньшей мере до 12, а затем упадет ниже 10, снова будет создано уведомление. Одной из основных причин таких колебаний является фактическое значение мощности около границы. Если мощность составляет 9,5, незначительные ее изменения будут приводить к скачкам между 9 и 10. Гистерезис со значением 1 будет подавлять ненужные уведомления. Другие события могут приводить к более сильным колебаниям и для них потребуется большее значение гистерезиса.

9. Взаимодействие с IANA

The ForCES model creates the need for a unique XML namespace for ForCES library definition usage, and unique class names and numeric class identifiers.

9.1. Регистрация пространства имен URN

Агентство IANA зарегистрировало новое пространство имен XML в соответствии с рекомендациями RFC 3688 [RFC3688].

   URI: URI для этого пространства имен имеет значение
   urn:ietf:params:xml:ns:forces:lfbmodel:1.0
   Registrant Contact: IESG
   XML: нет, но это пространство имен XML

9.2. Имена и идентификаторы классов LFB

Чтобы иметь четко определенные классы ForCES LFB и четко определенные идентификаторы в этих классах агентство IANA создало реестр имен классов LFB, соответствующих идентификаторов классов и документов с определениями классов LFB. Значения в реестре выделяются в порядке подачи заявок (FCFS17) Идентификаторы классов LFB со значением меньше 65536 зарезервированы для IETF Standards-Track RFC. Идентификаторы с номерами 65536 и выше в 32-битовом пространстве доступны для выделения в порядке поступления запросов. Все записи реестра должны быть документированы в стабильной форме с открытым доступом.

Поскольку в реестре предусмотрена процедура FCFS для части пространства идентификаторов, нужно определить правила именования классов, использующих идентификаторы из этого пространства. Поскольку они могут определяться любым путем, задается лишь требование отсутствия совпадений имен классов с именами классов, определенными IETF. По этой причине все классы FCFS должны начинаться с префикса «Ext-».

Агентство IANA создало реестр ForCES LFB Class Names и соответствующих идентификаторов ForCES LFB Class Identifiers как показано в таблице.

Имя класса LFB

Идентификатор класса LFB

Документ

Описание

Резерв

0

RFC 5812

Резерв

FE Object

1

RFC 5812

Определяет информацию ForCES FE

FE Protocol Object

2

RFC 5810

Определяет параметры операций ForCES

LFB, определяемые IETF

3 — 65535

Standards Track RFC

Зарезервированы для определяемых IETF RFC

Имена классов ForCES LFB с префиксом EXT-

> 65535

Любой документ с открытым доступом

Обслуживание в порядке очередности для любых целей

10. Почетные авторы

Ниже приведен список авторов, внесших свой вклад в создание ранних версий этого документа.

Ellen Delganes, Intel Corp.

Lily Yang, Intel Corp.

Ram Gopal, Nokia Research Center

Alan DeKok, Infoblox, Inc.

Zsolt Haraszti, Clovis Solutions

11. Благодарности

Многие из наших коллег в компаниях и участников почтовой конференции ForCES внесли важный вклад в эту работу. Особая благодарность Evangelos Haleplidis за помощью с XML.

12. Вопросы безопасности

Модель FE описывает организацию и представление наборов данных и компонент в FE. Базовый документ ForCES [RFC3746] включает всеобъемлющий анализ безопасности архитектуры ForCES в целом. Например, объекты протокола ForCES должны быть аутентифицированы в соответствии с требованиями ForCES до того, как они смогут получить доступ к описанной в этом документе информации по протоколу ForCES. Доступ к информации, содержащейся в модели FE, обеспечивается протоколом ForCES, который определен в отдельных документах, включающих рассмотрение вопросов безопасности.

13. Литература

13.1. Нормативные документы

[RFC2119] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, March 1997.

[RFC5810] Doria, A., Ed., Hadi Salim, J., Ed., Haas, R., Ed., Khosravi, H., Ed., Wang, W., Ed., Dong, L., Gopal, R., and J. Halpern, «Forwarding and Control Element Separation (ForCES) Protocol Specification», RFC 5810, March 2010.

[RFC3688] Mealling, M., «The IETF XML Registry», BCP 81, RFC 3688, January 2004.

[Schema1] Thompson, H., Beech, D., Maloney, M., and N. Mendelsohn, «XML Schema Part 1: Structures», W3C REC-xmlschema-1, http://www.w3.org/TR/xmlshcema-1/, May 2001.

[Schema2] Biron, P. and A. Malhotra, «XML Schema Part 2: Datatypes», W3C REC-xmlschema-2, http://www.w3.org/TR/xmlschema-2/, May 2001.

13.2. Дополнительная литература

[RFC3654] Khosravi, H. and T. Anderson, «Requirements for Separation of IP Control and Forwarding», RFC 3654, November 2003.

[RFC3746] Yang, L., Dantu, R., Anderson, T., and R. Gopal, «Forwarding and Control Element Separation (ForCES) Framework», RFC 3746, April 2004.

[RFC3317] Chan, K., Sahita, R., Hahn, S., and K. McCloghrie, «Differentiated Services Quality of Service Policy Information Base», RFC 3317, March 2003.

[RFC3318] Sahita, R., Hahn, S., Chan, K., and K. McCloghrie, «Framework Policy Information Base», RFC 3318, March 2003.

[RFC3444] Pras, A. and J. Schoenwaelder, «On the Difference between Information Models and Data Models», RFC 3444, January 2003.

[RFC3470] Hollenbeck, S., Rose, M., and L. Masinter, «Guidelines for the Use of Extensible Markup Language (XML) within IETF Protocols», BCP 70, RFC 3470, January 2003.

[UNICODE] Davis, M. and M. Suignard, «UNICODE Security Considerations», http://www.unicode.org/reports/tr36/tr36-3.html, July 2005.


Адреса авторов

Joel Halpern

Self

P.O. Box 6049

Leesburg, VA 20178

USA

Phone: +1 703 371 3043

EMail: jmh@joelhalpern.com

Jamal Hadi Salim

Znyx Networks

Ottawa, Ontario

Canada

EMail: hadi@mojatatu.com


Перевод на русский язык

Николай Малых

nmalykh@gmail.com

1Forwarding element.

2Forwarding and Control Element Separation — разделение элементов управления и пересылки.

3Control element.

4Internet Engineering Task Force.

5Internet Engineering Steering Group.

6Network element.

7Information model.

8Data model.

9Logical Functional Block.

10Logical Function Block.

11В оригинале ошибочно сказано FE. Прим. перев.

12Longest-Prefix-Matching — максимальный размер совпадения префиксов.

13Quality-of-service — качество обслуживания.

14Если FE включает в этот список непригодные значения, это с высокой вероятностью приведет к некорректным действиям CE и отказам в работе.

15Post-association — после создания ассоциации.

16Local Management Interface — локальный интерфейс управления. Прим. перев.

17First come, first served — первым пришел, первого обслужили.

Рубрика: RFC | Комментарии к записи RFC 5812 Forwarding and Control Element Separation (ForCES) Forwarding Element Model отключены

Файловая система tmpfs

PDF

Автор:
Christoph Rohland <cr@sap.com>, 1.12.01

Обновление:
Hugh Dickins, 4 June 2007

Обновление:
KOSAKI Motohiro, 16 Mar 2010

Файловая система tmpfs служит для хранения файлов в виртуальной памяти.

Содержимое tmpfs является временным в том смысле, что на «жесткие» диски диски компьютера файлы этой системы не записываются. При размонтировании экземпляра tmpfs все хранящиеся в этой файловой системе данные будут потеряны.

Файловая система tmpfs размещается во внутреннем кэше ядра и меняет свой размер (расширяется или сужается) в соответствии с обънмом хранящейся информации. Ненужные в настоящее время страницы могут «сбрасываться» в область подкачки (swap). Максимальный размер файловой системы можно исзменять в процессе работы с помощью команды mount -o remount …

В отличие от файловой системы ramfs (прообраз tmpfs) поддерживается возможность свопинга и контроля размера. Другим похожим объектом являются виртуальные диски в ОЗУ
(RAM-диск, /dev/ram*), которые имитируют «жесткий» диск фиксированного размера, размещаемый в физической памяти компьютера с организованной на нем обычной файловой системой. Для виртуальных дисков свопинг и изменение размера не поддерживаются.

Поскольку tmpfs может размещаться только в страницах кэша и области подкачки, все страницы tmpfs, находящиеся в памяти, будут выглядеть, как кэшированные. Они не будут представляться чем-либо типа разделяемых страниц. Более того, вы можете проверить реальное размещение данных tmpfs в ОЗУ и области подкачки с помощью команд df и du.

Файловая система tmpfs служит для решения ряда задач:

  1. В ядре используется несколько внутренних точек монтирования, невидимых для пользователя и служащих для организации разделяемых анонимных отображений и разделяемой памяти SYSV.

    На эти монтирования опция ядра CONFIG_TMPFS не указывает влияния. Если эта опция не была установлена при сборке ядра, видимая пользователю часть tmpfs не создается, но внутренние механизмы продолжают использоваться.

  2. glibc, начиная с версии 2.2, предполагает, что файловая система tmpfs примонтирована, как /dev/shm для разделяемой памяти POSIX (shm_open, shm_unlink). Для реализации этого в файле /etc/fstab указывается строка:

    tmpfs	/dev/shm	tmpfs	defaults	0 0

    Не забудьте создать на диске каталог, куда вы планируете монтировать tmpfs.

    Эта точка монтирования не требуется для разделяемой памяти SYSV, поскольку для этого служит внутреннее монтирование в ядре (в ядре версии 2.3 требовалось монтировать предшественника tmpfs — shm fs — для использования разделяемой памяти SYSV).

  3. Некоторые считают весьма удобным монтировать файловую систему tmpfs как /tmp и/или /var/tmp при наличии большого раздела подкачки. В большинстве дистрибутивов mkinitrd позволяет работать с tmpfs, примонтированной, как /tmp.

  4. Можно придумать еще множество вариантов применения tmpfs.

Файловая система tmpfs поддерживает три опции монтирования для управления размером:

size задает предельный размер экземпляра tmpfs в байтах (по умолчанию составляет половину размера имеющейся в системе физической памяти — ОЗУ). Создание tmpfs слишком большого размера может приводить к «зависанию» системы, поскольку обработчик OOM не сможет освободить эту память.

nr_blocks задает предельный размер числом блоков PAGE_CACHE_SIZE.

nr_inodes задает максимальное число узлов inode для данного экземпляра (по умолчанию совпадает меньшим из значений половины от числа страниц ОЗУ или на машинах с highmem половины от числа страниц ОЗУ lowmem).

При задании этих параметров можно использовать суффиксы k (kilo), m (mega) и g (giga). Для параметра size можно также использовать суффикс %, который показывает задание размера tmpfs в процентах от физического размера ОЗУ. По умолчанию, если ни один из параметров size, nr_blocks не задан, будет использоваться значение size=50%.
Если nr_blocks=0 (или size=0), число блоков для данного экземпляра не ограничивается; если nr_inodes=0, не ограничивается число узлов inode. В общем случае монтирование с такими опциями нежелательно, поскольку при этом каждый пользователь с правом записи сможет занять всю оперативную память системы, однако такие значения позволяют повысить уровень масштабируемости tmpfs в многопроцессорных машинах, интенсивно использующих файловую систему tmpfs.

Для tmpfs поддерживается опция монтирования mpol, позволяющая использовать политику выделения памяти NUMA для всех файлов данного экземпляра (при включенной опции CONFIG_NUMA). Значение данной опции также можно менять в процессе работы с помощью команды mount -o remount …

mpol=default использовать политику выделения для процессов (см. set_mempolicy(2));

mpol=prefer:Node предпочтительно выделять память из данного узла (Node);

mpol=bind:NodeList выделять память только из узлов списка NodeList;

mpol=interleave предпочтительно выделять память из каждого узла поочередно;

mpol=interleave:NodeList память выделяется из каждого узла NodeList поочередно;

mpol=local предпочительно выделять память из локального узла.

NodeList предсатвляет собой список разделенных запятыми десятичных значений или диапазонов (два десятичных числа, начиная с меньшего, через дефис). Например, mpol=bind:0-3,5,7,9-15.

Заданная при монтировании политика выделения памяти сохраняется для использования при создании файлов. Когда та или иная задача создает файл в tmpfs, политика выделения памяти, заданная при монтировании, применяется с соответствующим списком NodeList (если он задан) и с учетом ограничений набора процессоров (см. Documentation/cgroups/cpusets.txt в дистрибутиве ядра) и флагов, перечисленных ниже. Если в результате список NodeLists становится пустым, используется принятая по умолчанию политика выделения памяти (mpol=default).

Политика распределения памяти NUMA поддерживает ряд дополнительных флагов, используемых вместе с заданным при монтировании режимом. Эти флаги могут быть заданы при монтировании tmpfs путем указания после режима но перед списком NodeList. Полный список флагов можно найти в документе Documentation/vm/numa_memory_policy.txt, где описано также воздействие этих флагов на политику выделения памяти.

=static эквивалентно MPOL_F_STATIC_NODES

=relative эквивалентно MPOL_F_RELATIVE_NODES

Например, mpol=bind=static:NodeList эквивалентно политике выделения MPOL_BIND | MPOL_F_STATIC_NODES.

Отметим, что попытка монтирование tmpfs с опцией mpol будет приводить к отказу, если используемое ядро не поддерживает NUMA, а также в тех случаях, когда в списке присутствует неактивный узел. Если в вашей системе используется tmpfs, но некоторые варианты ядра могут не поддерживать NUMA (например, ядро, используемое при восстановлении системы) или отдельные узлы могут лказываться неактивными, рекомендуется исключить опцию mpol из параметров автоматического монтирования. Вы можете добавить нужную опцию позднее, когда tmpfs уже примонтирована (как MountPoint) с помощью команды mount -o remount,mpol=Policy:NodeList MountPoint.

Для задания изначального корневого каталога можно использовать приведенные ниже опции монтирования:

mode права доступа в восьмеричном формате;

uid идентификатор пользователя;

gid идентификатор группы.

Эти опции не меняются при перемонтировании файловой системы, но исх можно поменять с помощью команд chmod, chown и chgrp на смонтированной файловой системе.

Так, команда mount -t tmpfs -o size=10G,nr_inodes=10k,mode=700 tmpfs /mytmpfs будет создавать экземпляр tmpfs с точкой монтирования /mytmpfs, для которого будет выделено 10 Гбайт RAM/SWAP с 10240 узлами inode, доступный только пользователю root.

Перевод на русский язык

Николай Малых

nmalykh@protokols.ru

Рубрика: RFC | Комментарии к записи Файловая система tmpfs отключены

RFC 5830 GOST 28147-89: Encryption, Decryption, and Message Authentication Code (MAC) Algorithms

Independent Submission                              V. Dolmatov, Ed.
Request for Comments: 5830                           Cryptocom, Ltd.
Category: Informational                                   March 2010
ISSN: 2070-1721

 

GOST 28147-89. Алгоритмы шифрования, дешифрования и MAC

GOST 28147-89: Encryption, Decryption, and Message Authentication Code (MAC) Algorithms

PDF

Аннотация

Этот документ опубликован в качестве источника информации о стандарте Российской Федерации для алгоритмов шифрования, дешифрования и идентификации сообщений (GOST 28147-89), который является одним из российских стандартов для криптографических алгоритмов, называемых алгоритмами GOST. Недавно российские криптоалгоритмы начали использовать в приложениях Internet и этот документ был подготовлен в качестве источника информации для разработчиков и пользователей алгоритмов GOST 28147-89 в плане шифрования, дешифровки и идентификации сообщений.

Статус документа

Этот документ не является спецификацией проекта стандарта Internet и публикуется с информационными целями.

Этот документ подготовлен независимо от остальных документов серии RFC. Редактор документа (RFC Editor) был выбран для публикации документа по его собственному усмотрению и не делает каких-либо заявлений о значимости документа для реализации или развертывания. Документ одобрен для публикации редактором и не претендует на роль какого-либо стандарта Internet (см. параграф 2 документа RFC 5741).

Информацию о текущем состоянии документа, обнаруженных ошибках и способах связи с разработчиками можно найти по ссылке http://www.rfc-editor.org/info/rfc5830.

Авторские права

Авторские права ((c) 2010) принадлежат IETF Trust и лицам, являющимся авторами документа. Все права защищены.

К этому документу применимы права и ограничения, перечисленные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно.

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

1. Введение

1.1. Общие сведения

[GOST28147-89] является алгоритмом унифицированного криптографического преобразования для систем обработки информации разного назначения, определяющим правила шифрования/дешифрования и генерации кода идентификации сообщений (MAC1).

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

2. Применимость

GOST 28147-89 определяет модель шифрования/дешифрования и генерации MAC для заданного сообщения (документа), который предназначен для передачи по незащищенным публичным телекоммуникационным каналам между системами обработки данных разного назначения.

Алгоритм GOST 28147-89 обязателен в Российской Федерации для использования во всех системах обработки данных, предоставляющих публичный сервис.

3. Определения и обозначения

3.1. Определения

Ниже приведены определения используемых в стандарте терминов.

Running key — рабочий ключ2

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

Encryption — шифрование3

Процесс преобразования открытых данных в зашифрованные с помощью шифра.

MAC — код идентификации сообщения4

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

Key — ключ

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

Cryptographic protection — криптографическая защита, криптозащита

Защита данных с помощью их криптографического преобразования.

Cryptographic transformation – криптографическое преобразование

Преобразование данных с использованием шифрования и (или) MAC.

Decryption — дешифровка5

Процесс преобразования защищенных данных в открытые с использованием шифра.

Initialisation vector — вектор инициализации6

Исходные значения открытых параметров алгоритма криптографического преобразования.

Encryption equation — уравнение зашифровки

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

Decryption equation — уравнение расшифровки

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

Cipher — шифр

Набор обратимых преобразований множества возможных открытых данных во множество возможных зашифрованных данных, выполняемых по заданным правилам с применением ключей.

3.2. Обозначения

В этом документе используются следующие обозначения:

(+) побитовое сложение слов одного размера по модулю 2;

[+] сложение 32-битовых векторов по модулю 232.

[+]’ сложение 32-битовых векторов по модулю 232-1.

1..N множество целых чисел от 1 до N, включительно.

4. Общие сведения

Структурная схема алгоритма криптографических преобразований (криптографическая модель7) включает:

  • 256-битовое устройство хранения ключей (KDS8), состоящее из восьми 32-битовых регистров (X0, X1, X2, X3, X4, X5, X6, X7);
  • четыре 32-битовых регистра (N1, N2, N3, N4);
  • два 32-битовых регистра (N5 и N6), содержащих константы9 C1 и C2;
  • два 32-битовых сумматора по модулю 232 (CM1, CM3);
  • 32-битовый сумматор для побитового сложения по модулю 2 (CM2);
  • 32-битовый сумматор по модулю (232-1) (CM4);
  • сумматор по модулю 2 (CM5) без ограничения по разрядности;
  • блок подстановки (K);
  • циклический регистр сдвига на одиннадцать разрядов10 в сторону старшего разряда (R).

Блок подстановки (S-box) K состоит из восьми узлов замены K1, K2, K3, K4, K5, K6, K7, K8 с памятью по 64 бита в каждом. Приходящий в блок подстановки 32-битовый вектор делится на 8 последовательных 4-битовых векторов, каждый из которых преобразуется соответствующим узлом замены в другой 4-битовый вектор. Узел замены представляет собой таблицу из 16 строк по 4 бита. Входной вектор определяет номер строки в таблице, а содержимое этой строки служит выходным вектором. Далее 4-битовые выходные векторы последовательно объединяются в 32-битовый вектор.

Примечание: стандарт не определяет каких-либо блоков подстановки. Некоторые из таких блоков определены в [RFC4357].

При сложении и циклическом сдвиге двоичных векторов старшими считаются разряды с большими номерами.

При записи ключа (W1, W2, …, W256), Wq = 0..1, q = 1..256 в KDS:

  • значение W1 записывается в первый бит регистра X0;
  • значение W2 записывается во второй бит регистра X0;
  • значение W32 записывается в 32-й бит регистра X0;
  • значение W33 записывается в первый бит регистра X1;
  • значение W34 записывается во второй бит регистра X1;
  • значение W64 записывается в 32-й бит регистра X1;
  • значение W65 записывается в первый бит регистр X2;
  • значение W256 записывается в 32-й бит регистра X7.

При перезаписи информации значение p-го бита одного регистра (сумматора) записывается в p-й бит другого регистра (сумматора).

Значения констант C1 и C2, хранящихся в регистрах N5 и N6 приведены в приложении 1.

Ключи, определяющие заполнение KDS и таблиц блока подстановки K, являются секретными элементами и поставляются в установленном порядке.

Заполнение блока подстановки K описано в GOST 28147-89, как долговременный ключевой элемент, который является общим для компьютерной сети. Обычно K используется в качестве параметра алгоритма и некоторые возможные наборы значений K описаны в [RFC4357].

В криптографической модели предполагается 4 режима работы:

  • зашифровка (дешифровка) данных в режиме простой замены (ECB11);
  • зашифровка (дешифровка) данных в режиме гаммирования (CNT12);
  • зашифровка (дешифровка) данных в режиме гаммирования с обратной связью (CFB13);
  • генерация MAC (имитовставки).

В [RFC4357] также описан режим CBC, но он не входит в стандарт. =

5. Режим простой замены

5.1. Зашифровка открытых данных в режиме простой замены

Шифруемые данные делятся на блоки по 64 бита в каждом. Ввод любого двоичного блока Tp = (a1(0), a2(0), … , a31(0), a32(0), b1(0), b2(0), …, b32(0)) в регистры N1 и N2 выполняется таким образом, что значение a1(0) помещается в первый разряд регистра N1, значение a2(0) — во второй разряд N1 и т. д, а значение a32(0) помещается в 32-й разряд регистра N1. Значение b1(0) помещается в первый разряд регистра N2, значение b2(0) — во второй разряд N2, …, значение b32(0) — в 32-й разряд регистра N2.

В результате получается состояние (a32(0), a31(0), …, a2(0), a1(0)) в регистре N1 и состояние (b32(0), b31(0), …, b1(0)) в регистре N2.

В KDS вводятся 256 битов ключа. Содержимое восьми 32-битовых регистров X0, X1, …, X7 будет иметь вид:

X0 = W32, W31, ..., W2, W1
X1 = W64, W63, ..., W34, W33
. . . . . . . . . . . . . . .
X7 = W256, W255, ..., W226, W225

Алгоритм зашифровки 64-битового блока открытых данных в режиме простой подстановки состоит из 32 циклов.

В первом цикле начальное значение регистра N1 складывается по модулю 232 в сумматоре CM1 с содержимым регистра X0 блока хранения ключей. Отметим, что значение регистра N1 при этом остается неизменным.

Результат суммирования преобразуется в блоке подстановки K и полученный вектор помещается в регистр R, где он циклически сдвигает на 11 разрядов в направлении старших битов14. Результат операции сдвига суммируется поразрядно по модуля 2 в сумматоре CM2 с 32-битовым значением регистра N2. Полученные в сумматоре CM2 результат записывается в регистр N1, а прежнее содержимое этого регистра переносится в регистр N2. На этом первый цикл заканчивается.

Последующие циклы выполняются по аналогии с первым. При этом:

  • во втором цикле из KDS считывается15 содержимое регистра X1;
  • в третьем цикле из KDS считывается содержимое регистра X2;
  • в восьмом цикле из KDS считывается содержимое регистра X7.
  • в циклах 9 — 16 и 17 — 24 операции считывания содержимого регистров KDS повторяются в том же порядке:
X0, X1, X2, X3, X4, X5, X6, X7.
  • в последних 8 циклах (25 — 32) содержимое регистров KDS считывается в обратном порядке:

X7, X6, X5, X4, X3, X2, X1, X0.

Таким образом, в 32 циклах зашифровки выполняется следующий порядок выборки содержимого регистров KDS:

X0, X1, X2, X3, X4, X5, X6, X7, X0, X1, X2, X3, X4, X5, X6, X7,
X0, X1, X2, X3, X4, X5, X6, X7, X7, X6, X5, X4, X3, X2, X1, X0

В 32-м цикле результат из сумматора CM2 копируется в регистр N2, а в регистре N1 значение сохраняется.

После выполнения 32-го цикла в регистрах N1 и N2 будет содержаться зашифрованный блок данных, соответствующий блоку открытых данных.

Уравнения для зашифровки в режиме electronic codebook имеют вид:

|a(j) = (a(j-1) [+] X(j-1)(mod 8))*K*R (+) b (j-1)
|b(j) = a(j-1)

при j = 1..24;

|a(j) = (a(j-1) [+] X(32-j))*K*R (+) b(j-1)
|b(j) = a(j-1)

при j = 25..31; a32 = a31;

b(32) = (a(31) [+] X0)*K*R (+) b(31) 

при j=32.

Где:

a(0) = (a32(0), a31(0), …, a1(0)) — начальные значения регистра N1 перед первым циклом зашифровки;

b(0) = (b32(0), b31(0), …, b1(0)) — начальные значения регистра N2 перед первым циклом зашифровки;

a(j) = (a32(j), a31(j), …, a1(j)) — содержимое регистра N1 после j-го цикла зашифровки (j = 1..32);

b(j) = (b32(j), b31(j), …, b1(j)) — содержимое регистра N2 после j-го цикла зашифровки (j = 1..32).

R — операция циклического сдвига на 11 разрядов в направлении старших битов:

R(r32, r31, r30, r29, r28, r27, r26, r25, r24, r23, r22, r21, r20, ..., r2, r1) = 
(r21, r20, ..., r2, r1, r32, r31, r30, r29, r28, r27, r26, r25, r24, r23, r22)

64-битовый блок зашифрованных данных Tc считывается из регистров N1 и N2 в следующем порядке:

1-й, 2-й, …, 32-й бит регистра N1, затем 1-й, 2-й, …, 32-й бит регистра N2

Tc = a1(32), a2(32), ..., a32(32), b1(32), b2(32), ..., b32(32)).

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

5.2. Дешифровка в режиме простой подстановки

Ключ, который использовался при зашифровке (256 битов) загружается в KDS, зашифрованные данные делятся на блоки по 64 бита. Ввод любого двоичного блока

Tc = (a1(32), a2(32), ..., a32(32), b1(32), b2(32), ..., b32(32))

в регистры N1 и N2 выполняется следующим образом:

  • значение a1(32) записывается в первый бит регистра N1;
  • значение a2(32) записывается во второй бит регистра N1;
  • значение a32(32) записывается в 32-й бит регистра N1;
  • значение b1(32) записывается в первый бит регистра N2;
  • значение b32(32) записывается в 32-й бит регистра N2.

Процедура дешифровки использует тот же алгоритм, который применялся при зашифровке открытых данных с одним исключением — содержимое регистров X0, X1, …, X7 считывается из KDS для дешифровки в следующем порядке:

X0,X1,X2,X3,X4,X5,X6,X7, X7,X6,X5,X4,X3,X2,X1,X0,
X7,X6,X5,X4,X3,X2,X1,X0, X7,X6,X5,X4,X3,X2,X1,X0.

Уравнение дешифровки имеет вид:

|a(32-j) = (a(32-j+1) [+] X(j-1))*K*R (+) b(32-j+1)
|b(32-1) = a(32-j+1)

при j = 1..8;

|a(32-j) = (a(32-j+1) [+] X(j-1)(mod 8))*K*R (+) b(32-j+1)
|b(32-1) = a(32-j+1)

при j = 9..31;

|a(0) = a(1)
|b(0) = (a(1) [+] X0)*K*R (+) b1

при j=32.

Содержимое регистров N1 и N2 после 32 циклов работы составляет блок расшифрованных (открытых) данных.

Tp = (a1(0), a2(0), ... , a32(0), b1(0), b2(0), ..., b32(0))

соответствующий зашифрованному блоку:

  • значение a1(0) блока Tp соответствует первому биту регистра N1;
  • значение a2(0) соответствует второму биту регистра N1;
  • значение b1(0) соответствует первому биту регистра N2;
  • значение b2(0) соответствует второму биту регистра N2;
  • значение b32(0) соответствует 32-му биту регистра N2.

Оставшиеся блоки расшифровываются аналогично.

Алгоритм зашифровки в режиме простой замены 64-битового блока Tp обозначается A, т. е.:

A(Tp) = A(a(0), b(0)) = (a(32), b(32)) = Tc.

6. Режим гаммирования

6.1. Зашифровка открытых данных в режиме гаммирования

Открытые данные, разбитые на блоки по 64 бита Tp(1), Tp(2), …, Tp(M-1), Tp(M), зашифровываются в режиме гаммирования путем поразрядного суммирования по модулю 2 в сумматоре CM5 рабочим ключом (гаммой шифра) Gc, который генерируется блоками по 64 бита:

Gc = (Gc(1), Gc(2), ..., Gc(M-1), Gc(M))

где M определяется размером шифруемых данных.

Gc(i) — это i-й блок данных размером 64 бита, где i=1..M — число двоичных разрядов в блоке Tp(M) — может быть меньше 64 (в этом случае неиспользованная для шифрования часть рабочего ключа Gc(M) отбрасывается).

256 битов ключа помещаются в KDS. В регистры N1 и N2 помещаются 64-битовая двоичная последовательность (вектор инициализации или синхропосылка) S = (S1, S2, …, S64), которая служит исходными данными для генерации M блоков рабочего ключа. Вектор инициализации помещается в регистры N1 и N2 следующим образом:

  • значение S1 записывается в первый бит регистра N1;
  • значение S2 записывается во второй бит регистра N1;
  • значение S32 записывается в 32-й бит регистра N1;
  • значение S33 записывается в первый бит регистра N2;
  • значение S34 записывается во второй бит регистра N2;
  • значение S64 записывается в 32-й бит регистра N2.

Исходное содержимое регистров N1 и N2 (вектор инициализации S) шифруется в режиме простой подстановки в соответствии с требованиями параграфа 5.1. Результат шифрования A(S) = (Y0, Z0) записывается в 32-битовые регистры N3 и N4 (содержимое N1 записывается в N3, содержимое N2 — в N4).

Содержимое регистра N4 суммируется по модулю (232-1) в сумматоре CM4 с 32-битовой константой C1 из регистра N6, а результат записывается в регистр N4. Содержимое регистра N3 складывается по модулю 232 в сумматоре CM3 с 32-битовой константой C2 из регистра N5, а результат записывается в регистр N3.

Содержимое регистра N3 копируется в N1, а содержимое N4 — в N2, значения регистров N3 и N4 при этом не меняются.

Содержимое регистров N1 и N2 шифруется методом простой подстановки в соответствии с требованиями параграфа 5.1. Полученное в результате содержимое регистров N1 и N2 образует первый 64-битовый блок рабочего ключа Gc(1), который поразрядно суммируется по модулю 2 в сумматоре CM5 с первым 64-битовым блоком открытых данных:

Tp(1) = (t1(1), t2(1), ..., t63(1), t64(1)).

Результат суммирования дает 64-битовый блок зашифрованных данных:

Tc(1) = (tau1(1), tau2(1), ..., tau63(1), tau64(1)).

Значение tau1(1) блока Tc(1) является результатом сложения по модулю 2 в сумматоре CM5 значения t1(1) из блока Tp(1) со значением первого бита регистра N1, tau2(1) блока Tc(1) — результатом сложения по модулю 2 в сумматоре CM5 значения t2(1) из блока Tp(1) со значением второго бита N1 и т. д., значение tau64(1) блока Tc(1) является результатом сложения по модулю 2 в сумматоре CM5 значения t64(1) из блока Tp(1) со значением 32-го бита N2.

Для получения следующего 64-битового блока рабочего ключа Gc(2) содержимое регистра N4 складывается по модулю (232-1) в сумматоре CM4 с константой C1 из регистра N6; содержимое регистра N3 складывается по модулю 232 в сумматоре CM3 с константой C2 из регистра N5. Новое значение регистра N3 копируется в N1, новое значение N4 — в N216. Значения регистров N3 и N4 при этом сохраняются.

Содержимое регистров N1 и N2 шифруется методом простой подстановки в соответствии с требованиями параграфа 5.1. Полученное в результате зашифрованное содержимое регистров N1 и N2 образует первый 64-битовый блок рабочего ключа Gc(2), который поразрядно суммируется по модулю 2 в сумматоре CM5 с первым 64-битовым блоком открытых данных Tp(2). Генерация остальных блоков рабочего ключа Gc(3), Gc(4), …, Gc(M) и зашифровка открытых блоков Tp(3), Tp(4), …, Tp(M) выполняется аналогично. Если размер последнего (M-го) блока открытых данных менее 64 битов, из последнего блока рабочего ключа используется только соответствующее количество битов, а остальные биты отбрасываются17.

Вектор инициализации S и блоки зашифрованных данных Tc(1), Tc(2), …, Tc(M) передаются в канал связи или память ЭВМ.

Уравнение зашифровки имеет вид:

Tc(i) = A(Y[i-1] [+] C2, Z[i-1]) [+]' C1) (+) Tp(i) = Gc(i) (+) Tp(i)
i=1..M

где

Y[i] — содержимое регистра N3 после зашифровки i-го блока открытых данных Tp(i);

Z(i) — содержимое регистра N4 после зашифровки i-го блока открытых данных Tp(i);

(Y[0], Z[0]) = A(S).

6.2. Расшифровка данных с режиме гаммирования

В KDS вводятся 256 битов ключа, использованного для зашифровки открытых данных Tp(1), Tp(2), …, Tp(M). Значение вектора инициализации S помещается в регистры N1 и N2 и генерируются M блоков рабочего ключа Gc(1), Gc(2), …, Gc(M), как описано в параграфе 6.1. Блоки зашифрованных данных Tc(1), Tc(2), …, Tc(M) поразрядно складываются по модулю 2 в сумматоре CM5 с блоками рабочего ключа, что приводит к восстановлению блоков открытых данных Tp(1), Tp(2), …, Tp(M). Блок Tp(M) может иметь размер менее 64 битов.

Уравнение расшифровки имеет вид:

Tp(i) = A (Y[i-1] [+] C2, Z[i-1] [+]' C1) (+) Tc(i) = Gc(i) (+) Tc(i)
i = 1..M

7. Режим гаммирования с обратной связью

7.1. Зашифровка открытых данных в режиме гаммирования с обратной связью

Открытые данные разбиваются на блоки размером 64 бита Tp(1), Tp(2), …, Tp(M) и шифруются в режиме гаммирования с обратной связью путем поразрядного сложения по модулю в сумматоре CM5 с рабочим ключом (гаммой) Gc, генерируемым в форме 64-битовых блоков. Т. е., Gc(i)=(Gc(1), Gc(2), …, Gc(M)), где M определяется размером открытых данных, Gc(i) — i-й блок ключа размером 64 бита, i=1..M. Размер блока Tp(M) может быть менее 64 битов.

В KDS вводятся 256 битов ключа. 64-битовый вектор инициализации (синхропосылка) S = (S1, S2, …, S64) помещается в регистры N1 и N2, как описано в параграфе 6.1.

Исходное содержимое регистров N1 и N2 зашифровывается в режиме простой подстановки в соответствии с требованиями параграфа 5.118. Зашифрованное содержимое регистров N1 и N2 является первым 64-битовым блоком рабочего ключа Gc(1)=A(S), который складывается по модулю 2 в сумматоре CM5 с первым 64-битовым блоком открытых данных Tp(1) = (t1(1), t2(1), …, t64(1))19.

В результате получается 64-битовый блок зашифрованных данных

Tc(1) = (tau1(1), tau2(1), ..., tau64(1)).

Блок зашифрованных данных Tc(1) одновременно используется в качестве исходных значений регистров N1 и N2 для генерации второго блока рабочего ключа Gc(2) и по цепи обратной связи этот блок записывается в регистры следующим образом:

  • значение tau1(1) записывается в первый бит регистра N1;
  • значение tau2(1) записывается во второй бит регистра N1;
  • значение tau32(1) записывается в 32-й бит регистра N1;
  • значение tau33(1) записывается в первый бит регистра N2;
  • значение tau34(1) записывается во второй бит регистра N2;
  • значение tau64(1) записывается в 32-й бит регистра N2.

Содержимое регистров N1 и N2 зашифровывается в режиме простой подстановки в соответствии с требованиями параграфа 5.17. Зашифрованное содержимое регистров N1 и N2 образует второй 64-битовый блок рабочего ключа Gc(2), который складывается по модулю 2 в сумматоре CM5 со вторым блоком открытых данных Tp(2).

Генерация последующих блоков рабочего ключа Gc(i) и шифрование соответствующих блоков открытых данных Tp(i) (i = 3..M) выполняется аналогично. Если размер последнего (M-го) блока открытых данных меньше 64 битов, используются только соответствующие биты M-го блока рабочего ключа Gc(M), а оставшиеся биты отбрасываются.

Уравнение шифрования в режиме гаммирования с обратной связью имеет вид:

|Tc(1) = A(S) (+) Tp(1) = Gc(1) (+) Tp(1)
|Tc(i) = A(Tc(i-1)) (+) Tp(i) = Gc(i) + Tp(i), i = 2..M.

Вектор инициализации (синхропосылка) S и блоки зашифрованных данных Tc(1), Tc(2), …, Tc(M) предаются в канал связи или память ЭВМ.

7.2. Расшифровка в режиме гаммирования с обратной связью

В KDS помещаются 256 битов ключа, использованного для зашифровки блока открытых данных Tp(1), Tp(2), …, Tp(M). Вектор инициализации (синхропосылка) S в регистры N1 и N2, как описано в параграфе 6.1. Исходное содержимое регистров N1 и N2 (вектор инициализации S) шифруется в режиме простой подстановки в соответствии с требованиями параграфа 5.17. Зашифрованное содержимое регистров N1, N2 образует первый блок рабочего ключа Gc(1) = A(S), который суммируется поразрядно по модулю 2 в сумматоре CM5 с блоком зашифрованных данных Tc(1). Результатом этой операции является первый блок открытых (расшифрованных) данных Tp(1).

Блок зашифрованных данных Tc(1) служит исходным содержимым регистров N1, N2 при генерации второго блока рабочего ключаGc(2). Блок Tc(1) записывается в регистры N1 и N2 в соответствии с требованиями параграфа 6.1. Содержимое регистров N1 и N2 шифруется в режиме простой подстановки в соответствии с требованиями параграфа 5.1 и полученный а результате блок Gc(2) поразрядно суммируется по модулю 2 в сумматоре CM5 со вторым блоком зашифрованных данных Tc(2). В результате получается второй блок расшифрованных данных Tc(2).

Аналогично, блоки зашифрованных данных Tc(2), Tc(3), …, Tc(M-1) поочередно записываются в регистры N1, N2, а содержимое этих регистров шифруется в режиме простой подстановки для генерации блоков рабочего ключа Gc(3), Gc(4), …, Gc(M). Эти блоки поразрядно суммируются по модулю 2 в сумматоре CM5 с блоками зашифрованных данных Tc(3), Tc(4), …, Tc(M), в результате чего получаются блоки открытых (расшифрованных) данных Tp(3), Tp(4), …, Tp(M). Размер последнего блока открытых данных Tp(M) может быть менее 64 битов.

Уравнение расшифровки в режиме гаммирования с обратной связью имеет вид:

Tp(1) = A(S) (+) Tc(1) = Gc(1) (+) Tc(1)
Tp(1) = A(Tc(i-1)) (+) Tc(i) = Gc(i) (+) Tc(i), i=2..M

8. Режим генерации MAC

Для защиты от фальсификации открытых данных, представляющих собой M блоков размером 64 бита Tp(1), Tp(2), …, Tp(M), где M >= 2 генерируется дополнительный блок размером l (имитовставка или MAC — I(l)). Процесс генерации MAC в режимах зашифровки и расшифровки совпадает.

Первый блок открытых данных

Tp(1) = (t1(1), t1(2), ..., t64(1))
= (a1(1)[0], a2(1)[0], ..., a32(1)[0], b1(1)[0], b2(1)[0], ..., b32(1)[0])

записывается в регистры N1 и N2 следующим образом:

  • значение t1(1) = a1(1)[0] записывается в первый бит регистра N1;
  • значение t2(1) = a2(1)[0] записывается во второй бит регистра N1;
  • значение t32(1) = a32(1)[0] записывается в 32-й бит регистра N1;
  • значение t33(1) = b1(1)[0] записывается в первый бит регистра N2;
  • значение t64(1) = b32(1)[0] записывается в 32-й бит регистра N2.

Содержимое регистров N1 и N2 преобразуется в соответствии с первыми 16 циклами алгоритма шифрования в режиме простой подстановки (параграф 5.1). В KDS при этом находится тот же ключ, который используется для зашифровки блоков открытых данных Tp(1), Tp(2), …, Tp(M) в соответствующие блоки закрытых данных Tc(1), Tc(2), …, Tc(M).

Полученное после 16 циклов содержимое регистров N1 и N2, имеющее вид (a1(1)[16], a2(1)[16], …, a32(1)[16], b1(1)[16], b2(1)[16], …, b32(1)[16]), суммируется по модулю 2 в сумматоре CM5 со вторым блоком открытых данных Tp(2) = (t1(2), t2(2), …, t64(2)).

Результат суммирования

(a1(1)[16](+)t1(2), a2(1)[16](+)t2(2), ..., a32(1)[16](+)t32(2),
b1(1)[16](+)t33(2), b2(1)[16](+)t34(2), ..., b32(1)[16](+)t64(2))
=
(a1(2)[0], a2(2)[0] ..., a32(2)[0], b1(2)[0], b2(2)[0], ..., b32(2)[0])

записывается в регистры N1, N2 и преобразуется в соответствии с первыми 16 циклами процесса шифрования в режиме простой подстановки.

Полученное в результате содержимое регистров N1 и N2 суммируется по модулю 2 в сумматоре CM5 с третьим блоком Tp(3) и т. д. Последний блок Tp(M) = (t1(M), t2(M), …, t64(M)) при необходимости дополняется нулями до размера 64 бита и суммируется по модулю 2 в сумматоре CM5 с содержимым регистров N1 и N2

(a1(M-1)[16], a2(M-1)[16], ..., a32(M-1)[16], b1(M-1)[16], b2(M-1)[16], ..., b32(M-1)[16]).

Результат суммирования

(a1(M-1)[16](+)t1(M), a2(M-1)[16](+)t2(M), ..., a32(M-1)[16](+)
t32(M), b1(M-1)[16](+)t33(M), b2(M-1)[16](+)t34(M), ..., b32(M-1)[16](+)t64(M))
=
(a1(M)[0], a2(M)[0] ..., a32(M)[0], b1(M)[0], b2(M)[0], ..., b32(M)[0])

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

(a1(M)[16], a2(M)[16] ..., a32(M)[16], b1(M)[16], b2(M)[16], ..., b32(M)[16])

выбирается отрезок размером l-битов — имитовставка (MAC) I(l):

I(l) = [a(32-l+1)(M)[16], a(32-l+2)(M)[16], ..., a32(M)[16]].

MAC I(l) передается по каналу связи или в память ЭВМ в конце зашифрованных данных. Т. е., результат имеет вид

Tc(1), Tc(2), ..., Tc(M), I(l).

Полученные зашифрованные данные Tc(1), Tc(2), …, Tc(M) расшифровываются, а из полученных при этом блоков открытых данных Tp(1), Tp(2), …, Tp(M) генерируется MAC I'(l), как описано выше, и результат сравнивается с полученным (из канала передачи или памяти ЭВМ) вместе с зашифрованными данными значением MAC I(l). Если значения MAC не совпадают, полученные в результате расшифровки открытые данные Tp(1), Tp(2), …, Tp(M) считаются фальсифицированы.

Значения MAC I(l), (I'(l)) могут генерироваться перед зашифровкой (после расшифровки) всего сообщения или параллельно с процессом зашифровки (расшифровки) блоков данных. Первые блоки открытых данных, используемые для генерации MAC, могут содержать служебную информацию (адресную часть, временную метку, вектор инициализации и т. п.) и не зашифровываться.

Значение параметра l (размер MAC) определяется действующими криптографическими требованиями с учетом того, что вероятность навязывания ложных данных равна 2-l.

9. Вопросы безопасности

Документ целиком посвящен вопросам безопасности.

10. Нормативные документы

[GOST28147-89] «Система обработки информации. Защита криптографическая. Алгоритм криптографического преобразования», ГОСТ 28147-89, Государственный стандарт Союза ССР, Издательство стандартов, 1989.

[RFC4357] Popov, V., Kurepkin, I., and S. Leontiev, «Additional Cryptographic Algorithms for Use with GOST 28147-89, GOST R 34.10-94, GOST R 34.10-2001, and GOST R 34.11-94 Algorithms», RFC 4357, January 2006.

Приложение A. Значения констант C1 и C2

Константа C1 имеет вид:

Разряд N6 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Значение бита 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0

Константа C2 имеет вид:

Разряд N5 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Значение бита 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1

Приложение B. Разработчики документа

Dmitry Kabelev

Cryptocom, Ltd.

14 Kedrova St., Bldg. 2

Moscow, 117218

Russian Federation

EMail: kdb@cryptocom.ru

Igor Ustinov

Cryptocom, Ltd.

14 Kedrova St., Bldg. 2

Moscow, 117218

Russian Federation

EMail: igus@cryptocom.ru

Irene Emelianova

Cryptocom Ltd.

14 Kedrova St., Bldg. 2

Moscow, 117218

Russian Federation

EMail: irene@cryptocom.ru

Адрес автора

Vasily Dolmatov, редактор

Cryptocom, Ltd.

14 Kedrova St., Bldg. 2

Moscow, 117218

Russian Federation

EMail: dol@cryptocom.ru


Перевод на русский язык

Николай Малых

nmalykh@protokols.ru

1Message authentication code.

2В оригинальном стандарте используется термин «гамма шифра». Прим. перев.

3В оригинальном стандарте используется термин «зашифрование». Прим. перев.

4В оригинальном стандарте используется термин «имитовставка». Прим. перев.

5В оригинальном стандарте используется термин «расшифрование данных». Прим. перев.

6В оригинальном стандарте используется термин «синхропосылка». Прим. перев.

7В оригинальном стандарте используется термин «криптосхема». Прим. перев.

8Key data store. В оригинальном стандарте используется сокращение «КЗУ» — ключевое запоминающее устройство. Прим. перев.

9В оригинальном стандарте используется термин «постоянные запоминания». Прим. перев.

10В оригинальном стандарте не вполне корректно сказано «шагов», а не «разрядов». Прим. перев.

11Electronic codebook.

12Counter mode.

13Cipher feedback mode.

14Влево в привычной терминологии. Прим. перев.

15Для суммирования. Прим. перев.

16Здесь, равно как и в оригинальном стандарте, опущены операции копирования результатов суммирования в регистры N3 и N4, явно упомянутые для генерации первого блока рабочего ключа. Прим. перев.

17Ни здесь, ни в оригинальном стандарте явно не сказано, что следует брать из М-го блока рабочего ключа начальные (старшие) биты. Прим. перев.

18В исходном документе дана ссылка на параграф 6.1, однако в оригинальном стандарте ссылка дается на пункт, соответствующий параграфу 5.1 данного документа. Прим. перев.

19В исходном RFC 5830 это предложение отличается от оригинального стандарта и имеет вид: «Если зашифрованное содержимое регисторов N1 и N2 является первым 64-битовым блоком рабочего ключа Gc(1)=A(S), этот блок складывается по модулю 2 с первым 64-битовым блоком открытых данных Tp(1) = (t1(1), t2(1), …, t64(1))». Поскольку речь идет о начале процесса зашифровки, в соответствии с предшествующим текстом описания этот блок может быть только первым и в переводе RFC был сохранен текст, более точно соответствующий оригинальному стандарту. Прим. перев.

Рубрика: RFC | Оставить комментарий

RFC 5828 Generalized Multiprotocol Label Switching (GMPLS) Ethernet Label Switching Architecture and Framework

Internet Engineering Task Force (IETF)                      D. Fedyk
Request for Comments: 5828                            Alcatel-Lucent
Category: Informational                                    L. Berger
ISSN: 2070-1721                                                 LabN
                                                        L. Andersson
                                                            Ericsson
                                                          March 2010

 

Архитектура и схема обобщенной коммутации по меткам для Ethernet

Generalized Multiprotocol Label Switching (GMPLS) Ethernet Label Switching Architecture and Framework

PDF

Аннотация

В настоящее время выполняется множество работ по расширению возможностей коммутаторов Ethernet и повышению эффективности пересылки кадров Ethernet. В результате таких работ сфера применения Ethernet расширилась до транспортных сетей, в которых традиционно использовались такие технологии, как SONET1/SDH2, TDM3 и ATM4. В этом документе рассматривается архитектура и схема обобщенного уровня управления для Ethernet в такой «транспортной сети». Спецификации GMPLS5 для подобных технологий уже существуют. В этом документе рассмотрены некоторые расширения, которые потребовались на управляющем уровне GMPLS, а также схема таких расширений.

Статус документа

Этот документ не является спецификацией проекта стандарта Internet и публикуется с информационными целями.

Документ подготовлен рабочей группой Internet Engineering и содержит согласованный взгляд сообщества IETF. Документ обсуждался публично и одобрен для публикации IESG6. Не все документы, одобренные IESG, претендуют на статус стандартов Internet (см. раздел 2 документа RFC 5741).

Информацию о текущем состоянии данного документа, обнаруженных ошибках и способах обратной связи можно найти по ссылке http://www.rfc-editor.org/info/rfc5828.

Авторские права

Авторские права ((c) 2010) принадлежат IETF Trust и лицам, являющимся авторами документа. Все права защищены.

К этому документу применимы права и ограничения, перечисленные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включенные в этот документ, распространяются в соответствии с упрощенной лицензией BSD, как указано в параграфе 4.e документа Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

1. Введение

В настоящее время выполняется множество работ по расширению возможностей коммутаторов Ethernet и повышению эффективности пересылки кадров Ethernet. В результате таких работ сфера применения Ethernet расширилась до транспортных сетей, в которых прежде традиционно использовались такие технологии, как SONET/SDH, TDM и ATM. Развитие технологии Ethernet в направлении магистральных сетей идет очень активно и продолжается до сих пор.

Многие организации активно работают в сфере расширения технологии Ethernet для ее использования в магистральных сетях. Эта активность сосредоточена в рабочих группах IEEE7 802.1, сектора стандартизации телекоммуникаций ITU-T8 и MEF9. Усилия этих групп сфокусированы на пересылке Ethernet, расширении уровня управления Ethernet и протокола Spanning Tree, но не явно маршрутизируемого уровня управления, основанного на ограничениях.

В контексте уровня пересылки определяются или будут определены расширения для поддержки различных моделей транспортной пересылки Ethernet, режимов защиты и сервисных интерфейсов. Примерами таких расширений могут служить [802.1ah], [802.1Qay], [G.8011] и [MEF.6]. Эти расширения повышают гибкость уровня пересылки Ethernet, а в некоторых случаях позволяют отказаться от пересылки на основе модели «остовного дерева10». Например, в случае [802.1ah] повышение уровня гибкости пересылки обеспечивается путем добавления «адресного пространства провайдера». [802.1Qay] поддерживает использование систем обеспечения и протоколов сетевого управления, которые явно задают пути трафика.

В этом документе дается схема коммутации меток Ethernet — GELS11. Для поддержки разных моделей GELS явно требуется более одного типа коммутации и потребуется расширение процедур GMPLS в зависимости от типа коммутации. Эти вопросы будут рассматриваться в отдельных документах, связанных с конкретными технологиями.

В модели «провайдерского моста» (provider bridge), разработанной в рамках проекта IEEE 802.1ad и внесенной в стандарт IEEE 802.1Q [802.1Q], добавляется идентификатор виртуальной ЛВС (VLAN12) — VID. Этот VID называют сервисным VID (S-VID13) и он передается в специальном теге S-TAG14. В модели PBB15 [802.1ah] идентификатор опорной сети B-VID16 и заголовок B-MAC с тегом экземпляра сервиса (I-TAG) инкапсулируются в пользовательский или служебный кадр Ethernet.

В стандарте IEEE 802.1Q термины PBB и PBBN17 используются в контексте упомянутых расширений.

Пример защитного расширения Ethernet можно найти в [G.8031]. Эксплуатация, администрирование и обслуживание Ethernet (OAM18) являются другой важной сферой, которая должна быть расширена для обеспечения провайдерских услуг на основе Ethernet. Связанные с этим расширения можно найти в [802.1ag] и [Y.1731].

Модель сервиса на базе Ethernet будет определяться в контексте MEF и ITU-T. Документы [MEF.6] и [G.8011] обеспечивают основу для определения сетеориентированных характеристик сервиса Ethernet в транспортных сетях. В этих документах рассматриваются общие характеристики соединений Ethernet, интерaейсы Ethernet между пользователем и сетью (UNI19), а также межсетевые интерфейсы Ethernet (NNI20). [G.8011.1] определяет сервис «частных линий Ethernet» (EPL21), а [G.8011.2] — сервис «виртуальных частных линий Ethernet» (EVPL22). В [MEF.6] рассматриваются оба типа сервиса. Эти работы согласуются с типами коммутации Ethernet, определенными в [802.1ah].

Расширения Ethernet для уровней пересылки и управления позволяют отключить стандартный протокол STP23, но не определяют явно маршрутизируемого, основанного на ограничениях24 уровня управления. Например, [802.1Qay] является исправленным вариантом стандарта IEEE 802.1Q, который явно разрешает построение путей пересылки трафика Ethernet.

Работа IETF GMPLS обеспечивает общий уровень управления для различных технологий канального уровня в сетях провайдеров Internet и телекоммуникационных операторов. Архитектура GMPLS описана в RFC 3945 [RFC3945]. Спецификации протоколов GMPLS могут использоваться для управления технологиями «транспортных сетей» (например, оптических и TDM-сетей). GMPLS можно использовать также для коммутации пакетов и блоков данных канального уровня (кадров, ячеек).

В этом документе приведена схема использования GMPLS для управления «транспортными» путями коммутации по меткам Ethernet (Eth-LSP25). «Транспорт» Ethernet вносит дополнительные ограничения, которые требуется отличать от ограничений в ранее специфицированных для GMPLS технологиях. Требуются новые расширения для уровня управления GMPLS и в этом документе описана основа для таких расширений. Все расширения для поддержки Eth-LSP будут строиться на базе архитектуры GMPLS и соответствующих спецификаций.

В этом документе вводится и разъясняется применение уровня управления GMPLS для транспорта Ethernet и концепция Eth-LSP. Аспекты уровня данных Eth-LSP выходят за пределы данного документа и работы IETF.

Задачей этого документа является определение согласованного использования с возможно большим числом протоколов GMPLS. Например, использование уровня управления IP обеспечивает возможность применения существующих методов сигнализации, маршрутизации, протоколов управления каналами (LMP26) и расчета путей. Протоколы GMPLS поддерживают как иерархические, так и непрерывные (contiguous) LSP. Механизмы протоколов GMPLS поддерживают также множество «опорных точек» (network reference point) от UNI к NNI. Дополнения к существующим возможностям GMPLS будут вноситься только для аккомодации к уникальным особенностям транспорта Ethernet.

1.1. Терминология

1.1.1. Концепции

Ниже приведены определения основных терминов Ethernet и GMPLS.

Asymmetric Bandwidth — асимметричная полоса

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

Bidirectional congruent LSP — двухсторонний симметричный путь

Этот термин используется для обозначения свойства двухсторонних LSP, которые используют одни и те же узлы, порты и каналы для обоих направлений. Уровни данных Ethernet обычно используют симметричные пути (иногда их называют «конгруэнтными обратным»).

Contiguous Eth-LSP — непрерывный путь Eth-LSP

Непрерывный путь Eth-LSP представляет собой сквозной Eth-LSP, образованный из множества Eth-LSP, каждый из которых работает внутри VLAN и однозначно отображается на границах VLAN. «Сшитые» LSP формируют непрерывные LSP.

Eth-LSP

Путь Ethernet с коммутацией по меткам, который может контролироваться посредством GMPLS.

Hierarchical Eth-LSP — иерархический путь Eth-LSP

Иерархические пути Eth-LSP создают иерархию Eth-LSP.

In-band GMPLS signaling — сигнализация GMPLS в основной полосе

Сигнализация GMPLS в основной полосе основана на управляющих сообщениях IP, которые передаются через каналы Ethernet путем инкапсуляции в заголовок single-hop Ethernet. Логические каналы, которые используют выделенные VID на одном физическом канале, будут рассматриваться, как сигнализация в основной полосе.

Out-of-band GMPLS signaling — сигнализация GMPLS по отдельному каналу

Сигнализация GMPLS по отдельному каналу основана на управляющих сообщениях IP, передаваемых между коммутаторами Ethernet через каналы, которые отличаются от используемых уровнем данных Ethernet. Для сигнализации по отдельному каналу обычно используется скорость, отличная от скорости для уровня данных.

Point-to-point (P2P) Traffic Engineering (TE) service instance — экземпляр сервиса TE между парой точек

Экземпляр сервиса P2P TE включает один двухсторонний или два односторонних P2P Eth-LSP.

Point-to-multipoint (P2MP) Traffic Engineering (TE) service instance — экземпляр сервиса TE между точкой и множеством точек

Экземпляр сервиса TE, поддерживаемый набором LSP, который представляет собой один «многоготочечный» путь P2MP LSP от корня к n ветвей, плюс двухсторонний симметричный P2P LSP от каждой ветви к корню.

Shared forwarding- совместная пересылка

Свойство пути передачи данных, позволяющее одну запись таблицы пересылки (VID + MAC-адрес получателя) использовать для кадров из множества источников (MAC-адреса получателей). Совместная пересылка не меняет поведения уровня данных. Такая пересылка просто экономит пространство базы данных FDB27. Совместная пересылка обеспечивает похожие преимущества для слияния на уровне данных. Однако при совместной пересылке пакеты данных Ethernet не меняются. При совместной пересылке выделенные состояния управляющего уровня для всех Eth-LSP обслуживаются независимо от записей совместной пересылки.

1.1.2. Используемые сокращения

Ниже перечислены сокращения, используемые в этом документе.

CCM Continuity Check Message – сообщение для проверки непрерывности.

CFM Connectivity Fault Management — контроль нарушений связности.

DMAC Destination MAC Address — MAC-адрес получателя.

Eth-LSP Ethernet Label Switched Path — путь Ethernet с коммутацией по меткам.

I-SID Backbone Service Identifier carried in the I-TAG — идентификатор магистрального сервиса в I-TAG.

I-TAG Тег экземпляра магистрального сервиса, определенный в стандарте IEEE 802.1ah [802.1ah].

LMP Link Management Protocol — протокол управления каналом.

MAC Media Access Control — управление доступом к среде.

MP2MP Multipoint to multipoint — множество с множеством.

NMS Network Management System — система управления сетью.

OAM Operations, Administration, and Maintenance — эксплуатация, администрирование, обслуживание.

PBB Provider Backbone Bridges [802.1ah] — мосты опорной сети провайдера.

PBB-TE Provider Backbone Bridges Traffic Engineering [802.1Qay] — построение трафика мостов опорной сети.

P2P Point to Point — «точка-точка».

P2MP Point to Multipoint — «точка-многоточка».

QoS Quality of Service — качество обслуживания.

SMAC Source MAC Address — MAC-адрес отправителя.

S-TAG Тег сервиса, определенный в стандарте IEEE 802.1 [802.1Q].

TE Traffic Engineering — построение трафика.

TAG сокращенное обозначение заголовка TAG.

TAG Header Заголовок TAG — расширение кадра Ethernet для передачи уровня приоритета и других данных.

TSpec Traffic specification — спецификация трафика.

VID VLAN Identifier — идентификатор ВЛВС.

VLAN Virtual LAN — виртуальная ЛВС (ВЛВС).

2. Основные принципы

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

Представленный в этом параграфе материал основан на завершенных и продолжающихся работах в рамках IEEE 802.1, ITU-T, MEF. В этом параграфе приводится краткий обзор работ, но он не может служить заменой первоисточникам.

2.1. Коммутация Ethernet

В терминах коммутации Ethernet мост28 отвечает за пересылку и репликацию кадров. Мосты пересылают кадры на основе значений полей заголовков Ethernet — идентификаторов VLAN (VID) и MAC-адресов получателей (DMAC). В PBB [802.1ah] также определен тег экземпляра сервиса (I-TAG). Во всех расширениях Ethernet, уже упомянутых во введении, множество функций пересылки или сервисных интерфейсов определяется с использованием комбинации VID, DMAC и I-TAG. В документе PBB [802.1ah] дан анализ различных типов сервиса коммутации Ethernet, проиллюстрированный на рисунке 1.

               Типы сетевого сервиса PBB
                 _,,-'    |    '--.._
           _,.-''         |          `'--.._
     _,.--'               |                 `'--..
По портам              S-теги                 I-теги
                      _,-     -.
                   _.'          `.
                _,'               `.
         один к одному          групповой
                                _.-   =.
                            _.-'        ``-.._
                        _.-'                 `-..
                множество в один      один на множество
                                                 |
                                                 |
                                                 |
                                            прозрачный

Рисунок 1: Типы коммутируемого сервиса Ethernet

Типы коммутации определены в п. 25 стандарта [802.1ah]. Хотя это не описано явно в [802.1ah], типы сервиса Ethernet, определенные в контексте [MEF.6] и [G.8011], также относятся к типам сервиса, представленным на рисунке 1 (за исключением определенного недавно типа I-tagged).

В [802.1ah] определен новый тип сервиса I-tagged, но не определены специально типы сервиса Ethernet, которые определены в контексте [MEF.6] и [G.8011] и показаны на рисунке 1.

Обобщим определения типов сервиса.

Коммутация по портам

Этот основанный на кадрах тип сервиса поддерживает специфические типы кадров; теги Service VLAN и коммутация по MAC-адресам не используются.

S-теги

Существует множество вариантов коммутации по S-TAG, включая:

  • «один-к-одному» (взаимно-однозначный)

В этом случае каждое значение VID отображается на свой тип сервиса.

  • групповой (bundled)

В этом случае поддерживается отображение множества VID на один тип сервиса, включая:

  • множество на один

В этом сервисе на основе кадров множество VID отображается на один тип сервиса.

  • все на один

В этом сервисе на основе кадров все VID отображаются на один тип сервиса.

  • прозрачный

В этом специальном случае все кадры отображаются из одного входного порта в один выходной порт Ethernet.

I-теги

Периметр PBBN включает транслятор опорной сети (backbone relay или B-component relay) и транслятор экземпляра сервиса (service instance relay — I-component relay). I-TAG содержит 24-битовый идентификатор сервиса I-SID и маркеры приоритета, а также некоторые другие поля. Сервис I-tagged обычно организуется между краевыми узлами PBBN и завершается на I-компоненте каждого узла, которая «прикрывает» пользовательский порт так, что сервис часто остается невидимым за пределами краевых устройств. Однако, поскольку транслятор I-компоненты включает другой транслятор, можно получить видимый сервис с I-тегами путем отделения транслятора I-компоненты от транслятора B-компоненты. Ситуации, когда это следует делать, включают сервис I-tagged между двумя PBBN и подключение к пользовательскому порту Provider Instance Port.

В общем случае тип коммутации определяет, какие из полей заголовка Ethernet используются функцией пересылки/коммутации (например, только VID или VID и DMAC). Тип коммутации также может потребовать использования дополнительных заголовков Ethernet или полей в заголовках. В типах сервиса, определенных для UNI, имеется тенденция использования заголовков для запроса сервиса (service delimiter) на стыке между сайтом пользователя и периметром сети.

Во многих случаях применения мостов поля заголовков изменить нельзя, но разрешены некоторые трансляции значений поля VID (обычно на краю сети).

Для всех типов сервиса уровень данных является двухсторонним и симметричным. Это означает, что прямой и обратный путь используют один и тот же набор узлов, портов и двухсторонних каналов. Это свойство является фундаментальным. Группа 802.1 поддерживает это свойство двухсторонней симметрии в определении CFM29, являющегося частью OAM.

2.2. Эксплуатация, администрирование и обслуживание (OAM)

Отказоустойчивость повышается при добавлении OAM для уровня данных с поддержкой контроля отказов и управления производительностью.

Сообщения Ethernet OAM ([802.1ag] и [Y.1731]) основаны на пересылке кадров уровня данных в обоих направлениях. Определение прерванного пути или некорректно направленного пакета в этом случае основано на сообщении OAM, передаваемом вслед за Eth-LSP. Идентификаторы таких сообщений OAM зависят от уровня данных, поэтому они так же хорошо работают для путей, управляемых с помощью GMPLS.

Сообщения Ethernet OAM в настоящее время включают:

[802.1ag] и [Y.1731]:

  • CCM30/RDI31 — проверка непрерывности/индикация удаленного дефекта;
  • LBM/LBR32 — сообщение/отклик проверки по петле;
  • LTM/LTR33 — сообщение/отклик трассировки канала;
  • VSM/VSR34 — специфическое для производителя сообщение/отклик.

[Y.1731]:

  • AIS35 — сигнал тревоги;
  • LCK36 — сигнал блокировки;
  • TST — тест;
  • LMM/LMR37 — сообщение/отклик замера потерь;
  • DM38 — измерение задержки;
  • DMM/DMR39 — сообщение/отклик замера задержки;
  • EXM/EXR40 — сообщение/отклик для экспериментов;
  • APS, MCC41 — автоматическое переключение защиты, служебный коммуникационный канал.

Эти функции поддерживаются для всех стандартизованных форматов Eth-LSP.

2.3. Характеристики коммутации Ethernet

Технологии Ethernet и MPLS похожи в части инкапсуляции разнотипных пакетов и кадров для передачи данных. В Ethernet инкапсулированные данные называют данными MAC-клиента. Кадр Ethernet MAC с инкапсуляцией включает заголовок, адреса отправителя и получателя, необязательнее поле идентификатора VLAN, тип и размер данных клиента (вместе с возможным заполнением), а также контрольную сумму FCS42 в конце кадра.

Тип данных клиента обычно идентифицируется значением поля Ethertype (явное указание), но возможны и иные (неявные) способы индикации типа.

Коммутаторы Ethernet с функциями моста используют для пересылки MAC-адрес получателя и номер VLAN. Номер VLAN идентифицирует некий набор (возможно активных) мостов и ЛВС. Адрес предполагается уникальным и инвариантным в рамках VLAN. MAC-адрес зачастую являются уникальными в глобальном масштабе, но для работы мостов это не требуется.

3. Модель

В соответствии с архитектурой GMPLS, определенной в [RFC3945], уровень управления GMPLS может быть применен к некой технологии путем управления уровнем данных и коммутационными характеристиками этой технологии. В соответствии с [RFC3945] архитектура GMPLS позволяет использовать для управления мостами Ethernet и другими технологиями канального уровня коммутацию типа L2SC43. Однако управление коммутацией Ethernet не было явно определено в [RFC3471], [RFC4202] или каком-либо из последующих документов GMPLS.

Архитектура GMPLS делает явное различие между уровнем данных и уровнем управления. Такое разделение позволяет уровню управления GMPLS оставаться неизменным в плане архитектуры и функциональности для управления разными технологиями. Архитектура также требует IP-связности на уровне управления для обмена информацией, но не всегда требует IP на уровне данных.

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

  • профиль полосы пропускания;
  • уровень приоритета пересылки;
  • параметры «покупки» соединений;
  • возможности защиты/быстрого восстановления;
  • правила маршрутизации (например, явные маршруты);
  • двухсторонний сервис;
  • сквозная и посегментная защита;
  • иерархия.

Профиль полосы пропускания может использоваться для задания согласованной скорости передачи данных, пиковой скорости передачи и правил для случаев превышения или недостаточной нагрузки. Службы, управляемые по такой схеме, будут использовать TSpec для поддержки параметров трафика Ethernet, которые определены в [ETH-TSPEC].

При использовании GMPLS для «транспорта» Ethernet потребуется расширение GMPLS для работы с уровнем данных Ethernet и функциями коммутации. Определение поддержки Ethernet в GMPLS является многогранным по причине различий в функциях пересылки/коммутации, присущих различным типам сервиса, рассмотренным в параграфе 2.1. В общем случае поля заголовка, используемые функцией коммутации/пересылки (например, VID и DMAC), могут характеризоваться, как метки уровня данных. В некоторых ситуациях эти поля могут быть неизменными на пути Eth-LSP, а при других условиях они могут меняться на каждом этапе пересылки или на некоторых интерфейсах вдоль пути. В тех случаях, когда «метки» должны пересылаться без изменения, возникают незначительные ограничения при распределении меток, как в некоторых других технологиях (например, коммутации по «лямбдам44»)..

Характеристики уровня данных «транспорта» Ethernet не требуется менять для управления с помощью GMPLS. В качестве примера рассмотрим уровень данных IEEE 802.1Q [802.1Q]. Значение VID используется в качестве «фильтра», указывающего на определенную таблицу пересылки, и, если значение DMAC найдено в таблице, решение о пересылке принимается на базе DMAC. Если для пересылки используется связующее дерево и значение DMAC не найдено в таблице, применяется широковещательная пересылка через все выходные интерфейсы, для которых определено данное значение VID. Такая проверка MAC-адресов и широковещательная пересылка корректны и позволяют выполнить «обучение». В специальном случае, когда значение VID определено только для пары портов, пересылка осуществляется в режиме «точка-точка» (P2P). В этом случае все кадры, помеченные данным значением VID, принимаются через один из пары портов и пересылаются в другой порт пары без необходимости «обучения».

Стандарт [802.1Qay] позволяет отключить обучение и, следовательно, механизм широковещания, что обеспечивает возможность организации явно маршрутизируемых соединений Ethernet.

В этом документе не определяется какой-либо конкретный формат для меток Eth-LSP. Предполагается, что будут подготовлены документы для разных типов сервиса, определяющие все требуемые для поддержки конкретного сервиса Ethernet расширения в части сигнализации и маршрутизации. В зависимости от требований сервиса может потребоваться определение множества расширений и процедур протокола GMPLS. Предполагается, что все такие расширения будут совместимы с данным документом.

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

Тип коммутации (Switching Type) и дескриптор возможностей коммутации интерфейса (Interface Switching Capability Descriptor) используют общий набор значений и определены в [RFC3945], [RFC3471] и [RFC4202], как индикаторы типа коммутации, которую следует ([RFC3471]) и можно ([RFC4202]) осуществить на конкретном канале для LSP. Тип коммутации L2SC уже может использоваться реализациями коммутаторов канального уровня (включая Ethernet). В связи с этим и для сохранения возможности использования этого типа коммутации и существующих коммутаторов, а также для того, чтобы различать две парадигмы коммутации Ethernet, требуется определить новый тип коммутации для каждой поддерживаемой парадигмы коммутации Ethernet.

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

4. Модель маршрутизации и адресации GMPLS

Этот документ не меняет модели маршрутизации и адресации GMPLS. Управление GMPLS для путей Eth-LSP использует модель маршрутизации и адресации, описанную в [RFC3945]. Важно отметить, что эта модель включает использование адресов IP для идентификации интерфейсов и конечных точек LSP, а также поддержку безадресных интерфейсов.

В тех случаях, когда для поддержки того или иного сервиса Ethernet требуется другое семейство адресов или тип идентификаторов, могут определяться специальные расширения для отображения на адреса IP. Предполагается, что поддержка Eth-LSP будет строго соответствовать схеме адресации стека протоколов GMPLS, описанного в [RFC3471], [RFC3473] и других документах.

4.1. Маршрутизация GMPLS

Маршрутизация GMPLS в соответствии с определением [RFC4202] использует протоколы маршрутизации IP с TLV-расширением для поддержки распространения связанной с GMPLS информации TE (маршрутизатор и канал). Как всегда бывает в GMPLS, информация TE заполняется на основе данных о ресурсах, полученных от LMP или из параметров конфигурации. Ресурсы полосы каналов определяются при организации Eth-LSP. Интерфейсы, поддерживающие коммутацию Eth-LSP, идентифицируются по соответствующим дескрипторам возможностей (ISC45). Как отмечено в параграфе 3, предполагается определение одного или множества ISC для поддержки путей Eth-LSP. И снова L2SC ISC не будут использоваться для представления поддерживающих Eth-LSP интерфейсов, которые определены в данном документе и последующих работах для поддержки парадигмы коммутации транспорта Ethernet. Кроме того, для поддержки требований конкретного типа коммутируемого сервиса Ethernet при необходимости может быть определена относящаяся к ISC информация TE .

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

4.2. Сеть управления

Для работы уровня управления GMPLS требуется связная IP-сеть, пропускной способности которой достаточно для обмена маршрутной и сигнальной информацией GMPLS.

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

Такая связность IP может обеспечиваться за счет отдельной независимой сети (out-of-band) или через сеть коммутаторов Ethernet (in-band).

5. Сигнализация GMPLS

Сигнализация GMPLS ([RFC3471] и [RFC3473]) хорошо подходит для управления путями Eth-LSP и коммутаторами Ethernet. Сигнализация обеспечивает возможность динамической организации пути от входного узла к выходному. Полученный с помощью сигнализации путь может быть полностью статическим и неизменным в течение всего срока жизни. Однако сигнализация также позволяет динамически изменять путь после его создания. Выбор статического или динамического варианта определяется оператором. Стандартизованная сигнализация повышает уровень взаимодействия между операторами.

Сигнализация GMPLS поддерживает организацию и контроль для односторонних и двухсторонних путей. Технология Ethernet является двухсторонней и CFM46 создаются для усиления этого. До разработки CFM в двухсторонних соединениях использовались эмуляция провода и требования по обучению. В соответствии со сказанным от путей Eth-LSP требуется двухсторонняя симметрия. Eth-LSP может представлять собой P2P или P2MP (см. [RFC4875]). Сигнализация GMPLS также позволяет организовать полную или частичную защиту LSP (см. [RFC4872] и [RFC4873]).

Отметим, что стандарт GMPLS не поддерживает различной полосы для каждого направления двухсторонних LSP. В [RFC5467] и экспериментальных документах рассматриваются процедуры для тех случаев, когда на двухсторонних соединениях требуется асимметрия.

6. Управление каналом

Обнаружение каналов было специфицировано для мостов IEEE 802.1 в стандарте [802.1AB]. Преимущества обнаружения каналов в больших системах весьма существенны. Обнаружение каналов может снижать сложность настройки и вероятность возникновения недетектируемых ошибок в конфигурации, а также создания ошибочных соединений. Однако поддержка 802.1AB является необязательной, поэтому она может отсутствовать до активизации канала и поддерживает преимущественно уровень управления.

В контексте GMPLS был определен протокол управления каналом (LMP) [RFC4204] для поддержки управления каналами и автоматического детектирования на уровне управления GMPLS. LMP также поддерживает автоматизированное создание безадресных интерфейсов для уровня управления. Если LMP не используется, возникают дополнительные конфигурационные требования к идентификаторам каналов GMPLS. Для крупных реализаций предпочтительно использование LMP. Протокол LMP также имеет опции контроля отказов, прежде всего для использования с прозрачными и «темными» (opaque) сетевыми технологиями. С новыми возможностями IEEE CFM [802.1ag] и ITU-T [Y.1731] такая функция может остаться невостребованной. Задачей архитектуры GMPLS Ethernet является обеспечение возможности выбора наилучшего набора средств в соответствии с потребностями пользователей. При использовании уровня управления GMPLS следует применять всю функциональность Ethernet CFM .

LMP и 802.1AB сравнительно независимы. Поддержки LMP должно быть достаточно для того, чтобы обойтись без 802.1AB, однако при желании 802.1 AB можно независимо использовать в параллель. На рисунке 2 показаны возможные варианты одновременного применения LMP, 802.1AB и 802.1ag.

     +-------------+        +-------------+
     | +---------+ |        | +---------+ |
     | |         | |        | |         | |Корреляция
     | |  LMP    |-|<------>|-|  LMP    | |свойств
     | |         | |        | |         | |каналов GMPLS
     | |  (opt)  | |GMPLS   | |  (opt)  | |
     | |         | |        | |         | |Связывание
     | +---------+ |        | +---------+ |
     | +---------+ |        | +---------+ |
     | |         | |        | |         | |
     | | 802.1AB |-|<------>|-| 802.1AB | |идентификаторы
     | |  (opt)  | |Ethernet| |  (opt)  | |каналов P2P
     | |         | |        | |         | |
     | +---------+ |        | +---------+ |
     | +---------+ |        | +---------+ |
     | |         | |        | |         | |Сквозной
-----|-| 802.1ag |-|<------>|-| 802.1ag |-|-------
     | | Y.1731  | |Ethernet| | Y.1731  | |Контроль отказов
     | |  (opt)  | |        | |  (opt)  | |Управление
     | |         | |        | |         | |производительностью
     | +---------+ |        | +---------+ |
     +-------------+        +-------------+
       Коммутатор 1   Канал   Коммутатор 2

Рисунок 2: Опции управления логическим каналом

Рисунок 2 иллюстрирует функциональные соотношения между схемами управления каналами и OAM. Предполагается, что LMP будет использоваться для функций сопоставления свойств каналов на уровне управления, а механизмы Ethernet для OAM (такие, как CFM, трассировка каналов и т. п.) будут применяться на уровне данных для контроля и трассировки отказов.

7. Расчет и выбор пути

GMPLS не задает конкретных методов выбора путей или поддержки расчета путей. GMPLS позволяет использовать широкий спектр таких методов от очень простых расчетов пути до сложных методов координирования большого числа требуемых путей. Расчет путей может выполняться распределенно с локальным расчетом на управляющих станциях смены маршрута или с использованием изощренных расчетов на специальных серверах.

Пути Eth-LSP могут могут поддерживаться с использованием любых механизмов выбора или расчета путей. Как в любой функции выбора пути GMPLS и любом механизме выбора пути, в процессе выбора пути должны приниматься во внимание возможности коммутации и кодирования, анонсируемые конкретным интерфейсом. Eth-LSP можно также создавать с использованием методик, описанных в [RFC4655].

8. Множество VLAN

Этот документ позволяет поддерживать сигнализацию для параметров Ethernet через множество VLAN, поддерживающих как непрерывные Eth-LSP, так и Hierarchical Ethernet LSP. Смысл этого заключается в том, чтобы использовать иерархию GMPLS для поддержки одноранговых моделей, UNI и NNI.

9. Вопросы безопасности

Для управляемых с помощью GMPLS «транспортных» систем Ethernet следует иметь в виду, что пользователи и устройства, подключенные к UNI, могут вести себя враждебно, небрежно или некорректно. Трафик управления внутри сети провайдера предполагается доверенным. В общем случае эти требования не отличаются от требований безопасности для любой сети GMPLS. Доступ в доверенную сеть будет осуществляться только по протоколам, определенным для UNI или NNI, и через защищенные интерфейсы управления.

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

Если GMPLS используется только для управления VLAN, для портов UNI могут потребоваться общепринятые средства защиты от атак на службы (DoS) Ethernet.

Более подробное обсуждение вопросов безопасности MPLS и GMPLS проводится в документе [SECURITY]. Для защиты от множества атак можно использовать криптографические методы [SECURITY]. Одной из опций защиты «транспорта» Ethernet является использование технологии защиты управления доступом к среде47 802.1AE [802.1AE], обеспечивающей шифрование и аутентификацию. Предполагается, что документы по конкретным решениям будут включать полное рассмотрение вопросов безопасности, возникающих в связи с вводимым расширением.

10. Литература

10.1. Нормативные документы

[RFC3471] Berger, L., Ed., «Generalized Multi-Protocol Label Switching (GMPLS) Signaling Functional Description», RFC 3471, January 2003.

[RFC3473] Berger, L., Ed., «Generalized Multi-Protocol Label Switching (GMPLS) Signaling Resource ReserVation Protocol-Traffic Engineering (RSVP-TE) Extensions», RFC 3473, January 2003.

[RFC3945] Mannie, E., Ed., «Generalized Multi-Protocol Label Switching (GMPLS) Architecture», RFC 3945, October 2004.

[RFC4202] Kompella, K., Ed., and Y. Rekhter, Ed., «Routing Extensions in Support of Generalized Multi-Protocol Label Switching (GMPLS)», RFC 4202, October 2005.

10.2. Дополнительная литература

[802.1AB] «IEEE Standard for Local and Metropolitan Area Networks, Station and Media Access Control Connectivity Discovery», IEEE 802.1AB, 2009.

[802.1AE] «IEEE Standard for Local and metropolitan area networks Media Access Control (MAC) Security», IEEE 802.1AE-200649, August 2006.

[802.1ag] «IEEE Standard for Local and Metropolitan Area Networks — Virtual Bridged Local Area Networks — Amendment 5: Connectivity Fault Management», IEEE 802.1ag50, 2007.

[802.1ah] «IEEE Standard for Local and Metropolitan Area Networks — Virtual Bridged Local Area Networks — Amendment 6: Provider Backbone Bridges», IEEE Std 802.1ah-200851, August 2008.

[802.1Q] «IEEE standard for Virtual Bridged Local Area Networks», IEEE 802.1Q-200552, May 2006.

[802.1Qay] «IEEE Standard for Local and Metropolitan Area Networks — Virtual Bridged Local Area Networks — Amendment 10: Provider Backbone Bridge Traffic Engineering», IEEE Std 802.1Qay-2009, August 2009.

[ETH-TSPEC] Papadimitriou, D., «Ethernet Traffic Parameters», Work in Progress, January 2010.

[G.8011] ITU-T Recommendation G.801153, «Ethernet over Transport — Ethernet services framework», January 2009.

[G.8011.1] ITU-T Recommendation G.8011.1/Y.1307.154, «Ethernet private line service», January 2009.

[G.8011.2] ITU-T Recommendation G.8011.2/Y.1307.255, «Ethernet virtual private line service», January 2009.

[G.8031] ITU-T Recommendation G.8031, «Ethernet linear protection switching», November 2009.

[MEF.6] The Metro Ethernet Forum MEF 6, «Ethernet Services Definitions — Phase I», 200456.

[RFC4204] Lang, J., Ed., «Link Management Protocol (LMP)», RFC 4204, October 2005.

[RFC4875] Aggarwal, R., Ed., Papadimitriou, D., Ed., and S. Yasukawa, Ed., «Extensions to Resource Reservation Protocol — Traffic Engineering (RSVP-TE) for Point-to-Multipoint TE Label Switched Paths (LSPs)», RFC 4875, May 2007.

[RFC4655] Farrel, A., Vasseur, J.-P., and J. Ash, «A Path Computation Element (PCE)-Based Architecture», RFC 4655, August 2006.

[RFC4872] Lang, J., Ed., Rekhter, Y., Ed., and D. Papadimitriou, Ed., «RSVP-TE Extensions in Support of End-to-End Generalized Multi-Protocol Label Switching (GMPLS) Recovery», RFC 4872, May 2007.

[RFC4873] Berger, L., Bryskin, I., Papadimitriou, D., and A. Farrel, «GMPLS Segment Recovery», RFC 4873, May 2007.

[RFC5467] Berger, L., Takacs, A., Caviglia, D., Fedyk, D., and J. Meuric, «GMPLS Asymmetric Bandwidth Bidirectional Label Switched Paths (LSPs)», RFC 5467, March 2009.

[SECURITY] Fang, L., Ed., «Security Framework for MPLS and GMPLS Networks», Work in Progress, October 2009.

[Y.1731] ITU-T Recommendation Y.173157, «OAM Functions and Mechanisms for Ethernet based Networks», February 2008.

11. Благодарности

На начальных этапах работы в ней принимало участие множество людей. Документы по основам GELS и расширению PBB-TE оказали существенную помощь при выполнении работы по подготовке данного документа. Благодарим за работу авторов первоначальных документов: Dimitri Papadimitriou, Nurit Sprecher, Jaihyung Cho, Dave Allan, Peter Busschbach, Attila Takacs, Thomas Eriksson, Diego Caviglia, Himanshu Shah, Greg Sunderwood, Alan McGuire, Nabil Bitar.

George Swallow внес существенный вклад в подготовку данного документа.

Адреса авторов

Don Fedyk

Alcatel-Lucent

Groton, MA, 01450

Phone: +1-978-467-5645

EMail: donald.fedyk@alcatel-lucent.com

Lou Berger

LabN Consulting, L.L.C.

Phone: +1-301-468-9228

EMail: lberger@labn.net

Loa Andersson

Ericsson

Phone: +46 10 717 52 13

EMail: loa.andersson@ericsson.com


Перевод на русский язык

Николай Малых

nmalykh@protokols.ru

1Synchronous Optical Network — синхронная оптическая сеть.

2Synchronous Digital Hierarchy — синхронная цифровая иерархия.

3Time-Division Multiplexing — мультиплексирование с разделением по времени.

4Asynchronous Transfer Mode — асинхронный режим передачи.

5Generalized Multiprotocol Label Switching — обобщенная многопротокольная коммутация по меткам.

6Internet Engineering Steering Group.

7International Electrical and Electronics Engineers.

8International Telecommunication Union — Telecommunication Standardization Sector.

9Metro Ethernet Forum.

10Spanning Tree.

11GMPLS Ethernet Label Switching.

12Virtual Local Area Network.

13Service VID.

14Service TAG.

15Provider Backbone Bridges — магистральные мосты провайдера.

16Backbone VID.

17Provider Backbone Bridged Network — опорная сеть провайдера на базе мостов.

18Operations, administration, and maintenance.

19User-Network Interface.

20Network-Network Interface.

21Ethernet Private Line.

22Ethernet Virtual Private Line.

23Spanning Tree Protocol

24Constraint-based.

25Ethernet Label Switched Path.

26Link Management Protocol.

27Forwarding database.

28В оригинале используется термин Bridge relay. Прим. перев.

29Connectivity Fault Management — контроль отказов в соединениях.

30Continuity Check.

31Remote Defect Indication.

32Loopback Message/Reply.

33Link Trace Message/Reply.

34Vendor-Specific Message/Reply.

35Alarm Indication Signal.

36Locked Signal.

37Loss Measurement Message/Reply.

38Delay Measurement.

39Delay Measurement Message/Reply.

40Experimental Message/Reply.

41Automatic Protection Switching, Maintenance Communication Channel.

42Frame Check Sequence.

43Layer-2 Switch Capable.

44Длине волны в системах с мультиплексированием WDM. Прим. перев.

45Interface Switching Capabilities.

46Контроль нарушения связности. Прим. перев.

47Media Access Control Security.

49Этот стандарт доступен на сайте http://standards.ieee.org/getieee802/download/802.1AE-2006.pdf. Прим. перев.

50Этот стандарт доступен на сайте http://standards.ieee.org/getieee802/download/802.1ag-2007.pdf. Прим. перев.

51Этот стандарт доступен на сайте http://standards.ieee.org/getieee802/download/802.1ah-2008.pdf. Прим. перев.

52Этот стандарт доступен на сайте http://standards.ieee.org/getieee802/download/802.1Q-2005.pdf. Прим. перев.

53Этот документ доступен по ссылке http://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-G.8011-200901-I!!PDF-E&type=items. Прим. перев.

54Этот документ доступен по ссылке http://www.itu.int/rec/T-REC-G.8011.1/recommendation.asp?lang=en&parent=T-REC-G.8011.1-200901-I. Прим. перев.

55Документ доступен по ссылке http://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-G.8011.2-200901-I!!PDF-E&type=items. Прим. перев.

56В настоящее время действует новая версия спецификации, доступная по ссылке http://www.metroethernetforum.org/PDF_Documents/MEF6-1.pdf. Прим. перев.

57Документ доступен по ссылке http://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-Y.1731-200802-I!!PDF-E&type=items. Прим. перев.

Рубрика: RFC | Оставить комментарий

RFC 5795 The RObust Header Compression (ROHC) Framework

Internet Engineering Task Force (IETF)                   K. Sandlund
Request for Comments: 5795                              G. Pelletier
Obsoletes: 4995                                             Ericsson
Category: Standards Track                               L-E. Jonsson
ISSN: 2070-1721                                           March 2010

Модель отказоустойчивой компрессии заголовков ROHC

The RObust Header Compression (ROHC) Framework

PDF

Аннотация

Протокол ROHC обеспечивает концепцию гибкого, эффективного и готового к будущему сжатия заголовков. Он разработан для обеспечения эффективности и надежности при работе на каналах с различными технологиями и характеристиками.

Модель ROHC вместе с набором профилей сжатия была изначально предложена в RFC 3095. Для развития и упрощения спецификаций ROHC в этом документе явно разделены определения модели ROHC и профиля без компрессии. Приводимое здесь определение модели не меняет и не обновляет модели, описанной в RFC 3095.

Эта спецификация отменяет RFC 4995. Решена проблема взаимодействия, ошибочно внесенная в RFC 4995, и добавлены некоторые разъяснения.

Статус документа

Этот документ является проектом стандарта Internet (Internet Standards Track)..

Документ подготовлен IETF1 и содержит согласованный взгляд сообщества IETF. Документ обсуждался публично и одобрен для публикации IESG2. Дополнительная информация о стандартах Internet приведена в разделе 2 RFC 5741.

Информацию о текущем состоянии данного документа, обнаруженных ошибках и способах обратной связи можно найти по ссылке http://www.rfc-editor.org/info/rfc5795.

Авторские права

Авторские права ((c) 2010) принадлежат IETF Trust и лицам, являющимся авторами документа. Все права защищены.

К этому документу применимы права и ограничения, перечисленные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включенные в этот документ, распространяются в соответствии с упрощенной лицензией BSD, как указано в параграфе 4.e документа Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

Документ может содержать материалы из IETF Document или IETF Contribution, опубликованных или публично доступных до 10 ноября 2008 года. Лица, контролирующие авторские права на некоторые из таких документов, могли не предоставить IETF Trust права разрешать внесение изменений в такие документы за рамками процессов IETF Standards. Без получения соответствующего разрешения от лиц, контролирующих авторские права этот документ не может быть изменен вне рамок процесса IETF Standards, не могут также создаваться производные документы за рамками процесса IETF Standards за исключением форматирования документа для публикации или перевода с английского языка на другие языки.

1. Введение

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

Для каналов, где используются заголовки IP, суммарный размер этих заголовков может быть достаточно большим. Приложения, передающие данные по протоколу RTP [RFC3550], в дополнение к кадрированию канального уровня используют заголовок IPv4 [RFC0791] (20 октетов), заголовок UDP [RFC0768] (8 октетов) и заголовок RTP (12 октетов), что в сумме добавляет 40 октетов. При использовании IPv6 [RFC2460] заголовок IPv6 составит 40 октетов, а общий размер достигнет 60 октетов. Приложения, использующие протокол TCP [RFC0793], будут добавлять 20-октетный заголовок транспортного уровня и общий размер составит 40 октетов для IPv4 и 60 октетов для IPv6.

Относительный эффект компрессии для конкретных потоков (или приложений) зависит от используемого размера пакетов. Для приложений типа VoIP3, где размер данных, служащих для передачи голоса, может быть достаточно мал (15-20 октетов), компрессия заголовков может давать существенный эффект. Относительная эффективность для потоков TCP с большими пакетами (например, копирование файлов) будет значительно меньше, чем для потоков с мелкими пакетами (например, сигнализация или организация сессий).

По мере распространения беспроводных технологий передачи трафика IP требуется реализация специальных мер, учитывающих параметры каналов, обеспечиваемых этими технологиями, в части сжатия заголовков. Традиционные схемы сжатия заголовков (такие, как [RFC2507] и [RFC2508]), недостаточно эффективны для каналов с существенным уровнем потерь пакетов и достаточно большим периодом кругового обхода (например, беспроводных каналов и туннелей IP).

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

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

В RFC 3095 [RFC3095] определена схема ROHC и стартовый набор профилей сжатия. Для развития и упрощения спецификации модель и профили были разнесены в отдельные документы. Этот документ явно определяет модель ROHC, не меняя и не обновляя определения, данного в RFC 3095 (оба документа могут использоваться независимо один от другого). Реализации, основанные на определениях того и другого документа будут совместимы и смогут взаимодействовать. Однако, эту спецификацию следует рассматривать как замену RFC 3095 в качестве базовой спецификации для всех профилей, определяемых в будущем.

В этом документе исправления возникшая в RFC 4995 ошибка, приводящая к проблемам совместимости. Исправление приведено в параграфе 5.2.4.1 и связано с уточнением интерпретации поля Size в обратной связи ROHC.

2. Уровни требований

Ключевые слова необходимо (MUST), недопустимо (MUST NOT), требуется (REQUIRED), нужно (SHALL), не нужно (SHALL NOT), следует (SHOULD), не следует (SHOULD NOT), рекомендуется (RECOMMENDED), возможно (MAY), необязательно (OPTIONAL) в данном документе должны интерпретироваться в соответствии с [RFC2119].

2.1. Сокращения

В этом параграфе приведено большинство сокращений, используемых в документе.

ACK Acknowledgment — подтверждение.

CID Context Identifier — идентификатор контекста.

CO Compressed Packet Format — формат сжатого пакета.

CRC Cyclic Redundancy Check — контрольная сумма.

IR Initialization and Refresh — инициализация и обновление.

IR-DYN Initialization and Refresh, Dynamic part — инициализация и обновление, динамическая часть.

LSB Least Significant Bit — наименее значимый (младший) бит.

MRRU Maximum Reconstructed Reception Unit — максимальный восстанавливаемый на приеме блок.

MSB Most Significant Bit — наиболее значимый (старший) бит.

MSN Master Sequence Number — основной порядковый номер.

NACK Negative Acknowledgment — негативное подтверждение.

ROHC RObust Header Compression — сильная компрессия заголовков.

2.2. Терминология ROHC

Context — контекст

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

Context damage — повреждение контекста

Когда контекст декомпрессора не согласуется с контекстом сжатия, при попытке восстановления исходного заголовка могут происходить отказы. Такая ситуация может возникать в результате некорректной инициализации контекста декомпрессора, а также при потере или повреждении пакетов между компрессором и декомпрессором.

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

Context repair mechanisms — механизмы исправления контекста

Механизмы, используемые для ресинхронизации контекстов. Эти механизма достаточно важны, поскольку повреждение контекста вызывает распространение потерь. Примерами могут служить механизмы на базе NACK и периодическое обновление важной информации из контекста, выполняемое обычно в односторонней операции. Имеются механизмы, способные снизить вероятность несоответствия контекстов (например, повторение одного типа информации во множестве пакетов и использование CRC для защиты данных обновления контекста.

CRC-8 validation — проверка CRC-8

Проверка целостности в плане битовых ошибок для принятого заголовка IR и IR-DYN с использованием 8-битовой контрольной суммы CRC, включенной в заголовок IR/IR-DYN.

CRC verification — проверка CRC

Проверка результата попытки декомпрессии с использованием 3-битовых или 7-битовых контрольных сумм CRC, включенных в сжатый заголовок пакета.

Damage propagation — распространение повреждений

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

Error detection — детектирование ошибок

Обнаружение ошибок нижележащими уровнями. Если детектирование не полное, возникают остаточные ошибки.

Error propagation — распространение ошибок

Распространение повреждений или потерь.

ROHC profile — профиль ROHC

Протокол компрессии, определяющий механизмы сжатия для конкретных комбинаций заголовков. Профиль ROHC может быть адаптирован для работы с конкретным набором характеристик канала (например, уровень потерь, нарушение порядка доставки между точками компрессии и т. п.). Профили ROHC детализируют модель компрессии заголовков, определенную в этом документе, и с каждым профилем компрессии связан уникальный идентификатор профиля ROHC [ROHC-ids]. При организации канала ROHC согласуется набор профилей, поддерживаемых на обеих сторонах канала, и идентификатор профиля из согласованного набора используется для связывания каждого контекста сжатия с одним из профилей.

Link — канал

Физический путь передачи, образующий один интервал IP (hop).

Loss propagation — распространение потерь

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

Packet flow — поток пакетов

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

Residual error — остаточная ошибка

Ошибка, возникшая в процессе передачи и не обнаруженная на нижележащих уровнях.

ROHC channel — канал ROHC

Логический односторонний канал «точка-точка», передающий пакеты ROHC от одного компрессора к одному декомпрессору и опционально передающий данные обратной связи ROHC от имени другой пары компрессор-декомпрессор, работающей по отдельному каналу ROHC в противоположном направлении (см. также [RFC3759]).

В этом документе используется также концептуальная терминология из документа ROHC Terminology and Channel Mapping Examples [RFC3759].

3. Основы (информационный раздел)

В этом разделе приведена базовая информацию по сжатию заголовков. Описаны фундаментальные идеи и рассмотрена история схем компрессии заголовков. Обсуждаются также мотивы разработки и обнаруженные недостатки разных схем, послуживших основой при создании модели и профилей ROHC [RFC3095].

3.1. Основы компрессии заголовков

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

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

3.2. Краткая история компрессии заголовков

Первая схема компрессии заголовков CTCP4 [RFC1144] была предложена Van Jacobson. Схема CTCP, которую называют также компрессией VJ, позволяет уменьшить 40-октетные заголовки TCP/IP до 4 октетов. CTCP использует дельта-кодирование для последовательно изменяющихся полей. Компрессор CTCP детектирует повторы передачи на транспортом уровне и передает в таких случаях заголовок, обновляющий весь контекст. Такой механизм исправления не требует явной сигнализации между компрессором и декомпрессором.

В общей схеме компрессии заголовков IP (IPHC5) [RFC2507] достигнуты некоторые улучшения по сравнению с CTCP. IPHC позволяет сжимать любые заголовки IP, TCP и UDP. При сжатии заголовков, отличных от TCP, в IPHC не используется дельта-кодирование и это обеспечивает отказоустойчивость. Механизм исправления CTCP дополнен здесь негативными подтверждениями (их называют сообщениями CONTEXT_STATE), которые повышают скорость исправления. Скорость работы этого механизма исправления ограничивается временем кругового обхода для канала. IPHC не сжимает заголовки RTP.

CRTP [RFC2508] является расширением IPHC для протокола RTP. CRTP сжимает 40 октетов заголовков IPv4/UDP/RTP до 2 октетов при отключенных контрольных суммах UDP. При использовании UDP минимальный размер заголовков CRTP составляет октета.

На каналах с потерями и большим периодом кругового обхода CRTP не обеспечивает достаточной эффективности [CRTP-eval]. Каждый потерянный в канале пакет приводит к отказу при декомпрессии нескольких последующих пакетов, поскольку контекст повреждается на время не менее одного периода кругового обхода с момента потери пакета. К сожалению, большие заголовки, передаваемые CRTP при обновлении контекста, приводят к дополнительному расходу полосы.

CRTP использует механизм локального исправления TWICE, который был предложен в IPHC. Имя TWICE происходит от того, что для регулярных сжатых пакетов корректное предсказание потери пакета между точками компрессии определяется двойным (twice) обновлением в текущем пакете. Хотя механизм TWICE значительно повышает производительность CRTP, в [CRTP-eval] отмечено, что даже при его использовании протокол CRTP удваивает число теряемых пакетов.

Улучшенный вариант протокола CRTP, названный eCRTP [RFC3545], повышает отказоустойчивость CRTP при наличии разупорядочивания и потери пакетов, сохраняя сам протокол CRTP почти без изменений. В результате eCRTP обеспечивает повышение уровня отказоустойчивости, но за счет добавочных издержек несколько уступает протоколу CRTP по эффективности компрессии.

4. Обзор ROHC (информационный раздел)

4.1. Общие принципы

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

Первый этап включает идентификацию и группировку пакетов в различные «потоки» с максимальной избыточностью в рамках каждого потока для обеспечения максимальной сжимаемости. Группировка пакетов в потоки обычно осуществляется по адресам хостов отправителя и получателя (IP), типу протокола транспортного уровня (например, UDP или TCP), номерам процессов (портов) и, возможно, дополнительным уникальным идентификаторам приложений типа источника синхронизации (SSRC6) в RTP [RFC3550]. Компрессор и декомпрессор организуют контекст для потока пакетов и обозначают его идентификатором контекста CID7 включаемым в сжатый заголовок.

Вторым этапом является понимание картины изменения разных полей заголовков. На верхнем уровне поля заголовков можно разделить на несколько классов.

INFERRED — производные

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

STATIC — статический

Статические поля предполагаются неизменными в течение срока жизни потока. Значение такого поля достаточно передать один раз в начале потока.

STATIC-DEF — статические поля, определяющие принадлежность к потоку

Поля типа STATIC-DEF используются для определения потока, как отмечено выше. Пакеты, в которых соответствующие поля различаются, относят к разным потокам. В общем случае эти поля сжимаются, как STATIC.

STATIC-KNOWN — статические известные поля

Предполагается, что поля, относящиеся к типу STATIC-KNOWN, содержат общеизвестные значения, передавать которые, следовательно, не требуется.

CHANGING — меняющиеся

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

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

Однако эффективность компрессии требует компромисса с двумя другими свойствами — устойчивостью кодирования к потерям и ошибкам между компрессором и декомпрессором, а также возможностью обнаружения и корректировки ошибок в процессе декомпрессии.

4.2. Эффективность, отказоустойчивость и прозрачность компрессии

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

Эффективность сжатия

Эффективность сжатия определяется средним снижением размера заголовков в результате применения протокола.

Отказоустойчивость

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

Прозрачность сжатия

Прозрачность сжатия определяется степенью поддержки семантики исходных заголовков. Если все поля после декомпрессии побитово совпадают с исходными полями, схема компрессии обеспечивает прозрачность.

4.3. Развитие протокола ROHC

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

Для достижения требуемого компромисса схема компрессии должна обеспечивать декомпрессору средства проверки декомпрессии и детектирования потенциального повреждения контекста, а также механизмы восстановления (такие, как обратная связь). Схема компрессии заголовков, разработанные до создания рабочей группы ROHC, создавались без должного учета этих требований.

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

Документ RObust Header Compression (ROHC): Framework and four profiles: RTP, UDP, ESP, and uncompressed [RFC3095] был опубликован в 2001 году, как первый результат ROHC WG. Модель ROHC является обобщенной и расширяемой схемой компрессии заголовков, на основе которой могут определяться профили сжатия для различных протоколов. В RFC 3095 предложено множество новых методов компрессии, показавших соответствие предъявляемым требованиям, как описано в [RFC3096].

Тестирование взаимодействия RFC 3095 подтверждает возможности ROHC в части заявленных целей, но сообщения от разработчиков показали, что спецификация чересчур сложна и не всегда понятна. Один из основных недостатков заключался в том, что базовую модель и профили было достаточно сложно разделить в [RFC3095], что также осложняет разработку дополнительных профилей. Поэтому цель данного документа заключается в явной спецификации модели ROHC, а пересмотренные профили сжатия RFC 3095 приведены в отдельном документе [RFC5225].

4.4. Операционные характеристики канала ROHC

Отказоустойчивая компрессия заголовков может использоваться со многими технологиями канального уровня. Модель ROHC обеспечивает гибкость профилей для решения задач различных приложений и в этом параграфе кратко рассмотрены некоторые операционные характеристики каналов ROHC (см. также [RFC3759]).

Мультиплексирование через один логический канал

Канал ROHC обеспечивает механизм идентификации контекста в базовом формате пакетов ROHC. CID обеспечивает логическому каналу возможность использования ROHC для доставки множества потоков с компрессией заголовков, сохраняя возможность использования канала для одного потока пакетов без использования CID. Говоря точнее, ROHC использует отдельной пространство CID для логического канала и поле CID может быть опущено при использовании канала ROHC для одного потока.

Организация канальных параметров

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

Идентификация типа пакетов

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

Нарушение порядка доставки пакетов между конечными точками компрессии

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

Для профилей, заданных в [RFC3095], требуется, чтобы канал между компрессором и декомпрессором поддерживал упорядоченную доставку (т. е., в определениях этих профилей предполагается, что декомпрессор всегда получает пакеты в том порядке, в котором их передал компрессор). Влияние нарушения порядка на производительность этих профилей описано в [RFC4224]. Однако нарушение порядка доставки до точки компрессии обрабатывается этими профилями (т. е., в них не делается допущения о том, что компрессор получает все пакеты с сохранением порядка).

Профили ROHCv2, заданные в [RFC5225], предполагают, что декомпрессор может получать пакеты с нарушением порядка (т. е., не в том порядке, в котором они были переданы компрессором). Нарушение порядка доставки в точку компрессии также учитывается в этих профилях.

Дублирование пакетов

От канала, поддерживающего ROHC, требуется отсутствие дублирования пакетов (однако, такое дублирование может возникать до точки компрессии, поэтому предположений о получении компрессором единственного экземпляра каждого пакета не делается).

Кадрирование

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

Детектирование ошибок и защита от них

Профили ROHC следует разрабатывать так, чтобы они справлялись с остаточными ошибками в заголовках, доставляемых декомпрессору. Для детектирования отказов при декомпрессии и предотвращения или снижения уровня распространения повреждений используются контрольные суммы CRC. Однако рекомендуется реализовать детектирование ошибок на нижележащих уровнях для заголовков ROHC и предотвращение доставки заголовков ROHC с большим числом остаточных ошибок.

4.5. Компрессия и порядковый номер MSN

Компрессия полей заголовков основывается на организации функции от номера пакета (MSN8), которая описывает картину изменения полей по мере изменения MSN.

Картина изменения включает, например, поля с монотонным изменением, поля с незначительными изменениями, поля с редкими изменениями, а также поля, значения которых не меняются в течение срока жизни потока пакетов (в этом случае функция MSN эквивалентна константе).

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

MSN определяется на уровне профиля. Значение может извлекаться непосредственно из какого-либо поля сжимаемого заголовка (например, RTP SN [RFC5225]) или создаваться и поддерживаться самим компрессором (например, MSN для сжатия UDP в профиле 0x0102 [RFC5225] или MSN в ROHC-TCP [RFC4996]).

4.6. Статические и динамические части контекста

Контекст компрессии можно концептуально разделить на две части — статическую и динамическую, — каждая из которых основывается на свойствах сжимаемых полей.

Статическая часть включает информацию, требуемую для сжатия и декомпрессии полей класса STATIC, STATIC-KNOWN или STATIC-DEF (см. параграф 4.1).

Динамическая часть включает состояния, поддерживаемые для всех прочих полей (т. е. полей класса CHANGING).

5. Модель ROHC (нормативный раздел)

В этом разделе даются нормативные определения частей, общих для всех профилей ROHC (т. е. для модели в целом). Модель задает требования и функциональность канала ROHC включая способы обслуживания множества потоков сжатых пакетов в одном канале.

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

5.1. Канал ROHC

5.1.1. Контексты и их идентификаторы

С каждым сжатым потоком связывается контекст, представляющий собой состояние компрессора и декомпрессора, поддерживаемое для корректного сжатия и декомпрессии заголовков в пакетах из данного потока. Для идентификации контекста служит специальное значение CID.

Контекст считается новым, когда CID связывается с профилем в первый раз с момента создания канала ROHC или CID связывается с получением IR (не IR-DYN) для профиля, отличающегося от профиля контекста.

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

Пространство CID может быть небольшим (значения от 0 до 15) или большим (от 0 до 214 — 1 = 16383). Решение о размере пространства CID должно приниматься (возможно, путем согласования) до того, как можно будет передать первый пакет через канал ROHC.

Пространство CID организуется независимо доя каждого канала. Например, CID 3 для канала A и CID 3 для канала B не указывают на один контекст даже в тех случаях, когда конечные точки каналов A и B совпадают. В частности значения CID для любой пары каналов ROHC не связаны между собой (двум связанным каналам ROHC, каждый из которых используется в качестве канала обратной связи для другого, даже не требуется использовать пространства CID одного размера).

5.1.2. Поканальные параметры

Канал ROHC имеет множество параметров, которые формируют часть организованного состояния канала и состояния для каждого контекста. Состояние канала ROHC должно организовываться до того, как может быть передан первый пакет ROHC, что может быть реализовано за счет использования протоколов согласования, обеспечиваемых канальным уровнем (см. также [RFC3241], где описана опция согласования параметров ROHC для PPP). В этом параграфе приведено абстрактное описание отдельных компонент информации о состоянии канала.

LARGE_CIDS

Логическая переменная. Значение false говорит о малом пространстве CID (0 октетов или один префиксный октет, значения CID от 0 до 15), значение true — о большом пространстве CID (1 или 2 октета CID, значения CID от 0 до 16383). См. также параграфы 5.1.1 и 5.2.1.3.

MAX_CID

Неотрицательное целое число. Максимальный номер CID, который будет использоваться компрессором (отметим, что этот параметр не связан с LARGE_CIDS, но в дальнейшем может быть ограничен этим параметром). Это значение представляет согласие декомпрессора на выделение ресурсов памяти, достаточных для обслуживания по крайней мере MAX_CID+1 контекстов; декомпрессор должен поддерживать организованные контексты в этом пространстве, пока значение CID не будет использовано снова путем организации нового контекста или канала не прекратит существование.

PROFILES

Множество неотрицательных целых чисел, каждое из которых указывает профиль, поддерживаемый компрессором и декомпрессором. Профили идентифицируются 16-битовыми значениями, в которых 8 младших битов указывают реальный профиль, а 8 старших — вариант этого профиля. Формат сжатого заголовка ROHC идентифицирует используемый профиль только 8 младшими битами LSB — это означает, что при наличии у профиля вариантов во множество PROFILES после согласования недопустимо включать более одного варианта данного профиля. Компрессору недопустимо сжимать заголовки с использованием профилей, не включенных в PROFILES.

FEEDBACK_FOR

Необязательная ссылка на канал ROHC в обратном направлении между теми же конечными точками. При наличии этого параметра он указывает в какой канал ROHC передается вся обратная связь для данного канала ROHC (см. [RFC3759]).

MRRU9

Неотрицательное целое число. Показывает максимальный размер (в октетах) восстанавливаемого блока, который декомпрессор может собрать из сегментов (см. параграф 5.2.5). Это значение включает контрольную сумму сегментации. Если согласовано MRRU = 0, сегментацию недопустимо использовать на канале, а полученные сегменты должны отбрасываться декомпрессором.

5.1.3. Продолжительность контекста декомпрессора

Как часть согласования параметров канала, компрессор и декомпрессор с помощью параметра MAX_CID договариваются о максимальном используемом идентификаторе контекста (CID). Соглашаясь с MAX_CID, декомпрессор принимает на себя обязательство по выделению памяти для поддержки не менее MAX_CID+1 контекстов и контексты со значениями CID в этом согласованном пространстве декомпрессору следует сохранять, пока значение CID не будет использовано заново или пока канал не будет разорван или согласован заново.

5.2. Пакеты ROHC и их типы

В этом параграфе для диаграмм, показывающих различные типы пакетов, форматов и полей ROHC, двоеточие (:) указывает необязательную часть, а символ дробной черты (/) — переменный размер.

Схема индикации типа пакета ROHC разработана так, чтобы обеспечивалось необязательное поле заполнения, поле типа пакетов обратной связи, необязательный октет Add-CID (включает 4 бита CID) и простой механизм сегментации-сборки.

На уровне модели ROHC зарезервировано несколько типов пакетов:

11100000 : заполнение
1110nnnn : октет Add-CID (nnnn=CID со значениями от 0x1 до 0xF)
11110    : обратная связь
11111000 : пакет IR-DYN
1111110  : пакет IR
1111111  : сегмент

В отдельных профилях могут определяться и использоваться другие типы пакетов:

0        : доступно (не резервируется моделью ROHC)
10       : доступно (не резервируется моделью ROHC)
110      : доступно (не резервируется моделью ROHC)
1111101  : доступно (не резервируется моделью ROHC)
11111001 : доступно (не резервируется моделью ROHC)

5.2.1. Общий формат пакетов ROHC

Базовый формат пакета ROHC показан на рисунке.

       --- --- --- --- --- --- --- ---
      :           Padding             :
       --- --- --- --- --- --- --- ---
      :           Feedback            :
       --- --- --- --- --- --- --- ---
      :            Header             :
       --- --- --- --- --- --- --- ---
      :           Payload             :
       --- --- --- --- --- --- --- ---

Padding — заполнение

Произвольное (0 или больше) число октетов заполнения, формат которых определен в параграфе 5.2.1.1.

Feedback — обратная связь

Произвольное (0 или больше) число элементов обратной связи, формат которых определен в параграфе 5.2.4.1.

Header — заголовок

Специфический для профиля заголовок CO (см. параграф 5.2.1.3), заголовок IR или IR-DYN (см. параграф 5.2.2) или сегмент ROHC (см. параграф 5.2.5). В пакете ROHC не может быть более одного заголовка, который может отсутствовать, если пакет содержит только обратную связь (поле Feedback).

Payload — данные

Соответствует некоторому (0 или больше) числу октетов данных из несжатого пакета, начиная с первого октета в несжатом пакете вслед за последним заголовком, сжимаемым в этом профиле компрессии.

В пакете должно присутствовать по крайней мере одно поле Feedback или Header.

5.2.1.1. Формат октета заполнения

Октет заполнения показан на рисунке.

        0   1   2   3   4   5   6   7
      +---+---+---+---+---+---+---+---+
      | 1   1   1   0   0   0   0   0 |
      +---+---+---+---+---+---+---+---+

Отметим, что октет Padding недопустимо интерпретировать, как октет Add-CID для CID 0.

5.2.1.2. Формат октета Add-CID

Октет Add-CID показан на рисунке.

        0   1   2   3   4   5   6   7
      +---+---+---+---+---+---+---+---+
      | 1   1   1   0 |      CID      |
      +---+---+---+---+---+---+---+---+

CID

Значения от 0x1 до 0xF указывают CID от 1 до 15.

Отметим, что для CID 0 октет Add-CID совпадает с октетом заполнения (Padding).

5.2.1.3. Общий формат заголовка

Все типы пакетов ROHC используют общий формат заголовка (поле Header), показанный на рисунке.

  0              x-1  x       7
 --- --- --- --- --- --- --- ---
:         октет Add-CID         : если CID 1-15 и малое пространство CID
+--- --- --- --- ---+--- --- ---+
| type indication   |   body    | 1 октет (8-x битов образуют тело)
+--- --- --- --- ---+--- --- ---+
:                               :
/     0, 1, или 2 октета CID    / 1 или 2 октета при 
:                               : большом пространстве CID
+---+---+---+---+---+---+---+---+
/             body              / переменный размер
+---+---+---+---+---+---+---+---+

type indication

Тип пакета ROHC.

body

Интерпретируется в зависимости от типа пакета и данных CID в соответствии с определением профиля.

Заголовок начинается с индикации типа пакета или включает индикации, следующую сразу после октета Add-CID.

Когда канал ROHC настроен на использование малого пространства CID:

  • если поле Add-CID непосредственно предшествует индикации типа пакета, пакет имеет значение CID = Add-CID, в противном случае CID = 0;
  • CID = 0 из малого пространства представляется без использования каких-либо битов (0), следовательно, для потоков с CID 0 не возникает издержек на передачу CID в сжатом заголовке; в этом случае поле Header начинается с индикации типа пакета;
  • CID из малого пространства со значениями от 1 до 15 представляются октетом Add-CID, как описано выше; поле Header начинается с октета Add-CID, за которым следует индикация типа пакета;
  • CID из большого пространства не включаются в поле Header.

Если канал ROHC настроен на использование большого пространства CID:

  • большое значение CID всегда указывается с использованием схемы кодирования, описанной в параграфе 5.3.2 (не более 2 октетов); в таких случаях поле Header начинается с индикации типа пакета.

5.2.2. Типы пакетов инициализации и обновления (IR)

Тип пакетов IR10 содержит идентификатор профиля, определяющий интерпретацию остальной части заголовка и связывающий профиль с контекстом. Сохраненный параметр профиля в дальнейшем определяет синтаксис и семантику идентификаторов типа пакетов и типы, используемые в конкретном контексте.

Пакеты IR и IR-DYN всегда обновляют контекст в части содержащихся в заголовке полей обновления. Они никогда не сбрасывают контекст, за исключением случаев инициализации нового контекста (см. параграф 5.1.1) и ситуаций, когда профиль, указанный полем Profile задает иное.

5.2.2.1. Формат заголовка ROHC IR

Заголовок IR связывает CID с профилем и обычно также инициализирует контекст, а также обновляет все или часть контекстов. Для пакетов IR поле Header имеет формат, показанный на рисунке.

  0   1   2   3   4   5   6   7
 --- --- --- --- --- --- --- ---
:         октет Add-CID         : если CID 1-15 и малое пространство CID
+---+---+---+---+---+---+---+---+
| 1   1   1   1   1   1   0 | x | октет типа IR
+---+---+---+---+---+---+---+---+
:                               :
/   0, 1, или 2 октета CID      / 1 или 2 октета при 
:                               : большом пространстве CID
+---+---+---+---+---+---+---+---+
|            Profile            | 1 октет
+---+---+---+---+---+---+---+---+
|              CRC              | 1 октет
+---+---+---+---+---+---+---+---+
|                               |
/ profile-specific information  / переменный размер
|                               |
+---+---+---+---+---+---+---+---+

x

Зависящая от профиля информация, интерпретируемая в соответствии с профилем, указанным в поле Profile заголовка IR.

Profile

Профиль, связанный с CID. В заголовке IR профиль представляется 8 младшими битами идентификатора (см. параграф 5.1.2).

CRC

8-битовое значение контрольной суммы ( см. параграф 5.3.1.1).

Profile-specific information

Содержимое этой части заголовка IR определяется конкретным профилем и интерпретируется в соответствии с профилем, указанным в поле Profile.

5.2.2.2. Формат заголовка ROHC IR-DYN

В отличие от заголовка IR заголовок IR-DYN не может инициализировать неинициализированный контекст. Однако он может переопределить связанный с контекстом профиль, если указанный в заголовке IR-DYN профиль позволяет это. Этот тип пакетов также резервируется на уровне модели. Заголовок IR-DYN обычно также инициализирует или обновляет части контекста. Формат заголовка IR-DYN показан на рисунке.

  0   1   2   3   4   5   6   7
 --- --- --- --- --- --- --- ---
:         октет Add-CID         : если CID 1-15 и малое пространство CID
+---+---+---+---+---+---+---+---+
| 1   1   1   1   1   0   0   0 | октет типа IR-DYN
+---+---+---+---+---+---+---+---+
:                               :
/        0-2 октета CID         / 1 или 2 октета при
:                               : большом пространстве CID
+---+---+---+---+---+---+---+---+
|            Profile            | 1 октет
+---+---+---+---+---+---+---+---+
|              CRC              | 1 октет
+---+---+---+---+---+---+---+---+
|                               |
/ profile-specific information  / переменный размер
|                               |
+---+---+---+---+---+---+---+---+

Profile

Профиль, связанный с CID. Задается так же, как для пакетов IR.

CRC

8-битовое значение контрольной суммы ( см. параграф 5.3.1.1).

Profile-specific information

Содержимое этой части заголовка IR-DYN определяется конкретным профилем и интерпретируется в соответствии с профилем, указанным в поле Profile.

5.2.3. Изначальная обработка в декомпрессоре ROHC

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

При получении декомпрессором пакета типа IR указанный в нем профиль определяет обработку.

  • Если проверка целостности заголовка с помощью 8-битового поля CRC приводит к отказу, пакет недопустимо декомпрессировать и доставлять на вышележащие уровни. Если в контексте указан профиль, логика этого профиля определяет передачу данных обратной связи, если они имеются. Если профиль в контексте не отмечен, логика передачи данных обратной связи (при их наличии) определяется реализацией. Однако может оказаться разумным отказ от каких-либо дальнейших действий, поскольку причиной отказа может быть любая часть заголовка IR, покрываемая контрольной суммой.

При получении декомпрессором пакета IR-DYN указанный в нем профиль определяет обработку данного пакета.

  • Если проверка целостности заголовка с помощью 8-битового поля CRC приводит к отказу, пакет недопустимо декомпрессировать и доставлять на вышележащие уровни. Если в контексте указан профиль, логика этого профиля определяет передачу данных обратной связи, если они имеются. Если профиль в контексте не отмечен, логика передачи данных обратной связи (при их наличии) определяется реализацией. Однако может оказаться разумным отказ от каких-либо дальнейших действий, поскольку причиной отказа может быть любая часть заголовка IR-DYN, покрываемая контрольной суммой.
  • Если контекст еще не был инициализирован, пакет недопустимо декомпрессировать и доставлять на вышележащие уровни. При наличии данных обратной связи логику действий для них определяет профиль, указанный в заголовке IR-DYN (при совпадении 8-битовой контрольной суммы CRC).

При возникновении ошибок разбора пакетов любого типа декомпрессор должен отбрасывать такие пакеты без дальнейшей обработки. Например, поле CID присутствует в заголовке пакета при указанном использовании большого пространства CID для канала ROHC и поле представлено с использованием самоописывающего кодирования с переменным размером (см. параграф 5.3.2); если поле начинается с 110 или 111 это будет вызывать ошибку при разборе, поскольку такое поле не может быть представлено с размером, превышающим 2 октета.

Для профилей рекомендуется запрещать декомпрессору предпринимать попытки декомпрессии для пакетов, содержащих лишь 3-битовую контрольную сумму CRC после полной или частичной инвалидации динамического контекста, пока не будет получен, декомпрессирован и проверен по 7- или 8-битовой контрольной суммы CRC пакет с достаточной информации о динамических полях.

5.2.4. Обратная связь ROHC

Обратная связь обеспечивает компрессору информацию от декомпрессора. Для обратной связи может использоваться любой канал ROHC, работающий в нужном направлении.

Общий формат пакетов ROHC позволяет передавать данные обратной связи с использованием «размывания» (interspersion), «наложения» (piggybacking) (см. [RFC3759]) или их комбинации по любому каналу ROHC. Это обеспечивается за счет перечисленных ниже свойств

Reserved packet type — зарезервированный тип пакетов

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

CID information — информация CID

Данные обратной связи, передаваемые по отдельному каналу, направляются компрессору и интерпретируются им. Для этого в каждом пакете обратной связи содержится информация CID из канала, к которому относится обратная связь. Схема обратной связи в ROHC требует, чтобы канал обратной связи доставлял данные не более, чем одному компрессору. Связь компрессора с обратной связью для конкретного канала выходит за пределы данной спецификации (см. [RFC3759]).

Length information — информация о размере

Размер элемента обратной связи можно определить путем проверки нескольких первых октетов данных. Это позволяет добавлять данные обратной связи «в нагрузку» или объединять несколько элементов обратной связи в один пакет. Информация о размере, таким образом, отвязывает декомпрессор от связанного с ним компрессора на той же стороне, поскольку декомпрессор может извлечь данные обратной связи из сжатого заголовка без разбора его содержимого и передать найденную информацию.

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

5.2.4.1. Формат обратной связи ROHC

ROHC определяет три разных категории сообщений обратной связи — подтверждение (ACK), негативное подтверждение (NACK) и NACK для контекста в целом (STATIC-NACK). Для профилей могут определяться другие типы сообщений.

ACK

Подтверждает успешную декомпрессию пакета и показывает, что декомпрессор считает свой контекст корректным.

NACK

Показывает, что декомпрессор считается динамическую часть контекста или ее отдельные компоненты некорректными.

STATIC-NACK

Показывает, что декомпрессор считает некорректным статический контекст или этот контекст отсутствует.

Обратная связь передается в канал ROHC в виде одного или нескольких (конкатенация) элементов, формат которых показан на рисунке.

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 1   1   1   1   0 |   Code    | тип обратной связи
+---+---+---+---+---+---+---+---+
:             Size              : если Code = 0
+---+---+---+---+---+---+---+---+
:         октет Add-CID         : при малом пространстве CID и (CID != 0)
+---+---+---+---+---+---+---+---+
:                               :
/           large CID           / 1 или 2 октета при
:                               : большом пространстве CID
+---+---+---+---+---+---+---+---+
/         FEEDBACK data         / переменный размер
+---+---+---+---+---+---+---+---+

Code

Значение 0 указыва-ет на присутствие октета Size, 1-7 показывает общий размер полей FEEDBACK data и CID (если оно имеется) в октетах.

Size

Показывает общий размер полей FEEDBACK data и CID (если оно имеется) в октетах.

FEEDBACK data

FEEDBACK-1 или FEEDBACK-2 (см. ниже).

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

Поле большого CID (при его наличии) кодируется, как описано в параграфе 5.3.2 и для его представления недопустимо использовать более 2 октетов.

Поле FEEDBACK может содержать данных в любом из двух показанных ниже форматов.

FEEDBACK-1

        0   1   2   3   4   5   6   7
      +---+---+---+---+---+---+---+---+
      | profile-specific information  |  1 октет
      +---+---+---+---+---+---+---+---+

FEEDBACK-2

        0   1   2   3   4   5   6   7
      +---+---+---+---+---+---+---+---+
      |Acktype|                       |
      +---+---+   profile-specific    /  не менее 2 октетов
      /             information       |
      +---+---+---+---+---+---+---+---+

Acktype: 0 = ACK

1 = NACK

2 = STATIC-NACK

3 резерв (использование недопустимо; приводит к невозможности разбора).

5.2.5. Сегментация ROHC

ROHC определяет простой протокол сегментации. Компрессор может выполнить сегментацию, например, для передачи пакетов, размер которых превосходит заданное для канала значение.

5.2.5.1. Вопросы использования сегментации

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

Протокол сегментации ROHC был разработан в предположении сохранения порядка доставки пакетов между компрессором и декомпрессором, использования для детектирования ошибок только контрольной суммы CRC и отсутствия порядковых номеров. Если нет гарантии упорядоченной доставки, использовать сегментацию ROHC недопустимо.

Протокол сегментации также предполагает, что все сегменты пакета ROHC, относящиеся к одному контексту, принимаются без конфликтов с другими пакетами ROHC в том же канале, включая все пакеты ROHC, относящиеся к другим контекстам. С учетом этого допущения в сегменты не включается информация CID и они, следовательно, не могут быть связаны с соответствующим контекстом, пока не будут получены все сегменты и собран весь блок.

5.2.5.2. Протокол сегментации

Сегментация ROHC применяется к комбинации полей Header и Payload пакетов ROHC, как определено в параграфе 5.2.1.

Формат сегмента показан на рисунке.

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 1   1   1   1   1   1   1 | F |  тип сегмента
+---+---+---+---+---+---+---+---+
/           Segment             /  переменный размер
+---+---+---+---+---+---+---+---+

F

Финальный бит, указывающий последний сегмент восстанавливаемого блока. Октету типа сегмента могут предшествовать поля Padding и/или Feedback. Для сегментов не указывается CID, но информация CID включается в восстановленный блок. В этот блок недопустимо включать заполнение, сегменты или обратную связь.

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

Восстановленный блок показан на рисунке.

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
/            Header             /
+---+---+---+---+---+---+---+---+
:            Payload            :
+---+---+---+---+---+---+---+---+
/              CRC              /  4 октета
+---+---+---+---+---+---+---+---+

Header

См. параграф 5.2.1

Payload

См. параграф 5.2.1

CRC

32-битовое значение CRC вычисляется с использованием полинома, приведенного в параграфе 5.3.1.4.

Если размер восстановленного блока не превышает 4 октетов, проверка CRC завершается отказом или размер блока превышает значение параметра MRRU (см. параграф 5.1.2) для канала, восстановленный блок должен быть отброшен декомпрессором. При совпадении CRC восстановленный блок может быть подвергнут дальнейшей обработке.

5.3. Общие методы кодирования

5.3.1. Контрольные суммы при компрессии заголовка

В этом разделе описан расчет контрольных сумм CRC, используемых ROHC. Для всех значений CRC используется алгоритм, описанный в [RFC1662] и определенный в Приложении ,A к данному документу, с полиномами, заданными в последующих параграфах.

5.3.1.1. 8-битовая сумма CRC в заголовках IR и IR-DYN

Покрытие 8-битовой контрольной суммы в заголовках IR и IR-DYN зависит от профиля, но должно включать, по крайней мере, начальную часть заголовка, завершающуюся полем Profile и включающую CID или октет Add-CID. Обратная связь и заполнение не относятся к заголовку Header (параграф 5.2.1) и, таким образом, не включаются в расчет CRC. В спецификации профилей следует также включать в покрытие CRC все прочую информацию, используемую для инициализации контекста декомпрессора.

Говоря более точно, 8-битовое значение CRC не покрывает полностью исходный несжатый заголовок и, следовательно, не может обеспечить декомпрессору способа проверки результата декомпрессии или корректности контекста декомпрессии в целом. Однако применение контрольных сумм обеспечивает декомпрессору достаточную отказоустойчивость для обновления своего контекста с помощью информации из заголовков IR или IR-DYN.

Полином CRC для 8-битовой контрольной суммы имеет вид

C(x) = 1 + x + x^2 + x^8

При расчете контрольной суммы значение самого поля CRC в заголовке принимается нулевым, а в качестве начального содержимого регистра CRC устанавливаются все 1.

5.3.1.2. 3-битовая сумма CRC в сжатых заголовках

3-битовая контрольная сумма заголовка рассчитывается для всех октетов исходного заголовка до его компрессии.

В качестве начального содержимого регистра CRC устанавливаются все 1.

Для расчета контрольной суммы используется полином

C(x) = 1 + x + x^3

3-битовое значение CRC позволяет декомпрессору проверять результат декомпрессии для небольших сжатых заголовков и обнаруживать повреждения контекста на основе агрегированной вероятности для множества попыток декомпрессии. Однако эти суммы слишком слабы даже для того, чтобы гарантировать отсутствие ошибок в одном заголовке. По этой причине 3-битового значения CRC в сжатом заголовке обычно недостаточно для исправления контекста декомпрессора. Следовательно, профилям рекомендуется воздерживаться от декомпрессии таких заголовков, когда контекст декомпрессора или его часть предполагается некорректным.

5.3.1.3. 7-битовая контрольная сумма в сжатых заголовках

7-битовая контрольная сумма заголовка рассчитывается для всех октетов исходного заголовка до его компрессии .

В качестве начального содержимого регистра CRC устанавливаются все 1.

Для расчета контрольной суммы используется полином

C(x) = 1 + x + x^2 + x^3 + x^6 + x^7

7-битовые значения CRC предназначены для обеспечения декомпрессору возможности проверки результата декомпрессии для больших заголовков и восстановления контекста декомпрессора. 7-битовых значений CRC достаточно для того, чтобы предполагать успешное исправление контекста при декомпрессии одного заголовка. Следовательно, профили могут разрешать декомпрессию заголовка с 7-битовой контрольной суммой даже в предположении повреждения контекста декомпрессора.

5.3.1.4. 32-битовая контрольная сумма сегментации

32-битовые контрольные суммы используются схемой сегментации для проверки восстановленных блоков и, поэтому, рассчитываются для сегментируемого блока, т. е., включают поля Header и Payload пакетов ROHC.

В качестве начального содержимого регистра CRC устанавливаются все 1.

Для расчета контрольной суммы используется полином

C(x) = x^0 + x^1 + x^2 + x^4 + x^5 + x^7 + x^8 + x^10 + x^11 + x^12 + x^16 + x^22 + x^23 + x^26 + x^32

Назначением 32-битовых контрольных сумм CRC является проверка восстановленных блоков.

5.3.2. Самоописывающиеся значения переменного размера

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

Первый бит равен 0: 1 октет.

7 битов передается

десятичное значение до 127

Шестнадцатеричное представление октетов от 00 до 7F

Первые биты равны 10: 2 октета.

14 битов передается

десятичное значение до 16 383

Шестнадцатеричное представление октетов от 80 00 до BF FF

Первые биты равны 110: 3 октета.

21 бит передается

десятичное значение до 2 097 151

Шестнадцатеричное представление октетов от C0 00 00 до DF FF FF

Первые биты равны 111: 4 октета.

29 битов передается

десятичное значение до 536 870 911

Шестнадцатеричное представление октетов от E0 00 00 00 до FF FF FF FF

5.4. ROHC UNCOMPRESSED — без компрессии (профиль 0x0000)

В этом разделе описан профиль ROHC без компрессии, имеющий идентификатор 0x0000.

Профиль 0x0000 обеспечивает способ передачи пакетов IP без их сжатия. Он может использоваться с любыми пакетами, для которых недоступны профили из набора поддерживаемых для канала ROHC или в тех случаях, когда компрессия нежелательна по тем или иным причинам.

После инициализации единственной издержкой при передаче пакетов с использованием Profile 0x0000 является размер CID. Когда несжимаемые пакеты встречаются часто, Profile 0x0000 следует связывать с CID размером 0 или 1 октет. Profile 0x0000 не следует связывать с несколькими CID.

5.4.1. Пакет IR

Пакет инициализации и обновления (IR) для Profile 0x0000 имеет формат, показанный на рисунке.

  0   1   2   3   4   5   6   7
 --- --- --- --- --- --- --- ---
:         октет Add-CID         : для малых CID при (CID != 0)
+---+---+---+---+---+---+---+---+
| 1   1   1   1   1   1   0 |res|
+---+---+---+---+---+---+---+---+
:                               :
/    0-2 octets of CID info     / 1-2 октета для больших CID
:                               :
+---+---+---+---+---+---+---+---+
|         Profile = 0x00        | 1 октет
+---+---+---+---+---+---+---+---+
|              CRC              | 1 октет
+---+---+---+---+---+---+---+---+

res

это поле должно иметь значение 0; в противном случае декомпрес-сор должен отбрасывать пакет.

Profile

0x00

CRC

8-битовое значение CRC, рассчитанное с использованием полинома из параграфа 5.3.1.1. CRC покрывает первый октет IR Header до октета Profile в IR Header, т. е., не включает самого поля CRC. В контрольной сумме также не учитываются предшествующие поля Padding или Feedback и Payload.

Для пакетов IR поле Payload имеет формат, показанный на рисунке.

 --- --- --- --- --- --- --- ---
:                               : (необязательно)
/           IP packet           / переменный размер
:                               :
 --- --- --- --- --- --- --- ---

IP packet

Несжатый пакет IP может быть включен в пакет IR. Декомпрессор определяет присутствие пакета IP по размеру пакета IR.

5.4.2. Нормальный пакет

Пакет Normal представляет собой обычный пакет IP с дополнительной информацией CID. Для пакетов Normal формат, показанный на рисунке справа, соответствует полям Header и Payload (как определено в параграфе 5.2.1).

  0   1   2   3   4   5   6   7
 --- --- --- --- --- --- --- ---
:         октет Add-CID          : для малых CID при (CID != 0)
+---+---+---+---+---+---+---+---+
|   первый октет пакета IP      |
+---+---+---+---+---+---+---+---+
:                               :
/  0-2 октета информации CID    / 1-2 октета для больших CID
:                               :
+---+---+---+---+---+---+---+---+
|                               |
/       остаток пакета IP       / переменный размер
|                               |
+---+---+---+---+---+---+---+---+

Отметим, что первый октет пакета IP начинается с битовой последовательности 0100 (IPv4) или 0110 (IPv6). Это не вызывает конфликтов с какими-либо из зарезервированных типов пакетов.

При использовании в канале малых значений CID и связывании профиля 0x0000 с CID > 0, пакету IP предшествует октет Add-CID. Если на канале используются большие значения CID, идентификатор CID начинается со второго октета комбинированного формата Header/Payload, описанного выше.

Пакет Normal может содержать поле Padding и/или Feedback, как любые другие пакеты ROHC, перед комбинированным полем Header/Payload.

5.4.3. Инициализация контекста

Компрессор инициализирует статический контекст, связанный с профилем UNCOMPRESSED путем передачи пакетов IR (см. параграф 5.4.1). В процессе инициализации контекста компрессору рекомендуется передавать пакеты IR, пока не будет уверенности в том, что декомпрессор получил хотя бы один такой пакет. Подтверждением получения пакета может служить обратная связь от декомпрессора или сведения о характеристиках канала.

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

5.4.4. Работа декомпрессора

При получении пакета IR декомпрессор сначала проверяет его корректность, используя 8-битовое значение CRC.

  • Если проверка завершилась отказом для декомпрессора недопустимо передавать пакет IP вышележащим уровням;
  • при совпадении контрольных сумм декомпрессор
  1. инициализирует контекст, если у него нет корректного контекста для данного CID, связанного с этим профилем,
  2. доставляет пакет IP вышележащим уровням при наличии таковых,
  3. может передать подтверждение ACK.

При получении любых других пакетов декомпрессором в отсутствии требуемого контекста такие пакеты отбрасываются без выполнения с ними каких-либо действий.

При получении пакета Normal и наличии корректного контекста у декомпрессора из него извлекается пакет IP, который передается вышележащим уровням.

5.4.5. Обратная связь

Единственным типом обратной связи для 0x0000 является подтверждение ACK с использованием формата FEEDBACK-1 (см. параграф 5.2.4.1) с нулевым значением октета profile-specific в поле FEEDBACK-1. Формат FEEDBACK-2 не определен для Profile 0x0000.

6. Обзор профилей ROHC (информационный раздел)

Протокол ROHC включает модель и профили. Модель определяет общие для всех профилей механизмы, а профили определяют конкретный алгоритм сжатия и специфичные для профиля форматы пакетов.

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

Профиль ROHC определяет элементы, образующие протокол сжатия, и включает перечисленные ниже элементы.

Форматы пакетов

  • Bits-on-the-wire — биты в линии

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

  • Field encodings — кодирование полей

Биты и группы битов из схемы формата пакетов, называемые сжатыми полями (Compressed), представляют собой специфичный для метода результат кодирования данного поля в конкретном формате пакета. Эти методы кодирования определяются профилем.

  • Updating properties — свойства обновления

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

  • Verification — верификация

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

Управление контекстом

  • Robustness logic — логика отказоустойчивости

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

  • Repair mechanism — механизм исправления

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

7. Благодарности

Авторы выражают свою признательность всем, кто внес свой вклад в предшествующие работы по ROHC, и особенно авторам документа RFC 3095 [RFC3095], который послужил технической основой для данного документа. Спасибо всем, кто внес свои правки и разъяснения в корректирующий RFC 3095 документ [RFC4815], — их технические предложения (когда они были применимы) включены в этот документ. Спасибо Jani Juvan за обнаружение несоответствия между структурой обратной связи, описанной в [RFC4995], и аналогичной структурой из [RFC3095] — это сделало необходимым обновление [RFC4995].

Назначенными рабочей группой рецензентами документа были Carl Knutsson, Biplab Sarkar и Robert Stangarone — они принимали участие в работе над документом вплоть до ее завершения. Отдельная благодарность Bert Wijnen и Brian Carpenter за их комментарии в процессе IETF Last Call.

8. Согласование с IANA

Реестр IANA «RObust Header Compression (ROHC) Profile Identifiers» [ROHC-ids] был создан RFC 3095 [RFC3095]. Правила распределения, предложенные в RFC 3095, включают нижеперечисленное.

Идентификатор профиля ROHC представляет собой неотрицательное целое число. Во многих протоколах согласования оно представляется 16-битовым значением. В результате сжатия этих идентификаторов в пакетах ROHC младшие 8 битов идентификатора имеют специальное значение — два идентификатора профилей, совпадающие по восьми младшим битам, следует выделять лишь в тех случаях, когда идентификатор с большим значением предназначен для замены идентификатора с меньшим значением. Для того, чтобы не упустить это из виду, идентификаторы следует указывать в шестнадцатеричном формате (например, идентификатор 0x1234 можно выделить взамен 0x0A34).

Идентификатор профиля Применение Документ
0x0000 ROHC uncompressed RFC 5795
0x0001 ROHC RTP RFC 3095
0x0002 ROHC UDP RFC 3095
0x0003 ROHC ESP RFC 3095
0x0004 ROHC IP RFC 3843
0x0005 ROHC LLA RFC 3242
0x0105 ROHC LLA with R-mode RFC 3408
0x0006 ROHC TCP RFC 4996
0x0007 ROHC RTP/UDP-Lite RFC 4019
0x0008 ROHC UDP-Lite RFC 4019
0x0101 ROHCv2 RTP RFC 5225
0x0102 ROHCv2 UDP RFC 5225
0x0103 ROHCv2 ESP RFC 5225
0x0104 ROHCv2 IP RFC 5225
0x0107 ROHCv2 RTP/UDP-Lite RFC 5225
0x0108 ROHCv2 UDP-Lite RFC 5225

Приведенные далее правила были включены в [RFC5226]. Политика IANA при выделении новых значений идентификаторов профиля должна соответствовать процедуре Specification Required11 — значения и их трактовки должны быть документированы в RFC или аналогичном документе, доступном по известной и постоянной ссылке, достаточно подробно для обеспечения возможности взаимодействия независимых реализаций. В младших 8 битах идентификатора значения от 0 до 127 резервируются для спецификаций проектов стандартов IETF, диапазон от 128 до 254 доступен для других спецификаций, удовлетворяющих требованиям (таких, как информационные RFC). Значение 255 в младших восьми битах зарезервировано для будущих расширений данной спецификации.

Выделенные идентификаторы профилей перечислены в таблице справа.

Для новых профилей потребуется выделение агентством IANA новых идентификаторов, но этот документ не требует от IANA каких-либо действий.

9. Вопросы безопасности

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

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

Атаки на службы (DoS12) будут возможны, если атакующий способен ввести в канал обманные пакеты IR, IR-DYN или пакеты обратной связи, снижая тем самым эффективность компрессии. Однако атакующий с возможностью вставки на канальном уровне произвольных пакетов способен нанести более серьезный урон, нежели снижение эффективности компрессии заголовков.

10. Литература

10.1. Нормативные документы

[RFC2119] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, March 1997.

10.2. Дополнительная литература

[CRTP-eval] Degermark, M., Hannu, H., Jonsson, L., and K. Svanbro, «»Evaluation of CRTP Performance over Cellular Radio Networks», IEEE Personal Communication Magazine, Volume 7, number 4, pp. 20-25, August 2000.», 2000.

[RFC0768] Postel, J., «User Datagram Protocol», STD 6, RFC 768, August 1980.

[RFC0791] Postel, J., «Internet Protocol», STD 5, RFC 791, September 1981.

[RFC0793] Postel, J., «Transmission Control Protocol», STD 7, RFC 793, September 1981.

[RFC1144] Jacobson, V., «Compressing TCP/IP headers for low-speed serial links», RFC 1144, February 1990.

[RFC1662] Simpson, W., «PPP in HDLC-like Framing», STD 51, RFC 1662, July 1994.

[RFC2460] Deering, S. and R. Hinden, «Internet Protocol, Version 6 (IPv6) Specification», RFC 2460, December 1998.

[RFC2507] Degermark, M., Nordgren, B., and S. Pink, «IP Header Compression», RFC 2507, February 1999.

[RFC2508] Casner, S. and V. Jacobson, «Compressing IP/UDP/RTP Headers for Low-Speed Serial Links», RFC 2508, February 1999.

[RFC3095] Bormann, C., Burmeister, C., Degermark, M., Fukushima, H., Hannu, H., Jonsson, L-E., Hakenberg, R., Koren, T., Le, K., Liu, Z., Martensson, A., Miyazaki, A., Svanbro, K., Wiebke, T., Yoshimura, T., and H. Zheng, «Robust Header Compression (ROHC): Framework and four profiles: RTP, UDP, ESP, and uncompressed», RFC 3095, July 2001.

[RFC3096] Degermark, M., «Requirements for robust IP/UDP/RTP header compression», RFC 3096, July 2001.

[RFC3241] Bormann, C., «Robust Header Compression (ROHC) over PPP», RFC 3241, April 2002.

[RFC3545] Koren, T., Casner, S., Geevarghese, J., Thompson, B., and P. Ruddy, «Enhanced Compressed RTP (CRTP) for Links with High Delay, Packet Loss and Reordering», RFC 3545, July 2003.

[RFC3550] Schulzrinne, H., Casner, S., Frederick, R., and V. Jacobson, «RTP: A Transport Protocol for Real-Time Applications», STD 64, RFC 3550, July 2003.

[RFC3759] Jonsson, L-E., «RObust Header Compression (ROHC): Terminology and Channel Mapping Examples», RFC 3759, April 2004.

[RFC4224] Pelletier, G., Jonsson, L-E., and K. Sandlund, «Robust Header Compression (ROHC): ROHC over Channels That Can Reorder Packets», RFC 4224, January 2006.

[RFC4815] Jonsson, L-E., Sandlund, K., Pelletier, G., and P. Kremer, «RObust Header Compression (ROHC): Corrections and Clarifications to RFC 3095», RFC 4815, February 2007.

[RFC4995] Jonsson, L-E., Pelletier, G., and K. Sandlund, «The RObust Header Compression (ROHC) Framework», RFC 4995, July 2007.

[RFC4996] Pelletier, G., Sandlund, K., Jonsson, L-E., and M. West, «RObust Header Compression (ROHC): A Profile for TCP/IP (ROHC-TCP)», RFC 4996, July 2007.

[RFC5225] Pelletier, G. and K. Sandlund, «RObust Header Compression Version 2 (ROHCv2): Profiles for RTP, UDP, IP, ESP and UDP-Lite», RFC 5225, April 2008.

[RFC5226] Narten, T. and H. Alvestrand, «Guidelines for Writing an IANA Considerations Section in RFCs», BCP 26, RFC 5226, May 2008.

[ROHC-ids] IANA, «RObust Header Compression (ROHC) Profile Identifiers», <http://www.iana.org>.

Приложение A. Алгоритм CRC

   #!/usr/bin/perl -w
   use strict;
   #=================================
   #
   # ROHC CRC demo - Carsten Bormann cabo@tzi.org 2001-08-02
   #
   # Эта маленькая программа показывает 4 типа CRC, используемых в 3095
   # для отказоустойчивого сжатия заголовков. Введите данные в 
   # шестнадцатеричном формате и нажмите Control+D.
   #
   #---------------------------------
   #
   # utility
   #
   sub dump_bytes($) {
       my $x = shift;
       my $i;
       for ($i = 0; $i < length($x); ) {
     printf("%02x ", ord(substr($x, $i, 1)));
     printf("n") if (++$i % 16 == 0);
       }
       printf("n") if ($i % 16 != 0);
   }

   #---------------------------------
   #
   # Алгоритм расчета CRC
   #
   sub do_crc($$$) {
       my $nbits = shift;
       my $poly = shift;
       my $string = shift;

       my $crc = ($nbits == 32 ? 0xffffffff : (1 << $nbits) - 1);
       for (my $i = 0; $i < length($string); ++$i) {
         my $byte = ord(substr($string, $i, 1));
         for( my $b = 0; $b < 8; $b++ ) {
           if (($crc & 1) ^ ($byte & 1)) {
             $crc >>= 1;
             $crc ^= $poly;
           } else {
           $crc >>= 1;
           }
           $byte >>= 1;
         }
       }

       printf "%2d bits, ", $nbits;
       printf "CRC: %02xn", $crc;
   }

   #---------------------------------
   #
   # Тестирование
   #
   $/ = undef;
   $_ = <>;         # читать до конца файла
   my $string = ""; # извлечь все шестнадцатеричное
   s/([0-9a-fA-F][0-9a-fA-F])/$string .= chr(hex($1)), ""/eg;
   dump_bytes($string);

   #---------------------------------
   #
   # 32-битовое значение CRC для сегментации
   # Отметим, что в тексте предполагается дополнение, как в PPP
   # (это отличается от 8, 7 и 3-битовых CRC)
   #
   #      C(x) = x^0 + x^1 + x^2 + x^4 + x^5 + x^7 + x^8 + x^10 +
   #             x^11 + x^12 + x^16 + x^22 + x^23 + x^26 + x^32
   #
   do_crc(32, 0xedb88320, $string);

   #---------------------------------
   #
   # 8-битовая сумма для IR/IR-DYN
   #
   #      C(x) = x^0 + x^1 + x^2 + x^8
   #
   do_crc(8, 0xe0, $string);

   #---------------------------------
   #
   # 7-битовая сумма для FO/SO
   #
   #      C(x) = x^0 + x^1 + x^2 + x^3 + x^6 + x^7
   #
   do_crc(7, 0x79, $string);

   #---------------------------------
   #
   # 3-битовая сумма FO/SO
   #
   #      C(x) = x^0 + x^1 + x^3
   #
   do_crc(3, 0x6, $string);

Адреса авторов

Kristofer Sandlund

Ericsson

Box 920

Lulea SE-971 28

Sweden

Phone: +46 (0) 8 404 41 58

EMail: kristofer.sandlund@ericsson.com

Ghyslain Pelletier

Ericsson

Box 920

Lulea SE-971 28

Sweden

Phone: +46 (0) 8 404 29 43

EMail: ghyslain.pelletier@ericsson.com

Lars-Erik Jonsson

Optand 737

Ostersund SE-831 92

Sweden

Phone: +46 76 830 03 12

EMail: lars-erik@lejonsson.com


Перевод на русский язык

Николай Малых

nmalykh@gmail.com

1Internet Engineering Task Force.
2Internet Engineering Steering Group.
3Voice over IP — голосовая связь через IP.
4Compressed TCP.
5IP header compression.
6Synchronization source.
7Context Identifier.
8Master sequence number — основной порядковый номер.
9Maximum Reconstructed Reception Unit — максимальный восстанавливаемый блок для приема.
10Initialization and Refresh.
11Требуется спецификация.
12Denial-of-service.

 

Рубрика: RFC | Оставить комментарий

RFC 5810 Forwarding and Control Element Separation (ForCES) Protocol Specification

Internet Engineering Task Force (IETF)                     A. Doria, Ed.
Request for Comments: 5810                Lulea University of Technology
Category: Standards Track                             J. Hadi Salim, Ed.
ISSN: 2070-1721                                                     Znyx
                                                            R. Haas, Ed.
                                                                     IBM
                                                        H. Khosravi, Ed.
                                                                   Intel
                                                            W. Wang, Ed.
                                                                 L. Dong
                                           Zhejiang Gongshang University
                                                                R. Gopal
                                                                   Nokia
                                                              J. Halpern
                                                              March 2010

Спецификация протокола ForCES

Forwarding and Control Element Separation (ForCES) Protocol Specification

PDF

Аннотация

В этом документе описан протокол разделения элементов управления и пересылки ForCES1. Протокол ForCES служит для коммуникаций между элементами управления CE2 и элементами пересылки FE3 в элементах сети ForCES NE4. Данная спецификация соответствует требованиям к протоколу ForCES, определенным в RFC 3654. В дополнение к протоколу ForCES данная спецификация определяет также требования к уровню транспортного отображения TML5.

Статус документа

Документ относится к категории Internet Standards Track.

Документ является результатом работы IETF6 и представляет согласованный взгляд сообщества IETF. Документ прошел открытое обсуждение и был одобрен для публикации IESG7. Дополнительную информацию о стандартах Internet можно найти в разделе 2 в RFC 5741.

Информацию о текущем статусе документа, ошибках и способах обратной связи можно найти по ссылке http://www.rfc-editor.org/info/rfc5810.

Авторские права

Авторские права (Copyright (c) 2010) принадлежат IETF Trust и лицам, указанным в качестве авторов документа. Все права защищены.

К этому документу применимы права и ограничения, перечисленные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включенные в этот документ, распространяются в соответствии с упрощенной лицензией BSD, как указано в параграфе 4.e документа Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

1. Введение

Разделение элементов управления и пересылки (ForCES) определяет архитектурную модель и сопутствующие протоколы для стандартизации обмена информацией между уровнем правления (control plane) и уровнем пересылки (forwarding plane) в элементах сети ForCES (ForCES NE). В RFC 3654 определены требования к ForCES, а в RFC 3746 — модель ForCES. Хотя в архитектуре ForCES могу применяться многочисленные протоколы, в этом документе термины «протокол ForCES» и «протокол» относятся к только протоколу, служащему для стандартизации информационного обмена между элементами управления CE и элементами пересылки FE.

Модель ForCES FE [RFC5812] представляет формальный способ определения логических функциональных блоков FE LFB с использованием XML. Конфигурационные компоненты, возможности и события LFB определяются при формальном создании LFB. Логические блоки LFB внутри FE согласованно контролируются стандартизованным способом по протоколу ForCES.

Этот документ определяет спецификацию протокола ForCES, который работает в режиме «ведущий-ведомый» (master-slave), где FE играют роль ведомых, а CE — ведущего. Протокол включает команды для транспортировки конфигурационных данных LFB, организации связей (association), данных состояния, уведомлений о событиях и т. п.

В разделе 3 приведен глоссарий используемых в документе терминов.

Раздел 4 содержит обзор протокола с обсуждением модели и описанием протокольного уровня PL8, уровня транспортного отображения TML и механизмов протокола ForCES. В параграфе 4.4 рассмотрено несколько протокольных сценариев и приведено описание обмена сообщениями.

Документ не определяет TML, но в разделе 5 описаны услуги, которые TML должен обеспечивать (требования к TML).

Протокол ForCES определяет общий заголовок для всех сообщений. Этот заголовок описан в параграфе 6.1, а протокольные сообщения определены в разделе 7.

В разделе 8 описана поддержка протоколом механизмов высокой доступности, включая избыточность (redundancy) и отказоустойчивость (fail over).

В разделе 9 определены механизмы защиты, обеспечиваемые уровнями PL и TML.

2. Термины и соглашения

2.1. Уровни требований

Ключевые слова необходимо (MUST), недопустимо (MUST NOT), требуется (REQUIRED), нужно (SHALL), не следует (SHALL NOT), следует (SHOULD), не нужно (SHOULD NOT), рекомендуется (RECOMMENDED), не рекомендуется (NOT RECOMMENDED), возможно (MAY), необязательно (OPTIONAL) в данном документе интерпретируются в соответствии с [RFC2119].

2.2. Обозначения

В таблицах 1 и 2 используются приведенные ниже обозначения.

(value)+ — один или несколько экземпляров value;

(value)* — необязательные экземпляры value.

2.3. Целые числа

Все целые числа представляются беззнаковыми двоичными значениями подходящего размера.

3. Определения

В этом документе используются термины, определенные для требований к ForCES в [RFC3654] и модели ForCES в [RFC3746]. Определения для удобства повторены.

Addressable Entity (AE) – адресуемый объект (элемент)

Физическое сетевое устройство, которое непосредственно адресуется в данной технологии соединения. Например, в сетях IP — это устройства, к которым можно обращаться по адресу IP, а в матрице коммутации (switch fabric) — это устройства, к которым можно обращаться по номеру порта в матрице.

Control Element (CE) – элемент управления

Логический объект, который реализует протокол ForCES и инструктирует один или множество FE по части обработки пакетов. Функциональность CE включает исполнение протоколов управления и сигнализации.

CE Manager (CEM) – менеджер элементов управления

Логический объект, который отвечает за генерацию базовых задач управления CE. Используется, в частности, на этапе до объединения (pre-association phase) для определения FE, с которым CE следует взаимодействовать. Этот процесс называется обнаружением FE и может включать определение менеджером CE возможностей доступных FE.

Data Path – путь (передачи) данных

Концептуальный путь, по которому пакеты проходят через уровень пересылки в FE.

Forwarding Element (FE) – элемент пересылки

Логический элемент, реализующий протокол ForCES. Элементы FE используют базовое оборудование для обработки каждого пакета и управляются (контролируются) одним или множеством CE по протоколу ForCES.

FE Model – модель элемента пересылки

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

FE Manager (FEM) – менеджер FE

Логический элемент, которые работает в фазе до объединения и отвечает за определение CE, с которыми элементу FE следует взаимодействовать. Этот процесс называется обнаружением CE и может включать определение менеджером FE возможностей доступных CE. Менеджер FE может применять все, что угодно от статической конфигурации до протокола фазы до объединения (см. ниже) для определения используемого CE. Однако протокол фазы до объединения выходит за рамки документа. Будучи логическим устройством менеджер FE может быть физически объединен с любыми логическими элементами, упомянутыми в этом разделе, типа FE.

ForCES Network Element (NE) – элемент сети ForCES

Объект, состоящий из одного или множества CE и одного или множества FE. Для внешних наблюдателей NE представляется единой точкой управления. Обычно NE скрывает свою внутреннюю структуру от внешних наблюдателей.

High Touch Capability – работа с верхними уровнями

Этот термин обозначает возможности некоторых устройство пересылки (forwarder) выполнять операции над содержимым или заголовками пакетов, на основе данных, не входящих в заголовок IP. Примерами таких возможностей служат правила качества обслуживания (QoS), виртуальные частные сети, межсетевое экранирование, распознавание содержимого L7.

Inter-FE Topology – внешняя топология FE

См. FE Topology.

Intra-FE Topology – внутренняя топология FE

См. LFB Topology.

LFB (Logical Function Block) – логический функциональный блок

Базовый блок, с которым работает протокол ForCES. LFB — это четко определенный, логически разделяемый функциональный блок, который размещается в FE и управляется CE по протоколу ForCES. LFB может размещаться в пути данных FE и обрабатывать потоки, а может быть чистым объектом управления и настройки FE, с которым работает CE. Отметим, что LFB является функционально точной абстракцией возможностей обработки FE, а не точным аппаратным представлением реализации FE.

FE Topology – топология FE

Представление соединений между множеством FE в одном NE. Иногда это называют внешней топологией FE, чтобы отличать от внутренней топологии FE (т. е. топологии LFB).

LFB Class and LFB Instance – класс и экземпляр LFB

LFB делятся на классы. Экземпляр LFB представляет существование класса (или типа) LFB. В FE может присутствовать множество экземпляров одного класса (или типа) LFB. Класс LFB представляется идентификатором класса и экземпляром LFB, представленным идентификатором экземпляра. В результате идентификатор класса и связанный с ним идентификатор экземпляра однозначно указывают наличие LFB.

LFB Meta Data – метаданные LFB

Метаданные служат для передачи информации о состоянии на уровне отдельного пакета из одного блока LFB в другой, но без передачи через сеть. Модель FE определяет для таких данных идентификацию, обработку, и восприятие (потребление) другими LFB. Модель определяет функциональность, но не задает представления метаданных внутри реализации.

LFB Component – компонента LFB

Рабочие параметры LFB, которые должны быть видимы для элементов CE и концептуально заданы моделью FE как компоненты LFB. Эти компоненты включают, например, флаги, аргументы отдельных параметров, комплексные аргументы и таблицы, которые элемент CE может читать и/или записывать с помощью протокола ForCES (см. ниже).

LFB Topology – топология LFB

Представление логических связей между экземплярами LFB и их размещения в пути данных внутри одного элемента FE. Иногда используется термин «внутренняя топология FE», но не следует путать ее с топологией соединений между FE (inter-FE topology).

Pre-association Phase – фаза до объединения

Интервал времени, в течение которого менеджер FE (см. ниже) и менеджер CE (см. ниже) определяют каким FE и CE следует быть частью одного сетевого элемента. Все разделение PFE и PCE происходит на этом этапе.

Post-association Phase – фаза после объединения

Интервал времени, в течение которого FE знает управляющие им устройства CE и наоборот, включая интервал, в течение которого CE и FE организуют связи между собой.

ForCES Protocol – протокол ForCES

Хотя архитектура ForCES может включать множество протоколов, термины «протокол» и «протокол ForCES» относятся к опорным точкам (интерфейсам) Fp м модели ForCES [RFC3746]. Этот протокол не применяется для коммуникаций между парами элементов CE, парами элементов FE или менеджерами FE и CE. Протокол ForCES в основном работает в режиме «ведущий-ведомый», где элементы FE являются ведомыми, а CE — ведущими. Этот документ задает спецификацию протокола ForCES.

ForCES Protocol Layer (ForCES PL) – уровень протокола ForCES

Уровень архитектуры протокола ForCES, который определяет протокольные сообщения ForCES, схему передачи состояний протокола и архитектуру самого протокола ForCES (включая требования ForCES TML, как показано ниже). Спецификация ForCES PL также задана в этом документе.

ForCES Protocol Transport Mapping Layer (ForCES TML) — уровень транспортного отображения ForCES

Уровень архитектуры протокола ForCES, которые использует возможности существующих транспортных протоколов для решения задач доставки протокольных сообщений, таких как отображения этих сообщений на различные транспортные среды (TCP, IP, ATM, Ethernet и пр.), обеспечения гарантий доставки, групповой адресации, сохранения порядка и т. п. Спецификации ForCES TML задаются в отдельных документах ForCES для каждого типа TML.

4. Обзор

Читателям рекомендуется обратиться к документу [RFC3746] и, в частности, к его разделам 3 и 4, где приведен обзор архитектуры и описано протокол ForCES в рамках этой архитектуры. Содержимое упомянутого документа и данного раздела могут перекрываться в целях обеспечения ясности. Этот документ является полномочным для протокола, а [RFC3746] — для архитектуры.

4.1. Схема протокола

Рисунок 1, заимствованный из описания архитектуры, показывает NE с двумя элементами CE и двумя FE.

                       ---------------------------------------
                       | Сетевой элемент ForCES              |
--------------   Fc    | --------------      --------------  |
| CE Manager |---------+-|     CE 1   |------|    CE 2    |  |
--------------         | |            |  Fr  |            |  |
      |                | --------------      --------------  |
      | Fl             |         |  |    Fp       /          |
      |                |       Fp|  |----------| /           |
      |                |         |             |/            |
      |                |         |             |             |
      |                |         |     Fp     /|----|        |
      |                |         |  /--------/      |        |
--------------     Ff  | --------------      --------------  |
| FE Manager |---------+-|     FE 1   |  Fi  |     FE 2   |  |
--------------         | |            |------|            |  |
                       | --------------      --------------  |
                       |   |  |  |  |          |  |  |  |    |
                       ----+--+--+--+----------+--+--+--+-----
                           |  |  |  |          |  |  |  |
                           |  |  |  |          |  |  |  |
                             Fi/f                   Fi/f
    Fp — интерфейс CE-FE
    Fi — интерфейс FE-FE
    Fr — интерфейс CE-CE
    Fc — интерфейс между CE Manager и CE
    Ff — интерфейс между FE Manager и FE
    Fl — интерфейс между CE Manager и FE Manager
    Fi/f — внешний интерфейс FE

Рисунок 1. Архитектура ForCES.


Областью действия протокола ForCES являются опорные точки (интерфейсы) Fp. Опорные точки настройки конфигурации элементов протокола Fc и Ff также играют роль при загрузке протокола ForCES. Настройка конфигурации элементов протокола (опорные точки Fc, Ff и Fl в [RFC3746]) выходит за рамки протокола ForCES, но будет упоминаться в этом документе при рассмотрении FEM и CEM, поскольку это является частью фазы протокола pre-association (до объединения).

На рисунке 2 представлена детализация интерфейса Fp с помощью примера, включающего сетевой элемент MPLS с поддержкой QoS.

-------------------------------------------------
|       |       |       |       |       |       |
|OSPF   |RIP    |BGP    |RSVP   |LDP    |. . .  |
|       |       |       |       |       |       |
-------------------------------------------------
|               Интерфейс ForCES                |
-------------------------------------------------
                        ^   ^
            Управляющие |   | Пакеты 
              сообщения |   | данных
                 ForCES |   | (например, маршрутизации)
                        v   v
-------------------------------------------------
|               Интерфейс ForCES                |
-------------------------------------------------
|       |       |       |       |       |       |
|LPM Fwd|Meter  |Shaper |NAT    |Classi-|. . .  |
|       |       |       |       |fier   |       |
-------------------------------------------------
|                Ресурсы FE                     |
-------------------------------------------------

Рисунок 2. Примеры функций CE и FE.


Интерфейс ForCES, показанный на рисунке 2, состоит из двух частей — PL и TML, как показано на рисунке 3.

Уровень PL фактически является протоколом ForCES. Его семантика и схема сообщений определяются в этом документе. Уровень TML требуется для соединения между двумя ForCES PL, как показано на рисунке3. TML выходит за рамки этого документа, но входит в ForCES. Данный документ определяет требования PL, которые должны выполняться уровнем TML.

Уровни PL и TML стандартизуются IETF. Несмотря на определение одного PL, предполагается стандартизация различных TML. Для обеспечения взаимодействия между TML в элементах CE и FE предполагается их соответствие одному определению.

При передаче PL доставляет свои сообщения уровню TML. Локальный уровень TML доставляет сообщение TML получателя, а тот передает их уровню PL получателя.

+------------------------------------------------
|               CE PL                           |
+------------------------------------------------
|              CE TML                           |
+------------------------------------------------
                          ^
                          |
            Сообщения     | (т. е. данные ForCES
            ForCES PL     |  + пакеты управления)
            с конкретной  |
            инкапсуляцией |
            и транспортом |
            TML           |
                          |
                          v
+------------------------------------------------
|              FE TML                           |
+------------------------------------------------
|               FE PL                           |
+------------------------------------------------

Рисунок 3. Интерфейс ForCES.


4.1.1. Уровень протокола (PL)

PL является общим для всех реализации ForCES и стандартизуется IETF в соответствии с данным документом. PL отвечает за привязку (ассоциацию FE или CE к сетевому элементу NE, а также за разрыв таких ассоциаций (отсоединение). FE использует уровень PL для передачи событий, на которые задана подписка, в CE PL, а также откликов на различные запросы состояния со стороны CE PL. Элемент CE настраивает рабочие параметры FE и связанных с ним LFB, используя уровень PL. Кроме того, CE может передавать разные запросы элементам FE для их активации или отключения, изменения параметров HA10, подписки на определенные события и т. п. Более подробное описание этого приведено в разделе 7.

4.1.2. Уровень транспортного отображения (TML)

Уровень TML доставляет сообщения PL. С TML связаны вопросы обеспечения на транспортном уровне гарантированной доставки, контроля перегрузок, групповой адресации, соблюдения порядка и т. п. Предполагается стандартизация более одного уровня TML. Разные TML могут варьировать свои реализации с учетом возможностей базовой среды и транспорта. Однако стандартизация каждого TML будет гарантировать взаимодействие в случае поддержки конечными точками одного TML. Все реализации протокольного уровня ForCES должны обеспечивать переносимость между разными TML, поскольку все TML должны иметь на верхнем уровне одинаковую семантику, определенную в этом документе.

4.1.3. Интерфейс FEM/CEM

Компоненты FEM и CEM нужны на этапе организации и настройки как PL так TML, но не входят в протокол ForCES. Лучше всего рассматривать их как настройку и параметризацию PL и TML до того, как эти уровни станут активными (или начнут работать). В простейшем случае элемент FE или CE считывает конфигурацию из файла. В RFC 3746 приведено более подробное описание возможного использования FEM и CEM. Фаза pre-association, где могут применяться CEM и FEM, кратко описана в параграфе 4.2.1.

Примером того, что может быть настроено с помощью FEM/CEM, являются параметры уровня TML:

  1. организация соединения TML (например, используемый адрес IP, транспортный режим и т. п.);

  2. ID для FE (FEID) или CE (CEID), который также будет вводиться в фазе pre-association;

  3. параметры защиты типа ключей и т. п.;

  4. параметры организации соединения.

Примером параметров организации соединения могут быть:

  • простые параметры — передача до трех сообщений каждую секунду;

  • сложные параметры — передача до 4 сообщения с экспоненциально растущим интервалом.

4.2. Фазы протокола ForCES

Протокол ForCES, применительно к элементам NE, включает две фазы — pre-association, где происходит настройка, инициализация и загрузка уровней TML и PL, а также post-association, где протокол ForCES манипулирует параметрами FE.

После организации связи (ассоциации) FE может пересылать пакеты в зависимости от конфигурации его конкретных LFB. Элемент FE, связанный с CE, будет продолжать пересылку пакетов, пока не получит сообщения Association Teardown или не потеряет связь. Несвязанный FE может продолжать передачу пакетов при поддержке им свойства высокой доступности. Дополнительные детали приведены в разделе 8 и не рассматриваются здесь до четкого разъяснения основ.

Смена состояний FE контролируется с помощью компоненты FE Object LFB FEState, определенной в параграфе 5.1 [RFC5812] и описанной в параграфе 7.3.2 данного документа.

FE инициализируется в состоянии FEState OperDisable. Когда элемент FE готов для обработки пакетов в пути данных, он переводит себя в состояние OperEnable.

                CE передает Association Setup
    +---->--->------------>---->---->---->-------->----+
    |                                                  Y
    ^                                                  |
    |                                                  Y
+---+--------+                                     +-------------+
|            |                                     |             |
|Фаза FE pre-|  CE передает Association Teardown   |Фаза FE post-|
|association |<------- <------<-----<------<-------+ association |
|            |                                     |             |
+------------+                                     +-------------+
      ^                                                Y
      |                                                |
      +-<---<-------<-----<------<----<---------<------+
                     FE теряет привязку

Рисунок 4. Фазы протокола FE.


Элемент CE может принять решение о приостановке работы FE, находящегося в состоянии OperEnable, с помощью установки FEState AdminDisable. Элемент FE будет сохранять состояние AdminDisable до явного указания со стороны CE о переходе в состояние OperEnable.

Когда элемент FE теряет связь с CE, он может перейти в фазу, если это задано политикой. Для корректного перехода FE в состояние AdminDisable элемент должен прекратить пересылку пакетов и это может влиять на множество LFBS. Решение этой задачи выходит за рамки данной спецификации.

4.2.1. До объединения

Интерфейс ForCES настраивается в фазе pre-association. В простом варианте конфигурация задается статически и обычно считывается из файла. Все параметры ассоциации становятся известными по завершении фазы pre-association. Для получения конфигурационных параметров могут использоваться протоколы типа DHCP вместо считывания данных из конфигурационного файла. Отметим, что это все равно считается статической фазой pre-association. Динамическая настройка конфигурации может выполняться с использованием интерфейсов Fc, Ff и Fl (см. [RFC3746]). Производители могут применять фирменные протоколы обнаружения для передачи параметров. По сути, здесь приводятся лишь рекомендации, а детали отдаются на откуп разработчикам.

Ниже приведены рисунки из документа с описанием схемы, показывающие пример фазы до объединения.


<---интерф. Ff--->                <--интерф. Fc-->
FE Manager      FE                CE Manager    CE
 |              |                 |             |
 |              |                 |             |
(обмен для защиты)               (обмен для защиты)
1|<------------>| аутентификация 1|<----------->| аутентификация
 |              |                 |             |
(FE ID, компоненты)              (CE ID, компоненты)
2|<-------------| запрос         2|<------------|запрос
 |              |                 |             |
3|------------->| отклик         3|------------>|отклик
(соответствующий CE ID)          (соответствующий FE ID)
 |              |                 |             |
 |              |                 |             |

Рисунок 5. Пример обмена сообщениями через интерфейсы Ff и Fc.

<----------интерфейс Fl------------>            |
FE Manager      FE               CE Manager     CE
 |              |                 |             |
 |              |                 |             |
(обмен для защиты)                |             |
1|<------------------------------>|             |
 |              |                 |             |
 (список CE и их компонент)                     |
2|<-------------------------------|             |
 |              |                 |             |
(список FE и их компонент)                      |
3|------------------------------->|             |
 |              |                 |             |
 |              |                 |             |

Рисунок 6. Пример обмена сообщениями через интерфейс Fl.


До перехода в фазу объединения FEM будет организовывать контакт с компонентой CEM. Инициализация интерфейса ForCES завершена, проверка подлинности и определение возможностей также могут быть завершены. Элементы FE и CE будут иметь всю информацию, нужную при соединении для настройки, учета, идентификации и проверки подлинности. По окончании этого этапа обе стороны будут иметь все требуемые параметры протокола типа таймеров и пр. Интерфейс Fl может продолжать работу в фазе объединения и может применяться для отсоединения элементов FE или CE. Конкретные взаимодействия CEM и FEM, которые относятся к фазе pre-association, выходят за рамки спецификации и не будут далее рассматриваться. Читателю рекомендуется обратиться к [RFC3746].

4.2.2. После объединения

В этой фазе компоненты FE и CE взаимодействуют по протоколу ForCES (PL на основе TML), как определено в этом документе. Здесь имеются три субфазы:

  • этап создания ассоциации;

  • этап наличия ассоциации (связи);

  • этап потери ассоциации.

4.2.2.1. Этап создания ассоциации

FE пытается присоединиться к элементу NE, попытка может быть принята или отвергнута. После получения доступа в NE происходит обмен информацией о возможностях по запросу от CE к FE. После получения CE сведений о возможностях FE элемент CE может предложить начальную конфигурацию (возможно для восстановления состояния), а также запросить некоторые компоненты LFB или самого FE.

Более подробная информация приведена в параграфе 4.4.

При успешном завершении этого этапа FE присоединяется к NE и переходит на этап наличия связи (Established Stage).

4.2.2.2. Этап наличия ассоциации

На этом этапе FE постоянно получает обновления и запросы. FE может также передавать асинхронные уведомления о событиях элементу CE и синхронные уведомления heartbeat, если это задано. Этот этап продолжается по потери связности или прерывания ассоциации по инициативе CE или FE.

Поведение протокола на этом этапе подробно описано в параграфе 4.4.

4.2.2.3. Этап потери ассоциации

На этом этапе CE или FE (или оба элемента) сообщает другой стороне об потере ассоциации. Это может произойти по инициативе любой из сторон (административные причины) или в результате потери связности или иных технических причин.

Определена основа LFB, называемая FEPO11 (см. Приложение B и параграф 7.3.1). FEPO задает различные таймеры, которые могут применяться в месте с чувствительным к трафику механизмом heartbeat (параграф 4.3.3) для обнаружения потери связности.

Потеря связности между TML не указывает потерю ассоциации между соответствующими уровнями PL. Если TML не может восстановить утраченный транспорт до завершения отсчета заданных FEPO таймеров, связанных с FE, ассоциация между соответствующими уровнями PL будет потеряна.

FEPO определяет несколько правил, которые могут быть заданы для управления поведением в случае потери ассоциации. Заданная FEPO политика CE при отказах (см. раздел 8, параграфы 7.3.1, 4.3.3 и Приложение B) определяет, что будет происходить при потере ассоциации.

Для определенной в этом документе версии протокола элемент FE при повторном создании ассоциации должен отбрасывать любое состояние, как непригодное, и получать новое состояние. Такой подход продиктован соображениями простоты (в отличие от эффективности).

4.3. Механизмы протокола

Семантика, раскрываемая пользователям протокола через заголовки PL включает возможности транзакций и их неделимость, двухэтапное представления, группировку и распараллеливание операций, высокую доступность и восстановление при отказах, а также конвейеры команд.

Флаги EM (режим выполнения — Execution Mode), AT (неделимая транзакция — Atomic Transaction) и TP (фаза транзакции — Transaction Phase), определенные для общего заголовка (параграф 6.1), относятся к этим механизмам.

4.3.1. Транзакции, неделимость, выполнение и отклики

В режиме «ведущий-ведомый» CE инструктирует один или множество элементов FE о выполнении операций и отчетах о результате.

В этом параграфе описаны разные режимы, которые CE может запросить у элементов FE (см. параграф 4.3.1.1). Описаны также режимы форматирования откликов после выполнения запрошенной операции, которые CE может попросить у элементов FE. Эти режимы связаны с двухэтапными операциями транзакций.

4.3.1.1. Выполнение операций

Имеется 3 режима выполнения операций, которые могут быть запрошены для серии операций, охватывающей один или множество селекторов LFB (см. параграф 7.1.5) в одном протокольном сообщении. Флаг EM в общем заголовке (параграф 6.1) задает для протокольного сообщения режим выполнения операций:

  1. execute-all-or-none (выполнить все или ничего);

  2. continue-execute-on-failure (продолжать выполнение при возникновении отказа);

  3. execute-until-failure (выполнять до первого отказа).

4.3.1.1.1. Все или ничего

При установке этого режима выполнения независимые операции в сообщении могут направляться одним или множеством селекторов LFB в элементе FE. Все эти операции выполняются последовательно и элемент FE должен не иметь отказов при выполнении какой-либо из этих операций. Если при выполнении любой из операций возникает отказ, все предыдущие операции, выполненные до отказа, будут отменены (с возвратом к прежнему состоянию). Т. е. это режим выполнения операций с откатом при возникновении любой ошибки.

Использование этого режима в транзакциях описано в параграфе 4.3.1.2.2. В этом случае не выполняется ни одной операции, пока не будет представления (commit) от CE.

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

4.3.1.1.2. Продолжать при возникновении отказа

Если несколько независимых операций направляются одним или множеством селекторов LFB, выполнение операций продолжается в FE даже при возникновении одного или множества отказов.

4.3.1.1.3. Выполнять до первого отказа

В этом режиме все операции последовательно выполняются в FE, пока не возникнет первый отказ. Остальные операции не выполняются, а выполненные до отказа операции не отменяются. Т. е. этот режим не использует отката.

4.3.1.2. Транзакция и неделимость
4.3.1.2.1. Определение транзакции

Транзакция определяется как набор из одной или множества операций ForCES в одном или множестве сообщений PL, которые должны обладать свойствами ACIDity [ACID], как показано ниже.

Atomicity — неделимость

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

Consistency — согласованность

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

Isolation — изоляция

Транзакция, которая выполняется и не завершена, должна оставаться изолированной от всех прочих транзакций.

Durability — живучесть

Собранные данные сохраняются системой таким образом, что даже при возникновении отказа и перезапуске системы, данные остаются доступными в корректном состоянии.

Существуют ситуации, когда CE точно знает память и детали реализации FE (например, для пар FE-CE одного производителя, где FE и CE тесно связаны между собой). В таких случаях транзакции могут быть дополнительно упрощены за счет дополнительных вычислений в CE. Этот случай более подробно не рассматривается в данном документе, но отмечается, что такое поведение не запрещено.

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

  1. Внутри отдельного FE

    Например, обновление множества связанных между собой таблиц. При отказе во время обновления одной из таблиц уже обновленные должны быть возвращены в исходное состояние.

  2. Распределена в NE

    Например, обновление связанных таблиц в разных элементах FE (типа таблиц, связанных с пересылкой L3).

4.3.1.2.2. Протокол транзакций

Используя режим выполнения, как определено в параграфе 4.3.1.протокол обеспечивает механизм транзакций в рамках отдельного сообщения. Режим «все или ничего» может соответствовать требованиям ACID.

Для транзакций со множеством сообщений, выполняемых в одном или множестве FE, поддерживается классический протокол транзакций, известный как двухэтапная подача (two-phase commit — 2PC) [2PCREF], для обеспечения транзакционных операций, использующих сообщения Config (параграф 7.6.1).

Операции COMMIT и TRCOMP вместе с флагами AT и TP в общем заголовке (параграф 6.1) обеспечиваются для транзакций 2PC, включающих множество сообщений.

Флаг AT указывает, что сообщение относится к неделимой транзакции. Все сообщения для транзакции должны иметь флаг AT. Если флаг не установлен, это означает, что сообщение является автономным и не участвует в транзакции, включающей множество сообщений.

Флаг TP указывает фазу транзакции, к которой относится сообщение. Для транзакций возможны 4 фазы:

SOT (старт транзакции);

MOT (середина транзакции);

EOT (конец транзакции);

ABT (прерывание).

Операция COMMIT применяется CE для сигнализации элементам FE о представлении транзакции. При использовании с флагом ABT TP операция COMMIT сигнализирует элементам FE об отказе (т. е. un-COMMIT) от представленной ранее транзакции.

Операция TRCOMP является небольшим дополнением к классическому подходу 2PC. TRCOMP передается элементом CE для сигнала FE о представлении транзакции. Это дает элементам FE возможность очистить состояние которое они могут сохранять для выполнения отката (при необходимости).

Транзакция начинается с сообщения, в котором флаг TP имеет значение SOT (старт транзакции). Многокомпонентные сообщения после первого указываются флагом MOT (середина транзакции). Все сообщения от CE должны иметь флаг AlwaysACK (параграф 6) для запроса откликов от FE.

До того, как CE отдаст команду на выполнение (см. ниже), элемент FE должен лишь подтвердить возможность операции, не выполняя ее .

Любое уведомление от FE об отказе заставляет CE прервать транзакцию на всех вовлеченных в нее элементах FE. Это обеспечивается передачей сообщения Config с флагом ABT и операцией COMMIT.

Если ни на одном из участвующих в транзакции FE не обнаружено отказов, CE передает элементам FE сообщение Config с флагом EOT и операцией COMMIT.

Элемент FE должен ответить на сообщение EOT от CE. Существуют два случая отказов, при которых CE должен прервать транзакцию (как описано выше).

  1. Если участвующий в транзакции элемент FE отвечает сообщением об отказе, относящемся к транзакции.

  2. Если в течение заданного времени от участвующего в транзакции FE не получено отклика.

Если все участвующие FE возвращают индикацию успеха, элемент CE должен ввести операцию TRCOMP на всех участвующих FE. Элементам FE недопустимо отвечать на TRCOMP.

Отметим, что транзакции в общем случае неделимы, поэтому во всех сообщениях транзакции должен использоваться одинаковый режим execute-all-or-none. Если флаг EM указывает другой режим выполнения, это будет приводить к отказу транзакции.

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

4.3.1.2.3. Восстановление

Любой из участвующих FE, CE или связи между ними могут столкнуться с отказом после того, как сообщение EOT Response было передано FE, но до того, как элемент CE получит все отклики (например, отклик EOT не достигнет CE).

В этом выпуске протокола, как указано в параграфе 4.2.2.3, элементу FE, потерявшему ассоциацию, потребуется новое состояние от заново привязанного CE после восстановления ассоциации. Хотя такой подход проще и обеспечивает очевидность потери трафика данных, он выбран для снижения сложности поддержки изящного перезапуска. Для поддержки непрерывной работы при отказах FE обеспечиваются механизмы HA (раздел 8).

Гибкость обеспечивает способом реагирования на потерю связи элементом FE. Это продиктовано политикой CE для восстановления при отказах (см. раздел 8 и параграф 7.3).

4.3.1.2.4. Пример сообщений транзакции

В этом параграфе приведен пример успешного двухфазного представления между CE и FE в простом случае.

FE PL                                                  CE PL
  |                                                      |
  | (1) Config, SOT,AT, EM=All-or-None, OP= SET/DEL,etc  |
  |<-----------------------------------------------------|
  |                                                      |
  | (2) ACKnowledge                                      |
  |----------------------------------------------------->|
  |                                                      |
  | (3) Config, MOT,AT, EM=All-or-None, OP= SET/DEL,etc  |
  |<-----------------------------------------------------|
  |                                                      |
  | (4) ACKnowledge                                      |
  |----------------------------------------------------->|
  |                                                      |
  | (5) Config, MOT,AT, EM=All-or-None, OP= SET/DEL,etc  |
  |<-----------------------------------------------------|
  |                                                      |
  | (6) ACKnowledge                                      |
  |----------------------------------------------------->|
  .                                                      .
  .                                                      .
  .                                                      .
  .                                                      .
  |                                                      |
  | (N) Config, EOT,AT, EM=All-or-None, OP= COMMIT       |
  |<-----------------------------------------------------|
  |                                                      |
  | (N+1)Config-response, ACKnowledge, OP=COMMIT-RESPONSE|
  |----------------------------------------------------->|
  |                                                      |
  | (N+2) Config, OP=TRCOMP                              |
  |<-----------------------------------------------------|

Рисунок 7. Пример 2-этапного представления.

Для показанного на рисунке 7 примера выполняются перечисленные ниже действия.

  • На этапе 1 элемент CE передает сообщение Config с операцией типа DEL или SET. Устанавливаются флаги начала транзакции SOT, ее неделимости AT и режима execute-all-or-none (все или ничего).

  • FE проверяет возможность выполнения запроса и возвращает CE подтверждение в п. 2.

  • На этапе 3 CE повторяет конструкцию этапа 1, но с флагом середины транзакции MOT.

  • FE проверяет возможность выполнения запроса и возвращает CE подтверждение в п. 4.

  • Обмен CE-FE продолжается аналогиченм образом, пока все операции и их параметры не будут переданы элементу FE (это произойдет на этапе N-1).

  • На этапе N элемент CE передает команду представления (commit) с помощью сообщения Config с операцией типа COMMIT и флагом завершения транзакции EOT. Важно отметить, что это «пустое» сообщение запрашивает у элемента FE выполнение всех операций, собранных с начала транзакции (сообщение 1).

  • Элемент FE выполняет всю транзакцию целиком и передает CE подтверждение, содержащее COMMIT-RESPONSE, на этапе (N+1).

  • CE в этом случае просто передает операцию TRCOMP элементу FE на этапе (N+2).

4.3.2. Масштабируемость

Желательно, чтобы уровень PL не создавал «пробок», когда становятся доступными более широкополосные каналы. Например, при наличии каналов 100 Гбит/с и достаточном объеме работы уровню PL следует поддерживать возможность использования канала 100G. Для этого обеспечивается два механизма — пакетирование (batching) и конвейер команд (command pipeline).

Пакетирование обеспечивает возможность передачи множества команд (например, Config) в одном PDU12. Размер пакета (серии) команд зависит в том числе и от значения MTU для пути. Команды могут относиться к одной транзакции или быть не связанными между собой частями разных транзакций.

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

4.3.2.1. Серия операций

Существует несколько уровней пакетирования в разных протокольных иерархиях:

  • множество PL PDU может объединяться в одно сообщение TML;

  • множество классов и экземпляров LFB (указанных в селекторе LFB) могут размещаться в одном PL PDU;

  • множество операций может быть сосредоточено в одном классе и экземпляре LFB.

4.3.2.2. Конвейер команд

Протокол позволяет элементу CE ввести любое число сообщений до того, как от FE будут получены подтверждения (если они запрошены). Поэтому конвейерная обработка является просто частью природы протокола. Сопоставление откликов с запросами может быть организовано с помощью специального поля correlator в заголовке сообщения.

4.3.3. Механизм Heartbeat

Сообщения Heartbeat (HB) между элементами FE и CE зависят от трафика. Сообщение HB передается только в том случае, когда в течение заданного интервала не было обычного трафика PL между CE и FE. Это снижает объем трафика HB в периоды занятости PL.

Сообщения HB могут передаваться элементами CE или FE. При отправке сообщения элементом CE может быть запрошен отклик (аналогично ICMP ping). FE может генерировать сообщения HB только в том случае, когда это задано в настройках элементом CE (см. параграфы 7.3.1 и 7.10).

4.3.4. Объект FE и протокольные LFB

Все сообщения PL оперируют конструкциями LFB и это обеспечивает гибкость для будущих расширений. Это означает, что поддержка и настройка FE, NE и самого протокола ForCES должна выражаться в терминах архитектуры LFB. По этой причине были созданы специальные LFB, реализующие эти потребности.

Кроме того, это показывает, как сам протокол ForCES может контролироваться с помощью того же типа структур (LFB), которые служат для управления пересылкой IP, фильтрацией и т. п.

Для решения этих задач были добавлены специализированные блоки LFB, которые перечислены ниже.

  • FE Protocol LFB для управления протоколом ForCES.

  • FE Object LFB для управления компонентами, относящимися к FE (FEState [RFC5812], производитель, и т. п.).

Эти LFB подробно описаны в параграфе 7.3.

4.4. Протокольные сценарии

В этом параграфе приводится описание верхнего уровня для примеров последовательностей сообщений между элементами CE и FE. Представление протокольных сообщений описано в параграфе 6.1, а семантика протокола — в параграфе 4.3.

4.4.1. Состояние создания ассоциации

Ассоциация между элементами CE и FE инициируется сообщением Association Setup от FE. Если элемент CE принимает запрос (Setup Request), он возвращает сообщение Setup Response элементу FE. Если CE и FE работают в незащищенной среде, между ними организуется защищенная связь до обмена какими-либо сообщениями ассоциации. Уровень TML должен обеспечить организацию защищенных связей.

После этого обычно следуют запросы возможностей, определение топологии и пр. Когда элемент FE готов начать обслуживание пути данных, он устанавливает для компоненты FEO FEState состояние OperEnable (см. [RFC5812]) и сообщает об этом элементу CE, к которому он обращался с первым запросом. Готовность FE к обслуживанию пути данные обычно предполагается еще до создания ассоциации, но бывают (редкие) случаи, когда требуется некоторое время для той или иной предварительной обработки. В таких случаях FE будет начинать с состояния OperDisable и по мере готовности перейдет в состояние OperEnable. Пример FE, начинающего работу в состоянии OperDisable и затем переходящего в OperEnable, показан на рисунке 8. Элемент CE может в любой момент запретить операции FE в пути данных, устанавливая для FEState значение AdminDisable. Элементу FE недопустимо обрабатывать пакеты, пока CE не восстановит для него состояние OperEnable. Эти последовательности сообщений показаны на рисунке 8.

FE PL                  CE PL
  |                       |
  |   Asso Setup Req      |
  |---------------------->|
  |                       |
  |   Asso Setup Resp     |
  |<----------------------|
  |                       |
  | LFBx Query capability |
  |<----------------------|
  |                       |
  | LFBx Query Resp       |
  |---------------------->|
  |                       |
  | FEO Query (Topology)  |
  |<----------------------|
  |                       |
  | FEO Query Resp        |
  |---------------------->|
  |                       |
  | FEO OperEnable Event  |
  |---------------------->|
  |                       |
  |  Config FEO Adminup   |
  |<----------------------|
  |                       |
  | FEO Config-Resp       |
  |---------------------->|
  |                       |

Рисунок 8. Обмен сообщениями между CE и FE для создания ассоциации NE


При успешном завершении этого состояния FE присоединяется к элементу NE.

4.4.2. Состояние созданной ассоциации и установившееся состояние

В этом состоянии FE продолжает получать обновления и запросы. FE может также передавать элементу CE асинхронные уведомления о событиях, синхронные сообщения Heartbeat, а также сообщения Packet Redirect. Это продолжается до прерывания (или деактивации) ассоциации по инициативе CE или FE. Рисунок 9 иллюстрирует это состояние.

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


FE PL                          CE PL
  |                              |
  |    Heartbeat                 |
  |<---------------------------->|
  |                              |
  |   Heartbeat                  |
  |----------------------------->|
  |                              |
  | Config-set LFBy (Event sub.) |
  |<-----------------------------|
  |                              |
  |     Config Resp LFBy         |
  |----------------------------->|
  |                              |
  |  Config-set LFBx Component   |
  |<-----------------------------|
  |                              |
  |     Config Resp  LFBx        |
  |----------------------------->|
  |                              |
  |Config-Query LFBz (Stats)     |
  |<--------------------------- -|
  |                              |
  |    Query Resp LFBz           |
  |----------------------------->|
  |                              |
  |    FE Event Report           |
  |----------------------------->|
  |                              |
  |  Config-Del LFBx Component   |
  |<-----------------------------|
  |                              |
  |     Config Resp LFBx         |
  |----------------------------->|
  |                              |
  |    Packet Redirect LFBx      |
  |----------------------------->|
  |                              |
  |    Heartbeat                 |
  |<-----------------------------|
  .                              .
  .                              .
  |                              |

Рисунок 9. Обмен сообщениями между CE и FE в стационарном состоянии.

5. Требования к TML

Предполагается, что уровень TML будет соответствовать приведенным ниже требованиям. Этот текст не определяет способы реализации этих механизмов. Например, механизмы выполнения требований могут быть реализованы в оборудовании или между двумя и более программными процессами TML на разных CE и FE в схемах протокольного уровня.

Каждый TML должен описывать свой вклад в выполнение приведенных здесь требований ForCES. Если по какой-либо причине перечисленная здесь услуга не предоставляется, это должно быть обосновано.

Реализации, поддерживающие спецификацию протокола ForCES, должны реализовать [RFC5811]. Отметим, что в будущем могут быть заданы дополнительные TML и в случаях, когда новые TML будут обеспечивать лучшее выполнение приведенных требований, соответствующие требования могут быть переопределены.

  1. Надежность

    Различные сообщений ForCES будут требовать разных уровней гарантии доставки через TML. Уровень TML отвечает за обеспечение таких гарантий и описание отображения разных сообщений ForCES на соответствующие уровни гарантий.

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

    Данные типа конфигурации от CE и откликов от FE имеют критическое значение и должны доставляться с обеспечением твердых гарантий. Поэтому для информации этого типа уровень TML должен должен включать встроенные протокольные механизмы или использовать транспортный протокол с твердыми гарантиями.

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

    Для части информации типа пакетов heartbeat своевременность доставки может оказаться важнее гарантий надежности. Для такой информации TML может определять применение механизма без твердых гарантий (пр соблюдении остальных требований к TML типа контроля перегрузок).

  2. Безопасность

    Уровень TML обеспечивает услуги защиты для ForCES PL. Поскольку уровень ForCES PL используется для работы NE, основными целями сетевых атак можно считать создание путаницы, запрет или утечку информации из основанных на протоколе ForCES элементов NE.

    Атакующий с возможностью вставки ложных сообщений в поток PL, может воздействовать на обслуживание элементами FE пути данных (например, передавая ложные данные управления от имени CE) или сам элемент CE (изменяя уведомления о событиях или отклики от FE). По этой причине проверка подлинности элементов CE и FE, а также аутентификации сообщений TML имеют важное значение.

    Сообщения PL могут также содержать важную для атакующего информацию, включая данные конфигурации сети, ключи шифрования и другие деликатные данные, поэтому следует принимать меры по ограничению доступа к таким данным (только уполномоченные пользователи).

  • TML должен обеспечивать механизм проверки подлинности элементов ForCES CE и FE для предотвращения доступа неуполномоченных элементов CE и FE к управлению и обслуживанию пути данных для ForCES NE.

  • TML следует обеспечивать механизм проверки подлинности сообщений с данными PL , передаваемых между элементами CE и FE для предотвращения вставки некорректных данных в сообщения PL.

  • TML следует обеспечивать механизм защиты конфиденциальности данных, передаваемых от ForCES PL для предотвращения утечки информации уровня PL, передаваемой через TML.

Уровню TML следует поддерживать эти услуги с помощью TLS или IPsec.

  1. Контроль насыщения

    Должна быть определена схема контроля транспортных перегрузок, используемая TML. Механизм контроля насыщения, определенный TML, должен предотвращать коллапс насыщения [RFC2914] на стороне FE или CE.

  2. Индивидуальная, групповая и широковещательная адресация и доставка

    При наличии каких-либо отображений между индивидуальной, групповой и широковещательной адресацией между уровнями PL и TML, они должны быть определены.

  3. Высокий уровень доступности

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

    Более подробная информация представлена в разделе 8.

  4. Используемая инкапсуляция

    Разные типы TML будут инкапсулировать сообщения PL с использованием разных типов заголовков. Уровень TML должен указывать применяемую инкапсуляцию.

  5. Приоритизация

    Предполагается, что TML может поддерживать до 8 уровней приоритета, требуемых PL, и будет обеспечивать соответствующее обслуживание.

    Хотя от TML требуется определить, как обеспечивается поддержка приоритизации, следует отметить, что требование поддержки до 8 уровней приоритета вовсе не означает, что TML должен реально обеспечить эти уровни. Если базовый сервис TML не поддерживает 8 уровней приоритета, поддерживаемые уровни следует поделить между доступными в TML уровнями приоритета. Например, если TML поддерживает лишь два уровня, приоритеты 0-3 могут быть отображены на один из них, а 4-7 — на другой.

    Уровню TML недопустимо менять порядок следования пакетов config с одинаковым уровнем приоритета.

  6. Предотвращение перегрузки узла

    Уровень TML должен определять механизмы, которые он использует для предотвращения перегрузки узла.

    Перегрузка приводи к истощению вычислительных и/или канальных ресурсов узла и это снижает рабочую производительность ForCES NE. Перегрузка узла NE может быть осознанно спровоцирована злонамеренным узлом для атаки ForCES NE и отказа в обслуживании (DoS13). Перегрузка может возникать и по многим другим причинам типа значительных обновлений данных протоколов (например, осцилляции BGP), которые вызывают передачу многочисленных обновлений от CE в таблицы FE, переключения HA или отказа компонент, в результате которого работа FE или CE переносится на новый элемент FE или CE, и т. п. Хотя среды, в которых работают протоколы SIP и ForCES различаются, [RFC5390] обеспечивает хорошее руководство с базовыми требованиями, которым должен соответствовать защищаемый узел.

    Процессор узла ForCES может быть перегружен в результате слишком высокой скорости входящих потоков. В таких случаях транспортные очереди растут и может возникнуть транспортная перегрузка. Процессор узла ForCES может также быть перегружен в результате преднамеренной передачи небольшого числа пакетов без перегрузки транспорта (например, DoS-атака на алгоритм хэширования таблиц, приводящая к их переполнению и/или высокой загрузке CPU, не позволяющей обрабатывать другие задачи). Решение TML по предотвращению перегрузки узла должно препятствовать возникновению обоих вариантов перегрузки.

5.1. Параметризация TML

Предполагается, что для настройки TML используются средства типа менеджеров FEM или CEM.

Ниже перечислены некоторые из настраиваемых параметров.

  • PL ID.

  • Тип соединения и связанные с ним данные. Например, если TML использует IP/TCP/UDP, настраиваемыми параметрами будут номер порта TCP/UDP и адрес IP.

  • Число транспортных соединений.

  • Емкость соединения (пропускная способность и т. п.).

  • Разрешенные/поддерживаемые правила QoS (или контроля перегрузок) для соединения.

6. Инкапсуляция сообщений

Все PL PDU начинаются с общего заголовка, описанного в параграфе 6.1, за которым следует один или множество блоков TLV, описанных в параграфе 6.2, и могущих включать в себя другие TLV, как описано в параграфе 6.2.1. Все поля заголовка используют сетевой порядок байтов.

6.1. Общий заголовок

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|version| rsvd  | Message Type  |             Length            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Source ID                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Destination ID                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Correlator[63:32]                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Correlator[31:0]                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             Flags                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 10. Общий заголовок.


Сообщения выравниваются по 32-битовым границам.

version (4 бита)

Номер версии (текущее значение 1).

rsvd (4 бита)

Резервное поле, которое не анализируется получателем. Отправитель должен установить значение 0, а получатель должен игнорировать это поле.

Message Type (8 битов)

Команды, определенные в разделе 7.

Length (16 битов)

Размер заголовка и остальной части сообщения в DWORD (4 байта).

Source ID (32 бита)

Dest ID (32 бита)

  • Каждый идентификатор отправителя и получателя представляет собой 32-битовое значение, уникальное в масштабе NE, которое служит для указания конечной точки сообщения ForCES PL.
  • Идентификаторы поддерживают индивидуальную, групповую и широковещательную адресации, как показано ниже.
    1. Используется расщепленное адресное пространство для того, чтобы отличать элементы FE и CE. Хотя в больших NE число FE на один-два порядка больше числа CE, адресное пространство для простоты распределено однородно.
    2. Адресное пространство позволяет указать до 230 (более миллиарда) элементов CE и столько же FE.
       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |TS |                           sub-ID                          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      Рисунок 11. Формат ForCES ID.

    3. 2 старших бита TS (Type Switch) служат для разделения пространства идентификаторов:
TS        Диапазон идентификаторов     Назначение
--        ------------------------     ----------
0b00      0x00000000 - 0x3FFFFFFF      FE ID (2^30)
0b01      0x40000000 - 0x7FFFFFFF      CE ID (2^30)
0b10      0x80000000 - 0xBFFFFFFF      резерв
0b11      0xC0000000 - 0xFFFFFFEF      групповые ID (2^30 - 16)
0b11      0xFFFFFFF0 - 0xFFFFFFFC      резерв
0b11      0xFFFFFFFD                   широковещание всем CE
0b11      0xFFFFFFFE                   широковещание всем FE
0b11      0xFFFFFFFF                   широковещание всем FE и CE (NE)

Рисунок 12. Пространство типов Switch ID.

  • Групповые и широковещательные ID используются для групп конечных точек (типа CE и FE). Например, это может быть функциональная группа FE. Аналогично может быть выделена подгруппа CE, например, в режиме резервирования, чтобы скрыть их от FE:
    • Multicast ID могут использоваться для указания отправителей и получателей;
    • Broadcast ID могут применяться только для получателей.
  • В этом документе не рассматривается связи конкретных групповых идентификаторов с той или иной группой, которая может быть задана в процессе настройки. Список идентификаторов, которыми владеют FE (или входят в список), указывается в FE Object LFB.

Correlator (64 бита)

Это поле устанавливается элементом CE для сопоставления сообщений ForCES Request с откликами от FE. По сути, это поле играет роль cookie. Поле correlator элемент FE должен копировать в отклик из соответствующего запроса. Если сообщение от CE не вызывает отклика, это поле не имеет смысла.

Поле correlator может использоваться разными реализациями по усмотрению элементов CE. Например, CE может разделить поле на 32-битовые идентификаторы транзакции и порядкового номера сообщения. Другим примером может служить 64-битовый указатель на блок контекста. Конкретные варианты использования поля correlator выходят за рамки спецификации.

Следует отметить, что поле correlator передается через сеть как 64-битовое целое число без знака, начиная с левого или старшего октета (биты 63-56).

Когда поле correlator не требуется по причине того, что не ожидается отклика, следует указывать correlator = 0.

Flags (32 бита)

Флаги заголовка показаны на рисунке.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   |     |     |   | |   |                                     |
|ACK| Pri |Rsr  |EM |A|TP |     Reserved                        |
|   |     | vd. |   |T|   |                                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 13. Флаги заголовка.

ACK — индикатор ACK (2 бита)

Флаг ACK используется только CE при передаче сообщения Config (параграф 7.6.1) или HB (параграф 7.10), чтобы указать получателю должен ли он передать отклик. Отметим, что для всех сообщений, кроме Config и HB, этот флаг должен игнорироваться.

Значения флага показаны ниже.

NoACK (0b00) указывает, что получателю недопустимо передавать в ответ сообщение Response.

SuccessACK (0b01) указывает, что получатель должен передать в ответ сообщение Response только после успешной обработки принятого сообщения.

FailureACK (0b10) указывает, что получатель должен передать в ответ сообщение Response только при возникновении отказа в процессе обработки (выполнения) сообщения. Иными словами, отправитель не ждет отклика при успешной обработке сообщения получателем.

AlwaysACK (0b11) указывает, что получатель должен передать сообщение Response в любом случае.

Отметим, что в приведенных выше определениях термин «успех» означает полное выполнение без каких-либо отказов для сообщения. Все прочие результаты считаются отказами при обработке сообщения. В результате этого для режимов выполнения (определены в параграфе 4.3.1.1) типа execute-all-or-none, execute-until-failure и continue-execute-on-failure отказ любой операции из сообщения будет считаться отказом всего сообщения и приводить к отправке соответствующего отклика, если индикатор ACK имеет значение FailureACK или AlwaysACK.

Отметим также, что для сообщений, отличных от Config и HB, требования к откликам всегда задаются принятым по умолчанию способом, а не флагами ACK. Требования к принятой по умолчанию генерации откликов приведены ниже, а подробные описания приведены в определениях соответствующих сообщений.

  • Для Association Setup всегда ожидается передача отклика.
  • Для сообщений Association Teardown и Packet Redirect отклики не ожидаются.
  • Для сообщения Query всегда ожидается отклик.
  • Для сообщений Response дополнительные отклики не ожидаются.

Pri — Priority (3 бита)

Протокол ForCES определяет 8 уровней приоритета (0-7), которые могут применяться для того, чтобы различать разные типы сообщений, а также разные сообщения одного типа. Чем больше значение приоритета, тем более важным является PDU. Например сообщение REDIRECT может иметь разные уровни приоритета для протоколов маршрутизации и пакетов ARP, перенаправляемых от FE к CE. Обычный уровень приоритета имеет значение 1. Сообщения с разным приоритетом могут менять свой порядок, однако изменение порядка в наборе сообщений одной транзакции нежелательно и следует его избегать.

EM — Execution Mode (2 бита)

Поддерживается три режима выполнения, определенных в параграфе 4.3.1.1.

резерв (0b00);

execute-all-or-none (0b01);

execute-until-failure (0b10);

continue-execute-on-failure (0b11).

AT — Atomic Transaction (1 бит)

Этот флаг показывает является сообщение автономным или одним из группы сообщений, относящихся к транзакции 2PC (см. параграф 4.3.1.2.2).

автономное сообщение (0b0);

сообщение из транзакции 2PC (0b1).

TP — Transaction Phase (2 бита)

Сообщение от CE к FE в транзакции может указывать разные фазы этой транзакции (см. параграф 4.3.1.2.2).

SOT (0b00)

MOT (0b01)

EOT (0b10)

ABT (0b11)

6.2. Структуры TLV

Структуры TLV14 широко используются протоколом ForCES. TLV имеют ряд очень удобных свойств, которые делают их подходящими кандидатами для кодирования определений XML модели класса LFB. Эти свойства перечислены ниже.

  • Двоичное представление type-value, близкое к схеме представления строк XML tag-value.

  • Возможность быстрой генерации функций разбора.

  • Совместимость тегов с новыми и старыми версиями. Это эквивалентно подходу XML, т. е. старые приложения могут игнорировать новые TLV, а новые приложения могут игнорировать старые TLV.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| TLV Type                    | TLV Length                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               Value (собственно данные TLV)                   |
~                                                               ~
~                                                               ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 14. Представление TLV.


TLV Type (16)

Поле типа TLV имеет размер 2 октета и семантически показывает тип данных, инкапсулированных в TLV.

TLV Length (16)

Поле размера TLV занимает 2 октета и учитывает размер поля типа TLV (2 октета), TLV Length (2 октета), а также размер данных в поле значения TLV (в октетах). Отметим, что заполнение в поле значения не учитывается в размере.

TLV Value (переменный размер)

Поле значение TLV содержит данные. Для расширяемости значением TLV может быть другой блок TLV. Если размер значения не кратен 32 битам, требуется использовать заполнение минимальным числом октетов, требуемым для выравнивания TLV по 32-битовой границе. Размер значения до заполнения учитывается в поле TLV Length.

Примечание. Поле значения может быть пустым, поэтому минимальный размер TLV составляет 4 октета (размеры полей T и L).

6.2.1. Вложенные TLV

Значениями TLV могут быть другие TLV. Это обеспечивает протоколу гибкость (возможность добавлять расширения путем определения новых TLV). Вложенные TLV также позволяют концептуальную оптимизацию определений XML LFB для двоичного представления PL (использует вложенные TLV).

6.2.2. Область действия типа (T) в TLV

Имеются две глобальных области действия типа в TLV. Первой областью являются OPER-TLV, определенные в Приложении A.4, а вторая область не связана с OPER-TLV и определена в Приложении A.2.

6.3. ILV

ILV представляет собой вариацию TLV. Здесь в качестве типа (T) служит 32-битовый локальный индекс, который указывает идентификатор компоненты ForCES (см. параграф 6.4.1).

Поле ILV представляет собой 4-октетное целое число, которое учитывает размер типа ILV (4 октета), ILV Length (4 октета) и размер данных ILV в поле value (в октетах). Отметим, что как и для TLV, этот размер не учитывает заполнения поля value, если оно применяется.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Identifier                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Length                                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Value                                  |
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 15. Представление ILV.


Следует подчеркнуть, что значение I имеют локальную значимость и определяются декларациями данных из определения LFB. Применение ILV рассматривается в параграфе 7.1.8.

6.4. Вопросы инкапсуляции

В этом параграфе рассматривается несколько концепций инкапсуляции, которые используются протоколом ForCES для своих операций.

Для согласования контекста здесь повторяются концепции для путей и ключей из модели ForCES [RFC5812]. Читателю рекомендуется обратиться за подробностями к [RFC5812].

Для удобочитаемости введены схемы инкапсуляции, которые служат для передачи содержимого протокольных сообщений, а именно, FULLDATA-TLV, SPARSEDATA-TLV и RESULT-TLV.

6.4.1. Пути

Модель ForCES [RFC5812] определяет основанный на XML язык, который позволяет формально определять блоки LFB. Это похоже на взаимоотношения ASN.1 и определений SNMP MIB (MIB является аналогом LFB, ASN.1 — аналогом языка моделирования XML). Любой объект, который CE настраивает в FE, должен быть формально определен в LFB. Эти объекты могут быть скалярами (например, 32-битовый адрес IPv4) или векторами (например, таблица nexthop). Каждый объект в LFB задается 32-битовым числовым идентификатором, который называют component id. Данная схема позволяет «адресовать» компоненты в протокольной конструкции.

Эти адресуемые объекты могут быть иерархическими (например, колонка или ячейка в строке таблицы). Для адресации иерархических данных в модели [RFC5812] введена концепция пути. Путь представляет собой последовательность 32-битовых идентификаторов компонент, которые обычно разделяются точками (например, 1.2.3.4). Формальное определение использования путей для указания данных, которые будут инкапсулироваться в протокольное сообщение, приведено в разделе 7.

6.4.2. Ключи

Модель ForCES [RFC5812] определяет два способа адресации строк в таблицах. Стандартный (базовый) механизм позволяет представлять строку 32-битовым индексом. Второй механизм, основанный на использовании ключей, позволяет адресовать содержимое. Примером ключа может служить ключ содержимого с множеством полей, который использует адрес IP и размер префикса для однозначного указания строки таблицы маршрутизации IPv4. Сути, базовая схема адресации строк таблиц основана на индексах, а путь строки таблицы может быть выведен из ключа. KEYINFO-TLV (раздел 7) служит для переноса данных, которые используются при поиске.

6.4.3. TLV данных

Данные от элементов FE и к ним передаются в двух типах TLV — FULLDATA-TLV и SPARSEDATA-TLV. Отклики для выполненных FE операций передаются в RESULT-TLV.

Данные в FULLDATA-TLV кодируются таким образом, чтобы получатель, зная путь и определение LFB, мог вывести или сопоставить содержимое поля Value из TLV. Такая оптимизация помогает уменьшить объем описаний, требуемых для транспортируемых данных в грамматике протокола. Примеры FULLDATA-TLV представлены в Приложении C.

Ряду операций ForCES требуется указывать дополнительные данные в более крупных структурах. Кодирование SPARSEDATA-TLV обеспечивает упрощение инкапсуляции необязательных компонент данных. Примеры SPARSEDATA-TLV приведены в Приложении C.

RESULT-TLV передают отклики от FE на основе конфигурации, заданной CE. Схема RESULT-TLV описана в параграфе 7.1.7, а примеры представлены в Приложении C.

6.4.4. Адресация объектов LFB

В параграфах 6.4.1 и 6.4.2 описана адресация объектов внутри LFB. Однако используемый механизм адресации требует сначала выбрать тип и экземпляр LFB. Для такого выбора служит селектор LFB. В разделе 7 это описано более подробно, а здесь для иллюстрации концепции используется рисунок 16. Дополнительные примеры схем приведены ниже (например, рисунок 22).

main hdr (Тип сообщения. Например, config)
 |
 |
 |
 +- T = LFBselect
        |
        +-- LFBCLASSID (unique per LFB defined)
        |
        |
        +-- LFBInstance  (рабочая конфигурация)
        |
        +-- T = TLV операции указывает что мы делаем с объектом
            |   //Указывает значения OPER-TLV, перечисленные под
            |   //TLV, которые могут быть использованы для операций
            |
            |
            +--+-- Один или множество путей к цели объекта
               | // Указывает на обсуждение ключей и путей
               |
               |
               +-- Связанные данные для объекта (если они есть)
                 // Указывает на обсуждение FULL/SPARSE DATA TLV

Рисунок 16. Адресация объекта.


7. Устройство протокола

Блок PDU протокольного уровня состоит из базового заголовка, определенного в параграфе 6.1, и тела сообщения. После общего заголовка следует тело сообщения, зависящее от типа этого сообщения. Тело каждого сообщения состоит из одного или множества TLV верхнего уровня. Эти блоки TLV могут включать один или множество встроенных TLV, которые указываются в этом документа как OPER-TLV, поскольку они описывают выполняемые операции.

Таблица 1.

Имя сообщения

TLV верхнего уровня

OPER-TLV

Параграф

Association Setup

(LFBselect)*

REPORT

7.5.1

Association Setup Response

ASRresult-TLV

нет

7.5.2

Association Teardown

ASTreason-TLV

нет

7.5.3

Config

(LFBselect)+

(SET | SET-PROP | DEL | COMMIT | TRCOMP)+

7.6.1

Config Response

(LFBselect)+

(SET-RESPONSE | SET-PROP-RESPONSE | DEL-RESPONSE | COMMIT-RESPONSE)+

7.6.2

Query

(LFBselect)+

(GET | GET-PROP)+

7.7.1

Query Response

(LFBselect)+

(GET-RESPONSE | GET-PROP-RESPONSE)+

7.7.2

Event Notification

LFBselect

REPORT

7.8

Packet Redirect

REDIRECT-TLV

нет

7.9

Heartbeat

нет

нет

7.10

Сообщения разных типов перечислены в таблице 1, а числовые значения типов указаны в Приложении A.1. Определения для всех TLV даны в Приложении A.2.

LFBselect TLV (см. параграф 7.1.5) содержит LFB Classid и экземпляр LFB, на который ссылаются, а также OPER-TLV для выполняемых операций.

Каждый тип OPER-TLV ограничен в части описания интересующих путей и селекторов. Приведенная ниже форма BNF описывает базовую структуру OPER-TLV, а в таблице 2 приведены подробности для каждого типа.

  • OPER-TLV := 1*PATH-DATA-TLV
    PATH-DATA-TLV := PATH  [DATA]
    PATH := flags IDcount IDs [SELECTOR]
    SELECTOR :=  KEYINFO-TLV
    DATA := FULLDATA-TLV / SPARSEDATA-TLV / RESULT-TLV / 1*PATH-DATA-TLV
    KEYINFO-TLV, V= {1, FULLDATA-TLV V={100}}
    FULLDATA-TLV := кодированная компонента данных, которая может включать вложенные FULLDATA-TLV
    SPARSEDATA-TLV :=  кодированная компонента данных (может включать необязательные компоненты)
    RESULT-TLV := код результата и необязательный FULLDATA-TLV

    Рисунок 17. Форма BNF для OPER-TLV.


    PATH-DATA-TLV указывает целевую компоненту и может (но не обязательно) включать связанные с ней пути. Последний блок PATH-DATA-TLV для случая вложенных путей с использованием конструкции DATA в запросах SET и SET-PROP, а также откликах GET-RESPONSE и GET-PROP-RESPONSE завершается представленными данными или откликом в форме FULLDATA-TLV, SPARSEDATA-TLV или RESULT-TLV.

  • PATH указывает путь к данным, на которые ссылаются.

    • flags (16 битов) используются для уточнения операции, применяемой на пути (детали приведены ниже).

    • IDcount (16 битов) — счетчик 32-битовых значений ID.

    • IDs — необязательные 32-битовые идентификаторы (число которых указано в Idcount), определяющие основной путь. В зависимости от флагов (flags) идентификаторы могут быть только полями ID или комбинацией полей и динамических ID. Отсутствие идентификаторов является особым случаем использования контекста в качестве результата пути.

  • SELECTOR представляет собой необязательную конструкцию, дополняющую PATH. Единственным определенным в настоящее время селектором является KEYINFO-TLV, используемый для выбора элемента массива по значению поля key. Присутствие SELECTOR корректно лишь в тех случаях, когда оно указано полем flags.

  • KEYINFO-TLV представляет информацию, используемую для ключа содержимого.

    • 32-битовый идентификатор KeyID используется в KEYINFO-TLV для указания ключа, который будет служить в текущем массиве для выбора элемента.

    • Данные ключа key используются для поиска в массиве среди указанных ключом полей. Информация кодируется в соответствии с правилами для содержимого FULLDATA-TLV и представляет поле или поля, которые образуют ключ, указанный KeyID.

  • DATA может включать FULLDATA-TLV, SPARSEDATA-TLV, RESULT-TLV или один или несколько дополнительных выборов PATH-DATA. FULLDATA-TLV и SPARSEDATA-TLV разрешены только в запросах SET или SET-PROP, а также в откликах, возвращающих информацию содержимого (например, GET-RESPONSE). Можно включать также PATH-DATA для расширения пути в любом запросе.

    • Примечание. Вложенные PATH-DATA-TLV поддерживаются в качестве эффективного способа преобразования общих субвыражений.

    • FULLDATA-TLV и SPARSEDATA-TLV содержат данные, путь к которым указан с помощью PATH (см. параграф 7.1.

    • В таблице 2 показана применимость и ограничения для FULLDATA-TLV и SPARSEDATA-TLV, а также RESULT-TLV для OPER-TLV.

Таблица 2.

OPER-TLV

DATA TLV

RESULT-TLV

SET

нет

SET-PROP

(FULLDATA-TLV | SPARSEDATA-TLV)+

нет

SET-RESPONSE

нет

(RESULT-TLV)+

SET-PROP-RESPONSE

нет

(RESULT-TLV)+

DEL

нет

DEL-RESPONSE

нет

(RESULT-TLV)+

GET

нет

нет

GET-PROP

нет

нет

GET-RESPONSE

(FULLDATA-TLV)+

(RESULT-TLV)*

GET-PROP-RESPONSE

(FULLDATA-TLV)+

(RESULT-TLV)*

REPORT

(FULLDATA-TLV)+

нет

COMMIT

нет

нет

COMMIT-RESPONSE

нет

(RESULT-TLV)+

TRCOMP

нет

нет

  • RESULT-TLV содержит индикацию результата отдельной операции SET или SET-PROP. RESULT-TLV включается в предположении, что отдельные части запроса SET могут быть неудачными или успешными независимо от других.

В заключение отметим, характеристики описанного подхода.

  • В сообщении может быть одна или несколько комбинаций идентификаторов класса и экземпляра LFB (пакет).

  • Может быть одна или множество операций, указанных комбинацией идентификаторов класса и экземпляра LFB (пакет).

  • Может быть одна или множество целей путей на операцию (пакет).

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

Следует отметить, что приведенное выше описание оптимизировано для случая одного идентификатора класса и экземпляра LFB. Для множества экземпляров одного класса требуется множество LFBselect.

7.1. Кодирование

В параграфе 6.4.3 рассмотрены два типа кодирования DATA (FULLDATA-TLV и SPARSEDATA-TLV), а также дано обоснование их наличия. Здесь кодирование описывается более подробно.

7.1.1. Правила упаковки данных

Ниже приведены правила, которые используются в принятой здесь схеме кодирования данных.

  • Поле Value (V в TLV) в FULLDATA-TLV будет содержать передаваемые данные, как описано в определении LFB.

  • Данные переменного размера в FULLDATA-TLV будут инкапсулироваться внутри другого FULLDATA-TLV внутри V внешнего TLV. Примеры такого кодирования представлены в Приложениях C и D.

  • В случае FULLDATA-TLV.

    • Когда таблица указана в PATH (IDs) блока PATH-DATA-TLV, значение FULLDATA-TLV (V) будет включать содержимое строки этой таблицы с 32-битовым префиксом index/subscript. С другой стороны, PATH может содержать индекс, указывающий строку таблицы, и в этом случае значение FULLDATA-TLV (V) будет содержать только индекс для предотвращения неоднозначности.

7.1.2. Флаги пути

В поле flags для пути в настоящее время используется только бит 0 (SELECTOR), как показано на рисунке 18.

 0                   1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |                             |
|S|   Reserved                  |
| |                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 18. Флаги пути.

Семантика флага определена ниже.

  • Флаг SELECTOR — F_SELKEY(1) показывает присутствие KEY Selector вслед за этой информацией пути и его следует учитывать при определении содержимого пути.

7.1.3. Связь операционных флагов с глобальными флагами сообщения

Глобальные флаги типа индикаторов режима выполнения и неделимости, определенные в заголовке, применяются ко всем операциям в сообщении. Эти флаги обеспечивают семантику, которая ортогональная семантике операционных флагов типа тех, что определены в path-data. Область действия операционных флагов ограничена одной операцией.

7.1.4. Выбор пути к содержимому

KEYINFO-TLV описывает ключ KEY и связанные с ним данные. Ключи служат для поиска содержимого, ограничены и описываются в определении LFB.

7.1.5. LFBselect-TLV

LFBselect TLV является экземпляром TLV в соответствии с определением параграфа 6.2. Схема показана на рисунке.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        Type = LFBselect       |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          LFB Class ID                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        LFB Instance ID                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        OPER-TLV                               |
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~                           ...                                 ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        OPER-TLV                               |
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 19. Схема PL PDU.

Type

Тип TLV — LFBselect.

Length

Размер TLV в октетах с учетом полей T и L.

LFB Class ID

Это поле однозначно указывает класс/тип LFB.

LFB Instance ID

Это поле однозначно указывает экземпляр LFB.

OPER-TLV

Описывает операции, встроенные в LFBselect TLV. Отметим, что обычно следует включать не менее одного OPER-TLV для TLV выбора LFB.

7.1.6. OPER-TLV

OPER-TLV представляет TLV, которые определяют операции. Типы операций показаны в таблице 3.

Таблица 3.

OPER-TLV

Тип TLV

Комментарии

SET

0x0001

От CE к FE. Служит для создания, добавления или обновления компонент.

SET-PROP

0x0002

От CE к FE. Служит для создания, добавления или обновления свойств компонент.

SET-RESPONSE

0x0003

От FE к CE. Служит для передачи отклика SET.

SET-PROP-RESPONSE

0x0004

От FE к CE. Служит для передачи отклика SET-PROP.

DEL

0x0005

От CE к FE. Служит для удаления или исключения компонент.

DEL-RESPONSE

0x0006

От FE к CE. Служит для передачи отклика DEL

GET

0x0007

От CE к FE. Служит для получения компонент.

GET-PROP

0x0008

От CE к FE. Служит для получения свойств компонент.

GET-RESPONSE

0x0009

От FE к CE. Служит для передачи отклика GET.

GET-PROP-RESPONSE

0x000A

От FE к CE. Служит для передачи отклика GET-PROP.

REPORT

0x000B

От FE к CE. Служит для передачи асинхронных событий.

COMMIT

0x000C

От CE к FE. Служит для подачи на исполнение транзакции 2PC.

COMMIT-RESPONSE

0x000D

От FE к CE. Служит для подтверждения подачи транзакции 2PC.

TRCOMP

0x000E

От CE к FE. Служит для индикации успешной транзакции 2PC в масштабе NE.

OPER-TLV используется в разных сообщениях, как указано в таблицах 1 и 2.

Запросы SET, SET-PROP и GET/GET-PROP подаются элементом CE и не включают RESULT-TLV. С другой стороны, отклики SET-RESPONSE, SET-PROP-RESPONSE и GET-RESPONSE/GET-PROP-RESPONSE содержат RESULT-TLV.

GET-RESPONSE в отклике на успешный запрос GET будет иметь FULLDATA-TLV, добавленные к путям листьев для передачи запрошенных данных. Для отказавших операций GET вместо FULLDATA-TLV будет RESULT-TLV.

Для SET-RESPONSE/SET-PROP-RESPONSE каждый FULLDATA-TLV или SPARSEDATA-TLV в исходном запросе будет заменяться в отклике на RESULT-TLV. Если в запросе установлен флаг FailureACK, в отклике будут указаны только отказавшие элементы. При установленном флаге AlwaysACK все компоненты запроса будут в отклике с RESULT-TLV.

Отметим, что при запросе SET/SET-PROP со структурой в FULLDATA-TLV, имеющей непригодные поля, FE не будет пытаться указать такие поля, а просто покажет отказ операции. При наличии множества ошибок в одном листе PATH-DATA/FULLDATA-TLV элемент FE может выбирать ошибку для возврата. Если FULLDATA-TLV для SET/SET-PROP в структуре пытается записать поле, доступное только для чтения, а в другое поле записать непригодное значение, FE может выбрать для возврата любую из этих ошибок.

Операция SET/SET-PROP для компоненты переменного размера с length = 0 не то же самое, что ее удаление. Если CE хочет удалить компоненту, следует применять операцию DEL с путем, указывающим компоненту массива или необязательную компоненту структуры.

7.1.7. RESULT TLV

RESULT-TLV является экземпляром TLV в соответствии с определением параграфа 6.2. Схема показана на рисунке.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Type = RESULT-TLV          |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Result Value  |                  Reserved                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 20. RESULT-TLV.


Таблица 4. Определенные значения результатов

Результат

Значение

Определение

E_SUCCESS

0x00

Успех.

E_INVALID_HEADER

0x01

Неуказанная ошибка заголовка.

E_LENGTH_MISMATCH

0x02

Размер заголовка не соответствует реальному размеру пакета.

E_VERSION_MISMATCH

0x03

Непреодолимое несоответствие версий.

E_INVALID_DESTINATION_PID

0x04

Destination PID не действителен для получателя сообщения.

E_LFB_UNKNOWN

0x05

LFB Class ID не известен получателю.

E_LFB_NOT_FOUND

0x06

LFB Class ID известен получателю но сейчас не используется.

E_LFB_INSTANCE_ID_NOT_FOUND

0x07

LFB Class ID известен, но указанного экземпляра класса не существует.

E_INVALID_PATH

0x08

Заданный путь не возможен.

E_COMPONENT_DOES_NOT_EXIST

0x09

Заданный путь возможен, но компонента не существует (например, попытка изменить не созданную строку таблицы).

E_EXISTS

0x0A

Заданный объект существует, но его не должно быть для успеха операции (например, попытка добавить имеющийся экземпляр LFB или индекс массива).

E_NOT_FOUND

0x0B

Заданного объекта нет, но он должен быть для успеха операции (например, попытка удалить отсутствующий экземпляр LFB или индекс массива).

E_READ_ONLY

0x0C

Попытка изменить значение, открытое только для чтения.

E_INVALID_ARRAY_CREATION

0x0D

Попытка создать массив с неразрешенный индексом (subscript).

E_VALUE_OUT_OF_RANGE

0x0E

Попытка установить значение параметра за пределами диапазона.

E_CONTENTS_TOO_LONG

0x0D

Попытка записи содержимого, превышающего размер целевого объекта (выход за пределы буфера).

E_INVALID_PARAMETERS

0x10

Любая другая ошибка в параметрах данных.

E_INVALID_MESSAGE_TYPE

0x11

Тип сообщения не приемлем.

E_INVALID_FLAGS

0x12

Неприемлемые для данного типа сообщения флаги.

E_INVALID_TLV

0x13

Блок TLV не приемлем для данного типа сообщения.

E_EVENT_ERROR

0x14

Неуказанная ошибка при обработке события.

E_NOT_SUPPORTED

0x15

Попытка выполнить пригодную операцию ForCES, которую получатель не поддерживает.

E_MEMORY_ERROR

0x16

Ошибка памяти при обработке сообщения (в сообщении ошибок нет).

E_INTERNAL_ERROR

0x17

Неуказанная ошибка при обработке сообщения (в сообщении ошибок нет).

0x18-0xFE

Резерв.

E_UNSPECIFIED_ERROR

0xFF

Неуказанная ошибка (FE не понимает, что неверно).

7.1.8. DATA TLV

FULLDATA-TLV имеет T=FULLDATA-TLV, 16 битов поля размера и данные (содержимое). Аналогично, SPARSEDATA-TLV имеет T=SPARSEDATA-TLV, 16-битовое поле length и данные (содержимое). В случае SPARSEDATA-TLV каждая компонента Value будет дополнительно инкапсулирована в ILV.

Ниже приведены правила кодирования FULLDATA-TLV и SPARSEDATA-TLV, примеры правил даны в Приложении C:

  1. ILV и TLV должны выравниваться по 32-битовым границам. Байты заполнения должны устанавливаться в 0 при передаче, а на приемной стороне должны игнорироваться.

  2. FULLDATA-TLV могут применяться в качестве определенного пути лишь в том случае, когда присутствует каждая компонента этого уровня пути. В примере 1(c) приложения C эта концепция иллюстрируется наличием всех компонент структуры S в представлении FULLDATA-TLV. Это требование сохраняется для всех полей фиксированного или переменного размера, как обязательных, так и необязательных.

    • При использовании FULLDATA-TLV кодировщик должен разместить данные для каждой компоненты в том же порядке, как они были определены в спецификации LFB. Это позволит извлечь данные при декодировании. Для примера 1 в Приложении C это предполагает, что кодер и декодер знают как была определена структура S.

    • В случае SPARSEDATA-TLV упорядочивать данные не требуется, поскольку I в ILV однозначно указывает компоненты. Примеры 1(a) и 1(b) в Приложении C иллюстрируют возможности кодирования SPARSEDATA-TLV.

  3. Внутри FULLDATA-TLV.

    • Значения для неделимых полей фиксированного размера задаются без инкапсуляции TLV.

    • Значения для неделимых полей переменного размера задаются внутри FULLDATA-TLV.

    • Значения для массивов задаются в форме index/subscript, за которой следует значение, как сказано в параграфе 7.1.1. Правила упаковки данных и продемонстрировано примерами в приложениях.

  1. Внутри SPARSEDATA-TLV.

    • Значения всех полей должны быть в форме ILV (32-битовый индекс, 32-битовое поле размера).

  2. FULLDATA-TLV не могут включать ILV.

  3. Блоки FULLDATA-TLV могут включать в себя другие FULLDATA-TLV для компонент переменного размера. Однозначность декодирования обеспечивается приведенным выше правилом 3.

7.1.9. Взаимосвязи SET и GET

Предполагается, что GET-RESPONSE будет удовлетворять приведенным ниже требованиям.

  • Это будет в точности то же определение пути, которое было передано в GET. Единственное различие заключается в том, что GET-RESPONSE будет содержать FULLDATA-TLV.

  • Должно быть возможно взять тот же GET-RESPONSE и преобразовать его в SET, просто сменив T в TLV операции.

  • Из этого правила имеется два исключения.

    1. При использовании селектора KEY с путем в операции GET этот селектор не возвращается в GET-RESPONSE и вместо него возвращается результат (см. примеры использования KEY).

    2. При выгрузке целой таблицы в GET отклик GET-RESPONSE, который просто меняет T, чтобы стать SET, будет завершать переписывание таблицы.

7.2. Визуализация протокольного кодирования

На рисунке 21 показана общая схема PL PDU. За главным заголовком (main hdr) следует один или множество селекторов LFB, каждый из которых может содержать одну или множество операций.


main hdr (Config в данном случае)
     |
     |
     +--- T = LFBselect
     |        |
     |        +-- LFBCLASSID
     |        |
     |        |
     |        +-- LFBInstance
     |        |
     |        +-- T = SET
     |        |   |
     |        |   +--  // одна или множество целей путей
     |        |        // с добавлением здесь их данных
     |        |
     |        +-- T  = DEL
     |        .   |
     |        .   +--  // одна или множество целей путей для удаления
     |
     |
     +--- T = LFBselect
     |        |
     |        +-- LFBCLASSID
     |        |
     |        |
     |        +-- LFBInstance
     |        |
     |        + -- T= SET
     |        |    .
     |        |    .
     |        + -- T= DEL
     |        |    .
     |        |    .
     |        |
     |        + -- T= SET
     |        |    .
     |        |    .
     |
     |
     +--- T = LFBselect
             |
             +-- LFBCLASSID
             |
             +-- LFBInstance
             .
             .
             .

Рисунок 21. Логическая схема PL PDU.

На рисунке 22 представлен более подробный пример общей схемы операции внутри целевого выбора LFB. Идея состоит в демонстрации различных уровней вложенности, которые можно пройти для получения целевого пути.


T = SET
|  |
|  +- T = Path-data
|       |
|       + -- flags
|       + -- IDCount
|       + -- IDs
|       |
|       +- T = Path-data
|          |
|          + -- flags
|          + -- IDCount
|          + -- IDs
|          |
|          +- T = Path-data
|             |
|             + -- flags
|             + -- IDCount
|             + -- IDs
|             + -- T = KEYINFO-TLV
|             |    + -- KeyID
|             |    + -- KEY_DATA
|             |
|             + -- T = FULLDATA-TLV
|                  + -- data
|
|
T = SET
|  |
|  +- T = Path-data
|  |  |
|  |  + -- flags
|  |  + -- IDCount
|  |  + -- IDs
|  |  |
|  |  + -- T = FULLDATA-TLV
|  |          + -- data
|  +- T = Path-data
|     |
|     + -- flags
|     + -- IDCount
|     + -- IDs
|     |
|     + -- T = FULLDATA-TLV
|             + -- data
T = DEL
   |
   +- T = Path-data
        |
        + -- flags
        + -- IDCount
        + -- IDs
        |
        +- T = Path-data
           |
           + -- flags
           + -- IDCount
           + -- IDs
           |
           +- T = Path-data
              |
              + -- flags
              + -- IDCount
              + -- IDs
              + -- T = KEYINFO-TLV
              |    + -- KeyID
              |    + -- KEY_DATA
              +- T = Path-data
                   |
                   + -- flags
                   + -- IDCount
                   + -- IDs

Рисунок 22.Образец схемы операции.

В приложении D показан более выразительный набор примеров кодирования данных.

7.3. Основные LFB протокола ForCES

Имеется два блока LFB, которые применяются для управления работой протокола ForCES, а также взаимодействия с FE и CE:

  • FE Protocol LFB;

  • FE Object LFB.

Хотя эти LFB имеют такую же форму и интерфейс, как другие LFB, они выделяются во многих отношениях. Они имеют фиксированный общеизвестных LFB Class и Instance ID. Эти блоки определены статически (динамическое создание экземпляров не разрешено), а их статус не может быть изменен протоколом — любые операции по изменению состояния этих LFB (например, запрет LFB) должны приводить к ошибке. Кроме того, эти LFB должны существовать до того, как будет передано или принято первое сообщение ForCES. Все компоненты этих LFB должны иметь предопределенные значения для использования по умолчанию. Наконец, эти LFB не имеют входных и выходных портов и не интегрируются в топологию intra-FE LFB.

7.3.1. FE Protocol LFB

FE Protocol LFB является логическим объектом в каждом FE, который служит для управления протоколом ForCES. Идентификатор класса для FE Protocol LFB имеет значение 0x2, а идентификатор экземпляра — 0x1. В FE должен быть один и только один экземпляр FE Protocol LFB. Компоненты FE Protocol LFB имеют предопределенные значения, принятые по умолчанию, которые указаны здесь. Пока значения не заданы явно с помощью сообщений Config от CE, должны применяться заданные по умолчанию значения для корректной работы протокола.

Формальное определение FE Protocol Object LFB приведено в Приложении B.

7.3.1.1. Возможности FE Protocol

Возможности FE Protocol доступны только для чтения.

7.3.1.1.1. SupportableVersions

Версии протокола ForCES, поддерживаемые FE.

7.3.1.1.2. Компоненты FE Protocol

Компоненты FE Protocol (могут считываться и устанавливаться).

7.3.1.1.2.1. CurrentRunningVersion

Текущая работающая версия протокола ForCES.

7.3.1.1.2.2. FEID

Индивидуальный идентификатор FE.

7.3.1.1.2.3. MulticastFEIDs

Список групповых идентификаторов FE — идентификаторы групп, в которые входит FE. Идентификаторы задаются CE.

7.3.1.1.2.4. CEHBPolicy

Политика CE для heartbeat. Эта политика вместе с параметром CE Heartbeat Dead Interval (CE HDI), как описано ниже, определяет для FE рабочие параметры проверки живучести CE. Смысл значений политики описан ниже.

  • 0 (по умолчанию) — CE будет передавать сообщения Heartbeat элементам FE всякий раз по прошествии интервала в течение которого от CE к FE не было передано других сообщения PL (см. параграфы 4.3.3 и 7.10). Описанная ниже компонента CE HDI привязана к этой политике.

  • 1 — CE не будет генерировать сообщения HB. Это означает, что CE не желает, чтобы FE проверяли его живучесть.

  • прочие — резерв.

7.3.1.1.2.5. CEHDI

CE Heartbeat Dead Interval (CE HDI) — интервал, используемый FE для проверки живучести CE. Если FE не получил от CE сообщений в течение этого интервала, он считает, что связь потеряна в результате «умирания» CE или его выхода из ассоциации (по умолчанию 30 секунд).

7.3.1.1.2.6. FEHBPolicy

Политика FE для heartbeat, которая вместе с параметром FE Heartbeat Interval (FE HI) определяет рабочие параметры поведения FE, по которым CE может оценить его живучесть. Смысл значений политики описан ниже.

  • 0 (по умолчанию) — FE не следует генерировать сообщений Heartbeat. В этом варианте CE отвечает за проверку живучести FE путем установки в заголовке PL флага ACK = AlwaysACK. FE будет отвечать CE при получении от того запросов Heartbeat Request. (см. параграфы 4.3.3 и 7.10).

  • 1 — FE должен активно передавать сообщения Heartbeat по истечении интервала, заданного FE HI, если не было других сообщений от FE в течение этого интервала, как описано в параграфе 4.3.3.

  • прочие — резерв.

7.3.1.1.2.7. FEHI

FE Heartbeat Interval (FE HI) — интервал, по истечении которого FE следует передать сообщение HB, если в течение этого интервала не было передано других сообщений от FE к CE, как описано в параграфе 4.3.3 (по умолчанию 500 с).

7.3.1.1.2.8. CEID

Primary CEID — идентификатор CE, с которым элемент FE связан.

7.3.1.1.2.9. LastCEID

Последний Primary CEID — CEID идентификатор последнего CE, с которым был FE связан. Этот идентификатор CE передается новому Primary CEID.

7.3.1.1.2.10. BackupCEs

Список резервных CE, которые FE может использовать (см. раздел 8).

7.3.1.1.2.11. CEFailoverPolicy

Политика CE для восстановления при отказах — задает поведение FE при потере связи с CE. Политика переключения CE при отказе тесно связана с параграфами 7.3.1.1.2.8, 7.3.1.1.2.10, 7.3.1.1.2.12 и разделом 8. При потере связи активизируется одно из перечисленных ниже правил в зависимости от настройки.

  • 0 (по умолчанию) — FE следует незамедлительно прервать работу и перейти в состояние FE OperDisable.

  • 1 — FE следует продолжать работу и делать то, что возможно без связи с CE. Обычно это требует от FE поддержки изящного перезапуска CE (и указания такой поддержки в своих возможностях). Если интервал CEFTI истекает до того, как FE восстановит связь с основным CEID (параграф 7.3.1.1.2.8) или одним из резервных CE (параграф 7.3.1.1.2.10), FE будет прекращать работу.

  • прочие — резерв.

7.3.1.1.2.12. CEFTI

Интервал ожидания при отказе CE (CEFTI15) — время ожидания, связанное с политикой при отказе CE (CEFailoverPolicy) 0 или 1. По умолчанию время ожидания составляет 300 секунд. Отметим, что для CEFTI следует устанавливать значение существенно больше CEHDI, поскольку при этом тайм-ауте FE прекращает работу.

7.3.1.1.2.13. FERestartPolicy

Политика перезапуска FE — задает поведение элемента FE при его перезапуске в результате отказа или по иным причинам, требующим перезагрузки. Возможные значения указаны ниже.

  • 0 (по умолчанию) — FE перезапускается «с нуля» и в этом случае ему следует начинать с фазы pre-association.

  • прочие — резерв на будущее.

7.3.2. FE Object LFB

FE Object LFB представляет собой логический объект, содержащийся в каждом FE и включающий компоненты, относящиеся к самому FE, а не к работе протокола ForCES.

Формальное определение FE Object LFB дано в [RFC5812]. Модель отражает свойства верхнего уровня элемента FE, которые CE нужно знать для начала работы с FE. Идентификатор класса для этого класса LFB также задан в [RFC5812]. Единственный экземпляр этого класса существует всегда и всегда имеет внутри этого класса идентификатор экземпляра 0x1. Общепринято, хотя и не обязательно, получать большую часть информации о компонентах и возможностях из этого экземпляра LFB для CE, когда тот начинает операции управления элементом FE.

7.4. Семантика направления передачи сообщений

Напомним, что PL работает в режиме «ведущий(CE)-ведомый(FE)». LFB размещаются в FE и контролируются CE.

Когда приходит сообщение от CE, селектор LFB (класс и экземпляр) задает выбор LFB размещенного в элементе FE.

Когда сообщение от FE приходит в CE, селектор LFB (класс и экземпляр) указывает LFB-источник, находящийся в FE.

7.5. Сообщения для ассоциаций

Сообщения ForCES Association служат для организации и разрыва ассоциаций между элементами FE и CE.

7.5.1. Сообщение Association Setup

Это сообщение передается FE элементу CE для организации между ними связи (ассоциации) ForCES.

Направление передачи

От FE к CE.

Заголовок сообщения

Поле MessageType в заголовке имеет значение AssociationSetup. Флаг ACK в заголовке должен игнорироваться и всегда предполагается отклик на сообщение Association Setup от получателя (CE), независимо от результата. Поле correlator в заголовке устанавливается так, чтобы FE мог сопоставить сообщение с полученным откликом от CE. FE может установить в заголовке 0 для идентификатора источника, запрашивая тем самым у CE назначение для него FE ID в сообщении Setup Response.

Тело сообщения

Тело сообщения Association Setup может включать от 0 до 2 LFBselect TLV, как описано в параграфе 7.1.5. Сообщение Association Setup работает только с FE Object LFB и FE Protocol LFB, поэтому идентификатор класса LFB в LFBselect TLV указывает только эти два типа LFB.

OPER-TLV в LFBselect TLV определяется как операция REPORT. В этом сообщении может быть анонсировано несколько компонент с использованием операции REPORT, чтобы позволить FE заявить свои конфигурационные параметры без запроса. Здесь могут содержаться предлагаемые FE значения типа HB Interval или FEID. Структура OPER-TLV показана ниже.

OPER-TLV для Association Setup

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Type = REPORT              |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    PATH-DATA-TLV for REPORT                   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 23. OPER-TLV для Association Setup.

Type

Для сообщений Association Setup определен только один тип операции.

REPORT — задает для FE предоставление какого-либо «отчета» CE.

PATH-DATA-TLV для REPORT

Обычно это формат PATH-DATA-TLV, указанный в разделе 7 в определении PATH-DATA BNF. PATH-DATA-TLV для операции REPORT может включать блоки FULLDATA-TLV, не следует включать какие-либо RESULT-TLV в данные. RESULT-TLV определен в параграфе 7.1.7, а FULLDATA-TLV — в параграфе 7.1.8.

На рисунке формат PDU показан в виде дерева.

main hdr (type =  Association Setup)
     |
     |
     +--- T = LFBselect
     |        |
     |        +-- LFBCLASSID = FE Object
     |        |
     |        |
     |        +-- LFBInstance = 0x1
     |
     +--- T = LFBselect
              |
              +-- LFBCLASSID = FE Protocol Object
              |
              |
              +-- LFBInstance = 0x1
                    |
                    +---OPER-TLV = REPORT
                        |
                        +-- Path-data для одной или множества компонент

Рисунок 24. Формат PDU для сообщения Association Setup.


7.5.2. Сообщение Association Setup Response

Это сообщение CE передает элементу FE в ответ на сообщение Setup. Оно показывает FE результат попытки создания ассоциации.

Направление передачи

От CE к FE.

Заголовок сообщения

MessageType в заголовке имеет значение AssociationSetupResponse. Флаг ACK в заголовке должен игнорироваться и всегда предполагается, что сообщение Setup Response не будет возвращать каких-либо откликов от получателя (FE). Для идентификатора получателя в заголовке устанавливается значение идентификатора источника из соответствующего сообщения Association Setup, если этот идентификатор не был нулевым. В последнем случае CE будет назначать FE ID и указывать его в качестве идентификатора получателя.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        Type = ASRresult       |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                  Association Setup Result                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 25. OPER-TLV для ASResult.

Type (16 битов)

TLV имеет тип ASResult.

Length (16 битов)

Размер TLV с учетом полей T и L (в октетах).

Association Setup result (32 бита)

Это поле показывает результат сообщения Setup — успех или отказ CE. Значения приведены ниже.

0 = успех;

1 = непригодный FE ID;

2 = доступ отвергнут.

Формат PDU показан на рисунке в виде дерева.


main hdr (type =  Association Setup Response)
 |
 |
 +--- T = ASResult-TLV

Рисунок 26. Формат PDU для сообщения Association Setup Response.

7.5.3. Сообщение Association Teardown

Это сообщение может быть передано FE или CE любому элементу ForCES для завершения ассоциации ForCES с ним.

Направление передачи

От CE к FE, от FE к CE или от CE к CE.

Заголовок сообщения

MessageType в заголовке имеет значение AssociationTeardown. Флаг ACK должен игнорироваться. Поле correlator в заголовке должно быть установлено в 0 при передаче и должно игнорироваться получателем.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        Type = ASTreason       |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Teardown Reason                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 27. OPER-TLV для ASTreason.

Type (16 битов)

TLV имеет тип ASTreason.

Length (16 битов)

Размер TLV с учетом полей T и L (в октетах).

Teardown reason (32 бита)

Указывает причину разрыва ассоциации. Несколько кодов причин показано ниже:

0 — обычное прерывание администратором;

1 — ошибка (потеря heartbeat);

2 — ошибка (нехватка пропускной способности);

3 — ошибка (нехватка памяти);

4 — ошибка (авария приложения);

255 — ошибка (прочее).

Формат PDU в виде дерева представлен на рисунке.

main hdr (type =  Association Teardown)
 |
 |
 +--- T = ASTreason-TLV

Рисунок 28. Формат PDU для сообщения Association Teardown.

7.6. Конфигурационные сообщения

Сообщения ForCES Configuration служат CE для настройки FE в ForCES NE и возврата результата элементу CE.

7.6.1. Сообщение Config

Это сообщение передается от CE к FE для настройки компонент LFB в FE, а также для управления подпиской CE на события LFB.

Как обычно, сообщение Config состоит из общего заголовка, за которым следует тело сообщения с одним или множеством TLV. Подробное описание сообщения приведено ниже.

Направление передачи

От CE к FE.

Заголовок сообщения

MessageType в заголовке имеет значение Config. Флаг ACK в заголовке может иметь любое значение, определенное в параграфе 6.1, и служит для индикации ожидания отклика от FE.

OPER-TLV для Config

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Type                 |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        PATH-DATA-TLV                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 29. OPER-TLV для сообщения Config.


Type

Тип операции для Config. Ниже перечислены пять16 типов операций, определенных для сообщений Config.

SET — служит для установки компонент LFB.

SET-PROP — служит для установки свойств компонент LFB.

DEL — служит для удаления некоторых компонент LFB.

COMMIT — эта операция передается FE для представления транзакции 2PC. COMMIT TLV является пустым (не содержит V) и имеет размер 4 октета (только для заголовка).

TRCOMP — эта операция передается FE для указания успеха (с точки зрения NE) транзакции 2PC. TRCOMP TLV является пустым (не содержит V) и имеет размер 4 октета (только для заголовка).

PATH-DATA-TLV

Обычно это формат PATH-DATA-TLV, указанный в разделе 7 в определении PATH-DATA BNF. Ограничение использования PATH-DATA-TLV для операций SET/SET-PROP состоит в том, что этот блок должен включать FULLDATA-TLV или SPARSEDATA-TLV, но недопустимо включение RESULT-TLV. Ограничение использования PATH-DATA-TLV для операции DEL заключается в том, что блок может включать FULLDATA-TLV или SPARSEDATA-TLV, но недопустимо включение RESULT-TLV. Блок RESULT-TLV определен в параграфе 7.1.7, а FULLDATA-TLV и SPARSEDATA-TLV — в параграфе 7.1.8.

Примечание. Для подписки на события используются отдельные LFB, определяющие эти события.

Формат PDU в виде дерева представлен на рисунке.

main hdr (type = Config)
 |
 |
 +--- T = LFBselect
 .        |
 .        +-- LFBCLASSID = целевой класс LFB
 .        |
          |
          +-- LFBInstance = целевой экземпляр LFB
          |
          |
          +-- T = operation { SET }
          |   |
          |   +--  // Одна или множество целей пути
          |        // связанных с FULLDATA-TLV или SPARSEDATA-TLV(s)
          |
          +-- T = operation { DEL }
          |   |
          |   +--  // Одна или множество целей пути
          |
          +-- T = operation { COMMIT } //COMMIT TLV является пустым TLV
                   .
                   .

Рисунок 30. Формат PDU для сообщения Configuration.


7.6.2. Сообщение Config Response

Это сообщение FE передает элементу CE в ответ на сообщение Config. Сообщение показывает результат Config в FE, а также содержит подробные сведения, относящиеся к настройке каждой компоненты.

Направление передачи

От FE к CE.

Заголовок сообщения

MessageType в заголовке имеет значение Config Response. Флаг ACK в заголовке всегда игнорируется и для сообщений Config Response никогда не ожидается отклика со стороны получателя (CE).

OPER-TLV для Config Response

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Type                 |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        PATH-DATA-TLV                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 31. OPER-TLV для Config Response.


Type

Тип операции для сообщения Config Response. Ниже перечислены четыре17 типа операций, определенных для сообщений Config Response.

SET-RESPONSE — для получения отклика от операции SET для компонент LFB.

SET-PROP-RESPONSE — для получения отклика от операции SET SET-PROP для свойств компонент LFB.

DEL-RESPONSE — для получения отклика от операции DELETE для компонент LFB.

COMMIT-RESPONSE — эта операция передается элементу CE для подтверждения успешной подачи транзакции 2PC. COMMIT-RESPONSE TLV должен включать RESULT-TLV, показывающий успех или отказ.

PATH-DATA-TLV

Обычно это формат PATH-DATA-TLV, указанный в разделе 7 в определении PATH-DATA BNF. Ограничение использования PATH-DATA-TLV для операции SET-RESPONSE состоит в том, что блок должен содержать RESULT-TLV. Ограничение использования PATH-DATA-TLV для операции DEL-RESPONSE состоит в том, что блок должен содержать RESULT-TLV. Определение RESULT-TLV дано в параграфе 7.1.7.

На рисунке формат PDU представлен в виде дерева.


main hdr (type = ConfigResponse)
|
|
+--- T = LFBselect
.        |
.        +-- LFBCLASSID = целевой класс LFB
.        |
         |
         +-- LFBInstance = целевой экземпляр LFB
         |
         |
         +-- T = operation { SET-RESPONSE }
         |   |
         |   +--  // Одна или множество целей пути,
         |        // связанных с FULLDATA-TLV или SPARSEDATA-TLV
         |
         +-- T = operation { DEL-RESPONSE }
         |   |
         |   +--  //  Одна или множество целей пути
         |
         +-- T = operation { COMMIT-RESPONSE }
         |           |
         |           +--  RESULT-TLV

Рисунок 32. Формат PDU для сообщения Config Response.

7.7. Запросы

Сообщения ForCES Query используются CE для запроса у LFB в элементе FE информации типа компонент, возможностей, статистики LFB и пр. Группа Query включает сообщения Query и Query Response.

7.7.1. Сообщение Query

Сообщение Query состоит из общего заголовка и тела сообщения, включающего один или множество TLV с данными.

Направление передачи

От CE к FE.

Заголовок сообщения

MessageType в заголовке имеет значение Query. Поле ACK в заголовке игнорируется и для сообщений Query всегда ожидается полный отклик. В заголовке указывается поле Correlator для сопоставления с откликом FE.

OPER-TLV для Query

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Type = GET/GET-PROP        |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    PATH-DATA-TLV for GET/GET-PROP             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 33. OPER-TLV для сообщения Query.


Type

Один из двух определенных для сообщения типов операции.

GET — запрос компонент LFB.

GET-PROP — запрос свойств компонент LFB.

PATH-DATA-TLV для GET/GET-PROP

Обычно это формат PATH-DATA-TLV, указанный в разделе 7 в определении PATH-DATA BNF. Ограничение использования PATH-DATA-TLV для операции GET/GET-PROP состоит в том, что в него недопустимо включать SPARSEDATA-TLV или FULLDATA-TLV и RESULT-TLV.

Формат PDU в виде дерева представлен на рисунке.


main hdr (type = Query)
 |
 |
 +--- T = LFBselect
 .        |
 .        +-- LFBCLASSID = класс целевого LFB
 .        |
          |
          +-- LFBInstance = экземпляр целевого LFB
          |
          |
          +-- T = operation { GET }
          |   |
          |   +--  // Одна или множество целей пути
          |
          +-- T = operation { GET }
          .   |
          .   +--  // Одна или множество целей пути
          .

Рисунок 34. Формат PDU для сообщения Query.

7.7.2. Сообщение Query Response

При получении сообщения Query его следует обработать и определить результат запроса. Получатель сообщения передает этот результат отправителю запроса в сообщении Query Response. Результатом может быть запрошенная информация или коды ошибок, если запрос привел к отказу.

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

Направление передачи

От FE к CE.

Заголовок сообщения

MessageType в заголовке имеет значение QueryResponse. Флаг ACK в заголовке игнорируется. Поскольку само сообщение является откликом, оно не требует отклика для себя.

OPER-TLV для Query Response

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Type = GET-RESPONSE/GET-PROP-RESPONSE|    Length               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        PATH-DATA-TLV for GET-RESPONSE/GET-PROP-RESPONSE       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 35. OPER-TLV для сообщения Query Response.


Type

Один из двух типов операций, определенных для отклика на запрос:

GET-RESPONSE — отклик на запрос GET для компонент LFB.

GET-PROP-RESPONSE — отклик на запрос GET-PROP для свойств компонент LFB.

PATH-DATA-TLV для GET-RESPONSE/GET-PROP-RESPONSE

Обычно это формат PATH-DATA-TLV, указанный в разделе 7 в определении PATH-DATA BNF. PATH-DATA-TLV для операции GET-RESPONSE может содержать SPARSEDATA-TLV, FULLDATA-TLV и/или RESULT-TLV. Блок RESULT-TLV определен в параграфе 7.1.7, а SPARSEDATA-TLV и FULLDATA-TLV — в параграфе 7.1.8.

Формат PDU в виде дерева представлен на рисунке.


main hdr (type = QueryResponse)
  |
  |
  +--- T = LFBselect
  .        |
  .        +-- LFBCLASSID = target LFB class
  .        |
           |
           +-- LFBInstance = target LFB instance
           |
           |
           +-- T = operation { GET-RESPONSE }
           |   |
           |   +--  // Одна или множество целей пути
           |
           +-- T = operation { GET-PROP-RESPONSE }
           .   |
           .   +--  // Одна или множество целей пути
           .

Рисунок 36. Формат PDU для сообщения Query Response.

7.8. Уведомление о событии

Уведомления о событиях используются FE для асинхронного информирования CE о произошедших в FE событиях.

Все события, которые могут генерироваться в FE являются предметом подписки для CE, который может организовать такую подписку с помощью сообщения Config с операцией SET-PROP, включающей пути, которые указывают события, как определено в библиотеке LFB и описано в модели FE.

Как обычно, сообщение Event Notification состоит из общего заголовка и тела сообщения, включающего один или множество TLV с данными.

Направление передачи

От FE к CE.

Заголовок сообщения

MessageType в заголовке сообщения имеет значение EventNotification. Флаг ACK должен игнорироваться CE и для сообщений Event Notification отправитель никогда не ждет отклика.

OPER-TLV для Event Notification

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Type = REPORT              |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    PATH-DATA-TLV for REPORT                   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 37. TLV для Event Notification.

Type

Для сообщения Event Notification определена единственная операция:

REPORT — для передачи элементом FE информации о том или ином событии.

PATH-DATA-TLV для REPORT

Обычно это формат PATH-DATA-TLV, указанный в разделе 7 в определении PATH-DATA BNF. Блок PATH-DATA- TLV для операции REPORT может содержать FULLDATA-TLV или SPARSEDATA-TLV, но недопустимо включать в данные какие-либо RESULT-TLV.

Формат PDU в виде дерева представлен на рисунке.

main hdr (type = Event Notification)
  |
  |
  +--- T = LFBselect
             |
             +-- LFBCLASSID = target LFB class
             |
             |
             +-- LFBInstance = target LFB instance
             |
             |
             +-- T = operation { REPORT }
             |   |
             |   +--  // Одна или множество целей пути, 
             |        // связанных с FULL/SPARSE DATA TLV
             +-- T = operation { REPORT }
             .   |
             .   +--  // Одна или множество целей пути,
             .        // связанных с FULL/SPARSE DATA TLV

Рисунок 38. Формат PDU для сообщения Event Notification.

7.9. Сообщение PacketRedirect

Сообщения Redirect используются для передачи пакетов между CE и FE. Обычно эти пакеты содержат данные управления, но они могут быть также пакетами, которым нужна дополнительная обработка (исключение или вышележащие уровни). Возможны также сообщения, содержащие только метаданные.

Направление передачи

От CE к FE или от FE к CE.

Заголовок сообщения

MessageType в заголовке имеет значение PacketRedirect.

Тело сообщения

Сообщение содержит один или множество блоков TLV, которые включают пересылаемый пакет или описывают его. В качестве TLV используются Redirect TLV (Type=Redirect). Формат Redirect TLV показан ниже.


 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        Type = Redirect        |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Meta Data TLV                          |
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Redirect Data TLV                      |
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 39. Redirect_Data TLV.

TLV метаданных

Этот TLV задает метаданные, связанные с расположенными вслед за ними пересылаемыми данными.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Type = METADATA-TLV        |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Meta Data ILV                          |
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~                           ...                                 ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Meta Data ILV                          |
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 40. METADATA-TLV.


ILV метаданных

Этот формат Identifier-Length-Value используется для описания одного элемента метаданных.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Meta Data ID                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Length                                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Meta Data Value                        |
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 41. ILV для метаданных.

Meta Data ID представляет собой идентификатор метаданных, который статически задается в определении LFB.

TLV пересылаемых данных

Этот блок TLV описывает один пакет данных, пересылаемый с помощью операции Redirect.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Type = REDIRECTDATA-TLV    |               Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Redirected Data                        |
.                                                               .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок 42. REDIRECTDATA-TLV.

Redirected Data

Это поле содержит пакет, который пересылается с использованием сетевого порядка байтов. Пакет следует выравнивать по 32-битовой границе, как и все прочие данные в TLV. Метаданные указывают тип пересылаемого пакета, что упрощает декодирование инкапсулированных данных.

Формат PDU в виде дерева представлен на рисунке.


main hdr (type = PacketRedirect)
        |
        |
        +--- T = Redirect
        .        |
        .        +-- T = METADATA-TLV
                 |          |
                 |          +--  Meta Data ILV
                 |          |
                 |          +--  Meta Data ILV
                 |          .
                 |          .
                 |
                 +-- T = REDIRECTDATA-TLV
                     |
                     +--  // Redirected Data

Рисунок 43.Формат PDU для сообщения Packet Redirect.

7.10. Сообщение Heartbeat

Сообщение Heartbeat (HB) используется одним из элементов ForCES (FE или CE) для асинхронного уведомления одного или множества других элементов ForCES в том же ForCES NE о своей живучести. Используемый подход с учетом трафика описан в параграфе 4.3.3.

Сообщения Heartbeat передаются элементами ForCES периодически. Параметризация и правила передачи сообщений heartbeat для FE определяются как компоненты FE Protocol Object LFB и могут быть установлены элементами CE с помощью сообщений Config. Heartbeat слегка отличается от остальных сообщений протокола тем, что оно включает лишь базовый заголовок без тела сообщения.

Направление передачи

От FE к CE или от CE к FE.

Заголовок сообщения

MessageType в заголовке сообщения имеет значение Heartbeat. Используемые механизмы HB описаны в параграфе 4.3.3. Для флага ACK в заголовке должно устанавливаться значение NoACK или AlwaysACK.

  • NoACK означает, что HB не запрашивает отклик.
  • AlwaysACK указывает, что отправитель сообщения HB всегда ждет отклика от получателя. По правилам, приведенным в параграфе 7.3.1, только CE может передавать сообщения HB для проверки живучести FE. Для простоты и по причине минималистической природы HB откликов на сообщение HB служит другое сообщение HB, т. е. специального сообщения HB Response не определено. Когда FE получает сообщение HB с флагом AlwaysACK от элемента CE, этот FE должен незамедлительно передать сообщение HB. В сообщении HB, переданном FE в качестве отклика на AlwaysACK, идентификаторы отправителя и получателя должны поменяться местами, чтобы идентификатор FE указывал источник, а CE ID — получателя, а флаг ACK должен быть заменен на NoACK. Элементам CE недопустимо отвечать на сообщения HB с флагом AlwaysACK.

  • При установке флагов, отличных от NoACK и AlwaysACK, будет считаться, что HB имеет флаг NoACK.

Поле correlator в заголовке HB следует устанавливать так, чтобы отправитель мог сопоставить отклик с запросом. Поле correlator можно игнорировать, если отклика не ожидается.

Тело сообщения

Тело сообщения Heartbeat пусто.

8. Поддержка высокого уровня доступности

Протокол ForCES обеспечивает механизмы резервирования CE и восстановления при отказах для поддержки высокого уровня доступности (High Availability или HA) в соответствии с [RFC3654]. Резервирование FE и взаимодействие между элементами FE выходит за рамки этого документа. В одном элементе ForCES NE может присутствовать множество избыточных CE и FE. Однако в любой момент только один первичный элемент CE может управлять FE, хотя допускается множество вторичных CE. Уровень протокола (PL) в FE и CE знает о первичном и вторичных CE. Эта информация (первичный и вторичные CE) настраивается в PL элементов FE и CE в процессе создания ассоциации (pre-association) с помощью менеджеров FEM и CEM, соответственно. Управляющие FE сообщения передает только первичный CE.

8.1. Связь с FE Protocol

Параметризация HA в FE выполняется путем настройки FE Protocol Object LFB (см. Приложение B и параграф 7.3.1). Параметры FE Heartbeat Interval, CE Heartbeat Dead Interval и правила CE Heartbeat помогают обнаруживать проблемы связи между FE и CE. Политика CE для восстановления при отказах определяет реакцию на обнаружение отказа.

На рисунке 44 показана машина состояний с учетом новых состояний, упрощающих восстановление соединений.

(CE передал Teardown||    +-----------------+
  потеря связи) &&        | Pre-association |
политика восстан. CE = 0  | (Организуется   |
      +------------>-->-->|  ассоциации)    +<----+
      |                   |                 |     |
      |     CE передал    +--------+--------+     |
      |     Association        |                  | отсчет CFTI
      |       Setup            V                  | завершен
      |     ___________________+                  | 
      |     |                                     |
      |     V                                     ^
    +-+-----------+                          +-------+-----+
      |             |                          | Нет         |
      |             |  (CE передал Teardown || | ассоциации  |
      |             |    Lost association) &&  |             |
      | Associated  |  CE failover policy = 1  | (Можно      |
      |             |                          | продолжать  |
      |             |---------->------->------>|  пересылку) |
      |             |                          |             |
      +-------------+                          +-------------+
           ^                                         V
           |                                         |
           |            CE передал                   |
           |            Association                  |
           |            Setup Responce               |
           +_________________________________________+

Рисунок 44. Машина состояний FE с учетом HA.

Переходы между состояниями до ассоциации, а также при наличии и отсутствии связи описаны в параграфе 4.2.

При отказе коммуникаций между FE и CE (который связан с CE или каналом, но не с FE) TML в элементе FE укажет FE PL на этот отказ или проблема будет обнаружена с помощью сообщений HB между FE и CE. Коммуникационный отказ, независимо от способа его обнаружения, должен считаться потерей ассоциации между CE и соответствующим FE.

Если для политики восстановления в FE (FEPO) установлено значение 0 (принято по умолчанию), элемент незамедлительно перейдет в фазу pre-association. Это означает, что при восстановлении связи все состояния FE придется организовывать заново.

Если для политики восстановления в FE (FEPO) установлено значение 1, это говорит о способности FE к перезапуску в режиму HA. В таком случае FE переходит в состояние отсутствия связи и запускается таймер CEFTI. Элемент FE может продолжать пересылку пакетов, находясь в этом состоянии. Он может также переключиться на любой из настроенных вторичных CE, перебирая из по кругу. Сначала он добавляет свой первичный CE в конец списка резервных CE и устанавливает основным первый из списка резервных CE. После этого предпринимается попытка организовать ассоциацию с новым первичным CE. Если в течение отсчета таймера CEFTI не удалось организовать ассоциацию ни с одним из вторичных CE, элемент FE переходит в состояние pre-association.

Если FE, находясь вне ассоциации, удается соединиться с новым первичным CE до завершения отсчета CEFTI, он переходит в связанное состояние. После восстановления связи FE пытается восстановить состояние, которое могло быть потеряно за время отсутствия связи. Способы этого восстановления выходят за рамки документа.

На рисунке 45 показана последовательность сообщений ForCES, которые FE применяет при попытке восстановить связь.

  FE                   Основной CE       Резервный CE
  |                       |                    |
  | Обмен Asso Estb,Caps  |                    |
1 |<--------------------->|                    |
  |                       |                    |
  |   Все сообщения       |                    |
2 |<--------------------->|                    |
  |                       |                    |
  |                       |                    |
  |                   FAILURE                  |
  |                                            |
  |         Обмен Asso Estb, Caps              |
3 |<------------------------------------------>|
  |                                            |
  |       Event Report (отказ основного CE)    |
4 |------------------------------------------->|
  |                                            |
  |               Все сообщения                |
5 |<------------------------------------------>|

Рисунок 45. Переключение CE в режиме Report Primary.


Требуется протокол синхронизации элементов CE для поддержки быстрого восстановления при отказах, а также для решения некоторых других вопросов, однако это не входит в сферу протокола ForCES и не рассматривается в данном документе.

Явное сообщение (Config с установкой компоненты первичного CE в FE Protocol Object) от первичного CE также может служить для смены первичного CE в процессе обычной работы FE.

Отметим, что элементы FE в ForCES NE могут также использовать групповой идентификатор CE ID, т. е. они могут быть связаны с группой CE (это предполагает использование протокола синхронизации между CE, который выходит за рамки этой спецификации). В таких случаях потеря ассоциации будет означать потерю связи со всей группой CE. Описанные выше механизмы также применимы для этого случая. Однако, если вторичный CE тоже использует групповой идентификатор потерянной связи, FE придется создавать новую ассоциацию с другим CE ID. При наличии такой возможности FE может сначала предпринять попытку создать новую ассоциацию с исходным первичным CE, используя другой (не групповой) идентификатор CE ID.

8.2. Ответственность за HA

Уровень TML

  1. TML контролирует доступность логический соединений и восстановление при отказах.

  2. TML также контролирует управление партнерским HA.

На этом уровне роль TML заключается в контроле всех нижележащих уровней (например, адресов IP и MAC), а также соответствующих каналов.

Уровень PL

Все остальные функции, включая настройку поведения HA в процессе установки, идентификаторы CE для указания первичных и вторичных элементов CE, протокольные сообщения для уведомления об отказе (Event Report), сообщения Heartbeat для обнаружения отказов, сообщения для смены первичного CE (Config) и другие операции, связанные с HA, лежат в сфере ответственности уровня PL.

При недоступности пути к первичному CE уровень TML будет принимать меры по переходу на резервный путь, если это возможно. Если CE совсем не доступен, уровень PL будет уведомлен об этом и предпримет подобающие действия, описанные выше.

9. Вопросы безопасности

Раздел 8 рамочного документа ForCES [RFC3746] включает подробные сведения о разных угрозах безопасности, возможном влиянии этих угроз на протокол и возможных ответах на угрозы. Данный документ не повторяет этого рассмотрения, а просто рекомендует читателю обратиться к описанию архитектуры ForCES [RFC3746].

Уровень ForCES PL использует услуги защиты, предоставляемые уровнем ForCES TML, который обеспечивает проверку подлинности конечных точек и сообщений, а также защиту конфиденциальности. Служба аутентификации конечных точек вызывается на этапе организации соединения (фаза pre-association), тогда как аутентификация сообщений используется при получении элементом FE или CE каждого сообщения от своего партнера.

Ниже перечислены базовые механизмы защиты, которые требуются для ForCES PL.

  • Управление безопасностью на уровне сессии — после организации выбранного уровня защиты (No Security, Authentication, Confidentiality) это будет действовать в течение всего сеанса работы.

  • Оператору следует настраивать одинаковые правила безопасности для основных и резервных элементов FE и CE (если они есть). Это обеспечит однородность операций и избавит от неоправданных сложностей.

9.1. Без защиты

При выборе уровня No Security (без защиты) для коммуникаций протокола ForCES проверку подлинности конечных точек и сообщений должен выполнять уровень ForCES PL. Его механизмы достаточно слабы и не включают криптографических операций. Оператор может выбрать режим No Security, когда конечные точки протокола размещаются, например, в одном устройстве.

Для обеспечения взаимодействия и однотипной реализации уровней защиты, каждый элемент CE и FE должен поддерживать этот уровень.

Описанное в параграфах 9.1.1 и 9.1.2 является лишь проверкой ошибок, а не процедурами защиты. Защита описана в параграфе 9.2.

9.1.1. Проверка подлинности конечных точек

В каждом CE и FE уровень PL поддерживает список ассоциаций как часть своей конфигурации. Это выполняется через интерфейсы CEM и FEM. FE должен подключаться только к CE, заданным через FEM, а CE следует принимать соединения и создавать ассоциации с элементами FE, заданными через CEM. Элементу CE следует проверять идентификатор FE прежде, чем принять соединение в фазе pre-association.

9.1.2. Проверка подлинности сообщений

Когда CE или FE передает сообщение, принимающая сторона должна проверить инициатора по идентификатору CE или FE в базовом заголовке. Это обеспечит корректную работу протокола. Такая дополнительная проверка рекомендуется даже при использовании услуг защиты базового уровня TML.

9.2. ForCES PL и защитные услуги TML

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

Все настройки конфигурации должны быть выполнены до начала работы CE и FE.

При использовании в TML аутентификации на основе сертификатов эти сертификаты могут использовать связанную с ForCES структуру именования для задания имен и соответствующих правил безопасности в настройках CE и FE.

Детали, относящиеся к требованиям защиты TML, читателю следует искать в документах соответствующего TML.

9.2.1. Проверка подлинности конечных точек

При включенной защите TML уровень ForCES TML выполняет аутентификацию конечных точек. Защищенные связи организуются между элементами CE и FE и прозрачны для уровня ForCES PL.

9.2.2. Проверка подлинности сообщений

Относящиеся к TML операции прозрачны для ForCES PL (см. раздел 5).

9.2.3. Конфиденциальность

Относящиеся к TML операции прозрачны для ForCES PL (см. раздел 5).

10. Благодарности

Авторы документа выражают свою признательность и благодарности членам рабочей группы ForCES, особо отметив вклад Furquan Ansari, Alex Audu, Steven Blake, Shuchi Chawla, Alan DeKok, Ellen M. Deleganes, Xiaoyi Guo, Yunfei Guo, Evangelos Haleplidis, Zsolt Haraszti, Fenggen Jia, John C. Lin, Alistair Munro, Jeff Pickering, T. Sridhlar, Guangming Wang, Chaoping Wu и Lily L. Yang. Спасибо также David Putzolu и Patrick Droz за их комментарии и предложения по протоколу, а также за бесконечное терпение. Спасибо Sue Hares и Alia Atlas за рецензирование документа.

Alia Atlas проделала большую работу по улучшению читаемости документа, обеспечив отклики IESG.

Ross Callon сыграл важную роль по преодолению основных препятствий для публикации этого документа.

Редакторы использовали инструменты xml2rfc [RFC2629] для подготовки этого документа и очень признательны этим инструментам за их качество. Спасибо также Elwyn Davies за помощь в корректировке XML для этого документа.

11. Литература

11.1. Нормативные документы

[RFC2119] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, March 1997.

[RFC2914] Floyd, S., «Congestion Control Principles», BCP 41, RFC 2914, September 2000.

[RFC5226] Narten, T. and H. Alvestrand, «Guidelines for Writing an IANA Considerations Section in RFCs», BCP 26, RFC 5226, May 2008.

[RFC5390] Rosenberg, J., «Requirements for Management of Overload in the Session Initiation Protocol», RFC 5390, December 2008.

[RFC5811] Hadi Salim, J. and K. Ogawa, «SCTP-Based Transport Mapping Layer (TML) for the Forwarding and Control Element Separation (ForCES) Protocol», RFC 5811, March 2010.

[RFC5812] Halpern, J. and J. Hadi Salim, «Forwarding and Control Element Separation (ForCES) Forwarding Element Model», RFC 5812, March 2010.

11.2. Дополнительная литература

[2PCREF] Gray, J., «Notes on database operating systems», in «Operating Systems: An Advanced Course» Lecture Notes in Computer Science, Vol. 60, pp. 394-481, Springer-Verlag, 1978.

[ACID] Haerder, T. and A. Reuter, «Principles of Transaction-Orientated Database Recovery», 1983.

[RFC2629] Rose, M., «Writing I-Ds and RFCs using XML», RFC 2629, June 1999.

[RFC3654] Khosravi, H. and T. Anderson, «Requirements for Separation of IP Control and Forwarding», RFC 3654, November 2003.

[RFC3746] Yang, L., Dantu, R., Anderson, T., and R. Gopal, «Forwarding and Control Element Separation (ForCES) Framework», RFC 3746, April 2004.

Приложение A. Взаимодействие с IANA

В соответствии с правилами «Guidelines for Writing an IANA Considerations Section in RFCs» (RFC 5226 [RFC5226]) для ForCES определены пространства имён:

  • Message Type Namespace, Section 7

  • Operation Type Namespace, Section 7.1.6

  • Header Flags, Section 6.1

  • TLV Type, Section 7

  • RESULT-TLV18 Result Values, Section 7.1.7

  • LFB Class ID, Section 7.1.5 (resolved by model document, [RFC5812].

  • Result: Association Setup Response, Section 7.5.2

  • Reason: Association Teardown Message, Section 7.5.3

A.1. Пространство типов сообщений

Для типов сообщений используются 8-битовые значения. Ниже приведены рекомендации по распределению типов.

0x00 — 0x1F

Типы из этого диапазона являются частью базового протокола ForCES и выделяются по согласованию с IETF [RFC5226].

Значения, заданные этой спецификацией

	0x00               Reserved
	0x01               AssociationSetup
	0x02               AssociationTeardown
	0x03               Config
	0x04               Query
	0x05               EventNotification
	0x06               PacketRedirect
	0x07 - 0x0E        Reserved
	0x0F               Hearbeat
	0x11               AssociationSetupResponse
	0x12               Reserved
	0x13               ConfigResponse
	0x14               QueryResponse

0x20 — 0x7F

Типы из этого диапазона выделяются по процедуре Specification Required [RFC5226] и должны быть документированы в RFC или других доступных для чтения документах.

0x80 — 0xFF

Типы из этого диапазона зарезервированы для фирменных расширений и назначаются производителями. Взаимодействие с IANA для значений типов из этого диапазона не требуется.

A.2. Выбор операции

Для Operation Selection (OPER-TLV) используются 16-битовые значения. Ниже приведены рекомендации по распределению типов OPER-TLV.

0x0000-0x0FF

Типы OPER-TLV из этого диапазона выделяются по согласованию с IETF [RFC5226].

Значения, заданные этой спецификацией

	0x0000           Reserved
	0x0001           SET
	0x0002           SET-PROP
	0x0003           SET-RESPONSE
	0x0004           SET-PROP-RESPONSE
	0x0005           DEL
	0x0006           DEL-RESPONSE
	0x0007           GET
	0x0008           GET-PROP
	0x0009           GET-RESPONSE
	0x000A           GET-PROP-RESPONSE
	0x000B           REPORT
	0x000C           COMMIT
	0x000D           COMMIT-RESPONSE
	0x000E           TRCOMP

0x0100-0x7FFF

Типы OPER-TLV из этого диапазона должны быть документированы в RFC или других доступных для чтения документах [RFC5226].

0x8000-0xFFFF

Типы OPER-TLV из этого диапазона зарезервированы для фирменных расширений и назначаются производителями. Взаимодействие с IANA для значений типов из этого диапазона не требуется.

A.3. Флаги заголовка

Поле флагов в заголовке имеет размер 32 бита. Поле flags является частью базового протокола ForCES. Значения флагов выделяются по согласованию с IETF [RFC5226].

A.4. Типы TLV

Для типов TLV используются 16-битовые значения. Ниже приведены рекомендации по распределению типов TLV.

0x0000-0x01FF

Типы TLV из этого диапазона выделяются по согласованию с IETF [RFC5226].

Значения, заданные этой спецификацией

	0x0000           Reserved
	0x0001           REDIRECT-TLV
	0x0010           ASResult-TLV
	0x0011           ASTreason-TLV
	0x1000           LFBselect-TLV
	0x0110           PATH-DATA-TLV
	0x0111           KEYINFO-TLV
	0x0112           FULLDATA-TLV
	0x0113           SPARSEDATA-TLV
	0x0114           RESULT-TLV
	0x0115           METADATA-TLV
	0x0116           REDIRECTDATA-TLV

0x0200-0x7FFF

Типы TLV из этого диапазона должны быть документированы в RFC или других доступных для чтения документах [RFC5226].

0x8000-0xFFFF

Типы TLV из этого диапазона зарезервированы для фирменных расширений и назначаются производителями. Взаимодействие с IANA для значений типов из этого диапазона не требуется.

A.5. Коды результата в RESULT-TLV

Значения RTesult RESULT-TLV являются 8-битовыми.

	0x00        E_SUCCESS
	0x01        E_INVALID_HEADER
	0x02        E_LENGTH_MISMATCH
	0x03        E_VERSION_MISMATCH
	0x04        E_INVALID_DESTINATION_PID
	0x05        E_LFB_UNKNOWN
	0x06        E_LFB_NOT_FOUND
	0x07        E_LFB_INSTANCE_ID_NOT_FOUND
	0x08        E_INVALID_PATH
	0x09        E_COMPONENT_DOES_NOT_EXIST
	0x0A        E_EXISTS
	0x0B        E_NOT_FOUND
	0x0C        E_READ_ONLY
	0x0D        E_INVALID_ARRAY_CREATION
	0x0E        E_VALUE_OUT_OF_RANGE
	0x0F        E_CONTENTS_TOO_LONG
	0x10        E_INVALID_PARAMETERS
	0x11        E_INVALID_MESSAGE_TYPE
	0x12        E_INVALID_FLAGS19
	0x13        E_INVALID_TLV
	0x14        E_EVENT_ERROR
	0x15        E_NOT_SUPPORTED
	0x16        E_MEMORY_ERROR
	0x17        E_INTERNAL_ERROR
	0x18-0xFE   Reserved
	0xFF        E_UNSPECIFIED_ERROR

Все значения, не назначенные этой спецификацией, распределяются по процедуре Expert Review [RFC5226].

A.6. Отклик Association Setup

Для откликов Association Setup используются 32-битовые значения. Рекомендации по распределению приведены ниже.

0x00000000-0x000000FF20

Значения Association Setup Response из этого диапазона выделяются по согласованию с IETF [RFC5226].

Значения, заданные этой спецификацией21

	0x0000000   Success
	0x0000001   FE ID Invalid
	0x0000002   Permission Denied

0x00000100-0x00000FFF1

Значения Association Setup Response из этого диапазона выделяются по процедуре Specification Required [RFC5226] и должны быть документированы в RFC или других доступных для чтения документах [RFC5226].

0x00001000-0xFFFFFFFF1

Значения из этого диапазона зарезервированы для фирменных расширений и назначаются производителями. Взаимодействие с IANA для значений типов из этого диапазона не требуется.

A.7. Сообщение Association Teardown

Для сообщений Association Teardown используются 32-битовые значения. Рекомендации по распределению приведены ниже.

0x00000000-0x0000FFFF

Значения Association Teardown Message из этого диапазона выделяются по согласованию с IETF [RFC5226].

Значения, заданные этой спецификацией

	0x00000000        Normal - teardown by administrator
	0x00000001        Error  - loss of heartbeats
	0x00000002        Error  - loss of bandwidth
	0x00000003        Error  - out of Memory
	0x00000004        Error  - application crash
	0x000000FF        Error  - unspecified

0x00010000-0x7FFFFFFF

Коды Association Teardown Message из этого диапазона выделяются по процедуре Specification Required [RFC5226] и должны быть документированы в RFC или других доступных для чтения документах [RFC5226].

0x80000000-0xFFFFFFFFF

Значения из этого диапазона зарезервированы для фирменных расширений и назначаются производителями. Взаимодействие с IANA для значений типов из этого диапазона не требуется.

Приложение B. Схема LFB протокола ForCES

Приведенная ниже схема соответствует схеме LFB, описанной в модели ForCES [RFC5812].

Описания различных компонент этого определения приведены в параграфе 7.3.1.

   <LFBLibrary xmlns="urn:ietf:params:xml:ns:forces:lfbmodel:1.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       provides="FEPO">
   <!-- XXX  -->
     <dataTypeDefs>
        <dataTypeDef>
           <name>CEHBPolicyValues</name>
                  <synopsis>
                      Возможные значения политики CE для heartbeat
                  </synopsis>
              <atomic>
              <baseType>uchar</baseType>
              <specialValues>
                 <specialValue value="0">
                   <name>CEHBPolicy0</name>
                   <synopsis>
                        Политика CE для heartbeat, номер 0
                   </synopsis>
                   </specialValue>
                 <specialValue value="1">
                    <name>CEHBPolicy1</name>
                    <synopsis>
                         Политика CE для heartbeat, номер 1
                    </synopsis>
                 </specialValue>
               </specialValues>
               </atomic>
         </dataTypeDef>

         <dataTypeDef>
            <name>FEHBPolicyValues</name>
                 <synopsis>
                     Возможные значения политики FE для heartbeat
                </synopsis>
              <atomic>
              <baseType>uchar</baseType>
              <specialValues>
                <specialValue value="0">
                  <name>FEHBPolicy0</name>
                  <synopsis>
                       Политика FE для heartbeat, номер 0
                  </synopsis>
                </specialValue>
                <specialValue value="1">
                   <name>FEHBPolicy1</name>
                   <synopsis>
                        Политика FE для heartbeat, номер 1
                   </synopsis>
                  </specialValue>
               </specialValues>
               </atomic>
         </dataTypeDef>

         <dataTypeDef>
         <name>FERestartPolicyValues</name>
               <synopsis>
                    Возможные значения политики FE для перезапуска
               </synopsis>
              <atomic>
              <baseType>uchar</baseType>
              <specialValues>
                 <specialValue value="0">
                   <name>FERestartPolicy0</name>
                   <synopsis>
                        Политика FE для перезапуска, номер 0
                   </synopsis>
                   </specialValue>
               </specialValues>
               </atomic>
         </dataTypeDef>

         <dataTypeDef>
         <name>CEFailoverPolicyValues</name>
               <synopsis>
                   Возможные значения политики CE для восстановления при отказах
               </synopsis>
              <atomic>
              <baseType>uchar</baseType>
              <specialValues>
                <specialValue value="0">
                   <name>CEFailoverPolicy0</name>
                   <synopsis>
                        Политика CE для восстановления при отказах, номер 0
                   </synopsis>
                 </specialValue>
               <specialValue value="1">
                  <name>CEFailoverPolicy1</name>
                  <synopsis>
                       Политика CE для восстановления при отказах, номер 1
                  </synopsis>
                </specialValue>
               </specialValues>
               </atomic>
         </dataTypeDef>

        <dataTypeDef>
           <name>FEHACapab</name>
                  <synopsis>Поддерживаемые функции HA</synopsis>
              <atomic>
              <baseType>uchar</baseType>
              <specialValues>
                 <specialValue value="0">
                   <name>GracefullRestart</name>
                   <synopsis>
                        FE поддерживает Graceful Restart
                   </synopsis>
                   </specialValue>
                 <specialValue value="1">
                    <name>HA</name>
                    <synopsis>
                         FE поддерживает HA
                    </synopsis>
                 </specialValue>
               </specialValues>
               </atomic>
         </dataTypeDef>
     </dataTypeDefs>

     <LFBClassDefs>
       <LFBClassDef LFBClassID="2">
         <name>FEPO</name>
         <synopsis>
            FE Protocol Object
         </synopsis>
         <version>1.0</version>

     <components>
           <component componentID="1" access="read-only">
               <name>CurrentRunningVersion</name>
               <synopsis>Версия используемого в данный момент протокола ForCES</synopsis>
               <typeRef>uchar</typeRef>
             </component>
           <component componentID="2" access="read-only">
             <name>FEID</name>
             <synopsis>Индивидуальный FEID</synopsis>
             <typeRef>uint32</typeRef>
           </component>
           <component componentID="3" access="read-write">
              <name>MulticastFEIDs</name>
              <synopsis>
                 Таблица всех групповых идентификаторов
              </synopsis>
              <array type="variable-size">
               <typeRef>uint32</typeRef>
              </array>
           </component>
           <component componentID="4" access="read-write">
             <name>CEHBPolicy</name>
             <synopsis>
              Политика CE для Heartbeat
             </synopsis>
             <typeRef>CEHBPolicyValues</typeRef>
           </component>
           <component componentID="5" access="read-write">
             <name>CEHDI</name>
             <synopsis>
               Интервал CE Heartbeat Dead в миллисекундах
             </synopsis>
             <typeRef>uint32</typeRef>
           </component>
           <component componentID="6" access="read-write">
             <name>FEHBPolicy</name>
             <synopsis>
               Политика FE для Heartbeat
             </synopsis>
             <typeRef>FEHBPolicyValues</typeRef>
           </component>
           <component componentID="7" access="read-write">
             <name>FEHI</name>
             <synopsis>
               Интервал FE Heartbeat в миллисекундах
             </synopsis>
             <typeRef>uint32</typeRef>
           </component>
           <component componentID="8" access="read-write">
             <name>CEID</name>
             <synopsis>
                Первичный CE, с которым связан этот FE
             </synopsis>
             <typeRef>uint32</typeRef>
           </component>
           <component componentID="9" access="read-write">
              <name>BackupCEs</name>
              <synopsis>
                 Таблица всех резервных CE за исключением первичного
              </synopsis>
              <array type="variable-size">
               <typeRef>uint32</typeRef>
              </array>
           </component>
           <component componentID="10" access="read-write">
             <name>CEFailoverPolicy</name>
             <synopsis>
               Политика CE для восстановления при отказах
             </synopsis>
             <typeRef>CEFailoverPolicyValues</typeRef>
           </component>
           <component componentID="11" access="read-write">
             <name>CEFTI</name>
             <synopsis>
               Интервал CE Failover Timeout в миллисекундах
             </synopsis>
             <typeRef>uint32</typeRef>
           </component>
           <component componentID="12" access="read-write">
             <name>FERestartPolicy</name>
             <synopsis>
                Политика перезапуска FE
             </synopsis>
             <typeRef>FERestartPolicyValues</typeRef>
           </component>
           <component componentID="13" access="read-write">
             <name>LastCEID</name>
             <synopsis>
                Первичный CE с которым этот FE был связан в последний раз
             </synopsis>
             <typeRef>uint32</typeRef>
           </component>
         </components>

        <capabilities>
             <capability componentID="30">
                <name>SupportableVersions</name>
                <synopsis>
                   Таблица версий ForCES, поддерживаемых FE
                </synopsis>
                <array type="variable-size">
                 <typeRef>uchar</typeRef>
                </array>
              </capability>
           <capability componentID="31">
              <name>HACapabilities</name>
              <synopsis>
                 Таблица возможностей HA, поддерживаемых FE
              </synopsis>
              <array type="variable-size">
               <typeRef>FEHACapab</typeRef>
              </array>
           </capability>
         </capabilities>

         <events baseID="61">
           <event eventID="1">
             <name>PrimaryCEDown</name>
             <synopsis>Первичный CE был изменен</synopsis>
             <eventTarget>
                 <eventField>LastCEID</eventField>
             </eventTarget>
             <eventChanged/>
             <eventReports>
                <eventReport>
                  <eventField>LastCEID</eventField>
                </eventReport>
             </eventReports>
           </event>
         </events>
       </LFBClassDef>
     </LFBClassDefs>
   </LFBLibrary>

B.1. Возможности

SupportableVersions содержит перечисление всех версий ForCES, которые поддерживает элемент FE.

FEHACapab содержит перечисление всех возможностей HA в элементе FE. Если FE не поддерживает изящный перезапуск или HA, он не сможет участвовать в HA, как описано в параграфе 8.1.

B.2. Компоненты

Все компоненты описаны в параграфе 7.3.1.

Приложение C. Примеры кодирования данных

В этом приложении обсуждаются несколько примеров кодирования данных. Заполнение в примерах не показано.

Пример 1

Структура с тремя обязательными полями фиксированного размера

           struct S {
           	uint16 a
           	uint16 b
           	uint16 c
           }

(a) Описание всех полей, использующих SPARSEDATA-TLV

           PATH-DATA-TLV
             Путь к экземпляру структуры S ...
             SPARSEDATA-TLV
               ComponentIDof(a), lengthof(a), valueof(a)
               ComponentIDof(b), lengthof(b), valueof(b)
               ComponentIDof(c), lengthof(c), valueof(c)

(b) Описание подмножества полей

           PATH-DATA-TLV
             Путь к экземпляру структуры S ...
             SPARSEDATA-TLV
               ComponentIDof(a), lengthof(a), valueof(a)
               ComponentIDof(c), lengthof(c), valueof(c)

Примечание. Несмотря на присутствие в структуре S обязательных компонент, однозначная идентификация компонент позволяет селективно передавать компоненты структуры S (например, для обновления от CE к FE).

(c) Описание всех полей, использующих FULLDATA-TLV

           PATH-DATA-TLV
             Путь к экземпляру структуры S ...
             FULLDATA-TLV
               valueof(a)
               valueof(b)
               valueof(c)

Пример 2

Структура с тремя полями фиксированного размера, два из которых не обязательны.

           struct T {
           	uint16 a
          	uint16 b (необязательно)
           	uint16 c (необязательно)
           }

Этот пример идентичен примеру 1, как показано ниже.

(a) Описание всех полей, использующих SPARSEDATA-TLV

           PATH-DATA-TLV
             Путь к экземпляру структуры S ...
             SPARSEDATA-TLV
               ComponentIDof(a), lengthof(a), valueof(a)
               ComponentIDof(b), lengthof(b), valueof(b)
               ComponentIDof(c), lengthof(c), valueof(c)

(b) Описание подмножества полей, использующих SPARSEDATA-TLV

           PATH-DATA-TLV
             Путь к экземпляру структуры S ...
             SPARSEDATA-TLV
               ComponentIDof(a), lengthof(a), valueof(a)
               ComponentIDof(c), lengthof(c), valueof(c)

(c) Описание всех полей, использующих FULLDATA-TLV

           PATH-DATA-TLV
             Путь к экземпляру структуры S ...
             FULLDATA-TLV
               valueof(a)
               valueof(b)
               valueof(c)

Примечание. FULLDATA-TLV не может использоваться, пока не описаны все поля.

Пример 3

Структура с полями фиксированного и переменного размера, часть которых не обязательна. Переменный размер имеет строка b.

           struct U {
           uint16 a
           string b (optional)
           uint16 c (optional)
           }

(a) Описание всех полей, использующих SPARSEDATA-TLV

           Путь к экземпляру структуры U ...
           SPARSEDATA-TLV
             ComponentIDof(a), lengthof(a), valueof(a)
             ComponentIDof(b), lengthof(b), valueof(b)
             ComponentIDof(c), lengthof(c), valueof(c)

(b) Описание подмножества полей, использующих SPARSEDATA-TLV

           Путь к экземпляру структуры U ...
           SPARSEDATA-TLV
             ComponentIDof(a), lengthof(a), valueof(a)
             ComponentIDof(c), lengthof(c), valueof(c)

(c) Описание всех полей, использующих FULLDATA-TLV

           Путь к экземпляру структуры U ...
             FULLDATA-TLV
               valueof(a)
               FULLDATA-TLV
                 valueof(b)
               valueof(c)

Примечание. Поле переменного размера требует добавления FULLDATA-TLV во внешний FULLDATA-TLV, как для компоненты b выше.

Пример 4

Структура, содержащая массив структур другого типа.

           struct V {
           uint32 x
           uint32 y
           struct U z[]
           }

(a) Кодирование использует SPARSEDATA-TLV с двумя экземплярами z[], также описываемыми SPARSEDATA-TLV в предположении, что кодируются только элементы массива z[] с индексами 10 и 15.

        Путь к экземпляру структуры V ...
        SPARSEDATA-TLV
         ComponentIDof(x), lengthof(x), valueof(x)
         ComponentIDof(y), lengthof(y), valueof(y)
         ComponentIDof(z), lengthof(all below)
           ComponentID = 10 (i.e index 10 from z[]), lengthof(all below)
               ComponentIDof(a), lengthof(a), valueof(a)
               ComponentIDof(b), lengthof(b), valueof(b)
           ComponentID = 15 (index 15 from z[]), lengthof(all below)
               ComponentIDof(a), lengthof(a), valueof(a)
               ComponentIDof(c), lengthof(c), valueof(c)

Отметим пропуск в компонентах z (после 10 следует 15), а также разрыв в индексе 15 с присутствием только компонент a и c, но не b.

Приложение D. Варианты использования

Для приведенных ниже вариантов использования рассмотрим LFB с перечисленными ниже компонентами.

   foo1, type u32, ID = 1
   foo2, type u32, ID = 2
   table1: type array, ID = 3
           компоненты:
           t1, type u32, ID = 1
           t2, type u32, ID = 2  // индекс в table2
           KEY: nhkey, ID = 1, V = t2
   table2: type array, ID = 4
           компоненты:
           j1, type u32, ID = 1
           j2, type u32, ID = 2
           KEY: akey, ID = 1, V = { j1,j2 }
   table3: type array, ID = 5
           компоненты:
           someid, type u32, ID = 1
           name, type string variable sized, ID = 2
   table4: type array, ID = 6
           компоненты:
           j1, type u32, ID = 1
           j2, type u32, ID = 2
           j3, type u32, ID = 3
           j4, type u32, ID = 4
           KEY: mykey, ID = 1, V = { j1}
   table5: type array, ID = 7
           компоненты:
           p1, type u32, ID = 1
           p2, type array, ID = 2, array components of type-X
   Type-X:
           x1, ID 1, type u32
           x2, ID2 , type u32
                   KEY: tkey, ID = 1, V = { x1}

Во всех примерах используется valueof(x) для указания значения упомянутой компоненты x. При отсутствии F_SEL** (биты 00) флаги не будут показывать какой-либо выбор.

Все примеры показывают для кодирования данных только применение FULLDATA-TLV, хотя в некоторых случаях имеет больше смысла SPARSEDATA-TLV. Акцент делается на показе схем сообщений. Примеры использования FULLDATA-TLV и SPARSEDATA-TLV приведены в Приложении C.

1. Получение foo1

   OPER = GET-TLV
           PATH-DATA-TLV: IDCount = 1, IDs = 1

Результат

   OPER = GET-RESPONSE-TLV
           PATH-DATA-TLV:
                   flags=0, IDCount = 1, IDs = 1
                   FULLDATA-TLV L = 4+4, V =  valueof(foo1)

2. Установка foo2 = 10

   OPER = SET-TLV
           PATH-DATA-TLV:
                   flags = 0,  IDCount = 1, IDs = 2
                   FULLDATA-TLV: L = 4+4, V=10

Результат

   OPER = SET-RESPONSE-TLV
           PATH-DATA-TLV:
                   flags = 0,  IDCount = 1, IDs = 2
                   RESULT-TLV

3. Выгрузить (dump) table2

      OPER = GET-TLV
           PATH-DATA-TLV:
                   IDCount = 1, IDs = 4

Результат

      OPER = GET-RESPONSE-TLV
           PATH-DATA-TLV:
                   flags = 0, IDCount = 1, IDs = 4
                   FULLDATA-TLV: L = XXX, V= последовательность index, valueof(j1),
                        valueof(j2), представляющая всю таблицу

Примечание. Следует иметь возможность взять GET-RESPONSE-TLV и преобразовать его в SET-TLV. Если результат приведенного выше примера передать обратно в SET-TLV (вместо GET-RESPONSE_TLV), будет заменено все содержимое таблицы.

4. Пример множества операций для создания записей 0-5 в table2 (ошибки игнорируются)

   OPER = SET-TLV
           PATH-DATA-TLV:
                   flags = 0 , IDCount = 1, IDs = 4
                   PATH-DATA-TLV
                     flags = 0, IDCount = 1, IDs = 0
                     FULLDATA-TLV valueof(j1), valueof(j2) of entry 0
                   PATH-DATA-TLV
                     flags = 0, IDCount = 1, IDs = 1
                     FULLDATA-TLV valueof(j1), valueof(j2) of entry 1
                   PATH-DATA-TLV
                     flags = 0, IDCount = 1, IDs = 2
                     FULLDATA-TLV valueof(j1), valueof(j2) of entry 2
                   PATH-DATA-TLV
                     flags = 0, IDCount = 1, IDs = 3
                     FULLDATA-TLV valueof(j1), valueof(j2) of entry 3
                   PATH-DATA-TLV
                     flags = 0, IDCount = 1, IDs = 4
                     FULLDATA-TLV valueof(j1), valueof(j2) of entry 4
                   PATH-DATA-TLV
                     flags = 0, IDCount = 1, IDs = 5
                     FULLDATA-TLV valueof(j1), valueof(j2) of entry 5

Результат

   OPER = SET-RESPONSE-TLV
           PATH-DATA-TLV:
                   flags = 0 , IDCount = 1, IDs = 4
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 0
                       RESULT-TLV
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 1
                       RESULT-TLV
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 2
                       RESULT-TLV
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 3
                       RESULT-TLV
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 4
                       RESULT-TLV
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 5
                       RESULT-TLV

5. Пример блочных операций (с пропусками) – замена записей 0,2 в table2.

   OPER = SET-TLV
           PATH-DATA-TLV:
                flags =  0 , IDCount = 1, IDs = 4
                PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 0
                   FULLDATA-TLV с valueof(j1), valueof(j2) равными 0
                PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 2
                   FULLDATA-TLV с valueof(j1), valueof(j2) равными 2

Результат

   OPER = SET-TLV
           PATH-DATA-TLV:
                flags =  0 , IDCount = 1, IDs = 4
                PATH-DATA-TLV
                    flags = 0, IDCount = 1, IDs = 0
                    RESULT-TLV
                PATH-DATA-TLV
                    flags = 0, IDCount = 1, IDs = 2
                    RESULT-TLV

6. Пример получения первой строки из table2.

   OPER = GET-TLV
           PATH-DATA-TLV:
                   IDCount = 2, IDs = 4.0

Результат

   OPER = GET-RESPONSE-TLV
           PATH-DATA-TLV:
                   IDCount = 2, IDs = 4.0
                    FULLDATA-TLV с valueof(j1), valueof(j2)

7. Получение записей 0-5 из table2.

   OPER = GET-TLV
           PATH-DATA-TLV:
                   flags = 0, IDCount = 1, IDs = 4
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 0
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 1
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 2
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 3
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 4
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 5

Результат

   OPER = GET-RESPONSE-TLV
           PATH-DATA-TLV:
                   flags = 0, IDCount = 1, IDs = 4
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 0
                       FULLDATA-TLV с valueof(j1), valueof(j2)
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 1
                       FULLDATA-TLV с valueof(j1), valueof(j2)
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 2
                       FULLDATA-TLV с valueof(j1), valueof(j2)
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 3
                       FULLDATA-TLV с valueof(j1), valueof(j2)
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 4
                       FULLDATA-TLV с valueof(j1), valueof(j2)
                   PATH-DATA-TLV
                       flags = 0, IDCount = 1, IDs = 5
                       FULLDATA-TLV с valueof(j1), valueof(j2)

8. Создание строки в table2, индекс 5.

   OPER = SET-TLV
           PATH-DATA-TLV:
                flags = 0, IDCount = 2, IDs = 4.5
                FULLDATA-TLV с valueof(j1), valueof(j2)

Результат

   OPER = SET-RESPONSE-TLV
           PATH-DATA-TLV:
                flags = 0, IDCount = 1, IDs = 4.5
                RESULT-TLV

9. Выгрузка содержимого table1.

   OPER = GET-TLV
           PATH-DATA-TLV:
                   flags = 0, IDCount = 1, IDs = 3

Результат

   OPER = GET-RESPONSE-TLV
           PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 3
                   FULLDATA-TLV, Length = XXXX
                           (зависит от размера table1)
                           index, valueof(t1),valueof(t2)
                           index, valueof(t1),valueof(t2)
                           .
                           .
                           .

10. Использование ключей для получения строки из table4 с j1=100 (j1 определяет ключ для таблицы и его KeyID = 1).

   OPER = GET-TLV
           PATH-DATA-TLV:
                   flags = F_SELKEY  IDCount = 1, IDs = 6
                   KEYINFO-TLV = KeyID=1, KEY_DATA=100

Результат

Если j1=100 имела индекс 10

   OPER = GET-RESPONSE-TLV
           PATH-DATA-TLV:
                   flags = 0, IDCount = 1, IDs = 6.10
                   FULLDATA-TLV с valueof(j1), valueof(j2),valueof(j3),valueof(j4)

11. Удаление строки с KEY (j1=100, j2=200) из table2 (пара j1, j2 определяет ключ для table2).

   OPER = DEL-TLV
           PATH-DATA-TLV:
                   flags = F_SELKEY  IDCount = 1, IDs = 4
                   KEYINFO-TLV:  {KeyID =1 KEY_DATA=100,200}

Результат

Если пара (j1=100, j2=200) была строкой 15

   OPER = DELETE-RESPONSE-TLV
           PATH-DATA-TLV:
                   flags = 0  IDCount = 2, IDs = 4.15
                   RESULT-TLV

12. Выгрузка содержимого table3

Следует отметить, что таблица имеет столбец с именем компоненты переменного размера. Целью является демонстрация кодирования таких компонент.

   OPER = GET-TLV
           PATH-DATA-TLV:
                flags = 0 IDCount = 1, IDs = 5

Результат

   OPER = GET-RESPONSE-TLV
       PATH-DATA-TLV:
          flags = 0  IDCount = 1, IDs = 5
              FULLDATA-TLV, Length = XXXX
               index, someidv, TLV: T=FULLDATA-TLV, L = 4+strlen(namev),
                      V = valueof(v)
               index, someidv, TLV: T=FULLDATA-TLV, L = 4+strlen(namev),
                      V = valueof(v)
               index, someidv, TLV: T=FULLDATA-TLV, L = 4+strlen(namev),
                      V = valueof(v)
               index, someidv, TLV: T=FULLDATA-TLV, L = 4+strlen(namev),
                      V = valueof(v)
                  .
                  .
                  .

13. Множество неделимых операций

Примечание 1. Это эмулирует добавление новой записи nexthop и неделимого обновления записи L3, указывавшей на старых NH, с заменой ее на новый22. Предполагается, что обе таблицы относятся к одному LFB.

Примечание. Обратите внимание на две операции SET для одного экземпляра LFB.

   //Операция 1 - добавление новой записи в table2, индекс 20.
   OPER = SET-TLV
           Path-TLV:
                   flags = 0, IDCount = 2,  IDs = 4.20
                   FULLDATA-TLV, V= valueof(j1),valueof(j2)

   // Операция 2 - обновление в table1 записи, которая была указана
   // t2 = 10 на запись, указанную индексом 20
   OPER = SET-TLV
           PATH-DATA-TLV:
                   flags = F_SELKEY, IDCount = 1, IDs = 3
                   KEYINFO-TLV = KeyID=1 KEY_DATA=10
                   PATH-DATA-TLV
                           flags = 0  IDCount = 1, IDs = 2
                           FULLDATA-TLV, V= 20

Результат

   // Первая операция SET
   OPER = SET-RESPONSE-TLV
           PATH-DATA-TLV
                   flags = 0 IDCount = 3, IDs = 4.20
                   RESULT-TLV code = success
                           FULLDATA-TLV, V = valueof(j1),valueof(j2)
   // Вторая операция SET (предполагается обновление записи 16)
   OPER = SET-RESPONSE-TLV
           PATH-DATA-TLV
                   flags = 0 IDCount = 2, IDs = 3.16
                   PATH-DATA-TLV
                           flags = 0  IDCount = 1, IDs = 2
                           RESULT-TLV code = success
                                   FULLDATA-TLV, Length = XXXX v=20

14. Селективная установка

В table4 для индексов 1, 3, 5, 7 и 9 меняется j1 на 100, j2 на 200, j3 на 300. j4 сохраняется.

   PER = SET-TLV
       PATH-DATA-TLV
           flags = 0, IDCount = 1, IDs = 6
           PATH-DATA-TLV
               flags = 0, IDCount = 1, IDs = 1
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 1
                   FULLDATA-TLV, Length = XXXX, V = {100}
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 2
                   FULLDATA-TLV, Length = XXXX, V = {200}
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 3
                   FULLDATA-TLV, Length = XXXX, V = {300}
           PATH-DATA-TLV
               flags = 0, IDCount = 1, IDs = 3
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 1
                   FULLDATA-TLV, Length = XXXX, V = {100}
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 2
                   FULLDATA-TLV, Length = XXXX, V = {200}
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 3
                   FULLDATA-TLV, Length = XXXX, V = {300}
           PATH-DATA-TLV
               flags = 0, IDCount = 1, IDs = 5
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 1
                   FULLDATA-TLV, Length = XXXX, V = {100}
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 2
                   FULLDATA-TLV, Length = XXXX, V = {200}
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 3
                   FULLDATA-TLV, Length = XXXX, V = {300}
           PATH-DATA-TLV
               flags = 0, IDCount = 1, IDs = 7
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 1
                   FULLDATA-TLV, Length = XXXX, V = {100}
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 2
                   FULLDATA-TLV, Length = XXXX, V = {200}
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 3
                   FULLDATA-TLV, Length = XXXX, V = {300}
           PATH-DATA-TLV
               flags = 0, IDCount = 1, IDs = 9
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 1
                   FULLDATA-TLV, Length = XXXX, V = {100}
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 2
                   FULLDATA-TLV, Length = XXXX, V = {200}
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 3
                   FULLDATA-TLV, Length = XXXX, V = {300}

Отклик

   OPER = SET-RESPONSE-TLV
       PATH-DATA-TLV
           flags = 0, IDCount = 1, IDs = 6
           PATH-DATA-TLV
               flags = 0, IDCount = 1, IDs = 1
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 1
                   RESULT-TLV
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 2
                   RESULT-TLV
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 3
                   RESULT-TLV
           PATH-DATA-TLV
               flags = 0, IDCount = 1, IDs = 3
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 1
                   RESULT-TLV
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 2
                   RESULT-TLV
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 3
                   RESULT-TLV
           PATH-DATA-TLV
               flags = 0, IDCount = 1, IDs = 5
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 1
                   RESULT-TLV
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 2
                   RESULT-TLV
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 3
                   RESULT-TLV
           PATH-DATA-TLV
               flags = 0, IDCount = 1, IDs = 7
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 1
                   RESULT-TLV
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 2
                   RESULT-TLV
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 3
                   RESULT-TLV
           PATH-DATA-TLV
               flags = 0, IDCount = 1, IDs = 9
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 1
                   RESULT-TLV
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 2
                   RESULT-TLV
               PATH-DATA-TLV
                   flags = 0, IDCount = 1, IDs = 3
                   RESULT-TLV

15. Примеры манипуляций с таблицей таблиц – получение x1 из table10, строка 4 внутри table5 строка 10

   operation = GET-TLV
           PATH-DATA-TLV
                   flags = 0  IDCount = 5, IDs=7.10.2.4.1

Результат

   operation = GET-RESPONSE-TLV
           PATH-DATA-TLV
                   flags = 0  IDCount = 5, IDs=7.10.2.4.1
                   FULLDATA-TLV: L=XXXX, V = valueof(x1)

16. Получение X2 из строки row 10, table10 в table5 на основе значения x1 = 10 (x1 имеет KeyID 1).

   operation = GET-TLV
           PATH-DATA-TLV
                   flag = F_SELKEY, IDCount=3, IDS = 7.10.2
                   KEYINFO-TLV, KeyID = 1, KEY_DATA = 10
                   PATH-DATA-TLV
                           IDCount = 1, IDS = 2 //select x2

Результат

Если x1=10 было в записи 11

   operation = GET-RESPONSE-TLV
           PATH-DATA-TLV
                   flag = 0, IDCount=5, IDS = 7.10.2.11
                   PATH-DATA-TLV
                           flags = 0  IDCount = 1, IDS = 2
                           FULLDATA-TLV: L=XXXX, V = valueof(x2)

17. Дополнительный пример манипуляций с таблицей таблиц

Рассмотрим table6, определенную ниже.

   table6: type array, ID = 8
           компоненты:
           p1, type u32, ID = 1
           p2, type array, ID = 2, array components of type type-A

   type-A:
           a1, type u32, ID 1,
           a2, type array ID2 ,array components of type type-B

   type-B:
           b1, type u32, ID 1
           b2, type u32, ID 2

В этом примере проводятся замены

table6.10.p1 на 111;

table6.10.p2.20.a1 на 222;

table6.10.p2.20.a2.30.b1 на 333

в одном сообщении и одной операции.

Это можно сделать двумя способами:

a) используя вложенность;

b) используя плоский путь к данным.

A. Метод использует вложенность в одном сообщении с одной операцией.

   operation = SET-TLV
           PATH-DATA-TLV
                   flags = 0  IDCount = 2, IDs=6.10
                   PATH-DATA-TLV
                           flags = 0, IDCount = 1, IDs=1
                           FULLDATA-TLV: L=XXXX,
                                   V = {111}
                   PATH-DATA-TLV
                           flags = 0  IDCount = 2, IDs=2.20
                           PATH-DATA-TLV
                                   flags = 0, IDCount = 1, IDs=1
                                   FULLDATA-TLV: L=XXXX,
                                           V = {222}
                           PATH-DATA-TLV :
                                   flags = 0, IDCount = 3, IDs=2.30.1
                                   FULLDATA-TLV: L=XXXX,
                                           V = {333}

Результат

   operation = SET-RESPONSE-TLV
           PATH-DATA-TLV
                   flags = 0  IDCount = 2, IDs=6.10
                   PATH-DATA-TLV
                           flags = 0, IDCount = 1, IDs=1
                           RESULT-TLV
                   PATH-DATA-TLV
                           flags = 0  IDCount = 2, IDs=2.20
                           PATH-DATA-TLV
                                   flags = 0, IDCount = 1, IDs=1
                                   RESULT-TLV
                           PATH-DATA-TLV :
                                   flags = 0, IDCount = 3, IDs=2.30.1
                                   RESULT-TLV

B. Метод использует плоский путь к данным в одном сообщении с одной операцией.

   operation = SET-TLV
           PATH-DATA-TLV :
                   flags = 0, IDCount = 3, IDs=6.10.1
                   FULLDATA-TLV: L=XXXX,
                           V = {111}
           PATH-DATA-TLV :
                   flags = 0, IDCount = 5, IDs=6.10.1.20.1
                   FULLDATA-TLV: L=XXXX,
                           V = {222}
           PATH-DATA-TLV :
                   flags = 0, IDCount = 7, IDs=6.10.1.20.1.30.1
                   FULLDATA-TLV: L=XXXX,
                           V = {333}

Результат

   operation = SET-TLV
           PATH-DATA-TLV :
                   flags = 0, IDCount = 3, IDs=6.10.1
                   RESULT-TLV
           PATH-DATA-TLV :
                   flags = 0, IDCount = 5, IDs=6.10.1.20.1
                   RESULT-TLV
           PATH-DATA-TLV :
                   flags = 0, IDCount = 7, IDs=6.10.1.20.1.30.1
                   RESULT-TLV

18. Получение всего LFB (все его компоненты и пр.)

Например, при старте CE может потребоваться целиком FE Object LFB. Его можно получить с помощью запроса для класса 1 и экземпляра 1.

   operation = GET-TLV
           PATH-DATA-TLV
                   flags = 0  IDCount = 0

Результат

   operation = GET-RESPONSE-TLV
           PATH-DATA-TLV
                   flags = 0  IDCount = 0
                   FULLDATA-TLV кодирование LFB объекта FE

Адреса авторов

Avri Doria (редактор)

Lulea University of Technology

Rainbow Way

Lulea SE-971 87

Sweden

Phone: +46 73 277 1788

EMail: avri@ltu.se

Jamal Hadi Salim (редактор)

Znyx

Ottawa, Ontario

Canada

Phone:

EMail: hadi@mojatatu.com

Robert Haas (редактор)

IBM

Saumerstrasse 4

8803 Ruschlikon

Switzerland

Phone:

EMail: rha@zurich.ibm.com

Hormuzd M Khosravi (редактор)

Intel

2111 NE 25th Avenue

Hillsboro, OR 97124

USA

Phone: +1 503 264 0334

EMail: hormuzd.m.khosravi@intel.com

Weiming Wang (редактор)

Zhejiang Gongshang University

18, Xuezheng Str., Xiasha University Town

Hangzhou 310018

P.R. China

Phone: +86-571-28877721

EMail: wmwang@zjgsu.edu.cn

Ligang Dong

Zhejiang Gongshang University

18, Xuezheng Str., Xiasha University Town

Hangzhou 310018

P.R. China

Phone: +86-571-28877751

EMail: donglg@zjgsu.edu.cn

Ram Gopal

Nokia

5, Wayside Road

Burlington, MA 310035

USA

Phone: +1-781-993-3685

EMail: ram.gopal@nsn.com

Joel Halpern

P.O. Box 6049

Leesburg, VA 20178

USA

Phone: +1-703-371-3043

EMail: jmh@joelhalpern.com


Перевод на русский язык

Николай Малых

nmalykh@gmail.com


1Forwarding and Control Element Separation.

2Control Element.

3Forwarding Element.

4ForCES Network Element

5Transport Mapping Layer.

6Internet Engineering Task Force.

7Internet Engineering Steering Group.

8Protocol Layer.

9Logical Function Block.

10High Availability — высокий уровень доступности.

11FE Protocol Object — протокольный объект FE.

12Protocol Data Unit — блок данных протокола.

13Denial of service.

14Type Length Value — тип, размер, значение.

15CE Failover Timeout Interval.

16В оригинале ошибочно сказано «два типа». См. https://www.rfc-editor.org/errata/eid5348. Прим. перев.

17В оригинале ошибочно сказано «два типа». См. https://www.rfc-editor.org/errata/eid5349. Прим. перев.

18В оригинале допущена ошибка, см. https://www.rfc-editor.org/errata/eid2566. Прим. перев.

19В оригинале ошибочно сказано E_E_INVALID_FLAGS. См. https://www.rfc-editor.org/errata/eid4188. Прим. перев.

20В оригинале ошибочно указаны 16-битовые значения. См. https://www.rfc-editor.org/errata/eid2568. Прим. перев.

21В оригинале ошибочно указаны 16-битовые значения. См. https://www.rfc-editor.org/errata/eid2568. Прим. перев.

22В оригинале допущена ошибка, см. https://www.rfc-editor.org/errata/eid2574. Прим. перев.4188

Рубрика: RFC | Комментарии к записи RFC 5810 Forwarding and Control Element Separation (ForCES) Protocol Specification отключены

RFC 5798 Virtual Router Redundancy Protocol (VRRP) Version 3 for IPv4 and IPv6

Internet Engineering Task Force (IETF)                     S. Nadas, Ed.
Request for Comments: 5798                                      Ericsson
Obsoletes: 3768                                               March 2010
Category: Standards Track
ISSN: 2070-1721

Virtual Router Redundancy Protocol (VRRP) Version 3 for IPv4 and IPv6

Протокол резервирования виртуального маршрутизатора (VRRP) версии 3 для IPv4 и IPv6

PDF

Аннотация

Этот документ определяет протокол резервирования виртуального маршрутизатора (Virtual Router Redundancy Protocol или VRRP) для IPv4 и IPv6. Это третья (3) версия протокола, основанная на VRRP (версии 2) для IPv4, определённом в RFC 3768, и Virtual Router Redundancy Protocol for IPv6. VRRP задаёт протокол выбора, автоматически назначающего ответственность за виртуальный маршрутизатор одному из VRRP-маршрутизаторов в ЛВС. Маршрутизатор VRRP, контролирующий адреса IPv4 или IPv6, связанные с виртуальным маршрутизатором, называется ведущим (Master) и пересылает пакеты, направленные по этим адресам IPv4 или IPv6. Маршрутизаторы VRRP Master настраиваются на виртуальные адреса IPv4 или IPv6, а резервные маршрутизаторы VRRP (Backup) выводят семейство виртуальных адресов, передаваемых на основе транспортного протокола. В маршрутизаторе VRRP виртуальные маршрутизаторы каждого из семейств IPv4 и IPv6 образуют отдельные, не перекрывающиеся домены. Процесс выбора обеспечивает динамическую обработку отказов при пересылке, если Master становится недоступным. Для IPv4 преимущество применения VRRP заключается в высокой доступности принятого по умолчанию пути без необходимости настройки протоколов динамической маршрутизации или обнаружения маршрутизаторов на каждом конечном хосте. Для IPv6 преимущества применения VRRP заключаются в более быстром переключении на резервные маршрутизаторы (Backup), нежели обеспечивают стандартные механизмы IPv6 Neighbor Discovery.

Статус документа

Документ относится к категории Internet Standards Track.

Документ является результатом работы IETF1 и представляет согласованный взгляд сообщества IETF. Документ прошёл открытое обсуждение и был одобрен для публикации IESG2. Дополнительную информацию о стандартах Internet можно найти в разделе 2 в RFC 5741.

Информация о текущем статусе документа, найденных ошибках и способах обратной связи доступна по ссылке http://www.rfc-editor.org/info/rfc5798.

Авторские права

Авторские права ((c) 2010) принадлежат IETF Trust и лицам, являющимся авторами документа. Все права защищены.

К этому документу применимы права и ограничения, перечисленные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включённые в этот документ, распространяются в соответствии с упрощённой лицензией BSD, как указано в параграфе 4.e документа Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

Документ может содержать материалы из IETF Document или IETF Contribution, опубликованных или публично доступных до 10 ноября 2008 года. Лица, контролирующие авторские права на некоторые из таких документов, могли не предоставить IETF Trust права разрешать внесение изменений в такие документы за рамками процессов IETF Standards. Без получения соответствующего разрешения от лиц, контролирующих авторские права этот документ не может быть изменён вне рамок процесса IETF Standards, не могут также создаваться производные документы за рамками процесса IETF Standards за исключением форматирования документа для публикации или перевода с английского языка на другие языки.

1. Введение

Этот документ определяет протокол VRRP для IPv4 и IPv6. Это третья (3) версия протокола, основанная на VRRP (версии 2) для IPv4, определённой в [RFC3768], и [VRRP-IPv6]. VRRP задаёт протокол выбора, автоматически назначающего ответственность за виртуальный маршрутизатор одному из VRRP-маршрутизаторов в ЛВС. Маршрутизатор VRRP, контролирующий адреса IPv4 или IPv6, связанные с виртуальным маршрутизатором, называется ведущим (Master) и пересылает пакеты, направленные по этим адресам IPv4 или IPv6. Маршрутизаторы VRRP Master настраиваются на виртуальные адреса IPv4 или IPv6, а резервные маршрутизаторы VRRP (Backup) выводят семейство виртуальных адресов, передаваемых на основе транспортного протокола. В маршрутизаторе VRRP виртуальные маршрутизаторы каждого из семейств IPv4 и IPv6 образуют отдельные, не перекрывающиеся домены. Процесс выбора обеспечивает динамическую обработку отказов при пересылке, если Master становится недоступным.

VRRP обеспечивает функцию, похожую на фирменные (proprietary) протоколы Hot Standby Router Protocol (HSRP) [RFC2281] и IP Standby Protocol [IPSTB].

1.1. Замечание по терминологии

В этом документе рассматриваются операции IPv4 и IPv6, многие из которых применительно VRRP имеют общие описания и процедуры. В документе можно было бы использовать краткое обозначение IP для обоих протоколов IPv4 и IPv6. Однако исторически IP обычно указывает IPv4, поэтому здесь применяется обозначение IPvX (где X — 4 или 6) для обоих протоколов сразу. Там, где версия IP имеет значение, применяется соответствующее обозначение.

1.2. IPv4

Имеются методы, позволяющие конечному хосту IPv4 определить первый (first-hop) маршрутизатор в направлении конкретного получателя IPv4. Они включают применение (или отслеживание) протоколов динамической маршрутизации, таких как RIP [RFC2453] или OSPF версии 2 [RFC2328], применение клиента обнаружения маршрутизаторов ICMP [RFC1256], статическая настройка принятого по умолчанию маршрута.

Применение протокола динамической маршрутизации на каждом конечном хосте может быть невозможно по разным причинам, включая административные издержки, дополнительную обработку, проблемы безопасности, отсутствие реализации протокола для некоторых платформ. Протоколы обнаружения соседей или маршрутизаторов могут потребовать вовлечения всех хостов сети, что ведёт к большим значениям таймеров для снижения издержек протокола при большом числе хостов. Это может приводить к значительным задержкам обнаружения потери соседа, что может создавать длительные «чёрные дыры».

Применение статически заданных маршрутов по умолчанию (default) достаточно популярно, оно минимизирует издержки конечных хостов на настройку и обработку и поддерживается практически каждой реализацией IPv4. Этот режим работы будет, скорей всего, сохраняться по мере развёртывания протокола динамической настройки конфигурации хостов [RFC2131], который обычно задаёт для конечного хоста адрес IPv4 и принятый по умолчанию шлюз. Потеря заданного по умолчанию маршрута ведёт к возникновению больших проблем, изолируя все конечные хосты, которые не могут обнаружить какой-либо альтернативный путь.

Протокол VRRP предназначен для устранения критической точки отказа, присущей среде с заданным по умолчанию маршрутом. VRRP задаёт протокол выбора, который динамически назначает ответственность за виртуальный маршрутизатор одному из маршрутизаторов VRRP в ЛВС. Маршрутизатор VRRP, контролирующий адреса IPv4, связанные с виртуальным маршрутизатором, называется ведущим (Master) и пересылает пакеты, направленные по этим адресам IPv4. Процесс выбора обеспечивает динамическую обработку отказов при пересылке, если Master становится недоступным. После этого конечные хосты могут применять любой из адресов IPv4 виртуального маршрутизатора в ЛВС как принятый по умолчанию адрес первого маршрутизатора. Преимуществом применения VRRP является высокая доступность заданного по умолчанию пути без настройки динамической маршрутизации или обнаружения маршрутизаторов на каждом конечном хосте.

1.3. IPv6

Хосты IPv6 в ЛВС обычно узнают об одном или нескольких заданных по умолчанию маршрутизаторах из анонсов Router Advertisement, передаваемых с использованием протокола обнаружения соседей IPv6 (Neighbor Discovery или ND) [RFC4861]. Анонсы периодически передаются по групповым адресам с частотой, позволяющей хостам узнать о маршрутизаторах в течение нескольких минут. Это недостаточно часто, чтобы полагаться на такие анонсы для обнаружения отказов принятых по умолчанию маршрутов.

ND включает механизм обнаружения недоступности соседа (Neighbor Unreachability Detection) для обнаружения отказов соседа (хоста или маршрутизатора) или пути пересылки к соседу. Это выполняется путём отправки соседу индивидуальных сообщений ND Neighbor Solicitation. Для снижения связанных с этим издержек, такие сообщения передаются лишь соседям, которым активно отправляется трафик и лишь в тех случаях, когда в течение определённого времени не было никаких признаков активности маршрутизатора. При использовании принятых по умолчанию параметров ND хосту потребуется около 38, чтобы узнать о недоступности маршрутизатора, прежде чем он переключится на другой маршрутизатор, заданный по умолчанию. Такая задержка очень заметна для пользователей и вызывает тайм-ауты в некоторых реализациях транспортных протоколов.

Хотя обнаружение недоступности в ND можно было бы ускорить, изменив параметры в сторону повышения активности (отметим, что текущий нижний предел составляет 5 секунд), это существенно повысит связанные с трафиком ND издержки, особенно для хостов, пытающихся определить доступность одного из нескольких маршрутизаторов.

Протокол VRRP для IPv6 обеспечивает более быстрое переключение на другой маршрутизатор, заданный по умолчанию, нежели стандартные процедуры ND. Используя VRRP, маршрутизатор Backup может заменить неисправный маршрутизатор, принятый по умолчанию, примерно за 3 секунды (с принятыми по умолчанию параметрами VRRP). Это делается без взаимодействия с хостами и с минимальным объёмом трафика VRRP.

1.4. Уровни требований

Ключевые слова необходимо (MUST), недопустимо (MUST NOT), требуется (REQUIRED), нужно (SHALL), не нужно (SHALL NOT), следует (SHOULD), не следует (SHOULD NOT), рекомендуется (RECOMMENDED), возможно (MAY), необязательно (OPTIONAL) в данном документе должны интерпретироваться в соответствии с [RFC2119].

1.5. Область действия

В оставшейся части документа описаны функции, цели создания и теория работы VRRP. Представлены форматы сообщений, правила обработки и конечный автомат, гарантирующие сходимость выбора к одному Virtual Router Master. Рассмотрены также операционные вопросы, связанные с сопоставлением MAC-адресов, обработкой запросов ARP, генерацией сообщения ICMP и вопросы безопасности.

1.6. Определения

VRRP Router — маршрутизатор VRRP

Маршрутизатор, на котором работает протокол VRRP. Он может выступать как 1 или несколько виртуальных маршрутизаторов.

Virtual Router — виртуальный маршрутизатор

Абстрактный объект, поддерживаемый VRRP и выступающий принятым по умолчанию маршрутизатором для хостов общей ЛВС. Он включает Virtual Router Identifier и набор связанных адресов IPv4 или IPv6 для общей ЛВС. Маршрутизатор VRRP может поддерживать 1 или несколько виртуальных маршрутизаторов.

IP Address Owner — владелец адреса IP

Маршрутизатор VRRP имеющий адреса виртуальных маршрутизаторов IPvX как адреса реальных интерфейсов. Это маршрутизатор, который, будучи включённым, отвечает на пакеты, направленные по одному из этих адресов IPvX для ICMP ping, соединений TCP и т. п.

Primary IP Address — первичный (основной) адрес IP

В IPv4 это адрес IPv4, выбранный из набора реальных адресов интерфейсов. Одним из возможных вариантов является выбор первого адреса. В режиме IPv4 анонсы VRRP всегда передаются с использованием первичного адреса IPv4 в качестве адреса отправителя. В IPv6 используется адрес link-local интерфейса, с которого передаётся пакет.

Virtual Router Master — первичный (ведущий) виртуальный маршрутизатор

Маршрутизатор VRRP, который предполагается ответственным за пересылку пакетов, направленных по адресу IpvX, связанному с виртуальным маршрутизатором, ответы на запросы ARP для адресов IPv4 и запросы ND для адресов IPv6. Отметим, что при доступности владельца адреса IPvX он всегда играет роль ведущего (Master).

Virtual Router Backup — резервный виртуальный маршрутизатор

Набор маршрутизаторов VRRP, которые могут принять ответственность за пересылку для виртуального маршрутизатора в случае отказа текущего первичного маршрутизатора (Master).

2. Требуемые функции

В этом разделе очерчен набор функций, которые сочтены обязательными и которыми руководствовались при разработке VRRP.

2.1. Резервирование адресов IPvX

Резервирование адресов IPvX является основной функцией VRRP. Обеспечивая выбор ведущего виртуального маршрутизатора (Virtual Router Master) и описанные ниже дополнительные функции, протоколу следует также:

  • минимизировать продолжительность «чёрных дыр» в маршрутизации;

  • минимизировать расход пропускной способности в установившемся состоянии и сложность обработки;

  • работать с разными технологиями множественного доступа в ЛВС, способными поддерживать трафик IpvX;

  • поддерживать в сети несколько виртуальных маршрутизаторов для распределения нагрузки;

  • поддерживать множество подсетей IPvX в одном сегменте ЛВС.

2.2. Индикация предпочтительного пути

Простая модель выбора ведущего (Master) маршрутизатора из числа избыточных состоит в рассмотрении всех с одинаковым предпочтением и назначения ведущим любого маршрутизатора после сходимости к нему. Однако, скорей всего, во многих средах будут свои предпочтения (или диапазоны предпочтений) для разных маршрутизаторов из числа доступных. Например, предпочтения могут опираться на «стоимость» или скорость канала доступа, надёжность или производительность маршрутизатора, соображения политики. Протоколу следует разрешать выражение относительных предпочтений пути понятным интуитивно способом и обеспечивать выбор в качестве Master наиболее подходящего маршрутизатора из числа доступных.

2.3. Минимизация ненужного нарушения обслуживания

После выбора ведущего маршрутизатора ненужные переходы между Master и Backup могут приводить к нарушению обслуживания. Протоколу следует обеспечивать после выбора Master предотвращение смены состояния, вызванной любым Backup-маршрутизатором, имеющим предпочтение не выше, чем у продолжающего корректно работать Master.

В некоторых средах может давать преимущество предотвращение смены состояния при доступности текущего Master-маршрутизатора. Может оказаться полезным предотвращение немедленного схождения к предпочтительному пути.

2.4. Эффективная работа в расширенных ЛВС

Отправка пакетов IPvX (IPv4 или IPv6) в ЛВС с множественным доступом требует сопоставления адресов IPvX и MAC. Применение MAC-адреса виртуального маршрутизатора в расширенной ЛВС, использующей мосты с обучением, может оказывать существенное влияние на расход полосы пакетами, переданными виртуальному маршрутизатору. Если MAC-адрес виртуального маршрутизатора не применяется как адрес отправителя кадров канального уровня, его местоположение не будет известно и это ведёт к лавинной рассылке всех пакетов, адресованных виртуальному маршрутизатору. Для повышения эффективности таких сред протоколу следует 1) использовать MAC-адрес виртуального маршрутизатора в пакетах, передаваемых Master-маршрутизатором для включения этого адреса в процесс обучения, 2) передавать сообщение сразу по переходе в режим Master для обновления адреса на станциях и 3) периодически отправлять сообщения от Master для поддержки кэша адресов на станциях.

2.5. Субсекундные операции IPv4 и IPv6

Субсекундное обнаружение отказов маршрутизатора Master VRRP требуется в обеих средах IPv4 и IPv6. Ранее была предложена субсекундная оптимизация для IPv6, а данная спецификация использует этот подход для IPv4 и IPv6.

Один из возможных проблемных вариантов при использовании малых значений VRRP_Advertisement_Interval может возникать в случае, когда маршрутизатор доставляет в ЛВС больше пакетов, нежели сеть может воспринять и в маршрутизаторе возникает очередь. Задержка в такой очереди может превысить минимальное значение VRRP Advertisement_Interval. В этом случае значение Master_Down_Interval будет достаточно мало, чтобы обычные задержки в очереди могли привести к решению VRRP Backup о том, что маршрутизатор Master не работает и предложить себя в качестве нового ведущего. Вскоре после этого задержанные на ведущем маршрутизаторе пакеты Master вызовут обратный переход в состояние Backup. Этот процесс может многократно повторяться в течение 1 секунды, вызывая существенное нарушение трафика. Для смягчения этой проблемы следует рассмотреть приоритетную пересылку пакетов VRRP. Для VRRP Master следует поддерживать возможность наблюдать частое возникновение описанной ситуации и по меньшей мере записывать это в системный журнал (log).

3. Обзор VRRP

VRRP задаёт протокол выбора для обеспечения описанной выше функции виртуального маршрутизатора. Все сообщения протокола передаются в групповых (multicast) дейтаграммах IPv4 или IPv6, что позволяет применять протокол с разными технологиями ЛВС с множественным доступом, поддерживающие групповую передачу IPvX. Каждому каналу виртуального маршрутизатора VRRP выделяется 1 общеизвестный MAC-адрес. Этот документ определяет отображение лишь для сетей, использующих 44-битовые MAC-адреса IEEE 802. Адрес MAC используется как адрес отправителя во всех периодических сообщениях VRRP, передаваемых Master-маршрутизатором для обучения мостов в расширенной ЛВС.

Виртуальный маршрутизатор определяется идентификатором VRID (virtual router identifier) и набором адресов IPv4 или IPv6. Маршрутизатор VRRP может связать виртуальный маршрутизатор с реальным адресом на интерфейсе. Область действия каждого виртуального маршрутизатора ограничена одной ЛВС. На маршрутизаторе VRRP можно настроить дополнительные отображения и приоритеты виртуальных маршрутизаторов, которые будут служить резервными. Сопоставления VRID и адресов IPvX должны быть согласованы между всеми маршрутизаторами VRRP в ЛВС.

На повторное использование VRID с другим сопоставлением адресов в другой ЛВС, а также применение одного VRID для набора адресов IPv4 и IPv6, однако это будут разные виртуальные маршрутизаторы.

Для минимизации сетевого трафика только Master для каждого виртуального маршрутизатора передаёт периодические сообщения VRRP Advertisement. Маршрутизатор Backup не пытается вытеснить Master, пока у него нет более высокого приоритета. Это устраняет перебои в обслуживании, пока не станет доступным более предпочтительный путь. Можно также административно запретить попытки вытеснения. Единственным исключением является то, что маршрутизатор VRRP всегда принимает роль Master для любого виртуального маршрутизатора, связанного с адресом, которым он владеет. Если Master становится недоступным, маршрутизатор Backup с высшим приоритетом переходит в статус Master с короткой задержкой, обеспечивая контролируемый переход ответственности виртуального маршрутизатора с минимальным прерыванием обслуживания.

Устройство протокола VRRP обеспечивает быстрый переход маршрутизатора Backup в состояние Master для минимизации перерыва в обслуживании и включает оптимизацию, устраняющую сложности протокола при гарантии контролируемого перехода в состояние Master для типичных сценариев. Результатом оптимизации служит протокол выбора с минимальными рабочими требованиями к состоянию, минимальным числом активных состояний, одним типом сообщений и отправителем. Типовые сценарии работы определяются как наличие двух избыточных (резервных) маршрутизаторов и/или разных предпочтений пути для каждого маршрутизатора. Побоочным эффектом нарушения этих допущений (т. е. наличия более 2 избыточных путей с одинаковым предпочтением) является возможность передачи дубликатов пакетов в течение короткого интервала выбора Master. Однако допущения для типового сценария, вероятно, охватывают большинство развёртываний, потери Master-маршрутизатора редки, а ожидаемая сходимость выбора Master достаточно мала (<< 1 секунды). Таким образом, оптимизация VRRP обеспечивает значительное упрощение протокола, при этом вероятность кратковременного нарушения работы сети незначительна.

4. Примеры конфигурации

4.1. Пример 1

На рисунке показана простая сеть с двумя маршрутизаторами VRRP, реализующими 1 виртуальный маршрутизатор.

        +-----------+ +-----------+
        |   Rtr1    | |   Rtr2    |
        |(MR VRID=1)| |(BR VRID=1)|
        |           | |           |
VRID=1  +-----------+ +-----------+
IPvX A--------->*            *<---------IPvX B
                |            |
                |            |
----------------+------------+-----+----------+----------+----------+--
                                   ^          ^          ^          ^
                                   |          |          |          |
Адреса IPvX по умолчанию-----> (IPvX A)   (IPvX A)   (IPvX A)   (IPvX A)
                                   |          |          |          |
                          IPvX H1->* IpvX H2->* IPvX H3->* IPvX H4->*
                                +--+--+    +--+--+    +--+--+    +--+--+
                                |  H1 |    |  H2 |    |  H3 |    |  H4 |
                                +-----+    +-----+    +--+--+    +--+--+
   Обозначения
         --+---+---+-- = Ethernet, Token Ring, FDDI
                     H = Хост
                    MR = Master-маршрутизатор
                    BR = Backup-маршрутизатор
                    *  = адрес IPvX ; X = 4 для IPv4, 6 для IPv6
                (IPvX) = принятый по умолчанию маршрутизатор для хостов


Исключив упоминания VRRP (VRID=1) на рисунке, можно считать это типичным развёртыванием.

В случае IPv4 (т. е. IPvX = IPv4 на рисунке) каждому маршрутизатору назначается постоянный адрес IPv4 на интерфейсе ЛВС (Rtr1 получает IPv4 A, а Rtr2 — IPv4 B), а каждый хост устанавливает принятый по умолчанию маршрут через один из маршрутизаторов (в этом примере используется Rtr1 с адресом IPv4 A).

В случае IPv6 (т. е. IPvX = IPv6 на рисунке) каждый маршрутизатор имеет адрес IPv6 link-local на интерфейсе ЛВС (Rtr1 получает IPv6 Link-Local A, а Rtr2 — IPv6 Link-Local B), а каждый хост узнает принятый по умолчанию маршрут из Router Advertisement от одного из этих маршрутизаторов (в этом примере используется Rtr1 с адресом IPv6 Link-Local A).

В среде IPv4 VRRP каждый маршрутизатор имеет в точности 1 постоянно назначенный адрес IPv4. О Rtr1 говорят, что он имеет адрес IPv4 A, а Rtr2 — IPv4 B. Затем виртуальный адрес определяется назначением уникального идентификатора с адресом, принадлежащим маршрутизатору.

В среде IPv6 VRRP каждый маршрутизатор имеет в точности 1 постоянно назначенный адрес IPv6 Link-Local. Rtr1 получает адрес IPv6 A, а Rtr2 — IPv6 B. Затем виртуальный адрес определяется назначением уникального идентификатора с адресом, принадлежащим маршрутизатору.

В обоих случаях (IPv4 и IPv6) протокол VRRP управляет переключением виртуального маршрутизатора на Backup.

Приведённый выше пример для IPv4 показывает виртуальный маршрутизатор, настроенный на адрес IPv4, принадлежащий Rtr1 (VRID=1, IPv4_Address=A). Когда протокол VRRP включён на Rtr1 для VRID=1, этот маршрутизатор будет заявлять себя как Master с приоритетом 255, поскольку он является владельцем адреса IP виртуального маршрутизатора. Когда VRRP включён на Rtr2 для VRID=1, этот маршрутизатор будет в состоянии Backup с приоритетом 100 (задан по умолчанию), поскольку он не владеет адресом IPv4. При отказе Rtr1 протокол VRRP переведёт Rtr2 в состояние Master, временно передавая ему ответственность за пересылку IPv4 A для обеспечения непрерывного обслуживания хостов. При восстановлении Rtr1 он снова примет роль Master.

Приведённый выше пример для IPv6 показывает виртуальный маршрутизатор, настроенный на адрес IPv6, принадлежащий Rtr1 (VRID=1, IPv6_Address=A). Когда протокол VRRP включён на Rtr1 для VRID=1, этот маршрутизатор будет заявлять себя как Master с приоритетом 255, поскольку он является владельцем адреса IPv6 виртуального маршрутизатора. Когда VRRP включён на Rtr2 для VRID=1, этот маршрутизатор будет в состоянии Backup с приоритетом 100 (задан по умолчанию), поскольку он не владеет адресом IPv6. При отказе Rtr1 протокол VRRP переведёт Rtr2 в состояние Master, временно передавая ему ответственность за пересылку IPv6 A для обеспечения непрерывного обслуживания хостов.

Отметим, что для обоих случаев в этом примере IPvX B не резервируется и лишь применяется в качестве адреса интерфейса Rtr2. Для резервирования IPvX B требуется второй виртуальный маршрутизатор, как показано ниже.

4.2. Пример 2

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

        +-----------+      +-----------+
        |   Rtr1    |      |   Rtr2    |
        |(MR VRID=1)|      |(BR VRID=1)|
        |(BR VRID=2)|      |(MR VRID=2)|
VRID=1  +-----------+      +-----------+  VRID=2
IPvX A -------->*            *<---------- IPvX B
                |            |
                |            |
----------------+------------+-----+----------+----------+----------+--
                                   ^          ^          ^          ^
                                   |          |          |          |
Адреса IPvX по умолчанию-----> (IPvX A)   (IPvX A)   (IPvX A)   (IPvX A)
                                   |          |          |          |
                          IPvX H1->* IpvX H2->* IPvX H3->* IPvX H4->*
                                +--+--+    +--+--+    +--+--+    +--+--+
                                |  H1 |    |  H2 |    |  H3 |    |  H4 |
                                +-----+    +-----+    +--+--+    +--+--+
   Обозначения
         --+---+---+-- = Ethernet, Token Ring, FDDI
                     H = Хост
                    MR = Master-маршрутизатор
                    BR = Backup-маршрутизатор
                    *  = адрес IPvX ; X = 4 для IPv4, 6 для IPv6
                (IPvX) = принятый по умолчанию маршрутизатор для хостов


В случае IPv4 (т. е. IPvX = IPv4 на рисунке) половина хостов настроена на маршрут через IPv4 A маршрутизатора Rtr1, другая — через IPv4 B. Настройка виртуального маршрутизатора VRID=1 совпадает с предыдущим примером (параграф 4.1. Пример 1) и добавлен второй виртуальный маршрутизатор с адресом IPv4, принадлежащим Rtr2 (VRID=2, IPv4_Address=B). В этом случае Rtr2 будет заявлять себя как Master для VRID=2, а Rtr1 будет Backup. Этот вариант демонстрирует развёртывание, где доступны оба маршрутизатора и обеспечивается полное резервирование для отказоустойчивости.

В случае IPv6 (т. е. IPvX = IPv6 на рисунке) половина хостов настроена на маршрут через IPv6 A маршрутизатора Rtr1, другая — через IPv6 B. Настройка виртуального маршрутизатора VRID=1 совпадает с предыдущим примером (параграф 4.1. Пример 1) и добавлен второй виртуальный маршрутизатор с адресом IPv6, принадлежащим Rtr2 (VRID=2, IPv6_Address=B). В этом случае Rtr2 будет заявлять себя как Master для VRID=2, а Rtr1 будет Backup. Этот вариант демонстрирует развёртывание, где доступны оба маршрутизатора и обеспечивается полное резервирование для отказоустойчивости.

Детали распределения нагрузки выходят за рамки этого документа. Однако в случае, когда серверам нужны разные веса, может не иметь смысла полагаться лишь на анонсы маршрутизаторов для распределения между ними нагрузки.

5. Протокол

Пакет VRRP предназначен для передачи всем маршрутизаторам VRRP приоритета и состояния ведущего (Master) маршрутизатора, связанного с VRID.

Когда VRRP защищает адрес IPv4, пакеты VRRP инкапсулируются в IPv4 и передаются по групповому адресу IPv4, выделенному для VRRP.

Когда VRRP защищает адрес IPv6, пакеты VRRP инкапсулируются в IPv4 и передаются по групповому адресу IPv6, выделенному для VRRP.

5.1. Формат пакета VRRP

В этом разделе определён формат пакета VRRP и соответствующие поля заголовка IP.

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                        Поля IPv4 или IPv6                     |
   ...                                                             ...
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |Version| Type  | Virtual Rtr ID|   Priority    |Count IPvX Addr|
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |(rsvd) |     Max Adver Int     |          Checksum             |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    +                                                               +
    |                         Адреса IPvX                           |
    +                                                               +
    +                                                               +
    +                                                               +
    +                                                               +
    |                                                               |
    +                                                               +
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


5.1.1. Описания полей IPv4

5.1.1.1. Source Address

Основной адрес IPv4 на интерфейсе, с которого передаётся пакет.

5.1.1.2. Destination Address

Групповой адрес IPv4, выделенный IANA для VRRP (224.0.0.18) с действием на локальном канале (link-local). Маршрутизаторам недопустимо пересылать дейтаграммы с таким адресом получателя независимо от TTL.

5.1.1.3. TTL

Поле TTL должно иметь значение 255. Маршрутизатор VRRP должен отбрасывать принятые пакеты с иным TTL.

5.1.1.4. Protocol

Номер протокола IPv4, выделенный IANA для VRRP — 112 (десятичный).

5.1.2. Описания полей IPv6

5.1.2.1. Source Address

Адрес IPv6 link-local на интерфейсе, с которого передаётся пакет.

5.1.2.2. Destination Address

Групповой адрес IPv6, выделенный IANA для VRRP — FF02:0:0:0:0:0:0:12. Это групповой адрес с действием на локальном канале (link-local). Маршрутизаторам недопустимо пересылать дейтаграммы с таким адресом получателя независимо от Hop Limit.

5.1.2.3. Hop Limit

Поле Hop Limit должно иметь значение 255. Маршрутизатор VRRP должен отбрасывать принятые пакеты с иным Hop Limit.

5.1.2.4. Next Header

Протокол IPv6 Next Header, выделенный IANA для VRRP — 112 (десятичный).

5.2. Описания полей VRRP

5.2.1. Version

Поле, указывающее версию протокола VRRP для данного пакета. Этот документ определяет версию 3.

5.2.2. Type

Поле указывает тип данного пакета VRRP. В этой версии протокола определён единственный тип

   1 ADVERTISEMENT

Пакеты неизвестного типа должны отбрасываться.

5.2.3. Virtual Rtr ID (VRID)

Поле Virtual Rtr ID указывает виртуальный маршрутизатор, статус которого передаёт этот пакет.

5.2.4. Priority

Это поле указывает приоритет передающего маршрутизатора VRRP для виртуального маршрутизатора. Большее значение указывает более высокий приоритет. Значения интерпретируются как 8-битовое целое число без знака.

Поле приоритета для маршрутизатора VRRP, владеющего адресом IPvX, назначенным виртуальному маршрутизатору, должно иметь значение 255 (десятичное).

Маршрутизаторы VRRP, резервирующие виртуальный маршрутизатор, должны использовать значения приоритета от 1 до 254 (десятичные). По умолчанию приоритет маршрутизатора VRRP, резервирующего виртуальный маршрутизатор имеет значение 100 (десятичные).

Нулевой приоритет (0) имеет особое значение, указывающее, что текущий маршрутизатор Master прекратил участие в VRRP. Это служит для быстрого перехода маршрутизатора Backup в состояние Master без тайм-аута ведущего.

5.2.5. Count IPvX Addr

Число адресов IPv4 или IPv6 в этом анонсе VRRP (не менее 1).

5.2.6. Rsvd

Это поле должно иметь значение 0 при передаче и должно игнорироваться при получении.

5.2.7. Максимальный интервал между анонсами (Max Adver Int)

12-битовое поле, указывающее максимальный интервал между анонсами в сотых долях секунды. По умолчанию установлено значение 100 (1 секунда).

Отметим, что Master-маршрутизаторы с высоким приоритетом и меньшей частотой передачи по сравнению с Backup-маршрутизаторами, нестабильны. Это связано с тем, что маршрутизатор с меньшим приоритетом и более частой передачей анонсов может принять решение о том, что ему следует стать ведущим, до того, как услышит что-либо от приоритетного Master с низкой частотой анонсов. Это переключение будет временным, поскольку получив анонс от Master с высоким приоритетом, этот маршрутизатор вернётся к прежней роли.

5.2.8. Checksum

Поле контрольной суммы служит для обнаружения повреждений данных в сообщении VRRP.

Контрольная сумма представляет собой 16-битовое дополнение до 1 суммы дополнений до 1 слов всего сообщения VRRP, начиная с поля версии и заканчивая псевдозаголовком, определенным в параграфе 8.1 [RFC2460]. В поле next header псевдозаголовка должно быть установлено значение 112 (десятичное) для VRRP. При расчёте контрольной суммы значение поля checksum считается 0. Детали расчёта контрольных сумм приведены в [RFC1071].

5.2.9. IPvX Address

Это поле содержит 1 или несколько адресов IpvX, связанных с виртуальным маршрутизатором. Число адресов указано в поле Count IP Addr. Эти поля служат для поиска ошибок в конфигурации маршрутизаторов. Если указано несколько адресов, на всех маршрутизаторах, где эти адреса настроены, рекомендуется указывать их в одинаковом порядке для упрощения сравнений.

Для IPv4 это поле содержит 1 или несколько адресов IPv4, резервируемых виртуальным маршрутизатором.

Для IPv6 первым должен быть адрес IPv6 link-local, связанный с виртуальным маршрутизатором.

Это поле может содержать лишь адреса одного семейства (IPv4 или IPv6), т. е. смешивать IPv4 и IPv6 недопустимо.

6. Конечный автомат протокола

6.1. Параметры на уровне виртуального маршрутизатора

VRID

Идентификатор виртуального маршрутизатора — от 1 до 255 (десятичное). Значение по умолчанию не задано.

Priority

Приоритет, используемый данным маршрутизатором VRRP при выборе Master для этого виртуального маршрутизатора. Значение 255 (десятичное) зарезервировано для маршрутизатора, владеющего адресом IpvX, связанным с виртуальным маршрутизатором, значение 0 зарезервировано для маршрутизатора Master, указывающего снятие ответственности за виртуальный маршрутизатор. Значения от 1 до 254 (десятичные) доступны для маршрутизаторов VRRP, резервирующих виртуальный маршрутизатор. Большее значение задаёт более высокий приоритет. По умолчанию используется значение 100 (десятичное).

IPv4_Addresses

Один или несколько адресов IPv4, связанных с данным маршрутизатором. Значение по умолчанию не задано.

IPv6_Addresses

Один или несколько адресов IPv6, связанных с данным маршрутизатором. Значение по умолчанию не задано. Первым в списке должен быть адрес Link-Local, связанный с виртуальным маршрутизатором.

Advertisement_Interval

Время между ADVERTISEMENTS (в сотых долях секунды). По умолчанию задано 100 (1 секунда).

Master_Adver_Interval

Интервал анонсов, содержащихся в ADVERTISEMENTS от Master (в сотых долях секунды). Это значение сохраняют виртуальные маршрутизаторы в состоянии Backup и оно применяется при расчёте Skew_Time и Master_Down_Interval. Исходное значение совпадает с Advertisement_Interval.

Skew_Time

Величина смещения Master_Down_Interval в сотых долях секунды. Рассчитывается как (((256 — priority) * Master_Adver_Interval) / 256).

Master_Down_Interval

Интервал времени для Backup, чтобы объявить отказ Master (в сотых долях секунды). Рассчитывается как (3 * Master_Adver_Interval) + Skew_time.

Preempt_Mode

Определяет, будет ли (запускаемый или перезапускаемый) маршрутизатор Backup с более высоким приоритетом вытеснять Master с меньшим приоритетом. True (по умолчанию) разрешает вытеснение, False — запрещает.
Примечание. Маршрутизатор, владеющий адресом IpvX, связанным с виртуальным маршрутизатором, использует вытеснение независимо от этого флага.

Accept_Mode

Определяет, будет ли виртуальный маршрутизатор в состоянии Master воспринимать пакеты, адресованные владельцу IPvX, как свои, если IPvX ему не принадлежит. По умолчанию задано False. Развертывания, полагающиеся, например на ping для владельца адреса IPvX, могут устанавливать Accept_Mode = True.
Примечание. Сообщения IPv6 Neighbor Solicitation и Neighbor Advertisement недопустимо отбрасывать при Accept_Mode = False.

Virtual_Router_MAC_Address

MAC-адрес, указываемый в поле отправителя анонсов VRRP и в откликах ARP как MAC-адрес для IP_Addresses.

6.2. Таймеры

Master_Down_Timer

Таймер, срабатывающий при отсутствии ADVERTISEMENT в течение Master_Down_Interval.

Adver_Timer

Таймер, вызывающий отправку ADVERTISEMENT на основе Advertisement_Interval.

6.3. Диаграмма смены состояний

                   +---------------+
        +--------->|               |<-------------+
        |          |  Initialize   |              |
        |   +------|               |----------+   |
        |   |      +---------------+          |   |
        |   |                                 |   |
        |   V                                 V   |
+---------------+                       +---------------+
|               |---------------------->|               |
|    Master     |                       |    Backup     |
|               |<----------------------|               |
+---------------+                       +---------------+


6.4. Описание состояний

В приведённых ниже описаниях имена состояний указываются в форме {state-name}, а пакеты — заглавными буквами.

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

6.4.1. Initialize

В этом состоянии маршрутизатор ожидает события Startup, т. е. определяемого реализацией механизма, запускающего протокол после его настройки. Механизм настройки выходит за рамки спецификации.

   (100) По событию Startup выполняются указанные ниже действия.
      (105) Если Priority = 255 (маршрутизатор владеет адресом IPvX,
            связанным с виртуальным маршрутизатором,
         (110) передаётся ADVERTISEMENT.
         (115) Если защищаемый адрес IPvX является IPv4, 
            (120) передаётся широковещательный беспричинный запрос ARP с 
                  MAC-адресом виртуального маршрутизатора для каждого 
                  адреса IP, связанного с виртуальным маршрутизатором,
         (125) иначе, // IPv6
            (130) для каждого адреса IPv6, связанного с виртуальным
                  маршрутизатором, передаётся назапрошенный анонс
                  ND Neighbor Advertisement с установленным флагом R
                  (Router), сброшенным флагом S (Solicited ), 
                  установленным влагом O (Override), целевым адресом IPv6
                  виртуального маршрутизатора и целевым адресом канального
                  уровня, содержащим MAC-адрес виртуального маршрутизатора.
         (135) endif // защищаемый адрес является IPv4?
         (140) Устанавливается Adver_Timer = Advertisement_Interval.
         (145) Переход в состояние {Master}.
      (150) Иначе // маршрутизатор не владеет виртуальным адресом
         (155) Устанавливается Master_Adver_Interval = Advertisement_Interval.
         (160) Устанавливается Master_Down_Timer = Master_Down_Interval.
         (165) Переход в состояние {Backup}.
      (170) endif // приоритет не был равен 255
   (175) endif // было принято событие Startup

6.4.2. Backup

В состоянии {Backup} отслеживается доступность и состояние маршрутизатора Master.

   (300) Маршрутизатор VRRP ДОЛЖЕН выполнять указанные ниже действия.
      (305) Если защищаемый адрес IPvX является IPv4, 
         (310) НЕДОПУСТИМО отвечать на запросы ARP для адресов IPv4,
               связанных с виртуальным маршрутизатором,
      (315) иначе // IPv6
         (320) НЕДОПУСТИМО отвечать на сообщения ND Neighbor Solicitation
               для адресов IPv6, связанных с виртуальным маршрутизатором.
         (325) НЕДОПУСТИМО передавать сообщения ND Router Advertisement 
               для виртуального маршрутизатора.
      (330) endif // защищаемый адрес является IPv4?
      (335) ДОЛЖНЫ отбрасываться пакеты с MAC-адресом получателя,
            совпадающим с MAC-адресом виртуального маршрутизатора.
      (340) НЕДОПУСТИМО воспринимать пакеты, направленные по адресам IPvX,
            связанным с виртуальным маршрутизатором.
      (345) При получении события Shutdown 
         (350) отключается таймер Master_Down_Timer,
         (355) состояние меняется на {Initialize}.
      (360) endif // событие Shutdown
      (365) При завершении отсчёта Master_Down_Timer 
         (370) передаётся ADVERTISEMENT.
         (375) Если защищаемый адрес IPvX является IPv4, 
            (380) передаётся широковещательный беспричинный запрос ARP с 
                  MAC-адресом виртуального маршрутизатора для каждого 
                  адреса IPv4, связанного с виртуальным маршрутизатором,            
         (385) иначе // IPv6
            (390) вычисляется и присоединяется групповой адрес Solicited-
                  Node [RFC4291] для адресов IPv6, связанных с
                  виртуальным маршрутизатором.
            (395) Для каждого адреса IPv6, связанного с виртуальным 
                  маршрутизатором передаётся незапрошенный анонс 
                  ND Neighbor Advertisement с установленным флагом R
                  (Router), сброшенным флагом S (Solicited ), 
                  установленным влагом O (Override), целевым адресом IPv6
                  виртуального маршрутизатора и целевым адресом канального
                  уровня, содержащим MAC-адрес виртуального маршрутизатора.
         (400) endif // защищаемый адрес является IPv4?
         (405) Устанавливается Adver_Timer = Advertisement_Interval.
         (410) Переход в состояние {Master}.
      (415) endif // завершение Master_Down_Timer.
      (420) Если получен анонс ADVERTISEMENT,
         (425) Если в ADVERTISEMENT поле Priority = 0,
            (430) Устанавливается Master_Down_Timer = Skew_Time,
         (440) иначе // Priority отличается от 0.
            (445) Если Preempt_Mode = False или Priority в
                  ADVERTISEMENT не меньше локального Priority, 
               (450) Устанавливается Master_Adver_Interval = интервалу 
                     анонсирования из ADVERTISEMENT
               (455) Пересчитывается Master_Down_Interval.
               (460) Master_Down_Timer сбрасывавется в Master_Down_Interval.
            (465) Иначе // вытеснение включено и 3 приоритет меньше
               (470) Отбрасывается ADVERTISEMENT
            (475) endif // проверка вытеснения
         (480) endif // Priority = 0?
      (485) endif // был получен анонс ADVERTISEMENT?
   (490) endwhile // состояние Backup

6.4.3. Master

В состоянии {Master} маршрутизатор выполняет пересылку для адресов IPvX, связанных с виртуальным маршрутизатором. Поле Preempt_Mode в этом состоянии не принимается во внимание.

   (600) Маршрутизатор VRRP ДОЛЖЕН выполнять указанные ниже действия.
      (605) Если защищаемый адрес IPvX является IPv4, 
         (610) маршрутизатор ДОЛЖЕН отвечать на запросы ARP для адресов 
               IPv4, связанных с виртуальным маршрутизатором,
      (615) иначе // IPv6
         (620) маршрутизатор ДОЛЖЕН входить в группу Solicited-Node
               для адресов IPv6, связанных с виртуальным маршрутизатором,
         (625) ДОЛЖЕН отвечать на сообщения ND Neighbor Solicitation
               для адресов IPv6, связанных с виртуальным маршрутизатором,
         (630) ДОЛЖЕН передавать ND Router Advertisement для
               виртуального маршрутизатора.
         (635) Если Accept_Mode = False, НЕДОПУСТИМО отбрасывать IPv6 
               Neighbor Solicitation и Neighbor Advertisement.
      (640) endif // IPv4?
      (645) ДОЛЖЕН пересылать пакеты с MAC-адресом получателя,
            совпадающим с MAC-адресом виртуального маршрутизатора.
      (650) ДОЛЖЕН воспринимать пакеты, направленные по адресам IPvX, 
            связанным с виртуальным маршрутизатором, если он владеет 
            адресом IPvX или Accept_Mode = True. В иных случаях 
            НЕДОПУСТИМО воспринимать пакеты.
      (655) Если получено событие Shutdown,
         (660) отключается Adver_Timer,
         (665) передаётся ADVERTISEMENT с Priority = 0,
         (670) состояние меняется на {Initialize}.
      (675) endif // событие Shutdown.
      (680) Если завершён отсчёт Adver_Timer, 
         (685) передаётся ADVERTISEMENT,
         (690) Adver_Timer сбрасывается в Advertisement_Interval.
      (695) endif // завершение отсчёта Adver_Timer
      (700) Если получен анонс ADVERTISEMENT,
         (705) Если Priority = 0, 
            (710) передается ADVERTISEMENT,
            (715)  Adver_Timer сбрасывается в Advertisement_Interval,
         (720) иначе // Priority отличается от 0
            (725) Если Priority в ADVERTISEMENT больше локального,
            (730) или 
            (735) если Priority в ADVERTISEMENT совпадает с локальным
                  и первичный адрес IPvX у отправителя больше локального
                  первичного адреса IPvX,
               (740) отключается Adver_Timer,
               (745) устанавливается Master_Adver_Interval = интервал
                     анонсов из ADVERTISEMENT,
               (750) пересчитывается  Skew_Time,
               (755) пересчитывается Master_Down_Interval,
               (760) устанавливается Master_Down_Timer = Master_Down_Interval
               (765) состояние меняется на {Backup},
            (770) иначе // новый Master
               (775) отбрасывается ADVERTISEMENT
            (780) endif // новый Master?
         (785) endif // Priority = 0?
      (790) -endif // получен анонс ADVERTISEMENT
   (795) endwhile // состояние Master.

7. Передача и приём пакетов VRRP

7.1. Приём пакетов VRRP

При получении пакета VRRP выполняются указанные ниже действия

  • Если принят пакет IPv4,

    • должно проверяться условие IPv4 TTL = 255,

  • иначе // принят пакет IPv6

    • должно проверяться условие IPv6 Hop Limit = 255.

  • endif

  • Должна проверяться версия VRRP 3.

  • Должна проверяться полнота полученного пакета VRRP (фиксированные поля и адреса IPvX).

  • Должна проверяться контрольная сумма VRRP.

  • Должна проверяться настройка VRID на приёмном интерфейсе и то, что локальный маршрутизатор не является владельцем адреса IPvX (Priority = 255).

При отрицательном результате любой из проверок получатель должен отбросить пакет, следует записать событие в системный журнал (log) и можно указать ошибку через систему управления сетью.

  • Можно проверить, что Count IPvX Addrs и список адресов IPvX, соответствуют адресам, заданным для VRID.

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

7.2. Передача пакетов VRRP

При передаче пакета VRRP должны выполняться указанные ниже операции.

  • Поля пакета VRRP заполняются в соответствии с состоянием конфигурации виртуального маршрутизатора.

  • Рассчитывается контрольная сумма VRRP.

  • Если защищаемым адресом является IPv4,

    • устанавливается MAC-адрес отправителя в соответствии с MAC-адресом виртуального маршрутизатора;

    • для адреса отправителя IPv4 устанавливается первичный адрес интерфейса IPv4,

  • иначе, // IPv6

    • устанавливается MAC-адрес отправителя в соответствии с MAC-адресом виртуального маршрутизатора;

    • для адреса отправителя IPv6 устанавливается адрес интерфейса IPv6 Link-Local.

  • endif

  • Для протокола IPvX указывается значение VRRP.

  • Пакет VRRP передаётся в группу VRRP IPvX (multicast).

Примечание. Пакеты VRRP передаются с MAC-адресом виртуального маршрутизатора в качестве MAC источника, чтобы обучающиеся мосты могли корректно определить сегмент ЛВС, куда подключён виртуальный маршрутизатор.

7.3. MAC-адрес виртуального маршрутизатора

MAC-адрес виртуального маршрутизатора является адресом IEEE 802 MAC в показанном ниже формате.

Для IPv4: 00-00-5E-00-01-{VRID} (шестнадцатеричные цифры со стандартным для Internet порядком битов)

Первые 3 октета выводятся из уникального идентификатора организации IANA OUI (Organizational Unique Identifier). Следующие 2 октета (00-01) указывают адресный блок, выделенный для протокола VRRP с IPv4, {VRID} указывает идентификатор виртуального маршрутизатора. Это позволяет организовать в сети до 255 маршрутизаторов IPv4 VRRP.

Для IPv6: 00-00-5E-00-02-{VRID} (шестнадцатеричные цифры со стандартным для Internet порядком битов)

Первые 3 октета выводятся из IANA OUI. Следующие 2 октета (00-02) указывают адресный блок, выделенный для протокола VRRP с IPv6, {VRID} указывает идентификатор виртуального маршрутизатора. Это позволяет организовать в сети до 255 маршрутизаторов IPv6 VRRP.

7.4. Идентификаторы интерфейсов IPv6

Маршрутизаторы IPv6 с работающим VRRP должны создавать идентификаторы своих интерфейсов обычным путём (например, Transmission of IPv6 Packets over Ethernet Networks [RFC2464]). Им недопустимо использовать MAC-адрес виртуального маршрутизатора для создания идентификаторов EUI-64 (Modified Extended Unique Identifier).

Эта спецификация VRRP описывает, как анонсировать и распознавать адреса IPv6 Link-Local маршрутизаторов VRRP и преобразовывать другие адреса IPv6 в MAC-адреса виртуального маршрутизатора.

8. Операционные вопросы

8.1. IPv4

8.1.1. ICMP Redirect

Сообщения ICMP Redirect могут использоваться обычным способом при работе VRRP между группой маршрутизаторов. Это позволяет применять VRRP в средах с асимметричной топологией.

Адресом источника IPv4 в ICMP Redirect следует быть адресу, используемому конечным хостом при выборе следующего узла пересылки (next-hop). Если маршрутизатор VRRP выступает как Master для виртуальных маршрутизаторов, содержащих адреса, которыми он не владеет, маршрутизатор должен определить, какому из виртуальных маршрутизаторов был отправлен пакет, для указания адреса перенаправления. Одним из способов определения использованного виртуального маршрутизатора служит проверка MAC-адреса получателя в вызвавшем перенаправление пакете.

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

8.1.2. Запросы ARP от хостов

Когда хост передаёт запрос ARP для одного из адресов IPv4 виртуального маршрутизатора, Virtual Router Master должен отвечать откликом ARP, указывающим виртуальный MAC-адрес для виртуального маршрутизатора. Отметим, что адресом источника в кадре Ethernet с таким откликом ARP является физический MAC-адрес физического маршрутизатора. Маршрутизатору Virtual Router Master недопустимо указывать свой физический MAC-адрес в отклике ARP. Это позволяет клиенту всегда применять один и тот же адрес MAC, независимо от текущего Master.

При загрузке или перезапуске маршрутизатора VRRP ему не следует передавать сообщений ARP с использованием своего физического MAC-адреса для принадлежащих ему адресов IPv4. Ему следует передавать лишь сообщения ARP с виртуальным MAC-адресом.

Это может повлечь указанные ниже последствия.

  • При настройке интерфейса маршрутизаторам Virtual Router Master следует передавать широковещательный беспричинный запрос ARP с MAC-адресом виртуального маршрутизатора и адресом этого интерфейса IPv4.

  • При загрузке системы, когда инициализируются интерфейсы для операций VRRP беспричинные запросы и отклики ARP задерживаются, пока не будут настроены адрес IPv4 и MAC-адрес виртуального маршрутизатора.

  • Когда нужен доступ, например, ssh, к конкретному маршрутизатору VRRP, должен применяться адрес IP, заведомо принадлежащий этому маршрутизатору.

8.1.3. Proxy ARP

При использовании Proxy ARP на маршрутизаторе VRRP этот маршрутизатор должен анонсировать MAC-адрес виртуального маршрутизатора в сообщениях Proxy ARP. Иное поведение может приводить к тому, что хосты получат реальный MAC-адрес маршрутизатора VRRP.

8.2. IPv6

8.2.1. ICMPv6 Redirect

Сообщения ICMPv6 Redirect можно применять обычным способом при работе VRRP между группой маршрутизаторов [RFC4443]. Это позволяет применять VRRP в средах с асимметричной топологией (например, маршрутизаторы VRRP не соединены с одними и теми же получателями).

Адресом источника IPv6 в ICMPv6 Redirect следует быть адресу, используемому конечным хостом при выборе следующего узла пересылки (next-hop). Если маршрутизатор VRRP выступает как Master для виртуальных маршрутизаторов, содержащих адреса, которыми он не владеет, маршрутизатор должен определить, какому из виртуальных маршрутизаторов был отправлен пакет, для указания адреса перенаправления. Одним из способов определения использованного виртуального маршрутизатора служит проверка MAC-адреса получателя в вызвавшем перенаправление пакете.

8.2.2. ND Neighbor Solicitation

Когда хост передаёт сообщение ND Neighbor Solicitation для адреса IPv6 виртуального маршрутизатора, Virtual Router Master должен отвечать сообщением ND Neighbor Solicitation, указывающим виртуальный MAC-адрес виртуального маршрутизатора. Маршрутизатору Virtual Router Master недопустимо указывать свой физический MAC-адрес в отклике. Это позволяет клиенту всегда применять один и тот же адрес MAC, независимо от текущего Master.

Когда Virtual Router Master передаёт сообщение ND Neighbor Solicitation для адреса хоста IPv6, он должен включать виртуальный MAC-адрес виртуального маршрутизатора, если он указывает опцию адреса источника на канальном уровне в сообщение Neighbor Solicitation. Недопустмо использовать свой физический MAC-адрес в опции адреса канального уровня для отправителя.

При загрузке или перезапуске маршрутизатора VRRP ему не следует передавать сообщений ND с использованием своего физического MAC-адреса для принадлежащих ему адресов IPv6. Ему следует передавать лишь сообщения ND с виртуальным MAC-адресом.

Это может повлечь указанные ниже последствия.

  • При настройке интерфейса маршрутизаторам Virtual Router Master следует передавать незапрошенное сообщение ND Neighbor Advertisement с MAC виртуального маршрутизатора и IPv6 на этом интерфейсе.

  • При загрузке системы, когда инициализируются интерфейсы для операций VRRP все сообщения ND Router Advertisement, Neighbor Advertisement и Solicitation должны задерживаться, пока не будут настроены адрес IPv6 и MAC-адрес виртуального маршрутизатора.

Отметим, что при перезапуске Master, когда защищаемый VRRP адрес является адресом интерфейса (Priority = 255) обнаружение дубликатов адресов (duplicate address detection или DAD) может не сработать, поскольку маршрутизатор Backup может ответить, что он владеет этим адресом. Решением является отказ от запуска DAD в этом случае.

8.2.3. Router Advertisement

Когда Backup VRRP становится Master для виртуального маршрутизатора, он отвечает за передачу анонсов Router Advertisement для виртуального маршрутизатора, как указано в параграфе 6.4.3. Master. Маршрутизаторы Backup должны быть настроены для отправки таких же опций Router Advertisement, какие применяет владелец адреса.

Опции Router Advertisement, анонсирующие особые услуги (например, Home Agent Information Option), присутствующие у владельца адреса, ему не следует передавать, пока маршрутизаторы Backup не готовы предоставлять полностью те же услуги и не имеют полной и синхронизированной базы данных для них.

8.3. IPvX

8.3.1. Возможные петли пересылки

Если маршрутизатор VRRP не является владельцем адреса, ему не следует пересылать пакеты, направленные по адресу IPvX, для которого он становится Master. Пересылка таких пакетов ведёт к ненужному трафику. Кроме того, в ЛВС, которые получают передаваемые пакеты (например, Token Ring), это может приводить к петлям пересылки, завершающимся лишь по IPvX TTL.

Одним из механизмов для маршрутизаторов VRRP является добавление и удаление отклонения (reject) маршрута к хосту для каждого принятого адреса IPvX при переходе в состояние MASTER и выходе из него.

8.3.2. Рекомендации по значениям приоритета

Значение приоритета 255 указывает конкретный маршрутизатор как владельца адреса IPvX. Нужно соблюдать осторожность, чтобы не указать таким способом больше 1 маршрутизатора на канале для одного VRID.

Маршрутизаторы с приоритетом 255 будут при запуске вытеснять маршрутизаторы с меньшим приоритетом. На канале настраивается не более 1 маршрутизатора с приоритетом 255, особенно при включённом вытеснении. Если нет маршрутизатора с таким приоритетом и вытеснение отключено, его (вытеснения) не будет.

При наличии нескольких маршрутизаторов Backup их значения приоритета следует распределять однородно. Например, если один маршрутизатор Backup имеет принятый по умолчанию приоритет 100 и добавляется другой Backup, приоритет 50 для него будет лучшим выбором, нежели 99 или 100, для более быстрого схождения.

8.4. Взаимодействие VRRPv3 и VRRPv2

8.4.1. Допущения

  1. Совместная работа VRRPv2 и VRRPv3 не обязательна.

  2. Смешивать VRRPv2 и VRRPv3 следует лишь на время перехода от VRRPv2 к VRRPv3. Смешение двух версий не следует принимать как постоянное решение.

8.4.2. Поддержка VRRPv2 в VRRPv3

Как отмечено выше, эта поддержка предназначена для сценариев обновления и не рекомендуется для постоянного развёртывания.

Реализация может включать флаг конфигурации, указывающий, что она принимает и передаёт анонсы VRRPv2 и VRRPv3. Когда виртуальный маршрутизатор настроен так и является Master, он должен передавать оба типа с заданной частотой (даже субсекундной).

Когда виртуальный маршрутизатор настроен таким образом и служит Backup, ему следует вводить тайм-аут на основе частоты, анонсируемой маршрутизатором Master. В случае VRRPv2 Master это означает, что он должен транслировать полученное значение тайм-аута (в секундах) в сотые доли секунды. Кроме того, маршрутизатору Backup следует игнорировать анонсы VRRPv2 от текущего Master, если от того приходят также пакеты VRRPv3. Он может когда VRRPv3 Master не передаёт пакетов VRRPv2, это говорит о том, не согласована поддержка маршрутизаторов VRRPv2.

8.4.3. Вопросы поддержки VRRPv2 в VRRPv3

8.4.3.1. Медленные, высокоприоритетные Master

См. также параграф 5.2.7. Максимальный интервал между анонсами (Max Adver Int).

VRRPv2 Master, взаимодействующий с субсекундным VRRPv3 Backup, является наиболее важным примером.

Реализации VRRPv2 не следует давать более высокий приоритет, чем реализации VRRPv2/VRRPv3, с которой она взаимодействует, если VRRPv2/VRRPv3 использует субсекундную скорость.

8.4.3.2. Перегрузка VRRPv2 Backup

Представляется возможным, что маршрутизатор VRRPv3 Master, передающий с интервалом в сотые доли секунды, может перегрузить VRRPv2 Backup с неочевидными результатами.

В случае обновления следует поначалу запускать маршрутизаторы VRRPv3 Master с более низкой частотой (например, 100 = 1 секунда), пока маршрутизаторы VRRPv2 не будут обновлены. Затем, когда станет ясно, что VRRPv3 работает правильно, поддержку VRRPv2 можно отключить и задать субсекундную скорость.

9. Вопросы безопасности

VRRP для IPvX сейчас не включает проверки подлинности. Прежние версии VRRP (для IPv4) включали несколько типов аутентификации от простой до строгой. Опыт эксплуатации и дальнейший анализ показали, что это не обеспечивает достаточной защиты для преодоления уязвимостей, связанных с неверно заданными секретами, что вело к выбору нескольких маршрутизаторов Master. По природе протокола VRRP даже криптозащита сообщений VRRP не мешает враждебным узлам вести себя как VRRP Master и создавать несколько ведущий. Аутентификация сообщений VRRP может помешать враждебному узлу перевести все корректно работающие маршрутизаторы в состояние Backup. Однако наличие нескольких Master может вызывать столько же проблем, как и отсутствие маршрутизаторов и аутентификация не может это предотвратить. Кроме того, даже если враждебный узел не может нарушить работу VRRP, он способен помешать ARP и создать такой же эффект, как переход всех маршрутизаторов в состояние Backup.

Некоторые коммутаторы L2 поддерживают фильтрацию, например, сообщений ARP и/или ND от конечных хостов по портам коммутатора. Этот механизм может также фильтровать сообщения VRRP от портов коммутатора, связанных с конечными хостами и его можно рассматривать в системах с недоверенными хостами.

Следует отметить, что эти атаки ничем не хуже и являются подмножеством атак, которые любой узел, подключенный к ЛВС, может организовать независимо от VRRP. Атаки, которые злонамеренный узел ЛВС может организовать, включают неразборчивый (promiscuous) приём пакетов для любого MAC-адреса маршрутизатора, передачу пакетов с MAC-адресом маршрутизатора в качестве адреса источника в заголовке L2, чтобы вынудить коммутаторы L2 передавать адресованные маршрутизатору пакеты злонамеренному узлу, передачу перенаправлений (redirect), вынуждающих хосты передавать свой трафик не туда, передачу незапрошенных откликов ND и ответы на запросы ND и т. п. Все это возможно независимо от реализации VRRP и протокол VRRP не добавляет таких уязвимостей.

Независимо от типа аутентификации, VRRP включает механизм (установка TTL = 255 и проверка при получении), защищающий VRRP от внедрения пакетов из удалённой сети. Это избавляет от большинства удалённых атак.

VRRP не обеспечивает конфиденциальности. Она не требуется для корректной работы VRRP и в сообщениях VRRP нет сведений, которые нужно было бы скрывать от других узлов ЛВС.

В контексте IPv6 при развёртывании защищённого обнаружения соседей (SEcure Neighbor Discovery или SEND) протокол VRRP совместим с режимами trust anchor и trust anchor or cga в SEND [RFC3971]. Конфигурация SEND должна давать маршрутизаторам Master и Backup одинаковое делегирование префикса в сертификатах, чтобы Master и Backup анонсировали один набор префиксов подсетей. Однако маршрутизаторам Master и Backup следует иметь свои пары ключей, чтобы секретный ключ не был общим.

10. Участники работы и благодарности

Редактор благодарен V. Ullanatt за рецензирование ранней версии. Этот документ содержит мало нового материала (новый текст содержится в Приложении A) и был создан путём слияния xml-представления [VRRP-IPv6] и [RFC3768] с последующим внесением изменений, обсуждавшихся недавно в почтовой конференции рабочей группы VRRP. R. Hinden является автором, а J. Cruz — редактором первого. Участники разработки второго указаны ниже.

Связанный с IPv6 текст спецификации основан на [RFC2338], авторами которого являются S. Knight, D. Weaver, D. Whipple, R. Hinden, D. Mitzel, P. Hunt, P. Higginson, M. Shand, A. Lindem.

Автор [VRRP-IPv6] признателен Erik Nordmark, Thomas Narten, Steve Deering, Radia Perlman, Danny Mitzel, Mukesh Gupta, Don Provan, Mark Hollinger, John Cruz, Melissa Johnson за полезные предложения.

Связанный с IPv4 текст спецификации основан на [RFC3768]. Авторы этой спецификации благодарны Glen Zorn, Michael Lane, Clark Bremer, Hal Peterson, Tony Li, Barbara Denny, Joel Halpern, Steve Bellovin, Thomas Narten, Rob Montgomery, Rob Coltun, Radia Perlman, Russ Housley, Harald Alvestrand, Steve Bellovin, Ned Freed, Ted Hardie, Russ Housley, Bert Wijnen, Bill Fenner, Alex Zinin за их комментарии и предложения.

11. Взаимодействие с IANA

Агентство IANA выделило групповой адрес IPv6 link-local для работы VRRP по протоколу IPv6

      FF02:0:0:0:0:0:0:12

Присвоенные значения адресов вводятся в соответствии с параграфом 5.1.2.2. Destination Address.

Агентство IANA зарезервировало блок индивидуальных адресов IANA Ethernet для работы VRRP по протоколу IPv6

      00-00-5E-00-02-00 - 00-00-5E-00-02-FF (шестнадцатеричные)

Назначения указаны на сайте http://www.iana.org.

12. Литература

12.1. Нормативные документы

[ISO.10038.1993] International Organization for Standardization, «Information technology — Telecommunications and information exchange between systems — Local area networks — Media access control (MAC) bridges», ISO Standard 10038, 1993.

[RFC2119] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, March 1997.

[RFC2460] Deering, S. and R. Hinden, «Internet Protocol, Version 6 (IPv6) Specification», RFC 24604, December 1998.

[RFC3768] Hinden, R., «Virtual Router Redundancy Protocol (VRRP)», RFC 3768, April 2004.

[RFC4291] Hinden, R. and S. Deering, «IP Version 6 Addressing Architecture», RFC 4291, February 2006.

[RFC4443] Conta, A., Deering, S., and M. Gupta, Ed., «Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification», RFC 4443, March 2006.

[RFC4861] Narten, T., Nordmark, E., Simpson, W., and H. Soliman, «Neighbor Discovery for IP version 6 (IPv6)», RFC 4861, September 2007.

12.2. Дополнительная литература

[VRRP-IPv6] Hinden, R. and J. Cruz, «Virtual Router Redundancy Protocol for IPv6», Work in Progress, March 2007.

[IPSTB] Higginson, P. and M. Shand, «Development of Router Clusters to Provide Fast Failover in IP Networks», Digital Technical Journal, Volume 9 Number 3, Winter 1997.

[IPX] Novell Incorporated, «IPX Router Specification Version 1.10», October 1992.

[RFC1071] Braden, R., Borman, D., Partridge, C., and W. Plummer, «Computing the Internet checksum», RFC 1071, September 1988.

[RFC1256] Deering, S., Ed., «ICMP Router Discovery Messages», RFC 1256, September 1991.

[RFC1469] Pusateri, T., «IP Multicast over Token-Ring Local Area Networks», RFC 1469, June 1993.

[RFC2131] Droms, R., «Dynamic Host Configuration Protocol», RFC 2131, March 1997.

[RFC2281] Li, T., Cole, B., Morton, P., and D. Li, «Cisco Hot Standby Router Protocol (HSRP)», RFC 2281, March 1998.

[RFC2328] Moy, J., «OSPF Version 2», STD 54, RFC 2328, April 1998.

[RFC2338] Knight, S., Weaver, D., Whipple, D., Hinden, R., Mitzel, D., Hunt, P., Higginson, P., Shand, M., and A. Lindem, «Virtual Router Redundancy Protocol», RFC 2338, April 1998.

[RFC2453] Malkin, G., «RIP Version 2», STD 56, RFC 2453, November 1998.

[RFC2464] Crawford, M., «Transmission of IPv6 Packets over Ethernet Networks», RFC 2464, December 1998.

[RFC3971] Arkko, J., Ed., Kempf, J., Zill, B., and P. Nikander, «SEcure Neighbor Discovery (SEND)», RFC 3971, March 2005.

[TKARCH] IBM Incorporated, «IBM Token-Ring Network, Architecture Specification, Publication SC30-3374-02, Third Edition», September 1989.

Приложение A. Работа через FDDI, Token Ring, ATM LANE

A.1. Работа через FDDI

Интерфейсы FDDI удаляют из кольца FDDI кадры с MAC-адресом источника, совпадающим с аппаратным адресом устройства. При некоторых условиях, таких как изоляция маршрутизатора, повреждение кольца, протокольные переходы и т. п., VRRP может приводить к наличию нескольких маршрутизаторов Master. Если Master устанавливает MAC-адрес виртуального маршрутизатора на устройстве FDDI, анонсы ADVERTISEMENTS от других ведущих будут удаляться из кольца при выборе Master и схождения не произойдет.

Для предотвращения этого реализации следует настраивать MAC-адрес виртуального маршрутизатора с использованием индивидуального (unicast) фильтра MAC в устройстве FDDI вместо смены аппаратного адреса MAC. Это предотвратит удаление маршрутизатором Master анонсов ADVERTISEMENTS, исходящих от других.

A.2. Работа через Token Ring

Некоторые характеристики Token Ring осложняют работу VRRP, как указано ниже.

  • Для переключения на новый маршрутизатор Master, размещённый в другом сегменте моста Token-Ring при использовании мостов source-route требуется механизм обновления кэшированных данных source-route.

  • Не поддерживается общего для старых и новых реализаций адаптера Token-Ring не поддерживается общий механизм групповой передачи. Хотя многие из новых адаптеров Token-Ring поддерживают групповые адреса, поддержка функциональных адресов Token-Ring является единственным общедоступным механизмом групповой передачи. Ограниченное число функциональных адресов Token-Ring может вызывать конфликты при их использовании.

Из-за этих сложностей предпочтительным режимом работы через Token Ring является применение функциональных адресов Token-Ring для виртуальных MAC-адресов VRID. В этих функциональных адресах Token-Ring два старших бита первого октета MAC имеют значение 15. Адреса занимают диапазон от 03-00-00-00-00-80 до 03-00-02-00-00-00 (канонический формат). Однако в отличие от групповых адресов для каждой битовой позиции имеется лишь 1 функциональный адрес. Адреса от 03-00-00-10-00-00 до 03-00-02-00-00-00 зарезервированы архитектурой Token-Ring [TKARCH] для определяемых пользователями приложений. Однако, поскольку имеется лишь 12 определяемых пользователем функциональных адресов Token-Ring, могут существовать отличные от IPvX протоколы, применяющие те же адреса. Поскольку протокол Novell IPX [IPX] использует функциональный адрес 03-00-00-10-00-00, при работе VRRP через Token Ring следует избегать его применения. В общем случае пользователи Token-Ring VRRP отвечают за конфликты при распознавании других определяемых пользователем функциональных адресов Token-Ring.

VRID напрямую сопоставляются с функциональными адресами Token-Ring. Для снижения вероятности конфликтов выделение начинается с большего функционального адреса. Большинство отличных от IPvX протоколов используют первый адрес или пару пользовательских функциональных адресов и предполагается, что пользователи VRRP будут выбирать VRID последовательно, начиная с 1.

VRID

Функциональный адрес Token-Ring

1

03-00-02-00-00-00

2

03-00-04-00-00-00

3

03-00-08-00-00-00

4

03-00-10-00-00-00

5

03-00-20-00-00-00

6

03-00-40-00-00-00

7

03-00-80-00-00-00

8

03-00-00-01-00-00

9

03-00-00-02-00-00

10

03-00-00-04-00-00

11

03-00-00-08-00-00

Более кратко, октеты 3 и 4 функционального адреса имеют значение (0x4000 >> (VRID — 1)) в неканоническом формате.

Поскольку функциональные адреса не могут применяться в качестве адреса источника на уровне MAC в анонсах VRRP адресом источника служит реальный MAC-адрес. Это не является проблемой для мостов, поскольку пакеты, направленные по функциональным адресам, будут передаваться по пути проводника (explorer) связующего дерева [ISO.10038.1993].

Режим работы с функциональным адресом должен быть реализован на маршрутизаторах VRRP в сети Token Ring.

Кроме того, маршрутизаторы могут поддерживать индивидуальный (unicast) режим работы, чтобы использовать преимущества новых реализаций адаптеров Token-Ring, поддерживающих избирательное получение для множества индивидуальных адресов MAC, и избежать как группового трафика, так и конфликтов, связанных с применением функциональных адресов Token-Ring. Индивидуальный режим использует такое же сопоставление VRID с виртуальными MAC-адресами, как Ethernet. Однако имеется важное различие — пакеты запросов и откликов ND содержат виртуальный MAC-адрес в качестве адреса источника. Причина этого заключается в том, что реализации драйверов Token-Ring сохраняют кэш сопоставления адресов MAC и данных source-routing независимо от кэша ND.

Следовательно, эти реализации должны получать пакет с виртуальным MAC-адресом источника для передачи по этому адресу в сети с мостами source-route.

Для индивидуального режима Token Ring следует учитывать одно ограничение. Если маршрутизаторы VRID расположены в разных сегментах source-route-bridge и имеются реализации хостов, хранящие свои сведения source-route в кэше ND и не слушающие беспричинные ND, эти хосты не будут корректно обновлять свои данные ND source-route при смене ведущего маршрутизатора. Единственным решением является размещение всех маршрутизаторов с одним VRID в одном сегменте source-route-bridge и применение методов предотвращения критических отказов в этом сегменте. Эти методы выходят за рамки документа.

При индивидуальном и групповом режиме работы анонсы VRRP, передаваемые по адресу 224.0.0.18, следует инкапсулировать в соответствии с [RFC1469].

A.3. Работа через ATM LANE

Работа VRRP через ATM LANE на маршрутизаторах с интерфейсами ATM LANE и/или маршрутизаторах за прокси-LEC (LAN Emulation Client) выходит за рамки этого документа.

Адрес автора

Stephen Nadas (editor)
Ericsson
900 Chelmsford St., T3 4th Floor
Lowell, MA 01851
USA
Phone: +1 978 275 7448
EMail: stephen.nadas@ericsson.com

Перевод на русский язык

Николай Малых

nmalykh@protokols.ru


1Internet Engineering Task Force — комиссия по решению инженерных задач Internet.

2Internet Engineering Steering Group — комиссия по инженерным разработкам Internet.

3В оригинале ошибочно сказано «или», см. https://www.rfc-editor.org/errata/eid4698. Прим. перев.

4Заменён RFC 8200. Прим. перев.

5Порядок битов в адресе Token Ring отличается. Для преобразования значений можно воспользоваться таблицей. Прим. перев.

Рубрика: RFC | Оставить комментарий