RFC 8640 Dynamic Subscription to YANG Events and Datastores over NETCONF

Internet Engineering Task Force (IETF)                           E. Voit
Request for Comments: 8640                                 Cisco Systems
Category: Standards Track                                       A. Clemm
ISSN: 2070-1721                                                Futurewei
                                                      A. Gonzalez Prieto
                                                               Microsoft
                                                       E. Nilsen-Nygaard
                                                             A. Tripathy
                                                           Cisco Systems
                                                          September 2019

Dynamic Subscription to YANG Events and Datastores over NETCONF

Динамическая подписка на события и хранилища данных YANG через NETCONF

PDF

Аннотация

Этот документ обеспечивает привязку протокола управления сетью (Network Configuration Protocol или NETCONF) к возможности динамической подписки на уведомления и YANG-Push.

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

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

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

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

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

Авторские права (Copyright (c) 2019) принадлежат 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. Введение

Этот документ задаёт привязку потока событий, составляющих часть динамической подписки, к протоколу NETCONF [RFC6241]. Динамическая подписка определена в [RFC8639]. Поскольку [RFC8641] базируется на [RFC8639], этот документ позволяет клиенту NETCONF запрашивать через динамическую подписку и получать обновления из хранилища YANG на сервере NETCONF.

Документ предполагает знакомство читателя с терминологией и концепциями [RFC8639].

2. Терминология

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

В [RFC8639] определены термины dynamic subscription (динамическая подписка), event stream (поток событий), notification message (сообщение с уведомлением), publisher (издатель), receiver (получатель), subscriber (подписчик), subscription (подписка). Данный документ не задаёт новых терминов.

3. Совместимость с <create-subscription> из RFC 5277

Издатель может одновременно поддерживать RPC динамической подписки, как указано в [RFC8639], и RPC <create-subscription> из [RFC5277]. Однако в одной транспортной сессии NETCONF недопустимо поддерживать сразу эту спецификацию и RPC <create-subscription> из [RFC5277]. Для защиты от попыток использования обоих вариантов в одно транспортной сессии NETCONF применяются указанные ниже меры.

  • Решение должно возвращать элемент <rpc-error> [RFC6241] с error-tag operation-not-supported при получении RPC <create-subscription> в сессии NETCONF, где имеется подписка в соответствии с [RFC8639].

  • Решение должно возвращать элемент <rpc-error> [RFC6241] с error-tag operation-not-supported при получении запроса establish-subscription в сессии NETCONF, где имеется подписка на основе RPC <create-subscription> из [RFC5277].

Если издатель поддерживает эту спецификацию, но не реализует подписку в соответствии с [RFC5277], ему недопустимо анонсировать urn:ietf:params:netconf:capability:notification:1.0.

4. Обязательная поддержка XML, потока событий и хранилища

Должно поддерживаться свойство encode-xml из [RFC8639], указывающее, что XML является пригодным кодированием для RPC, уведомлений о смене состояния и содержимого подписки.

Издатель NETCONF, поддерживающий подписку на поток событий в соответствии с [RFC8639], должен поддерживать поток событий NETCONF, заданный этим документом.

5. Связность NETCONF и динамическая подписка

Управление динамическими подписками выполняется через RPC, как указано в [RFC8641] и [RFC8639]. Для динамической подписки при прерывании сессии NETCONF, вовлеченной establish-subscription, подписка должна прерываться.

Для динамической подписки любые RPC modify-subscription, delete-subscription, resync-subscription должны передаваться в той же сессии NETCONF, где была организована соответствующая подписка.

6. Уведомления

Уведомления, транспортируемые через NETCONF, должны кодироваться в сообщения <notification>, как указано в разделе 4 [RFC5277]. В соответствии с определением объекта <eventTime> в [RFC5277], в <eventTime> помещается время, когда произошло событие.

Для динамической подписки все уведомляющие сообщений должны использовать транспортную сессию NETCONF, где был вызов RPC establish-subscription.

7. Динамическая подписка и отклики RPC Error

При возникновении ошибки RPC, как указано в параграфе 2.4.6 [RFC8639] и Приложении A [RFC8641], отклик NETCONF RPC должен включать элемент <rpc-error> [RFC6241] с указанными ниже сведениями об ошибке.

  • error-type application.

  • Узел error-tag, значением которого является строка, соответствующая связанному с ошибкой идентификатору. Для заданных в этом документе механизмов error-tag будет соответствовать идентификаторам из (1) параграфа 2.4.6 в [RFC8639], показанным ниже (базовые ошибки подписки)

 

Идентификатор ошибки

error-tag

dscp-unavailable

invalid-value

encoding-unsupported

invalid-value

filter-unsupported

invalid-value

insufficient-resources

resource-denied

no-such-subscription

invalid-value

replay-unsupported

operation-not-supported

 

или (2) приложения A.1 к [RFC8641] для ошибок, связанных с конкретным хранилищем YANG

 

Идентификатор ошибки

error-tag

cant-exclude

operation-not-supported

datastore-not-subscribable

invalid-value

no-such-subscription-resync

invalid-value

on-change-unsupported

operation-not-supported

on-change-sync-unsupported

operation-not-supported

period-unsupported

invalid-value

update-too-big

too-big

sync-too-big

too-big

unchanging-selection

operation-failed

 

  • Может включаться error-severity или error.

  • Узел error-app-tag, значением которого является строка, соответствующая связанному с ошибкой идентификатору, как указано в параграфе 2.4.6 [RFC8639] для ошибок общего типа и в приложении A.1 к [RFC8641] для подписок на хранилища данных. Используемый идентификатор зависит от вызова RPC, для которого возникла ошибка. Каждый идентификатор ошибки вставляется как error-app-tag в формате <modulename>:<identityname>. Примером корректного кодирования служит ietf-subscribed-notifications:no-such-subscription. Допустимые значения ошибок для разных RPC указаны ниже.

 

RPC

Базовый идентификатор

establish-subscription

establish-subscription-error

modify-subscription

modify-subscription-error

delete-subscription

delete-subscription-error

kill-subscription

delete-subscription-error

resync-subscription

resync-subscription-error

 

  • В случаях ошибок при запросе establish-subscription или modify-subscription можно включать узел error-info, который может содержать в кодировке XML советы по установке параметров для повторения запроса RPC в будущем. Могут возвращаться структуры yang-data из [RFC8639] и [RFC8641], показанные ниже.

 

establish-subscription

Советы в yang-data structure

target: event stream

establish-subscription-stream-error-info

target: datastore

establish-subscription-datastore-error-info

 


modify-subscription

Советы в yang-data structure

target: event stream

modify-subscription-stream-error-info

target: datastore

modify-subscription-datastore-error-info

В структуру yang-data, помещенную в error-info, не следует включать необязательный лист reason, поскольку он будет избыточным с учётом сведений в error-app-tag.

В случае ошибок RPC delete-subscription, kill-subscription, resync-subscription не требуется включать error-info, поскольку subscription-id является единственным входным параметром RPC и советов о смена параметра не может быть.

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

Этот документ не создаёт новых проблем безопасности для динамических подписок в дополнение к рассмотренным в [RFC8639]. Но есть одно соображение, которое следует уточнить с учётом ориентированной на соединения природы NETCONF. В частности, если включающий ошибки или скомпрометированный подписчик NETCONF передаёт ряд запросов establish-subscription, эти подписки аккумулируются и могут потреблять излишние ресурсы системы. В таких случаях подписки можно прервать, закрывая соответствующую сессию NETCONF. Издатель может также приостановить часть активных подписок в сессии NETCONF для восстановления ресурсов и обеспечения нормальной работы других подписчиков.

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

Документ не требует действий IANA.

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

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

[RFC2119] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC5277] Chisholm, S. and H. Trevino, «NETCONF Event Notifications», RFC 5277, DOI 10.17487/RFC5277, July 2008, <https://www.rfc-editor.org/info/rfc5277>.

[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., «Network Configuration Protocol (NETCONF)», RFC 6241, DOI 10.17487/RFC6241, June 2011, <https://www.rfc-editor.org/info/rfc6241>.

[RFC8174] Leiba, B., «Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words», BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8639] Voit, E., Clemm, A., Gonzalez Prieto, A., Nilsen-Nygaard, E., and A. Tripathy, «Subscription to YANG Notifications», RFC 8639, DOI 10.17487/RFC8639, September 2019, <https://www.rfc-editor.org/info/rfc8639>.

[RFC8641] Clemm, A. and E. Voit, «Subscription to YANG Notifications for Datastore Updates», RFC 8641, DOI 10.17487/RFC8641, September 2019, <https://www.rfc-editor.org/info/rfc8641>.

[W3C.REC-xml-20081126] Bray, T., Paoli, J., Sperberg-McQueen, M., Maler, E., and F. Yergeau, «Extensible Markup Language (XML) 1.0 (Fifth Edition)», World Wide Web Consortium Recommendation REC-xml-20081126, November 2008, <https://www.w3.org/TR/2008/REC-xml-20081126>.

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

[RFC8347] Liu, X., Ed., Kyparlis, A., Parikh, R., Lindem, A., and M. Zhang, «A YANG Data Model for the Virtual Router Redundancy Protocol (VRRP)», RFC 8347, DOI 10.17487/RFC8347, March 2018, <https://www.rfc-editor.org/info/rfc8347>.

[XPATH] Clark, J. and S. DeRose, «XML Path Language (XPath) Version 1.0», November 1999, <https://www.w3.org/TR/1999/REC-xpath-19991116>.

Приложение A. Примеры

Это приложение не является нормативным. Используемые идентификаторы подписок 22, 23, 39, 99 служат лишь примерами. В реальной среде значения id могут быть достаточно большими целыми числами.

A.1. Обнаружение потока событий

Как указано в [RFC8639], поток событий представляет продолжающийся набор событий, доступных для подписки. Клиент NETCONF может получить список доступных потоков событий от издателя NETCONF с помощью операции <get> для контейнера streams верхнего уровня, заданного в параграфе 3.9 [RFC8639]. Приведённый ниже пример XML [W3C.REC-xml-20081126] иллюстрирует получения списка доступных потоков событий.

<rpc message-id="101"
  xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get>
    <filter type="subtree">
      <streams
     xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications"/>
    </filter>
  </get>
</rpc>

Рисунок 1. Запрос <get> для извлечения потоков событий.

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

A.2. Динамические подписки

A.2.1. Организация динамической подписки

На рисунке 2 показаны два успешных вызова RPC establish-subscription, как описано в [RFC8639]. Первый вызов имеет идентификатор подписки 22, второй — 23.

+------------+                 +-----------+
| Подписчик  |                 | Издатель  |
+------------+                 +-----------+
      |                              |
      |    Обмен возможностями       |
      |<---------------------------->|
      |                              |
      |    establish-subscription    |
      |----------------------------->|  (a)
      | RPC Reply: OK, id = 22       |
      |<-----------------------------|  (b)
      |                              |
      |     уведомление (для 22)     |
      |<-----------------------------|
      |                              |
      |    establish-subscription    |
      |----------------------------->|
      |     уведомление (для 22)     |
      |<-----------------------------|
      | RPC Reply: OK, id = 23       |
      |<-----------------------------|
      |                              |
      |     уведомление (для 22)     |
      |<-----------------------------|
      |     уведомление (для 23)     |
      |<-----------------------------|
      |                              |

Рисунок 2. Несколько подписок в сессии NETCONF.


В качестве примера передаваемых сведений ниже представлены сообщения для взаимодействий (a) и (b) на рисунке 2 (рисунки 3 и 4).

<rpc message-id="102" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <establish-subscription
      xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
    <stream-xpath-filter xmlns:ex="https://example.com/events">
      /ex:foo/
    </stream-xpath-filter>
    <stream>NETCONF</stream>
    <dscp>10</dscp>
  </establish-subscription>
</rpc>

Рисунок 3. Запрос establish-subscription (a).

Поскольку издатель NETCONF мог полностью выполнить запрос (a), он передаёт идентификатор воспринятой подписки в отклике (b)

  <rpc-reply message-id="102"
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <id
      xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
      22
    </id>
  </rpc-reply>

Рисунок 4. Запрос establish-subscription (b).

Если издатель NETCONF не модет полностью выполнить запрос или у подписчика нет прав на организацию подписки, издатель возвращает сообщение об ошибке RPC. Например, если заданное подписчиком значение dscp 10 (Рисунок 3) неприемлемо, издатель может вернуть показанное ниже сообщение.

   <rpc-reply message-id="102"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <rpc-error>
      <error-type>application</error-type>
      <error-tag>invalid-value</error-tag>
      <error-severity>error</error-severity>
      <error-app-tag>
        ietf-subscribed-notifications:dscp-unavailable
      </error-app-tag>
     </rpc-error>
   </rpc-reply>

Рисунок 5. Неудачный вызов establish-subscription.

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

A.2.2. Изменение динамической подписки

Имеющуюся подписку можно изменить. На рисунке 6 показано согласование такого изменения за несколько обменов между подписчиком и издателем. Согласование включает отказ RPC с попыткой изменения подписки, отклик на него и последующее успешное изменение.

+------------+                 +-----------+
| Подписчик  |                 | Издатель  |
+------------+                 +-----------+
      |                              |
      |     уведомление (для 23)     |
      |<-----------------------------|
      |                              |
      | modify-subscription (id = 23)|
      |----------------------------->|  (c)
      | RPC error (с советом)        |
      |<-----------------------------|  (d)
      |                              |
      | modify-subscription (id = 23)|
      |----------------------------->|
      | RPC Reply: OK                |
      |<-----------------------------|
      |                              |
      |     уведомление (для 23)     |
      |<-----------------------------|
      |                              |

Рисунок 6. Модель взаимодействия при успешном изменении подписки.


Если изменяемая на рисунке 6 подписка является подпиской на хранилище данных в соответствии с [RFC8641], запрос на изменение (c) может выглядеть как на рисунке 7. Вносимые изменения включают применение фильтра XPath, а также установку интервала передачи.

<rpc message-id="303"
  xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <modify-subscription
       xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications"
       xmlns:yp="urn:ietf:params:xml:ns:yang:ietf-yang-push">
    <id>23</id>
    <yp:datastore-xpath-filter xmlns:ex="https://example.com/datastore">
        /ex:foo/ex:bar
    </yp:datastore-xpath-filter>
    <yp:periodic>
      <yp:period>500</yp:period>
    </yp:periodic>
  </modify-subscription>
</rpc>

Рисунок 7. Запрос изменения подписки на хранилище данных.

Если издатель NETCONF может выполнить оба запроса, он передаст положительный отклик для RPC. Если какое-либо из предложенных изменений издатель NETCONF не может выполнить, он передаёт отклик об ошибке RPC (d). Рисунок 8 показывает пример отклика об ошибке RPC для (d) с включением совета, указывающего другой интервал, который позволит внести изменение.

   <rpc-reply message-id="303"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <rpc-error>
       <error-type>application</error-type>
       <error-tag>invalid-value</error-tag>
       <error-severity>error</error-severity>
       <error-app-tag>
           ietf-yang-push:period-unsupported
       </error-app-tag>
       <error-info>
         <modify-subscription-datastore-error-info
             xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
           <period-hint>
               3000
           </period-hint>
         </modify-subscription-datastore-error-info>
       </error-info>
     </rpc-error>
   </rpc-reply>

Рисунок 8. Отказ modify-subscription с советом (d)

A.2.3. Удаление динамической подписки

Figure 9 demonstrates the deletion of a subscription. This subscription may have been to either a stream or a datastore.

  <rpc message-id="103"
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <delete-subscription
      xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
      <id>22</id>
    </delete-subscription>
  </rpc>

Рисунок 9. delete-subscription.

Если издатель NETCONF может выполнить запрос, он возвращает отклик, указывающий успех.

Если издатель NETCONF не может выполнить запрос, он передаёт элемент <rpc-error>, указывающий, что изменение не прошло. На рисунке 10 показан корректный отклик для имеющегося идентификатора подписки, организованной в другой транспортной сессии NETCONF.

   <rpc-reply message-id="103"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <rpc-error>
       <error-type>application</error-type>
       <error-tag>invalid-value</error-tag>
       <error-severity>error</error-severity>
       <error-app-tag>
           ietf-subscribed-notifications:no-such-subscription
       </error-app-tag>
     </rpc-error>
   </rpc-reply>

Рисунок 10. Неудачный вызов delete-subscription.

A.3. Уведомления о состоянии подписки

Издатель будет передавать уведомления о состоянии динамической подписки в соответствии с [RFC8639].

A.3.1. subscription-modified

В соответствии с параграфом 2.7.2 в [RFC8639] может передаваться уведомление subscription-modified через NETCONF, если меняется настроенный фильтр. Уведомление о смене состояния подписки кодируется в XML, как показано ниже.

<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
  <eventTime>2007-09-01T10:00:00Z</eventTime>
  <subscription-modified
      xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
    <id>39</id>
    <stream-xpath-filter xmlns:ex="https://example.com/events">
      /ex:foo
    </stream-xpath-filter>
    <stream>NETCONF</stream>
  </subscription-modified>
</notification>

Рисунок 11. Уведомление о состоянии подписки subscription-modified.

A.3.2. subscription-resumed и replay-complete

Возобновление подписки (subscription-resumedимеет вид

  <notification
    xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
    <eventTime>2007-09-01T10:00:00Z</eventTime>
    <subscription-resumed
      xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
      <id>39</id>
    </subscription-resumed>
  </notification>

Рисунок 12. Уведомление subscription-resumed.

Уведомление replay-complete очень похоже, но вместо subscription-resumed применяется replay-complete.

A.3.3. subscription-terminated и subscription-suspended

Уведомление subscription-terminated имеет вид

  <notification
    xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
    <eventTime>2007-09-01T10:00:00Z</eventTime>
    <subscription-terminated
      xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
      <id>39</id>
      <reason>
         suspension-timeout
      </reason>
    </subscription-terminated>
  </notification>

Рисунок 13. Уведомление о состоянии подписки subscription-terminated.

Уведомление subscription-suspended отличается лишь заменой subscription-terminated на subscription-suspended.

A.4. Примеры фильтров

В этом приложении даны примеры применения методов XPath и subtree для фильтрации содержимого записей о событиях. Примеры основаны на уведомлении YANG vrrp-protocol-error-event из модели данных YANG ietf-vrrp в [RFC8347]. Записи о событиях, создаваемые издателем на основе этой спецификации, могут иметь вид

  <notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
    <eventTime>2018-09-14T08:22:33.44Z</eventTime>
    <vrrp-protocol-error-event
         xmlns="urn:ietf:params:xml:ns:yang:ietf-vrrp">
       <protocol-error-reason>checksum-error</protocol-error-reason>
    </vrrp-protocol-error-event>
  </notification>

Рисунок 14. Пример уведомления VRRP в соответствии с RFC 8347.

Предположим, что подписчик хочет организовать подписку, в которой предоставляются лишь записи о событиях, где checksum-error является частью события протокола резервирования виртуального маршрутизатора (Virtual Router Redundancy Protocol или VRRP). Предположим также, что издатель помещает такие записи в поток NETCONF. Для получения продолжающейся серии соответствующих записей о событиях подписчик может запросить применение фильтра XPath к потоку NETCONF. RPC establish-subscription для решения этой задачи может иметь вид

 <rpc message-id="601" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
   <establish-subscription
     xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
     <stream>NETCONF</stream>
     <stream-xpath-filter xmlns="urn:ietf:params:xml:ns:yang:ietf-vrrp">
       /vrrp-protocol-error-event[
          vrrp:protocol-error-reason="vrrp:checksum-error"]
     </stream-xpath-filter>
   </establish-subscription>
 </rpc>

Рисунок 15. Причина ошибки при организации подписки (XPath).

Дополнительные примеры фильтров XPath приведены в [XPATH].

Предположим, что вызов establish-subscription с рисунка 15 был воспринят, а позднее подписчик решил расширить подписку включением всех событий протокола VRRP (а не только с checksum-error). Подписчик может попытаться изменить подписку путём замены фильтра XPath на фильтр subtree, который будет передавать все события протокола VRRP. Такой вызов RPC modify-subscription может иметь вид

 <rpc message-id="602" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
   <modify-subscription
      xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
     <id>99</id>
     <stream-subtree-filter>
      <vrrp-protocol-error-event
             xmlns="urn:ietf:params:xml:ns:yang:ietf-vrrp"/>
     </stream-subtree-filter>
   </modify-subscription>
 </rpc>

Рисунок 16. Пример RPC modify-subscription.

Дополнительные примеры фильтров subtree приведены в параграфе 6.4 [RFC6241].

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

Авторы признательны Andy Bierman, Yan Gang, Sharon Chisholm, Hector Trevino, Peipei Guo, Susan Hares, Tim Jenkins, Balazs Lengyel, Martin Bjorklund, Mahesh Jethanandani, Kent Watsen, Qin Wu, Guangying Zheng за полезный вклад, комментарии и предложения .

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

Eric Voit
Cisco Systems
Email: evoit@cisco.com
 
Alexander Clemm
Futurewei
Email: ludwig@clemm.org
 
Alberto Gonzalez Prieto
Microsoft
Email: alberto.gonzalez@microsoft.com
 
Einar Nilsen-Nygaard
Cisco Systems
Email: einarnn@cisco.com
 
Ambika Prasad Tripathy
Cisco Systems
Email: ambtripa@cisco.com

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

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

nmalykh@protokols.ru

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

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

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

Тестирование платы HiFive Unleashed с ядром Linux

Тестирование платы HiFive Unleashed с ядром Linux

PDF

Плата HiFive Unleashed [1] производства компании SiFive основана на процессоре Freedom U540 [2], включающем одно 64-битовое ядро E51 RISC-V, используемое для мониторинга и управления, а также четыре 64-битовых ядра E54 RISC-V, применяемых для решения прикладных задач. Схемы платы подробно описаны в документе [3], а внешний вид представлен на рисунке 1, заимствованном из [1].

Рисунок 1. Внешний вид платы HiFive Unleashed.

Подробное рассмотрение устройства платы в наши задачи не входило, поэтому отошлем интересующихся читателей к документам [1-3]. Мы же рассмотрим более подробно вопросы загрузки ОС Linux, а также возможности трассировки ядра для оценки производительности сетевых операций.

В комплект поставки платы входит карта микро-SD с загрузчиком BBL и простой оболочкой Buildroot на основе ядра Linux 4.15.0. Для наших задач это не представляло сколь-нибудь существенного интереса, поэтому мы сразу начали сборку своей системы на основе Freedom Unleashed Software Development Kit [4]. Репозиторий GitHub для Freedom U-SDK содержит полный набор исходных кодов и инструментов для кросс-компиляции загрузчика bbl на основе ядра Linux (в настоящее время версии 4.19) и самого ядра. Обеспечивается также загрузка и установка демонстрационной ОС Linux семейства Debian. Для работы с SDK в вашей системе должны быть установлены перечисленные ниже пакеты1.

  • git;
  • build-essential;
  • autotools;
  • texinfo;
  • bison;
  • flex;
  • lib64gmp-devel;
  • lib64mpfr-devel;
  • gawk;
  • lib64zlib-devel;
  • lib64openssl-devel;
  • dtc;
  • mtools.

Кроме того, потребуется около 16 Гбайт свободного пространства, из которого примерно половину составляет код, загружаемый из сети.

Загрузка и сборка SDK

От своего имени (не root) вводим команду

$ git clone https://github.com/sifive/freedom-u-sdk.git

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

$ cd freedom-u-sdk

и загружаем требуемые для сборки субмодули с помощью команды

$ git submodule update --recursive -init

Пока конфигурационные параметры ядра в дереве ещё отсутствуют (они создаются в процессе сборки) и править нечего, поэтому просто запускаем от своего имени из корневого каталога SDK команду

$ make

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

Тут возможны два варианта — дождаться завершения сборки с принятыми по умолчанию настройками или прервать ее и заняться настройкой параметров конфигурации ядра в соответствии со своими задачами. Для полноты картины рассмотрим более длинный вариант со сборкой первоначально без какой-либо своей настройки.

Итак, процесс в конце концов завершился и на экране появилось сообщение

GPT (for SPI flash or SDcard) and U-boot Image files have 
been generated for an ISA of rv64imafdc and an ABI of lp64d 

/home/user/SRC/freedom-u-sdk/work/image-ddbe382-dirty.fit 
/home/user/SRC/freedom-u-sdk/work/hifive-unleashed-ddbe382-dirty.gpt 

To completely erase, reformat, and program a disk sdX, run: 
 make DISK=/dev/sdX format-boot-loader 
 ... you will need gdisk and e2fsprogs installed 
 Please note this will not currently format the SDcard ext4 partition 
 This can be done manually if needed

Следующим этапом является перенос созданных образов на карту микро-SD для установки этой карты на плате HiFive Unleashed и последующей загрузки системы. Для этого нужна будет микро-SD карта размером 8 Гбайт, которую следует поместить в тот или иной считыватель, а затем ввести команду

$ make DISK=/dev/sdX format-boot-loader

заменив sdX именем устройства, на которое карта SD отображается в вашей системе3. Предположим, что это /dev/sdj.

$ sudo make DISK=/dev/sdj format-boot-loader 
[sudo] пароль для user: 
/sbin/sgdisk --clear 	\
--new=1:2048:65502 --change-name=1:"Vfat Boot" --typecode=1:EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 	\ 
--new=2:264192:15521840 --change-name=2:root --typecode=2:0FC63DAF-8483-4772-8E79-3D69D8477DE4 \ 
--new=3:1100:2020 --change-name=3:uboot --typecode=3:5B193300-FC78-40CD-8002-E86C45580B47 \ 
--new=4:1024:1099 --change-name=4:uboot-env 	--typecode=4:a09354ac-cd63-11e8-9aff-70b3d592f0fa \ 
	/dev/sdj 
Setting name! 
partNum is 0 
Setting name! 
partNum is 1 
Setting name! 
partNum is 2 
Setting name! 
partNum is 3 
The operation has completed successfully. 
/sbin/partprobe 
dd if=/home/user/SRC/freedom-u-sdk/work/HiFive_U-Boot/u-boot.bin of=/dev/sdj3 bs=4096 
113+1 записей получено 
113+1 записей отправлено 
464941 байт (465 kB, 454 KiB) скопирован, 0,051439 s, 9,0 MB/s 
dd if=/home/user/SRC/freedom-u-sdk/work/hifive-unleashed-vfat.part of=/dev/sdj1 bs=4096 
7931+1 записей получено 
7931+1 записей отправлено 
32488448 байт (32 MB, 31 MiB) скопирован, 2,81572 s, 11,5 MB/s

По завершении работы команды можно проверить, что на SD-карте создана таблица GPT с 4 разделами

# fdisk -l […] Диск /dev/sdj: 7,4 GiB, 7948206080 байт, 15523840 секторов 
Disk model: STORAGE DEVICE   
Единицы: секторов по 1 * 512 = 512 байт 
Размер сектора (логический/физический): 512 байт / 512 байт 
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт 
Тип метки диска: gpt 
Идентификатор диска: E51737DC-8AD9-4575-8DFD-AF167E7F246B 

Устр-во    начало    Конец  Секторы Размер Тип 
/dev/sdj1    2048    65502    63455    31M Microsoft basic data 
/dev/sdj2  264192 15521840 15257649   7,3G Файловая система Linux 
/dev/sdj3    1100     2020      921 460,5K HiFive Unleashed FSBL 
/dev/sdj4    1024     1099       76    38K неизвестный 

Элементы таблицы разделов упорядочены не так, как на диске.

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

Welcome to Buildroot 

Password:  
# help 
Built-in commands: 
------------------ 
       . : [ [[ alias bg break cd chdir command continue echo eval exec 
       exit export false fg getopts hash help history jobs kill let 
       local printf pwd read readonly return set shift source test times 
       trap true type ulimit umask unalias unset wait

Перечисленные по команде help доступные команды оболочки Buildroot для нас интереса не представляют, поэтому сразу пойдем дальше и установим на SD-карту
образ Debian Linux, предоставляемый SiFive. Для этого введите команду

$ sudo make DISK=/dev/sdj format-demo-image

В результате из сети будет загружен образ sifive-debian-demo-mar7.tar.xz (он сохранится локально в каталоге Freedom U-SDK), который будет скопирован в раздел /dev/sdj2 с помощью утилиты dd. Процедура загрузки и установки образа (примерно 1,1 Гбайт) займет некоторое время, поэтому наберитесь терпения.

После завершения процесса SD-карту можно отключить от компьютера и установить
в гнездо платы HiFive Unleashed. Установив карту, подсоединяем кабель микро-USB к компьютеру, который будет служить для контроля за процессом загрузки и последующей работы с платой. Для подключения к плате можно воспользоваться утилитой screen или другой программой эмуляции терминала по вашему выбору. Включаем питание платы и вводим на консоли управления команду

$ sudo screen -L /dev/ttyUSB1 115200

Опция -L задает запись консольного вывода в журнальный файл screenlog.0. В процессе работы этот файл может дать вам обширную информацию о процессе загрузки и поможет при устранении проблем, если таковые возникнут. Если вам удобней сохранять консольный вывод в другой файл, его можно задать опцией -Logfile <имя файла> в командной строке screen.

Если все пошло нормально, через несколько секунд на консоли появится вывод процесса загрузки и примерно через 30 секунд после включения должен замигать зелёный светодиод, ближний к разъему микро-USB на плате. Если что-то пошло не так, попробуйте изменить положение DIP-переключателей на плате. В описании платы указано, что по умолчанию переключатели должны быть установлены в положение 1111 (левая позиция 4 нижних переключателей на рисунке 1). На практике у меня созданный с помощью Freedom U-SDK образ грузился при положении переключателей 1101 (второй снизу на рисунке 1 переключатель сдвинут
вправо). Этот факт отмечен и в файле README.md, хранящемся в корневом каталоге Freedom U-SDK.

После загрузки система запросит имя (root) и пароль (sifive), а после их ввода вы окажетесь в среде buildroot (если не установили образ Debian). Можно поэкспериментировать с этой средой, но для наших задач в ней ничего интересного не нашлось. Если же вы установили Debian, после ввода имени и пароля вы окажетесь в обычной консоли Linux. Изначально состав установленных приложений не богат, но можно установить пакеты из настроенного изначально репозитория с помощью обычных команд apt или apt-get. На этом вопросе мы останавливаться не
будем.

Итак, мы загрузили демонстрационную ОС Debian Linux и готовы начать работу с ней. Вот только сразу же сталкиваемся с неприятным сюрпризом — файловая система смонтирована в режиме только чтения (read-only). Поиск командной строки загрузки ядра, где задаётся режим монтирования файловой системы, привёл к файлу uEnv.txt, размещенному в первом разделе SD-карты (Vfat Boot). Для монтирования файловой системы и управления загрузкой в этот файл нужно внести некоторые изменения. Забегая вперёд, отмечу, что исходный файл, который при создании загрузочного образа копируется на SD-карту, расположен в каталоге conf дерева исходных кодов Freedom U-SDK. Поэтому, если вы планируете экспериментировать со сборкой ядра, лучше отредактировать файл uEnv.txt в этом каталоге, чем менять каждый раз его копию на SD-карте.

Итак, начинаем смотреть файл uEnv.txt (в каталоге исходных кодов или на SD-карте по вашему усмотрению). Начало этого файла выглядит как показано ниже. Номера строк слева добавлены мной для удобства ссылок на них в последующем тексте.

01 # The current convention (SUBJECT TO CHANGE) is that this file 
02 # will be loaded from the first MSDOS(fat) GPT partition on the 
03 # MMC card.  
04
05 bootargs=debug console=tty0 console=ttySIF0 root=/dev/mmcblk0p2 rootwait 
06
07 # To boot from partition 2 of an NVME drive (with a PCI iofpga, 
08 # such as the MicroSemi expansion board, uncomment below: 
09 
10 #bootargs=debug console=tty0 console=ttySIF0 root=/dev/nvme0n1p2 
11
12 # to boot an initramfs (buildroot or debian/etc) use this 
13 setupchosen=run setupvml; run setupird 
14
15 # to boot with straight to the root= parition, uncomment below 
16 # so we do not set the ramdisk pointers 
17 #setupchosen=run setupvml 
18
19 # The FIT file to boot from 
20 fitfile=hifiveu.fit 
21 
22 # The rest of this is mostly of interest to u-boot developers 
23 # below much match what's in FIT (ugha)

Приступим к редактированию файла uEnv.txt. Перво-наперво откроем файловую систему Linux для записи и чтения. Для этого в строку 5 добавим rw в конце. Можно также убрать параметр debug в начале строки, если избыток отладочной информации вам мешает. В итоге в файле останется строка вида

bootargs=rootwait console=tty0 console=ttySIF0 root=/dev/mmcblk0p2 rw

Далее, поскольку мы планируем загрузить нормальную ОС Linux, следует убрать символ комментария в начале строки 17 и добавить такой символ в начало строки 13 (иначе будет грузиться Builsroot, а не Debian).

После этого можно установить карту в гнездо платы HiFive и загрузить Linux. Для входа в систему используется имя пользователя root и пароль sifive. После загрузки плата должна получить адрес IP по протоколу DHCP (для этого в вашей сети должен быть действующий сервер DHCP) и запустить демон sshd. Если при этом не возникло никаких ошибок (обычно это так), вы сможете работать с платой уже не только из консоли screen, но и удалённо, по протоколу SSH.

Как уже было отмечено выше, набор пакетов в демонстрационном образе Debian достаточно скромен и для работы его придется дополнить с помощью стандартных команд apt или apt-get. Я бы рекомендовал сразу установить net-tools и lshw. Далее в тексте предполагается, что все нужные для работы пакеты установлены и напоминаний о них больше не будет.

Для начала разберёмся, что мы имеем в плане аппаратных компонент с помощью команды lshw.

root@HiFiveU:~# lshw 
hifiveu                      
   description: Computer 
   product: ed_cluster_alloc_exit: OK 
   width: 64 bits 
   capabilities: smp 
 *-core 
      description: Motherboard 
      physical id: 0 
    *-memory 
         description: System memory 
         physical id: 0 
         size: 7993MiB 
    *-cpu:0 
         physical id: 1 
         bus info: cpu@0 
         width: 32 bits 
    *-cpu:1 
         physical id: 2 
         bus info: cpu@1 
         width: 32 bits 
    *-cpu:2 
         physical id: 3 
         bus info: cpu@2 
         width: 32 bits 
    *-cpu:3 
         physical id: 4 
         bus info: cpu@3 
         width: 32 bits 
 *-network 
      description: Ethernet interface 
      physical id: 1 
      logical name: eth0 
      serial: 70:b3:d5:92:f2:20 
      size: 1Gbit/s 
      capacity: 1Gbit/s 
      capabilities: ethernet physical tp mii 10bt 10bt-fd 100bt 100bt-fd 1000bt 1000bt-fd autonegotiation 
      configuration: autonegotiation=on broadcast=yes driver=macb duplex=full ip=192.168.0.3 link=yes multicast=yes port=MII speed=1Gbit/s

Мы видим 64-битовую систему с материнской платой, поддерживающей многопроцессорную архитектуру SMP, 8 Гбайт (7993 MiB) оперативной памяти, 4 процессора и 1-гигабитный сетевой адаптер, для которого используется драйвер macb (запомните это — пригодится при настройке конфигурации ядра). Утилита почему-то воспринимает процессоры 32-разрядными (я не стал разбираться с этим вопросом), однако другая утилита lscpu показывает более достоверные параметры процессоров.

root@HiFiveU:~# lscpu 
Architecture:        riscv64 
Byte Order:          Little Endian 
CPU(s):              4 
On-line CPU(s) list: 0-3 
Thread(s) per core:  1 
Core(s) per socket:  1 
Socket(s):           4 
L1i cache:           16K

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

Возвращаемся к системе, где у нас находится дерево исходных кодов Freedom U-SDK, и начинаем настраивать конфигурацию ядра. Для этого переходим в каталог work/linux (ссылки здесь и далее указываются относительно корня дерева Freedom U-SDK). Здесь мы видим множество файлов с расширением .dwo и после них (при сортировке по именам) будут два файла .config и .config.old. Скопируйте на всякий случай первый из этих файлов, он может пригодится для возврата к исходной конфигурации в случае ошибок. Далее нужно этот файл отредактировать. Можно сделать это вручную, но в таком случае достаточно велика вероятность ошибок, да и работа получится трудоёмкой. разумней воспользоваться общепринятыми при настройке конфигурации ядра командами make menuconfig (консольный интерфейс выбора опций) или более удобным вариантом make xconfig, имеющим графический интерфейс. Если для работы этих команд потребуется установить дополнительные пакеты, система сообщит вам об этом.

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

  • поддержку звука;
  • поддержку графики;
  • все сетевые интерфейсы (устройства) за исключением Ethernet;
  • все драйверы Ethernet за исключением Cadence.

Следует включить опции CONFIG_HVC_DRIVER, CONFIG_HVC_RISCV_SBI и CONFIG_VIRTIO_CONSOLE в разделе Non-8250 serial port support. Это обеспечит вывод информации о загрузке системы уже с самых первых стадий процесса.

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


Рисунок 2. Опции трассировки.

Сохраняем созданную конфигурацию и выходим из интерфейса настройки параметров ядра. Не следует беспокоиться о том, что те или иные важные опции не были учтены, поскольку в начале сборки нового ядра будут заданы вопросы, уточняющие важные для нашего случая параметры. Собирать ядро командой make из каталога work/linux не следует, поскольку в нашем случае сборка ядра является лишь частью общего процесса. Поэтому возвращаемся в корень Freedom U-SDK и вводим команду make (или make -j).

[user@Lhotze freedom-u-sdk (master)]$ make 
make -C /home/user/SRC/freedom-u-sdk/linux O=/home/user/SRC/freedom-u-sdk/work/linux \ 
       ARCH=riscv \ 
       CROSS_COMPILE=/home/user/SRC/freedom-u-sdk/work/buildroot_initramfs/host/bin/riscv64-sifive-linux-gnu- \ 
       PATH=/home/user/SRC/freedom-u-sdk/work/buildroot_initramfs/host/bin:/usr/share/colorgcc:/usr/local/bin:/usr/bin:/usr/local/games:/usr/games:/usr/lib64/qt5/bin:/usr/lib64/qt4/bin:/home/user/bin \ 
       vmlinux 
make[1]: вход в каталог «/home/user/SRC/freedom-u-sdk/linux» 
make[2]: вход в каталог «/home/user/SRC/freedom-u-sdk/work/linux» 
 GEN     ./Makefile 
scripts/kconfig/conf  --syncconfig Kconfig 
* 
* Restart config... 
* 
* 
* Platform type 
* 
Base ISA 
 1. RV32I (ARCH_RV32I) (NEW) 
> 2. RV64I (ARCH_RV64I) (NEW)

Как уже было отмечено выше, при сборке выдаются запросы на установку некоторых важных опций после предварительной настройки конфигурации ядра. На приведённый выше вопрос отвечаем 2 (Enter), поскольку ядро нам нужно 64-битовое. На следующие несколько вопросов отвечаем просто нажатием клавиши Enter, соглашаясь с предложенными вариантами.

Kernel Code Model 
 1. medium low code model (CMODEL_MEDLOW) (NEW) 
> 2. medium any code model (CMODEL_MEDANY) (NEW) 
choice[1-2?]:  
Maximum Physical Memory 
 1. 2GiB (MAXPHYSMEM_2GB) (NEW) 
> 2. 128GiB (MAXPHYSMEM_128GB) (NEW) 
choice[1-2?]:  
Symmetric Multi-Processing (SMP) [Y/n/?] y 
 Maximum number of CPUs (2-32) (NR_CPUS) [8] 8 
CPU Tuning 
> 1. generic (TUNE_GENERIC) (NEW) 
choice[1]: 1 
Emit compressed instructions when building Linux (RISCV_ISA_C) [Y/n/?] (NEW)  
* 
* supported PMU type 
* 
Base Performance Monitoring Unit (RISCV_BASE_PMU) [Y/n/?] (NEW)  
FPU support (FPU) [Y/n/?] (NEW)  
* 
* Boot options 
* Built-in kernel command line (CMDLINE_BOOL) [Y/n/?] y 
 Built-in kernel command string (CMDLINE) [earlyprintk] earlyprintk 
 Built-in command line overrides bootloader arguments (CMDLINE_FORCE) [N/y/?] (NEW)

Далее нужно будет изменить некоторые из предлагаемых вариантов

* 
* Character devices 
* 
Enable TTY (TTY) [Y/n/?] y 
 Virtual terminal (VT) [Y/n/?] y 
   Enable character translations in console (CONSOLE_TRANSLATIONS) [Y/n/?] y 
   Support for console on virtual terminal (VT_CONSOLE) [Y/n/?] y 
   Support for binding and unbinding console drivers (VT_HW_CONSOLE_BINDING) [Y/n/?] y 
 Unix98 PTY support (UNIX98_PTYS) [Y/n/?] y 
 Legacy (BSD) PTY support (LEGACY_PTYS) [Y/n/?] y 
   Maximum number of legacy PTY in use (LEGACY_PTY_COUNT) [256] 256 
 Non-standard serial port support (SERIAL_NONSTANDARD) [N/y/?] n 
 HSDPA Broadband Wireless Data Card - Globe Trotter (NOZOMI) [N/m/y/?] n 
 GSM MUX line discipline support (EXPERIMENTAL) (N_GSM) [N/m/y/?] n 
 Trace data sink for MIPI P1149.7 cJTAG standard (TRACE_SINK) [N/m/y/?] n 
/dev/mem virtual device support (DEVMEM) [Y/n/?] y 
/dev/kmem virtual device support (DEVKMEM) [N/y/?] n 
TTY driver to output user messages via printk (TTY_PRINTK) [N/m/y/?] n 
RISC-V SBI console support (HVC_RISCV_SBI) [N/y/?] (NEW)

Для последнего вопроса по умолчанию предусмотрен ответ N и его нужно заменить на Y, поскольку консоль SBI обеспечивает вывод информации на самых ранних стадиях загрузки, а нам эта информация будет нужна. Более подробно об этом можно узнать из блога Палмера Даббета [5].

Аналогично предлагается поступить и со следующим вопросом, включив контроллер прерываний PLIC, по умолчанию отключенный.

* 
* Device Drivers 
* 
SiFive Platform-Level Interrupt Controller (SIFIVE_PLIC) [N/y/?] (NEW)

На последующие вопросы, если они возникнут, просто соглашаемся с принятым по умолчанию вариантом. После завершения настройки опций ядра начнётся процесс компиляции и сборки ядра и загрузчика BBL, по завершении которого нужно повторить описанную выше процедуру копирования образов на карту SD. Если вы не меняли файл uEnv.txt в каталоге conf, а ограничились его редактированием на SD-карте, придётся повторить и эту процедуру.

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

Напомним, что для последующего просмотра и анализа загрузочных сообщений целесообразно включить запись log-файла в терминальной программе (-L для консоли screen). Загрузим систему и начнем изучать файл с сообщениями загрузки.

Первое, на что следует обратить внимание, — это сообщение о том, что харт с идентификатором 0 замаскирован.

[    0.000000] CPU with hartid=0 has a non-okay status of "masked"

Сначала это показалось странным, но чёткого обозначения идентификаторов хартов
в документации найти не удалось. Видимо причина этого сообщения заключается в том, что харт 0 — это управляющее ядро U51, которое отфильтровывается из дерева устройств загрузчиком BBL [5]. Поскольку никаких явных проблем в дальнейшем с
этим не возникает, проигнорируем данную информацию.

Следующее важное сообщение гласит о невозможности трассировки функций

[    0.060000] Running postponed tracer tests: 
[    0.060000] Testing tracer function: .. no entries found ..FAILED! 
[    0.210000] ------------[ cut here ]------------ 
[    0.220000] WARNING: CPU: 0 PID: 1 at kernel/trace/trace.c:1513 run_tracer_selftest+0x122/0x180 
[    0.220000] Modules linked in: 
[    0.230000] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.0-sifive-1+ #37 
[    0.230000] Call Trace: 
[    0.230000] [<ffffffe00004f718>] walk_stackframe+0x0/0xc4 
[    0.230000] [<ffffffe00004f9cc>] show_stack+0x3c/0x46 
[    0.230000] [<ffffffe000522ef0>] dump_stack+0x8e/0xc8 
[    0.230000] [<ffffffe000055c7a>] __warn.part.3+0xb8/0xfa 
[    0.230000] [<ffffffe000055dfa>] warn_slowpath_null+0x4a/0x58 
[    0.230000] [<ffffffe0000e99c2>] run_tracer_selftest+0x122/0x180 
[    0.230000] [<ffffffe00000b42a>] init_trace_selftests+0x8a/0x10a 
[    0.230000] [<ffffffe00004d070>] do_one_initcall+0x44/0x184 
[    0.230000] [<ffffffe000000fb8>] kernel_init_freeable+0x216/0x2ce 
[    0.230000] [<ffffffe00053582e>] kernel_init+0x1c/0x10e 
[    0.230000] [<ffffffe00004e250>] ret_from_exception+0x0/0xc 
[    0.240000] ---[ end trace 44c325814a888e3d ]--- 
[    0.240000] ------------[ cut here ]------------

И действительно после загрузки системы трассировщик function отсутствует в списке доступных.

root@HiFiveU:~# cat /sys/kernel/debug/tracing/available_tracers  
hwlat nop

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

[ … ] [    0.260000] Testing tracer nop: PASSED 
[    0.270000] Testing tracer irqsoff:  
[    0.270000] failed to start irqsoff tracer 
[    0.270000] .. no entries found ..FAILED! [ … ] [    0.300000] Testing tracer wakeup:  
[    0.300000] failed to start wakeup tracer 
[    0.310000] .. no entries found ..FAILED!
[ … ] [    0.330000] Testing tracer function_graph:  
[    0.330000] Failed to init function_graph tracer, init returned -19 
[    0.340000] FAILED!

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

[   23.250000] Ring buffer PASSED! 
[   23.250000] Running tests on trace events: 
[   23.260000] Testing event initcall_finish: OK 
[   23.380000] Testing event initcall_start: OK 
[   23.500000] Testing event initcall_level: OK 
[   23.620000] Testing event task_rename: OK 
[   23.740000] Testing event task_newtask: OK 
[   23.860000] Testing event cpuhp_exit: OK 
[   23.980000] Testing event cpuhp_multi_enter: OK 
[   24.100000] Testing event cpuhp_enter: OK 
[   24.220000] Testing event softirq_raise: OK 
[   24.340000] Testing event softirq_exit: OK 
[   24.460000] Testing event softirq_entry: OK 
[   24.580000] Testing event irq_handler_exit: OK 
[   24.700000] Testing event irq_handler_entry: OK 
[   24.820000] Testing event signal_deliver: OK 
[   24.940000] Testing event signal_generate: OK 
[   25.060000] Testing event workqueue_execute_end: OK 
[   25.180000] Testing event workqueue_execute_start: OK

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

# cat /sys/kernel/debug/tracing/available_events

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

echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable

включит трассировку событий sched_wakeup, а команда

echo 0 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable

выключит ее. Однако рассмотрение вопросов трассировки событий не входило пока в наши планы и не рассматривается здесь. Интересующимся читателям рекомендуется обратиться к документу [6].

Отметим дополнительно, что трассировка ветвлений при настройке конфигурации была выключена осознанно, поскольку во многих случаях попытка ею воспользоваться приводит к «зависанию» системы. Аналогичная ситуация наблюдается и с трассировщиком аппаратных задержек hwlat. Неоднократные попытки воспользоваться тем и другим с разными настройками результатов не дали. Отметим, что система при этом не умирает и ее сетевая активность сохраняется (по меньшей мере она отвечает на ping). Но попытки ввода команд в консоли screen или ssh приводят к тому, что после нажатия клавиши Enter никакие другие действия уже не возможны и никакого вывода на консоль не наблюдается.

Заключение

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

Литература

[1] SiFive HiFive Unleashed Getting Started Guide, https://sifive.cdn.prismic.io/sifive%2Ffa3a584a-a02f-4fda-b758-a2def05f49f9_hifive-unleashed-getting-started-guide-v1p1.pdf

[2] SiFive FU540-C000 Manual, https://sifive.cdn.prismic.io/sifive%2F834354f0-08e6-423c-bf1f-0cb58ef14061_fu540-c000-v1.0.pdf

[3] HiFive Unleashed Schematics, https://sifive.cdn.prismic.io/sifive%2Ff7173056-bf37-4407-87cb-d5ab76abf61a_hifive-unleashed-a00-schematics.pdf

[4] Freedom Unleashed Software Development Kit, https://github.com/sifive/freedom-u-sdk

[5] Palmer Dabbelt,
All Aboard, Part 6: Booting a RISC-V Linux Kernel,
https://www.sifive.com/blog/all-aboard-part-6-booting-a-risc-v-linux-kernel

[6] Исходный
код ядра Linux, файл Documentation/trace/events.rst.

1Список приведён для системы Mageia v7 x86_64. В файле README.md в корневом каталоге Freedom U-SDK приведён список пакетов, требуемых для Ubuntu 16.04 x86_64.

2При попытке ускорить сборку за счёт использования множества потоков с опцией make -j процесс завершается ошибкой 2 по причине несинхронизированной сборки отдельных компонент. В этом случае можно повторить команду и тогда все будет собрано корректно и в нужном порядке. Но и в этом случае времени потребуется немало.

3Определить имя устройства можно с помощью команды fdisk -l. Здесь следует соблюдать осторожность, поскольку указание неверного имени устройства может привести к удалению всех данных с неверно указанного устройства.

Рубрика: Linux, RISC-V | Комментарии к записи Тестирование платы HiFive Unleashed с ядром Linux отключены

RFC 8609 Content-Centric Networking (CCNx) Messages in TLV Format

Internet Research Task Force (IRTF)                             M. Mosko
Request for Comments: 8609                                    PARC, Inc.
Category: Experimental                                          I. Solis
ISSN: 2070-1721                                                 LinkedIn
                                                                 C. Wood
                                         University of California Irvine
                                                               July 2019

Content-Centric Networking (CCNx) Messages in TLV Format

Сообщения ориентированных на содержимое сетей (CCNx) в формате TLV

PDF

Аннотация

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

Документ является результатом работы исследовательской группы ICNRG2. Документ был рассмотрен множеством участников ICNRG. Две реализации активно применяются и показывают техническую зрелость спецификации протокола.

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

Документ не является спецификацией стандартного протокола Internet (Standards Track) и публикуется для проверки, экспериментальной реализации и оценки.

Документ определяет экспериментальный протокол для сообщества Internet. Документ является результатом работы IRTF3. IRTF публикует результаты связанных с Internet исследований и разработок. Эти результаты могут оказаться не подходящими для развертывания. Данный RFC представляет согласованное мнение группы ICNRG в составе IRTF. Документ одобрен для публикации IRSG и не претендует на роль стандарта Internet (см. раздел 2 в RFC 7841).

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

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

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

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

1. Введение

Этот документ задает формат пакетов TLV4, а также кодирование типа и значения TLV для сообщений CCNx. Полное описание сетевого протокола CCNx с независимым от кодирования описанием сообщений CCNx и их элементов можно найти в [RFC8569]. Сетевой протокол CCNx использует иерархические имена для пересылки запросов и сопоставления откликов с запросами. Протокол не использует адресов конечных точек, как это делает протокол IP. Ограничения в запросе могут лимитировать отклик открытым ключом подписавшей его стороны или криптографическим хэш-значением отклика. Каждый узел пересылки CCNx на пути выполняет сопоставление имен и проверку ограничений. Протокол CCNx вписывается в более широкую модель протоколов ICN5 [RFC7927].

Этот документ описывает схему TLV, использующую 2-байтовые поля T и L. Основания этого выбора приведены в разделе 5. Вкратце, это позволяет избежать множества вариантов кодирования одного значения (псевдонимов) и уменьшить работу при проверке пригодности для обеспечения соответствия. В отличие от некоторых других применений TLV в сетях, каждый интервал пересылки должен проверять кодирование, поэтому даже небольшая задержка на каждом узле будет приводить к значительной суммарной задержке пересылки. Для очень мелких пакетов и низкоскоростных каналов, где лишние байты могут иметь значение, можно применять протокол сжатия TLV (например, [compress] и [CCNxz]).

В документе используются термины пакет CCNx, сообщение CCNx и TLV сообщения CCNx. Пакетом CCNx называют всю дейтаграмму L3, как указано в параграфе 3.1. Сообщение CCNx — это маркер ABNF, определенный семантикой CCNx [RFC8569]. TLV сообщения CCNx говорит о кодировании сообщения CCNx в соответствии с параграфом 3.6.

Этот документ задает:

  • формат пакетов CCNx;

  • формат TLV сообщений CCNx;

  • типы TLV, используемые в сообщениях CCNx;

  • кодирование значений каждого типа;

  • типы верхнего уровня, существующие во внешнем окружении;

  • Interest TLV, существующие в Interest;

  • Content Object TLV, используемые в Content Object.

Данный документ дополняется указанными ниже документами:

  • [RFC8569], описывающий семантику сообщений и протокольные операции, относящиеся к сообщениям Interest и Content Object, включая протокол Interest Return;

  • [CCNxURI], описывающий нотацию CCNx URI.

Значения типов в разделе 4 соответствуют выделенным IANA номерам для протокола CCNx. В документе применяются символьные имена, определенные в указанном разделе. Все значения для типов TLV указываются относительно их родительских контейнеров. Например, каждый уровень вложенной структуры TLV может определять type = 1 со своим смыслом.

Пакеты представляются в форме 32-битовых слов. По причине вложенности TLV и наличия необязательных полей нет возможности показать все варианты. Поля на рисунках, ограниченные символами | представляют точный размер в битах. Поля с символами / имеют переменный размер и обычно дополняются до границы слова для удобства восприятия.

Документ выражает согласованные взгляды ICN RG. Это первый протокол ICN рабочей группы, созданный на базе раннего протокола CCNx [nnc] с существенным пересмотром и учетом предложения сообщества ICN и членов исследовательской группы. Документ прошел рецензирование нескольких участников сообщества ICN и исследовательской группы. Авторы и руководитель исследовательской группы одобрили документ. Подготовка документа поддержана IRTF, документ выпущен за рамками процесса IETF и не является стандартом IETF. Это экспериментальный протокол, который может не подойти для конкретных применений. Спецификация в будущем может измениться.

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

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

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

Приведенные ниже определения взяты из [RFC8569]. Данный документ определяет их кодирование.

Name

Иерархически организованный идентификатор переменного размера, представленный упорядоченным списком сегментов пути, являющихся строками октетов с переменным размером. В удобной для человека форме имена представляются в формате URI, как ccnx:/path/part. Здесь нет строк хостов и запросов. Подробности именования приведены в [CCNxURI].

Interest

Сообщение, запрашивающее Content Object с совпадающим именем (Name) и другими необязательными селекторами для выбора из множества объектов с одинаковым именем. Любой Content Object с Name и атрибутами, соответствующими Name, и необязательным селекторам в Interest считается удовлетворяющим Interest.

Content Object

Объект данных, передаваемый в ответ на запрос Interest, имеющий необязательное имя (Name) и данные содержимого, связанные вместе криптографическими средствами.

3. Пакеты TLV

Для кодирования пакетов на основе TLV применяются 16-битовые поля Type и Length. Это обеспечивает 65536 значений типов и размер до 64 Кбайт. При 65536 возможных типах на каждом уровне кодирования TLV пространства базовых протокольных типов вполне достаточно и остается место для экспериментов, приложений, фирменных расширений и последующего роста. При таком кодировании не возникает больших пакетов (jumbo), размер которых превышает 64 Кбайта. При использовании в средах с поддержкой кадров jumbo можно определить агрегирование множества мелких кадров в один большой.

Таблица 1. Резервные типы TLV.

Сокращение

Имя

Описание

T_ORG

Информация производителя

Информация, относящаяся к реализации данного прозводителя (параграф 3.3.2).

T_PAD

Заполнение

Дополнение поля до нужного размера (параграф 3.3.1).

нет

Эксперимент

Экспериментальное использование.

Имеется несколько глобальных определений TLV, зарезервированных для всех вариантов иерархического контекста. TLV типов 0x1000 — 0x1FFF являются резервом для экспериментов (Reserved for Experimental Use), TLV типа T_ORG — для фирменных расширений (Reserved for Vendor Extensions, см. параграф 3.3.2), TLV типа T_PAD служат для заполнения полей до нужной границы.

                     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             |
+---------------+---------------+---------------+---------------+

Рисунок 1. Кодирование типа и размера.


Поле Length указывает размер поля Value в октетах, не включая размер полей Type и Length. Поле Length может иметь значения 0.

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

Значения типов зависят от контекста. Внутри контейнера TLV могут применяться ранее использованные типы для новых целей, зависящих от контекста.

3.1. Общий формат пакетов

Каждый пакет CCNx включает 8-байтовый фиксированный заголовок, описанный ниже, за которым следует набор TLV. Эти поля содержат необязательные поэтапные (hop-by-hop) заголовки и данные пакета (Packet Payload).

                     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    |  PacketType   |         PacketLength          |
+---------------+---------------+---------------+---------------+
|         Зависимые от PacketType поля          | HeaderLength  |
+---------------+---------------+---------------+---------------+
/ TLV необязательных поэтапных заголовков                       /
+---------------+---------------+---------------+---------------+
/ PacketPayload TLV                                             /
+---------------+---------------+---------------+---------------+

Рисунок 2. Общий формат пакета.


PacketPayload в пакете CCNx представляет собой само протокольное сообщение. Значение Content Object Hash рассчитывается только для PacketPayload без учета фиксированных и поэтапных заголовков, которые могут меняться в пути. В подписанную информацию или хэш-значения сходства не следует включать фиксированные или поэтапные заголовки. Полю PacketPayload следует быть самодостаточным на случай удаления фиксированных и поэтапных заголовков (см. параграф 3.4.3).

Как и TLV сообщения CCNx, поле PacketPayload может включать необязательный блок Validation TLV.

                     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
+---------------+---------------+---------------+---------------+
| CCNx Message TLV                                              /
+---------------+---------------+---------------+---------------+
/ Необязат. CCNx ValidationAlgorithm TLV                        /
+---------------+---------------+---------------+---------------+
/ Необязат. CCNx ValidationPayload TLV (требуется ValidationAlg)/
+---------------+---------------+---------------+---------------+

Рисунок 3. PacketPayload TLV.


После отбрасывания фиксированных и поэтапных заголовков оставшееся поле PacketPayload должно быть действительным протокольным сообщением. Поэтому PacketPayload всегда начинается с 4 байтов типа и размера, которые указывают протокольное сообщение (Interest, Content Object или иное) и его полный размер. Встраивание самодостаточного протокольного блока данных с фиксированными и поэтапными заголовками позволяет сетевому стеку отбросить заголовки и работать лишь с сообщением. Это также отвязывает поле PacketType, которое указывает, как передавать пакет, от PacketPayload.

Набор байтов, защищенных полем Validation, включает CCNx Message TLV и ValidationAlgorithm TLV.

ContentObjectHash начинается с CCNx Message TLV и завершается в конце CCNx Packet.

3.2. Фиксированные заголовки

Ниже приведены описания полей фиксированного заголовка, показанных на рисунке 2.

Version

Определяет версию пакета и должно иметь значение 1.

HeaderLength

Указывает размер фиксированного (8 байтов) и поэтапных заголовков. Значение должно быть не меньше 8.

PacketType

Описывает действия узла пересылки по отношению к пакету.

PacketLength

Общее число октетов в пакете с учетом всех заголовков и протокольного сообщения.

Зависимые от PacketType поля

Зависящие от PacketType поля пакета.

Поле PacketType указывает, как узлу пересылки следует обрабатывать пакет. Пакеты запроса (Interest) имеют PacketType = PT_INTEREST, отклики (Content Object) — PacketType = PT_CONTENT, а Interest Return — PacketType = PT_RETURN.

HeaderLength указывает число октетов от начала пакета CCNx (Version) до конца поэтапных заголовков, PacketLength — число октетов от начала до конца пакета. Оба поля имеет значение не меньше 8 (размер фиксированного заголовка).

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

3.2.1. Фиксированный заголовок Interest

Если PacketType = PT_INTEREST, это говорит о том, что пакет следует пересылать в соответствии с конвейером Interest, описанным в параграфе 2.4.4 [RFC8569].Для этого типа пакетов фиксированный заголовок включает поле HopLimit, а также поля Reserved и Flags. Поле Reserved в сообщениях Interest должно иметь значение 0. Флаги в настоящее время не определены и поле Flags должно иметь значение 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    |  PT_INTEREST  |         PacketLength          |
+---------------+---------------+---------------+---------------+
|   HopLimit    |   Reserved    |     Flags     | HeaderLength  |
+---------------+---------------+---------------+---------------+

Рисунок 4. Заголовок Interest.


3.2.1.1. Interest HopLimit

Для сообщений Interest поле HopLimit содержит счетчик, декрементируемый на каждом интервале пересылки (hop). Оно ограничивает дальность перемещения Interest через сеть. Создавший Interest узел может поместить в это поле любое значение до 255. Каждый узел, принявший Interest с HopLimit декрементирует значение поля при получении. Если после декремента значение становится 0, Interest недопустимо пересылать за пределы узла.

Прием от удаленного узла сообщений Interest с HopLimit = 0 является ошибкой.

3.2.2. Фиксированный заголовок Content Object

Если PacketType = PT_CONTENT, это указывает, что пакет следует пересылать в соответствии с конвейером Content Object, определенным в параграфе 2.4.4 [RFC8569]. Content Object включает поле Flags, однако флаги в настоящее время не определены и поле должно иметь значение 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    |  PT_CONTENT   |         PacketLength          |
+---------------+---------------+---------------+---------------+
|            Reserved           |     Flags     | HeaderLength  |
+---------------+---------------+---------------+---------------+

Рисунок 5. Заголовок Content Object.


3.2.3. Фиксированный заголовок Interest Return

Если PacketType = PT_RETURN, это указывает, что пакет следует обрабатывать в соответствии с правилами Interest Return, указанными в разделе 10 [RFC8569]. Единственным различием сообщения Interest Return и исходного Interest является замена PacketType на PT_RETURN и включение ReturnCode в поле ReturnCode. Все прочие поля сохраняются неизменными из пакета Interest. Целью этого заключается в предотвращении смены размера, чтобы не нужно было добавлять байты для возврата Interest на предыдущий интервал.

                     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    |   PT_RETURN   |         PacketLength          |
+---------------+---------------+---------------+---------------+
|   HopLimit    |  ReturnCode   |     Flags     | HeaderLength  |
+---------------+---------------+---------------+---------------+

Рисунок 6. Заголовок Interest Return.


3.2.3.1. Interest Return HopLimit

Это поле HopLimit из сообщения Interest до декрементирования его узлом, передающим Interest Return.

3.2.3.2. Флаги Interest Return

Поле Flags из сообщения Interest.

3.2.3.3. Коды возврата

В этом параграфе имена кодов возврата из [RFC8569] отображены на символические имена TLV. В параграфе 4.2 символические имена отображены на числовые значения. Это поле устанавливается узлом, создающим Interest Return.

Код возврата 0 недопустимо устанавливать, поскольку он показывает, что возвращающая сообщение система не изменила поле Return Code.

Таблица 2. Коды возврата.

ReturnType

Имя в 8569

T_RETURN_NO_ROUTE

No Route

T_RETURN_LIMIT_EXCEEDED

Hop Limit Exceeded

T_RETURN_NO_RESOURCES

No Resources

T_RETURN_PATH_ERROR

Path Error

T_RETURN_PROHIBITED

Prohibited

T_RETURN_CONGESTED

Congested

T_RETURN_MTU_TOO_LARGE

MTU too large

T_RETURN_UNSUPPORTED_HASH_RESTRICTION

Unsupported ContentObjectHashRestriction

T_RETURN_MALFORMED_INTEREST

Malformed Interest

3.3. Глобальные форматы

В этом параграфе определены глобальные форматы, которые могут быть встроены в другие TLV.

3.3.1. Заполнение

Тип pad может применяться отправителями, которые хотят выравнивать данные по границе слова. Дополнение 4-байтовых слов может иметь размер 1, 2 или 3 байта, заполнение 8-байтовых слов — 0, 1, 2, 3, 5, 6 или 7 байтов.

Недопустимо применять заполнение в поле Name. Заполнение можно включать в любые другие TLV в CCNx Message TLV или ValidationAlgorithm TLV. В оставшейся части документа не будут указываться необязательные Pad TLV.

                     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
+---------------+---------------+---------------+---------------+
|             T_PAD             |             Length            |
+---------------+---------------+---------------+---------------+
/   Заполнение переменного размера, которое ДОЛЖНО содержать 0  /
+---------------+---------------+---------------+---------------+

Рисунок 7. Заполнение.


3.3.2. Фирменные TLV

Специфичные для организация TLV (фирменные) должны использовать тип T_ORG. Поле Length указывает размер фирменной информации + 3. Поле Value начинается с 3-байтового номера организации, выведенного из значения в реестре IANA Private Enterprise Numbers [IANA-PEN] с сетевым порядком байтов, а за ним следуют специфичные для организации данные.

T_ORG MAY может служит сегментом пути в Name, которые трактуется как все прочие сегменты пути.

                     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
+---------------+---------------+---------------+---------------+
|             T_ORG             |   Length (3+значение размера) |
+---------------+---------------+---------------+---------------+
|   PEN[0]      |    PEN[1]     |     PEN[2]    |               /
+---------------+---------------+---------------+               +
/                  Vendor Specific Value                        /
+---------------+---------------+---------------+---------------+

Рисунок 8. Organization-Specific TLV.


3.3.3. Формат хэш-значений

Хэш-значения применяются в нескольких полях пакетов. В такие поля обычно встраиваются TLV для указания используемой хэш-функции и ее значения. Отметим, что здесь также имеются резервные типы TLV для определяемых пользователями экспериментальных функций.

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

Применение вложенного формата обусловлено тем, что он позволяет выполнять двоичное сравнение хэш-значений некоторых полей без необходимости понимания маршрутизатором новой хэш-функции. Например, поле KeyIdRestriction в Interest сравнивается побитово с полем KeyId в ContentObject. Этот формат означает, что значения внешнего поля не меняются при разных хэш-функциях, поэтому маршрутизатор может идентифицировать эти поля и выполнить двоичное сравнение хэш-TLV, не зная конкретной функции. Другой подход (например, использование T_KEYID_SHA512-256) будет требовать от маршрутизатора обновлять анализатор и поддерживать определяемые пользователями хэш-функции, что связано со значительными издержками при анализе.

Элементы CCNx должны поддерживать хэширование T_SHA-256 и могут поддерживать другие типы.

Таблица 3. Хэш-функции CCNx.

Сокращение

Размер в октетах

T_SHA-256

32

T_SHA-512

64, 32

нет

Экспериментальные типы TLV

 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
+---------------+---------------+---------------+---------------+
|             T_FOO             |              36               |
+---------------+---------------+---------------+---------------+
|           T_SHA512            |               32              |
+---------------+---------------+---------------+---------------+
/                        32-байтовое хэш-значение               /
+---------------+---------------+---------------+---------------+

Рисунок 9. Пример вложенности в тип T_FOO.

3.3.4. Link

Link представляет собой кортеж {Name, [KeyIdRestr], [ContentObjectHashRestr]}. Это базовая форма кодирования, применяемая в данных Content Object с PayloadType = Link и поле KeyLink объектов Content. Link по сути является телом Interest.

                     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
+---------------+---------------+---------------+---------------+
/ Обязательное имя CCNx                                         /
+---------------+---------------+---------------+---------------+
/ Необязательный KeyIdRestriction                               /
+---------------+---------------+---------------+---------------+
/ Необязательный ContentObjectHashRestriction                   /
+---------------+---------------+---------------+---------------+

Рисунок 10. Кодирование Link.


3.4. TLV поэтапных заголовков

TLV поэтапных (hop-by-hop) заголовков являются неупорядоченными и упорядочивать их недопустимо. В документе определены три заголовка hop-by-hop, показанных в таблице.

Таблица 4. Типы поэтапных заголовков.

Сокращение

Имя

Описание

T_INTLIFE

Interest Lifetime (параграф 3.4.1)

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

T_CACHETIME

Recommended Cache Time (параграф 3.4.2)

Рекомендуемое время кэширования для Content Object.

T_MSGHASH

Message Hash (параграф 3.4.3)

Криптографическая хэш-функция (параграф 3.3.3).

Дополнительные поэтапные заголовки определены в спецификациях верхнего уровня, таких как фрагментирование.

3.4.1. Срок действия Interest

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

Значение 0 (кодируется одним байтом 0x00) указывает, что сообщение Interest не вызвало получения отклика Content Object. Сообщение все еще может пересылаться, но отклика не ожидается и узел пересылки может не создавать запись PIT.

                     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
+---------------+---------------+---------------+---------------+
|          T_INTLIFE            |             Length            |
+---------------+---------------+---------------+---------------+
/                                                               /
/                      Lifetime (Length октетов)                /
/                                                               /
+---------------+---------------+---------------+---------------+

Рисунок 11. Кодирование Interest Lifetime.


3.4.2. Рекомендуемое время кэширования

RCT6 указывает срок действия Content Object, назначенный издателем содержимого или восходящим узлом. Это значение служит рекомендацией для хранилищ Content Store при определении срока кэширования объектов Content. Кэш имеет право игнорировать эти рекомендации. Это отличается от времени ExpiryTime (параграф 3.6.2.2.2), которое имеет преимущество перед RCT и должно соблюдаться.

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

RCT (временная метка в миллисекундах с начала эпохи в UTC) является 64-битовым целым числом без знака с сетевым порядком байтов, которое указывает время завершения срока действия данных UTC).

                     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
+---------------+---------------+---------------+---------------+
|         T_CACHETIME           |               8               |
+---------------+---------------+---------------+---------------+
/                                                               /
/                    Recommended Cache Time                     /
/                                                               /
+---------------+---------------+---------------+---------------+

Рисунок 12. Кодирование рекомендуемого времени кэширования.


3.4.3. Хэш сообщения

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

Криптографическое хэш-значение сообщения учитывает данные от начала CCNx Message TLV до конца пакета. Оно служит для сопоставления с ContentObjectHashRestriction (параграф 3.6.2.1.2). Message Hash может превышать по размеру ограничение Interest и в этом случае устройству следует принимать расположенные слева байты Message Hash для сравнения с Interest.

Message Hash может содержать только одно хэш-значение и заголовок Message Hash может быть лишь один.

Заголовок Message Hash не защищен, поэтому практический смысл имеет лишь в доверенном домене, таком как автономная система оператора.

                    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
+---------------+---------------+---------------+---------------+
|          T_MSGHASH            |         (length + 4)          |
+---------------+---------------+---------------+---------------+
|          hash type            |            length             |
+---------------+---------------+---------------+---------------+
/                           хэш-значение                        /
+---------------+---------------+---------------+---------------+

Рисунок 13. Заголовок Message Hash.


3.5. Типы верхнего уровня

Типы TLV верхнего уровня, показанные в таблице, размещаются на внешнем уровне CCNx Message TLV.

Таблица 5. Типы верхнего уровня CCNx.

Сокращение

Имя

Описание

T_INTEREST

Interest (параграф 3.6)

Сообщение типа Interest.

T_OBJECT

Content Object (параграф 3.6)

Сообщение типа Content Object.

T_VALIDATION_ALG

Validation Algorithm (параграф 3.6.4.1)

Метод проверки сообщения, такой как MIC7, MAC8 или криптографическая подпись.

T_VALIDATION_PAYLOAD

Validation Payload (параграф 3.6.4.2)

Выход проверки, такой как код CRC32C или подпись RSA.

3.6. TLV сообщений CCNx

Здесь описан формат самого сообщения CCNx. TLV сообщения CCNx является частью пакета CCNx между поэтапными заголовками и Validation TLV. На рисунке показано расширение CCNx Message TLV, указанное в начале раздела 3. CCNx Message TLV начинается с MessageType и тянется вплоть до необязательного Payload. Один базовый формат применяется для сообщений Interest и Content Object, различающихся лишь полями MessageType. Первым TLV в CCNx Message TLV всегда является Name TLV, если имя имеется. Далее следуют необязательные Message TLV и необязательный Payload TLV.

                     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
+---------------+---------------+---------------+---------------+
|         MessageType           |         MessageLength         |
+---------------+---------------+---------------+---------------+
/ Name TLV       (Type = T_NAME)                                /
+---------------+---------------+---------------+---------------+
/ Необязательные Message TLV   (разные типы)                    /
+---------------+---------------+---------------+---------------+
/ Необязательный Payload TLV  (Type = T_PAYLOAD)                /
+---------------+---------------+---------------+---------------+

Рисунок 14. Кодирование TLV сообщения CCNx.


Таблица 6. Типы TLV сообщений CCNx.

Сокращение

Имя

Описание

T_NAME

Name (параграф 3.6.1)

Имя CCNx Name запрошенное в Interest или опубликованное в Content Object.

T_PAYLOAD

Payload (параграф 3.6.3)

Данные сообщения.

3.6.1. Name

Name представляет собой TLV, кодированный последовательностью сегментов. В таблице 7 указаны типы сегментов имен. В Name недопустимо включать Pad TLV.

Как указано в семантике CCNx [RFC8569], при использовании нотации CCNx URI [CCNxURI] T_NAME нулевого размера соответствует ccnx:/ (маршрут по умолчанию). Грамматика сообщений не позволяет иметь нулевой размер первому сегменту в CCNx Message TLV Name. При кодировании TLV значение ccnx:/ соответствует T_NAME размера 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
+---------------+---------------+---------------+---------------+
|            T_NAME             |            Length             |
+---------------+---------------+---------------+---------------+
/ TLV сегментов имени                                           /
+---------------+---------------+---------------+---------------+

Рисунок 15. Кодирование Name.

Таблица 7. Типы имен CCNx.

Символическое имя

Имя

Описание

T_NAMESEGMENT

Name segment (параграф 3.6.1.1)

Базовый сегмент имени.

T_IPID

Interest Payload ID (параграф 3.6.1.2)

Идентификатор, представляющий поле Interest Payload. Например, Payload ID может быть хэш-значением Interest Payload. Это позволяет разделять сообщения Interest на основе их данных без анализа всех байтов данных лишь по сегменту имени Payload ID.

T_APP:00 — T_APP:4096

Application Components (параграф 3.6.1.1)

Определяемые приложением данные в сегменте имени. Приложение может использовать свою семантику для 4096 зарезервированных типов.

3.6.1.1. Сегменты имен

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

На рисунке 16 показано возможное представление имени ccnx:/foo/bar/hi.

                     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
+---------------+---------------+---------------+---------------+
|            (T_NAME)           |           0x14 (20)           |
+---------------+---------------+---------------+---------------+
|        (T_NAME_SEGMENT)       |           0x03 (3)            |
+---------------+---------------+---------------+---------------+
|       f                o               o      |(T_NAME_SEGMENT)
+---------------+---------------+---------------+---------------+
|               |            0x03 (3)           |       b       |
+---------------+---------------+---------------+---------------+
|      a                r       |           (T_NAME_SEGMENT)    |
+---------------+---------------+---------------+---------------+
|           0x02 (2)            |       h       |       i       |
+---------------+---------------+---------------+---------------+

Рисунок 16. Пример кодирования имени.


3.6.1.2. Идентификатор данных Interest

InterestPayloadID — это сегмент имени, создаваемый источником Interest для представления Interest Payload. Это позволяет мультиплексировать Interest на основе имен, если они различаются содержимым. Базовым вариантом является использование хэш-значений Interest Payload в качестве InterestPayloadID.

Как часть поля Value в TLV значение InterestPayloadID содержит 1-октетный идентификатор метода, использованного для создания InterestPayloadID, за которым следует строка октетов переменного размера. От реализаций не требуется поддержка какого-либо метода для приема Interest, поле InterestPayloadID можно считать просто строкой октетов для мультиплексирования Interest с разными данными. Алгоритмы требуется реализовать лишь на устройствах, создающих и проверяющих сегмент имени InterestPayloadID.

В поле применяется кодирование хэш-значений, описанное в параграфе 3.3.3.

При нормальной работе рекомендуется отображать InterestPayloadID просто как строку октетов в CCNx URI.

В InterestPayloadID (даже если это хэш) не следует передавать какой-либо контекст защиты. Если система требует подтверждения события, связанного с созданием Interest Payload, ей следует применять криптографическую подпись Interest в ValidationAlgorithm и ValidationPayload или использовать свой метод внутри Interest Payload.

3.6.2. TLV сообщений

С каждым типом сообщений (Interest и Content Object) связан набор Message TLV. Для создания дополнительных типов могут быть подготовлены другие спецификации.

3.6.2.1. TLV сообщений Interest

В настоящее время имеется два Message TLV, связанных с сообщениями Interest, — селектор KeyIdRestriction и селектор ContentObjectHashRestr, используемые для сужения пространства подходящих Content Object, которые удовлетворяют запросу Interest.

                     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
+---------------+---------------+---------------+---------------+
|         MessageType           |         MessageLength         |
+---------------+---------------+---------------+---------------+
| Name TLV                                                      |
+---------------+---------------+---------------+---------------+
/ Необязательный KeyIdRestriction TLV                           /
+---------------------------------------------------------------+
/ Необязательный ContentObjectHashRestriction TLV               /
+---------------------------------------------------------------+

Рисунок 17. Interest Message TLV.

Таблица 8. Типы CCNx Interest Message TLV.

Сокращение

Имя

Описание

T_KEYIDRESTR

KeyIdRestriction (параграф 3.6.2.1.1)

Представление KeyId (параграф 3.3.3).

T_OBJHASHRESTR

ContentObjectHashRestriction (параграф 3.6.2.1.2)

Представление хэш-значения конкретного Content Object, который удовлетворяет Interest (параграф 3.3.3).

3.6.2.1.1. KeyIdRestriction

Сообщение Interest может включать селектор KeyIdRestriction, который задает соответствие Interest лишь объектов Content с совпадающими KeyId (см. параграф 3.6.4.1.4.1).

3.6.2.1.2. ContentObjectHashRestriction

Сообщение Interest может включать селектор ContentObjectHashRestriction. Это хэш-значение Content Object — самосертифицированное ограничение имени, которое должно проверяться в сети, если Interest содержит это расширение (см. параграф 3.4.3). Поле LENGTH должно иметь одно из разрешенных для этого хэширования значений (см. параграф 3.3.3).

ContentObjectHashRestriction следует иметь тип T_SHA-256 и размер 32 байта.

                     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
+---------------+---------------+---------------+---------------+
|        T_OBJHASHRESTR         |           (LENGTH+4)          |
+---------------+---------------+---------------+---------------+
|        тип хэширования        |             LENGTH            |
+---------------+---------------+---------------+---------------+
/                  LENGTH октетов хэш-значения                  /
+---------------+---------------+---------------+---------------+

Рисунок 18. Кодирование ContentObjectHashRestriction.


3.6.2.2. TLV сообщений Content Object

Для сообщений Content Object в настоящее время определены 2 необязательных TLV — PayloadType и ExpiryTime.

                     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
+---------------+---------------+---------------+---------------+
|         MessageType           |         MessageLength         |
+---------------+---------------+---------------+---------------+
| Name TLV                                                      |
+---------------+---------------+---------------+---------------+
/ Необязательный PayloadType TLV                                /
+---------------------------------------------------------------+
/ Необязательный ExpiryTime TLV                                 /
+---------------------------------------------------------------+

Рисунок 19. Content Object Message TLV.

Таблица 9. Типы CCNx Content Object Message TLV.

Сокращение

Имя

Описание

T_PAYLDTYPE

PayloadType (параграф 3.6.2.2.1)

Указывает тип содержимого Payload.

T_EXPIRY

ExpiryTime (параграф 3.6.2.2.2)

Время завершения срока действия Payload, указанное числом миллисекунд с начала эпохи в UTC. При отсутствии этого значения срок действия Content Object не ограничен.

3.6.2.2.1. PayloadType

Октет PayloadType представляет базовый тип Payload TLV.

T_PAYLOADTYPE_DATA

Data (возможно шифрование)

T_PAYLOADTYPE_KEY

Key

T_PAYLOADTYPE_LINK

Link

Тип Data указывает, что Payload в сообщении ContentObject содержит неанализируемые байты приложения. Тип Key показывает, что Payload содержит открытый ключ в DER-представлении. Тип Link указывает, что Payload содержит один или несколько каналов (параграф 3.3.4). При отсутствии поля предполагается тип Data.

                     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
+---------------+---------------+---------------+---------------+
|            T_PAYLDTYPE        |               1               |
+---------------+---------------+---------------+---------------+
|  PayloadType  |
+---------------+

Рисунок 20. Кодирование PayloadType.


3.6.2.2.2. ExpiryTime

ExpiryTime показывает время окончания срока действия Payload, выраженное числом миллисекунд с начала эпохи в UTC (64-битовое целое число без знака с сетевым порядком байтов). Системе кэширования или конечной системе не следует отдавать отклики с просроченными Content Object (ExpiryTime в прошлом). Маршрутизаторы, пересылающие Content Object, не обязаны проверять ExpiryTime. При отсутствии ExpiryTime срок действия Content Object считается неограниченным, поэтому системы кэширования и конечные системы могут использовать его неограниченно долго.

                     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
+---------------+---------------+---------------+---------------+
|           T_EXPIRY            |               8               |
+---------------+---------------+---------------+---------------+
/                          ExpiryTime                           /
/                                                               /
+---------------+---------------+---------------+---------------+

Рисунок 21. Кодирование ExpiryTime.


3.6.3. Payload

В Payload 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
+---------------+---------------+---------------+---------------+
|           T_PAYLOAD           |            Length             |
+---------------+---------------+---------------+---------------+
/                        содержимое Payload                     /
+---------------+---------------+---------------+---------------+

Рисунок 22. Кодирование Payload.


3.6.4. Validation

Сообщения Interest и Content Object могут включать информацию, указывающую способ проверки пригодности сообщения CCNx. Эта информация содержится в двух TLV — ValidationAlgorithm и ValidationPayload. Блок ValidationAlgorithm TLV задает механизм проверки сообщения CCNx (например, MIC, MAC или криптографическая подпись). ValidationPayload TLV содержит выход проверки, такой как код CRC32C или подпись RSA.

В сообщениях Interest скорей всего будет применяться только тип MIC — CRC, контрольная сумма или подпись.

3.6.4.1. Алгоритм проверки

ValidationAlgorithm — это набор вложенных TLV, которые содержат всю информацию, требуемую для проверки сообщения. Внешний контейнер имеет тип T_VALIDATION_ALG. Первый вложенный блок TLV определяет конкретный тип проверки, применяемой для сообщения. Тип задается полем ValidationType, как показано на рисунке 23 и описано в таблице 10. В контейнере размещаются TLV для всех зависящих от ValidationType данных (например, идентификатор ключа, его местоположение и т. п.).

Примеры для нескольких типов проверок представлены в параграфе 3.6.4.1.5.

                     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
+---------------+---------------+---------------+---------------+
|       T_VALIDATION_ALG        |      ValidationAlgLength      |
+---------------+---------------+---------------+---------------+
|        ValidationType         |            Length             |
+---------------+---------------+---------------+---------------+
/ Зависимые от ValidationType данные                            /
+---------------+---------------+---------------+---------------+

Рисунок 23. Кодирование алгоритма проверки.

Таблица 10. Типы CCNx Validation TLV.

Сокращение

Имя

Описание

T_CRC32C

CRC32C (параграф 3.6.4.1.1)

Castagnoli CRC32 (iSCSI, ext4 и т. п.) с полиномом нормальной формы 0x1EDC6F41.

T_HMAC-SHA256

HMAC-SHA256 (параграф 3.6.4.1.2)

HMAC (RFC 2104) с использованием SHA256.

T_RSA-SHA256

RSA-SHA256 (параграф 3.6.4.1.3)

Подпись RSA с открытым ключом SHA256.

T_EC-SECP-256K1

SECP-256K1 (параграф 3.6.4.1.3)

Подпись на основе эллиптической кривой с параметрами SECP-256K1 [ECC].

T_EC-SECP-384R1

SECP-384R1 (параграф 3.6.4.1.3)

Подпись на основе эллиптической кривой с параметрами SECP-384R1 [ECC].

3.6.4.1.1. Проверка целостности сообщения

Коды MIC не требуют других данных для выполнения проверки (например, CRC32C имеет значение нулевого размера).

3.6.4.1.2. Коды аутентификации сообщений

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

3.6.4.1.3. Подпись

Тип Signature задает механизм и алгоритм подписи для проверки сообщения. Примеры включают подписи RSA с SHA256, подписи на основе эллиптической кривой с параметрами SECP-256K1 и т. п. Для таких проверок требуется KeyId и механизм получения открытого ключа издателя (KeyLocator), а также может применяться PublicKey, Certificate или KeyLink.

3.6.4.1.4. Зависящие от способа проверки данные

Различные алгоритмы проверки требуют доступа к разным частям данных в ValidationAlgorithm TLV. Как указано выше, Key Id, Key Locator, Public Key, Certificate, Link и Key Name играют роль в разных алгоритмах проверки. В Validation Algorithm TLV может присутствовать любой число зависящих от способа проверки контейнеров данных.

Таблица 11. Типы данных, зависящие от способа проверки.

Сокращение

Имя

Описание

T_KEYID

SignerKeyId (параграф 3.6.4.1.4.1)

Идентификатор общего секрета или открытого ключа, связанного с MAC или Signature.

T_PUBLICKEY

PublicKey (параграф 3.6.4.1.4.2)

Открытый ключ в DER-представлении.

T_CERT

Certificate (параграф 3.6.4.1.4.3)

Ключ X.509 в DER-представлении.

T_KEYLINK

KeyLink (параграф 3.6.4.1.4.4)

Объект CCNx Link.

T_SIGTIME

SignatureTime (параграф 3.6.4.1.4.5)

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

3.6.4.1.4.1. KeyId

KeyId для подписи является идентификатором открытого ключа издателя. Это похоже на Subject Key Identifier в X.509 (см. параграф 4.2.1.2 в [RFC5280]). Значение следует выводить из ключа, использованного для подписи (например, хэш SHA-256 для ключа). Это применимо к системам как с симметричными, так и с открытыми ключами.

KeyId представляется с использованием формата хэш-значений, описанного в параграфе 3.3.3. Если прикладной протокол применяет иной идентификатор, ему следует использовать зарезервированные значения.

                     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
+---------------+---------------+---------------+---------------+
|            T_KEYID            |            LENGTH+4           |
+---------------+---------------+---------------+---------------+
|          <hash type>          |             LENGTH            |
+---------------+---------------+---------------+---------------+
/                  LENGTH октетов хэш-значения                  /
+---------------+---------------+---------------+---------------+

Рисунок 24. Кодирование KeyId.


3.6.4.1.4.2. Открытый ключ

Открытый ключ указывается DER-представлением блока SPKI9 как в сертификате X.509.

                     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
+---------------+---------------+---------------+---------------+
|          T_PUBLICKEY          |            Length             |
+---------------+---------------+---------------+---------------+
/           Открытый ключ (DER-представление SPKI)              /
+---------------+---------------+---------------+---------------+

Рисунок 25. Кодирование открытого ключа.


3.6.4.1.4.3. Сертификат

Certificate указывается DER-представлением сертификата X.509. KeyId (параграф 3.6.4.1.4.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
+---------------+---------------+---------------+---------------+
|            T_CERT             |            Length             |
+---------------+---------------+---------------+---------------+
/             Certificate (DER-представление X.509)             /
+---------------+---------------+---------------+---------------+

Рисунок 26. Кодирование сертификата.


3.6.4.1.4.4. KeyLink

KeyLink типа KeyLocator представляет Link.

                     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
+---------------+---------------+-------------------------------+
|          T_KEYLINK            |            Length             |
+---------------+---------------+-------------------------------+
/ Link                                                          /
+---------------------------------------------------------------+

Рисунок 27. Кодирование KeyLink.


При наличии KeyLink ContentObjectHashRestr это поле содержит дайджест Content Object, указанный KeyLink, а не подпись открытого ключа. Аналогично, KeyIdRestr в KeyLink является KeyId для ContentObject, а не обязательно «завернутого» ключа.

3.6.4.1.4.5. SignatureTime

SignatureTime указывает временную метку (в миллисекундах) момента создания подписи. Подписывающий устанавливает это поле в соответствии с текущим временем. Проверяющий может использовать это значение для проверки того, что подпись была создана в период действия ключа или это происходило в разумной последовательности с другими связанными подписями. Значение SignatureTime не связано с моментом создания сообщения CCNx (оно могло быть создано задолго до подписания). По умолчанию принято включать SignatureTime при создании аутентифицированных сообщений (например, HMAC или RSA).

SignatureTime является 64-битовым целым числом без знака с сетевым порядком байтов, которое указывает число миллисекунд с начала эпохи в UTC при создании подписи.

                     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
+---------------+---------------+-------------------------------+
|           T_SIGTIME           |               8               |
+---------------+---------------+-------------------------------+
/                         SignatureTime                         /
+---------------------------------------------------------------+

Рисунок 28. Кодирование SignatureTime.


3.6.4.1.5. Примеры проверок

Как пример проверки типа MIC кодирование CRC32C может иметь вид, представленный ниже.

                     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
+---------------+---------------+---------------+---------------+
|      T_VALIDATION_ALG         |               4               |
+---------------+---------------+---------------+---------------+
|            T_CRC32C           |               0               |
+---------------+---------------+---------------+---------------+

Рисунок 29. Пример кодирования CRC32C.


Как пример проверки типа MAC кодирование HMAC с использованием SHA256 может иметь вид

                     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
+---------------+---------------+---------------+---------------+
|       T_VALIDATION_ALG        |               40              |
+---------------+---------------+---------------+---------------+
|        T_HMAC-SHA256          |               36              |
+---------------+---------------+---------------+---------------+
|             T_KEYID           |               32              |
+---------------+---------------+---------------+---------------+
/                            KeyId                              /
/---------------+---------------+-------------------------------+

Рисунок 30. Пример кодирования HMAC-SHA256.


Как пример проверки типа Signature кодирование подписи с открытым ключом RSA при использовании подписи SHA256 и Public может иметь вид

                     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
+---------------+---------------+---------------+---------------+
|       T_VALIDATION_ALG        |   44 octets + Variable Length |
+---------------+---------------+---------------+---------------+
|          T_RSA-SHA256         |   40 octets + Variable Length |
+---------------+---------------+---------------+---------------+
|             T_KEYID           |               32              |
+---------------+---------------+---------------+---------------+
/                            KeyId                              /
/---------------+---------------+-------------------------------+
|          T_PUBLICKEY          |  Variable Length (~160 octets)|
+---------------+---------------+---------------+---------------+
/                Public Key (DER-encoded SPKI)                  /
+---------------+---------------+---------------+---------------+

Рисунок 31. Пример кодирования RSA-SHA256.


3.6.4.2. Данные Validation
                     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
+---------------+---------------+---------------+---------------+
|     T_VALIDATION_PAYLOAD      |  ValidationPayloadLength      |
+---------------+---------------+---------------+---------------+
/ Type-dependent data                                           /
+---------------+---------------+---------------+---------------+

Рисунок 32. Пример кодирования данных проверки.


ValidationPayload содержит вывод проверки, такой как код CRC32C или подпись RSA.

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

В этом разделе подробно описаны все типы значений протокола CCNx, которые могут регистрироваться. Каждый реестр может обновляться путем постепенного расширения пространства, например, за счет выделения и резервирования новых типов. В соответствии с [RFC8126] этот раздел описывает создание реестра Content-Centric Networking (CCNx) и его субреестров.

4.1. Реестр типов пакетов

Агентство IANA создало реестр CCNx Packet Types и выделило значения для типа пакетов, приведенные ниже. Регистрация выполняется по процедуре RFC Required. Размер Type составляет 1 октет, диапазон — 0x00-0xFF.

Типы пакетов.

 

Тип

Имя

Документ

0x00

PT_INTEREST

Фиксированные заголовки (параграф 3.2)

0x01

PT_CONTENT

Фиксированные заголовки (параграф 3.2)

0x02

PT_RETURN

Фиксированные заголовки (параграф 3.2)

 

4.2. Реестр кодов Interest Return

Агентство IANA создало реестр CCNx Interest Return Code Types и выделило значения кодов, приведенные ниже. Регистрация выполняется по процедуре RFC Required. Размер Type составляет 1 октет, диапазон — 0x00-0xFF.

Типы CCNx Interest Return.

 

Тип

Имя

Документ

0x00

Резерв

0x01

T_RETURN_NO_ROUTE

Фиксированные заголовки (параграф 3.2.3.3)

0x02

T_RETURN_LIMIT_EXCEEDED

Фиксированные заголовки (параграф 3.2.3.3)

0x03

T_RETURN_NO_RESOURCES

Фиксированные заголовки (параграф 3.2.3.3)

0x04

T_RETURN_PATH_ERROR

Фиксированные заголовки (параграф 3.2.3.3)

0x05

T_RETURN_PROHIBITED

Фиксированные заголовки (параграф 3.2.3.3)

0x06

T_RETURN_CONGESTED

Фиксированные заголовки (параграф 3.2.3.3)

0x07

T_RETURN_MTU_TOO_LARGE

Фиксированные заголовки (параграф 3.2.3.3)

0x08

T_RETURN_UNSUPPORTED_HASH_RESTRICTION

Фиксированные заголовки (параграф 3.2.3.3)

0x09

T_RETURN_MALFORMED_INTEREST

Фиксированные заголовки (параграф 3.2.3.3)

 

4.3. Реестр типов Hop-by-Hop

Агентство IANA создало реестр CCNx Hop-by-Hop Types и выделило значения кодов, приведенные ниже. Регистрация выполняется по процедуре RFC Required. Размер Type составляет 2 октета, диапазон — 0x0000-0xFFFF.

Типы CCNx Hop-by-Hop

 

Тип

Имя

Документ

0x0000

Резерв

0x0001

T_INTLIFE

TLV поэтапных заголовков (параграф 3.4)

0x0002

T_CACHETIME

TLV поэтапных заголовков (параграф 3.4)

0x0003

T_MSGHASH

TLV поэтапных заголовков (параграф 3.4)

0x0004 — 0x0007

Резерв

0x0FFE

T_PAD

Заполнение (параграф 3.3.1)

0x0FFF

T_ORG

Фирменные TLV (параграф 3.3.2)

0x1000 — 0x1FFF

Резерв

Экспериментальное использование (раздел 3)

 

4.4. Реестр типов верхнего уровня

Агентство IANA создало реестр CCNx Top-Level Types и выделило значения кодов, приведенные ниже. Регистрация выполняется по процедуре RFC Required. Размер Type составляет 2 октета, диапазон — 0x0000-0xFFFF.

Типы верхнего уровня CCNx

 

Тип

Имя

Документ

0x0000

Резерв

0x0001

T_INTEREST

Типы верхнего уровня (параграф 3.5)

0x0002

T_OBJECT

Типы верхнего уровня (параграф 3.5)

0x0003

T_VALIDATION_ALG

Типы верхнего уровня (параграф 3.5)

0x0004

T_VALIDATION_PAYLOAD

Типы верхнего уровня (параграф 3.5)

 

4.5. Реестр типов сегментов имен

Агентство IANA создало реестр CCNx Name Segment Types и выделило значения кодов, приведенные ниже. Регистрация выполняется по процедуре RFC Required. Размер Type составляет 2 октета, диапазон — 0x0000-0xFFFF.

Типы сегментов имен CCNx.

 

Тип

Имя

Документ

0x0000

Резерв

0x0001

T_NAMESEGMENT

Name (параграф 3.6.1)

0x0002

T_IPID

Name (параграф 3.6.1)

0x0010 — 0x0013

Резерв

RFC 8609

0x0FFF

T_ORG

Фирменные TLV (параграф 3.3.2)

0x1000 — 0x1FFF

T_APP:00 — T_APP:4096

Сегменты имен (параграф 3.6.1.1)

 

4.6. Реестр типов сообщений

Агентство IANA создало реестр CCNx Message Types и выделило значения кодов, приведенные ниже. Регистрация выполняется по процедуре RFC Required. Размер Type составляет 2 октета, диапазон — 0x0000-0xFFFF.

Типы сообщений CCNx.

 

Тип

Имя

Документ

0x0000

T_NAME

TLV сообщений CCNx (параграф 3.6)

0x0001

T_PAYLOAD

TLV сообщений CCNx (параграф 3.6)

0x0002

T_KEYIDRESTR

TLV сообщений CCNx (параграф 3.6)

0x0003

T_OBJHASHRESTR

TLV сообщений CCNx (параграф 3.6)

0x0005

T_PAYLDTYPE

TLV сообщений Content Object (параграф 3.6.2.2)

0x0006

T_EXPIRY

TLV сообщений Content Object (параграф 3.6.2.2)

0x0007 — 0x000C

Резерв

RFC 8609

0x0FFE

T_PAD

Заполнение (параграф 3.3.1)

0x0FFF

T_ORG

Фирменные TLV (параграф 3.3.2)

0x1000-0x1FFF

Резерв

Экспериментальное использование (раздел 3)

 

4.7. Реестр типов данных

Агентство IANA создало реестр CCNx Payload Types и выделило значения кодов, приведенные ниже. Регистрация выполняется по процедуре Specification Required. Размер Type составляет 1 октет, диапазон — 0x00-0xFF.

Типы CCNx Payload.

 

Тип

Имя

Документ

0x00

T_PAYLOADTYPE_DATA

PayloadType (параграф 3.6.2.2.1)

0x01

T_PAYLOADTYPE_KEY

PayloadType (параграф 3.6.2.2.1)

0x02

T_PAYLOADTYPE_LINK

PayloadType (параграф 3.6.2.2.1)

 

4.8. Реестр типов алгоритма проверки

Агентство IANA создало реестр CCNx Validation Algorithm Types и выделило значения кодов, приведенные ниже. Регистрация выполняется по процедуре Specification Required. Размер Type составляет 2 октета, диапазон — 0x0000-0xFFFF.

Типы алгоритмов проверки CCNx.

 

Тип

Имя

Документ

0x0000

Резерв

0x0002

T_CRC32C

Алгоритм проверки (параграф 3.6.4.1)

0x0004

T_HMAC-SHA256

Алгоритм проверки (параграф 3.6.4.1)

0x0005

T_RSA-SHA256

Алгоритм проверки (параграф 3.6.4.1)

0x0006

T_EC-SECP-256K1

Алгоритм проверки (параграф 3.6.4.1)

0x0007

T_EC-SECP-384R1

Алгоритм проверки (параграф 3.6.4.1)

0x0FFE

T_PAD

Заполнение (параграф 3.3.1)

0x0FFF

T_ORG

Фирменные TLV (параграф 3.3.2)

0x1000 — 0x1FFF

Резерв

Экспериментальное использование (раздел 3)

 

4.9. Реестр зависимых от типа проверки данных

Агентство IANA создало реестр CCNx Validation-Dependent Data Types и выделило значения кодов, приведенные ниже. Регистрация выполняется по процедуре RFC Required. Размер Type составляет 2 октета, диапазон — 0x0000-0xFFFF.

Зависящие от способа проверки типы данных CCNx.

 

Тип

Имя

Документ

0x0000

Резерв

0x0009

T_KEYID

Зависящие от способа проверки данные (параграф 3.6.4.1.4)

0x000A

T_PUBLICKEYLOC

Зависящие от способа проверки данные (параграф 3.6.4.1.4)

0x000B

T_PUBLICKEY

Зависящие от способа проверки данные (параграф 3.6.4.1.4)

0x000C

T_CERT

Зависящие от способа проверки данные (параграф 3.6.4.1.4)

0x000D

T_LINK

Зависящие от способа проверки данные (параграф 3.6.4.1.4)

0x000E

T_KEYLINK

Зависящие от способа проверки данные (параграф 3.6.4.1.4)

0x000F

T_SIGTIME

Зависящие от способа проверки данные (параграф 3.6.4.1.4)

0x0FFF

T_ORG

Фирменные TLV (параграф 3.3.2)

0x1000-0x1FFF

Резерв

Экспериментальное использование (раздел 3)

 

4.10. Реестр типов хэш-функций

Агентство IANA создало реестр CCNx Hash Function Types и выделило значения кодов, приведенные ниже. Регистрация выполняется по процедуре Specification Required. Размер Type составляет 2 октета, диапазон — 0x0000-0xFFFF.

Типы хэш-функций CCNx.

 

Тип

Имя

Документ

0x0000

Резерв

0x0001

T_SHA-256

Формат хэш-значений (параграф 3.3.3)

0x0002

T_SHA-512

Формат хэш-значений (параграф 3.3.3)

0x0FFF

T_ORG

Фирменные TLV (параграф 3.3.2)

0x1000-0x1FFF

Резерв

Экспериментальное использование (раздел 3)

 

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

CCNx является протоколом сетевого уровня (L3), который может работать в режиме наложения с использованием такого транспорта, как UDP или туннели. Протокол имеет встроенную поддержку аутентификации сообщений с помощью подписи (например, RSA или эллиптическая кривая) или кода аутентификации (например, HMAC). Взамен аутентификатора может применяться проверка целостности сообщения (например, SHA или CRC). CCNx не определяет «конверт» шифрования, оставляя это вышележащим протоколам (например, [esic]).

Формат пакетов CCNx позволяет присоединить MIC (например, CRC32C), MAC (например, HMAC) и подписи (например, RSA или ECDSA) к пакетам любого типа. Это не означает, что хорошей идеей будет использование произвольного ValidationAlgorithm или включать ресурсоемкие алгоритмы в пакеты Interest, поскольку это может приводить к DoS-атакам за счет вычислений. Приложениям следует использовать явный протокол для руководства применением подписей пакетов. В качестве общего руководства приложения могут использовать MIC в сообщениях Interest для обнаружения непреднамеренно поврежденных пакетов. Если нужна защита Interest, следует рассмотреть возможность шифрования и протокол, предотвращающий атаки с повторным использованием, особенно при использовании Interest в качестве исполнительного механизма (actuator). Простое применение кода аутентификации или подписи не обеспечивает защиты Interest. В литературе имеется несколько примеров защиты обмена сообщениями в стиле ICN [mobile] [ace].

Поскольку документ относится к протоколу L3, он не описывает способов доставки ключей и механизмов доверия к ним. Content Object в CCNx может включать открытый ключ или сертификат, а также может использовать поле KeyLink для указания открытого ключа или сертификата для проверки подлинности сообщения. Одной из спецификаций обмена ключами является CCNxKE [ccnx-ke] [mobile], где обмен похож на процедуру TLS 1.3, отличаясь тем, что происходит через сообщения CCNx L3. Вопросы доверия выходят за рамки протокола L3 и решаются приложениями.

Комбинация обмена эфемерными ключами (например, CCNxKE [ccnx-ke]) с инкапсулирующим шифрованием (например, [esic]) обеспечивает эквивалент туннеля TLS. Промежуточные узлы могут пересылать сообщения Interest и Content Object, но не будут видеть их содержимого. Это также полностью скрывает внутренние имена, заменяя их именами, используемыми уровнем шифрования. Этот тип туннельного шифрования полезен для передачи содержимого, которое не мало или совсем не подходит для кэширования, поскольку оно может применяться лишь теми, кто знает эфемерный ключ. Краткосрочное кэширование может помочь на каналах с потерями, но длительное кэширование обычно не представляет интереса.

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

Конкретное кодирование сообщений будет влиять на безопасность. В [RFC8609] применяется кодирование TLV. Был выбран компромисс между расширяемостью и однозначностью кодирования типа и размера. Некоторые TLV используют поля T и L переменного размера, чтобы вместить более широкий диапазон значений с сохранением эффективного использования байтов. Здесь TLV кодируются с 2-байтовыми полями T и L, что решает 2 проблемы. Первая проблема связана с псевдонимами. Если можно кодировать одно значение в полях разного размера (например, %x02 и %x0002), кто-то может счесть их одним, а другой — разными. Если есть различие, оно должно определяться в буферах, а не числовом представлении. Если от этого отказаться, придется проверять кодирование TLV в каждом поле каждого пакета на всех узлах пересылки. Если они одинаковы, возникает другая проблема — как задавать фильтры. Например, если имя включает 6 компонент, имеется 7 полей T и 7 полей L, каждое из которых может иметь до 4 представлений одного значения. В результате имеется 14 полей с 4 представлениями для каждого или «1001 комбинация». Это также означает невозможность сравнения, например, имени через функции памяти, поскольку нужно учитывать разные форматы T и L.

Сообщение Interest Return не имеет аутентификатора от предыдущего интервала. Поэтому данные из Interest Return следует применять лишь локально для сопоставления с Interest. Узлу не следует пересылать эти Interest Payload как Interest. Он должен также убедиться, что передал Interest в Interest Return нужному узлу и не позволять кому-либо отменять сообщения Interest.

Кэширующие узлы должны соблюдать осторожность при обработке Content Object. Важно, чтобы хранилище Content Store следовало правилам параграфа 2.4.3 во избежание некоторых типов атак. CCNx 1.0 не имеет механизмов обхода нежелательных результатов из сети (нет «исключений»), поэтому при отравлении кэша непригодным содержимым это может вызвать проблемы при поиске. Существует 3 типа доступа к содержимому из Content Store — неограниченный, а также ограниченные подписью и хэш-значением. Если Interest не имеет ограничений, запрашивающая сторона не заботится о том, что она получит в ответ и подойдет любой кэшированный объект. При ограничении по хэш-значению запрашивающая сторона очень точно определяет желаемый результат и Content Store (и каждый пересылающий узел) может легко проверить соответствие содержимого запросу. При ограничении подписью (часто служит для начального обнаружения манифеста) запрашивающий знает лишь KeyId для подписи содержимого. Этот случай требует пристального внимания в Content Store, чтобы избежать усиления неверных данных. Хранилище Content Store должно отвечать лишь объектами Content с проверенной подписью. Это значит, что Content Object содержит в себе открытый ключ или Interest передает открытый ключ в дополнение к KeyId. Если это не выполняется, хранилищу Content Store следует рассматривать Interest как отсутствие кэша и позволять конечной точке ответить.

Кэш пользовательского уровня может выполнять полную проверку подписи путем извлечения открытого ключа или сертификата по KeyLink. Однако это не та задача, которую можно отдать узлу пересылки. Пользовательский кэш может также полагаться на внешнюю (out-of-band) аттестацию, например, если оператор кэша включает лишь информацию, для которой у него есть корректная подпись.

Грамматика CCNx обеспечивает гибкость алгоритма хэширования с помощью HashType, указывая список приемлемых алгоритмов, которые следует реализовать на каждом узле пересылки. Некоторые типы пригодны лишь для конечных систем и обновление их не влияет на узлы пересылки, которые будут просто сопоставлять буферы, включающие type-length-hash. Некоторые поля (например, ConObjHash) должны проверяться на каждом узле, поэтому узел пересылки (или связанная с ним система) должен знать алгоритм хэширования. Это может вызвать проблемы совместимости при смене типа хэша. [RFC8609] является официальным источником данных о разрешенных типах хэширования.

Для имен CCNx применяется двоичное сопоставление, тогда как для URI используются имена хостов без учета регистра. Некоторые системы могут применять независимое от регистра сопоставление путей URI к ресурсу. В результате введенные человеком имена CCNx будут скорей всего сталкиваться с несоответствием символов разных регистров и символы не-ASCII, если не применять нормализацию URI для имен CCNx. Это означает, что объект, регистрирующий маршрутизируемый префикс CCNx, скажем ccnx:/example.com, должен зарегистрировать варианты типа ccnx:/Example.com. Если это не учтено в нормализации URI normalization и соглашениях протокола маршрутизации, становятся возможными фишинговые атаки.

Более общее рассмотрение вопросов безопасности ICN приведено в [RFC7927] и [RFC7945].

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

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

[RFC2119] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC8174] Leiba, B., «Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words», BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

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

[ace] Shang, W., Yu, Y., Liang, T., Zhang, B., and L. Zhang, «NDN-ACE: Access control for constrained environments over named data networking», NDN Technical Report NDN-0036, 2015, <http://new.named-data.net/wp-content/uploads/2015/12/ndn-0036-1-ndn-ace.pdf>.

[ccnxke] Mosko, M., Uzun, E., and C. Wood, «CCNx Key Exchange Protocol Version 1.0», Work in Progress, draft-wood-icnrg-ccnxkeyexchange-02, March 2017.

[CCNxURI] Mosko, M. and C. Wood, «The CCNx URI Scheme», Work in Progress, draft-mosko-icnrg-ccnxurischeme-01, April 2016.

[CCNxz] Mosko, M., «CCNxz TLV Header Compression Experimental Code», commit f1093a2, March 2018, <https://github.com/PARC/CCNxz>.

[compress] Mosko, M., «Header Compression for TLV-based Packets», ICNRG Interim Meeting, 2016, <https://datatracker.ietf.org/meeting/interim-2016-icnrg-02/materials/slides-interim-2016-icnrg-2-7>.

[ECC] Certicom Research, «SEC 2: Recommended Elliptic Curve Domain Parameters», 2010, <http://www.secg.org/sec2-v2.pdf>.

[esic] Mosko, M. and C. Wood, «Encrypted Sessions In CCNx (ESIC)», Work in Progress, draft-wood-icnrg-esic-01, September 2017.

[IANA-PEN] IANA, «Private Enterprise Numbers», <http://www.iana.org/assignments/enterprise-numbers>.

[mobile] Mosko, M., Uzun, E., and C. Wood, «Mobile Sessions in Content-Centric Networks», IFIP Networking, 2017, <http://dl.ifip.org/db/conf/networking/networking2017/1570334964.pdf>.

[nnc] Jacobson, V., Smetters, D., Thornton, J., Plass, M., Briggs, N., and R. Braynard, «Networking Named Content», Proceedings of the 5th international conference on Emerging networking experiments and technologies (CoNEXT ’09), 2009, <http://dx.doi.org/10.1145/1658939.1658941>.

[RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, «Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile», RFC 5280, DOI 10.17487/RFC5280, May 2008, <https://www.rfc-editor.org/info/rfc5280>.

[RFC7927] Kutscher, D., Ed., Eum, S., Pentikousis, K., Psaras, I., Corujo, D., Saucez, D., Schmidt, T., and M. Waehlisch, «Information-Centric Networking (ICN) Research Challenges», RFC 7927, DOI 10.17487/RFC7927, July 2016, <https://www.rfc-editor.org/info/rfc7927>.

[RFC7945] Pentikousis, K., Ed., Ohlman, B., Davies, E., Spirou, S., and G. Boggia, «Information-Centric Networking: Evaluation and Security Considerations», RFC 7945, DOI 10.17487/RFC7945, September 2016, <https://www.rfc-editor.org/info/rfc7945>.

[RFC8126] Cotton, M., Leiba, B., and T. Narten, «Guidelines for Writing an IANA Considerations Section in RFCs», BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>.

[RFC8569] Mosko, M., Solis, I., and C. Wood, «Content-Centric Networking (CCNx) Semantics», RFC 8569, DOI 10.17487/RFC8569, July 2019, <https://www.rfc-editor.org/info/rfc8569>.

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

Marc Mosko

PARC, Inc.

Palo Alto, California 94304

United States of America

Phone: +01 650-812-4405

Email: mmosko@parc.com

Ignacio Solis

LinkedIn

Mountain View, California 94043

United States of America

Email: nsolis@linkedin.com

Christopher A. Wood

University of California, Irvine

Irvine, California 92697

United States of America

Phone: +01 315-806-5939

Email: woodc1@uci.edu


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

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

nmalykh@protokols.ru

1Content-Centric Networking — ориентированные на содержимое сети.

2Information-Centric Networking Research Group — группа по исследованию ориентированных на информацию сетей.

3Internet Research Task Force.

4Type-Length-Value — тип, размер, значение.

5Information-Centric Networking — ориентированная на информацию сеть.

6Recommended Cache Time — рекомендуемое время кэширования.

7Message Integrity Check — код целостности сообщения.

8Message Authentication Code — код аутентификации сообщения.

9Subject Public Key Info — информация о субъекте открытого ключа.

Рубрика: RFC | Комментарии к записи RFC 8609 Content-Centric Networking (CCNx) Messages in TLV Format отключены

RFC 8569 Content-Centric Networking (CCNx) Semantics

Internet Research Task Force (IRTF)                             M. Mosko
Request for Comments: 8569                                    PARC, Inc.
Category: Experimental                                          I. Solis
ISSN: 2070-1721                                                 LinkedIn
                                                                 C. Wood
                                         University of California Irvine
                                                               July 2019

Content-Centric Networking (CCNx) Semantics

Семантика ориентированных на содержимое сетей (CCNx)

PDF

Аннотация

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

Протокол также применяет управляющие сообщения Interest Return, посредством которых одна система может возвращать сообщения Interest на предыдущий интервал пересылки (hop) при возникновении ошибки. Это указывает предыдущему интервалу, что текущая система не будет отвечать на Interest.

Документ является результатом работы исследовательской группы ICNRG2. Документ был рассмотрен множеством участников ICNRG. Две реализации активно применяются и показывают техническую зрелость спецификации протокола.

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

Документ не является спецификацией стандартного протокола Internet (Standards Track) и публикуется для проверки, экспериментальной реализации и оценки.

Документ определяет экспериментальный протокол для сообщества Internet. Документ является результатом работы IRTF3. IRTF публикует результаты связанных с Internet исследований и разработок. Эти результаты могут оказаться не подходящими для развертывания. Данный RFC представляет согласованное мнение группы ICNRG в составе IRTF. Документ одобрен для публикации IRSG и не претендует на роль стандарта Internet (см. раздел 2 в RFC 7841).

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

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

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

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

1. Введение

Этот документ описывает принципы архитектуры CCNx. Описан протокол, применяющий иерархические имена для пересылки запросов и сопоставления откликов с запросами. Протокол не использует адресов конечных точек (таких, как IP). Ограничения в запросе могут лимитрировать отклик открытым ключом подписавшей стороны или криптографическим хэшем отклика. Каждый узел пересылки CCNx в пути проверяет соответствие имен и ограничения. Протокол CCNx вписывается в более широкую модель протоколов ориентированных на информацию сетей (ICN4) [RFC7927]. Этот документ посвящен семантике протокола и не зависит от представления данных в линии. В документе, посвященном сообщениям CCNx [RFC8609], описано представление TLV5 для сигналов в линии. В этом параграфе рассмотрены основные концепции CCNx, которые более подробно описаны в оставшейся части документа.

Протокол CCNx основан на ранних работах ICN, выполненных Jacobson и др. [nnc]. Версия Jacobson для CCNx известна как 0.x (CCNx 0.x), а настоящая работа имеет версию 1.0 (CCNx 1.0). Имеются две активные реализации CCNx 1.0. Наиболее полной является Community ICN (CICN) [cicn] — проект Linux Foundation, размещенный на fd.io. Другой активной реализацией является CCN-lite [ccn-lite], поддерживающая системы IoT6 и операционную систему RIOT. CCNx 0.x стал основой для университетского проекта NDN7 [ndn].

Текущая спецификация CCNx 1.0 отличается от CCNx 0.x в нескольких значимых областях. Наиболее явное поведенческое различие между CCNx 0.x и CCNx 1.0 состоит в том, что CCNx 1.0 имеет более простую обработку откликов. В обоих версиях пересылающие узлы используют иерархическое сопоставление самого длинного совпадающего префикса с информационной базой пересылки (FIB8) для отправки запроса через сеть в систему, которая может выдать ответ. Пересылающий узел должен затем сопоставить имя отклика с именем запроса для определения обратного пути и доставить отклик запрашивающему. В CCNx 0.x имя Interest может быть иерархическим префиксом имени отклика, который позволяет обнаруживать содержимое на уровне 3 (L3). В CCNx 1.0 имя отклика должно совпадать с именем запроса. Обнаружение содержимого выполняет протокол вышележащего уровня.

Протокол селекторов CCNx Selectors [selectors] является примером использования протокола вышележащего уровня над CCNx 1.0 L3 для обнаружения содержимого. Протокол селекторов использует метод, похожий на исходные методы CCNx 0.x, не требуя частичного сопоставления имен откликов и запросов в пересылающем узле.

Этот документ представляет согласованную точку зрения группы ICNRG. Это первый протокол ICN исследовательской группы, созданный на основе раннего протокола CCNx [nnc] с существенным пересмотром и вкладом сообщества ICN и членов исследовательской группы. Документ прошел критический обзор нескольких членов сообщества ICN и исследовательской группы. Авторы и руководитель исследовательской группы одобрили документ. Документ поддержан IRTF, выпущен без участия IETF и не является стандартом IETF. Это экспериментальный протокол, который может не подойти для конкретных применений. Спецификация в будущем может измениться.

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

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

1.2. Архитектура

Опишем архитектуру сети, в которой работает CCNx и введем некоторые термины из [terminology]. Подробное описание всех компонент и грамматика сообщений рассмотрены в разделе 2.

Производителем (producer) или издателем (publisher) является конечная точка, которая инкапсулирует содержимое в объекты Content для транспортировки в сеть CCNx. Издатель имеет открытый и секретный ключ, а также подписывает (напрямую или опосредованно) объекты Content. Обычно идентификатор открытого ключа издателя KeyId (хэш открытого ключа) широко известен или может быть выведен из пространства имен издателя стандартным путем.

Издатель оперирует в одном или нескольких пространствах имен, которые являются префиксами имен, представленными в информационных базах пересылки (FIB). Это позволяет запросу достичь издателя и получить отклик (если он существует).

Таблица FIB говорит пересылающему узлу, куда направить запрос. Она может указывать локальное приложение, локальный кэш или хранилище содержимого (Content Store), а также удаленную систему. Если в FIB не найдено соответствующей записи, узел пересылки не может обработать запрос. Детали правил сопоставления имен с FIB приведены в параграфе 2.4.4. Конечная точка имеет FIB, хотя это может быть простой маршрут, принятый по умолчанию. Промежуточные системы (т. е. маршрутизаторы) обычно имеют более крупные базы FIB. Центральный узел пересылки CCNx, например, будет знать все глобальные маршруты.

Потребителем является конечная точка, запрашивающая имя. Этот документ не описывает способов выяснения имен или KeyId издателей потребителями — протокол вышележащего уровня, работающий на основе CCNx, выполняет функции машины поиска и служб поиска или общеизвестных имен. Потребитель создает запрос, называемый Interest (интерес), и пересылает его через FIB конечной точки. Потребитель должен получить ответ на запрос (объект Content), соответствующий Interest, или управляющее сообщение (Interest Return), указывающее невыполнимость запроса.

Имеется 3 способа обнаружения ошибок при обработке Interest. Interest Return представляет собой управляющее сообщение, которое указывает ошибку низкого уровня, такую как отсутствие маршрута (no route) или нехватку ресурсов (out of resources). Если Interest приходит к издателю, но у того нет запрошенного содержимого, издателю следует передать зависящее от приложения сообщение об ошибке (например, not found — не найдено). Наконец, потребитель может не получить ничего (тайм-аут) и, в зависимости от приложения, ему следует повторить запрос или вернуть ошибку приложению.

1.3. Обзор протокола

Целью CCNx является именование содержимого и его извлечение из сети без привязки к конкретной конечной точке. Система маршрутизации (задается отдельно) заполняет таблицы FIB на каждом маршрутизаторе CCNx иерархическими префиксами имен, которые указывают издателей содержимого для данного префикса. Запрос находит соответствующее содержимое по этим путям и в этом случае отклик возвращает данные. Если совпадения не найдено, управляющее сообщение говорит об отказе. Запрос может дополнительно уточнять подходящие отклики путем ограничений для подписывающей отклик стороны и криптографического хэширования отклика. Детали таких ограничений рассмотрены ниже.

Имя CCNx представляет собой иерархическую последовательность сегментов имен, каждый из которых имеет тип и может иметь значение. Сопоставление двух имен выполняется путем посегментного двоичного сравнения типа и значения. Удобная для человека форма определена по схеме URI «ccnx:» [ccnx-uri], хотя каноническое кодирование имен представляет собой последовательность пар (тип, строка октетов). К сегментам имен не предъявляется требований удобочитаемости или кодировки UTF-8. Первые несколько сегментов имени будут сопоставляться с FIB и протокол маршрутизации может вносить свои ограничения для компонент маршрутизируемого имени (например, максимальный размер или правила кодирования символов). В принципе сегменты имен и имена могут иметь неограниченный размер, хотя на практике они ограничиваются кодированием в линии и практическими соображениями протоколов маршрутизации. Отметим, что в CCNx для сегментов имен применяется двоичное сравнение, тогда как в URI — имена хостов сравниваются без учета регистра символов (обусловлено DNS).

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

CCNx является протоколом запросов и откликов, выбирающим блоки данных (chunk) по именам. Целостность каждого блока может быть подтверждена напрямую с помощью цифровой подписи или кода MAC9, а также опосредованно с помощью хэш-цепочек. Блоки также могут включать более слабые коды MIC10 или совсем не использовать защиты целостности. Поскольку информация об источнике передается в каждом блоке (или более крупном блоке с защитой целостности), больше не нужно полагаться на идентификацию хоста, такую как сертификат TLS, для подтверждения легитимности блока. Таким образом, целостность данных является основным свойством CCNx и не зависит от канала передачи данных. Имеется несколько вариантов защиты конфиденциальности, рассмотренных ниже.

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

Важная концепция CCNx заключается в том, что субъективное имя криптографически связывается с фиксированными данными (payload). Эти создаваемые издателями привязки можно проверить криптографическими методами. Именованные данные в результате являются кортежами {{Name, ExtraFields, Payload, ValidationAlgorithm}, ValidationPayload}, где все поля внутреннего кортежа учитываются в проверочных полях (например, в подписи). Потребители данных могут проверить целостность этих блоков путем выполнения расчета тех же криптографических хэш-значений и сравнения с цифровыми подписями в ValidationPayload.

В дополнение к цифровым подписям (например, RSA) CCNx поддерживает коды проверки подлинности (например, HMAC11) и целостности (например, CRC12). Для поддержки криптографических привязок следует применять по меньшей мере одну подпись или код аутентификации, но это требуется не для всех объектов. Например, первый объект с подписью может охватывать другие объекты с помощью хэш-цепочки, дерева Merkle или подписанного манифеста. Последующие объекты могут не иметь каких-либо проверок и полагаться лишь на ссылки. Код целостности (например, CRC) предназначен для обнаружения случайных повреждений в Interest.

CCNx задает сетевой протокол для объектов Interest (запросные сообщения) и Content (отклики) для переноса именованных данных. Interest включает поле Name, которое указывает желаемый отклик, и необязательные ограничения по соответствию, определяющие подходящие объекты Content. Имеется два ограничения — для идентификатора ключа (KeyIdRestr) и хэш-значения объекта Content (ContentObjectHashRestr). Первое ограничение для KeyId позволяет отобрать отклики с полем ValidationAlgorithm KeyId, соответствующим заданному значению. Второе ограничение позволяет выбрать отклики, в которых криптографическое хэш-значение совпадает с заданным ограничением. В разделе 9 описано применение этих ограничений при сопоставлении объектов Content с Interest.

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

Другая концепция CCNx заключается в наличии баланса между потоками сообщений Interest и Content Object. На уровне сети сообщение Interest, проходящее по одному пути, должно вызывать не более одного отклика Content Object. Если некоторые узлы передают Interest по разным путям, таким узлам следует объединять отклики, чтобы к запрашивающему приходил лишь один поток Content Object. При передаче Interest в широковещательном или групповом режиме, отправителю следует быть готовым к множеству откликов, если не применяется зависимый от среды механизм, такой как подавление «болтовни» или выбор ведущего.

По мере перемещения Interest в направлении следующей таблицы FIB устанавливается состояние на каждом узле пересылки, так что ответ Content Object может возвращаться к исходному запрашивающему (запрашивающим) без необходимости включения запрашивающей стороной маршрутизируемого адреса возврата. Применяется смысловая таблица PIT13 в качестве метода хранения состояний, упрощающих возврат Content Object.

Таблица PIT хранит последний интервал (hop) для Interest, а также поле Name и необязательные ограничения. Эти данные нужны для сопоставления Content Object с Interest (см. раздел 9). При поступлении Content Object он сопоставляется с PIT для определения подходящей записи. Для каждой такой записи передается не более одного Content Object в каждый указанный в таблице PIT последний интервал.

Реальные таблицы PIT не задаются данной спецификацией. Реализация может применять любой метод, обеспечивающий такое же внешнее поведение. Имеются исследовательские работы, где применялись методы, подобные коммутации по меткам в некоторых частях сети для снижения на узлах числа состояний, создаваемых PIT [dart]. Некоторые реализации хранят состояния PIT в FIB, не используя второй таблицы.

Если на узел приходит множество Interest с одинаковыми {Name, [KeyIdRestr], [ContentObjectHashRestr]} до прибытия Content Object, соответствующего первому Interest, они группируются в одну запись PIT и их последние интервалы (hop) агрегируются (см. параграф 2.4.2). Таким образом, один объект Content может соответствовать множеству ожидающих Interest в таблице PIT.

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

Этот документ описывает также управляющее сообщение Interest Return. Элемент сети может вернуть сообщение Interest Return на предыдущий интервал, если при обработке Interest возникла ошибка. Возвращенное сообщение может быть дополнительно обработано предыдущим интервалом или возвращено в направлении источника Interest. Когда узел возвращает Interest Return, он указывает, что предыдущему интервалу не следует ожидать от него отклика для Interest, т. е. на возвращающем узле нет записи PIT для Content Object.

Есть много способов описания более крупных объектов в CCNx. Агрегирование L3 Content Object в более крупные объекты выходит за рамки документа. Один из предложенных методов FLIC14 [flic] использует манифест для перечисления фрагментов большого объекта. Сами манифесты являются объектами Content. Другим вариантом является применение соглашений в именах Content Object как в протоколе CCNx Chunking [chunking], где большой объект дробится на мелкие блоки и каждый такой блок получает специальную компоненту имени, указывающую его порядковый номер. Один из экспериментальных протоколов фрагментирования BeginEnd Fragments [befrags] использует метод в стиле многоточечного PPP для работы через интерфейсы L2 с указанием сообщений CCNx [RFC8609] в форме TLV для кодирования в линии.

На основе этих концепций в оставшейся части документа определяется поведение узлов пересылки при обработке сообщений Interest, Content Object и Interest Return.

2. Протокол

В этом разделе определена грамматика сообщений CCNx (Interest, Content Object, Interest Return). Затем описано типичное поведение потребителей, издателей и узлов пересылки. В параграфе, посвященном пересылке, подробно описана обработка относящихся к пересылке вопросов, таких как HopLimit и Content Store, а также конвейеры обработки сообщений Interest и Content Object .

2.1. Грамматика сообщений

ABNF-грамматика [RFC5234] для сообщений CCNx показана на рисунке 1. Грамматика не включает разграничителей кодирования, таких как TLV. Кодирование в линиях представлено в отдельном документе. При наличии раздела Validation поле Validation Algorithm охватывает данные от Body (BodyName или BodyOptName) до конца раздела ValidationAlg. Поля InterestLifetime, CacheTime и Return Code не учитываются для проверки и могут быть изменены.

HashType, PayloadType и Private Enterprise Number (PEN) должны соответствовать значениям IANA в регистрах CCNx Hash Function Types, CCNx Payload Types [ccnx-registry] и Private Enterprise Numbers [eprise-numbers], соответственно.

Ниже представлены определения полей в алфавитном порядке.

AbsTime

Абсолютное время в виде 64-битового значения UTC в миллисекундах с начала эпохи (стандартное время POSIX).

CacheTime

Абсолютное время, при котором издатель будет считать кэшированный Content Object малоценным. Этот параметр рекомендуется для систем кэширования (см. раздел 4).

Cert

Некоторые приложения могут захотеть встраивать сертификат X.509 для проверки и обеспечения доверенной привязки. Cert представляет собой сертификат X.509 с кодированием DER.

ConObjField

Необязательные поля, которые могут присутствовать в объектах Content.

ConObjHash

Значение Content Object Hash, рассчитываемое с помощью SHA256-32 для сообщения от начала тела до конца сообщения. Отметим, что область охвата отличается от ValidationAlg. Значению не следует доверять за пределами домена (см. раздел 5).

ContentObjectHashRestr

Ограничение Content Object Hash. Объект Content должен хэшироваться до того же значения, что и ограничение, с использованием того же HashType. В ContentObjectHashRestr должно использоваться хэширование SHA256-32.

ExpiryTime

Абсолютное время, при котором Content Object следует считать устаревшим (см. раздел 4).

Hash

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

HashType

Алгоритм, используемый для расчета свертки (hash), который должен соответствовать одному из перечисленных в реестре IANA CCNx Hash Function Types [ccnx-registry].

HopLimit

Сообщения Interest могут попадать в петли, если они имеются на уровне пересылки. Для устранения влияния таких петель в каждом Interest содержится поле HopLimit, декрементируемое на каждом интервале. При достижении 0 сообщение не будет пересылаться. См. параграф 2.4.

InterestField

Необязательные поля, которые могут присутствовать в сообщении Interest.

KeyId

Идентификатор ключа, используемого в ValidationAlg. См описание Validation (раздел 8), где рассматривается использование ключей для кодов MAC и подписей.

KeyIdRestr

Ограничения KeyId. Объект Content должен иметь KeyId, значение которого совпадает с ограничением.

KeyLink

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

Lifetime

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

Name

Имя состоит из непустого первого сегмента, за которым могут следовать дополнительные сегменты возможно с нулевым размером. Сегменты имени являются не анализируемыми строками октетов и при использовании кодировки UTF-8 учитывается регистр символов. Объект Interest должен иметь имя (Name), Content Object может иметь Name (см. раздел 9). Сегменты имени называют полными, если они однозначно указывают один объект Content. Имя является точным, если его сегменты полны. Interest с полным именем — это объект, который указывает точное имя и ограничение Content Object Hash соответствующего Content Object.

Payload

Данные сообщения в соответствии с PayloadType.

PayloadType

Формат поля Payload. При отсутствии типа предполагается тип Data (T_PAYLOADTYPE_DATA) [ccnx-registry], означающий не анализируемые байты данных приложения. Тип Key (T_PAYLOADTYPE_KEY [ccnx-registry]) указывает DER-кодированный открытый ключ или сертификат X.509. Тип Link (T_PAYLOADTYPE_LINK [ccnx-registry]) указывает один или множество каналов (Link, см. раздел 6).

PublicKey

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

RelTime

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

ReturnCode

Указывает причины возврата сообщения Interest на предыдущий интервал (см. параграф 10.2).

SigTime

Абсолютное время создания подписи (UTC, в миллисекундах). Время подписи относится только к алгоритму проверки и не обязательно указывает момент создания проверяемого сообщения.

Vendor

Зависящие от производителя не анализируемые (opaque) данные. Данные Vendor включают IANA Private Enterprise Number [eprise-numbers], за которым следует заданная производителем информация. CCNx разрешает зависящие от производителя данные во многих местах.

Message       = Interest / ContentObject / InterestReturn
Interest      = IntHdr BodyName [Validation]
IntHdr        = HopLimit [Lifetime] *Vendor
ContentObject = ConObjHdr BodyOptName [Validation]
ConObjHdr     = [CacheTime / ConObjHash] *Vendor
InterestReturn= ReturnCode Interest
BodyName      = Name Common
BodyOptName   = [Name] Common
Common        = *Field [Payload]
Validation    = ValidationAlg ValidationPayload

Name          = FirstSegment *Segment
FirstSegment  = 1*OCTET / Vendor
Segment       = *OCTET / Vendor

ValidationAlg = (RSA-SHA256 / EC-SECP-256K1 / EC-SECP-384R1 /
                 HMAC-SHA256 / CRC32C) *Vendor
ValidationPayload = 1*OCTET
PublicAlg     = KeyId [SigTime] [KeyLink] [PublicKey] [Cert]
RSA-SHA256    = PublicAlg
EC-SECP-256K1 = PublicAlg
EC-SECP-384R1 = PublicAlg
HMAC-SHA256   = KeyId [SigTime] [KeyLink]
CRC32C        = [SigTime]

AbsTime       = 8OCTET ; 64-bit UTC msec since epoch
CacheTime     = AbsTime
ConObjField   = ExpiryTime / PayloadType
ConObjHash    = Hash
ExpiryTime    = AbsTime
Field         = InterestField / ConObjField / Vendor
Hash          = HashType 1*OCTET
HashType      = 2OCTET ; IANA "CCNx Hash Function Types"
HopLimit      = OCTET
InterestField = KeyIdRestr / ContentObjectHashRestr
KeyId         = Hash
KeyIdRestr    = Hash
KeyLink       = Link
Lifetime      = RelTime
Link          = Name [KeyIdRestr] [ContentObjectHashRestr]
ContentObjectHashRestr  = Hash
Payload       = *OCTET
PayloadType   = OCTET ; IANA "CCNx Payload Types"
PublicKey     = *OCTET ; DER-encoded public key
Cert          = *OCTET ; DER-encoded X.509 Certificate
RelTime       = 1*OCTET ; msec
ReturnCode    = OCTET ; см. параграф 10.2
SigTime       = AbsTime
Vendor        = PEN *OCTET
PEN           = 1*OCTET ; IANA "Private Enterprise Number"

Рисунок 1. ABNF-грамматика сообщений CCNx.

2.2. Поведение потребителя

Для запроса части содержимого данного кортежа {Name, [KeyIdRest], [ContentObjectHashRestr]} потребитель создает сообщение Interest с указанными значениями. Он может добавить раздел validation (обычно только CRC32C). Потребитель может включить поле Payload в сообщение Interest для отправки издателю в дополнение к имени. Имя служит для маршрутизации и может запоминаться на каждом интервале в смысловой таблице PIT для облегчения возврата Content Object. Сохранение большого числа состояний в имени ведет к высокому расходу памяти. Поскольку данные (payload) не рассматриваются при пересылке Interest или сопоставлении Content Object с Interest, потребителю следует включать Interest Payload ID (см. параграф 3.2) как часть имени, чтобы позволить пересылающему узлу сопоставить Interest с Content Object и предотвратить объединение Interest с разными данными. Точно также, если потребитель применяет MAC или подпись, ему следует включать уникальный сегмент как часть имени для предотвращения агрегирования Interest с другими сообщениями Interest или его удовлетворение объектом Content, не связанным с проверкой пригодности.

Потребителю следует указать время InterestLifetime, в течение которого он готов ждать отклика. Значение InterestLifetime определяется приложением, а не временем кругового обхода в сети (см. параграф 2.4.2). По умолчанию применяется InterestLifetime = 2 сек.

Потребителю следует установить подходящее значение Interest HopLimit или использовать принятое по умолчанию ограничение (255). Если потребителю известно число интервалов маршрутизации до издателя, следует указать его.

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

Сообщения Interest не обеспечивают надежной доставки. Потребителю следует применять транспортный протокол, который будет повторять безответные сообщения Interest, пока не пройдет время InterestLifetime. Транспортный протокол этим документом не задается.

Сеть может передать потребителю сообщение Interest Return, указывающее невозможность выполнить Interest. Значение ReturnCode указывает причину отказа, такую как отсутствие маршрута или перегрузка. В зависимости от ReturnCode потребитель может повторить Interest или вернуть ошибку запрашивающему приложению.

Если содержимое найдено и возвращено первому узлу пересылки, потребитель получит Content Object. Для проверки принятого Content Object потребитель использует приведенный ниже набор тестов.

  • Потребитель должен убедиться в корректности формата Content Object.

  • Потребитель должен проверить, что полученный Content Object соответствует одному или нескольким Interest, как описано в разделе 9.

  • Если Content Object подписан, потребителю следует криптографически проверить подпись в соответствии с разделом 8. При отсутствии нужного ключа потребителю следует получить его (например, от службы распространения ключей или через KeyLink).

  • Если подпись содержит SigTime, потребитель может использовать это значение для проверки действия подписи. Например, если потребитель запрашивает динамически создаваемое содержимое, ему следует ожидать, что значение SigTime будет не раньше времени создания Interest.

  • Если Content Object подписан, потребителю следует подтвердить доверие к ключу подписи для пространства имен. Эта процедура выходит за рамки документа, хотя можно использовать традиционные методы PKI, службы распространения доверенных ключей или методы, подобные [trust].

  • Потребитель может кэшировать Content Object для последующего использования вплоть до ExpiryTime, если это значение присутствует.

  • Потребитель может воспринять просроченный Content Object из линии. Срок действия пакета Content Object может завершиться в процессе передачи, если узлы пересылки не отбрасывают просроченные пакеты «на лету». Единственным требованием для просроченных объектов является недопустимость их размещения в Content Store или кэше, а издателям недопустимо отправлять просроченные Content Object.

2.3. Поведение издателя

Этот документ не задает методов заполнения именами таблиц FIB на узлах пересылки (см. параграф 2.4). Издатель настраивает один или множество префиксов имен, с которыми он может создавать содержимое, или выбирает префиксы имен и информирует уровень маршрутизации для анонсирования этих префиксов.

При получении издателем сообщения Interest ему следует выполнить указанные ниже действия.

  • Убедиться, что Interest является частью пространства имен издателя.

  • Если в Interest есть раздел Validation, нужно проверить его в соответствии с разделом 8. Обычно Interest включают лишь CRC32C, если приложение издателя явно не указывает восприятие других вариантов. Издатель может отбрасывать Interest с разделом Validation, если приложение издателя не ожидает таких подписей, поскольку это может быть формой атаки на отказ в обслуживании. Если подпись требует ключа, которого нет у издателя, ему не рекомендуется получать ключ из сети, когда это не является частью ожидаемого поведения приложения.

  • Нахождение или создание Content Object и возврат его на предыдущий интервал Interest. Если запрошенное содержимое не может быть возвращено, издателю следует ответить сообщением Interest Return или Content Object с данными, говорящими о недоступности содержимого. В такой объект Content следует включать малое значение ExpiryTime (в будущем) или 0 (чтобы его не кэшировали).

2.4. Поведение пересылающего узла

Пересылающий узел маршрутизирует сообщения Interest на основе таблицы пересылки (FIB), возвращает Content Object, соответствующие Interest, на предыдущий интервал Interest и обрабатывает управляющие сообщения Interest Return. Он может также сохранять кэш сообщений Content Object в смысловой таблице Content Store. Этот документ не задает внутреннего поведения узла пересылки, определяя лишь внешние характеристики.

В этом документе применяется два конвейера обработки — один для Interest, другой для Content Object. Обработка Interest состоит в проверке наличия дубликатов Interest в PIT (см. параграф 2.4.2), проверке наличия кэшированного Content Object в Content Store (см. параграф 2.4.3) и пересылке Interest на основе FIB. Обработка Content Store заключается в сопоставлении Interest с таблицей PIT и пересылке на предыдущий интервал.

2.4.1. Interest HopLimit

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

Петли могут также разрываться при агрегировании Interest с предыдущей записью PIT внутри петли. В этом случае Content Object будет отправлен назад по петле и может вернуться на узел, который уже переслал содержимое, где он скорей всего не будет иметь записи в PIT и будет отброшен. Может оказаться так, что новое или другое попавшее в петлю сообщение Interest вернется на тот же узел и в этом случае узел будет возвращать кэшированный отклик для создания новой записи PIT, как описано ниже.

HopLimit является последним средством устранения петель Interest, когда Content Object проходит в петле Interest, где промежуточные узлы по каким-то причинам больше не имеют записи в PIT и кэшированного Content Object.

Каждое сообщение Interest должно включать HopLimit. Сообщение Interest от локального приложения может иметь HopLimit = 0, что ограничивает Interest локальными источниками.

При получении Interest от другого узла пересылки значение HopLimit должно быть положительным — в противном случае пересылающий узел отбрасывает Interest. Пересылающий узел должен декрементировать HopLimit в Interest перед пересылкой по меньшей мере на 1.

Если после декрементирования HopLimit приобретает значение 0, сообщение Interest недопустимо пересылать другому узлу пересылки, но его можно передать локальному приложению издателя или обслужить из локального Content Store.

Рекомендуемый конвейер обработки HopLimit представлен ниже.

  • Если сообщение Interest получено от удаленной системы:

    • при HopLimit = 0 сообщение Interest отбрасывается и можно передать Interest Return (HopLimit Exceeded);

    • в остальных случаях HopLimit уменьшается на 1.

  • Выполняется обработка по правилам Content Store и Aggregation.

  • Если сообщение Interest будет пересылаться:

    • при (возможно декрементированном) HopLimit = 0, пересылка ограничивается локальной системой;

    • в остальных случаях сообщение пересылается локальной или удаленной системе.

2.4.2. Агрегирование Interest

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

CCNx использует правило агрегирования Interest, которое считает, что время InterestLifetime сродни времени подписки, а не кругового обхода в сети. В некоторых прежних правилах агрегирования срок действия считался временем кругового обхода и это создавало проблемы завершения срока действия Interest до прихода отклика, если значение RTT было недооценено или возникали конфликты со схемой автоматического повтора запросов (ARQ15), которая хотела повторить Interest, но для предыдущего Interest значение RTT было переоценено.

Узел пересылки может реализовать схему агрегирования Interest. Если это не делается, узел будет пересылать все сообщения Interest. Это не означает возврата множества (возможно идентичных) Content Object. Пересылающий узел должен по-прежнему выполнять все ожидающие запросы Interest, поэтому один Content Object может удовлетворять множеству похожих Interest, даже если узел пересылки не подавляет дубликаты Interest.

Рекомендуется приведенная ниже схема агрегирования Interest.

  • Два сообщения Interest считаются «похожими», если у них совпадают Name, KeyIdRestr и ContentObjectHashRestr, а отсутствующие в одном сообщении поля отсутствуют и в другом.

  • Разрешать совпадение двух смысловых значения InterestExpiry (локальные для пересылающего узла) со временем приема + InterestLifetime (или зависимое от платформы значение по умолчанию, если поле не задано).

  • Запись Interest (в таблице PIT) считается недействительной, если ее время InterestExpiry в прошлом.

  • Полученное первым сообщение Interest должно пересылаться.

  • Второе и последующие сообщения Interest, похожие на действительное ожидающее сообщение Interest, от того же предыдущего интервала должны пересылаться (это считается повтором передачи запроса).

  • Второе и последующие сообщения Interest, похожие на действительное ожидающее сообщение Interest, от другого предыдущего интервала можно агрегировать (не пересылать). Если это сообщение Interest имеет большее значение HopLimit, нежели ожидающее Interest, оно должно пересылаться.

  • Агрегирование Interest должно продлевать время InterestExpiry для записи Interest. Реализация может сохранять одно значение InterestExpiry для всех предыдущих интервалов или сохранять InterestExpiry независимо для каждого интервала. В первом случае пересылающий узел может передать Content Object по пути, где объект уже не ждут и в этом случае предыдущий интервал (следующий для Content Object) будет отбрасывать его.

2.4.3. Поведение хранилища содержимого

Content Store представляет собой специальный кэш, являющийся частью узла пересылки CCNx. Это хранилище не является обязательным и служит для исправления поврежденных пакетов и обработки множественных (flash) запросов популярного содержимого. Хранилище может заполняться заранее или содержать кэшированные данные. Поскольку Content Store можно использовать для усиления атак с помощью «отправления кэша», для Content Store применяются специальные правила, указанные ниже.

  1. Пересылающий узел может реализовать Content Store. В этом случае содержимое Content Store сопоставляется с Content Object для Interest по обычным правилам (см. раздел 9).

  2. Если Interest имеет ограничение KeyId, хранилище Content Store недопустимо использовать для ответа при отсутствии уверенности в корректности подписи совпадающего Content Object. Это можно проверить с помощью внешнего источника (например, в управляемой сети или системе с заранее заполненным кэшем) или путем получения открытого ключа для криптографической проверки подписи. От Content Store не требуется проверять подписи и отказ от предоставления непроверенного объекта просто считается его отсутствием.

  3. Если Content Store выбирает проверку подписей, это можно сделать, как описано далее. Если открытый ключ указан в самом Content Object (в поле PublicKey field) или в сообщении Interest, хранилище Content Store должно проверить совпадение хэш-значения открытого ключа с KeyId, а затем проверить подпись (см. параграф 8.4). Content Store может проверять цифровую подпись Content Object перед его кэшированием, но это не требуется. Хранилищу Content Store не следует получать ключи через сеть. Если подпись еще не проверена или ее невозможно проверить, следует считать Interest не кэшированным.

  4. Если Interest имеет ограничение Content Object Hash, хранилищу Content Store недопустимо отвечать на этот запрос, пока нет уверенности в наличии у Content Object корректного хэш-значения. Если проверка значения невозможна, Interest считается не кэшированным.

  5. Хранилище должно выполнять директивы управления кэшем (см. раздел 4).

2.4.4. Конвейер Interest

  1. Выполняется проверка HopLimit (см. параграф 2.4.1).

  2. Если Interest включает проверку пригодности, такую как MIC или подпись со встроенным открытым ключом или сертификатом, пересылающий узел может проверить Interest, как указано в разделе 8. Пересылающему узлу не следует получать ключ через KeyLink. Если пересылающий узел отбрасывает Interest в результате проверки, он может передать Interest Return (параграф 10.3.9).

  3. Определяется возможность агрегирования Interest, как указано в параграфе 2.4.2. Если агрегирование возможно, оно выполняется и Interest не пересылается.

  4. При пересылке Interest проверяется его наличие в Content Store, как описано в параграфе 2.4.3. Если соответствующий Content Object найден, он возвращается на предыдущий интервал Interest и объект помещается в Content Store, как описано в параграфе 2.4.5.

  5. Выполняется просмотр Interest в таблице FIB с поиском максимально длинного префикса (LPM16) по сегментам имени (а не по байтам или битам). Предыдущий интервал Interest следует исключать. Если найдено соответствие, сообщение Interest пересылается. Если соответствия не найдено или узел решил не пересылать сообщение по локальным условиям (например, перегрузка), ему следует передать сообщение Interest Return, как указано в разделе 10.

2.4.5. Конвейер объектов Content

  1. Пересылающему узлу, получившему Content Object, рекомендуется проверить, что Content Object принят от ожидаемого предыдущего узла. На этот узел указывает FIB или запись в PIT, которая имеет совпадающее сообщение Interest, отправленное по этому пути.

  2. Объект Content должен соответствовать всем ожидающим запросам Interests, которые удовлетворяют правилам сопоставления (см. раздел 9). Каждый удовлетворяющий запрос Interest должен удаляться из числа ожидающих Interest.

  3. Пересылающему узлу не следует передавать более одной копии полученного Content Object на один предыдущий интервал Interest. Например, может случиться так, что два Interest запрашивают один Content Object по-разному (например, по имени или KeyId и имени) и оба объекта придут от одного предыдущего интервала. Нормально передавать несколько раз один Content Object через один интерфейс (например, Ethernet), если он передается на разные предыдущие интервалы.

  4. Content Object следует помещать в Content Store лишь в том случае, когда он удовлетворяет Interest (см. п. 1 выше). Это снизит вероятность отравления кэша.

3. Имена

Имя CCNx состоит из нескольких сегментов, каждый из которых содержит метку, указывающую цель сегмента и его значение. Например, некоторые сегменты являются именами общего назначения, а другие служат для определенных целей, таких как передача информации о версии или упорядочение множества блоков большого объекта в мелкие подписанные Content Object.

В CCNx имеется три разных типа имен — префиксы, точные и полные имена. Префикс является просто именем, которое однозначно указывает не один Content Object, а скорее пространство имен или префикс существующего имени Content Object. Точное имя однозначно указывает Content Object. Полное имя включает точное имя и сопровождающее его явное или неявное значение ConObjHash. Явные ConObjHash используются в Interest, неявные — в Content Object.

Отметим, что узлам пересылки не нужно знать семантику имен. Они должны лишь быть способны сопоставлять префиксы для пересылки Interest и точное или полное имя — для пересылки Content Object. Узлы пересылки не чувствительны к типам сегментов.

Метки сегментов имен, заданных в этом документе, представлены в таблице 1. Name Segment является сегментом общего назначения, Interest Payload ID указывает данные Interest, а Application Components представляет набор типов сегментов имен, зарезервированных для приложений.

Таблица 1. Типы сегментов имен CCNx.

Тип

Описание

Name Segment

Базовый сегмент имени, включающий произвольные октеты.

Interest Payload ID

Строка октетов, указывающая данные, переносимые в Interest. Например, Payload ID может быть хэш-значением Interest Payload. Это позволяет различать Interest через сегмент имени без включения самих байтов данных.

Application Components

Специфичные для приложения данные в сегменте имени. Приложение может использовать свою семантику компонент. Хорошим тоном является указание приложения в сегменте имени перед сегментами компонент приложения.

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

3.1. Примеры имен

В этом параграфе используется представление CCNx URI [ccnx-uri] для имен CCNx. Отметим, что эта грамматика применяется на уровне сообщения и у Interest должно быть поле Name хотя бы с одним сегментом имени, который должен иметь не менее 1 октета в значении. У Content Object должно быть похожее имя или совсем не быть имени. FIB может иметь имена размером 0 (принятый по умолчанию маршрут), первый сегмент без значения или обычное имя.

Таблица 2. Примеры имен CCNx.

Имя

Описание

ccnx:/

Пустое (0-length) имя, соответствующее принятому по умолчанию маршруту.

ccnx:/NAME=

Имя с 1 сегментом нулевого размера. Отличается от ccnx:/.

ccnx:/NAME=foo/APP:0=bar

2-сегментное имя, где первый сегмент имеет тип NAME, а второй — APP:0.

3.2. Идентификатор данных Interest

Interest может включать поле Payload, в котором передается состояние Interest, не используемое для сопоставления с Content Object. Если Interest содержит данные, в имя Interest следует включать Interest Payload ID (IPID). Значение IPID позволяет записи PIT корректно мультиплексировать Content Object в ответ на конкретные Interest с конкретным идентификатором данных. IPID можно выводить из хэш-значения данных, а также применять уникальный идентификатор GUID17 или одноразовое значение (nonce). Необязательное поле Metadata определяет поле IPID так, чтобы другие системы могли проверить его (например, при выводе из хэш-значения). Проверка IPID не требуется.

4. Управление кэшем

CCNx поддерживает два поля для воздействия на управление кэшем, управляющие обработкой Content Object в кэше или Content Store. Они не применяются в быстром пути и служат лишь для определения возможности внедрения Content Object в быстрый путь при отклике на Interest.

Поле ExpiryTime используется в «конверте» подписи Validation Algorithm. Оно указывает время UTC в миллисекундах, после которого Content Object считается устаревшим и должен больше не применяться в откликах на Interest из кэша. Устаревшее содержимое может исключаться из кэша.

Поле RCT18 размещается за пределами конверта подписи и указывает время UTC в миллисекундах, по достижении которого издатель будет считать Content Object малоценным для кэша. Системе кэширования следует отбрасывать объекты после RCT, хотя их можно хранить и применять в откликах. Кэш может отбросить Content Object до RCT — нет никаких обязательств по хранению объектов.

Эта формулировка позволяет издателю создавать объекты Content с большим ExpiryTime, но коротким RCT, снова и снова переиздавая один и тот же подписанный Content Object с расширением RCT. Это позволяет издателю периодически видеть, что содержимое продолжает использоваться.

5. Хэш Content Object

CCNx позволяет сообщениям Interest ограничивать отклик определенным хэшем, который учитывает тело сообщения Content Object и разделы проверки, если они имеются. Таким образом, для подписанного Content Object хэш будет учитывать значение подписи. Хэш не включает фиксированные и поэтапно добавляемые заголовки Content Object. Поскольку это является частью правил сопоставления (см. раздел 9), хэш применяется на каждом интервале.

Имеется два варианта сопоставления с ограничением Content Object Hash в Interest. Во-первых, узел пересылки может рассчитывать для себя хэш-значение и сравнивать его с ограничением, однако это ресурсоемкая операция. Вторым вариантом является расчет хэш-значения на граничном устройстве и его размещение в заголовке (ConObjHash), передаваемом через сеть. Этот вариант не обеспечивает защиты сопоставления, поэтому его следует применять лишь в доверенных средах. Заголовок следует удалять на границе доверенной области.

6. Канал

Link представляет собой кортеж {Name, [KeyIdRestr], [ContentObjectHashRestr]}, информация которого состоит из полей Interest, определяющих цель Link. Content Object с PayloadType = Link является объектом, данными которого является один или несколько каналов (Link). Этот кортеж может применяться в качестве KeyLink для указания конкретного объекта с «обернутым» сертификатом ключом. Рекомендуется включать хотя бы одно ограничение KeyId или Content Object Hash. Если таких ограничений нет, от издателя может быть возвращен любой Content Object с совпадающим именем.

7. Хэш-значения

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

В этом документе предложены несколько функций хэширования (например, SHA-256), но конкретная реализация может применять функцию, которая кажется лучшей. Нормативную спецификацию сообщений CCNx [RFC8609] следует считать определением подходящих функций и их использования.

8. Проверка пригодности

8.1. Алгоритм проверки

Validator включает раздел ValidationAlgorithm, задающий способ проверки сообщения, и ValidationPayload с выводом проверки (например, цифровая подпись или MAC). Раздел ValidationAlgorithm определяет тип используемого алгоритма и включает требуемую дополнительную информацию. Проверка выполняется от начала сообщения CCNx до конца раздела ValidationAlgorithm (т. е. до данных проверки, но без их включения). Это называется областью проверки. ValidationPayload содержит байты значения контроля целостности, такие как MAC или подпись.

Грамматика сообщения CCNx (параграф 2.1) показывает разрешенные алгоритмы и их структуру. Для случая алгоритма Vendor производитель может использовать любую желаемую структуру. Validator может применяться лишь к Interest и Content Object, но не к Interest Return. Interest внутри Interest Return будет иметь исходное поле проверки, если оно есть.

Грамматика разрешает множество расширений Vendor для алгоритма проверки. Производитель должен описать область проверки для каждого расширения. Например, производитель может использовать обычную подпись в алгоритме проверки, затем добавить фирменный код MIC для обнаружения ошибок в сети без применения дорогостоящей проверки подписи. Данная спецификация не разрешает использовать несколько блоков Validation Algorithm за пределами фирменных методов.

8.2. Коды целостности сообщений

Если алгоритмом проверки служит CRC32C, данные проверки являются выводом CRC для проверяемой области. Этот алгоритм разрешает необязательную временную метку момента подписи (SigTime) при проверке сообщения (не совсем корректно называется «временем подписи», но здесь для этих целей применяется одно поле в MIC, MAC и подписях).

Коды MIC обычно применяются с Interest для предотвращения непреднамеренного повреждения в сети. Они обычно не используются с Content Object, поскольку объекты как правило подписаны или связаны с хэш-цепочкой, поэтому значение CRC32C избыточно.

8.3. Коды аутентификации сообщений

Если для проверки применяется алгоритм HMAC-SHA256, проверочными данными служит вывод HMAC для области проверки. Алгоритм проверки требует KeyId и разрешает SigTime и KeyLink.

Поле KeyId указывает общий секрет, используемый двумя сторонами для аутентификации сообщений. Эти секреты следует выводить из протокола обмена ключами, такого как [ccnx-ke]. KeyId для общего секрета следует быть неанализируемым идентификатором, который не выводится из реального ключа (хорошим выбором, например, будет целочисленный счетчик).

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

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

8.4. Подпись

Для проверки подписи применяются криптографические алгоритмы с открытым ключом, такие как RSA и ECDSA19. Данная спецификация и документ по кодированию [RFC8609] поддерживают лишь 3 конкретных алгоритма — RSA-SHA256, EC-SECP-256K1 и EC-SECP-384R1. Дополнительные алгоритмы могут применяться на основе других документов или с использованием экспериментальных и фирменных типов.

Для подписи на основе открытого ключа требуется поле KeyId и она может включать время подписи, встроенный открытый ключ и KeyLink. Время подписи является обычной временной меткой момента создания подписи. Применение этого поля и его взаимодействие с другими полями описано ниже.

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

Поле KeyId в ValidationAlgorithm указывает открытый ключ, применяемый для проверки подписи. Он похож на Subject Key Identifier в X.509 (параграф 4.2.1.2 [RFC5280]). KeyId определен как криптографическое хэш-значение открытого ключа в форме DER. Все реализации должны поддерживать SHA-256 для хэширования KeyId.

Использование других алгоритмов для KeyId разрешено и не будет вызывать проблем на узлах пересылки, поскольку эти узлы сопоставляют лишь алгоритм и его результат, не выполняя самих вычислений (см. раздел 9). Могут возникать проблемы с Content Store, поскольку хранилищу нужно проверять соответствие KeyId и PublicKey (см. параграф 2.4.3), хотя в этом случае может происходить лишь потеря кэша и сообщение Interest будет пересылаться издателю. Пока издатель и потребитель поддерживают хэш, данные будут проверяемы.

В соответствии с разделом 9, пересылающий узел сопоставляет лишь KeyId с ограничениями для него. Ему не нужно смотреть такие поля, как открытый ключ, сертификат или KeyLink.

Если в сообщении имеется несколько KeyId, открытых ключей, сертификатов или KeyLink, конечная точка (потребитель, кэш или Content Store) должна обеспечить согласованность этих полей. Поле KeyId должно быть соответствующим хэш-значением встроенного открытого ключа или открытого ключа сертификата. Хэш-функцией является HashType из KeyId. Если есть встроенный открытый ключ и сертификат, открытые ключи должны совпадать.

Сообщению не следует иметь PublicKey и KeyLink для открытого ключа, поскольку это избыточно. Оно может иметь PublicKey и KeyLink для сертификата.

KeyLink в первом Content Object может указывать на второй Content Object с DER-представлением открытого ключа в поле PublicKey и необязательным DER-представлением сертификата X.509 в поле данных (payload). KeyId второго Content Object должен совпадать с KeyId первого объекта. Поле PublicKey второго объекта должно быть открытым ключом, соответствующим KeyId. Этот ключ должен проверять пригодность подписей первого и второго объекта. Сертификат X.509 в форме DER может быть включен в данные второго объекта, а его встроенный открытый ключ должен соответствовать PublicKey. Он должен быть выдан доверенным центром, предпочтительно задающим действительное пространство имен ключа в отличительном имени. Второму объекту недопустимо иметь KeyLink, поскольку рекурсивный поиск ключа не разрешен.

9. Сопоставление Interest и Content Object

Content Object соответствует запросу Interest тогда и только тогда, когда (a) имя Content Object при его наличии совпадает с именем Interest, (b) ValidationAlgorithm KeyId в Content Object совпадает с ограничением Interest KeyId при наличии и (c) рассчитанное значение Content Object Hash совпадает с ограничением Interest Content Object при наличии.

KeyId и KeyIdRestr используют формат Hash (см. параграф 2.1), имеющий встроенное поле HashType, за которым следует хэш-значение. При сравнении KeyId и KeyIdRestr сравниваются HashType и значение.

Правила сопоставления задаются утверждением, значение true в котором означает, что Content Object соответствует Interest, Ni = Name в Interest (не может быть пустым), Ki = KeyIdRestr в Interest (может быть пустым), Hi = ContentObjectHashRestr в Interest (может быть пустым). No, Ko и Ho являются свойствами Content Object, где No и Ko могут быть пустыми, а Ho существует всегда (это внутреннее свойство Content Object). Для двоичных выражений используются символы & (AND) и | (OR), E означает оператор существования (не пусто), а ! — оператор отсутствия.

В особом случае, когда ограничение Content Object Hash в Interest задает не поддерживаемый алгоритм хэширования, Content Object не может соответствовать Interest, поэтому системе следует отбросить Interest и можно передать Interest Return на предыдущий интервал. В этом случае приведенное ниже утверждение никогда не выполняется, поскольку Interest не пересылается. Если система использует необязательное поведение, заключающееся в том, что другая система рассчитывает хэш для нее, эта система может предполагать поддержку всех хэш-функций и оставлять другой системе решение вопроса о восприятии или отклонении Interest.

   (!No | (Ni=No)) & (!Ki | (Ki=Ko)) & (!Hi | (Hi=Ho)) & (E No | E Hi)

Как можно видеть, имеется два типа атрибутов, которые могут совпадать. Первое совпадение зависит от наличия атрибута в Content Object, а два следующих — от наличия атрибута в Interest. Последним совпадением является ограничение Nameless Object (безымянный объект), которое говорит, что Content Object, не имеющий Name, должен соответствовать Interest хотя бы по ограничению Hash.

Если Content Object не содержит Content Object Hash в явном виде, хэш-значение должно рассчитываться в сети для сопоставления. В автономной системе достаточно рассчитать Content Object Hash на граничном маршрутизаторе и передавать его доверенным способом внутри автономной системы. Если ValidationAlgorithm в Content Object не имеет KeyId, этот объект Content не может соответствовать Interest с ограничением KeyId.

10. Возврат Interest

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

Возвращаемое сообщение совместимо с имеющимся форматом пакетов TLV (фиксированный заголовок, необязательные поэтапные заголовки и тело сообщения CCNx). Возвращаемый пакет Interest имеет лишь 2 отличия:

  • в PacketType устанавливается Interest Return для индикации сообщения Feedback;

  • в ReturnCode указывается подходящее значение для обозначения причины возврата.

Детали кодирования Interest Return указаны в [RFC8609].

Пересылающий узел не обязан передавать какие-либо сообщения Interest Return.

Пересылающий узел не обязан обрабатывать полученные сообщения Interest Return. Если он не может обработать Interest Return, следует просто отбросить сообщение.

Сообщения Interest Return не применяются к Content Object и другим типам сообщений.

Сообщение Interest Return передается между партнерами одного интервала (1-hop) и не распространяется через множество интервалов с применением FIB. Промежуточный узел, получивший Interest Return, может выполнить корректирующие действия или передать свое сообщение Interest Return на предыдущий интервал, указанный в пути возврата записи PIT.

10.1. Формат сообщения

Сообщение Interest Return выглядит как исходное сообщение Interest, отличаясь лишь двумя отмеченными выше изменениями. Поле PacketType устанавливается для индикации типа сообщения Interest Return, а резервный байт в заголовке Interest служит кодом возврата. Значения PacketType и ReturnCode приведены в [RFC8609].

10.2. Типы ReturnCode

В этом параграфе описаны коды возврата Interest Return (ReturnCode), определенные в данном RFC. Численные значения кодов, используемые в пакетах, определены в [RFC8609].

Таблица 3. Коды причин Interest Return.

Имя

Описание

No Route (параграф 10.3.1)

Возвращающий узел пересылки не имеет пути к имени в Interest.

HopLimit Exceeded (параграф 10.3.2)

Значение HopLimit уменьшено до 0, но требуется пересылка пакета.

Interest MTU too large (параграф 10.3.3)

MTU для Interest не соответствует требуемому минимуму и нужна фрагментация.

No Resources (параграф 10.3.4)

Узел не имеет ресурсов для обработки Interest.

Path error (параграф 10.3.5)

Ошибка передачи при пересылке Interest по маршруту (временная ошибка).

Prohibited (параграф 10.3.6)

Административные настройки запрещают обработку Interest.

Congestion (параграф 10.3.7)

Сообщение Interest отброшено по причине перегрузки (временная ошибка).

Unsupported Content Object Hash Algorithm (параграф 10.3.8)

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

Malformed Interest (параграф 10.3.9)

Сообщение Interest отброшено по причине невозможности корректного разбора.

10.3. Протокол возврата Interest

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

Если узел пересылки получает Interest Return, ему следует выполнить стандартные корректировочные действия. Узлу разрешено игнорировать сообщения Interest Return, при этом для записи PIT действует обычная процедура тайм-аута.

  • Проверка прибытия Interest Return со следующего интервала, на который было реально передано Interest.

  • Если записи PIT для соответствующего Interest нет, узлу пересылки следует игнорировать Interest Return.

  • Если запись PIT для соответствующего Interest имеется, узел может выбрать один из двух вариантов:

    • попробовать другой путь пересылки при его наличии и отбросить Interest Return;

    • сбросить состояние PIT и передать Interest Return по пути возврата.

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

При использовании узлом пересылки дополнительных маршрутов он может получить второе сообщение Interest Return возможно другого типа, нежели первое сообщение Interest Return. Например, узел A передал Interest для узла B, который вернул сообщение No Route. Затем узел A пытается передать сообщение через узел C, который возвращает Prohibited Interest Return. Узлу A следует выбрать подходящий код для отправки своему предыдущему интервалу.

При использовании узлом пересылки дополнительных маршрутов ему следует декрементировать Interest Lifetime с учетом времени, уже затраченного на обработку Interest.

10.3.1. No Route

Если узел пересылки получает Interest, для которого нет маршрута или существует лишь маршрут назад к передавшей Interest системе, узлу пересылки следует генерировать сообщение Interest Return No Route.

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

10.3.2. HopLimit Exceeded

Узел пересылки может передавать сообщения HopLimit Exceeded при получении сообщений Interest с HopLimit = 0, которые нужно пересылать.

10.3.3. Interest MTU Too Large

Если узел пересылки получает сообщение Interest, в котором MTU превышает предписанный минимум, узел может передать сообщение Interest MTU Too Large или просто отбросить Interest.

Если узел пересылки получает отклик Interest MTU Too Large, ему не следует пробовать другие пути. Следует передать это сообщение Interest Return на предыдущий интервал.

10.3.4. No Resources

Если узел пересылки получает сообщение Interest и не может его обработать по причине нехватки ресурсов, он может передать сообщение No Resources. Нехватка ресурсов может быть связана с размером PIT или иными ограничениями.

10.3.5. Path Error

Если узел пересылки обнаруживает ошибку при пересылке Interest (например, через надежный канал), он может передать сообщение Path-Error, указывающее неспособность устранить ошибку при пересылке.

10.3.6. Prohibited

Узел пересылки может иметь административные правила, такие как списки контроля доступа (ACL20), которые препятствуют приему или пересылке Interest. Если узел отбрасывает Interest на основании правил, он может передать сообщение Prohibited на предыдущий интервал. Например, при наличии ACL, разрешающего получать /example/private только на интерфейсе e0, но полученном на e1, узел должен иметь способ вернуть Interest с указанием причины.

10.3.7. Congestion

Узел пересылки, отбрасывающий Interest по причине перегрузки, может передать Congestion на предыдущий интервал.

10.3.8. Unsupported Content Object Hash Algorithm

Если ограничение Content Object Hash задает алгоритм хэширования, который узел пересылки не может проверить, Interest не следует воспринимать и узел может передать Interest Return на предыдущий интервал.

10.3.9. Malformed Interest

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

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

Этот документ не задает действий IANA.

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

CCNx является протоколом сетевого уровня (L3), котрый может работать в режиме наложения с использованием такого транспорта, как UDP или туннели. Протокол имеет встроенную поддержку аутентификации сообщений с помощью подписи (например, RSA или эллиптическая кривая) или кода аутентификации (например, HMAC). Взамен аутентификатора может применяться проверка целостности сообщения (например, SHA или CRC). CCNx не определяет «конверт» шифрования, оставляя это вышележащим протоколам (например, [esic]).

Формат сообщений CCNx позволяет присоединить MIC (например, CRC32C), MAC (например, HMAC) и подписи (например, RSA или ECDSA) к пакетам любого типа. Это не означает, что хорошей идеей будет использовать произвольный ValidationAlgorithm или включать ресурсоемкие алгоритмы в пакеты Interest, поскольку это может приводить к DoS-атакам за счет вычислений. Приложениям следует использовать явный протокол для руководства применением подписей пакетов. В качестве общего руководства приложения могут использовать MIC в сообщениях Interest для обнаружения непреднамеренно поврежденных пакетов. Если нужна защита Interest, следует рассмотреть возможность шифрования и протокол, предотвращающий атаки с повторным использованием, особенно при использовании Interest в качестве исполнительного механизма (actuator). Простое применение кода аутентификации или подписи не обеспечивает защиты Interest. В литературе имеется несколько примеров защиты обмена сообщениями в стиле ICN [mobile] [ace].

Поскольку документ относится к протоколу L3, он не описывает способов доставки ключей и механизмов доверия к ним. Content Object в CCNx может включать открытый ключ или сертификат, а также может использовать поле KeyLink для указания открытого ключа или сертификата для проверки подлинности сообщения. Одной из спецификаций обмена ключами является CCNxKE [ccnx-ke] [mobile], где обмен похож на процедуру TLS 1.3, отличаясь тем, что происходит через сообщения CCNx L3. Вопросы доверия выходят за рамки протокола L3 и решаются приложениями.

Комбинация обмена эфемерными ключами (например, CCNxKE [ccnx-ke]) с инкапсулирующим шифрованием (например, [esic]) обеспечивает эквивалент туннеля TLS. Промежуточные узлы могут пересылать сообщения Interest и Content Object, но не будут видеть их содержимого. Это также полностью скрывает внутренние имена, заменяя их именами, используемыми уровнем шифрования. Этот тип туннельного шифрования полезен для передачи содержимого, которое мало или совсем не подходит для кэширования, поскольку оно может применяться лишь теми, кто знает эфемерный ключ. Краткосрочное кэширование может помочь на каналах с потерями, но длительное кэширование обычно не представляет интереса.

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

Конкретное кодирование сообщений будет влиять на безопасность. В [RFC8609] применяется кодирование TLV. Был выбран компромисс между расширяемостью и однозначностью кодирования типа и размера. Некоторые TLV используют поля T и L переменного размера, чтобы вместить более широкий диапазон значений с сохранением эффективного использования байтов. Здесь TLV кодируются с 2-байтовыми полями T и L, что решает 2 проблемы. Первая проблема связана с псевдонимами. Если можно кодировать одно значение в полях разного размера (например, %x02 и %x0002), кто-то может счесть их одним, а другой — разными. Если есть различие, оно должно определяться в буферах, а не числовом представлении. Если от этого отказаться, придется проверять кодирование TLV в каждом поле каждого пакета на всех узлах пересылки. Если они одинаковы, возникает другая проблема — как задавать фильтры. Например, если имя включает 6 компонент, имеется 7 полей T и 7 полей L, каждое из которых может иметь до 4 представлений одного значения. В результате имеется 14 полей с 4 представлениями для каждого или «1001 комбинация». Это также означает невозможность сравнения, например, имени через функции памяти, поскольку нужно учитывать разные форматы T и L.

Сообщение Interest Return не имеет аутентификатора от предыдущего интервала. Поэтому данные из Interest Return следует применять лишь локально для сопоставления с Interest. Узлу не следует пересылать эти Interest Payload как Interest. Он должен также убедиться, что передал Interest в Interest Return нужному узлу и не позволять кому-либо отменять сообщения Interest.

Кэширующие узлы должны соблюдать осторожность при обработке Content Object. Важно, чтобы хранилище Content Store следовало правилам параграфа 2.4.3 во избежание некоторых типов атак. CCNx 1.0 не имеет механизмов обхода нежелательных результатов из сети (нет «исключений»), поэтому при отравлении кэша непригодным содержимым это может вызвать проблемы при поиске. Существует 3 типа доступа к содержимому из Content Store — неограниченный, а также ограниченные подписью и хэш-значением. Если Interest не имеет ограничений, запрашивающая сторона не заботится о том, что она получит в ответ и подойдет любой кэшированный объект. При ограничении по хэш-значению запрашивающая сторона очень точно определяет желаемый результат и Content Store (и каждый пересылающий узел) может легко проверить соответствие содержимого запросу. При ограничении подписью (часто служит для начального обнаружения манифеста) запрашивающий знает лишь KeyId для подписи содержимого. Этот случай требует пристального внимания в Content Store, чтобы избежать усиления неверных данных. Хранилище Content Store должно отвечать лишь объектами Content с проверенной подписью. Это значит, что Content Object содержит в себе открытый ключ или Interest передает открытый ключ в дополнение к KeyId. Если это не выполняется, хранилищу Content Store следует рассматривать Interest как отсутствие кэша и позволять конечной точке ответить.

Кэш пользовательского уровня может выполнять полную проверку подписи путем извлечения открытого ключа или сертификата по KeyLink. Однако это не та задача, которую можно отдать узлу пересылки. Пользовательский кэш может также полагаться на внешнюю (out-of-band) аттестацию, например, если оператор кэша включает лишь информацию, для которой у него есть корректная подпись.

Грамматика CCNx обеспечивает гибкость алгоритма хэширования с помощью HashType, указывая список приемлемых алгоритмов, которые следует реализовать на каждом узле пересылки. Некоторые типы пригодны лишь для конечных систем и обновление их не влияет на узлы пересылки, которые будут просто сопоставлять буферы, включающие type-length-hash. Некоторые поля (например, ConObjHash) должны проверяться на каждом узле, поэтому узел пересылки (или связанная с ним система) должен знать алгоритм хэширования. Это может вызвать проблемы совместимости при смене типа хэша. [RFC8609] является официальным источником данных о разрешенных типах хэширования.

Для имен CCNx применяется двоичное сопоставление, тогда как для URI сравниваются имена хостов без учета регистра. Некоторые системы могут применять независимое от регистра сопоставление путей URI к ресурсу. В результате введенные человеком имена CCNx будут скорей всего сталкиваться с несоответствием символов разных регистров и символов не-ASCII, если не применять нормализацию URI для имен CCNx. Это означает, что объект, регистрирующий маршрутизируемый префикс CCNx, скажем ccnx:/example.com, должен зарегистрировать варианты типа ccnx:/Example.com. Если это не учтено в нормализации URI и соглашениях протокола маршрутизации, становятся возможными фишинговые атаки.

Более общее рассмотрение вопросов безопасности ICN приведено в [RFC7927] и [RFC7945].

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

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

[RFC2119] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC8174] Leiba, B., «Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words», BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

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

[ace] Shang, W., Yu, Y., Liang, T., Zhang, B., and L. Zhang, «NDN-ACE: Access Control for Constrained Environments over Named Data Networking», NDN Technical Report NDN-0036, December 2015, <http://new.named-data.net/wp-content/uploads/2015/12/ndn-0036-1-ndn-ace.pdf>.

[befrags] Mosko, M. and C. Tschudin, «ICN «Begin-End» Hop by Hop Fragmentation», Work in Progress, draft-mosko-icnrg-beginendfragment-02, December 2016.

[ccn-lite] Tschudin, C., et al., «CCN-lite», University of Basel, 2011-2019, <http://ccn-lite.net>.

[ccnx-ke] Mosko, M., Uzun, E., and C. Wood, «CCNx Key Exchange Protocol Version 1.0», Work in Progress, draft-wood-icnrg-ccnxkeyexchange-02, March 2017.

[ccnx-registry] IANA, «Content-Centric Networking (CCNx)», <https://www.iana.org/assignments/ccnx>.

[ccnx-uri] Mosko, M. and C. Wood, «The CCNx URI Scheme», Work in Progress, draft-mosko-icnrg-ccnxurischeme-01, April 2016.

[chunking] Mosko, M., «CCNx Content Object Chunking», Work in Progress, draft-mosko-icnrg-ccnxchunking-02, June 2016.

[cicn] FD.io, «Community ICN (CICN)», February 2017, <https://wiki.fd.io/index.php?title=Cicn&oldid=7191>.

[dart] Garcia-Luna-Aceves, J. and M. Mirzazad-Barijough, «A Light-Weight Forwarding Plane for Content-Centric Networks», International Conference on Computing, Networking, and Communications (ICNC), DOI 10.1109/ICCNC.2016.7440637, February 2016, <https://arxiv.org/pdf/1603.06044.pdf>.

[eprise-numbers] IANA, «IANA Private Enterprise Numbers», <https://www.iana.org/assignments/enterprise-numbers>.

[esic] Mosko, M. and C. Wood, «Encrypted Sessions In CCNx (ESIC)», Work in Progress, draft-wood-icnrg-esic-01, September 2017.

[flic] Tschudin, C. and C. Wood, «File-Like ICN Collection (FLIC)», Work in Progress, draft-tschudin-icnrg-flic-03, March 2017.

[mobile] Mosko, M., Uzun, E., and C. Wood, «Mobile Sessions in Content-Centric Networks», IFIP Networking Conference (IFIP Networking) and Workshops, DOI 10.23919/IFIPNetworking.2017.8264861, June 2017, <https://dl.ifip.org/db/conf/networking/networking2017/1570334964.pdf>.

[ndn] UCLA, «Named Data Networking», 2019, <https://www.named-data.net>.

[nnc] Jacobson, V., Smetters, D., Thornton, J., Plass, M., Briggs, N., and R. Braynard, «Networking Named Content», Proceedings of the 5th International Conference on Emerging Networking Experiments and Technologies, DOI 10.1145/1658939.1658941, December 2009, <https://dx.doi.org/10.1145/1658939.1658941>.

[RFC5234] Crocker, D., Ed. and P. Overell, «Augmented BNF for Syntax Specifications: ABNF», STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <https://www.rfc-editor.org/info/rfc5234>.

[RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, «Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile», RFC 5280, DOI 10.17487/RFC5280, May 2008, <https://www.rfc-editor.org/info/rfc5280>.

[RFC7927] Kutscher, D., Ed., Eum, S., Pentikousis, K., Psaras, I., Corujo, D., Saucez, D., Schmidt, T., and M. Waehlisch, «Information-Centric Networking (ICN) Research Challenges», RFC 7927, DOI 10.17487/RFC7927, July 2016, <https://www.rfc-editor.org/info/rfc7927>.

[RFC7945] Pentikousis, K., Ed., Ohlman, B., Davies, E., Spirou, S., and G. Boggia, «Information-Centric Networking: Evaluation and Security Considerations», RFC 7945, DOI 10.17487/RFC7945, September 2016, <https://www.rfc-editor.org/info/rfc7945>.

[RFC8609] Mosko, M., Solis, I., and C. Wood, «Content-Centric Networking (CCNx) Messages in TLV Format», RFC 8609, DOI 10.17487/RFC8609, July 2019, <https://www.rfc-editor.org/info/rfc8609>.

[selectors] Mosko, M., «CCNx Selector Based Discovery», Work in Progress, draft-mosko-icnrg-selectors-01, May 2019.

[terminology] Wissingh, B., Wood, C., Afanasyev, A., Zhang, L., Oran, D., and C. Tschudin, «Information-Centric Networking (ICN): CCN and NDN Terminology», Work in Progress, draft-irtf-icnrg-terminology-04, June 2019.

[trust] Tschudin, C., Uzun, E., and C. Wood, «Trust in Information-Centric Networking: From Theory to Practice», 25th International Conference on Computer Communication and Networks (ICCCN), DOI 10.1109/ICCCN.2016.7568589, August 2016, <https://doi.org/10.1109/ICCCN.2016.7568589>.

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

Marc Mosko

PARC, Inc.

Palo Alto, California 94304

United States of America

Phone: +01 650-812-4405

Email: marc.mosko@parc.com

Ignacio Solis

LinkedIn

Mountain View, California 94043

United States of America

Email: nsolis@linkedin.com

Christopher A. Wood

University of California Irvine

Irvine, California 92697

United States of America

Phone: +01 315-806-5939

Email: woodc1@uci.edu


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

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

nmalykh@protokols.ru


1Content-Centric Networking.

2Information-Centric Networking Research Group — группа по исследованию ориентированных на информацию сетей.

3Internet Research Task Force.

4Information-Centric Networking.

5Type-length-value — тип, размер, значение.

6Internet of Things — Internet вещей.

7Named Data Networking — сеть именованных данных.

8Forwarding information base.

9Message Authentication Code — код аутентификации сообщения.

10Message Integrity Code — код целостности сообщения.

11Hashed Message Authentication Code — хешированный код аутентификации сообщения.

12Cyclic Redundancy Check — циклическая контрольная сумма с избыточностью.

13Pending Interest Table — таблица ожидающих Interest.

14File-Like ICN Collection — файлоподобная коллекция ICN.

15Automatic Repeat reQuest.

16Longest Prefix Match.

17Globally Unique Identifier — уникальный в глобальном масштабе идентификатор.

18Recommended Cache Time — рекомендуемое время кэширования.

19Elliptic Curve Digital Signature Algorithm — алгоритм цифровой подписи на основе эллиптической кривой.

20Access control list.

Рубрика: RFC | Комментарии к записи RFC 8569 Content-Centric Networking (CCNx) Semantics отключены

NPL — Network Programming Language Specification

NPL — Network Programming Language Specification

v1.3

June 11, 2019

Перевод спецификации языка NPL, версия 1.3

PDF

1. Сфера применения

Этот документ описывает конструкции и применение языка сетевого программирования NPL1. Основной целью NPL является описание поведения обработки пакетов на уровне данных (Data Plane Packet Processing) с использованием подходящего набора конструкций. Приложение обработки пакетов в NPL включает конструкции высокого уровня для таких задач, как синтаксический анализ, таблицы «сопоставление-действие», редактирование пакетов. Язык также включает другие конструкции, такие как функции.

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

Документ предназначен для системных архитекторов, инженеров-проектировщиков и инженеров-программистов, которым нужно понимать логику NPL, вносить изменения в программы NPL или разрабатывать приложения для обработки пакетов. Инженерам-тестировщикам также следует понимать NPL для выполнения эффективных тестов.

Документ не рассматривает архитектуру программируемых устройств и работу компиляторов NPL.

2. Термины

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

NPL Compiler — компилятор NPL

Состоит компиляторов Front End (FE) и Back End (BE).

Front End (FE) Compiler — компилятор FE

Компонент компилятора, выполняющий синтаксический анализ и проверку корректности исходного кода NPL, а также генерирующий промежуточное представление.

Back End (BE) Compiler — компилятор BE

Компонент компилятора, создающий аппаратный код на основе IR.

IR files — файлы IR

Файлы промежуточного представления.

Constructs — конструкции

Встроенные компоненты для выполнения определенных функций.

Metadata — метаданные

Поля шины (bus), заголовка (header) и таблицы (table), которые не создаются в NPL, но присутствуют и доступны.

3. Обзор

Рост программно-определяемых сетей (SDN2) повысил уровень ожиданий в части программируемости и автоматизации сетей. Исходно задачей SDN было решение проблем уровня управления в стремлении преодолеть ограничения традиционных моделей управления. Впоследствии пользователям потребовались более гибкие решения, способные адаптироваться к изменению сетевых потребностей, например, поддержка новых наложенных протоколов и расширение возможностей телеметрии. Это расширило сферу применения SDN путем включения задач программирования уровня данных. Однако новые гибкие решения для коммутации должны обеспечивать производительность на полной скорости линии с оптимизацией ресурсов коммутатора и потребляемой мощности.

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

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

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

В NPL применяется ряд описанных ниже абстракций.

Data Types — типы данных

Определяет тип поля данных.

Parser — синтаксический анализатор

Идентифицирует разрешенные заголовки в принятых пакетах и извлекает поля таких заголовков.

Logical Bus — логическая шина

Задает поля и наложения (overlay) логической шины, соединяющей объекты NPL.

Logical Table (Match Action table) — логическая таблица (сопоставление-действие)

Описывает конкретную таблицу с ключами поиска и действиями. NPL поддерживает таблицы index, hash, tcam, lpm, alpm.

Editor — редактор

Обеспечивает возможность добавлять, удалять или заменять заголовки.

Special Function — специальная функция

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

Function — функция

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

Strength Resolution – выбор среди таблиц

Механизм выбора одной из нескольких таблиц, одновременно (параллельно) обновляющих один объект.

Packet Drop, Packet Trace, Packet Count

Встроенные функции для отбрасывания, трассировки и учета пакетов.

Create Checksum, Update Packet Length

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

Metadata for MA and Parser — метаданные для таблиц и анализаторов

Данные, не создаваемые в NPL, но существующие в процессе работы с пакетом и доступные для использования в NPL.

Язык NPL не привязан к какой-либо аппаратной архитектуре и предназначен для реализации на разных аппаратных платформах, включая ASIC, программируемые NIC3, FPGA и программные коммутаторы. Хотя определенные конструкции языка предназначены для использования конкретных свойств оборудования, это не препятствует отображению программ на цели, не поддерживающие таких свойств.

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

3.1. Преимущества

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

По сравнению с настраиваемыми и другими программируемыми решениями, доступными сегодня, NPL обеспечивает ряд преимуществ. Изощренные возможности языка обеспечивают:

  • настраиваемые конвейеры таблиц;

  • интеллектуальное выполнение действий;

  • параллельную обработку;

  • расширенные возможности логических таблиц;

  • уровень интегрированного инструментария;

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

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

3.2. Архитектурная модель

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

На рисунке 1 показана архитектурная модель в виде блок-схемы базовых компонент NPL и связей между ними.

Рисунок 1. Архитектурная модель.

Каждый функциональный блок взаимодействует со своими соседями, читая или записывая данные в одну или несколько шин. Шина содержит набор полей, заданных с использованием NPL. Логически поток шин через блоки образует конвейер обработки. Например. Таблицы «сопоставление-действие» (СД), функции и специальные функции обычно читают поля шины и записывают в них. Блок анализа принимает пакет на входе и записывает значения полей в шину, а блок редактирования использует поля шины для обновления или создания выходного пакета.

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

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

4. Компоненты язык NPL

4.1. Поддерживаемые конструкции

Документ поделен в соответствии с функциональными частями конвейера в коммутаторе.

  • Типы данных.
  • Программные конструкции.
  • Конструкции синтаксического анализатора.
  • Конструкции шин.
  • Конструкции таблиц «сопоставление-действие».
  • Функции.
  • Конструкции редактора.
  • Конструкции специальных функций.
  • Метаданные для таблиц «сопоставление-действие» и анализатора.

Определения идентификаторов и констант NPL, а также полная грамматика NPL описаны в Приложении D.

  • Идентификаторы должны начинаться с символов [a-z A-Z _] и могут включать символы [a-z A-Z _ 0-9].

  • Десятичные и шестнадцатеричные литералы.

  • Строковые литералы (например, “foobar”)

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

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

NPL поддерживает базовые типы данных bit, varbit, list, const и auto_enum, а также производный тип struct.

4.2.1. bit

Тип bit относится к базовым. Значение данного типа может быть 0 или 1. Тип служит для описания полей в производных типах данных, таких как struct. Этот тип также применяется в logical_table, logical_register, special_function и других конструкциях.

4.2.1.1. bit-array

Для описания многобитовых полей применяется тип bit-array с указанием размера. NPL не задает ограничений для размера битовых массивов. Массивы битовых массивов не поддерживаются в NPL.

Пример

bit		cfi;		// однобитовое поле
bit[3]		pri;		// 3-битовое поле pri 
bit[12]	vid;		// 12-битовое поле vid
bit[128]	bit_map;	// 128-битовое поле bit_map
bit[8]		label[5];	// не разрешего, поскольку массивы битовых массивов не поддерживаются
4.2.1.2. Индексирование bit-array

NPL поддерживает статические и переменные индексы для массивов. Изначально поддержка ограничена битовыми массивами. Размер массива и размер индекса должны соответствовать.

Статическое индексирование bit-array

Индекс задается целым числом без знака и может указывать один бит или диапазон битов.

Пример

local.rst1 = local.rpa_id_profile1[3:2];
local.rst1 = local.rpa_id_profile1[0:0];

Индексирование bit-array переменной

Индексирование массивов переменной обычно применяется для битовых полей (bitmap).

Пример

local.rst1 = local.rpa_id_profile1[ip_tmp_bus.idx:ip_tmp_bus.idx];

4.2.2. varbit

Тип varbit служит для задания битовых массивов переменного размера. Некоторые протоколы используют в заголовках поля, размер которых может меняться от пакета к пакету. Тип varbit[X] задает переменную, размер которой не может превышать X битов.

Пример

varbit[120]	options; // опции размером да 120 битов.

4.2.3. const

Тип данных const используется для обозначения постоянных величин (integer или enum).

Пример

usage_mode_create(in const index,
		     in bit[2] in_pkt_color,
		     in varbit[14] meter_action_set,
		     in varbit[10] color_table_index0,
		     in varbit[8] color_pdd_sbr_index0,
		     out bit[2] color
		    );

4.2.4. list

В некоторых конструкциях NPL может требоваться объединение переменного числа элементов в список. Примерами могут служить dynamic_table, strength_resolve и create_checksum. Для представления этого служит тип данных list. Элементы списка должны указываться в фигурных скобках.

{ipv4.protocol, ipv4.dip}

Списки используются в следующих конструкциях:

  • dynamic_table для указания переменного числа входных и выходных полей;

  • update_checksum для указания переменного числа, учитываемых в контрльной сумме;

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

Пример

Аргументы dynamic_table используют list для указания полей, которые могут применяться в заранее выбранном шаблоне.

flex_digest_lkup.presel_template(
	{
	ing_cmd_bus.l2_iif_opaque_ctrl_id,
	ing_cmd_bus.vfi_opaque_ctrl_id,
	ing_cmd_bus.l2_iif_flex_digest_ctrl_id_a,
	ing_cmd_bus.l2_iif_flex_digest_ctrl_id_b,
	ing_cmd_bus.fixed_hve_iparser1_0,
	ing_cmd_bus.flex_hve_iparser1_1,
	ing_cmd_bus.fixed_hve_iparser2_0,
	ing_cmd_bus.flex_hve_iparser2_1,
	ing_cmd_bus.my_station_hit
	});

Конструкция create_checksum содержит аргумент list со списком полей, учитываемых в контрольной сумме.

create_checksum(egress_pkt.fwd_l3_l4_hdr.udp.checksum,
	{
	egress_pkt.fwd_l3_l4_hdr.ipv4.sa,
	egress_pkt.fwd_l3_l4_hdr.ipv4.da,
	editor_dummy_bus.zero_byte,
	egress_pkt.fwd_l3_l4_hdr.ipv4.protocol,
	egress_pkt.fwd_l3_l4_hdr.udp.udp_length,
	egress_pkt.fwd_l3_l4_hdr.udp.src_port,
	egress_pkt.fwd_l3_l4_hdr.udp.dst_port,
	egress_pkt.fwd_l3_l4_hdr.udp.udp_length,
	egress_pkt.fwd_l3_l4_hdr.udp._PAYLOAD
	});

4.2.5. struct

Тип struct служит для задания упорядоченного множества полей. Структуры применяются в разных типах конструкций. Внутри структур могут присутствовать лишь типы bit и struct. Тип struct поддерживает перекрытия (overlay) для указания полей несколькими способами

Таблица 1. Конструкция struct.

Конструкция

Аргументы, опции

Описание

struct

Задает новую структуру с именем и полями.

fields

bit, bit[n], varbit или struct are allowed. Другие типы и конструкции не разрешены.

overlays

Задает наложения для полей структуры. В структуре разрешается лишь одна конструкция overlays. Все наложения struct указываются в конструкции overlays.

4.2.6. Массивы struct

В NPL разрешены одномерные массивы struct. NPL не ограничивает размер массива struct. Ниже приведены примеры использования массивов struct.

obj_bus.struct1[arr1].field = field;
obj_bus.struct1[arr1].struct2[arr2].field = field;
cmd_bus.struct1 = obj_bus.struct1[arr];

Пример

Простая структура

struct vlan_s {
	fields {
		bit		cfi;	// 1-битовое поле
		bit[3]		pri;	// 3-битовое поле pri
		bit[12]	vid;	// 12-битовое поле vid
	}
}

Структура с наложением

struct switch_bus_s {
	fields {
		bit[4]	otpid_enable;
		bit	olp_enable;
		bit	ts_enable;
		bit[10]	ing_port_num; // Базовое поле для определенных далее наложений.
		bit	svp_enable;
	}
	overlays {
		ing_svp :	ing_port_num[7:0];
		ing_pri :	ing_port_num[9:8]; // Наложения на базовое поле  ing_port_num.
		exp :		ing_port_num[9:8];
	}
}

Массив структур

struct mpls_header_stack_t {
	fields {
		mpls_t mpls[3];	// Здесь может быть 3 заголовка mpls_t.
	}
}

Элементы массива можно указать в форме mpls[0], mpls[1], mpls[2].

4.2.7. enum

NPL поддерживает конструкцию enum для определения перечисляемых типов. Значения элементов enum должен предоставлять пользователь. Перечисляемое в NPL — это просто идентификатор, указывающий подмножество того, что предоставляется в C/C++, и не является типом данных в NPL. Перечисляемые служат для представления констант и определяют константы, используемые в качестве аргументов функций и rvalue в операторах присваивания.

Пример

enum drop_reason{
	NO_DROP = 0,
	MEMBERSHIP_DROP = 1,
	TTL_DROP = 2
}
packet_drop(drop_bus.disable_drop, drop_reason.TTL_DROP, 5);

4.2.8. auto_enum

NPL поддерживает тип данных auto_enum для задания перечисляемых типов. Значения элементов auto_enum назначает компилятор. Производитель целевой платформы может принять решение о способе отображения и присваивания значений auto_enum.

Типовыми применениями auto_enum являются Logical Table Lookup, Multi-Data View и Strength Based Resolution Index.

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

Пример

auto_enum qos_entry {
	QOS_DISABLE,
	QOS_L3_TUNNEL,
	QOS_L2_TUNNEL
}
qos_sfc.sf_profile_entry("sfc_qos_profile", qos_entry.QOS_L3_TUNNEL,
	{
		obj_bus.mapping_ptr,
		cmd_bus.effective_exp
	},
	{
		cmd_bus.int_pri,
		cmd_bus.pri
	} 
);

4.3. Выражения

4.3.1. Обозначение чисел

NPL поддерживает только десятичные и шестнадцатеричные литеральные константы. Числовая нотация применяется при задании значений полей. NPL не поддерживает тип bool, значение 0 соответствует false, все прочие — true.

Пример

a = 5;		// десятичное значение
ipv4.ttl = 0xF;	// шестнадцатеричное значение
ipv6.dip = 0x01234567;
ipv6.dip[63:0] = 0x0123456789abcdef;.
if (ipv4.protocol == 0x23)
ipv4.protocol = 0x231;

4.3.2. Условные операторы

NPL поддерживает операторы условий в разных конструкциях.

Таблица 2. Условные конструкции NPL.

Условные операторы

Описание

if, else if, else

Оператор if

switch

Оператор switch

4.3.3. Операторы

NPL поддерживает множество операторов. Ограничения при их использовании рассмотрены ниже.

Таблица 3. Операторы NPL.

Оператор

Символ

Описание

Арифметические операторы

+

Сложение

Вычитание

*

Умножение

/

Деление

%

Деление по модулю

Операторы отношений

==

Равно

!=

Не равно

<

Меньше

<=

Меньше или равно

>

Больше

>=

Больше или равно

Оператор слияния

<>

Конкатенация

Логические операторы

&&

Логическое И (AND)

||

Логическое ИЛИ (OR)

Операторы сдвига

<<

Сдвиг влево

>>

Сдвиг вправо

Побитовые логические операторы

&

И

|

ИЛИ

!A

Отрицание (NOT)

~A

Дополнение ло 1

^

Исключающее ИЛИ (XOR)

Унарные операторы

&A

Сокращение И (все биты 1)

|A

Сокращение ИЛИ (все биты 0)

Оператор присваивания

=

Присваивание значений5

Оператор маскирования

mask

Применяется в операторе switch, трактуется как AND. Операнды слева и справа от = могут иметь разные размеры. Если левый операнд (lvalue) больше правого (rvalue) по размеру значение дополняется нулями. В противном случае компилятор возвращает ошибку.

4.3.4. Области действия переменных

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

Ниже приведен список переменных NPL с глобальной областью действия. Такие переменные должны иметь уникальные имена:

  • enum;

  • auto_enum;

  • struct;

  • bus;

  • packet;

  • logical_table;

  • logical_register;

  • parser_node;

  • function;

  • special_function;

  • dynamic_table;

  • strength.

4.3.4.2. Локальные переменные

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

  • logical_table — поля, ключи;

  • struct — поля, структуры;
  • logical_register — поля;
  • enum — элементы;
  • auto_enum — элементы;
  • special_function — методы;
  • dynamic_table — методы.

4.4. Конструкция program

Программы представляют собой приложения NPL. Имя программы является точкой входа, как main в языке C. Конструкция program определяет порядок выполнения других конструкций конвейера обработки пакетов. Для управления потоком обработки по условиям используются конструкции if-then-else.

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

  • дерево синтаксического анализатора;
  • поиск в таблицах (logical_table, dynamic_table);
  • функции обработки пакетов;
  • специальные функции;
  • сравнение силы.

Присваивание значений не допускается в конструкции program.

Таблица 4. Конструкция program (порядок выполнения).

Конструкция

Аргументы, опции

Описание

program

Задает порядок выполнения операций обработки пакета.
Условные конструкции

В конструкциях с условием внутри program можно вызывать:

  • конструкции и операторы if/else/else if и switch;

  • все операторы NPL.

parse_begin(<имя узла>)

Прохождение дерева синтаксического анализа от корневого узла. Для разных пакетов могут применяться разные деревья.

parse_continue(<имя узла>)

Возврат процесса к заданному узлу дерева анализа.

<table>.lookup(<lookup_num>)

Поиск в таблице с автоматическим выполнением связанных с таблицей методов.

Вызовы функций обработки пакетов
Вызовы специальных функций
Сравнение силы Выбор результата при поиске в нескольких таблицах.

Пример

program mim_main () {
	parse_begin (ethernet);	/* Начало анализа из узла parser_node Ethernet. */
	port.lookup (0);		/* Поиск в таблице port. */
	iif.lookup (0);		/* Поиск в таблице iif. */
	my_station.lookup (0);	/* Поиск в таблице my_station. */
	isid.lookup (0);		/* Поиск в таблице isid. */
	mim_isid_switch_logic1();	/* Выполнение логической функции. */
	...
	if (cmd_bus.do_l3) {	/* Поиск по условию. */
		l3_host.lookup (0);
	}
	...
	l3_switch_logic1();		/* Вызов функции обработки пакета. */
	...
	next_hop.lookup (0);	/* Поиск в таблице next_hop. */
	do_packet_edits();		/* Функция редактирования. */
}

4.5. Конструкция синтаксического анализатора

Конструкция parser определяет:

  • заголовки — упорядоченный набор полей фиксированного или переменного размера;
  • группы заголовков;
  • пакеты, состоящие из групп заголовков;
  • связи между типами заголовков, формирующие дерево анализа.

NPL позволяет задавать базовые типы заголовков с помощью struct. Спецификация анализатора использует типы заголовков при объявлении struct для групп заголовков, а группы — при объявлении struct для пакетов. Программы NPL должны определять пакеты в форме packet.header_group.header


Рисунок 2. Заголовки, группы и пакеты.

4.5.1. Заголовок (struct)

Заголовки определяются с помощью типа данных struct, в которых поля заголовка определяются типами bit, bit-array и varbit для задания полей переменного размера, где header_length_exp служит для указания размера поля varbit. В NPL поддерживаются массивы заголовков.

Таблица 5. Конструкция заголовка (struct)

Аргументы, опции

Описание

struct

Задает новый тип заголовка.

varbit

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

header_length_exp

Для полей переменного размера задает выражение, определяющее реальный размер. В выражении можно использовать операторы + и *. Выражения следует указывать в форме var * c0 + c1, где var является полем заголовка, а c0 и c1 — константами.

Для полей фиксированного размера это поле не требуется.

Пример

Статический заголовок

struct vlan_t {
	fields {
		bit[3]		pcp;
		bit		cfi;
		bit[12]	vid;
		bit[16]	ethertype;
	}
}

Задает размер и порядок упаковки полей в заголовок пакета.

Заголовок переменного размера

struct ipv4_t {
	fields {
	bit[4]	version;
	bit[4]	hdr_len;
	bit[8]	tos;
	bit[32]	sa;
	bit[32]	da;
	varbit[320]	option;	// максимальный размер поля
}
header_length_exp:	hdr_len*4; 	// задает способ расчета числа байтов в заголовке

В приведенном примере option является полем переменного размера, а header_length_exp указывает способ вычисления размера заголовка. Другим примером может служить header_length_exp : (payload_len*4)+2. Вы выражении докускаются операторы + и *. В varbit[num] значение num указывает максимальный размер поля. Для каждого заголовка с полями переменного размера должен указываться атрибут header_length_exp. Структуры с несколькими полями переменного размера не поддерживаются.

4.5.2. Группа заголовков (struct)

Группы заголовков определяются с помощью типа struct и впоследствии служат для задания пакетов (4.5.3. Конструкция для пакета). Специальных опций для таких структур не поддерживается. Структура уровня группы заголовков позволяет «массовые» манипуляции и ссылки на заголовки в пакетах. Заголовки помещаются в группу в порядке, указанном NPL.

  • Группа заголовков может включать лишь struct с заголовками. Типы bit или bit-array не разрешаются.

  • Массивы групп заголовков не поддерживаются.

  • Заголовки и группы заголовков должны указываться в порядке их размещения в пакетах. Это важно!

Пример

Группа заголовков с множеством struct

struct l2_header_t {
	fields {
		bit[48]	macda;
		bit[48]	macsa;
		bit[16]	ethertype;
	}
}

struct vlan_tag_t {
	fields {
		bit[3]		pcp;
		bit		cfi;
		bit[12]	vid;
	}
}

struct group0_t {
	fields {
		l2_header_t	l2_header;
		vlan_tag_t	ovlan;
	}
}

Для группы заголовков struct задает порядок размещения заголовков в группе.

Задание массива заголовков

struct group1_t {
	fields {
		mpls_t mpls[3];	// говорит о наличии трех заголовков mpls_t.
	}
}

Элементы массива можно указывать в форме mpls[0], mpls[1], mpls[2].

4.5.3. Конструкция для пакета

Пакет состоит из групп заголовков и в NPL представляется с помощью struct. Экземпляры пакета объявляются с ключевым словом packet

packet struct-name instance-name;

Здесь объявляется пакет с именем instance-name, который описан в структуре struct-name, называемой структурой уровня пакета. Элементами этой структуры должны быть структуры групп заголовков. Структура для пакета не может содержать типы bit и bit-array, а экземпляры пакетов не могут быть массивами.

Структура уровня пакета служит для объединения групп заголовков в пакет.

Пример

Определение структуры и создание экземпляра пакета

struct macs_t {	// Структура заголовка, где все элементы являются массивами битов
	fields {
		bit[48] dmac;
		bit[48] smac;
	}
}

struct vlan_t {	// Структура заголовка
	fields {
		bit[16]	tpid;
		bit[3]		pcp;
		bit		dei;
		bit[12]	vid;
	}
}

struct ethertype_t {	// Структура заголовка
	fields {
		bit[16] type;
	}
}

struct mpls_t {	// Структура заголовка, где все элементы являются массивами битов
	fields {
		bit[20] 	label;
		bit[3] 	tc;
		bit		s;
		bit[8] 	ttl;
	}
}

struct mpls_grp_t {	// Структура группы заголовков
	fields{
		mpls_t mpls[3];
	}
}

struct ipv4_t {	// Структура заголовка
	fields {
		// Определения полей IPv4 (только bit-array)...
	}
}

struct ipv6_t {	// Структура заголовка
	fields {
		// Определения полей IPv6 (только bit-array)...
	}
}

struct l2_t {	// Структура группы заголовков, где все элементы являются структурами
	fields {
		macs_t 	macs;
		vlan_t 	ctag;
		ethertype_t 	etype;
	}
}

struct l3_t {	// Структура группы заголовков
	fields {
		ipv4_t ipv4;
		ipv6_t ipv6;
	}
}

struct ingress_packet_t {	// Структура уровня пакета
	fields {
		l2_t		l2;
		mpls_grp_t 	mpls_grp;
		l3_t		l3;
	}
}
packet ingress_packet_t ing_pkt;	// Указывает ingress_packet_t как структуру уровня пакета

Заголовок и поля в пакете должны указываться, как приведено ниже.

ing_pkt.l2.macs.da

Ниже показано, как должны задаваться массивы в заголовке.

ing_pkt.mpls_grp.mpls[0].label

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

4.5.4. Метаданные заголовка

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

Пример

struct tcp_t {
	fields {
		...
	}
}

struct group0_t {
	fields {
		tcp_t tcp;
		...
	}
}

struct packet_t {
	fields {
		group0_t group0;
	...
	}
}

packet packet_t ing_pkt;

program l3 () {
	...
	if (ing_pkt.group0.tcp._PRESENT) {
		l2_table.lookup(0);
	}
	...
}

4.5.5. Соединения дерева анализа (parser_node)

Конструкция parser_node задает соединения экземпляров заголовков в пакетах. По сути, она определяет узлы анализа и переходы. В parser_node поддерживаются условные конструкции для перехода к следующему parser_node.

Таблица 6. Конструкция parser_node.

Конструкция

Аргументы, опции

Описание

parser_node

Задает узел синтаксического анализатора и его соединения со следующими узлами.

name

Имя parser_node.

root_node

В дереве анализатора может быть лишь один корневой узел. Функция parse_begin() может указывать только один корневой узел. Для прерывания и повторного входа в дерево анализа служат parse_break и parse_continue.

next_node<node>

Задает следующий узел, с которым соединен данный parser_node.

switch

Задает оператор switch для описания условия перехода к следующему parser_node. В операторах может применяться ключевое слово mask. В операторах разрешены битовые массивы. Значения вариантов могут быть константами или константами с маской (операция AND).

if/else

Условие перехода к следующему узлу. Поддерживаются операторы сравнения == и !=, если rvalue является константой. Поддерживаются логические операции &&, ||, !.

extract_fields(packet.header)

Задает экземпляр заголовка для анализа. Текущая позиция анализа пакета выходит за пределы этого заголовка.

parse_break(<node>)

Задает выход из дерева анализа и возврат в программу. Указанный аргументом узел является следующим узлом, с которого возобновляется анализ при возврате в дерево.

end_node

Указывает последний лист в дереве.

latest

Указывает последний заголовок, проанализированный в этом parser_node. Имя latest.field может использоваться в дереве анализа.

current

Указывает текущие байты пакета для выравнивания. Например, для просмотра следующих 2 байтов в пакете следует использовать current.

При вызове extract_fields указатель current выходит за пределы анализируемого заголовка.

current (смещение первого бита, число выбираемых битов)

default

Задает в операторе switch вариант, применяемый при отсутствии иного подходящего.

Пример

Задание дерева анализа

struct vlan_t {
	fields {
		bit[3]		pcp;
		bit[1]		cfi;
		bit[12]	vid;
		bit[16]	ethertype;
	}
}

struct l2_t {
	fields {
		bit[48]	macda;
		bit[48]	macsa;
		bit[16]	ethertype;
	}
}

struct group1_t {
	fields {
		l2_t	l2;
		vlan_t	vlan;
	}
}

struct ing_pkt_t {
	fields {
		group1_t group1;
	}
}

parser_node start {
	root_node : 1;
	next_node ethernet;
}

parser_node ethernet {
	extract_fields(ing_pkt.group1.l2);
	switch (latest.ethertype) {
		0x8100		: {next_node ctag};
		default	: {next_node ingress};
	}
}

parser_node ctag {
	extract_fields(ing_pkt.group1.vlan);
	if (current(0,16) == r_ing_outer_tpid_0.tpid) {
		next_node otag;
	}
	next_node ingress;
}

parser_node ingress {
	end_node : 1;
}

4.5.6. Выход и повторный вход в дерево (parse_break, parse_continue)

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

Пример

Выполнение поиска в таблице перед анализом пакета ethernet и mpls.

program mpls_switch() {
	parse_begin(start);
	port_table.lookup(0);
	// узел ethernet принимает вывод из port_table, т. е. logical_bus.otpid_enable
	parse_continue(ethernet);
	// узел mpls_label принимает вывод из mpls_table, т. е. 
	// logical_bus.mpls_table_result_type
	mpls_table.lookup(0);
	parse_continue(mpls_label);
}
parser_node start {
	root_node : 1;
	switch(logical_bus.rx_port_parse_ctrl) {
		0x0:	next_node ppd;
		0x2:	next_node sobmh;
		0x3:	parse_break(ethernet);
		default: next_node ingress;
	}
}
parser_node ethernet {
	extract_fields(ingress_pkt.outer_l2_hdr.l2);
	if (logical_bus.otpid_enable[3:3] && latest.ethertype == 0x8100) {next_node otag;} 
	//0x8100
	if (logical_bus.otpid_enable[2:2] && latest.ethertype == 0x8100) {next_node otag;} 
	//0x8100
	if (logical_bus.otpid_enable[1:1] && latest.ethertype == 0x8100) {next_node otag;} 
	//0x8100
	if (logical_bus.otpid_enable[0:0] && latest.ethertype == 0x8100) {next_node otag;} 
	//0x8100
}
parser_node mpls_0 {
	extract_fields(ingress_pkt.outer_l3_l4_hdr.mpls[0]);
	switch (latest.stack) {
		0x0: next_node mpls_1;
		0x1: parse_break(mpls_label);
		default: next_node ingress;
	}
}
parser_node mpls_label {
	extract_fields(ingress_pkt.outer_l3_l4_hdr.mpls[4]);
	switch (logical_bus.mpls_table_result_type) {
		0x0: next_node mpls_cw;
		0x1: next_node inner_ethernet;
		0x2: next_node inner_l3_speculative;
		default: next_node ingress;
	}
}
parser_node ingress {
	end_node:1;
}

Запись end_node:1 указывает завершение анализа.

4.6. Конструкция логической шины

Конструкции логических шин служат для определения набора полей (переменных)).

4.6.1. Определение шины

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

4.6.2. Создание экземпляра шины (bus)

Для создания шины используется ключевое слово bus, а шина определяется с помощью struct. Шина может включать наложение полей, которые могут индивидуально указываться в программе NPL.

Пример

Создание экземпляра шины

struct control_bus_t {
	fields {
		bit	ts_enable;
		bit	olp_enable;
		bit[4] otpid_enable;
	}
}

bus	control_bus_t	control_id;

parser_node pkt_start{
	root_node : 1;
	next_node ethernet;
}

parser_node ethernet {
	extract_fields(ing_pkt.group0.l2);
	if (control_id.ts_enable == 0) { // control_id - логическая шина, 
						// ts_enable - поле шины.
		if (control_id.otpid_enable != 0 ) {
			switch (latest.ethertype) {
				0xABCD	: {next_node vntag};
				0x8888	: {next_node etag};
				0x8100	: {next_node otag};
				0x9100	: {next_node itag};
				0x0000 mask 0xFC00 	: {next_node llc};
				default	: {next_node payload};
			}
		}
	}
}

parser_node otag{
	extract_fields(ing_pkt.group0.ovlan);
	end_node:1;
}

4.7. Конструкции логических таблиц

Конструкция логической таблицы служит для определения таблицы с ключами (keys), полями fields, key_construct, fields_assign, а также minsize и maxsize. Таблицы также имеют встроенный метод lookup().

4.7.1. Логическая таблица (logical_table)

Конструкция logical_table служит для объявления таблиц «сопоставление-действие» (СД). Это позволяет пользователю задать структур данных, которую уровень управление или уровень данных может менять. Пользователь может задать поля ключа и правила для хранения в таблице, а также механизм создания ключей с использованием полей логической шины. Кроме того, logical_table позволяет задать метод fields_assign для работы с полями.

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

Все объявленные логические таблицы должны вызваться конструкцией вида <имя таблицы>.lookup(lookup_num). lookup_num = 0 указывает первый поиск.

Таблица 7. Конструкция logical_table.

Конструкция

Аргументы, опции

Описание

logical_table

Задает новую таблицу.

table_name

Задает имя таблицы.

table_type

Задает тип таблицы с точки зрения пользователя. Допустимы типы index, tcam, hash, alpm. Компилятор может отображать типы на разные компоненты, а целевая платформа может добавлять свои типы.

keys

Задает ключи, использцемые для доступа к логической таблице. Размер ключа задается объявлением bit. Ключи могут иметь тип bit или bit-array, тип struct не разрешен для ключей.

fields

Задает поля правил для logical_table. Размер поля задается объявлением bit. Поля могут иметь тип bit, bit-array и auto_enum, тип struct не разрешен. Тип auto_enum служит для задания множества представления данных.

key_construct()

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

  • Может поддерживаться множество поисков в одной таблице (4.7.3. Множественный поиск в таблице).

  • Для множественного поиска разрешены условные выражения с метаданными _LOOKUP0 и _LOOKUP1 и т. д.

  • Ключи создаются из полей шин.

fields_assign()

Метод описания функциональности обработки и назначения полей логической шины.

  • Может поддерживаться множество поисков в одной таблице (4.7.3. Множественный поиск в таблице).

  • Для множественного поиска в данной таблице разрешены условные выражения с метаданными _LOOKUP0 и _LOOKUP1 и т. д.

  • Назначения могут дополнительно ограничены _VALID и multi-view(auto_enum)

  • Другие условия и операции не разрешены в блоках fields_assign.

minsize

Минимальный гарантированный размер. Физическая таблица должна иметь такое число элементов.

maxsize

Максимальный разрешенный размер. При разных maxsize и minsize это значение служит в основном для заполнения SDK6. Одинаковые значения minsize и maxsize считаются «размером» таблицы и компилятор должен найти физическую таблицу указанного размера.

Пример

Определение индексной таблицы

logical_table port {
	table_type : index;
	minsize : 128;
	maxsize : 128;
	keys {
		bit[7] port_num;
	}
	fields {
		bit[1] l3_enable;
		bit[1] otag_enable;
		bit[8] src_modid;
		bit[12] default_vid;
	}
	key_construct() {
		port_num = obj_bus.port_num;
	}
	fields_assign() {
		if (_LOOKUP0 == 1) {
			cmd_bus.port_l3_enable = l3_enable;
			...
		}
	}
}

Определение таблицы TCAM

logical_table my_station_hit {
	table_type : tcam;
	maxsize : 512;
	minsize : 512;
	keys {
		bit[48] macda;
		bit[12] vid;
		bit[8] src_modid;
	}
	fields {
		bit[2] mpls_tunnel_type;
		bit	local_l3_host;
	}
	key_construct() {
		macda	= ing_pkt.l2_grp.l2.macda;
		vid	= obj_bus.vlan_id;
		src_modid = obj_bus.source_logical_port;
	}
	fields_assign() {
		if (_LOOKUP0 == 1) {
			l3_cmd_bus.local_l3_host = local_l3_host;
			...
		}
	}
}

Вызов таблицы

program ingress {
	port.lookup(0); //calls port
 	logical table
	if (cmd_bus.vlan_valid == 1) {
		my_station_hit.lookup(0);
 		// Вызов поиска в my_station_hit первый раз
		my_station_hit.lookup(1);
 		// Вызов поиска в my_station_hit второй раз
	}
}

4.7.2. Метаданные логической таблицы

В NPL каждая логическая таблица имеет перечисленные ниже метаданные. Для каждого пакета значение метаданных присваивается с использованием ряда правил.

  • _LOOKUPx — 1-битовое значение, устанавливается при поиске в таблице для пакета.

  • _HIT_INDEXx — 32-битовое значение, указывающее строку таблицы, которой соответствует пакет. Формат _HIT_INDEXx может зависеть от целевой платформы. Должен использоваться один бит, показывающий, соответствует ли поиск действительной записи.

  • _VALID — 1-битовое значение, устанавливаемое если поиск дает действительную запись.

В именах x представляет lookup_num (0, 1 и т. д.).

Пример

logical_table table_a {
	...
	fields_assign() {
		if (_LOOKUP0) {
			obj_bus.src_hit_index = _HIT_INDEX0;
		}
		if (_LOOKUP1) {
			obj_bus.dst_hit_index = _HIT_INDEX1;
		}
	}
}

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

4.7.3. Множественный поиск в таблице

NPL позволяет задать множественный поиск в одной logical_table. В этом случае могут применяться метаданные _LOOKUP0, _LOOKUP1 и т. д., чтобы различать ключи и поля, обрабатываемые в блоках key_construct() и fields_assign().

Пример

//Определение логической таблицы
logical_table mac_table {
	table_type : hash;
	minsize : 64;
	maxsize : 64;
	keys {
		bit[48] macda;
	}
	fields {
		bit[16] port;
		bit[1] dst_discard;
		bit[1] src_discard;
	}
	key_construct() {
		if (_LOOKUP0==1) {
			macda = ing_pkt.l2_grp.l2.da;
		}
		if (_LOOKUP1==1) {
			macda = ing_pkt.l2_grp.l2.sa;
		}
	}
	fields_assign() {
		if (_LOOKUP0==1) { // Например, Entry 100
			obj_bus.dst = port;
			obj_bus.dst_discard = dst_discard;
		}
		if (_LOOKUP1==1) { //Например, Entry 200
			temp_bus.src_port = port;
			obj_bus.src_discard = src_discard;
		}
	}
}
program {
	if ((ing_pkt.l2_grp.l2._PRESENT) & (ing_pkt.l2_grp.vlan.vid != 0)) { 
		// Условие поддерживается.
		mac_table.lookup(0);
		mac_table.lookup(1);
	}
}

4.7.4. Множество типов данных (резимы размера данных)

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

Разработчик NPL должен задать все эти поля разных типов данных в конструкции fields{}. Например, логическая таблица NHI имеет два представления данных:

представление 1 — поля A, B, C;

представление 2 — поля A, D, E, F.

Правила NPL _VALID:

  • если логическая таблица имеет много типов данных, она будет включать 1 вхождение _VALID (_VALID = 0);

  • если некоторые поля имеют strength, они должны быть указаны в разделе _VALID=0 внутри блока fields_assign(). Вызовы strength выполняются лишь для случаев _VALID=1.

Пример

auto_enum multi_view {
	UC_VIEW,
	MC_VIEW,
	BC_VIEW
}
logical_table NHI {
	...
	fields {
		bit[3] 	A;
		bit[15] 	B;
		bit[7] 	C;
		bit[10] 	D;
		bit[4] 	E,
		bit[4] 	F;
		bit[16] 	strength_object_G;
		multi_view X; // поле data_type для обозначения разных представления (auto_enum).
	}
	fields_assign() {
		if (_LOOKUP0 == 0) {
			if (_VALID == 1) { // _VALID — то же, что «попадание».
				if (X == UC_VIEW) {
					bus.A = A;
					bus.B = B;
					bus.C = C;
				}
				if (X == MC_VIEW) {
					bus.A = A;
					bus.D = D;
					bus.E = E;
					bus.F = F;
				}
			} // завершение _VALID == 1
			else { // _VALID == 0 задает лишь поля data_type = 0.
				bus.A = 0;
				bus.B = 0;
				bus.C = 5; 	// пример ненулевой константы.
				bus.G = 0;
			} // завершение _VALID == 0
		}
		if (_LOOKUP1 == 1) {
			...
		}
	}
}

4.8. Конструкция логического регистра

Конструкция logical_register служит для задания объекта со множеством полей и глубиной 1 (регистр). Логический регистр обеспечивает программам интерфейс для настройки элементов управления. В отличие от таблиц регистры не имеют ключей поиска. Поля могут инициализироваться во время компиляции и заполняться в процессе работы.

4.8.1. Определение одноуровневого хранилища

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

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

Таблица 8. Конструкция logical_register.

Конструкция

Аргументы, опции

Описание

logical_register

Задает новый регистр, который может иметь произвольный размер.

fields

Задает поля данных логического регистра. Размер полей указывается с использованием типа bit. Для каждого поля должно указываться значение при сбросе.

Пример

Определение логического регистра

// Fэта конструкция может использоваться, например, для задания значений, подобных TPID.
logical_register tpid_values {
	fields {
		bit[16] tpid0 = 0x8100;
		bit[16] tpid1 = 0x9100;
		bit[16] tpid2 = 0x7100;
		bit[16] tpid3 = 0x8868;
	}
}

В определении указан размер и значение каждого поля при сбросе.

4.9. Функции обработки пакетов (function)

Функции применяются в NPL для описания базовой обработки пакетов и обработки результатов синтаксического анализа, логических таблиц, special_function и других конструкций. Функции являются императивными конструкциями, которые могут преобразовывать данные и поддерживать модульность приложений. Из функций могут вызываться другие конструкции NPL.

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

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

Функции позволяют также организовать модульную структуру приложения. Для этого функция может включать поиск в логических таблицах, сравнение силы, вызовы динамических таблиц и т. п. Все элементы, которые могут быть заданы в конструкции program, подходят для функций. Рекомендуется создавать отдельные функции для поддержки модульности и обработки пакетов.

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

Таблица 9. Конструкция function.

Конструкция

Аргументы, опции

Описание

function

Задает новую функцию обработки пакетов.

function_name

Имя функции.

Любые условные, арифметические и логические операторы, манипуляции с логическими шинами, поиск в logical_table, special_function, editor, strength.

Пример

// Шина будет применяться внутри функций.
struct switch_logic_t {
	fields {
		bit no_l3_switch;
		bit l2_same_port_drop;
	}
}

// Логические регистры доступны из функций.
logical_register cpu_control {
	fields {
		bit
 		tunnel_to_cpu = 0; // Инициализация.
	}
}

bus switch_logic_t temp;

function l3_switch_logic1 () {
	temp.no_l3_switch = 0;
	if (port.l3_enable &&
		(ingress_pkt.outer_l3_l4_hdr.ipv4._PRESENT || 
		ingress_pkt.outer_l3_l4_hdr.ipv6._PRESENT)
	   ) {
		if (obj_bus.tunnel_pkt || obj_bus.tunnel_error) {
			if (obj_bus.tunnel_error) {
				obj_bus.tunnel_decap = 0;
				temp.no_l3_switch = 1;
				if (cpu_control.tunnel_to_cpu) {
					obj_bus.copy_to_cpu = 1;
				}
			} else {
				obj_bus.tunnel_decap = 1;
			}
		} else { // Не туннельный пакет.
			obj_bus.tunnel_decap = 0;
		}
	}
	// Трассировка пакета
	packet_trace(temp.no_l3_switch, cpu_reason.NO_SWITCH);

	temp.l2_same_port_drop = obj_bus.src_prune_en && (obj_bus.l2_oif == obj_bus.l2_iif);
	// Отбрасывание пакета
	packet_drop(temp.l2_same_port_drop, drop_reason.L2_SAME_PORT_DROP, 
			L2_SAME_PORT_DROP_STR);
}

4.10. Конструкции редактирования пакетов

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

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

4.10.1. Добавление заголовка

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

Таблица 10. Конструкция add_header.

Конструкция

Аргументы, опции

Описание

add_header

Задает добавление заголовка в пакет.

new_header_name

Имя нового заголовка, совпадающее с именем в спецификации пакета.

Пример

Добавление заголовка в пакет

Если приложению нужно добавить otag и создать его до вызова add_header(otag), можно задать

egr_pkt.group1.otag.vid = ing_pkt.itag.vid+100; // otag и itag заданы как заголовки в packet.
egr_pkt.group1.otag.pcp = obj_bus.egr_port_table_pcp; // из шины object.
egr_pkt.group1.otag.tpid = 0x9100;
add_header(egr_pkt.group1.otag);

Добавление туннельного заголовка к пакету

Если приложению нужно добавить туннельный заголовок Tunnel L2 и VLAN ID, можно задать

egr_pkt.group2.tunnel_l2.dmac = 0xff;
egr_pkt.group2.tunnel_l2.smac = obj_bus.l3_interface_smac;
egr_pkt.group2.tunnel_l2.vid = obj_bus.l3_next_hop_vid;
add_header(egr_pkt.group2.tunnel_l2);

4.10.2. Удаление заголовка

Удаляет заголовок из стека заголовков пакета. Применяется в некоторых приложениях, таких как выход краевого коммутатора, для удаления туннельных заголовков.

Таблица 11. Конструкция delete_header.

Конструкция

Аргументы, опции

Описание

delete_header

Задает удаление заголовка из пакета. Для указания заголовка используется спецификация синтаксического анализа.

header_name

Имя удаляемого заголовка, совпадающее с именем в спецификации пакета.

Пример

Для удаление заголовка otag из пакета можно задать

delete_header(egr_pkt.group1.otag);

Это работает с экземпляром пакета, удаляя из него otag без влияния на дерево синтаксического анализа.

Для удаления группы заголовков можно использовать

delete_header(egr_pkt.group1);

Это работает с экземпляром пакета, удаляя из него группу заголовков group1 без влияния на дерево анализа.

4.10.3. Перезапись заголовка

Для некоторых протоколов при обработке пакета требуется изменять некоторые поля заголовка.

Таблица 12. Конструкция replace_header_field.

Конструкция

Аргументы, опции

Описание

replace_header_field

Заменяет поле заголовка полем из лины или другим полем заголовка.

dest_field

Имя изменяемого поля заголовка.

src_field

Имя поля, используемого в качестве источника при замене (bus.field или header.field).

Пример

Для изменения поля dscp можно использовать

replace_header_field(egr_pkt.ipv4.dscp, obj_bus.new_dscp);

4.10.4. Создание контрольной суммы

Конструкция create_checksum может использоваться только в функциях и поддерживает расчет контрольных сумм TCP и UDP.

Таблица 13. Конструкция create_checksum.

Конструкция

Аргументы, опции

Описание

create_checksum

Создает контрольную сумму.

checksum_field

Задает имя поля контрольной суммы в пакете (<packet.field>).

<packet_field_list>

Упорядоченный список полей для расчета контрольной суммы. <packet._PAYLOAD> считается флагом включения данных в контрольную сумму.

create_checksum(egress_pkt.group2.ipv4.hdr_checksum,
	{egress_pkt.group2.ipv4.version, egress_pkt.group2.ipv4.hdr_len,
	egress_pkt.group2.ipv4.tos, egress_pkt.group2.ipv4.v4_length,
	egress_pkt.group2.ipv4.id, egress_pkt.group2.ipv4.flags,
	egress_pkt.group2.ipv4.frag_offset, egress_pkt.group2.ipv4.ttl,
	egress_pkt.group2.ipv4.protocol, egress_pkt.group2.ipv4.sa,
	egress_pkt.group2.ipv4.da});

create_checksum(egress_pkt.fwd_l3_l4_hdr.udp.checksum,
	{egress_pkt.fwd_l3_l4_hdr.ipv4.sa,
	egress_pkt.fwd_l3_l4_hdr.ipv4.da,
	editor_dummy_bus.zero_byte,
	egress_pkt.fwd_l3_l4_hdr.ipv4.protocol,
	egress_pkt.fwd_l3_l4_hdr.udp.udp_length,
	egress_pkt.fwd_l3_l4_hdr.udp.src_port,
	egress_pkt.fwd_l3_l4_hdr.udp.dst_port,
	egress_pkt.fwd_l3_l4_hdr.udp.udp_length,
	egress_pkt.fwd_l3_l4_hdr.udp._PAYLOAD});

4.10.5. Обновление размера пакета

Конструкция update_packet_length может применяться только в функциях.

Таблица 14. Конструкция update_packet_length.

Конструкция

Аргументы, опции

Описание

update_packet_length

Обновляет размер пакета.

packet_length_field

Задает имя поля размера в пакете (<packet.field>).

update_type

Задает тип обновления размера пакета:

  • 0 указывает использование лишь размера данных (payload) пакета;

  • 1 указывает использование данных и заголовка.

truncate_mode

Указывает выполнение отсечки пакета:

  • 0 — пакет не усекается;

  • 1 пакет усекается.

update_packet_length(egress_pkt.group2.ipv4.v4_length, 1);

Пример

Использование create_checksum и update_packet_length

function do_checksum_update() {
	create_checksum(egress_pkt.group2.ipv4.hdr_checksum,
		{egress_pkt.group2.ipv4.version, egress_pkt.group2.ipv4.hdr_len,
		egress_pkt.group2.ipv4.tos, egress_pkt.group2.ipv4.v4_length,
		egress_pkt.group2.ipv4.id, egress_pkt.group2.ipv4.flags,
		egress_pkt.group2.ipv4.frag_offset, egress_pkt.group2.ipv4.ttl,
		egress_pkt.group2.ipv4.protocol, egress_pkt.group2.ipv4.sa,
		egress_pkt.group2.ipv4.da});
	create_checksum(egress_pkt.group4.ipv4.hdr_checksum,
		{egress_pkt.group4.ipv4.version, egress_pkt.group4.ipv4.hdr_len,
		egress_pkt.group4.ipv4.tos, egress_pkt.group4.ipv4.v4_length,
		egress_pkt.group4.ipv4.id, egress_pkt.group4.ipv4.flags,
		egress_pkt.group4.ipv4.frag_offset, egress_pkt.group4.ipv4.ttl,
		egress_pkt.group4.ipv4.protocol, egress_pkt.group4.ipv4.sa,
		egress_pkt.group4.ipv4.da});
}

function do_packet_length_update() {
	update_packet_length(egress_pkt.group2.ipv4.v4_length, 1);
	update_packet_length(egress_pkt.group4.ipv4.v4_length, 1);
}

program app {
	...
	do_packet_length_update();
	do_checksum_update();
	...
}

5. Конструкции для целевой платформы

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

  1. внешние функции платформы;

  2. специальные функции;

  3. динамические таблицы.

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

Конструкции специальных функций используются для указания ускорителей или блока IP7 целевой платформы и режимов их использования. Для специальных функций нужны особые соединения в терминах входов и выходов. Внутреннее устройство специальных функций на задается в NPL, это остается за производителем, программы NPL просто вызывают функции.

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

5.1. Внешние функции целевой платформы

Каждое сетевое устройство имеет набор фундаментальных функций, вызываемых многократно. Например, отбрасывание пакета, копирование в CPU или другой порт для трассировки или подсчета пакетов. Эти базовые функции могут быть связаны с logical_table, функцией или иной конструкцией NPL. Например, отбрасывание пакета является частью поиска в логической таблице, а отображение пакета (mirroring) — частью функции обработки.

NPL позволяет производителям платформ задавать такие функции как внешние. Производитель задает шаблон внешней функции с информацией, требуемой для эффективного использования оборудования.

5.1.1. Определение внешней функции

Определяемый производителем шаблон внешней функции аналогичен применяемым в других языках.

Таблица 15. Конструкция extern.

Конструкция

Аргументы, опции

Описание

extern <имя функции>

Заданная производителем внешняя функция.

direction

in или out.

Имя поля

Задает поля с размером и типом.

Пример

Определение внешней функции для отбрасывания пакетов

extern packet_drop(in bit[1] trigger, in const value, in const drop_code);

Здесь trigger указывает то или иное поле шины, которое может вызывать отбрасывание пакета. Остальные свойства связаны с процедурой отбрасывания.

5.1.2. Применение внешних функций

Разработчик программ NPL может вызывать внешние функции из приложения, помещая вызовы в logical_table или function.

Пример

logical_table packet_integrity {
....
	fields {
		bit copy_to_cpu;
		bit pkt_integrity_drop;
	}
......
	fields_assign() {
		....
		packet_drop(pkt_integrity_drop, drop_reason.PKT_INTEGRITY_CHECK_FAILED, 2);
	}
}

5.2. Конструкция для специальных функций

5.2.1. Определение специальной функции

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

Таблица 16. Конструкция special_function.

Конструкция

Аргументы, опции

Описание

special_function

Заданная производителем внешняя функция.

special_function_name

Задает имя IP-блока.

<generic method>([in/out] [const] или [auto_enum] или [str] или [bit/varbit][size] или [list] [name])

Прототип метода IP-блока, задающий направление и типа аргументов. Предоставляется производителем платформы. Компилятор для платформы должен обеспечивать обработку определений и вызовов. Поддерживается множество методов. Тип varbit указывает маскируемый аргумент.

5.2.1.1. Пример задания special_function для целевой платформы

Производитель платформы может применять разные методы для задания интерфейса с IP-блоком.

Пример

special_function flex_qos_phb {
	usage_mode_create(in const index,
		in bit[10]
 		qos_base,
		in varbit[6] qos_attr,
		out bit[4]
 		int_pri);
	usage_mode_select(in bit[6] eindex);
}

5.2.2. Использование специальных функций

Программист NPL связывает блоки IP с логической функциональностью в программе NPL, используя:

  • методы из библиотеки special_function целевой платформы;

  • встроенный в NPL метод execute().

5.2.2.1. Методы специальных функций

Разработчик программ NPL использует методы special_function, предоставляемые целевой архитектурой, для задания соединений с блоками IP. Размещение вызовов этих блоков в коде NPL не отражает последовательность вызовов. Синтаксис вызова показан ниже. Тип и порядок аргументов должны совпадать с указанными в шаблоне. Аргументы метода special_function method передаются по ссылкам.

<special_function_name>.<method_name>(<arguments>)
5.2.2.2. execute()

Встроенный метод execute() не задается в конструкции special_function. Этот метод активирует блок IP и обеспечивает его относительную позицию в логической функциональности. Метод не использует аргументов.

Таблица 17. Конструкция execute().

Конструкция

Аргументы, опции

Описание

execute()

Встроенный метод активирования блока IP.

5.2.2.3. Пример использования special_function для целевой платформы

Программист NPL может получить доступ к IP-блоку целевой платформы, используя прототипы метода special_function.

Пример

program app {
	...
	flex_qos_phb.usage_mode_create(flex_qos_entry.QOS_MPLS_EXP_L3_TUNNEL_ECN,
		ing_obj_bus.mpls_exp_mapping_ptr[9:0],
		ing_cmd_bus.mpls_effective_exp_for_phb,
		ing_cmd_bus.int_pri);
	flex_qos_phb.usage_mode_create(flex_qos_entry.QOS_MPLS_EXP_L2_TUNNEL_ECN,
		ing_obj_bus.mpls_exp_mapping_ptr[9:0],
		ing_cmd_bus.mpls_effective_exp_for_phb1,
		ing_cmd_bus.int_pri1);
	...
	flex_qos_phb.usage_mode_select(phb_select_lts_tcam_key.entry_index);
	flex_qos_phb.execute();
	...
}

5.3. Конструкции для динамических таблиц

5.3.1. dynamic_table

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

Определение dynamic_table предоставляет производитель платформы и оно не имеет явных входных или выходных соединений, лишь указывая SDK, как использовать динамические таблицы. Таблица может иметь множество методов для поддержки разных целей. Размер dynamic_table определяется равным 1.

Таблица 18. Конструкция dynamic_table.

Конструкция

Аргументы, опции

Описание

dynamic_table

Задает динамическую таблицу.

dynamic_table_name

Имя блока динамической таблицы

<generic method>([in/out] [list] [name])

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

5.3.1.1. Пример определения dynamic_table для целевой платформы

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

Пример

dynamic_table ing_fp {
	presel_template(in list presel_menu);
	rule_template(in list rule_menu);
	action_template(out list action_menu);
}

5.3.2. Использование динамических таблиц

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

5.3.2.1. <dynamic_table_name>.<method_name>(<argument_list>)

Разработчик NPL применяет методы dynamic_table, предоставленные целевой архитектурой, для связывания логических сигналов с блоками динамической таблицы. Местоположение вызовов методов в NPL не отражает реальный порядок вызовов. Формат вызова шаблона метода имеет вид

<dynamic_table_name>.<method_name>(<argument_list>)

Аргументы метода динамической таблицы передаются ссылками.

5.3.2.2. lookup()

Встроенный метод lookup() не задается в конструкции dynamic_table и служит для задания места вызова dynamic_table.

Таблица 19. Конструкция lookup().

Конструкция

Аргументы, опции

Описание

lookup()

Встроенный метод для вызова блока динамической таблицы.

5.3.2.3. Образец применения dynamic_table для целевой платформы

Разработчик NPL может получить доступ к блоку dynamic_table целевой платформы, используя прототипы методов dynamic_table.

Пример

program {
	...
	ing_fp.presel_template({
		ing_cmd_bus.l2_iif_opaque_ctrl_id,
		ing_cmd_bus.l3_iif_opaque_ctrl_id,
		...
	});
	ing_fp.rule_template({
		pkt_fwd_field_bus.macda,
		pkt_fwd_field_bus.macsa,
		...
	});
	ing_fp.action_template({
		ifp_scratch_bus.ifp_drop_action,
		ifp_scratch_bus.ifp_drop_code,
		...
	});
ing_fp.lookup(); // поиск служит конструктором для dynamic_table
}

6. Конструкции сравнения силы

В парадигме NPL может одновременно выполняться поиск в нескольких таблицах. Когда несколько таблиц назначает (assign) один и тот же объект, нужен механизм выбора между ними. В NPL используется механизм выбора на основе «силы» (strength), которая задается численным значением.

В NPL имеются конструкции для связывания значений силы с результатами поиска. При каждом поиске создается профиль силы для результата. Значение силы может быть статическим (для таблицы) или динамическим (для записи).

Для выбора на основе силы в NPL используется несколько конструкций:

  • сила записей логических таблиц;

  • таблица fields_assign() для указания необходимости сравнения силы;

  • функция сравнения силы.

6.1. Создание логической таблицы силы

Конструкция strength объявляет прототип для записей логической таблицы силы, которая может содержать одно или несколько полей strength. Для создания таблицы применяются конструкции struct, указываюшие поля, нужные для сравнения силы. Эта структура может включать лишь поля типа bit (но не вложенные struct). Экземпляры таблиц создаются с помощью конструкции strength, имя которой должно быть уникальным в глобальном масштабе. Записи таблицы для поиска при сравнении силы задаются конструкуиями strength_resolve.

Таблица 20. Конструкция strength.

Конструкция

Аргументы, опции

Описание

strength

Создает экземпляр таблицы силы.

Имя struct

Имя структуры таблицы силы, имена полей которой представляют элементы записи таблицы силы (тип struct).

Имя таблицы

Имя таблицы силы в форме строки (string).

6.2. Присоединение таблицы силы

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

Таблица 21. Конструкция use_strength.

Конструкция

Аргументы, опции

Описание

use_strength

Привязывает таблицу силы к логической таблице.

strength table name

Имя таблицы силы, объявленное со структурой strength.

index

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

  • константой, определяемой при компиляции;

  • полем данной логической таблицы (динамическая сила);

  • полем шины.

6.3. Конструкция strength_resolve

Конструкция strength_resolve задает объект шины, который назначается с помощью сравнения силы. Она также задает (strength_list) значение силы для каждого сравниваемого поиска logical_table. Соответствующие записи (source_field_list) связывают значения силы с результатами поиска в таблице, которые нужно сравнить (индексы use_strength). Таблица с наибольшим значением силы будет предоставлять значение объекта шины.

Таблица 22. Конструкция strength_resolve.

Конструкция

Аргументы, опции

Описание

strength_resolve

Задает способ назначения объекта выбранного из разных источников.

destination bus.field

Поле шины bus.field, куда передается объект после сравнения силы.

destination bus.field strength

Сила, связанная с целевым bus.field (bus.field или NULL).

<strength_entry_0>

Список свойств, описывающих первый элемент силы (см. strength_entry).

<strength_entry_1>

Список свойств, описывающих второй элемент силы (см. strength_entry).

<strength_entry_n>

Список свойств, описывающих nый элемент силы (см. strength_entry).

strength_entry

{table_lookup, user_defined_view_type, strength, source_field}

table_lookup

Указывает поиск в таблице, где source_field имеет значение table.field (table._LOOKUP0 или table._LOOKUP1).

user_defined_view_type

Задает тип представления поля, заданный пользователем. Используется то же значение auto_enum, которое задано в блоке fields_assign(). Возможны значения auto_enum и NULL.

strength

Сила, связанная с результатом logical_table, соответствующим сравниваемому объекту (поле силы table.field).

source_field

Исходное поле, которое может быть назначено целевому полю (logical_table.field).

Пример

Указание статической силы для объекта, полученного из 2 таблиц

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

if (obj_strength_profile[1].obj_k_str > obj_strength_profile[2].obj_k_str)
	cmd_bus.obj_k = Table_A.obj_k;
else
	cmd_bus.obj_k = Table_B.obj_k;

Рисунок 3. Сила при использовании таблиц со статическим индексированием.

Конструкция будет иметь вид

struct cmd_bus_t {
	fields {
		bit[8]	obj_k;
	}
}

struct obj_strength_t {
	fields {
		bit[4]	obj_k_str;
	}

bus cmd_bus_t	cmd_bus;
strength obj_strength_t	obj_strength_profile; // таблицы профилей силы

logical_table Table_A {
	...
	fields {
		bit[8]	obj_k;
	}
	fields_assign() {
		use_strength(obj_strength_profile, 1);	// ссылка на запись таблицы профилей силы
	}
}

logical_table Table_B {
	...
	fields {
		bit[8]	obj_k;
	}
	fields_assign() {
		use_strength(obj_strength_profile, 2); // ссылка на запись таблицы профилей силы
	}
}

program app {
	...
	strength_resolve(cmd_bus.obj_k, NULL,
		{ Table_A._LOOKUP0, NULL, obj_strength_profile.obj_k_str, Table_A.obj_k},
		{ Table_B._LOOKUP0, NULL, obj_strength_profile.obj_k_str, Table_B.obj_k});
	...
}

Указание динамической силы для объекта, полученного из 2 таблиц

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

if (obj_strength_profile[index_A].obj_k_str > obj_strength_profile[index_B].obj_k_str)
	cmd_bus.obj_k = Table_A.obj_k;
else
	cmd_bus.obj_k = Table_B.obj_k;

Рисунок 4. Сила при использовании таблиц со динамическим индексированием.

Конструкция будет иметь вид

struct cmd_bus_t {
	fields {
		bit[8]	obj_k;
	}
}

struct obj_strength_t {
	fields {
		bit[4]	obj_k_str;
	}
}

bus cmd_bus_t cmd_bus;
strength obj_strength_t obj_strength_profile;

logical_table Table_A {
	...
	fields {
		bit[8]	obj_k;
		bit[5]	strength_index;
	}
	fields_assign() {
		use_strength(obj_strength_profile, strength_index);
	}
}

logical_table Table_B {
	...
	fields {
		bit[8]	obj_k;
		bit[5]	strength_index;
	}
	fields_assign() {
		use_strength(obj_strength_profile, strength_index);
	}
}
program app {
	...
	strength_resolve(cmd_bus.obj_k, NULL,
		{ Table_A._LOOKUP0, NULL, obj_strength_profile.obj_k_str, Table_A.obj_k},
		{ Table_B._LOOKUP0, NULL, obj_strength_profile.obj_k_str, Table_B.obj_k});
	...
}

Указание силы для объекта, полученного из таблицы и шины

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

if (obj_strength_profile[a_strength_index].obj_k_str > cmd_bus.obj_k_str)
	cmd_bus.obj_k = Table_A.obj_k;
	else
cmd_bus.obj_k = cmd_bus.obj_k;

Рисунок 5. Сила при использовании таблицы и шины.

Конструкция будет иметь вид

struct cmd_bus_t {
	fields {
		bit[8]	obj_k;
		bit[4]	obj_k_str;
	}
}
struct obj_strength_t {
	fields {
	bit[4]	obj_k_str;
	}
}

bus cmd_bus_t cmd_bus;
strength obj_strength_t obj_strength_profile;

logical_table Table_A {
	...
	fields {
		bit[8]	obj_k;
		bit[3]	a_strength_index;
	}
	fields_assign() {
		use_strength(obj_strength_profile, a_strength_index);
	}
}

program () {
	strength_resolve(cmd_bus.obj_k, cmd_bus.obj_k_str,
		{Table_A._LOOKUP0, NULL, obj_strength_profile.obj_k_str, Table_A.obj_k});
}

Указание силы при использовании двух таблиц с множественным поиском

struct obj_bus_t {
	fields {
		bit[12]	dst_vlan;
		bit[12]	src_vlan;
		bit[11]	dst_vfi;
		bit[11]	src_vfi;
	}
}

struct cmd_bus_t {
	fields {
		bit	dst_discard;
		bit	src_discard;
	}
}

struct UAT_strength_profile_t {
	fields {
		bit[4] obj_src_discard_str;
		bit[4] obj_K_str;
	}
}

strength UAT_strength_profile_t UAT_strength_profile;
bus obj_bus_t obj_bus;
bus cmd_bus_t cmd_bus;

// множество поисков
logical_table Table_A {
	...
	field {
		bit[12] vlan;
		bit	discard; // поле сравнения силы
	}
	fields_assign() {
		if (_LOOKUP0)
			obj_bus.dst_vlan = vlan;
		if (_LOOKUP1)
			obj_bus.src_vlan = vlan;
		use_strength(UAT_strength_profile, 10);
	}
}

// один поиск, не нужно добавлять _LOOKUP0 в fields_assign().
logical_table Table_C {
	...
	field {
		bit[11] vfi;
		bit	discard; // поле сравнения силы
	}
	fields_assign() {
		obj_bus.dst_vfi = vfi;
	}
}

// То же, что Table_A, но с заданной ниже логикой силы
logical_table Table_B {
	...
	field {
		bit[11] vfi;
		bit	discard; // поле сравнения силы
	}
	fields_assign() {
		if (_LOOKUP0) {
			obj_bus.dst_vfi = vfi;
		}
		if (_LOOKUP1) {
			obj_bus.src_vfi = vfi;
		}
		use_strength(UAT_strength_profile, 20);
	}
}
program () {
	...
	// два поиска
	Table_A.lookup(0);
	Table_A.lookup(1);
	// один поиск
	Table_C.lookup(0);
	
	// два поиска
	Table_B.lookup(0);
	Table_B.lookup(1);
	strength_resolve(cmd_bus.src_discard, NULL,
	  {Table_A._LOOKUP1, NULL, UAT_strength_profile.obj_src_discard_str, Table_A.discard},
	  {Table_B._LOOKUP1, NULL, UAT_strength_profile.obj_src_discard_str, Table_B.discard});
	strength_resolve(cmd_bus.dst_discard, NULL,
	  {Table_A._LOOKUP0, NULL, UAT_strength_profile.obj_K_str, Table_A.discard},
	  {Table_B._LOOKUP0, NULL, UAT_strength_profile.obj_K_str, Table_B.discard});
	...
}

6.4. Сравнение силы с помощью функции

Конструкция function может также применяться для сравнения силы при последовательном обращении к таблицам. При компиляции может быть выбрана иная схема отображения.

7. Базовые конструкции

7.1. Атрибуты NPL

Атрибуты NPL служат для передачи намерений программы NPL в файлы yaml, которые будут доступны для извлечения соответствующей информации. Атрибуты помещаются в «скобки» <! и !>. Компилятор не пытаяется проверять содержимое атрибутов NPL.

7.1.1. Позиционные атрибуты

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

Атрибуты NPL поддерживаются для перечисленных ниже элементов:

  • logical_table — ключи, поля;

  • logical_register — поля;

  • шина (struct) — поля, наложения;

  • заголовок пакета (struct) — поля;

  • special_function и dynamic_table.

Компляторы могут распространять атрибуты NPL в выходные файлы для целевой платформы. Например, целевой компилятор может распространить документацию logical_table в выходной файл Regsfile или Map.

Таблица 23. Позиционные атрибуты.

Дескриптор

Назначение

Описание

REGSFILE, DESC: <desc>

logical_regsfile.yml

header.yml

Применимы к logical_table, logical_table.field, logical_table.key, logical_register, logical_register.field, struct, (bus/header) struct.field. (bus/header)

Атрибут <desc> применяется как TABLE <tbl> DESC, TABLE <tbl.fld> DESC, REGISTER <reg> DESC, REGISTER <reg.fld> DESC, FORMAT <struct> DESC, FORMAT <struct.fld> DESC, HEADER <struct> DESC, HEADER <struct.fld> DESC.

REGSFILE, ENCODING: <enum>

logical_regsfile.yml

Применимы к logical_table.field.

Атрибут <enum> применяется как поле таблицы, ENCODINGS

REGSFILE, ENCODING: DESC:

enum.field = <desc>

logical_regsfile.yml

Применимы к logical_table.field, enum.field.

Атрибут <desc> применяется как поле
logical_table, поле ENCODINGS, DESC.

REGSFILE, FIELD_NAME: <field>

logical_sftblfile.yml

Применимы к dynamic_table.arg.

Атрибут <field> применяется как dyamic_table.field

Пример (REGSFILE, DESC: <desc>)

Код NPL

<!(REGSFILE, DESC: "This table is looked up using Layer 2 incoming interface packet was received on. This table provides incoming Layer 2 interface attributes for the packet.") !>
logical_table ing_l2_iif_table {
	...
	fields {
		<!(REGSFILE, DESC: "If set, IPV6 Tunnel is enabled on this interface.") !>
		bit ipv6_tunnel_enable;
	}
}

Представление Regsfile

TABLE = {
	ing_l2_iif_table:
	DESC: |-
		This table is looked up using Layer 2 incoming interface packet was received on.
		This table provides incoming Layer 2 interface attributes for the packet.
	FIELDS:
		ipv6_tunnel_enable:
			DESC: |-
				If set, IPV6 Tunnel is enabled on this interface.
			MAXBIT: 13
			MINBIT: 13
			ORDER: 4
			TAG: data
			WIDTH: 1

Пример (REGSFILE, ENCODING: <enum>)/(REGSFILE, ENCODING: DESC: enum.field = <desc>)

Код NPL

enum pvlan_port {
	PVLAN_PROMISCUOUS_PORT = 0,
	PVLAN_COMMUNITY_PORT = 1,
	PVLAN_ISOLATED_PORT = 2
}
logical_table ing_vfi_table {
	...
	fields {
		<!REGSFILE, ENCODING: pvlan_port !> !
		<!REGSFILE, ENCODING: DESC: pvlan_port.PVLAN_PROMISCUOUS_PORT = Pvlan Promiscuous 		port !>
		bit[FIELD_2_WD] src_pvlan_port_type;
	}
}

Представление Regsfile

ing_vfi_table:
	FIELDS:
		src_pvlan_port_type:
			ENCODINGS:
				pvlan_port__PVLAN_PROMISCUOUS_PORT:
					DESC: |-
						Pvlan Promiscuous port
					VALUE: 0
				pvlan_port__PVLAN_COMMUNITY_PORT:
					DESC: ‘’
					VALUE: 1
				pvlan_port.PVLAN_ISOLATED_PORT
					DESC: ‘’
					VALUE: 2

Пример (REGSFILE, FIELD_NAME: <field>)

Код NPL

dynamic_table egr_flex_ctr {
	presel_template (in list presel_menu);
	object_template (in list object_menu);
}
	egr_flex_ctr.presel_template(
	{
		<!REGSFILE, FIELD_NAME: "mirror_pkt_ctrl_0" !>
		egr_cmd_bus.mirror_pkt_ctrl
	});

Представление Regsfile

dt_egr_flex_ctr_presel_template:
	FIELDS:
		mirror_pkt_ctrl_0:
			BUS_SELECT_WIDTH: 4
			DESC: |-
				Input - egr_cmd_bus_mirror_pkt_ctrl
			MAXBIT: 65
			MINBIT: 2
			ORDER: 2
			TAG: bus_select
			WIDTH: 64

7.1.2. Непозиционные атрибуты

Непозиционные атрибуты позволяют разработчику NPL полностью передать свои намерения. Все такие атрибуты собираются в выходном файле IFILE (Intent File) формата yaml. Другие атрибуты в IFILE не включаются. В файле атрибуты группируются по указанной функциональности, которую они поддерживают. Программист NPL отвечает за указание формата содержимого непозиционных атрибутов, а потребитель таких атрибутов — за их анализ и преобразование в желаемый формат, а также проверку атрибутов. Потребитель IFILE должен создать утилиту для приема выхода компилятора и преобразования его в желаемый формат с проверкой.

Непозиционные атрибуты NPL передаются в IFILE на основе описаний.

Таблица 24. Непозиционные атрибуты.

Дескриптор

Назначение

Описание

(IFILE, <blk>: <code>)

ifile.yml

Поле <code> добавляется к блоку <blk> в файле IFILE.

7.1.2.1. Инициализация

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

Пример

Код NPL

// назначение логической таблицы NPL
<! IFILE, INIT: ”lt ing_l3_next_hop_1_table nhop_index_1=0 dvp=0x0 l3_oif_1=0x0” !>

// назначение физического ресурса по потребности
<! IFILE, INIT: ”pt IFTA150_SBR_PROFILE_TABLE_0_INDEX=10 strength=0x5” !>

// назначение символьного элемента (в будущем)
<! IFILE, INIT: ”lt _SYMBOL=TIMESTAMP _INDEX=10 data=0x5” !>

// использование перечисляемого NPL
<! IFILE, INIT: ”pt EPOST_FMT_AUX_BOTP_IN_DATA mtu_drop=NPL_EGR_MTU_DROP_ENUM” !>

Выходной IFILE

INIT:
	0: |-
		lt ing_l3_next_hop_1_table nhop_index_1=0 dvp=0x0 l3_oif_1=0x0
	1: |-
		pt IFTA150_SBR_PROFILE_TABLE_0_INDEX=10 strength=0x5
	2: |-
		lt _SYMBOL=TIMESTAMP _INDEX=10 data=0x5
	3: |-
		pt EPOST_FMT_AUX_BOTP_IN_DATA mtu_drop=NPL_EGR_MTU_DROP_ENUM
7.1.2.2. Relational

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

Пример

Код NPL

<! IFILE, REL: ”ecmp_level0:npl_ecmp_level0_member_table” !>

Выходной IFILE

REL:
	0: |-
		ecmp_level0:npl_ecmp_level0_member_table

7.2. Конструкции препроцессора

7.2.1. #include

Директива #include служит для включения исходного кода NPL в другую программу NPL.

#include "bus.npl"			// файл из того же каталога
#include "../lib/header.npl"	// файл из другого каталога

7.2.2. #if — #endif

NPL поддерживает условную компиляцию в стиле C/C++.

#ifdef XYZ

7.2.3. #define

NPL поддерживает макросы в стиле C/C++ для переменных, но без параметризации. Определения задаются заглавными буквами.

#define CPU_PORT		5
#define MAC_ADDR_BCAST	0xffffffffffff

7.3. Комментарии

NPL поддерживает 2 варианта комментариев:

  • многострочные с использованием символов /* и */. Такие комментарии можно включать в строку (in-line);

  • однострочные от символов // до конца строки.

7.4. print

NPL использует конструкцию print для вывода значений переменных в программе. Команда print транслируется в модель Behavioral C. Это не имеет значения с точки зрения компиляции. Вызов print в модели C выполняется в том же порядке, что и в программе NPL. Печатаются только поля (не struct). Команда print работает аналогично C printf.

print("Value of the SVP is %d, VFI is %d\n", obj_bus.svp, obj_bus.vfi);

8. Приложение A. Пример конвейера

Пример конвейера в коммутаторе показан на рисунке. Язык NPL может поддерживать разную архитектуру.

Parser задает и изменяет поведение аппаратного блока синтаксического анализа (HW Parser Block).

Match Action — логические таблицы и регистры NPL, задающие и изменяющие поведение блоков «сопоставление-действие» (Match Action Block).

Target IP — блок IP, относящийся к производителю платформы и представленный конструкцией special_function.

Processing Unit — базовый элемент обработки на целевой платформе, поведение которого задают и изменяют функции NPL и сравнение силы.

Editor — редактор NPL, определяющий поведение блока редактирования.

Целевая платформа может использовать несколько экземпляров этих блоков в произвольном порядке.

9. Приложение B. Рекомендации по использованию

9.1. struct в заголовках

Объекты верхнего уровня (например, logical_table, logical_register, enum) не могут быть частью struct. NPL поддерживает вложенные структуры с учетом приведенных ниже ограничений.

Таблица 25. Использование struct.

Применение

bit/bit[n]

overlay

struct

Вложенные struct

Тип header

+

Тип header_group

+

Пакет

+

Шина

+

+

+

+

Таблица 26. Ссылки на struct в пакетах.

Действительная конструкция

Возможно

Описание ссылки

packet.struct.struct.field

+

packet.group.header.field

packet.struct.struct

+

packet.group.header

packet.struct.field

Нет группы/заголовка

packet.field

Пакет должен иметь группу/заголовок

Нет пакета

9.2. Функции

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

9.3. Правила наложения

Наложения могут применяться во многих конструкциях и должны следовать приведенным ниже правилам.

  1. Поля наложения могут быть заданы для базовых полей типа bit и bit[n].

  2. Поля наложения могут быть заданы для базовых полей типа struct (т. е., полей, заданных как struct в шине). Однако для struct не разрешено частичное наложение.

  3. Наложения могут перекрываться.

  4. Не допускается задание наложений для других полей наложения.

  5. Наложенные поля не могут иметь тип struct.

9.4. «Нарезка» битовых массивов

NPL поддерживает «нарезку» (диапазон) битовых массивов (bit-array) в назначениях, уравнениях, специальных функциях. Диапазоны битов можно указывать в обеих частях (lvalue и rvalue) уравнений.

Пример

a = b[7:4];
if (b[5:3])...
obj_bus.a[5:4] = ing_pkt.ipv4.ecn;	// в основном функции и действия
a = b[0:0];					// доступ к одному биту с указанием диапазона 1 бит

Варианты применения

  1. if (a[5:3]) 		// корректно
  2. a[5:3] = b[5:3]; 	// корректно

9.5. Правила конкатенации

  • При назначении конкатенация разрешена лишь в правой стороне уравнений. Обычно она применяется для полей varbit.

    a = b<>c;
  • Конкатенация не разрешена в левой части уравнения.

    b<>c = a[5:0];
  • Конкатенация разрешена для однотипных полей (например, struct<>struct).

    two_mpls_hdrs = mpls_hdr_0<>mpls_hdr_1;
  • Конкатенация разрешена для разнотипных полей (например, struct<>bit).

    new_mpls_hdr = mpls_hdr_0<>c[3:0];
  • Конкатенация разрешена для частей полей (например, da[5:0]<>sa[5:3]).

    a[5:0] = b[3:2]<>c[3:0];
  • При сравнении со значением регистра поддерживается лишь оператор ==.

10. Приложение C. Зарезервированные слова NPL

fields_assign

add_header

auto_enum

bit

bus

create_checksum

default

delete_header

define

dynamic_table

else

enum

extract_fields

fields

function

hash

header_length_exp

if

index

keys

latest

logical_register

logical_table

mask

maxsize

minsize

next_node

NPL_PRAGMA

overlays

packet

keys_construct

parse_break

parse_continue

parse_begin

end_node

parser_node

print

program

replace_header_field

root_node

special_function

strength

strength_resolve

struct

switch

table_type

tcam

update_packet_length

use_strength

varbit

_HIT_INDEXx

_LOOKUPx

_PRESENT

_VALID

extern

true

false

11. Приложение D. Грамматика NPL

В этом приложении описана грамматика NPL с использованием нотации yacc.

Лексер маркирует идентификаторы (ID) для заданных пользователем имен регулярным выражением [A-Za-z_][\w_]*. Десятичные константы должны быть натуральными числами. Шестнадцатеричные константы задаются в обычной форме (например, 0x0f, 0X0f, 0x0F). Константы размера подобны шестнадцатеричным константам с размерами в стиле printf (например, 8×00). Строковые константы должны заключаться в двойные кавычки и не содержать символов новой строки (например, “foo.bar”).

Идентификаторы

primary_types:	constant
			| identifier

			|STR_CONST	/* r'\"([^\\\n]|(\\.))*?\"' */
constant :		|DEC_CONST	/* ([0-9][0-9]*) */
			|HEX_CONST	/* (0[xX][0-9A-Fa-f]+) */

identifier : ID

dir :	IN
	| OUT

Объявления

npl_node :	npl_declaration_specifier
		| empty

npl_declaration_specifier :	npl_declaration
					| npl_declaration_specifier npl_declaration

npl_declaration :	struct_definition_specifier
			|packet_definition_specifier
			|strength_definition_specifier
			|bus_definition_specifier
			|sp_definition_specifier
			|function_definition_specifier
			|special_func_defintion_specifier
			|enum_defintiion_specifier
			|program_definition_specifier
			|table_definition_specifier
			|register_definition_specifier
			|parsernode_definition_specifier
			|print_command
			|generic_block

array_access_format : ‘[’ postfix_expression ‘]’

range_access_format : ‘[’ postfix_expression ‘:’postfix_expression ‘]’

declaration_expn :	BIT identifier ‘;’
			| BIT array_access_format identifier ‘;’
			| VARBIT array_access_format identifier ‘;’
			| identifier identifier ‘;’
			| identifier identifier array_access_format ‘;’
			| BIT array_access_format identifier ‘==’ constant ‘;’

field_declarator :	:FIELDS ‘{’ field_declaration_list ‘}’

field_declaration_list :	declaration_expn
				| field_declaration_list declaration_expn

key_declarator :	KEYS ‘{’ field_declaration_list ‘}’

Наложение

overlay_declarator :	OVERLAYS ‘{’ overlay_declaration_list ‘}’

overlay_declaration_list:	overlay_expression :
				| overlay_declaration_list overlay_expression

overlay_expression :	identifier ‘:’ concat_format_list ‘;’

Конкатенация сигналов

concat_format_list :	concat_format
				| concat_format_list CONCAT concat_format

concat_format :	identifier
			| identifier range_access_format

Структура

struct_definition_specifier : 	STRUCT identifier ‘{’ struct_body ‘}’
					| STRUCT identifier ‘{’field_declaration_list ‘}’
					| STRUCT ‘{’struct_body‘}’

struct_body :		field_declarator header_len_opt
			| struct_body overlay_declarator

header_len_opt :	HEADER_LENGTH_EXP ‘:’ expression_statement
			| empty

Перечисление

enum_defintiion_specifier : ENUM postfix_expression args_list_format

Объявление шины

bus_definition_specifier : BUS identifier identifier ‘;’

Объявление таблицы

table_definition_specifier : LOGICAL_TABLE identifier ‘{’ table_body_block ‘}’
table_type
table_body_block : 	table_body
			| table_body_block table_body

table_body : TABLE_TYPE ‘:’ table_type
	| key_declarator
	| field_declarator
	| KEY_CONSTRUCT key_construct_definition_block
	| FIELDS_ASSIGN fields_assign_definition_block
	| MAXSIZE ‘:’ constant ‘;’
	| MINSIZE ‘:’ constant ‘;’

table_type : INDEX ‘;’
		| HASH ‘;’
		| TCAM ‘;’
		| ALPM ‘;’

table_keys_list : table_keys_expression
		| table_keys_list table_keys_expression

table_keys_expression : postfix_expression ‘;’

key_construct_definition_block : ‘{’ generic_statement_list ‘}’

fields_assign_definition_block : ‘{’ generic_statement_list ‘}’

Объявление регистра

register_definition_specifier : LOGICAL_REGISTER identifier ‘{’ field_declarator ‘}’

Объявление пакета

packet_definition_specifier : packet_instance
packet_instance : PACKET identifier identifier ‘;’

Strength

strength_definition_specifier : strength_instance
strength_instance : STRENGTH identifier identifier ‘;’

Блок операторов

generic_statement_list : generic_block
				| generic_statement_list generic_block

generic_block : statement

statement : expression_statement
		| select_statement
		| compound_statement
		| label_statement
		| header_command
		| parser_statement
		| pragma_call

compound_statement : ‘{’ generic_statement_list ‘}’

Условные операторы

select_statement :	IF ‘(’ expression ‘)’ statement ELSE statement
			| IF ‘(’ expression ‘)’ statement
			| SWITCH ‘(’ expression ‘)’ statement

label_statement :	postfix_expression ‘:’ statement
			| DEFAULT ‘:’ statement
			| constant MASK constant ‘:’ next_node

Выражения

expression_statement : expression ‘;’

expression :	assignment_expression
		| lookup_statement
		| parse_init
		| function_call

assignment_expression : generic_expression
			| generic_expression assignment_operator assignment_expression

generic_expression : binary_expression

binary_expression :	unary_expression
			| function_call
			| binary_expression	‘!=’ binary_expression
			| binary_expression	‘==’ binary_expression
			| binary_expression	‘&’ binary_expression
			| binary_expression	‘<’ binary_expression
			| binary_expression	‘<=’ binary_expression
			| binary_expression	‘>=’ binary_expression
			| binary_expression	‘>’ binary_expression
			| binary_expression	‘|’ binary_expression
			| binary_expression	‘^’ binary_expression
			| binary_expression	‘&&’ binary_expression
			| binary_expression	‘||’ binary_expression
			| binary_expression	‘<<’ binary_expression
			| binary_expression	‘>>’ binary_expression
			| binary_expression	‘*’ binary_expression
			| binary_expression	‘+’ binary_expression
			| binary_expression	‘-’ binary_expression
			| binary_expression	‘/’ binary_expression
			| binary_expression	‘%’ binary_expression
			| binary_expression	‘<>’ binary_expression

unary_expression : 	unary_operator unary_expression
			| args_format_specifier
			| parser_access_latest

unary_operator : 	‘~’
			| ‘!’
			| ‘|’
			| ‘&’

assignment_operator : ‘==’

primary_expression : ‘(’ expression‘)’

primary_expression : 	primary_types
				| metainfo
				| header_position
				| profile_type

postfix_expression : 	primary_expression
				| postfix_expression ‘.’ identifier
				| postfix_expression ‘.’ metainfo
				| postfix_expression array_access_format
				| postfix_expression range_access_format

Программа

program_definition_specifier : PROGRAM postfix_expression ‘{’ generic_statement_list ‘}’
		| PROGRAM postfix_expression ‘{’ ‘}’

Синтаксический анализатор

parsernode_definition_specifier : PARSER_NODE identifier ‘{’ generic_statement_list ‘}’

parser_statement : 	next_node
			| root_node
			| parsing_done
			| parser_field_extract

root_node : ROOT_NODE ‘:’ constant ‘;’

next_node : NEXT_NODE identifier ‘;’

parse_init : PARSE_BEGIN ‘(’ postfix_expression ‘)’

parsing_done : END_NODE’:’ constant‘;’

parser_field_extract : EXTRACT_FIELDS ‘(’ postfix_expression ‘)’ ‘;’

parser_access_latest : LATEST ‘.’ postfix_expression

Обновление заголовков пакета

header_command : 	CREATE_CHECKSUM ‘(’ args_format_specifier ‘)’ ‘;’
		| UPDATE_PACKET_LENGTH ‘(’ args_format_specifier ‘)’ ‘;’
		| ADD_HEADER ‘(’ postfix_expression ‘)’ ‘;’
		| DELETE_HEADER ‘(’ postfix_expression ‘)’ ‘;’
		| COPY_HEADER ‘(’ postfix_expression ‘,’ postfix_expression ‘)’ ‘;’
		| REPLACE_HEADER_FIELD ‘(’ postfix_expression ‘,’ postfix_expression ‘)’ ‘;’

Поиск в таблицах

lookup_statement : LOOKUP args_access_format

Функции

function_call : 	postfix_expression ‘(’ ‘)’
			| postfix_expression args_access_format

function_definition_specifier : 	FUNCTION postfix_expression ‘(’ func_def_args ‘)’ \
					‘{’ function_code_block ‘}’

func_def_args : 	args_format_specifier
			| empty

function_code_block : 	statement
				| function_code_block statement

Специальные функции

sp_definition_specifier : SFC postfix_expression postfix_expression ‘;’

special_func_defintion_specifier : SPECIAL_FUNCTION postfix_expression ‘{’ 
				special_func_def_list‘}’

special_func_def_list : 	special_func_def
				| special_func_def_list special_func_def

special_func_def : function_call ‘;’

Аргументы функций

args_access_format : ‘(’ args_format_specifier ‘)’

args_type_specifier : 	dir LIST postfix_expression
				| dir STR postfix_expression

args_format_specifier : 	args_type_specifier
				| args_format_specifier ‘,’ args_type_specifier
				| args_list_format
				| args_format_specifier ‘,’ args_list_format
				| postfix_expression
				| args_format_specifier ‘,’ postfix_expression
				| args_size_dir
				| args_format_specifier ‘,’ args_size_dir

args_list_format : 	‘{’ args_format_specifier ‘}’
			| ‘{’ ‘}’

args_def_list_format : ‘{’ args_size_multi ‘}’

args_size_dir : 	dir args_def_list_format
			| dir args_size

args_size_multi : 	args_size
			| args_size_multi ‘,’ args_size
args_size :	BIT postfix_expression
		| BIT array_access_format postfix_expression

Команда print

print_command : PRINTLN ‘(’ STR_CONST ‘)’

Pragma

pragma_call : directive NPL_PRAGMA pragma_access_format

directive : PRAGMA

pragma_access_format : ‘(’ postfix_expression ‘,’ pragma_format_specifier ‘)’

pragma_format_specifier : pragma_format_specifier ‘,’ \
				| postfix_expression ‘:’ postfix_expression
				| postfix_expression

12. Приложение E. Директивы (@NPL_PRAGMA)

В помощь компиляторам можно задавать в прикладных программах директивы. Компиляторы FE и BE используют эти директивы для размещения и других функций. Директивы не являются частью NPL, однако для лучшего понимания здесь описан синтаксис директив и даны примеры использования.

12.1. Директивы

Директивы помогают задать желаемое поведение, которое может зависеть от оборудования. Это помогает при отображениях BE. Для директив действует ряд правил:

  • директивы можно задавать в логическом файле NPL или отдельном файле;

  • с директивами не связано позиционирования;

  • директива должна начинаться с новой строки;

  • следует использовать ключевое слово null, если объект не связан с директивой или для директивы нужно несколько объектов.

Синтаксис и ключевое слово для директив имеют вид

@NPL_PRAGMA(object_name, property_name:property_value);

Пример

Задание директивы bus_type

Если в приложении пользователь хочет определить фиксированную шину, это может иметь вид

bus mpls_fixed_bus_s mpls_fixed_bus;
@NPL_PRAGMA(mpls_fixed_bus, bus_type:ing_obj_fixed);

Задание директивы mapping

Для отображения конкретной таблицы, функции, sfc или bus_field на определенный аппаратный блок можно задать

function vlan_assign_functions()
@NPL_PRAGMA(vlan_assign_functions,mapping:"hw_proc_block_20")

13. Примеры внешних функций

Отбрасывание пакета

Для отбрасывания пакетов применяется внешняя функция packet_drop.

Таблица 27. packet_drop.

Конструкция

Аргументы, опции

Описание

packet_drop

Отбрасывает пакет.

bus.field_name

Задает имя поля, при установке которого пакет должен отбрасываться (<bus.field>). В logical_table fields_assign() это должно быть <table_field>.

drop_code

Задает константу, связанную с причиной отбрасывания (constant или enum). Допустимы значения от 0 до 255, 0 означает отсутствие кода.

strength

Задает приоритет или силу, связанные с отбрасыванием (константа или поле регистра).

packet_drop(
	<bus.field_name>, 	// имя сигнала, с которым пользователь хочет связать отбрасывание
	<drop_code>,		// код причины отбрасывания
	<strength>		// приоритет причины отбрасывания
);

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

Для трассировки пакетов применяется внешняя функция packet_trace.

Таблица 28. packet_trace.

Конструкция

Аргументы, опции

Описание

packet_trace

Трассировка пакета.

bus.field_name

Задает имя поля, установка которого активизирует трассировку пакета (<bus.field>). В logical_table fields_assign() это должно быть <table_field>.

trace_code

Задает константу, связанную с трассировкой (constant или enum). Допустимы значения от 0 до 47, 0 означает отсутствие кода.

packet_trace(
	<bus.field_name>,	// имя сигнала, с которым пользователь хочет связать трассировку
	<trace_code>		// код операции трассировки
);

Подсчет пакетов

Для подсчета пакетов служит внешняя функция packet_count.

Таблица 29. packet_count.

Конструкция

Аргументы, опции

Описание

packet_count

Подсчет пакетов.

bus.field_name

Задает имя поля, установка которого активизирует подсчет пакетов (<bus.field>). В logical_table fields_assign() это должно быть 0 или 1

counter_id

Задает идентификатор счетчика (constant или enum) и может принимать значение от 1 до 63. В logical_table fields_assign() это должно быть <table_field>.

packet_count(
	<bus.field_name>,	// имя сигнала, с которым пользователь хочет связать подсчет
	<counter_id>		// идентификатор счетчика
);

Пример

Использование packet_drop, packet_trace, packet_count

Ниже приведен пример использования count, trace и drop, выполняющий ряд задач:

  • отбрасывание всех пакетов IPV4 с нулевым значением 0 с использованием drop_code 11 и priority 5;

  • трассировка всех пакетов IPV4 с  ttl = 1;

  • подсчет всех пакетов IPV4 с ttl = 2

struct cond_bus_s {
	bit	ttl_0;
	bit	ttl_1;
	bit	ttl_2;
}

bus cond_bus_s cond_bus;
#define TTL0 11
function func_ttl_proc () {
	if (header_ipv4.ttl == 0) {
		cond_bus.ttl_0 = 1;
	}
	if (header_ipv4.ttl == 1) {
		cond_bus.ttl_1 = 1;
	}
	if (header_ipv4.ttl == 2) {
		cond_bus.ttl_2 = 1;
	}
	packet_drop(cond_bus.ttl_0, TTL0, 5);
	packet_trace(cond_bus.ttl_1, 3);
	packet_count(cond_bus.ttl_2, 1);
}

program ipv4() {
	...
	func_ttl_proc();
	...
}

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

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

nmalykh@protokols.ru

1Network Programming Language.
2Software Defined Networks.
3Network interface card — сетевая интерфейсная плата (адаптер).
4Полного произвола здесь явно быть не должно, поскольку блоки анализа и редактирования следует размещать в начале и конце конвейера, соответственно. Прим. перев.
5Здесь явно следовало бы указать дополнение нулями слева или справа. Текущая формулировка может приводить к ошибкам в реализации. Прим. перев.
6Software Development Kit — пакет для разработки программ.
7Intellectual Property — закрытый блок, защищенный авторским правом. Прим. перев.
Рубрика: Сетевое программирование | Комментарии к записи NPL — Network Programming Language Specification отключены

RFC 8597 Cooperating Layered Architecture for Software-Defined Networking (CLAS)

Independent Submission                                     LM. Contreras
Request for Comments: 8597                                    Telefonica
Category: Informational                                    CJ. Bernardos
ISSN: 2070-1721                                                     UC3M
                                                                D. Lopez
                                                              Telefonica
                                                            M. Boucadair
                                                                  Orange
                                                              P. Iovanna
                                                                Ericsson
                                                                May 2019

Архитектура CLAS для программно-определяемых сетей

Cooperating Layered Architecture for Software-Defined Networking (CLAS)

PDF

Аннотация

Программно-определяемые сети (SDN1) ратуют за отделение уровня управления от уровня данных на узлах сети и концентрацию управления на одном или множестве управляющих элементов. Большая часть интеллекта сетей и/или служб перемещается в эти элементы управления. Обычно такой элемент рассматривается как набор взаимодействующих функций управления с вертикальной интеграцией. Перенос функций управления из множества сетевых узлов в логический центральный элемент концептуально объединяет множество функций управления, имеющих разные цели. В результате имеющиеся решения не обеспечивают четкого разделения между управлением транспортом и услугами, которые опираются на возможности транспорта.

В этом документе описан подход, названный многоуровневой архитектурой взаимодействия для программно-определяемых сетей (CLAS2), где связанные с транспортом функции управления отделены от функций, связанным с услугами так, что они могут предоставляться, поддерживаться и развиваться независимо и самостоятельно.

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

Этот документ не является спецификацией Internet Standards Track и публикуется с информационными целями.

Этот документ в серии RFC не связан с каким-либо потоком RFC. Редактор (RFC Editor) принял решение о публикации документа по своему усмотрению и не делает каких-либо заявлений о возможности реализации или развертывания. Документ одобрен для публикации редактором и не претендует на статус Internet Standard (см. раздел 2 в RFC 7841).

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

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

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

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

1. Введение

Успехи в сфере программных сетевых решений облегчают внедрение программируемых служб и инфраструктуры операторов связи. Обычно это достигается за счет применения программно-определяемых сетей (SDN) [RFC7149] [RFC7426], включая контроллеры и оркестраторы.

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

SDN предлагает разделять уровни управления и данных в сетевых устройствах путем абстрагирования обоих уровней, позволяющего централизовать логику управления в объекте, обычно называемом контроллером SDN (в сети может применяться один или множество контроллеров). Затем определяется программный интерфейс между элементом пересылки (в узлах сети) и управляющим элементом. Через этот интерфейс управляющий элемент инструктирует узлы уровня пересылки и меняет нужным образом их поведение в части пересылки трафика. Поддержка дополнительных возможностей (например, мониторинга производительности, контроля отказов и т. п.) также может осуществляться через этот программный интерфейс [RFC7149].

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

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

  • Комплексное и многократное использование функций для предоставления услуг.

  • Закрытая, монолитная архитектура управления.

  • Сложность взаимодействия и взаимозаменяемости функциональных компонент.

  • Размытие границ бизнеса между провайдерами, особенно в случаях, где один провайдер обеспечивает связность, а другой — услуги на базе этой связности.

  • Сложность диагностики и обслуживания сети, а также поиска неполадок (в частности, определение ответственного за отказ уровня).

Перемещение функций управления из множества распределенных сетевых узлов в другой элемент концептуально собирает вместе множество возможностей управления, имеющих разные цели. В результате существующие решение SDN не обеспечивают четкого разделения между управлением транспортом и услугами. В этом документе разделение услуг и транспорта следует стандарту [Y.2011] и определению в разделе 2.

Этот документ описывает подход, названный многоуровневой архитектурой взаимодействия для программно-определяемых сетей (CLAS), где связанные с транспортом функции управления отделены от функций, связанным с услугами так, что они могут предоставляться, поддерживаться и развиваться независимо и самостоятельно.

Несмотря на такое различие, тесное взаимодействие между уровнями услуг и транспорта (или слоями в [Y.2011]) и связанными компонентами требуется для эффективного использования ресурсов.

2. Терминология

Ниже приведены определения используемых в документе терминов.

Transport — транспорт

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

Service – сервис (услуга, служба)

Логическая конструкция, использующая транспортные возможности.

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

Layer — уровень

Набор элементов с возможностями транспорта или услуг в соответствии с предшествующими определениями. В [Y.2011] уровни называются слоями (stratum) и в этом документе применяются оба термина.

Domain — домен

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

SDN Intelligence — интеллект SDN

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

Интеллект может быть распределенным или централизованным. В документе рассматриваются оба варианта.

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

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

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

CLAS

Cooperating Layered Architecture for SDN — многоуровневая архитектура взаимодействия для программно-определяемых сетей.

FCAPS

Fault, Configuration, Accounting, Performance, and Security — отказы, настройка, учет, производительность и безопасность.

SDN

Software-Defined Networking — программно-определяемая сеть.

SLA

Service Level Agreement — соглашение об уровне обслуживания.

3. Обзор архитектуры

Современные операторские сети поддерживают множество услуг (например, VoIP3, IPTV, мобильные услуги VoIP и т. п.) на основе разных транспортных технологий. Предоставление и доставка услуг независимо от базового транспорта требует разделения связанной с транспортом функциональности и абстракции транспортной сети, чтобы скрыть специфику базовых транспортных технологий, сохраняя базовый набор возможностей.

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

Этот документ в основном посвящен решению перечисленных ниже задач:

  • представление транспортных возможностей сервису;

  • фиксация требований сервиса к транспорту;

  • уведомление сервисного интеллекта о транспортных событиях, например, для корректировки процесса принятия решения при том или ином событии на транспорте;

  • информирование базового транспорта о новых требованиях и т. п.

Примером является гарантия некоторых уровней качества обслуживания (QoS4). Различные предложения на основе QoS могут быть представлены на сервисном и транспортном уровне. Должны быть предусмотрены вертикальные связи между механизмами QoS транспортного и сервисного уровня, чтобы гарантировать качество обслуживания конечному пользователю.

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

На рисунке 1 показана архитектура CLAS, основанная на функциональном разделении архитектуры NGN5, определенной ITU-T в стандарте [Y.2011], где заданы два слоя (уровня) функциональности. Эти слои называются сервисным (Service Stratum) и транспортным (Transport Stratum). Функции каждого из этих уровней дополнительно группируются по уровням управления, администрирования и данных (пользовательский).

CLAS принимает структурную модель, описанную в [Y.2011], но применяет ее для решения задач программируемости с помощью SDN [RFC7149]. В этом отношении CLAS предлагает разделение услуг и транспорта на основе различия их задач.

                                  Приложения
                                      /\
                                      ||
                                      ||
+-------------------------------------||-------------+
| Сервисный слой                      ||             |
|                                     \/             |
|                       ...........................  |
|                       . Интеллект SDN           .  |
|                       .                         .  |
|  +--------------+     .        +--------------+ .  |
|  |    Уровень   |     .        |Уровень админ.| .  |
|  |    ресурсов  |<===>.  +--------------+     | .  |
|  |              |     .  |Уровень управ.|     | .  |
|  +--------------+     .  |              |-----+ .  |
|                       .  |              |       .  |
|                       .  +--------------+       .  |
|                       ...........................  |
|                                     /\             |
|                                     ||             |
+-------------------------------------||-------------+
                                      ||   Стандартный
                                   -- || --    API
                                      ||
+-------------------------------------||-------------+
| Транспортный слой                   ||             |
|                                     \/             |
|                       ...........................  |
|                       . Интеллект SDN           .  |
|                       .                         .  |
|  +--------------+     .        +--------------+ .  |
|  |    Уровень   |     .        |Уровень админ.| .  |
|  |    ресурсов  |<===>.  +--------------+     | .  |
|  |              |     .  |Уровень управ.|     | .  |
|  +--------------+     .  |              |-----+ .  |
|                       .  |              |       .  |
|                       .  +--------------+       .  |
|                       ...........................  |
|                                                    |
|                                                    |
+----------------------------------------------------+

Рисунок 1.Архитектура CLAS.


В архитектуре CLAS функции управления и администрирования выполняются на одном или множестве контроллеров SDN (например, для расширяемости и надежности), обеспечивая интеллект SDN таким способом, что контроллеры SDN представлены в сервисном и транспортном слое. Функции администрирования считаются частью интеллекта SDN, обеспечивающего эффективную работу в экосистеме сервис-провайдера [RFC7149], хотя в некоторых предложениях эти функции не считались частью среды SDN [ONFArch].

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

Контроллеры SDN взаимодействуют для предоставления и доставки услуг. Имеется иерархия, в которой интеллект сервисной SDN делает запросы к интеллекту транспортной SDN для предоставления транспортных возможностей.

Интеллект сервисной SDN выступает клиентом интеллекта транспортной SDN.

Кроме того, интеллект транспортной SDN взаимодействует с интеллектом сервисной SDN для информирования о событиях в транспортной сети, которые могут вызывать действия на уровне сервиса.

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

3.1. Функциональные слои

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

Согласованность определяется и характеризуется уровнем сервиса.

3.1.1. Транспортный слой

Транспортный слой включает функции, ориентированные на передачу данных между взаимодействующими конечными точками (например, между пользовательскими устройствами, сервисными шлюзами и т. п.). Узлы пересылки данных управляются и поддерживаются компонентой Transport SDN.

Уровень управления в SDN Intelligence отвечает за указание устройствам пересылки создавать сквозной путь передачи данных для каждого взаимодействия или обеспечивать надлежащую настройку услуг пересылки. Пересылка не может зависеть исключительно от настроенных заранее элементом — это значит, что можно включить средства динамического построения путей маршрутизации и пересылки (это может потребовать от узлов поддержки некоторых функций управления). Наконец, уровень управления выполняет функции управления (т. е., FCAPS) на этих устройствах как часть возможностей транспортного слоя.

3.1.2. Сервисный слой

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

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

3.1.3. Рекурсия уровней

В некоторых вариантах применения может использоваться рекурсивное деление на уровни, где транспортный слой дополнительно делится на сервисный и транспортный слои. Это может возникать в случаях предоставления транспортных услуг, дополненных расширенными возможностями (например, для поддержки SLA [RFC7297]).

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

3.2. Разделение уровней

Архитектура CLAS усиливает разделение уровней. Как отмечено в параграфах 3.1.1 и 3.1.2, в каждом слое выделяются три разных уровня. Взаимодействие между соответствующими уровнями в разных слоях основано на стандартных, открытых интерфейсах.

3.2.1. Уровень управления

Уровень управления логически централизует функции управления каждого слоя и непосредственно управляет соответствующими ресурсами. Роль уровня управления в архитектуре SDN рассмотрена в [RFC7426]. Этот уровень является частью SDN Intelligence и может взаимодействовать с другими уровнями управления в том же или другом слое для реализации управляющих функций.

3.2.2. Уровень администрирования

Уровень администрирования логически централизует административные функции каждого слоя, включая администрирование уровней управления и ресурсов. Уровень администрирования в среде SDN описан в [RFC7426]. Этот уровень также является частью SDN Intelligence и может взаимодействовать с соответствующими уровнями администрирования в контроллерах SDN того же или другого слоя.

3.2.3. Уровень ресурсов

Уровень ресурсов включает ресурсы для выполнения транспортных или сервисных функций. В некоторых случаях сервисные ресурсы могут быть подключены к транспортным (например, служить точками завершения транспортных функций), в других они могут быть полностью отделены от ресурсов транспорта (например, база данных с реестром для конечных пользователей). Уровни пересылки и операций, предложенные в [RFC7426], являются в данной архитектуре частью уровня ресурсов.

4. Требуемые функции

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

  • Абстрагирование — отображение физических ресурсов на соответствующие абстрактные ресурсы.

  • Трансляция параметров сервиса (например, в форме SLA) в параметры (возможности) транспорта в соответствии с различными правилами.

  • Мониторинг — механизмы (например, уведомления о событиях) для динамического обновления состояний (абстрагированных) ресурсов с учетом, например, уровня трафика.

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

  • Оркестровка — возможность комбинировать разные ресурсы (например, IT и сетевые) оптимальным способом.

  • Учет использования ресурсов.

  • Безопасность — защищенное взаимодействие между компонентами с предотвращением атак (например, DoS).

5. Взаимодействие между контроллерами SDN

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

С точки зрения сервиса требуется Service SDN Intelligence для упрощения доступа к транспортным ресурсам через четко определенные интерфейсы API, чтобы определить возможности, предоставляемые транспортным слоем. Могут применяться разные способы получения информации о транспорте, например, механизмы обнаружения или публикации. В первом случае Service SDN Intelligence может обрабатывать полную информацию о транспортных возможностях (включая ресурсы), предлагаемых транспортным слоем. Во втором варианте транспортный слой раскрывает доступные возможности (например, через каталог), снижая объем передаваемых через сеть деталей.

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

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

6. Варианты развертывания

Варианты развертывания могут существенно различаться в зависимости от характеристик используемой сети.

6.1. Среда SDN

В этом варианте сети, участвующие в предоставлении и доставке услуг, обладают возможностями SDN.

6.1.1. Множество сервисных слоев с одним транспортным слоем

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

6.1.2. Один сервисный слой с множеством транспортных слоев

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

6.2. Гибридные среды

В этом разделе рассмотрены варианты где один из слоев является полностью или частично унаследованным (не SDN).

6.2.1. Сервисный слой SDN и унаследованный транспортный слой

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

Интеллект SDN в сервисном слое не знает об унаследованной природе базового транспортного слоя.

6.2.2. Унаследованный сервисный слой и транспортный слой SDN

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

6.3. Многодоменные варианты в транспортном слое

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

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

В этом конкретном случае рекурсия делает возможным использовать множество доменов на транспортном уровне.

Многодоменные варианты могут возникать при использовании сетей как одного, так и множества операторов.

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

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

7. Примеры использования

В этом разделе представлены примеры использования в качестве иллюстрации применимости модели CLAS.

7.1. Виртуализация сетевых функций (NFV)

Среды NFV6 включает два возможных уровня управления SDN [GSNFV-EVE005]. Одним из уровней является необходимость управлять инфраструктурой NFV (NFVI) для обеспечения сквозной связности между VNF (Virtual Network Function — функция виртуальной сети) или между VNF и PNF (Physical Network Function — функция физической сети). Вторым уровнем является настройка и управление VNF (настройка сетевых служб, реализуемых VNF), которая выигрывает от программных возможностей SDN. Эти уровни разделены по своей природе, однако можно предполагать взаимодействие между ними для оптимизации, расширяемости и влияния друг на друга.

7.2. Абстракции и управление в сетях TE

Модель ACTN7 [RFC8453] позволяет создавать виртуальные сети, предлагаемые клиентам. Роль провайдера в ACTN ограничивается предоставлением услуг виртуальных сетей. Эти услуги по сути являются транспортными и соответствуют транспортному слою в CLAS. Сервисный слой CLAS может считаться клиентом в контексте ACTN.

ACTN определяет иерархию контроллеров для облегчения создания и функционирования виртуальных сетей. Определен интерфейс для взаимодействия между клиентами, запрашивающими услуги виртуальных сетей, и контроллером, отвечающим за оркестровку и обслуживание таких запросов. Такой интерфейс эквивалентен показанному на рисунке 1 (раздел 3) интерфейсу между сервисным и транспортным слоем.

8. Реализация взаимодействия между слоями сервиса и транспорта

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

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

    Некоторые из таких предложений могут быть решениями, подобными [CPNP8] или I-CPI9 [ONFArch].

    Другими кандидатами могут служить транспортный API [TAPI] или транспортный интерфейс северного моста [TRANS-NORTH]. Каждый из этих вариантов имеет свою область действия.

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

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

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

  • Отображение SLA. Оба слоя будут обрабатывать SLA, но природа этих SLA может различаться. Поэтому от объектов каждого слоя требуется отображение сервисных SLA на транспортные (связность) для надлежащей доставки услуг.

  • Связи между слоями могут настраиваться заранее или оба слоя могут использовать механизмы обнаружения для динамической организации таких связей.

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

  • Учет. Контроль и учет использования ресурсов услугами должен поддерживаться для связей между слоями.

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

С этим документом не связано действий IANA.

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

Архитектура CLAS опирается на функциональные элементы, определенные в [RFC7149] и [RFC7426]. Поэтому следует принимать в внимание вопросы безопасности, отмеченные в разделе 5 [RFC7149].

Связи между транспортными и сервисными контроллерами SDN должны быть защищены с использованием:

  • взаимной аутентификации сторон до выполнения каких-либо действий;

  • защиты целостности сообщения.

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

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

Защиту взаимодействий между слоями следует применять к API (и/или протоколам), которые применяются для связи. Поэтому вопросы безопасности будут определяться конкретным решением.

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

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

[Y.2011] International Telecommunication Union, «General principles and general reference model for Next Generation Networks», ITU-T Recommendation Y.2011, October 2004, <https://www.itu.int/rec/T-REC-Y.2011-200410-I/en>.

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

[CPNP] Boucadair, M., Jacquenet, C., Zhang, D., and P. Georgatsos, «Connectivity Provisioning Negotiation Protocol (CPNP)», Work in Progress, draft-boucadair-connectivity-provisioning-protocol-15, December 2017.

[GSNFV-EVE005] ETSI, «Network Functions Virtualisation (NFV); Ecosystem; Report on SDN Usage in NFV Architectural Framework», ETSI GS NFV-EVE 005, V1.1.1, December 2015, <https://www.etsi.org/deliver/etsi_gs/NFV-EVE/001_099/005/01.01.01_60/gs_nfv-eve005v010101p.pdf>.

[ONFArch] Open Networking Foundation, «SDN Architecture, Issue 1», June 2014, <https://www.opennetworking.org/images/stories/downloads/sdn-resources/technical-reports/TR_SDN_ARCH_1.0_06062014.pdf>.

[RFC7149] Boucadair, M. and C. Jacquenet, «Software-Defined Networking: A Perspective from within a Service Provider Environment», RFC 7149, DOI 10.17487/RFC7149, March 2014, <https://www.rfc-editor.org/info/rfc7149>.

[RFC7297] Boucadair, M., Jacquenet, C., and N. Wang, «IP Connectivity Provisioning Profile (CPP)», RFC 7297, DOI 10.17487/RFC7297, July 2014, <https://www.rfc-editor.org/info/rfc7297>.

[RFC7426] Haleplidis, E., Ed., Pentikousis, K., Ed., Denazis, S., Hadi Salim, J., Meyer, D., and O. Koufopavlou, «Software-Defined Networking (SDN): Layers and Architecture Terminology», RFC 7426, DOI 10.17487/RFC7426, January 2015, <https://www.rfc-editor.org/info/rfc7426>.

[RFC7926] Farrel, A., Ed., Drake, J., Bitar, N., Swallow, G., Ceccarelli, D., and X. Zhang, «Problem Statement and Architecture for Information Exchange between Interconnected Traffic-Engineered Networks», BCP 206, RFC 7926, DOI 10.17487/RFC7926, July 2016, <https://www.rfc-editor.org/info/rfc7926>.

[RFC8453] Ceccarelli, D., Ed. and Y. Lee, Ed., «Framework for Abstraction and Control of TE Networks (ACTN)», RFC 8453, DOI 10.17487/RFC8453, August 2018, <https://www.rfc-editor.org/info/rfc8453>.

[SDN-ARCH] Contreras, LM., Bernardos, CJ., Lopez, D., Boucadair, M., and P. Iovanna, «Cooperating Layered Architecture for SDN», Work in Progress, draft-irtf-sdnrg-layered-sdn-01, October 2016.

[TAPI] Open Networking Foundation, «Functional Requirements for Transport API», June 2016, <https://www.opennetworking.org/wp-content/uploads/2014/10/TR-527_TAPI_Functional_Requirements.pdf>.

[TRANS-NORTH] Busi, I., King, D., Zheng, H., and Y. Xu, «Transport Northbound Interface Applicability Statement», Work in Progress, draft-ietf-ccamp-transport-nbi-app-statement-05, March 2019.

Приложение A. Связь с RFC 7426

В [RFC7426] введена таксономия SDN путем определения множества плоскостей, уровней абстракции и интерфейсов или API между ними для прояснения связей между разными составляющими SDN (сетевые устройства, управление, администрирование). Определено множество уровней (плоскостей), включая:

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

  • операционный уровень, обеспечивающий поддержку рабочего состояния сетевого устройства;

  • уровень управления, предназначенный для инструктирования устройств в части пересылки пакетов;

  • уровень администрирования, отвечающий за мониторинг и поддержку сетевых устройств;

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

Кроме этого [RFC7426] предлагает множество уровней абстракции, позволяющих объединить разные плоскости через общие интерфейсы. Архитектура CLAS фокусируется на уровнях управления, администрирования и ресурсов в качестве базовых компонент. По существу, уровень управления меняет поведение и действия контролируемых ресурсов. Уровень администрирования обеспечивает мониторинг и получение статуса этих ресурсов. А уровень ресурсов группирует все ресурсы, связанные с задачами каждого слоя.

С этой точки зрения уровни CLAS можно считать надмножеством уровней [RFC7426]. Однако в некоторых случаях не все уровни [RFC7426] могут полностью присутствовать в представлении CLAS (например, уровень пересылки в сервисном слое). При этом внутренняя структура слоя CLAS может соответствовать таксономии [RFC7426]. Отличительная особенность заключается в специализации сред SDN за счет разделения услуг и транспорта.

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

Этот документ рассмотрен и принят исследовательской группой IRTF SDN как [SDN-ARCH]. После завершения работы группы IRTF SDN RG документ был преобразован в независимое представление (Independent Submission) некоторыми из участников групповых обсуждений.

Авторы выражают свою признательность (в алфавитном порядке) Bartosz Belter, Gino Carrozzo, Ramon Casellas, Gert Grammel, Ali Haider, Evangelos Haleplidis, Zheng Haomian, Giorgios Karagianis, Gabriel Lopez, Maria Rita Palatella, Christian Esteve Rothenberg и Jacek Wytrebowicz за их комментарии и предложения.

Спасибо Adrian Farrel за рецензию.

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

Luis M. Contreras

Telefonica

Ronda de la Comunicacion, s/n

Sur-3 building, 3rd floor

Madrid 28050

Spain

Email: luismiguel.contrerasmurillo@telefonica.com

URI: http://lmcontreras.com

Carlos J. Bernardos

Universidad Carlos III de Madrid

Av. Universidad, 30

Leganes, Madrid 28911

Spain

Phone: +34 91624 6236

Email: cjbc@it.uc3m.es

URI: http://www.it.uc3m.es/cjbc/

Diego R. Lopez

Telefonica

Ronda de la Comunicacion, s/n

Sur-3 building, 3rd floor

Madrid 28050

Spain

Email: diego.r.lopez@telefonica.com

Mohamed Boucadair

Orange

Rennes 35000

France

Email: mohamed.boucadair@orange.com

Paola Iovanna

Ericsson

Pisa

Italy

Email: paola.iovanna@ericsson.com


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

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

nmalykh@protokols.ru


1Software-Defined Networking.

2Cooperating Layered Architecture for Software-Defined Networking.

3Voice over IP — голосовая связь по протоколу IP.

4Quality-of-Service.

5Next Generation Network — сеть следующего поколения.

6Network Function Virtualization.

7Abstraction and Control of TE Networks.

8Connectivity Provisioning Negotiation Protocol — протокол согласования связности.

9Intermediate-Controller Plane Interface — интерфейс с промежуточным контроллером.

Рубрика: RFC | Комментарии к записи RFC 8597 Cooperating Layered Architecture for Software-Defined Networking (CLAS) отключены

RFC 8575 YANG Data Model for the Precision Time Protocol (PTP)

Internet Engineering Task Force (IETF)                     Y. Jiang, Ed.
Request for Comments: 8575                                        Huawei
Category: Standards Track                                         X. Liu
ISSN: 2070-1721                                              Independent
                                                                   J. Xu
                                                                  Huawei
                                                        R. Cummings, Ed.
                                                    National Instruments
                                                                May 2019

YANG Data Model for the Precision Time Protocol (PTP)

Модель данных YANG для протокола точного времени (PTP)

PDF

Аннотация

Этот документ задаёт модель данных YANG для настройки устройств и часов с использованием протокола точного времени (Precision Time Protocol или PTP), заданного стандартом IEEE Std 1588-2008. Документ также определяет извлечение конфигурационных сведений, наборов данных и рабочих состояний часов PTP. Модуль YANG соответствует архитектуре хранилищ данных управления сетью (Network Management Datastore Architecture — NMDA).

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

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

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

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

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

Copyright (c) 2019. Авторские права принадлежат 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).

1. Введение

Как протокол синхронизации, IEEE Std 1588-2008 [IEEE1588] широко поддерживается в сетях операторов, промышленных и автомобильных сетях, а также во многих других приложениях. Протокол может обеспечить синхронизацию часов с наносекундной точностью. Протокол зависит от машины PTP для автоматического определения состояния и транспортного уровня PTP для передачи сигналов синхронизации и сообщений о качестве. Наборы данных конфигурации и рабочего состояния IEEE Std 1588-2008 весьма широки.

В соответствии с концепциями, описанными в [RFC3444], IEEE Std 1588-2008 сам по себе обеспечивает информационную модель в нормативной спецификации наборов данных (IEEE Std 1588-2008 clause 8). Некоторые органы стандартизации, включая IETF, имеют свои модели данных в базах управляющей информации (MIB или Management Information Base) для наборов данных IEEE Std 1588-2008 (например, [RFC8173] и [IEEE8021AS]). Эти MIB обычно сосредоточены на извлечении данных состояния с применением простого протокола управления сетью (Simple Network Management Protocol или SNMP), а настройка наборов данных PTP даже не рассматривается в [RFC8173].

Некоторым поставщикам услуг и приложениям нужно, чтобы упреаление сетью синхронизации IEEE Std 1588-2008 было гибким и в большей степени основанным на Internet (накладывалось на транспортные сети). Программно-определяемые сети (Software-Defined Networking или SDN) являются ещё одним фактором, требующим улучшения возможностей настройки сетей синхронизации.

Язык моделирования данных YANG [RFC7950] служит для моделирования данных конфигурации и состояния, управляемых по протоколам сетевого управления, таким как протокол настройки сетей (Network Configuration Protocol или NETCONF) [RFC6241]. Небольшой набор встроенных типов данных определён в [RFC7950], а коллекция базовых типов — в [RFC6991]. Преимущества YANG включают основанные на Internet возможности настройки, проверки и отката конфигурации и т. д. Эти характеристики деляют YANG привлекательным в качестве ещё одного кандидата в языки моделирования для IEEE Std 1588-2008.

Этот документ определяет модель данных YANG для настройки устройств и часов IEEE Std 1588-2008, а также извлечения данных состояния часов IEEE Std 1588-2008. Модель данных основана на наборах данных PTP, заданных в [IEEE1588]. Связанные с конкретными технологиями сведения PTP (например, реализованные в профилях для мостов, маршрутизаторов или операторов) выходят за рамки этого документа.

Представленный здесь модуль YANG соответствует архитектуре хранилищ данных управления сетью (NMDA) [RFC8342].

При практическом использовании сетевой продукция для поддержки синхронизации обычно соответствует одному или нескольким профилям IEEE Std 1588-2008. Каждый профиль задаёт применение IEEE Std 1588-2008 в данной отрасли (например, в телекоммуникациях или автомобилестроении) и приложении. Профиль может требовать свойств, которые не обязательны в IEEE Std 1588-2008, а также задавать новые свойства, основанные на IEEE Std 1588-2008.

Предполагается знакомство читателя с IEEE Std 1588-2008. Ниже указаны некоторые аспекты применения модуля.

  • Модуль YANG IEEE Std 1588-2008 может использоваться для продукции, соответствующей одному или нескольким профилям, заданным в IEEE Std 1588-2008.

  • При пересмотре стандарта IEEE Std 1588 (например, это происходило во время создания данного документа) в наборы данных могут добавляться новые необязательные свойства (функции). Представленный здесь модуль YANG может пересматриваться для поддержки таких новых функций. Оператор YANG revision должен использоваться для указания изменений в модуле YANG в таких обстоятельствах.

  • Стандарт профиля на основе IEEE Std 1588-2008 может приводить к созданию отдельного модуля YANG для этого профиля. Модулям YANG с профилями следует использовать оператор YANG import для импорта модуля YANG IEEE Std 1588-2008 в качестве своей основы. Для добавления связанных с профилем возможностей в модуле YANG следует использовать оператор YANG augment.

  • Для продукции, соответствующей стандартному профилю, могут создаваться свои модули YANG, в которых следует использовать оператор import, а также augment при добавлении связанных с продукцией возможностей.

1.1. Используемые соглашения

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

1.2. Термины

Большая часть используемых в документе терминов заимствована из [IEEE1588].

BC Boundary Clock

Пограничные часы, см. параграф 3.1.3 в [IEEE1588].

DS Data Set

Набор данных, см. параграф 8.1.1 в [IEEE1588]

E2E End-to-End

Сквозной, см. параграф 3.2 в [IEEE1588]

IANA Internet Assigned Numbers Authority

Агентство по выделению значений для Internet.

OC Ordinary Clock

Обычные часы, см. параграф 3.1.22 в [IEEE1588]

P2P Peer-to-Peer

Одноранговый, см. параграф 3.2 в [IEEE1588]

PTP Precision Time Protocol

Протокол точного времен, см. параграф 3.1.28 в [IEEE1588]

TAI International Atomic Time

Международные атомные часы, см. параграф 3.2 в [IEEE1588]

TC Transparent Clock

«Прозрачные» часы, см. параграф 3.1.46 в [IEEE1588]

UTC Coordinated Universal Time

Универсальное координатное время, см. параграф 3.2 в [IEEE1588]

PTP data set

Набор данных PTP — структурированные атрибуты часов (в OC, BC, TC), используемые для решений PTP и предоставления значений в полях сообщений PTP, см. раздел 8 в [IEEE1588].

PTP instance

Экземпляр PTP — реализация протокола в устройстве (т. е. OC или BC), представленная конкретным набором данных PTP.

2. Иерархия модели данных YANG IEEE Std 1588-2008

В этом разделе показана иерархия модуля YANG для IEEE Std 1588-2008, в частности, запросы и конфигурация сведений для устройства в целом или порта, а также наборы данных в часах.

Запросы и конфигурация сведений о часах включают3:

  • атрибуты набора данных в узле часов включают current-ds, parent-ds, default-ds, time-properties-ds, transparent-clock-default-ds.

  • Атрибуты набора данных для порта включают port-ds и transparent-clock-port-ds.

Поскольку все термины и атрибуты наборов данных PTP подробно описаны в IEEE Std 1588-2008, в этом документе они представлены лишь в общих чертах в модуле YANG.

Для модулей YANG обычно применяется упрощённое представление модели данных в виде дерева [RFC8340]. Здесь используется синтаксис представления дерева, заданный в [RFC8340].

   module: ietf-ptp
     +--rw ptp
        +--rw instance-list* [instance-number]
        |  +--rw instance-number      uint32
        |  +--rw default-ds
        |  |  +--rw two-step-flag?    boolean
        |  |  +--ro clock-identity?   clock-identity-type
        |  |  +--rw number-ports?     uint16
        |  |  +--rw clock-quality
        |  |  |  +--rw clock-class?                  uint8
        |  |  |  +--rw clock-accuracy?               uint8
        |  |  |  +--rw offset-scaled-log-variance?   uint16
        |  |  +--rw priority1?        uint8
        |  |  +--rw priority2?        uint8
        |  |  +--rw domain-number?    uint8
        |  |  +--rw slave-only?       boolean
        |  +--rw current-ds
        |  |  +--rw steps-removed?        uint16
        |  |  +--rw offset-from-master?   time-interval-type
        |  |  +--rw mean-path-delay?      time-interval-type
        |  +--rw parent-ds
        |  |  +--rw parent-port-identity
        |  |  |  +--rw clock-identity?   clock-identity-type
        |  |  |  +--rw port-number?      uint16
        |  |  +--rw parent-stats?                 boolean
        |  |  +--rw observed-parent-offset-scaled-log-variance? uint16
        |  |  +--rw observed-parent-clock-phase-change-rate?    int32
        |  |  +--rw grandmaster-identity?         clock-identity-type
        |  |  +--rw grandmaster-clock-quality
        |  |  |  +--rw clock-class?                  uint8
        |  |  |  +--rw clock-accuracy?               uint8
        |  |  |  +--rw offset-scaled-log-variance?   uint16
        |  |  +--rw grandmaster-priority1?           uint8
        |  |  +--rw grandmaster-priority2?           uint8
        |  +--rw time-properties-ds
        |  |  +--rw current-utc-offset-valid?   boolean
        |  |  +--rw current-utc-offset?         int16
        |  |  +--rw leap59?                     boolean
        |  |  +--rw leap61?                     boolean
        |  |  +--rw time-traceable?             boolean
        |  |  +--rw frequency-traceable?        boolean
        |  |  +--rw ptp-timescale?              boolean
        |  |  +--rw time-source?                uint8
        |  +--rw port-ds-list* [port-number]
        |     +--rw port-number              uint16
        |     +--rw port-state?              port-state-enumeration
        |     +--rw underlying-interface?         if:interface-ref
        |     +--rw log-min-delay-req-interval?   int8
        |     +--rw peer-mean-path-delay?         time-interval-type
        |     +--rw log-announce-interval?        int8
        |     +--rw announce-receipt-timeout?     uint8
        |     +--rw log-sync-interval?            int8
        |     +--rw delay-mechanism?       delay-mechanism-enumeration
        |     +--rw log-min-pdelay-req-interval?   int8
        |     +--rw version-number?                uint8
        +--rw transparent-clock-default-ds
        |  +--ro clock-identity?    clock-identity-type
        |  +--rw number-ports?      uint16
        |  +--rw delay-mechanism?   delay-mechanism-enumeration
        |  +--rw primary-domain?    uint8
        +--rw transparent-clock-port-ds-list* [port-number]
           +--rw port-number                    uint16
           +--rw log-min-pdelay-req-interval?   int8
           +--rw faulty-flag?                   boolean
           +--rw peer-mean-path-delay?          time-interval-type

2.1. Интерпретации от рабочей группы IEEE 1588

Предшествующая модель и связанный с ней модуль YANG имеют незначительные отличия от спецификаций наборов данных в IEEE Std 1588-2008, основанные на интерпретации рабочей группы IEEE 1588 и предназначенные для обеспечения совместимости с будущими версиями IEEE Std 1588.

В IEEE Std 1588-2008 физическая продукция может реализовать несколько часов PTP (например, обычные, граничные и прозрачные часы). Как указано в параграфе 7.1 IEEE Std 1588-2008, каждые из таких часов работают в независимом домене. Однако организация нескольких доменов PTP не ясна в наборах данных IEEE Std 1588-2008. Этот документ вводит понятие экземпляра PTP, который является реализацией PTP в устройстве (т. е. OC или BC), представленной конкретным набором данных PTP. Каждый экземпляр работает в единственном домене. Понятие экземпляра применяется лишь для поддержки нескольких доменов. Номер экземпляра не применяется в сообщениях PTP.

На основе утверждений в параграфах 8.3.1 и 10.1 IEEE Std 1588-2008, большинство устройств с прозрачными часами интерпретируют наборы данных прозрачных часов как одиночный элемент (singleton) на корневом уровне управляемого объекта и модель данных YANG отражает эту позицию.

2.2. Конфигурация и состояние

Информационная модель IEEE Std 1588-2008 разделяет наборы данных PTP на 3 указанных ниже класса.

Configurable — настраиваемые

Доступные для записи из системы управления

Dynamic — динамические

Доступные лишь для чтения из системы управления и изменяемые протокольными операциями PTP.

Static — статические

Доступные лишь для чтения из системы управления и обычно неизменяемые.

Подробности классификации каждого элемента наборов данных PTP приведены в спецификации IEEE Std 1588-2008.

При некоторых обстоятельствах классификация элементов наборов данных IEEE Std 1588 может изменяться для реализации YANG, например, настраиваемый элемент нужно сделать доступным лишь для записи. В таких случаях реализации следует возвращать предупреждение при попытке записи в доступный лишь для чтения объект или использовать механизм отклонений для создания новой модели, как указано в параграфе 7.20.3 [RFC7950].

3. Модуль YANG IEEE Std 1588-2008

Этот модуль импортирует определение типа interface-ref из [RFC8343]. Большинство атрибутов основано на модели информации из [IEEE1588], но их имена приведены в соответствие со стилем именования в YANG.

  <CODE BEGINS> file "ietf-ptp@2019-05-07.yang"
  module ietf-ptp {
    yang-version 1.1;
    namespace "urn:ietf:params:xml:ns:yang:ietf-ptp";
    prefix ptp;

    import ietf-interfaces {
      prefix if;
      reference
        "RFC 8343: A YANG Data Model for Interface Management";
    }

    organization
      "IETF TICTOC Working Group";
    contact
      "WG Web:   https://datatracker.ietf.org/wg/tictoc/ 
       WG List:  <mailto:tictoc@ietf.org> 
       Editor:   Yuanlong Jiang
                 <mailto:jiangyuanlong@huawei.com> 
       Editor:   Rodney Cummings
                 <mailto:rodney.cummings@ni.com>"; 
    description
      "Этот модуль YANG задаёт модель данных для настройки часов 
       IEEE Std 1588-2008, а также извлечения из них данных состояния.";

    revision 2019-05-07 {
      description
        "Исходный выпуск";
      reference
        "RFC 8575: YANG Data Model for the Precision Time Protocol";
    }

    typedef delay-mechanism-enumeration {
      type enumeration {
        enum e2e {
          value 1;
          description
            "Порт использует механизм задержки запросов-откликов.";
        }
        enum p2p {
          value 2;
          description
            "Порт использует механизм задержки у партнера.";
        }
        enum disabled {
          value 254;
          description
            "Порт не реализует механизмов задержки.";
        }
      }
      description
        "Порт использует опцию измерения задержки при распространении.
         Значения этого перечисляемого типа полностью заданы стандартом
         IEEE Std 1588.";
      reference
        "IEEE Std 1588-2008: 8.2.5.4.4";
    }

    typedef port-state-enumeration {
      type enumeration {
        enum initializing {
          value 1;
          description
            "Порт инициализирует свои наборы данных, аппаратные и 
             коммуникационные средства.";
        }
        enum faulty {
          value 2;
          description
            "Порт находится в состоянии отказа.";
        }
        enum disabled {
          value 3;
          description
            "Порт отключён и не участвует в обмене сообщениями PTP
             (кроме возможных управляющих сообщений PTP).";
        }
        enum listening {
          value 4;
          description
            "Порт прослушивает сообщения Announce.";
        }
        enum pre-master {
          value 5;
          description
            "Порт находится в состоянии pre-master.";
        }
        enum master {
          value 6;
          description
            "Порт ведёт себя как первичный (master).";
        }
        enum passive {
          value 7;
          description
            "Порт находится в пассивном состоянии.";
        }
        enum uncalibrated {
          value 8;
          description
            "Ведущий порт выбран, но порт остаётся некалиброванным.";
        }
        enum slave {
          value 9;
          description
            "Порт синхронизируется с выбранным ведущим портом.";
        }
      }
      description
        "Текущее состояние машины протокола, связанной с портом.
         Перечисляемые значения полностью заданы IEEE Std 1588.";
      reference
        "IEEE Std 1588-2008: 8.2.5.3.1, 9.2.5";
    }

    typedef time-interval-type {
      type int64;
      description
        "Производный тип данных для интервала времени, представляемый 
         в наносекундах с умножением на 2^16.";
      reference
        "IEEE Std 1588-2008: 5.3.2";
    }

    typedef clock-identity-type {
      type binary {
        length "8";
      }
      description
        "Производный тип данных для идентификации часов.";
      reference
        "IEEE Std 1588-2008: 5.3.4";
    }

    grouping clock-quality-grouping {
      description
        "Производный тип данных для качества часов, содержащий
         clockClass, clockAccuracy, offsetScaledLogVariance.";
      reference
        "IEEE Std 1588-2008: 5.3.7";
      leaf clock-class {
        type uint8;
        default "248";
        description
          "clockClass обозначает прослеживаемость времени или 
           частоты, распространяемых часами.";
      }
      leaf clock-accuracy {
        type uint8;
        description
          "clockAccuracy указывает ожидаемую точность часов.";
      }
      leaf offset-scaled-log-variance {
        type uint16;
        description
          "offsetScaledLogVariance предоставляет оценку отклонений
           часов от линейного хода при отсутствии синхронизации
           с другими часами по протоколу.";
      }
    }

    container ptp {
      description
        "Структура PTP, содержащая все атрибуты набора данных PTP,
         в которую могут добавляться необязательные атрибуты PTP.";
      list instance-list {
        key "instance-number";
        description
          "Список наборов данных PTP в устройстве(см. параграф 6.3 в 
           IEEE Std 1588-2008). Каждый набор данных PTP представляет 
           экземпляр реализации PTP в устройстве (т. е., OC или BC).";
        leaf instance-number {
          type uint32;
          description
            "Номер текущего экземпляра PTP, используемый для управления.
             Этот номер не представляет номер домена PTP и не 
             применяется в сообщениях PTP.";
        }
        container default-ds {
          description
            "Принятый по умолчанию набор данных часов (см. параграф
             8.2.1 в IEEE Std 1588-2008). Этот набор представляет 
             конфигурацию и состояние, требуемые для работы конечных
             автоматов протокола точного времени (PTP).";
          reference
            "IEEE Std 1588-2008: 8.2.1";
          leaf two-step-flag {
            type boolean;
            description
              "Значение true указывает двухшаговые (two-step) часы, 
               иначе часы являются одношаговыми (one-step).";
          }
          leaf clock-identity {
            type clock-identity-type;
            config false;
            description
              "Значение clockIdentity для локальных часов.";
          }
          leaf number-ports {
            type uint16;
            description
              "Число портов PTP в экземпляре.";
          }
          container clock-quality {
            description
              "Значение clockQuality для локальных часов.";
            uses clock-quality-grouping;
          }
          leaf priority1 {
            type uint8;
            description
              "Атрибут priority1 для локальных часов.";
          }
          leaf priority2 {
            type uint8;
            description
              "Атрибут priority2 для локальных часов.";
          }
          leaf domain-number {
            type uint8;
            description
              "Номер текущего домена синхронизации.";
          }
          leaf slave-only {
            type boolean;
            description
              "Значение true указывает вторичные (slave-only) часы.";
          }
        }
        container current-ds {
          description
            "Текущий набор данных часов (см. параграф 8.2.2 в IEEE Std
             1588-2008). Этот набор данных представляет локальные 
             состояния полученные из обмена сообщениями PTP.";
          reference
            "IEEE Std 1588-2008: 8.2.2";
          leaf steps-removed {
            type uint16;
            default "0";
            description
              "Число коммуникационных путей, пройденных между локальными 
               и эталонными (grandmaster) часами.";
          }
          leaf offset-from-master {
            type time-interval-type;
            description
              "текущая разница времени между ведущими и ведомыми часами,
               рассчитанная ведомыми (slave).";
          }
          leaf mean-path-delay {
            type time-interval-type;
            description
              "Текущее среднее время распространения между ведущими и
               ведомыми часами, рассчитанное ведомыми.";
          }
        }
        container parent-ds {
          description
            "Родительский набор данных для часов (см. параграф 8.2.3 в 
             IEEE Std 1588-2008).";
          reference
            "IEEE Std 1588-2008: 8.2.3";
          container parent-port-identity {
            description
              "Значение portIdentity порта на ведущем устройстве,
               содержащее clockIdentity и portNumber.";
            reference
              "IEEE Std 1588-2008: 5.3.5";
            leaf clock-identity {
              type clock-identity-type;
              description
                "Идентификатор часов.";
            }
            leaf port-number {
              type uint16;
              description
                "Номер порта.";
            }
          }
          leaf parent-stats {
            type boolean;
            default "false";
            description
              "Значение true указывает, что
               observedParentOffsetScaledLogVariance и
               observedParentClockPhaseChangeRate у parentDS
               измерены и действительны.";
          }
          leaf observed-parent-offset-scaled-log-variance {
            type uint16;
            default "65535";
            description
              "Оценка вариаций PTP родительских часов, наблюдаемых
               ведомыми часами.";
          }
          leaf observed-parent-clock-phase-change-rate {
            type int32;
            description
              "Оценка скорости изменения фазы родительской часов, 
               наблюдаемой ведомыми часами.";
          }
          leaf grandmaster-identity {
            type clock-identity-type;
            description
              "Атрибут clockIdentity эталонных (grandmaster) часов.";
          }
          container grandmaster-clock-quality {
            description
              "Значение clockQuality эталонных (grandmaster) часов.";
            uses clock-quality-grouping;
          }
          leaf grandmaster-priority1 {
            type uint8;
            description
              "Атрибут priority1 эталонных (grandmaster) часов.";
          }
          leaf grandmaster-priority2 {
            type uint8;
            description
              "Атрибут priority2 эталонных (grandmaster) часов.";
          }
        }
        container time-properties-ds {
          description
            "Набор данных timeProperties в часах (см. параграф 8.2.4 в
             IEEE Std 1588-2008).";
          reference
            "IEEE Std 1588-2008: 8.2.4";
          leaf current-utc-offset-valid {
            type boolean;
            description
              "Значение true указывает действительное смещение UTC.";
          }
          leaf current-utc-offset {
            when "../current-utc-offset-valid='true'";
            type int16;
            description
              "Смещение (в секундах) между TAI и UTC когда эпохой 
               системы PTP является эпоха PTP, т. е. ptp-timescale 
               имеет значение TRUE. В ином случае не имеет смысла.";
          }
          leaf leap59 {
            type boolean;
            description
              "Значение true указывает, что последняя минута текущих
               суток UTC содержит 59 секунд.";
          }
          leaf leap61 {
            type boolean;
            description
              "Значение true указывает, что последняя минута текущих
               суток UTC содержит 61 секунду.";
          }
          leaf time-traceable {
            type boolean;
            description
              "Значение true говорит, что шкала времени и 
               currentUtcOffset отслеживаются до первичного источника.";
          }
          leaf frequency-traceable {
            type boolean;
            description
              "Значение true говорит, что частота, задающая шкалу 
               времени, отслеживается до первичного источника.";
          }
          leaf ptp-timescale {
            type boolean;
            description
              "Значение true говорит, что шкала времени эталонных часов
               является PTP, иначе она произвольна (ARB).";
          }
          leaf time-source {
            type uint8;
            description
              "Источник времени эталонных часов (grandmaster).";
          }
        }
        list port-ds-list {
          key "port-number";
          description
            "Список наборов данных порта часов (см. параграф 8.2.5 в 
             IEEE Std 1588-2008).";
          reference
            "IEEE Std 1588-2008: 8.2.5";
          leaf port-number {
            type uint16;
            description
              "Номер порта. Наборы данных (т. е. модель информации)
               IEEE Std 1588-2008 задают значения portDS.portIdentity, 
               используемые типизованной структурой с элементами 
               clockIdentity и portNumber.

               В этой модели YANG параметр portIdentity не моделируется
               в port-ds-list. Однако его элементы представлены:
               portIdentity.portNumber обеспечивается этим листом 
               port-number в port-ds-list, а portIdentity.clockIdentity -
               листом clock-identity в default-ds экземпляра
               (т. е., ../../default-ds/clock-identity).";
          }
          leaf port-state {
            type port-state-enumeration;
            default "initializing";
            description
              "Текущее состояние, связанное с портом.";
          }
          leaf underlying-interface {
            type if:interface-ref;
            description
              "Ссылка на настроенный базовый интерфейс, используемый
               этим портом PTP (см. RFC 8343).";
            reference
              "RFC 8343: A YANG Data Model for Interface Management";
          }
          leaf log-min-delay-req-interval {
            type int8;
            description
              "Двоичный логарифм minDelayReqInterval (минимально
               разрешённый средний интервал между сообщениями
               Delay_Req).";
          }
          leaf peer-mean-path-delay {
            type time-interval-type;
            default "0";
            description
              "Оценка текущей задержки распространения в одном
               направлении, когда delayMechanism — это P2P, в ином 
               случае это 0.";
          }
          leaf log-announce-interval {
            type int8;
            description
              "Двоичный логарифм среднего значения announceInterval
               (средний интервал между последовательными Announce).";
          }
          leaf announce-receipt-timeout {
            type uint8;
            description
              "Число announceIntervals без получения сообщений 
               Announce message перед возникновением события
               ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES.";
          }
          leaf log-sync-interval {
            type int8;
            description
              "Двоичный логарифм среднего значения SyncInterval для
               групповых сообщений. Скорость индивидуальных передач
               согласуется отдельно на уровне портов и не ограничивается
               этим атрибутом.";
          }
          leaf delay-mechanism {
            type delay-mechanism-enumeration;
            description
              "Вариант измерения задержки распространения, используемого 
               портом при расчёте meanPathDelay.";
          }
          leaf log-min-pdelay-req-interval {
            type int8;
            description
              "Двоичный логарифм среднего значения minPdelayReqInterval
               (минимально разрешённый средний интервал между 
               сообщениями Pdelay_Req).";
          }
          leaf version-number {
            type uint8;
            description
              "Используемая портом версия PTP.";
          }
        }
      }
      container transparent-clock-default-ds {
        description
          "Элементы набора данных transparentClockDefault
           (см. параграф 8.3.2 в IEEE Std 1588-2008).";
        reference
          "IEEE Std 1588-2008: 8.3.2";
        leaf clock-identity {
          type clock-identity-type;
          config false;
          description
            "Значение clockIdentity для прозрачных часов.";
        }
        leaf number-ports {
          type uint16;
          description
            "Число портов PTP в прозрачных часах.";
        }
        leaf delay-mechanism {
          type delay-mechanism-enumeration;
          description
            "Вариант измерения задержки распространения,
             применяемый прозрачными часами.";
        }
        leaf primary-domain {
          type uint8;
          default "0";
          description
            "Значение domainNumber основного домена синхронизации 
             (см. параграф 10.1 в IEEE Std 1588-2008).";
          reference
            "IEEE Std 1588-2008: 10.1";
        }
      }
      list transparent-clock-port-ds-list {
        key "port-number";
        description
          "Список наборов данных transparentClockPort прозрачных часов
           (см. параграф 8.3.3 в IEEE Std 1588-2008).";
        reference
          "IEEE Std 1588-2008: 8.3.3";
        leaf port-number {
          type uint16;
          description
            "Номер порта. Наборы данных (т. е. модель информации)
             IEEE Std 1588-2008 задают значения 
             transparentClockPortDS.portIdentity, используемые
             типизованной структурой с элементами clockIdentity
             и portNumber.

             В этой модели YANG параметр portIdentity не моделируется в
             transparent-clock-port-ds-list. Однако его элементы 
             представлены: portIdentity.portNumber обеспечивается этим 
             листом в transparent-clock-port-ds-list, а 
             portIdentity.clockIdentity - листом clock-identity в 
             transparent-clock-default-ds (т. е., 
             ../../transparent-clock-default-ds/clock-identity).";
        }
        leaf log-min-pdelay-req-interval {
          type int8;
          description
            "Двоичный логарифм minPdelayReqInterval (минимально
             разрешённый средний интервал между сообщениями
             Pdelay_Req).";
        }
        leaf faulty-flag {
          type boolean;
          default "false";
          description
            "Значение true указывает отказ порта.";
        }
        leaf peer-mean-path-delay {
          type time-interval-type;
          default "0";
          description
            "Оценка текущей односторонней задержки распространения
             на канале, когда delayMechanism — это P2P, в ином 
             случае 0.";
        }
      }
    }
  }

  <CODE ENDS>

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

Заданные этим документом модули YANG определяют схему для данных, предназначенную для доступа через сеть с использованием протоколов управления, таких как NETCONF [RFC6241] или RESTCONF [RFC8040]. Нижним уровнем NETCONF служит защищённый транспорт с обязательной поддержкой SSH (Secure Shell) [RFC6242]. Нижним уровнем RESTCONF служит протокол HTTPS с обязательной поддержкой защиты на транспортном уровне (TLS) [RFC8446].

Модель доступа к конфигурации сети (NACM – Network Configuration Access Control Model) [RFC8341] обеспечивает возможность разрешить доступ лишь определённых пользователей NETCONF или RESTCONF к заранее заданному подмножеству операций NETCONF или RESTCONF и содержимого.

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

/ptp/instance-list задаёт экземпляры (т. е. наборы данных PTP) для OC или BC.

/ptp/transparent-clock-default-ds задаёт принятый по умолчанию набор данных для TC.

/ptp/transparent-clock-port-ds-list задаёт список наборов данных портов для TC.

Запись в такие узлы (например, edit-config) без должной защиты может негативно влиять на работу сети. В частности, неподходящая настройка может отрицательно сказаться на работе сети синхронизации PTP. Например, это может быть потеря синхронизации часов, снижение точности набора часов и даже выход из строя всей сети синхронизации.

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

Этот документ регистрирует URI в реестре IETF XML Registry [RFC3688]

   URI: urn:ietf:params:xml:ns:yang:ietf-ptp
   Registrant Contact: The IESG
   XML: N/A; запрошенный URI является пространством имён XML

Документ регистрирует модуль YANG в реестре YANG Module Names [RFC6020]

   Name:         ietf-ptp
   Namespace:    urn:ietf:params:xml:ns:yang:ietf-ptp
   Prefix:       ptp
   Reference:    RFC 8575

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

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

[RFC2119] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC3688] Mealling, M., «The IETF XML Registry», BCP 81, RFC 3688, DOI 10.17487/RFC3688, January 2004, <https://www.rfc-editor.org/info/rfc3688>.

[RFC6020] Bjorklund, M., Ed., «YANG — A Data Modeling Language for the Network Configuration Protocol (NETCONF)», RFC 6020, DOI 10.17487/RFC6020, October 2010, <https://www.rfc-editor.org/info/rfc6020>.

[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., «Network Configuration Protocol (NETCONF)», RFC 6241, DOI 10.17487/RFC6241, June 2011, <https://www.rfc-editor.org/info/rfc6241>.

[RFC6242] Wasserman, M., «Using the NETCONF Protocol over Secure Shell (SSH)», RFC 6242, DOI 10.17487/RFC6242, June 2011, <https://www.rfc-editor.org/info/rfc6242>.

[RFC6991] Schoenwaelder, J., Ed., «Common YANG Data Types», RFC 6991, DOI 10.17487/RFC6991, July 2013, <https://www.rfc-editor.org/info/rfc6991>.

[RFC7950] Bjorklund, M., Ed., «The YANG 1.1 Data Modeling Language», RFC 7950, DOI 10.17487/RFC7950, August 2016, <https://www.rfc-editor.org/info/rfc7950>.

[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, «RESTCONF Protocol», RFC 8040, DOI 10.17487/RFC8040, January 2017, <https://www.rfc-editor.org/info/rfc8040>.

[RFC8174] Leiba, B., «Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words», BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8341] Bierman, A. and M. Bjorklund, «Network Configuration Access Control Model», STD 91, RFC 8341, DOI 10.17487/RFC8341, March 2018, <https://www.rfc-editor.org/info/rfc8341>.

[RFC8342] Bjorklund, M., Schoenwaelder, J., Shafer, P., Watsen, K., and R. Wilton, «Network Management Datastore Architecture (NMDA)», RFC 8342, DOI 10.17487/RFC8342, March 2018, <https://www.rfc-editor.org/info/rfc8342>.

[RFC8343] Bjorklund, M., «A YANG Data Model for Interface Management», RFC 8343, DOI 10.17487/RFC8343, March 2018, <https://www.rfc-editor.org/info/rfc8343>.

[RFC8446] Rescorla, E., «The Transport Layer Security (TLS) Protocol Version 1.3», RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.

[IEEE1588] IEEE, «IEEE Standard for a Precision Clock Synchronization Protocol for Networked Measurement and Control Systems», IEEE Std 1588-2008, DOI 10.1109/IEEESTD.2008.4579760, July 2008.

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

[IEEE8021AS] IEEE, «IEEE Standard for Local and Metropolitan Area Networks — Timing and Synchronizations for Time-Sensitive Applications in Bridged Local Area Networks», IEEE 802.1AS-2001.

[RFC3444] Pras, A. and J. Schoenwaelder, «On the Difference between Information Models and Data Models», RFC 3444, DOI 10.17487/RFC3444, January 2003, <https://www.rfc-editor.org/info/rfc3444>.

[RFC4663] Harrington, D., «Transferring MIB Work from IETF Bridge MIB WG to IEEE 802.1 WG», RFC 4663, DOI 10.17487/RFC4663, September 2006, <https://www.rfc-editor.org/info/rfc4663>.

[RFC7384] Mizrahi, T., «Security Requirements of Time Protocols in Packet Switched Networks», RFC 7384, DOI 10.17487/RFC7384, October 2014, <https://www.rfc-editor.org/info/rfc7384>.

[RFC8340] Bjorklund, M. and L. Berger, Ed., «YANG Tree Diagrams», BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, <https://www.rfc-editor.org/info/rfc8340>.

[RFC8173] Shankarkumar, V., Montini, L., Frost, T., and G. Dowd, «Precision Time Protocol Version 2 (PTPv2) Management Information Base», RFC 8173, DOI 10.17487/RFC8173, June 2017, <https://www.rfc-editor.org/info/rfc8173>.

Приложение A. Перенос работы YANG в IEEE 1588 WG

Это приложение является информационным и описывает будущий план передачи ответственности за модули YANG IEEE Std 1588 от рабочей группы (Working Group или WG) IETF TICTOC в IEEE 1588 WG, разрабатывающей технологию синхронизации времени, для управления которой создаются модули YANG. Приложение ориентировано на будущие планы стандартизации IETF и IEEE. Поскольку такие планы невозможно предсказать достоверно, приложение носит информационный характер и не задаёт императивной или нормативной спецификации.

Модуль YANG IEEE Std 1588-2008 представляет сотрудничество между IETF (YANG) и IEEE (1588). Для исходной стандартизации модулей YANG IEEE-1588 YANG информационная модель относительно понятна (наборы данных IEEE Std 1588), но нужен опыт работы с YANG, делающий IETF подходящим местом для стандартизации. У TICTOC WG есть опыт работы с IEEE Std 1588, делающий рабочую группу подходящей для разработки в рамках IETF.

IEEE 1588 WG предполагает, что стандарт будет постоянно обновляться. По мере того, как члены IEEE 1588 WG приобретут практический опыт работы с YANG, рабочая группа IEEE 1588 станет более подходящим местом для стандартизации модулей YANG. При пересмотре и/или изменении стандарта IEEE 1588 члены IEEE 1588 смогут более эффективно синхронизировать выпуски модуля YANG с новыми версиями стандарта IEEE 1588.

Это приложение предназначено для установки чётких ожиданий IETF и IEEE в плане грядущей передачи модулей YANG IEEE 1588 в IEEE 1588 WG, чтобы сделать эту передачу как можно более гладкой. По мере передачи могут возникать разные ситуации, которые могут быть разрешены путём обсуждения в почтовых конференциях IETF TICTOC WG и/или у соответствующих представителей.

Это приложение основано на информационном документе [RFC4663], где обсуждается похожая передача работы по MIB от IETF Bridge MIB WG в IEEE 802.1 WG.

A.1. Допущения о переносе

Предположим, что в IESG одобрена публикация RFC с модулем YANG для опубликованного стандарта IEEE 1588. Сейчас это IEEE Std 1588-2008, но возможны выпуски модулей YANG для последующих версий 1588, которые может публиковать IETF TICTOC WG. В этом приложении используется выражение «последний выпуск YANG IETF 1588» для обозначения наиболее свежего опубликованного модуля YANG 1588 от IETF TICTOC WG.

Комитет по новым стандартам (New Standards Committee или NesCom) совета по стандартизации IEEE-SA обрабатывает новые запросы на предоставление полномочий проектам (Project Authorization Request или PAR, <http://standards.ieee.org/board/nes/>). Документы PAR похожи на уставы рабочих групп (Working Group Charter) IETF и включают сведения, относящиеся к области действия, цели и обоснованию проектов стандартизации.

Предположим, что в IEEE 1588 одобрен новый документ PAR, явно задающий разработку модуля YANG. Передача работы YANG будет происходит в контексте IEEE 1588 PAR. В этом приложении используется выражение «первый стандарт YANG IEEE 1588» для обозначения первого стандарта IEEE 1588 для YANG.

Предположим, что в рамках передачи работы YANG группа IETF TICTOC WG согласилась прервать свою работу над стандартными модулями YANG для IEEE 1588. Также предположим, что IEEE 1588 WG участвовала в разработке последнего выпуска модуля YANG IETF 1588, так что первый стандарт YANG IEEE 1588 фактически будет выпуском этого модуля. Иными словами, передача работы YANG будет достаточно «чистой».

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

A.2. Вопросы интеллектуальной собственности

При рассмотрении юридических вопросов, связанных с передачей документов Bridge MIB WG в IEEE 802.1 WG (параграф 3.1 и раздел 9 в [RFC4663]) был сделан вывод об отсутствии у IETF достаточных юридических полномочий для передачи документов в IEEE без согласия авторов.

Если последний выпуск YANG IETF 1588 публикуется как RFC, работа должна быть передана из IETF в IEEE, чтобы IEEE 1588 WG могла начать работу над первым стандартом YANG IEEE 1588.

Когда работа над первым модулем IEEE YANG начнётся в IEEE 1588 WG, она будет базироваться на последнем модуле IETF YANG из этого RFC, что требует передачи этой работы из IETF в IEEE. Чтобы передача не зависела от авторов этого RFC, отдел управления рисками и лицензирования IEEE SA предоставил авторам соответствующие формы и механизмы для неисключительного предоставления IEEE прав на создание производных от документа работ. Эти формы и механизмы потребуется обновлять для будущих моделей IETF YANG IEEE 1588 (подписанные формы хранятся в отделе управления рисками и лицензирования IEEE SA). Это поможет сделать будущую передачу работы из IETF в IEEE максимально гладкой.

Как отмечено в разделе «Статус документа», содержащийся здесь модуль YANG соответствует положениям BCP 78. IETF сохраняет за собой все права, предоставленные на момент публикации RFC.

A.3. Пространство имён и имя модуля

Как указано в разделе 5. Взаимодействие с IANA, модуль YANG из этого документа использует IETF как корень своего пространства имён URN и имени модуля YANG. Использование IETF в качестве корня для этих имён подразумевает, что модуль YANG стандартизован рабочей группой IETF по процессу IETF. Если рабочая группа IEEE 1588 продолжит использовать имена с корнями в IETF, стандартизацию IEEE 1588 YANG придётся сохранять в IETF. Цель переноса работы YANG состоит в исключении такой зависимости между органами стандартизации.

В IEEE 802 имеется активный документ PAR (IEEE P802d) по созданию пространства имён URN для использования IEEE (<http://standards.ieee.org/develop/project/802d.html>). Вполне вероятно одобрение и публикация IEEE 802 PAR до переноса работы YANG в IEEE 1588 WG. В этом случае IEEE 1588 WG может использовать пространство имён IEEE URN для первого стандартного модуля YANG IEEE 1588, например, urn:ieee:Std:1588:yang:ieee1588-ptp, где ieee1588-ptp — зарегистрированное имя модуля YANG в IEEE.

При допущениях из Приложения A.1, префикс первого модуля YANG IEEE 1588 будет совпадать с префиксом последнего модуля YANG IETF 1588 (т. е. ptp). Другие модули YANG могут сохранять префикс импорта ptp для доступа к узлам PTP в процессе перехода от последнего модуля YANG IETF 1588 к первому YANG IEEE 1588.

Результатом такой смены имён будет то, что для полной совместимости сервер (узел IEEE 1588) может реализовать последний модуль YANG IETF 1588 (с корнем IETF) и первый модуль YANG IEEE 1588 (with IEEE root). Поскольку содержимое передаваемого модуля YANG не меняется, реализация сервера фактически одинакова для обоих.

Клиент последнего модуля YANG IETF 1588 (или более ранних) ищет модуль с корнем IETF, а клиент первого YANG IEEE 1588 (или позднее) ищет модуль с корнем IEEE.

A.4. Модули YANG IEEE 1588 в формате ASCII

Хотя IEEE 1588 может принять решение о публикации модулей YANG лишь в формате PDF, который принят для их стандартов, не публикуя вариант ASCII, но большинство систем сетевого управления не сможет импортировать модули YANG из PDF. Таким образом, отказ от публикации ASCII-версии модуля YANG негативно повлияет на реализацию и внедрение модуля YANG и затруднить возможное рецензирование модуля со стороны IETF.

Этот документ рекомендует IEEE 1588 WG рассмотреть свои будущие планы в части указанных ниже аспектов.

  • Общий доступ к модуля YANG в формате ASCII в процессе разработки проектов. Эти файлы позволят участникам IETF работать с этими документами для предварительного рецензирования.

  • Общедоступная YANG-часть выпущенных стандартов IEEE 1588, предоставляемая в форме файла ASCII для каждого модуля YANG. Эти файлы ASCII предназначены для использования стандарта IEEE 1588.

Как пример общей доступности в IEEE 802 при разработке проектов используется тот же репозиторий, который IETF использует для разработки модулей YANG (<https://github.com/YangModels/yang>). Ветви IEEE предназначены для экспериментальных работ (до PAR), а также стандартных работ (после PAR). В IEEE-SA одобрено использование этого репозитория для разработки проектов, но не для опубликованных стандартов.

Примером публичной доступности для опубликованных стандартов IEEE 802.1 может служить список ASCII-файлов для MIB (<http://www.ieee802.org/1/files/public/MIBs/> и <http://www.ieee802.org/1/pages/MIBS.html>). Аналогичные списки планируются и для файлов IEEE 802.1 YANG.

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

Авторы благодарны Tom Petch, Radek Krejci, Mahesh Jethanandani, Tal Mizrahi, Opher Ronen, Liang Geng, Alex Campbell, Joe Gwinn, John Fletcher, William Zhao, Dave Thaler за их значимые рецензии и предложения. Спасибо Benoit Claise и Radek Krejci за проверку модуля YANG, а также Jingfei Lv и Zitao Wang за обсуждения IEEE 1588 и YANG, соответственно.

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

Yuanlong Jiang (editor)
Huawei
Bantian, Longgang district
Shenzhen 518129
China
Email: jiangyuanlong@huawei.com
 
Xian Liu
Independent
Shenzhen 518129
China
Email: lene.liuxian@foxmail.com
 
Jinchun Xu
Huawei
Bantian, Longgang district
Shenzhen 518129
China
Email: xujinchun@huawei.com
 
Rodney Cummings (editor)
National Instruments
11500 N. Mopac Expwy Bldg. C
Austin, TX 78759-3504
United States of America
Email: Rodney.Cummings@ni.com

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

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

nmalykh@protokols.ru

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

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

3Имена атрибутов соответствуют IEEE Std 1588-2008, но изменены в стиле YANG, т. е. приведены к нижнему регистру и пробелы заменены символами дефиса.

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

RFC 8532 Generic YANG Data Model for the Management of Operations, Administration, and Maintenance (OAM) Protocols That Use Connectionless Communications

Internet Engineering Task Force (IETF)                          D. Kumar
Request for Comments: 8532                                         Cisco
Category: Standards Track                                        M. Wang
ISSN: 2070-1721                                               Q. Wu, Ed.
                                                                  Huawei
                                                               R. Rahman
                                                             S. Raghavan
                                                                   Cisco
                                                              April 2019

Generic YANG Data Model for the Management of Operations, Administration, and Maintenance (OAM) Protocols That Use Connectionless Communications

Базовая модель данных YANG для управления протоколами OAM без соединений

PDF

Аннотация

В этом документе представлена базовая модель данных YANG для управления протоколами OAM1, не использующими соединений (connectionless). Модель данных определена с использованием языка YANG, заданного в RFC 7950. Модель представляет независимую от технологии абстракцию важных конструкций OAM для протоколов OAM, не использующих соединений. Представленная здесь модель может быть расширена путём включения детялей для конкретных технологий.

Такой подход обеспечивает два важных преимущества — во-первых, единообразие для разных протоколов OAM, во-вторых, поддержка как вложенных рабочих процессов OAM (т. е. выполнение функций OAM на одном или разных уровнях через один унифицированный интерфейс), так и интерактивных процессов OAM (т. е. выполнение функций OAM на одном уровне через унифицированный интерфейс).

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

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

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

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

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

Copyright (c) 2019. Авторские права принадлежат 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).

1. Введение

Функции OAM важны для сети и позволяют операторам:

  1. отслеживать сетевые коммуникации (т. е. проверка доступности и непрерывности работы);

  2. находить и устранять неполадки;

  3. отслеживать соглашения о уровне обслуживания и производительность (управление производительностью).

Обзор инструментов OAM представлен в [RFC7276].

Утилиты Ping и Traceroute [RFC4443], а также обнаружение двухсторонней пересылки (Bidirectional Forwarding Detection или BFD) [RFC5880] являются общеизвестными инструментами проверки и отыскания точки отказа, особенно в сетях IP [RFC792]. За прошедшие годы в разных технологиях были разработаны похожие наборы для решения таких же задач.

Различные инструменты OAM могут поддерживать технологии, ориентированные на соединения, и технологии без соединений. В первом случае до передачи данных организуется соединение и после его создания для передачи фактических данных пользователя больше не требуется дополнительных управляющих сведений, таких как сигнализация или сведения об операциях и обслуживании. В технологиях без соединений данные обычно передаются конечными точками без предварительного согласования, но для идентификации получателя требуется управляющая информация (например, [G.800] и [RFC7276]). Модель данных YANG для протоколов OAM, использующих соединения, приведена в [RFC8531].

Этот документ определяет модель данных YANG [RFC7950] для протоколов OAM, не использующих соединений. Базовая модель данных YANG для OAM без соединений включает только данные конфигурации и состояния. Она может применяться в сочетании с моделью метода извлечения данных, описанной в [RFC8533] и содержащей процедуры извлечения, такие как RPC, или использоваться независимо от этой модели извлечения данных.

2. Используемые соглашения

Ниже указаны используемые в этом документе термины, которые определены в [RFC6241].

  • client — клиент;
  • configuration data — данные конфигурации;
  • server — сервер;
  • state data — данные состояния.

Ниже указаны используемые в этом документе термины, которые определены в [RFC7950].

  • augment — дополнение;
  • data model — модель данных;
  • data node — узел данных.

Термины для описания моделей данных YANG представлены в [RFC7950].

2.1. Сокращения

BFD — Bidirectional Forwarding Detection [RFC5880] — обнаружение двухсторонней пересылки.

RPC — Remote Procedure Call [RFC1831] — удалённый вызов процедуры.

DSCP — Differentiated Services Code Point — код дифференцированного обслуживания.

VRF — Virtual Routing and Forwarding [RFC4382] — виртуальная маршрутизация и пересылка.

OWAMP — One-Way Active Measurement Protocol [RFC4656] — протокол односторонних активных измерений.

TWAMP — Two-Way Active Measurement Protocol [RFC5357] — протокол двухсторонних активных измерений.

AS — Autonomous System — автономная система.

LSP — Label Switched Path — путь с коммутацией по меткам.

TE — Traffic Engineering — огранизация (построение) трафика.

MPLS — Multiprotocol Label Switching — многопротокольная коммутация по меткам.

NI — Network Instance — сетевой интерфейс.

PTP — Precision Time Protocol [IEEE.1588v2] — протокол точного времени.

NTP — Network Time Protocol [RFC5905] — протокол сетевого времени.

2.2. Терминология

MAC

Media Access Control — управление доступом к среде.

MAC address

Адрес интерфейса на канальном уровне.

TP

Test Point — тестовая точка. Функциональный элемент, определённый на узле сеть, который может инициировать и/или реагировать на диагностические тесты OAM. Этот документ сосредоточен на функциональности TP в плоскости данных.

RPC operation

Конкретная операция RPC.

CC

Continuity Check — проверка непрерывности [RFC7276], служащая для проверки доступности адресата и называемая также проверкой доступности.

2.3. Диаграммы деревьев

Диаграммы деревьев данных в этом документе используют нотацию [RFC8340].

3. Обзор модели OAM без соединений

Модель данных YANG для протоколов OAM без соединений разделена на два модуля:

  • ietf-lime-time-types содержит базовые определения, такие как связанные со временем типы данных;

  • ietf-connectionless-oam задаёт независимые от топологии абстракции основных конструкций OAM для протоколов OAM, не использующих соединений.

Модуль ietf-connectionless-oam дополняет путь /networks/network/node, заданный в модуле ietf-network [RFC8345] группировкой test-point-locations (параграф 3.5). Узлы сети в пути /networks/network/node служат для описания сетевых иерархий и инвентаризации узлов сети. В группировке test-point-locations местоположение каждой тестовой точки определяется листом tp-location-type, выбор которого ведёт к контейнеру, включающему test-point-locations. Каждый список test-point-locations включает группировку test-point-location-info, содержащую группировки:

  • tp-technology;

  • tp-tools;

  • connectionless-oam-tps.

Группировки tp-address и tp-address-ni не входят в группировку test-point-location-info. Чтобы обеспечить независимость от адресации и различный состав. В зависимости от выбора tp-location-type (определяется tp-address-ni) каждый контейнер отличается по своему составу test-point-locations, а test-point-location-info является общим аспектом всех test-point-locations.

Группировка tp-address-ni служит для описания соответствующего экземпляра сети, а tp-technology указывает технологические детали OAM. Группировка connectionless-oam-tps применяется для описания связи тестовой точки с другими тестовыми точками. Группировка tp-tools описывает поддерживаемые инструменты OAM.

На верхнем уровне модели имеется контейнер cc-oper-data для статистики сессии, а также задана группировка для общей статистики сессий, применимой лишь для проактивных сеансов OAM (см. 3.2. Инструменты).

3.1. Адрес TP

В протоколах OAM адресом TP может быть:

  • MAC-адрес [RFC6136] для TP канального уровня;

  • адрес IPv4 или IPv6 для TP уровня IP;

  • атрибут TP, указывающий TP связанную с функцией прикладного уровня;

  • Router-id для представления устройства или узла, обычно применяемый для идентификации узлов при маршрутизации и в других протоколах плоскости управления [RFC8294].

Для задания способов пересылки тестовых пакетов группировка tp-address должна быть связана с дополнительными параметрами, например DSCP для IP или Traffic Class [RFC5462] для MPLS. В базовой модели YANG для OAM без соединений эти параметры не задаются явно и пользователь модели может добавлять параметры в соответствии со своими требованиями.

3.2. Инструменты

Различные инструменты OAM могут применяться с проактивной активацией или по запросу. Проактивными являются действия OAM, выполняемые непрерывно для упреждающего информирования об отказах. Для проактивного метода OAM требуется сохраняющаяся конфигурация. Действия OAM по запросу инициируются ручным вмешательством для выполнения определённой диагностики в ограниченном интервале времени. Для таких методов нужна лишь временная конфигурация (например, [RFC7276] и [G.8013]). В OAM без соединений группировка session-type определяет тип активации для текущей сессии.

В OAM без соединений атрибуты инструментов служат для описания инструментария поиска и изоляции отказов. Кроме того, они могут служить условиями ограничений при расширении базовой модели для конкретной технологии OAM. Например, для настройки ICMP PING следует установить в листе ../coam:continuity-check значение true, а затем дополнить базовую модель LIME4 деталями, относящимися к ICMP PING.

3.3. Соседние тестовые точки OAM

С учётом многоуровневой архитектуры типичного сетевого стека набор связанных протоколов OAM также имеет многоуровневую структуру — каждый коммуникационный уровень в стеке может иметь свои протоколы OAM [RFC7276], которые могут быть связаны с определенным административным доменом. Управление этими связанными протоколами OAM требует соответствующих тестовых точек на узлах, доступных соответствующему домену управления. Поэтому данный сетевой интерфейс может на деле представлять несколько тестовых точек.

Каждая тестовая точка OAM может иметь список связанных с ней соседних тестовых точек на других уровнях стека протоколов для того же интерфейса. Это позволяет пользователям легко перемещаться между связанными соседними уровнями для эффективного поиска и устранения неполадок. В этой модели лист position задаёт относительное положение соседней тестовой точки, соответствующей текущей тестовой точке и это позволяет сопоставлять отказы в разных местах. Если имеется соседняя тестовая точка, размещённая впереди текущей, для листа position устанавливается значение -1. Если имеется соседняя тестовая точка, размещённая после текущей, лист position имеет значение 1. При отсутствии соседних тестовых точек впереди или позади текущей точки лист position имеет значение 0.

     +-- oam-neighboring-tps* [index]
        +-- index?                         uint16
        +-- position?                      int8
        +-- (tp-location)?
           +--:(mac-address)
           |  +-- mac-address-location?    yang:mac-address
           +--:(ipv4-address)
           |  +-- ipv4-address-location?   inet:ipv4-address
           +--:(ipv6-address)
           |  +-- ipv6-address-location?   inet:ipv6-address
           +--:(as-number)
           |  +-- as-number-location?      inet:as-number
           +--:(router-id)
              +-- router-id-location?      rt:router-id

3.4. Сведения о местоположении TP

Это базовая группировка для сведений о местоположении тестовой точки (test-point-location-info), указывающая расположение TP с использованием группировок tp-technology, tp-tools и oam-neighboring-tps, показанных выше.

3.5. Местоположение TP

Это базовая группировка для местоположений TP. Лист tp-location-type служит для указания типа местоположения, например, ipv4-location-type, ipv6-location-type и т. п. Для каждого типа местоположения задан контейнер со списком адресов тестовых точек и ключом, сведениями о местоположении TP, определенными выше, и именем экземпляра сети (например, именем VRF), если оно требуется.

3.6. Данные обнаружения пути

Это базовая группировка для модели данных обнаружения пути, которые можно получить с помощью любого метода извлечения, включая операции RPC. Вывод метода обнаружения пути включает контейнеры src-test-point и dst-test-point, листья sequence-number и hop-cnt, различные типы статистики сессии и сведения, относящиеся к проверке и трассировке пути. Обнаружение пути включает данные, извлекаемые по этапам пересылки (per-hop), через список элементов path-trace-info-list, включающий группировку timestamp, ingress-intf-name, egress-intf-name и app-meta-data. Модель данных обнаружения пути сделана достаточно общей для использования различных методов извлечения данных и по этой причине ни одно поле не является обязательным. Набор методов извлечения задан в [RFC8533].

3.7. Данные проверки непрерывности

Это базовая группировка для модели данных проверки непрерывности, которые можно получить с помощью любого метода извлечения, включая операции RPC. Вывод Continuity Check включает контейнеры src-test-point и dst-test-point, листья sequence-number и hop-cnt, различные типы статистики сессии и сведения, относящиеся к проверке и трассировке пути. Модель данных проверки непрерывности сделана достаточно общей для использования различных методов извлечения данных и по этой причине ни одно поле не является обязательным. Набор методов извлечения задан в [RFC8533].

3.8. Иерархия данных OAM

Ниже приведена полная иерархия данных, связанных с моделью YANG OAM.

  module: ietf-connectionless-oam
      +--ro cc-session-statistics-data {continuity-check}?
         +--ro cc-session-statistics* [type]
            +--ro type                           identityref
            +--ro cc-ipv4-sessions-statistics
            |  +--ro cc-session-statistics
            |     +--ro session-count?              uint32
            |     +--ro session-up-count?           uint32
            |     +--ro session-down-count?         uint32
            |     +--ro session-admin-down-count?   uint32
            +--ro cc-ipv6-sessions-statistics
               +--ro cc-session-statistics
                  +--ro session-count?              uint32
                  +--ro session-up-count?           uint32
                  +--ro session-down-count?         uint32
                  +--ro session-admin-down-count?   uint32
    augment /nd:networks/nd:network/nd:node:
      +--rw tp-location-type?                identityref
      +--rw ipv4-location-type
      |  +--rw test-point-ipv4-location-list
      |     +--rw test-point-locations* [ipv4-location ni]
      |        +--rw ipv4-location          inet:ipv4-address
      |        +--rw ni                     routing-instance-ref
      |        +--rw (technology)?
      |        |  +--:(technology-null)
      |        |     +--rw tech-null?             empty
      |        +--rw tp-tools
      |        |  +--rw continuity-check    boolean
      |        |  +--rw path-discovery      boolean
      |        +--rw root?                  <anydata>
      |        +--rw oam-neighboring-tps* [index]
      |           +--rw index                    uint16
      |           +--rw position?                int8
      |           +--rw (tp-location)?
      |              +--:(mac-address)
      |              |  +--rw mac-address-location?    yang:mac-address
      |              +--:(ipv4-address)
      |              |  +--rw ipv4-address-location?   inet:ipv4-address
      |              +--:(ipv6-address)
      |              |  +--rw ipv6-address-location?   inet:ipv6-address
      |              +--:(as-number)
      |              |  +--rw as-number-location?      inet:as-number
      |              +--:(router-id)
      |                 +--rw router-id-location?      rt:router-id
      +--rw ipv6-location-type
      |  +--rw test-point-ipv6-location-list
      |     +--rw test-point-locations* [ipv6-location ni]
      |        +--rw ipv6-location          inet:ipv6-address
      |        +--rw ni                     routing-instance-ref
      |        +--rw (technology)?
      |        |  +--:(technology-null)
      |        |     +--rw tech-null?             empty
      |        +--rw tp-tools
      |        |  +--rw continuity-check    boolean
      |        |  +--rw path-discovery      boolean
      |        +--rw root?                  <anydata>
      |        +--rw oam-neighboring-tps* [index]
      |           +--rw index                    uint16
      |           +--rw position?                int8
      |           +--rw (tp-location)?
      |              +--:(mac-address)
      |              |  +--rw mac-address-location?    yang:mac-address
      |              +--:(ipv4-address)
      |              |  +--rw ipv4-address-location?   inet:ipv4-address
      |              +--:(ipv6-address)
      |              |  +--rw ipv6-address-location?   inet:ipv6-address
      |              +--:(as-number)
      |              |  +--rw as-number-location?      inet:as-number
      |              +--:(router-id)
      |                 +--rw router-id-location?      rt:router-id
      +--rw mac-location-type
      |  +--rw test-point-mac-address-location-list
      |     +--rw test-point-locations* [mac-address-location]
      |        +--rw mac-address-location    yang:mac-address
      |        +--rw (technology)?
      |        |  +--:(technology-null)
      |        |     +--rw tech-null?              empty
      |        +--rw tp-tools
      |        |  +--rw continuity-check    boolean
      |        |  +--rw path-discovery      boolean
      |        +--rw root?                   <anydata>
      |        +--rw oam-neighboring-tps* [index]
      |           +--rw index                    uint16
      |           +--rw position?                int8
      |           +--rw (tp-location)?
      |              +--:(mac-address)
      |              |  +--rw mac-address-location?    yang:mac-address
      |              +--:(ipv4-address)
      |              |  +--rw ipv4-address-location?   inet:ipv4-address
      |              +--:(ipv6-address)
      |              |  +--rw ipv6-address-location?   inet:ipv6-address
      |              +--:(as-number)
      |              |  +--rw as-number-location?      inet:as-number
      |              +--:(router-id)
      |                 +--rw router-id-location?      rt:router-id
      +--rw group-as-number-location-type
      |  +--rw test-point-as-number-location-list
      |     +--rw test-point-locations* [as-number-location]
      |        +--rw as-number-location     inet:as-number
      |        +--rw ni?                    routing-instance-ref
      |        +--rw (technology)?
      |        |  +--:(technology-null)
      |        |     +--rw tech-null?             empty
      |        +--rw tp-tools
      |        |  +--rw continuity-check    boolean
      |        |  +--rw path-discovery      boolean
      |        +--rw root?                  <anydata>
      |        +--rw oam-neighboring-tps* [index]
      |           +--rw index                    uint16
      |           +--rw position?                int8
      |           +--rw (tp-location)?
      |              +--:(mac-address)
      |              |  +--rw mac-address-location?    yang:mac-address
      |              +--:(ipv4-address)
      |              |  +--rw ipv4-address-location?   inet:ipv4-address
      |              +--:(ipv6-address)
      |              |  +--rw ipv6-address-location?   inet:ipv6-address
      |              +--:(as-number)
      |              |  +--rw as-number-location?      inet:as-number
      |              +--:(router-id)
      |                 +--rw router-id-location?      rt:router-id
      +--rw group-router-id-location-type
         +--rw test-point-system-info-location-list
            +--rw test-point-locations* [router-id-location]
               +--rw router-id-location     rt:router-id
               +--rw ni?                    routing-instance-ref
               +--rw (technology)?
               |  +--:(technology-null)
               |     +--rw tech-null?             empty
               +--rw tp-tools
               |  +--rw continuity-check    boolean
               |  +--rw path-discovery      boolean
               +--rw root?                  <anydata>
               +--rw oam-neighboring-tps* [index]
                  +--rw index                    uint16
                  +--rw position?                int8
                  +--rw (tp-location)?
                     +--:(mac-address)
                     |  +--rw mac-address-location?    yang:mac-address
                     +--:(ipv4-address)
                     |  +--rw ipv4-address-location?   inet:ipv4-address
                     +--:(ipv6-address)
                     |  +--rw ipv6-address-location?   inet:ipv6-address
                     +--:(as-number)
                     |  +--rw as-number-location?      inet:as-number
                     +--:(router-id)
                        +--rw router-id-location?      rt:router-id

4. Модуль YANG LIME Time Types

   <CODE BEGINS> file "ietf-lime-time-types@2019-04-16.yang"

   module ietf-lime-time-types {
     yang-version 1.1;
     namespace "urn:ietf:params:xml:ns:yang:ietf-lime-time-types";
     prefix lime;

     organization
       "IETF LIME Working Group";
     contact
       "WG Web:   <https://datatracker.ietf.org/wg/lime> 
        WG List:  <mailto:lmap@ietf.org> 

        Editor:   Qin Wu
                  <bill.wu@huawei.com>"; 
     description
       "Этот модуль содержит связанные с временем определения, 
        используемые моделями, написанными для среды LIME. Модуль
        задаёт идентификаторы, а не элементы дерева схемы.

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

        Распространение и использование модуля в исходном или двоичном
        формате, с изменениями или без таковых разрешено в соответствии 
        с условиями лицензии Simplified BSD License, изложенными в
        разделе 4.c документа IETF Trust's Legal Provisions для
        документов IETF (http://trustee.ietf.org/license-info). 

        Эта версия модуля YANG является частью RFC 8533, где правовые
        аспекты изложены более полно.";

     revision 2019-04-16 {
       description
         "Initial version.";
       reference
         "RFC 8532: Generic YANG Data Model for the Management of
          Operations, Administration, and Maintenance (OAM) Protocols
          That Use Connectionless Communications";
     }

     /*** Набор базовых типов, связанных со временем ***/
     /*** Идентификаторы единиц времени ***/

     identity time-unit-type {
       description
         "Тип единицы времени.";
     }

     identity hours {
       base time-unit-type;
       description
         "Время в часах.";
     }

     identity minutes {
       base time-unit-type;
       description
         "Время в минутах.";
     }

     identity seconds {
       base time-unit-type;
       description
         "Время в секундах.";
     }

     identity milliseconds {
       base time-unit-type;
       description
         "Время в миллисекундах.";
     }

     identity microseconds {
       base time-unit-type;
       description
         "Время в микросекундах.";
     }

     identity nanoseconds {
       base time-unit-type;
       description
         "Время в наносекундах.";
     }

     /*** Идентификаторы формата метки времени ***/

     identity timestamp-type {
       description
         "Базовый идентификатор для типов временных меток.";
     }

     identity truncated-ptp {
       base timestamp-type;
       description
         "64-битовая краткая метка PTP.";
     }

     identity truncated-ntp {
       base timestamp-type;
       description
         "32-битовая краткая метка NTP.";
     }

     identity ntp64 {
       base timestamp-type;
       description
         "64-битовая метка NTP.";
     }

     identity icmp {
       base timestamp-type;
       description
         "32-битовая метка ICMP.";
     }

     identity ptp80 {
       base timestamp-type;
       description
         "80-битовая метка PTP.";
     }
   }

   <CODE ENDS>

5. Модуль YANG для OAM без соединений

Этот модуль импортирует определение производных типов YANG (модуль ietf-yang-types) и определения связанных с Internet производных типов (модуль ietf-inet-types) из [RFC6991], модуль ietf-routing-types из [RFC8294], ietf-interfaces из [RFC8343], ietf-network из [RFC8345], ietf-network-instance из [RFC8529] и ietf-lime-time-types из раздела 4. Модуль ссылается на [IEEE.1588v1], [IEEE.1588v2], [RFC8029], и RFC, упомянутые в документе.

<CODE BEGINS> file "ietf-connectionless-oam@2019-04-16.yang"

module ietf-connectionless-oam {
  yang-version 1.1;
  namespace "urn:ietf:params:xml:ns:yang:ietf-connectionless-oam";
  prefix cl-oam;

  import ietf-yang-schema-mount {
    prefix yangmnt;
  }
  import ietf-network {
    prefix nd;
  }
  import ietf-yang-types {
    prefix yang;
  }
  import ietf-interfaces {
    prefix if;
  }
  import ietf-inet-types {
    prefix inet;
  }
  import ietf-network-instance {
    prefix ni;
  }
  import ietf-routing-types {
    prefix rt;
  }
  import ietf-lime-time-types {
    prefix lime;
  }

  organization
    "IETF LIME Working Group";
  contact
    "WG Web:   <https://datatracker.ietf.org/wg/lime> 
     WG List:  <mailto:lmap@ietf.org> 

     Deepak Kumar <dekumar@cisco.com> 
     Qin Wu <bill.wu@huawei.com> 
     Srihari Raghavan <srihari@cisco.com> 
     Michael Wang <wangzitao@huawei.com> 
     Reshad Rahman <rrahman@cisco.com>"; 
  description
    "Этот модуль YANG задаёт базовую конфигурацию, модель данных и
     статистику для протоколов OAM без явных соединений, описанные
     независимо от протокола. Предполагается, что каждый протокол
     отображает соответствующие абстракции в свой естественный формат.
     Протоколы могут расширять заданную здесь модель данных YANG для
     включения своих расширений.

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

     Распространение и использование модуля в исходном или двоичном
     формате, с изменениями или без таковых разрешено в соответствии 
     с условиями лицензии Simplified BSD License, изложенными в
     разделе 4.c документа IETF Trust's Legal Provisions применительно
     к документам IETF (http://trustee.ietf.org/license-info). 

     Эта версия модуля YANG является частью RFC 8532, где правовые
     аспекты изложены более полно.";

  revision 2019-04-16 {
    description
      "Базовая модель для OAM.";
    reference
      "RFC 8532: Generic YANG Data Model for the Management of
       Operations, Administration, and Maintenance (OAM) Protocols
       That Use Connectionless Communications";
  }

  feature connectionless {
    description
      "Указывает, что решение OAM работает без соединений.";
  }

  feature continuity-check {
    description
      "Указывает, что сервер поддерживает выполнение команды OAM
       Continuity Check и возвращает отклик. Серверы, не анонсирующие
       это свойство, не поддерживают выполнение Continuity Check и
       модель операции RPC для команд Continuity Check.";
  }

  feature path-discovery {
    description
      "Указывает, что сервер поддерживает выполнение команды OAM для
       поиска пути и возвращает отклик. Серверы, не анонсирующие это
       свойство, не поддерживают выполнение команд поиска пути и
       модель операции RPC для команд обнаружения пути.";
  }

  feature ptp-long-format {
    description
      "Указывает длинный формат временных меток PTP.";
  }

  feature ntp-short-format {
    description
      "Указывает короткий формат временных меток NTP.";
  }

  feature icmp-timestamp {
    description
      "Указывает формат временных меток ICMP.";
  }

  identity traffic-type {
    description
      "Базовый идентификатор типа трафика (IPv4, IPv6 и т. п.).";
  }

  identity ipv4 {
    base traffic-type;
    description
      "Идентификатор трафика IPv4.";
  }

  identity ipv6 {
    base traffic-type;
    description
      "Идентификатор трафика IPv6.";
  }

  identity address-attribute-types {
    description
      "Базовый идентификатор типа атрибута адреса - 
       Generic IPv4/IPv6 Prefix, BGP Labeled IPv4/IPv6 Prefix,
       Tunnel ID, PW ID, VPLS VE ID и т. п. (см. RFC 8029).";
  }

  typedef address-attribute-type {
    type identityref {
      base address-attribute-types;
    }
    description
      "Тип атрибута целевого адреса.";
  }

  typedef percentage {
    type decimal64 {
      fraction-digits 5;
      range "0..100";
    }
    description
      "Процент.";
  }

  typedef routing-instance-ref {
    type leafref {
      path "/ni:network-instances/ni:network-instance/ni:name";
    }
    description
      "Тип для листьев, указывающих конфигурацию экземпляра 
       маршрутизации.";
  }

  grouping cc-session-statistics {
    description
      "Группировка для статистики сессии.";
    container cc-session-statistics {
      description
        "CC session counters.";
      leaf session-count {
        type uint32;
        default "0";
        description
          "Число сессий Continuity Check. Значение 0 указывает, что
           счётчик сессий не передан.";
      }
      leaf session-up-count {
        type uint32;
        default "0";
        description
          "Число активных сессий. Значение 0 указывает, что
           счётчик сессий не передан.";
      }
      leaf session-down-count {
        type uint32;
        default "0";
        description
          "Число неактивных (down) сессий. Значение 0 указывает, что
           счётчик сессий не передан.";
      }
      leaf session-admin-down-count {
        type uint32;
        default "0";
        description
          "Число сессий, отключённых администратором (admin-down).
           Значение 0 указывает, что счётчик сессий не передан.";
      }
    }
  }

  grouping session-packet-statistics {
    description
      "Группировка для статистики по пакетам сессии.";
    container session-packet-statistics {
      description
        "Статистика по пакетам сессии.";
      leaf rx-packet-count {
        type uint32 {
          range "0..4294967295";
        }
        default "0";
        description
          "Общее число полученных пакетов OAM. Значение устанавливается
           в 0 при создании сессии и монотонно увеличивается до
           максимума 2^32-1 (4294967295), где оно снова переходит в 0.";
      }
      leaf tx-packet-count {
        type uint32 {
          range "0..4294967295";
        }
        default "0";
        description
          "Общее число переданных пакетов OAM. Значение устанавливается
           в 0 при создании сессии и монотонно увеличивается до
           максимума 2^32-1 (4294967295), где оно снова переходит в 0.";
      }
      leaf rx-bad-packet {
        type uint32 {
          range "0..4294967295";
        }
        default "0";
        description
          "Общее число полученных некорректных пакетов OAM. При создании
           сессии устанавливается 0, затем значение монотонно растёт до
           максимума 2^32-1 (4294967295), где оно снова переходит в 0.";
      }
      leaf tx-packet-failed {
        type uint32 {
          range "0..4294967295";
        }
        default "0";
        description
          "Общее число пакетов OAM, которые не удалось передать. При 
           создании сессии устанавливается 0, затем значение монотонно 
           растёт до 2^32-1 (4294967295), где оно снова переходит в 0.";
      }
    }
  }

  grouping cc-per-session-statistics {
    description
      "Группировка для статистики по сессиям.";
    container cc-per-session-statistics {
      description
        "Статистика на сессию.";
      leaf create-time {
        type yang:date-and-time;
        description
          "Дата и время создания сессии.";
      }
      leaf last-down-time {
        type yang:date-and-time;
        description
          "Дата и время последнего отключения (down) сессии.";
      }
      leaf last-up-time {
        type yang:date-and-time;
        description
          "Дата и время последней активации (up) сессии.";
      }
      leaf down-count {
        type uint32 {
          range "0..4294967295";
        }
        default "0";
        description
          "Общее число отключённых (down) сессий Continuity Check. При 
           создании устанавливается 0, затем значение монотонно 
           растёт до 2^32-1 (4294967295), где оно снова переходит в 0.";
      }
      leaf admin-down-count {
        type uint32 {
          range "0..4294967295";
        }
        default "0";
        description
          "Общее число сессий Continuity Check, отключённых 
           администратором (admin-down). При создании устанавливается 
           0, затем значение монотонно растёт до 2^32-1 (4294967295), 
           где оно снова переходит в 0.";
      }
      uses session-packet-statistics;
    }
  }

  grouping session-error-statistics {
    description
      "Группировка для статистики ошибок по сессиям.";
    container session-error-statistics {
      description
        "Статистика ошибок на сессию.";
      leaf packet-loss-count {
        type uint32 {
          range "0..4294967295";
        }
        default "0";
        description
          "Общее число отбрасываний принятых пакетов. При создании 
           сессии устанавливается 0, затем значение монотонно растёт до
           2^32-1 (4294967295), где оно снова переходит в 0.";
      }
      leaf loss-ratio {
        type percentage;
        description
          "Доля потерянных пакетов в процентах от числа переданных.";
      }
      leaf packet-reorder-count {
        type uint32 {
          range "0..4294967295";
        }
        default "0";
        description
          "Общее число переупорядочений пакетов. При создании сессии
           устанавливается 0, затем значение монотонно растёт до
           2^32-1 (4294967295), где оно снова переходит в 0.";
      }
      leaf packets-out-of-seq-count {
        type uint32 {
          range "0..4294967295";
        }
        description
          "Общее число пакетов принятых с нарушением порядка. При 
           создании сессии устанавливается 0, затем значение монотонно 
           растёт до 2^32-1 (4294967295) и снова переходит в 0.";
      }
      leaf packets-dup-count {
        type uint32 {
          range "0..4294967295";
        }
        description
          "Общее число принятых дубликатов пакетов. При создании 
           сессии устанавливается 0, затем значение монотонно 
           растёт до 2^32-1 (4294967295) и снова переходит в 0.";
      }
    }
  }

  grouping session-delay-statistics {
    description
      "Группировка для статистики задержек по сессиям.";
    container session-delay-statistics {
      description
        "Сводные сведения о задержках для сессии. По умолчанию для
         измерения применяется односторонний протокол (например, OWAMP).
         Если используется двухсторонний протокол (например, TWAMP), это
         указывается с помощью  protocol-id, заданного в операции RPC
         для метода извлечения в OAM без соединения (RFC 8533), т. е.
         устанавливается protocol-id как OWAMP. Отметим, что для 
         задержки задан лишь один протокол измерения из соображений
         функциональной совместимости.";
      leaf time-unit-value {
        type identityref {
          base lime:time-unit-type;
        }
        default "lime:milliseconds";
        description
          "Единица времени - s, ms, ns, и т. п.";
      }
      leaf min-delay-value {
        type uint32;
        description
          "Минимальная наблюдавшаяся задержка.";
      }
      leaf max-delay-value {
        type uint32;
        description
          "Максимальная наблюдавшаяся задержка.";
      }
      leaf average-delay-value {
        type uint32;
        description
          "Средняя задержка.";
      }
    }
  }

  grouping session-jitter-statistics {
    description
      "Группировка для статистики вариаций задержки по сессиям.";
    container session-jitter-statistics {
      description
        "Сводные сведения о вариациях задержки для сессии. По умолчанию 
         вариации измеряются с помощью IPDV в соответствии с RFC 3393.
         Если применяется иной метод (например, Packet Delay Variation
         из ITU-T Recommendation Y.1540), его можно указать с помощью
         protocol-id-meta-data о операции RPC методов извлечения для
         OAM без соединений (RFC 8533). Отметим, что для вариаций
         задержки задан лишь один протокол измерения из соображений
         функциональной совместимости.";
      leaf unit-value {
        type identityref {
          base lime:time-unit-type;
        }
        default "lime:milliseconds";
        description
          "Единица времени - s, ms, ns, и т. п.";
      }
      leaf min-jitter-value {
        type uint32;
        description
          "Минимальные наблюдавшиеся вариации задержки.";
      }
      leaf max-jitter-value {
        type uint32;
        description
          "Максимальные наблюдавшиеся вариации задержки.";
      }
      leaf average-jitter-value {
        type uint32;
        description
          "Средние вариации задержки.";
      }
    }
  }

  grouping session-path-verification-statistics {
    description
      "Группировка для статистики проверки пути на сессию.";
    container session-path-verification-statistics {
      description
        "Статистика проверки пути OAM на сессию.";
      leaf verified-count {
        type uint32 {
          range "0..4294967295";
        }
        description
          "Общее число пакетов, прошедших по предусмотренному пути. 
           Исходно устанавливается 0, затем значение монотонно растёт 
           до 2^32-1 (4294967295), где оно снова переходит в 0.";
      }
      leaf failed-count {
        type uint32 {
          range "0..4294967295";
        }
        description
          "Общее число пакетов, прошедших по непредусмотренному пути. 
           Исходно устанавливается 0, затем значение монотонно растёт 
           до 2^32-1 (4294967295), где оно снова переходит в 0.";
      }
    }
  }

  grouping session-type {
    description
      "Указывает тип активации при создании сессии.";
    leaf session-type {
      type enumeration {
        enum proactive {
          description
            "Текущая сессия является проактивной.";
        }
        enum on-demand {
          description
            "Текущая сессия создана по запросу.";
        }
      }
      default "on-demand";
      description
      "Указывает тип активации при создании сессии.";
    }
  }

  identity tp-address-technology-type {
    description
      "Тип адреса тестовой точки.";
  }

  identity mac-address-type {
    base tp-address-technology-type;
    description
      "Адрес типа MAC.";
  }

  identity ipv4-address-type {
    base tp-address-technology-type;
    description
      "Адрес типа IPv4.";
  }

  identity ipv6-address-type {
    base tp-address-technology-type;
    description
      "Адрес типа IPv6.";
  }

  identity tp-attribute-type {
    base tp-address-technology-type;
    description
      "Тип атрибута тестовой точки.";
  }

  identity router-id-address-type {
    base tp-address-technology-type;
    description
      "Тип адреса System ID.";
  }

  identity as-number-address-type {
    base tp-address-technology-type;
    description
      "Адрес типа номер AS.";
  }

  identity route-distinguisher-address-type {
    base tp-address-technology-type;
    description
      "Адрес типа Route Distinguisher.";
  }

  grouping tp-address {
    leaf tp-location-type {
      type identityref {
        base tp-address-technology-type;
      }
      mandatory true;
      description
        "Тип адреса тестовой точки.";
    }
    container mac-address {
      when "derived-from-or-self(../tp-location-type,"
         + "'cl-oam:mac-address-type')" {
        description
          "Адрес типа MAC.";
      }
      leaf mac-address {
        type yang:mac-address;
        mandatory true;
        description
          "MAC-адрес.";
      }
      description
        "Указание TP по MAC-адресу.";
    }
    container ipv4-address {
      when "derived-from-or-self(../tp-location-type,"
         + "'cl-oam:ipv4-address-type')" {
        description
          "Адрес типа IPv4.";
      }
      leaf ipv4-address {
        type inet:ipv4-address;
        mandatory true;
        description
          "Адрес IPv4.";
      }
      description
        "Указание TP по IP-адресу.";
    }
    container ipv6-address {
      when "derived-from-or-self(../tp-location-type,"
         + "'cl-oam:ipv6-address-type')" {
        description
          "Адрес типа IPv6.";
      }
      leaf ipv6-address {
        type inet:ipv6-address;
        mandatory true;
        description
          "Адрес IPv6.";
      }
      description
        "Указание TP по адресу IPv6.";
    }
    container tp-attribute {
      when "derived-from-or-self(../tp-location-type,"
         + "'cl-oam:tp-attribute-type')" {
        description
          "Тип атрибута тестовой точки.";
      }
      leaf tp-attribute-type {
        type address-attribute-type;
        description
          "Тип тестовой точки.";
      }
      choice tp-attribute-value {
        description
          "Значение тестовой точки.";
        case ip-prefix {
          leaf ip-prefix {
            type inet:ip-prefix;
            description
              "Базовый префикс IPv4/IPv6. См. параграфы 3.2.13 и
               3.2.14 в RFC 8029.";
            reference
              "RFC 8029: Detecting Multiprotocol Label
               Switched (MPLS) Data-Plane Failures";
          }
        }
        case bgp {
          leaf bgp {
            type inet:ip-prefix;
            description
              "Префикс IPv4/IPv6 с меткой BGP. См. параграфы
               3.2.11 и 3.2.12 в RFC 8029.";
            reference
              "RFC 8029: Detecting Multiprotocol Label
               Switched (MPLS) Data-Plane Failures";
          }
        }
        case tunnel {
          leaf tunnel-interface {
            type uint32;
            description
              "Базовый идентификатор туннеля IPv4/IPv6. См. 
               параграфы 3.2.3 и 3.2.4 в RFC 8029.";
            reference
              "RFC 8029: Detecting Multiprotocol Label
               Switched (MPLS) Data-Plane Failures.";
          }
        }
        case pw {
          leaf remote-pe-address {
            type inet:ip-address;
            description
              "Адрес удалённого PE. См. параграф 3.2.8 в RFC 8029.";
            reference
              "RFC 8029: Detecting Multiprotocol Label
               Switched (MPLS) Data-Plane Failures";
          }
          leaf pw-id {
            type uint32;
            description
              "Ненулевой 32-битовый Pseudowire ID. См. параграфы
               3.2.8 и 3.2.9 в RFC 8029.";
            reference
              "RFC 8029: Detecting Multiprotocol Label
               Switched (MPLS) Data-Plane Failures";
          }
        }
        case vpls {
          leaf route-distinguisher {
            type rt:route-distinguisher;
            description
              "Route Distinguisher - 8-октетный идентификатор,
               служащий для различения сведений о разных
               L2VPN, анонсируемых узлом.";
            reference
              "RFC 8029: Detecting Multiprotocol Label
               Switched (MPLS) Data-Plane Failures";
          }
          leaf sender-ve-id {
            type uint16;
            description
              "2-октетный идентификатор VE ID отправителя.";
            reference
              "RFC 8029: Detecting Multiprotocol Label
               Switched (MPLS) Data-Plane Failures";
          }
          leaf receiver-ve-id {
            type uint16;
            description
              "2-октетный идентификатор VE ID получателя.";
            reference
              "RFC 8029: Detecting Multiprotocol Label
               Switched (MPLS) Data-Plane Failures";
          }
        }
        case mpls-mldp {
          choice root-address {
            description
              "Выбор корневого адреса.";
            case ip-address {
              leaf source-address {
                type inet:ip-address;
                description
                  "Адрес IP.";
              }
              leaf group-ip-address {
                type inet:ip-address;
                description
                  "IP-адрес группы.";
              }
            }
            case vpn {
              leaf as-number {
                type inet:as-number;
                description
                  "Номер AS, указывающий автономную систему.";
              }
            }
            case global-id {
              leaf lsp-id {
                type string;
                description
                  "LSP ID - идентификатор LSP в сети MPLS.";
                reference
                  "RFC 8029: Detecting Multiprotocol Label
                   Switched (MPLS) Data-Plane Failures";
              }
            }
          }
        }
      }
      description
        "Контейнер атрибутов тестовой точки.";
    }
    container system-info {
      when "derived-from-or-self(../tp-location-type,"
         + "'cl-oam:router-id-address-type')" {
        description
          "Тип адреса System ID.";
      }
      leaf router-id {
        type rt:router-id;
        description
          "Router ID этого узла.";
      }
      description
        "Контейнер Router ID.";
    }
    description
      "Адрес TP.";
  }

  grouping tp-address-ni {
    description
      "Адрес тестовой точки с VRF.";
    leaf ni {
      type routing-instance-ref;
      description
        "Лист ni служит для описания разделения виртуальных ресурсов,
         которое может присутствовать в сетевом устройстве. Примером
         может служить широко используемый 'экземпляр VRF'.";
    }
    uses tp-address;
  }

  grouping connectionless-oam-tps {
    list oam-neighboring-tps {
      key "index";
      leaf index {
        type uint16 {
          range "0..65535";
        }
        description
          "Индекс списка соседних тестовых точек выше и ниже в стеке
           для интерфейса, связанного с текущей тестовой точкой.";
      }
      leaf position {
        type int8 {
          range "-1..1";
        }
        default "0";
        description
          "Положение соседней тестовой точки относительно текущей.
           Значение 0 указывает тестовую точку на том же уровне, что и
           текущая, -1 указывает точку ниже в стеке, +1 - точку выше.";
      }
      choice tp-location {
        case mac-address {
          leaf mac-address-location {
            type yang:mac-address;
            description
              "MAC-адрес.";
          }
          description
            "Указание TP по MAC-адресу.";
        }
        case ipv4-address {
          leaf ipv4-address-location {
            type inet:ipv4-address;
            description
              "Адрес IPv4.";
          }
          description
            "Указание TP по адресу IP.";
        }
        case ipv6-address {
          leaf ipv6-address-location {
            type inet:ipv6-address;
            description
              "Адрес IPv6.";
          }
          description
            "Указание TP по адресу IPv6.";
        }
        case as-number {
          leaf as-number-location {
            type inet:as-number;
            description
              "Местоположение по номеру AS.";
          }
          description
            "Номер AS для point-to-multipoint OAM.";
        }
        case router-id {
          leaf router-id-location {
            type rt:router-id;
            description
              "Местоположение по System ID.";
          }
          description
            "System ID.";
        }
        description
          "Местоположение TP.";
      }
      description
        "Список соседних тестовых точек на том же уровне, связанных с
         текущей тестовой точкой. Для соседней точки после текущей
         устанавливается позиция +1, для соседа перед текущей точкой - 
         -1, а при отсутствии соседних точек на этом уровне - 0.";
    }
    description
      "Список соседних тестовых точек для OAM без соединений.";
  }

  grouping tp-technology {
    choice technology {
      default "technology-null";
      case technology-null {
        description
          "Заглушка для случая, когда технология не нужна.";
        leaf tech-null {
          type empty;
          description
            "Технология не задана.";
        }
      }
      description
        "Выбор технологии.";
    }
    description
      "Технология OAM.";
  }

  grouping tp-tools {
    description
      "Инструменты OAM в тестовой точке.";
    container tp-tools {
      leaf continuity-check {
        type boolean;
        mandatory true;
        description
          "Флаг поддержки функции Continuity Check.";
        reference
          "RFC 792: INTERNET CONTROL MESSAGE PROTOCOL
           RFC 4443: Internet Control Message Protocol (ICMPv6)
               for the Internet Protocol Version 6 (IPv6) Specification
           RFC 5880: Bidirectional Forwarding Detection
           RFC 5881: BFD for IPv4 and IPv6
           RFC 5883: BFD for Multihop Paths
           RFC 5884: BFD for MPLS Label Switched Paths
           RFC 5885: BFD for PW VCCV
           RFC 6450: Multicast Ping Protocol
           RFC 8029: Detecting Multiprotocol Label Switched (MPLS)
               Data-Plane Failures";
      }
      leaf path-discovery {
        type boolean;
        mandatory true;
        description
          "Флаг поддержки функции обнаружения пути.";
        reference
          "RFC 792: INTERNET CONTROL MESSAGE PROTOCOL
           RFC 4443: Internet Control Message Protocol (ICMPv6)
               for the Internet Protocol Version 6 (IPv6) Specification
           RFC 4884: Extended ICMP to Support Multi-Part Messages
           RFC 5837: Extending ICMP for Interface and Next-Hop
               Identification
           RFC 8029: Detecting Multiprotocol Label Switched (MPLS)
               Data-Plane Failures";
      }
      description
        "Контейнер для инструментов OAM в тестовой точке.";
    }
  }

  grouping test-point-location-info {
    uses tp-technology;
    uses tp-tools;
    anydata root {
      yangmnt:mount-point "root";
      description
        "Корень для моделей, поддерживаемых на тестовую точку.";
    }
    uses connectionless-oam-tps;
    description
      "Местоположение тестовой точки.";
  }

  grouping test-point-locations {
    description
      "Группа местоположений тестовых точек.";
    leaf tp-location-type {
      type identityref {
        base tp-address-technology-type;
      }
      description
        "Тип местоположения тестовой точки.";
    }
    container ipv4-location-type {
      when "derived-from-or-self(../tp-location-type,"
         + "'cl-oam:ipv4-address-type')" {
        description
          "Тестовая точка указана адресом IPv4.";
      }
      container test-point-ipv4-location-list {
        list test-point-locations {
          key "ipv4-location ni";
          leaf ipv4-location {
            type inet:ipv4-address;
            description
              "Адрес IPv4.";
          }
          leaf ni {
            type routing-instance-ref;
            description
              "Лист ni служит для описания экземпляра сети.";
          }
          uses test-point-location-info;
          description
            "Список местоположений тестовых точек.";
        }
        description
          "Контейнер верхнего уровня для списка местоположений
           тестовых точек.";
      }
      description
        "Контейнер для местоположений по адресу IPv4.";
    }
    container ipv6-location-type {
      when "derived-from-or-self(../tp-location-type,"
         + "'cl-oam:ipv6-address-type')" {
        description
          "Тестовая точка указана адресом IPv6.";
      }
      container test-point-ipv6-location-list {
        list test-point-locations {
          key "ipv6-location ni";
          leaf ipv6-location {
            type inet:ipv6-address;
            description
              "Адрес IPv6.";
          }
          leaf ni {
            type routing-instance-ref;
            description
              "Лист ni служит для описания экземпляра сети.";
          }
          uses test-point-location-info;
          description
            "Список местоположений тестовых точек.";
        }
        description
          "Контейнер верхнего уровня для списка местоположений
           тестовых точек.";
      }
      description
        "Контейнер для местоположений по адресу IPv6.";
    }
    container mac-location-type {
      when "derived-from-or-self(../tp-location-type,"
         + "'cl-oam:mac-address-type')" {
        description
          "Тестовая точка указана адресом MAC.";
      }
      container test-point-mac-address-location-list {
        list test-point-locations {
          key "mac-address-location";
          leaf mac-address-location {
            type yang:mac-address;
            description
              "MAC-адрес.";
          }
          uses test-point-location-info;
          description
            "Список местоположений тестовых точек.";
        }
        description
          "Контейнер верхнего уровня для списка местоположений
           тестовых точек.";
      }
      description
        "Контейнер для местоположений по адресу MAC.";
    }
    container group-as-number-location-type {
      when "derived-from-or-self(../tp-location-type,"
         + "'cl-oam:as-number-address-type')" {
        description
          "Тестовая точка указана номером AS.";
      }
      container test-point-as-number-location-list {
        list test-point-locations {
          key "as-number-location";
          leaf as-number-location {
            type inet:as-number;
            description
              "Номер AS для point-to-multipoint OAM.";
          }
          leaf ni {
            type routing-instance-ref;
            description
              "Лист ni служит для описания экземпляра сети.";
          }
          uses test-point-location-info;
          description
            "Список местоположений тестовых точек.";
        }
        description
          "Контейнер верхнего уровня для списка местоположений
           тестовых точек.";
      }
      description
        "Контейнер для местоположений по номеру AS.";
    }
    container group-router-id-location-type {
      when "derived-from-or-self(../tp-location-type,"
         + "'cl-oam:router-id-address-type')" {
        description
          "Тестовая точка указана номером System ID.";
      }
      container test-point-system-info-location-list {
        list test-point-locations {
          key "router-id-location";
          leaf router-id-location {
            type rt:router-id;
            description
              "System ID.";
          }
          leaf ni {
            type routing-instance-ref;
            description
              "Лист ni служит для описания экземпляра сети.";
          }
          uses test-point-location-info;
          description
            "Список местоположений тестовых точек.";
        }
        description
          "Контейнер верхнего уровня для списка местоположений
           тестовых точек.";
      }
      description
        "Контейнер для местоположений по System ID.";
    }
  }

  augment "/nd:networks/nd:network/nd:node" {
    description
      "Дополняет путь /networks/network/node, заданный в модуле 
       ietf-network (RFC 8345), группировкой test-point-locations.";
    uses test-point-locations;
  }

  grouping timestamp {
    description
      "Группировка для временных меток.";
    leaf timestamp-type {
      type identityref {
        base lime:timestamp-type;
      }
      description
        "Тип временной метки, например, Truncated PTP или NTP.";
    }
    container timestamp-64bit {
      when "derived-from-or-self(../timestamp-type,"
         + "'lime:truncated-ptp')"
         + "or derived-from-or-self(../timestamp-type,"
         + "'lime:ntp64')" {
        description
          "Применяется лишь для усечённых меток PTP и 64-битовых NTP.";
      }
      leaf timestamp-sec {
        type uint32;
        description
          "Абсолютная метка в секундах в соответствии с IEEE 1588v2 или
           секунды из 64-битовой метки NTP.";
      }
      leaf timestamp-nanosec {
        type uint32;
        description
          "Дробная часть в наносекундах в соответствии с IEEE 1588v2 или
           дробная часть 64-битовой метки NTP.";
      }
      description
        "Контейнер для 64-битовой временной метки. Метки NTP заданы в
         RFC 5905, усечённые метки PTP - в IEEE 1588v1.";
      reference
        "RFC 5905: Network Time Protocol Version 4: Protocol and
             Algorithms Specification
         IEEE 1588v1: IEEE Standard for a Precision Clock
             Synchronization Protocol for Networked Measurement and
             Control Systems Version 1";
    }
    container timestamp-80bit {
      when "derived-from-or-self(../timestamp-type, 'lime:ptp80')" {
        description
          "Применяется лишь для 80-битовых меток PTP.";
      }
      if-feature "ptp-long-format";
      leaf timestamp-sec {
        type uint64 {
          range "0..281474976710655";
        }
        description
          "48-битовая метка в секундах в соответствии с IEEE 1588v2.";
      }
      leaf timestamp-nanosec {
        type uint32;
        description
          "Дробная часть в наносекундах в соответствии с IEEE 1588v2.";
      }
      description
        "Контейнер для 80-битовой метки времени.";
    }
    container ntp-timestamp-32bit {
      when "derived-from-or-self(../timestamp-type,"
         + "'lime:truncated-ntp')" {
        description
          "Применимо лишь к коротким 32-битовым меткам NTP.";
      }
      if-feature "ntp-short-format";
      leaf timestamp-sec {
        type uint16;
        description
          "Метка в секундах в коротком формате NTP.";
      }
      leaf timestamp-nanosec {
        type uint16;
        description
          "Дробная часть 16-битовой метки NTP.";
      }
      description
        "Контейнер для 32-битовой метки времени RFC 5905.";
      reference
        "RFC 5905: Network Time Protocol Version 4: Protocol and
         Algorithms Specification.";
    }
    container icmp-timestamp-32bit {
      when "derived-from-or-self(../timestamp-type, 'lime:icmp')" {
        description
          "Применимо лишь к меткам времени ICMP.";
      }
      if-feature "icmp-timestamp";
      leaf timestamp-millisec {
        type uint32;
        description
          "Миллисекунды метки времени ICMP.";
      }
      description
        "Контейнер для 32-битовой метки времени. Метки ICMP заданы в
         RFC 792.";
    }
  }

  grouping path-discovery-data {
    description
      "Вывод данных от узлов, связанных с обнаружением пути.";
    container src-test-point {
      description
        "Исходная тестовая точка.";
      uses tp-address-ni;
    }
    container dest-test-point {
      description
        "Целевая тестовая точка.";
      uses tp-address-ni;
    }
    leaf sequence-number {
      type uint64;
      default "0";
      description
        "Порядковый номер в пакете данных, 0 указывает, что номер
         не передаётся.";
    }
    leaf hop-cnt {
      type uint8;
      default "0";
      description
        "Число пересылок, 0 указывает, что это число не передаётся.";
    }
    uses session-packet-statistics;
    uses session-error-statistics;
    uses session-delay-statistics;
    uses session-jitter-statistics;
    container path-verification {
      description
        "Необязательные сведения, относящиеся к проверке пути.";
      leaf flow-info {
        type string;
        description
          "Сведения, укахывающие поток.";
      }
      uses session-path-verification-statistics;
    }
    container path-trace-info {
      description
        "Необязательные сведения поэтапной трассировки пути о тестовых
         точках. Обычно указывают 1 элемент на интервал (hop), такой как
         операцию RPC для обнаружения пути, но могут включаться и другие
         сведения от методов извлечения данных.";
      list path-trace-info-list {
        key "index";
        description
          "Список сведений трассировки пути.";
        leaf index {
          type uint32;
          description
            "Индекс сведений трассировки.";
        }
        uses tp-address-ni;
        uses timestamp;
        leaf ingress-intf-name {
          type if:interface-ref;
          description
            "Имя входного интерфейса.";
        }
        leaf egress-intf-name {
          type if:interface-ref;
          description
            "Имя выходного интерфейса.";
        }
        leaf queue-depth {
          type uint32;
          description
            "Длина очереди интерфейса, с которого пакет пересылается.
             Это может быть текущее число буферов памяти, использованных 
             очередью, а пакет может занимать 1 или несколько таких
             буферов.";
        }
        leaf transit-delay {
          type uint32;
          description
            "Время, затраченное пакетом на прохождение через узел.";
        }
        leaf app-meta-data {
          type uint64;
          description
            "Зависящие от приложения данные, добавленные узлом.";
        }
      }
    }
  }

  grouping continuity-check-data {
    description
      "Вывод данных Continuity Check от узлов.";
    container src-test-point {
      description
        "Исходная тестовая точка.";
      uses tp-address-ni;
      leaf egress-intf-name {
        type if:interface-ref;
        description
          "Имя выходного интерфейса.";
      }
    }
    container dest-test-point {
      description
        "Целевая тестовая точка.";
      uses tp-address-ni;
      leaf ingress-intf-name {
        type if:interface-ref;
        description
          "Имя входного интерфейса.";
      }
    }
    leaf sequence-number {
      type uint64;
      default "0";
      description
        "Порядковый номер в пакете данных, 0 указывает, что номер
         не передаётся.";
    }
    leaf hop-cnt {
      type uint8;
      default "0";
      description
        "Число пересылок, 0 указывает, что это число не передаётся.";
    }
    uses session-packet-statistics;
    uses session-error-statistics;
    uses session-delay-statistics;
    uses session-jitter-statistics;
  }

  container cc-session-statistics-data {
    if-feature "continuity-check";
    config false;
    list cc-session-statistics {
      key "type";
      leaf type {
        type identityref {
          base traffic-type;
        }
        description
          "Тип трафика.";
      }
      container cc-ipv4-sessions-statistics {
        when "../type = 'ipv4'" {
          description
            "Применимо только для трафика IPv4.";
        }
        description
          "CC ipv4 sessions.";
        uses cc-session-statistics;
      }
      container cc-ipv6-sessions-statistics {
        when "../type = 'ipv6'" {
          description
            "Применимо только для трафика IPv6.";
        }
        description
          "Сессии IPv6 CC.";
        uses cc-session-statistics;
      }
      description
        "Список статистических данных сессии CC.";
    }
    description
      "Рабочие сведения CC.";
  }
}

<CODE ENDS>

6. Применимость модели

Заданный в этом документе модуль ietf-connectionless-oam обеспечивает независимую от технологии абстракцию основных конструкций OAM для протоколов OAM без организации соединений. Этот модуль можно расширить включением связанных с технологией деталей, например, узлов данных с зависимыми от технологии функциями параметрами, помещённых в подходящие места базовой модели, чтобы создать связанную с технологией модель OAM без соединений.

В этом разделе показана применимость модели данных YANG OAM для разных технологий OAM без соединений, например, BFD и LSP ping. Отметим, что фрагменты кода расширений приведены здесь лишь для иллюстрации. Полными расширениями моделей следует заниматься рабочим группам соответствующих протоколов.

6.1. Расширение BFD

RFC 7276 определяет BFD как ориентированный на соединения протокол. Он применяется для мониторинга протоколов без организации соединений в случае базового BFD для IP.

6.1.1. Метод дополнения

В последующих параграфах показано, как расширить модуль ietf-connectionless-oam для охвата технологии BFD. Для этого вводится набор расширений, таких как тип технологии и атрибуты тестовой точки.

Отметим, что модель данных YANG BFD стандартизована в [BFD-YANG]. Дополнение модуля ietf-connectionless-oam связанными с BFD деталями обеспечивает дополнительный подход с унифицированным представлением управляющих сведений в разных протоколах OAM. Связанные с BFD детали могут быть группировкой в модели BFD, что позволит избежать дублирования работы.

6.1.1.1. Расширение technology-type

В модуле ietf-connectionless-oam не задан тип технологии BFD, поэтому нужно расширение модуля. Ниже приведён фрагмент кода, добавляющий тип bfd в модуль ietf-connectionless-oam.

   augment "/nd:networks/nd:network/nd:node/"
   +"coam:location-type/coam:ipv4-location-type"
   +"/coam:test-point-ipv4-location-list/"
   +"coam:test-point-locations/coam:technology"
   {
       leaf bfd{
      type string;
     }
   }
6.1.1.2. Расширение атрибутов тестовой точки

Для поддержки BFD модуль ietf-connectionless-oam можно расширить добавлением конкретных параметров в список test-point-locations и/или нового типа местоположения, такого как «BFD через MPLS TE» в узел выбора location-type.

6.1.1.2.1. Определение и вставка новых узлов в test-point-location

В модуле ietf-connectionless-oam задано несколько списков test-point-location в узле выбора location-type. Поэтому для вывода модели для неких технологий BFD (таких как IP single-hop, IP multihop и т. п.) нужно добавить узлы с конкретными данными BFD в соответствующий список test-point-locations. В этом параграфе используются некоторые группировки из [BFD-YANG]. Приведённый ниже код показывает, как можно расширить модуль ietf-connectionless-oam для поддержки BFD IP Single-Hop.

   augment "/nd:networks/nd:network/nd:node/"
   +"coam:location-type/coam:ipv4-location-type"
   +"/coam:test-point-ipv4-location-list/"
           +"coam:test-point-locations"
   {
           container session-cfg {
             description "Конфигурация сессии BFD IP single-hop.";
             list sessions {
               key "interface dest-addr";
               description "Список сессий IP single-hop";
               leaf interface {
                 type if:interface-ref;
                 description
                   "Интерфейс, на котором работает сессия BFD.";
               }
               leaf dest-addr {
                 type inet:ip-address;
                 description "IP-адрес партнёра";
               }
               uses bfd:bfd-grouping-common-cfg-parms;
               uses bfd:bfd-grouping-echo-cfg-parms;
             }
           }
   }

Похожие дополнения можно сделать для других технологий BFD, таких как BFD IP Multihop, BFD over MPLS и т. п.

6.1.1.2.2. Добавление вариантов location-type

Если в модуле ietf-connectionless-oam нет варианта location-type, подходящего для расширения, можно добавить новый вариант, поместив его в узел выбора location-type. Это обеспечивает гибкость и пользователь модуля может добавить location-type для поддержки других типов тестовых точек, отсутствующих в модуле ietf-connectionless-oam. В этом параграфе приведён пример добавления location-type для поддержки BFD over MPLS-TE с использованием группировок из модуля, заданного в [BFD-YANG].

   augment "/nd:networks/nd:network/nd:node/coam:location-type"{
    case te-location{
     list test-point-location-list{
      key "tunnel-name";
      leaf tunnel-name{
       type leafref{
    path "/te:te/te:tunnels/te:tunnel/te:name";
   }
   description
   "Указание экземпляра TE.";
      }
       uses bfd:bfd-grouping-common-cfg-parms;
           uses bfd-mpls:bfd-encap-cfg;
     }
    }
   }

Похожие дополнения возможны для поддержки других технологий BFD, таких как BFD через LAG и т. п.

6.1.2. Монтирование схемы

Ещё одним методом является использование механизма монтирования схемы из [RFC8528] в модуле ietf-connectionless-oam. В списке test-point-locations задаётся атрибут root, создающий точку монтирования для моделей, которые будут добавляться в test-point-locations. Таким способом модуль ietf-connectionless-oam может предоставить в иерархии узлов место, куда можно присоединить другие модели данных YANG OAM без специального расширения модуля YANG ietf-connectionless-oam. Отметим ограничение метода монтирования схемы, связанное с невозможностью указывать определённые модули, которые нужно примонтировать. Ниже приведён фрагмент кода с определением атрибута root.

         anydata root {
          yangmnt:mount-point root;
          description
            "Корень для моделей, поддерживаемых тестовой точкой.";
         }

В следующем параграфе показано, как модуль ietf-connectionless-oam может применять монтирование схемы для поддержки технологии BFD.

6.1.2.1. Модули BFD, заполняемые в примонтированных схемах

Для поддержки технологий BFD ietf-bfd-ip-sh и ietf-bfd-ip-mh модули YANG можно заполнить в контейнере schema-mounts.

      <schema-mounts
          xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-schema-mount">
        <mount-point>
          <module> ietf-connectionless-oam </module>
          <name>root</name>
          <use-schema>
            <name>root</name>
          </use-schema>
        </mount-point>
        <schema>
          <name>root</name>
          <module>
            <name>ietf-bfd-ip-sh </name>
            <revision>2016-07-04</revision>
            <namespace>
              urn:ietf:params:xml:ns:yang:ietf-bfd-ip-sh
            </namespace>
            <conformance-type>implement</conformance-type>
          </module>
          <module>
            <name>ietf-bfd-ip-mh</name>
            <revision> 2016-07-04</revision>
            <namespace>
              urn:ietf:params:xml:ns:yang:ietf-bfd-ip-mh
            </namespace>
            <conformance-type>implement</conformance-type>
          </module>
        </schema>
      </schema-mounts>

Модуль ietf-connectionless-oam может иметь вид

   <ietf-connectionless-oam
   uri="urn:ietf:params:xml:ns:yang:ietf-connectionless-oam">
      ...
    <test-point-locations>
     <ipv4-location>192.0.2.1</ipv4-location>
      ...
     <root>
      <ietf-bfd-ip-sh uri="urn:ietf:params:xml:ns:yang:ietf-bfd-ip-sh">
       <ip-sh>
        foo
        ...
       </ip-sh>
      </ietf-bfd-ip-sh>
      <ietf-bfd-ip-mh uri="urn:ietf:params:xml:ns:yang:ietf-bfd-ip-mh">
       <ip-mh>
        foo
        ...
       </ip-mh>
      </ietf-bfd-ip-mh>
     </root>
    </test-point-locations>
   </ietf-connectionless-oam>

6.2. Расширение LSP Ping

6.2.1. Метод дополнения

В следующих параграфах показано, как можно расширить модуль ietf-connectionless-oam для поддержки технологии LSP ping. Для этого задан набор расширений, таких как technology-type и attributes для тестовой точки.

Модель данных YANG LSP Ping задана в [LSP-PING-YANG]. Как и для BFD, можно дополнить модель ietf-connectionless-oam деталями, относящимися к LSP Ping для однородного представления разных технологий. Эти детали могут быть группировкой, заданной в модели LSP Ping, для предотвращение дублирования работы.

6.2.1.1. Расширение technology-type

Тип технологии LSP Ping не задан в модуле ietf-connectionless-oam, поэтому для него нужно расширение модуля. Ниже приведён фрагмент кода, добавляющий в ietf-connectionless-oam тип lsp-ping.

   augment "/nd:networks/nd:network/nd:node/"
   +"coam:location-type/coam:ipv4-location-type"
   +"/coam:test-point-ipv4-location-list/"
           +"coam:test-point-locations/coam:technology"
   {
      leaf lsp-ping{
      type string;
     }
   }
6.2.1.2. Расширение атрибутов тестовой точки

Для поддержки LSP Ping можно расширить модуль ietf-connectionless-oam, определив параметры, связанные с LSP Ping, и поместив их в список test-point-locations. Можно использовать атрибуты или группировки из [LSP-PING-YANG], как показано ниже. Приведённый фрагмент кода показывает дополнение списка test-point-locations атрибутами LSP Ping.

   augment "/nd:networks/nd:network/nd:node/"
   +"coam:location-type/coam:ipv4-location-type"
   +"/coam:test-point-ipv4-location-list/"
           +"coam:test-point-locations"
   {
   list lsp-ping {
            key "lsp-ping-name";
            leaf lsp-ping-name {
             type string {
               length "1..31";
            }
           mandatory "true";
           description "Имя теста LSP Ping.";
           ...
         }

6.2.2. Монтирование схемы

Ещё одним методом является использование механизма монтирования схемы из [RFC8528] в модуле ietf-connectionless-oam. В списке test-point-locations задаётся атрибут root, создающий точку монтирования для моделей, которые будут добавляться в test-point-locations. Таким способом модуль ietf-connectionless-oam может предоставить в иерархии узлов место, куда можно присоединить другие модели данных YANG OAM без специального расширения модуля YANG ietf-connectionless-oam. Отметим ограничение метода монтирования схемы, связанное с невозможностью указывать определённые модули, которые нужно примонтировать. Ниже приведён фрагмент кода с определением атрибута root.

         anydata root {
          yangmnt:mount-point root;
          description
         "Корень для моделей, поддерживаемых тестовой точкой.";
         }

В следующем параграфе показано, как модуль ietf-connectionless-oam может применять монтирование схемы для поддержки технологии LSP Ping.

6.2.2.1. Методы LSP Ping, заполняемые в примонтированных схемах

Для поддержки технологии LSP Ping модуль YANG ietf-lsp-ping [LSP-PING-YANG] можно заполнить в контейнере schema-mounts.

      <schema-mounts
          xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-schema-mount">
        <mount-point>
          <module> ietf-connectionless-oam </module>
          <name>root</name>
          <use-schema>
            <name>root</name>
          </use-schema>
        </mount-point>
        <schema>
          <name>root</name>
          <module>
            <name>ietf-lsp-ping </name>
            <revision>2016-03-18</revision>
            <namespace>
              urn:ietf:params:xml:ns:yang: ietf-lsp-ping
            </namespace>
            <conformance-type>implement</conformance-type>
          </module>
        </schema>
      </schema-mounts>

Модуль ietf-connectionless-oam может иметь вид

   <ietf-connectionless-oam
   uri="urn:ietf:params:xml:ns:yang:ietf-connectionless-oam">
      ...
    <test-point-locations>
     <ipv4-location> 192.0.2.1</ipv4-location>
      ...
     <root>
      <ietf-lsp-ping uri="urn:ietf:params:xml:ns:yang:ietf-lsp-ping">
       <lsp-pings>
        foo
        ...
       </lsp-pings>
      </ietf-lsp-ping>
     </root>
    </test-point-locations>
   </ietf-connectionless-oam>

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

Описанный здесь модуль YANG определяет схему для данных, которые предназначены для доступа с помощью протоколов сетевого управления, таких как NETCONF [RFC6241] или RESTCONF [RFC8040]. Нижним уровнем NETCONF является защищённый транспорт с обязательной поддержкой протокола SSH5 [RFC6242]. Нижним уровнем RESTCONF служит HTTPS с обязательной поддержкой протокола TLS [RFC8446].

Модель управления доступом к конфигурации сети [RFC8341] обеспечивает способы ограничить доступ определенных пользователей NETCONF или RESTCONF предопределенным подмножеством операций и содержимого NETCONF или RESTCONF.

Множество узлов данных в модуле YANG доступны для чтения, создания и удаления (значение config true, принятое по умолчанию). Эти узлы могут считаться деликатными в некоторых сетевых средах. Запись в такие узлы (например, edit-config) без соответствующей защиты может оказывать негативное влияние на работу сети. К таким узлам и ветвям относятся:

/nd:networks/nd:network/nd:node/cl-oam:location-type/cl-oam:ipv4-location-type/cl-oam:test-point-ipv4-location-list/cl-oam:test-point-locations/
/nd:networks/nd:network/nd:node/cl-oam:location-type/cl-oam:ipv6-location-type/cl-oam:test-point-ipv6-location-list/cl-oam:test-point-locations/
/nd:networks/nd:network/nd:node/cl-oam:location-type/cl-oam:mac-location-type/cl-oam:test-point-mac-address-location-list/cl-oam:test-point-locations/
/nd:networks/nd:network/nd:node/cl-oam:location-type/cl-oam:group-as-number-location-type/cl-oam:test-point-as-number-location-list/cl-oam:test-point-locations/
/nd:networks/nd:network/nd:node/cl-oam:location-type/cl-oam:group-router-id-location-type/cl-oam:test-point-system-info-location-list/cl-oam:test-point-locations/

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

Некоторые из доступных для чтения узлов в этом модуле YANG могут быть конфиденциальны или уязвимы в той или иной сетевой среде. Важно контролировать доступ к таким объектам (например, get, get-config, notification). Ниже перечислены ветви и узлы, которые могут быть конфиденциальны или уязвимы.

/coam:cc-session-statistics-data/cl-oam:cc-ipv4-sessions-statistics/cl-oam:cc-session-statistics/cl-oam:session-count/
/coam:cc-session-statistics-data/cl-oam:cc-ipv4-sessions-statistics/cl-oam:cc-session-statistics/cl-oam:session-up-count/
/coam:cc-session-statistics-data/cl-oam:cc-ipv4-sessions-statistics/cl-oam:cc-session-statistics/cl-oam:session-down-count/
/coam:cc-session-statistics-data/cl-oam:cc-ipv4-sessions-statistics/cl-oam:cc-session-statistics/cl-oam:session-admin-down-count/
/coam:cc-session-statistics-data/cl-oam:cc-ipv6-sessions-statistics/cl-oam:cc-session-statistics/cl-oam:session-count/
/coam:cc-session-statistics-data/cl-oam:cc-ipv6-sessions-statistics/cl-oam:cc-session-statistics/cl-oam:session-up-count/
/coam:cc-session-statistics-data/cl-oam:cc-ipv6-sessions-statistics/cl-oam:cc-session-statistics/cl-oam:session-down-count//coam:cc-session-statistics-data/cl-oam:cc-ipv6-sessions-statistics/cl-oam:cc-session-statistics/cl-oam:session-admin-down-count/

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

Этот документ регистрирует URI в реестре IETF XML Registry [RFC3688]

      URI: urn:ietf:params:xml:ns:yang:ietf-lime-time-types
      Registrant Contact: The IESG.
      XML: N/A; запрошенный URI является пространством имён XML.

      URI: urn:ietf:params:xml:ns:yang:ietf-connectionless-oam
      Registrant Contact: The IESG.
      XML: N/A; запрошенный URI является пространством имён XML.

Этот документ регистрирует два модуля YANG в реестре YANG Module Names [RFC6020].

      Name: ietf-lime-time-types
      Namespace: urn:ietf:params:xml:ns:yang:ietf-lime-time-types
      Prefix: lime
      Reference: RFC 8532

      Name: ietf-connectionless-oam
      Namespace: urn:ietf:params:xml:ns:yang:ietf-connectionless-oam
      Prefix: cl-oam
      Reference: RFC 8532

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

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

[RFC792] Postel, J., «Internet Control Message Protocol», RFC 792, September 1981.

[RFC1831] Srinivasan, R., «RPC: Remote Procedure Call Protocol Specification Version 2», RFC 1831, DOI 10.17487/RFC1831, August 1995, <https://www.rfc-editor.org/info/rfc1831>.

[RFC3688] Mealling, M., «The IETF XML Registry», BCP 81, RFC 3688, DOI 10.17487/RFC3688, January 2004, <https://www.rfc-editor.org/info/rfc3688>.

[RFC4382] Nadeau, T., Ed. and H. van der Linde, Ed., «MPLS/BGP Layer 3 Virtual Private Network (VPN) Management Information Base», RFC 4382, DOI 10.17487/RFC4382, February 2006, <https://www.rfc-editor.org/info/rfc4382>.

[RFC4443] Conta, A., Deering, S., and M. Gupta, Ed., «Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification», STD 89, RFC 4443, DOI 10.17487/RFC4443, March 2006, <https://www.rfc-editor.org/info/rfc4443>.

[RFC4656] Shalunov, S., Teitelbaum, B., Karp, A., Boote, J., and M. Zekauskas, «A One-way Active Measurement Protocol (OWAMP)», RFC 4656, DOI 10.17487/RFC4656, September 2006, <https://www.rfc-editor.org/info/rfc4656>.

[RFC5357] Hedayat, K., Krzanowski, R., Morton, A., Yum, K., and J. Babiarz, «A Two-Way Active Measurement Protocol (TWAMP)», RFC 5357, DOI 10.17487/RFC5357, October 2008, <https://www.rfc-editor.org/info/rfc5357>.

[RFC5880] Katz, D. and D. Ward, «Bidirectional Forwarding Detection (BFD)», RFC 5880, DOI 10.17487/RFC5880, June 2010, <https://www.rfc-editor.org/info/rfc5880>.

[RFC5905] Mills, D., Martin, J., Ed., Burbank, J., and W. Kasch, «Network Time Protocol Version 4: Protocol and Algorithms Specification», RFC 5905, DOI 10.17487/RFC5905, June 2010, <https://www.rfc-editor.org/info/rfc5905>.

[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., «Network Configuration Protocol (NETCONF)», RFC 6241, DOI 10.17487/RFC6241, June 2011, <https://www.rfc-editor.org/info/rfc6241>.

[RFC6242] Wasserman, M., «Using the NETCONF Protocol over Secure Shell (SSH)», RFC 6242, DOI 10.17487/RFC6242, June 2011, <https://www.rfc-editor.org/info/rfc6242>.

[RFC6991] Schoenwaelder, J., Ed., «Common YANG Data Types», RFC 6991, DOI 10.17487/RFC6991, July 2013, <https://www.rfc-editor.org/info/rfc6991>.

[RFC7950] Bjorklund, M., Ed., «The YANG 1.1 Data Modeling Language», RFC 7950, DOI 10.17487/RFC7950, August 2016, <https://www.rfc-editor.org/info/rfc7950>.

[RFC8029] Kompella, K., Swallow, G., Pignataro, C., Ed., Kumar, N., Aldrin, S., and M. Chen, «Detecting Multiprotocol Label Switched (MPLS) Data-Plane Failures», RFC 8029, DOI 10.17487/RFC8029, March 2017, <https://www.rfc-editor.org/info/rfc8029>.

[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, «RESTCONF Protocol», RFC 8040, DOI 10.17487/RFC8040, January 2017, <https://www.rfc-editor.org/info/rfc8040>.

[RFC8294] Liu, X., Qu, Y., Lindem, A., Hopps, C., and L. Berger, «Common YANG Data Types for the Routing Area», RFC 8294, DOI 10.17487/RFC8294, December 2017, <https://www.rfc-editor.org/info/rfc8294>.

[RFC8341] Bierman, A. and M. Bjorklund, «Network Configuration Access Control Model», STD 91, RFC 8341, DOI 10.17487/RFC8341, March 2018, <https://www.rfc-editor.org/info/rfc8341>.

[RFC8343] Bjorklund, M., «A YANG Data Model for Interface Management», RFC 8343, DOI 10.17487/RFC8343, March 2018, <https://www.rfc-editor.org/info/rfc8343>.

[RFC8345] Clemm, A., Medved, J., Varga, R., Bahadur, N., Ananthakrishnan, H., and X. Liu, «A YANG Data Model for Network Topologies», RFC 8345, DOI 10.17487/RFC8345, March 2018, <https://www.rfc-editor.org/info/rfc8345>.

[RFC8446] Rescorla, E., «The Transport Layer Security (TLS) Protocol Version 1.3», RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.

[RFC8529] Berger, L., Hopps, C., Lindem, A., Bogdanovic, D., and X. Liu, «YANG Model for Network Instances», RFC 8529, DOI 10.17487/RFC8529, March 2019, <https://www.rfc-editor.org/info/rfc8529>.

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

[BFD-YANG] Rahman, R., Zheng, L., Jethanandani, M., Networks, J., and G. Mirsky, «YANG Data Model for Bidirectional Forwarding Detection (BFD)», Work in Progress6, draft-ietf-bfd-yang-17, August 2018.

[G.800] «Unified functional architecture of transport networks», ITU-T Recommendation G.800, 2016.

[G.8013] «OAM functions and mechanisms for Ethernet based networks», ITU-T Recommendation G.8013/Y.1731, 2013.

[IEEE.1588v1] «IEEE Standard for a Precision Clock Synchronization Protocol for Networked Measurement and Control Systems Version 1», IEEE Std 1588, 2002.

[IEEE.1588v2] «IEEE Standard for a Precision Clock Synchronization Protocol for Networked Measurement and Control Systems Version 2», IEEE Std 1588, 2008.

[LSP-PING-YANG] Zheng, L., Zheng, G., Mirsky, G., Rahman, R., and F. Iqbal, «YANG Data Model for LSP-Ping», Work in Progress, draft-zheng-mpls-lsp-ping-yang-cfg-10, January 2019.

[RFC5462] Andersson, L. and R. Asati, «Multiprotocol Label Switching (MPLS) Label Stack Entry: «EXP» Field Renamed to «Traffic Class» Field», RFC 5462, DOI 10.17487/RFC5462, February 2009, <https://www.rfc-editor.org/info/rfc5462>.

[RFC6020] Bjorklund, M., Ed., «YANG — A Data Modeling Language for the Network Configuration Protocol (NETCONF)», RFC 6020, DOI 10.17487/RFC6020, October 2010, <https://www.rfc-editor.org/info/rfc6020>.

[RFC6136] Sajassi, A., Ed. and D. Mohan, Ed., «Layer 2 Virtual Private Network (L2VPN) Operations, Administration, and Maintenance (OAM) Requirements and Framework», RFC 6136, DOI 10.17487/RFC6136, March 2011, <https://www.rfc-editor.org/info/rfc6136>.

[RFC7276] Mizrahi, T., Sprecher, N., Bellagamba, E., and Y. Weingarten, «An Overview of Operations, Administration, and Maintenance (OAM) Tools», RFC 7276, DOI 10.17487/RFC7276, June 2014, <https://www.rfc-editor.org/info/rfc7276>.

[RFC8340] Bjorklund, M. and L. Berger, Ed., «YANG Tree Diagrams», BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, <https://www.rfc-editor.org/info/rfc8340>.

[RFC8528] Bjorklund, M. and L. Lhotka, «YANG Schema Mount», RFC 8528, DOI 10.17487/RFC8528, March 2019, <https://www.rfc-editor.org/info/rfc8528>.

[RFC8531] Kumar, D., Wu, Q., and M. Wang, «Generic YANG Data Model for Connection-Oriented Operations, Administration, and Maintenance (OAM) Protocols», RFC 8531, DOI 10.17487/RFC8531, April 2019, <https://www.rfc-editor.org/info/rfc8531>.

[RFC8533] Kumar, D., Wang, M., Wu, Q., Ed., Rahman, R., and S. Raghavan, » A YANG Data Model for Retrieval Methods for the Management of Operations, Administration, and Maintenance (OAM) Protocols That Use Connectionless Communications», RFC 8533, DOI 10.17487/RFC8533, April 2019.

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

Авторы документа благодарны Elwyn Davies, Alia Atlas, Brian E. Carpenter, Greg Mirsky, Adam Roach, Alissa Cooper, Eric Rescorla, Ben Campbell, Benoit Claise, Kathleen Moriarty, Carlos Pignataro и другим людям за их предметные рецензии и комментарии, а также предложения по стабилизации и улучшению этого документа.

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

Deepak Kumar
CISCO Systems
510 McCarthy Blvd
Milpitas, CA 95035
United States of America
Email: dekumar@cisco.com
 
Michael Wang
Huawei Technologies, Co., Ltd
101 Software Avenue, Yuhua District
Nanjing 210012
China
Email: wangzitao@huawei.com
 
Qin Wu (editor)
Huawei
101 Software Avenue, Yuhua District
Nanjing, Jiangsu 210012
China
Email: bill.wu@huawei.com
 
Reshad Rahman
Cisco Systems
2000 Innovation Drive
Kanata, Ontario K2K 3E8
Canada
Email: rrahman@cisco.com
 
Srihari Raghavan
Cisco Systems
Tril Infopark Sez, Ramanujan IT City
Neville Block, 2nd floor, Old Mahabalipuram Road
Chennai, Tamil Nadu 600113
India
Email: srihari@cisco.com

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

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

nmalykh@protokols.ru


1Operations, Administration, and Maintenance — эксплуатация, администрирование, обслуживание.

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

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

4Layer Independent OAM Management in the Multi-Layer Environment — независимое от уровня управление OAM в многоуровневой среде.

5Secure Shell — защищенная оболочка.

6Опубликовано в RFC 9314. Прим. перев.

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

RFC 8533 A YANG Data Model for Retrieval Methods for the Management of Operations, Administration, and Maintenance (OAM) Protocols That Use Connectionless Communications

Internet Engineering Task Force (IETF)                          D. Kumar
Request for Comments: 8533                                         Cisco
Category: Standards Track                                        M. Wang
ISSN: 2070-1721                                               Q. Wu, Ed.
                                                                  Huawei
                                                               R. Rahman
                                                             S. Raghavan
                                                                   Cisco
                                                              April 2019

A YANG Data Model for Retrieval Methods for the Management of Operations, Administration, and Maintenance (OAM) Protocols That Use Connectionless Communications

Модель данных YANG для методов извлечения в протоколах OAM без использования соединений

PDF

Аннотация

В этом документе представлена модель данных YANG для метода извлечения в протоколах OAM1 без организации явных соединений. Модель обеспечивает независимые от протокола операции RPC для протоколов OAM, использующих обмен данными без организации соединений. Представленную здесь модель методов извлечения можно расширить для включения зависящих от технологии деталей. Такой подход обеспечивает два важных преимущества — во-первых, единообразие для разных протоколов OAM, во-вторых, поддержка как вложенных рабочих процессов OAM (т. е. выполнение функций OAM на одном или разных уровнях через один унифицированный интерфейс), так и интерактивных процессов OAM (т. е. выполнение функций OAM на одном уровне через унифицированный интерфейс).

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

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

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

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

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

Copyright (c) 2019. Авторские права принадлежат 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).

1. Введение

Функции OAM важны для сети и позволяют операторам:

  1. отслеживать сетевые коммуникации (т. е. проверка доступности и непрерывности работы);

  2. находить и устранять неполадки;

  3. отслеживать соглашения о уровне обслуживания и производительность (управление производительностью).

Обзор инструментов OAM представлен в [RFC7276].

Утилиты Ping и Traceroute [RFC4443], а также обнаружение двухсторонней пересылки (Bidirectional Forwarding Detection или BFD) [RFC5880] являются общеизвестными инструментами проверки и отыскания точки отказа, особенно в сетях IP [RFC792]. За прошедшие годы в разных технологиях были разработаны похожие наборы для решения таких же задач.

В этом документе представлена модель данных YANG для извлечения по запросам сведений для протоколов OAM без организации соединений. Модель обеспечивает независимые от протоколов операции RPC для протоколов OAM, которые не используют явных соединений (connectionless OAM). Это отделено от базовой модели данных YANG для OAM без организации соединений [RFC8532] и позволяет не смешивать модели при извлечении данных. Предполагается, что процедуры извлечения будут развиваться быстрее, чем модель данных [RFC8532] и такой подход позволит определять новые процедуры для извлечения тех же данных, которые определены в базовой модели данных YANG для OAM без организации соединений.

2. Используемые соглашения

Ниже указаны используемые в этом документе термины, которые определены в [RFC6241].

  • client — клиент;
  • configuration data — данные конфигурации;
  • server — сервер;
  • state data — данные состояния.

Ниже указаны используемые в этом документе термины, которые определены в [RFC6020].

  • augment — дополнение;
  • data model — модель данных;
  • data node — узел данных.

Термины для описания моделей данных YANG представлены в [RFC6020].

2.1. Термины

TP — Test Point — точка тестирования.

MAC — Media Access Control — управление доступом к среде.

RPC — Remote Procedure Call — удалённый вызов процедуры.

RPC Operation — конкретный вызов RPC.

2.2. Диаграммы деревьев

Диаграмма дерева данных в этом документе использует нотацию [RFC8340].

3. Обзор модели методов извлечения данных OAM без соединений

Этот документ описывает модель данных YANG для извлечения сведений по запросу в протоколах OAM без организации соединений. Модель описывает независимые от протокола процедуры извлечения (операции RPC) для протоколов OAM без соединений. Это обеспечивает гибкое извлечение данных, определённых в модуле ietf-connectionless-oam.yang [RFC8532].

3.1. Определения операций RPC

Модель RPC упрощает отправку команд серверу протокола управления сетью (Network Configuration Protocol или NETCONF), которым в данном случае является устройство, где нужно выполнить команду OAM и получить отклик.

В модуле connectionless-oam-methods обобщены базовые функции OAM и определены две базовых операции RPC — continuity-check и path-discovery. На практике эти операции RPC активируются по запросу и поддерживаются соответствующими инструментами OAM для конкретной технологии [RFC7276]. Например, для модели IP OAM вызов Continuity Check RPC соответствует IP Ping [RFC792] [RFC4443], а операция обнаружения пути — IP Traceroute [RFC792] [RFC4443].

Отметим, что представленная в документе операция RPC является основой для вывода моделей для зависящих от технологии OAM (т. е. ICMP Ping [RFC792] [RFC4443] и LSP Ping [RFC8029]). Эту основу следует расширять специфичными для технологии параметрами. Для упрощения этого в будущих расширениях методов извлечения данных, RPC собраны в отдельный модуль.

Базовая группировка tp-address применяется как ввод данных из различных RPC, описанных в документе. Базовые группировки path-discovery-data и continuity-check-data, заданные в модуле ietf-connectionless-oam.yang [RFC8532], применяются как вывод данных из различных RPC, описанных в документе. Аналогичные методы, включая другие RPC, могут извлекать данные с использованием той же модели (т. е. модуля ietf-connectionless-oam.yang). Ниже представлен фрагмент кода для операций RPC.

        rpc continuity-check {
         if-feature cl-oam:continuity-check;
         description
           "Continuity Check RPC в соответствии с RFC 7276.";
         reference
           "RFC 7276: An Overview of Operations, Administration, and
            Maintenance (OAM) Tools";
         input {
         uses rpc-input-parameters;
         ....
         }
       output {
         container response-info {
           leaf protocol-id {
             type identityref {
               base protocol-id;
             }
             mandatory true;
             description
               "Протокол, применяемый в Continuity Check. ";
           }
           leaf protocol-id-meta-data {
              type identityref {
               base protocol-id-meta-data;
               }
                description
                "Необязательные метаданные, относящиеся к protocol ID.";
           }
           leaf status-code {
             type identityref{
            base status-code;
          }
             mandatory true;
             description
               "Код статуса для операции Continuity Check RPC.";
           }
           leaf status-sub-code {
             type identityref{
             base status-sub-code;
          }
             mandatory true;
             description
               "Субкод статуса для операции Continuity Check RPC.";
           }
           description
             "Код и субкод статуса для операции Continuity Check RPC.";
         }
         uses cl-oam:continuity-check-data;
       }
     }

       rpc path-discovery {
         description
           "RPC обнаружения пути в соответствии с RFC 7276.";
         reference
           "RFC 7276: An Overview of Operations, Administration, and
            Maintenance (OAM) Tools";
         input {
         uses rpc-input-parameters;
         .....
         }
       output {
         list response-list {
           key "response-index";
           description
             "Список откликов при обнаружении путей.";
           leaf response-index {
             type uint32;
             mandatory true;
             description
               "Индекс отклика.";
           }
           leaf protocol-id {
             type identityref {
               base protocol-id;
             }
             mandatory true;
             description
               "Протокол, применяемый для обнаружения пути. ";
           }
           leaf protocol-id-meta-data {
              type identityref {
               base protocol-id-meta-data;
               }
                description
                "Необязательные метаданные, относящиеся к protocol ID.";
           }
           leaf status-code {
             type identityref{
             base status-code;
           }
             mandatory true;
             description
               "Код состояния для RPC обнаружения пути. ";
           }
           leaf status-sub-code {
             type identityref{
             base status-sub-code;
          }
             mandatory true;
             description
               "Субкод состояния для RPC обнаружения пути . ";
           }
         }
         uses cl-oam:path-discovery-data;
       }
     }

3.2. Иерархия методов извлечений OAM

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

   module: ietf-connectionless-oam-methods

     rpcs:
       +---x continuity-check {cl-oam:continuity-check}?
       |  +---w input
       |  |  +---w destination-tp
       |  |  |  +---w tp-location-type    identityref
       |  |  |  +---w mac-address
       |  |  |  |  +---w mac-address    yang:mac-address
       |  |  |  +---w ipv4-address
       |  |  |  |  +---w ipv4-address    inet:ipv4-address
       |  |  |  +---w ipv6-address
       |  |  |  |  +---w ipv6-address    inet:ipv6-address
       |  |  |  +---w tp-attribute
       |  |  |  |  +---w tp-attribute-type?
       |  |  |  |  |       address-attribute-type
       |  |  |  |  +---w (tp-attribute-value)?
       |  |  |  |     +--:(ip-prefix)
       |  |  |  |     |  +---w ip-prefix?
       |  |  |  |     |          inet:ip-prefix
       |  |  |  |     +--:(bgp)
       |  |  |  |     |  +---w bgp?
       |  |  |  |     |          inet:ip-prefix
       |  |  |  |     +--:(tunnel)
       |  |  |  |     |  +---w tunnel-interface?         uint32
       |  |  |  |     +--:(pw)
       |  |  |  |     |  +---w remote-pe-address?
       |  |  |  |     |  |       inet:ip-address
       |  |  |  |     |  +---w pw-id?                    uint32
       |  |  |  |     +--:(vpls)
       |  |  |  |     |  +---w route-distinguisher?
       |  |  |  |     |  |       rt:route-distinguisher
       |  |  |  |     |  +---w sender-ve-id?             uint16
       |  |  |  |     |  +---w receiver-ve-id?           uint16
       |  |  |  |     +--:(mpls-mldp)
       |  |  |  |        +---w (root-address)?
       |  |  |  |           +--:(ip-address)
       |  |  |  |           |  +---w source-address?
       |  |  |  |           |  |       inet:ip-address
       |  |  |  |           |  +---w group-ip-address?
       |  |  |  |           |          inet:ip-address
       |  |  |  |           +--:(vpn)
       |  |  |  |           |  +---w as-number?
       |  |  |  |           |          inet:as-number
       |  |  |  |           +--:(global-id)
       |  |  |  |              +---w lsp-id?             string
       |  |  |  +---w system-info
       |  |  |     +---w router-id?   rt:router-id
       |  |  +---w source-interface      if:interface-ref
       |  |  +---w outbound-interface    if:interface-ref
       |  |  +---w vrf?
       |  |  |       cl-oam:routing-instance-ref
       |  |  +---w session-type?         enumeration
       |  |  +---w count?                uint32
       |  |  +---w ttl?                  uint8
       |  |  +---w packet-size?          uint32
       |  +--ro output
       |     +--ro response-info
       |     |  +--ro protocol-id              identityref
       |     |  +--ro protocol-id-meta-data?   identityref
       |     |  +--ro status-code              identityref
       |     |  +--ro status-sub-code          identityref
       |     +--ro src-test-point
       |     |  +--ro ni?                 routing-instance-ref
       |     |  +--ro tp-location-type    identityref
       |     |  +--ro mac-address
       |     |  |  +--ro mac-address    yang:mac-address
       |     |  +--ro ipv4-address
       |     |  |  +--ro ipv4-address    inet:ipv4-address
       |     |  +--ro ipv6-address
       |     |  |  +--ro ipv6-address    inet:ipv6-address
       |     |  +--ro tp-attribute
       |     |  |  +--ro tp-attribute-type?
       |     |  |  |       address-attribute-type
       |     |  |  +--ro (tp-attribute-value)?
       |     |  |     +--:(ip-prefix)
       |     |  |     |  +--ro ip-prefix?
       |     |  |     |          inet:ip-prefix
       |     |  |     +--:(bgp)
       |     |  |     |  +--ro bgp?
       |     |  |     |          inet:ip-prefix
       |     |  |     +--:(tunnel)
       |     |  |     |  +--ro tunnel-interface?         uint32
       |     |  |     +--:(pw)
       |     |  |     |  +--ro remote-pe-address?
       |     |  |     |  |       inet:ip-address
       |     |  |     |  +--ro pw-id?                    uint32
       |     |  |     +--:(vpls)
       |     |  |     |  +--ro route-distinguisher?
       |     |  |     |  |       rt:route-distinguisher
       |     |  |     |  +--ro sender-ve-id?             uint16
       |     |  |     |  +--ro receiver-ve-id?           uint16
       |     |  |     +--:(mpls-mldp)
       |     |  |        +--ro (root-address)?
       |     |  |           +--:(ip-address)
       |     |  |           |  +--ro source-address?
       |     |  |           |  |       inet:ip-address
       |     |  |           |  +--ro group-ip-address?
       |     |  |           |          inet:ip-address
       |     |  |           +--:(vpn)
       |     |  |           |  +--ro as-number?
       |     |  |           |          inet:as-number
       |     |  |           +--:(global-id)
       |     |  |              +--ro lsp-id?             string
       |     |  +--ro system-info
       |     |  |  +--ro router-id?   rt:router-id
       |     |  +--ro egress-intf-name?   if:interface-ref
       |     +--ro dest-test-point
       |     |  +--ro ni?                  routing-instance-ref
       |     |  +--ro tp-location-type     identityref
       |     |  +--ro mac-address
       |     |  |  +--ro mac-address    yang:mac-address
       |     |  +--ro ipv4-address
       |     |  |  +--ro ipv4-address    inet:ipv4-address
       |     |  +--ro ipv6-address
       |     |  |  +--ro ipv6-address    inet:ipv6-address
       |     |  +--ro tp-attribute
       |     |  |  +--ro tp-attribute-type?
       |     |  |  |       address-attribute-type
       |     |  |  +--ro (tp-attribute-value)?
       |     |  |     +--:(ip-prefix)
       |     |  |     |  +--ro ip-prefix?
       |     |  |     |          inet:ip-prefix
       |     |  |     +--:(bgp)
       |     |  |     |  +--ro bgp?
       |     |  |     |          inet:ip-prefix
       |     |  |     +--:(tunnel)
       |     |  |     |  +--ro tunnel-interface?         uint32
       |     |  |     +--:(pw)
       |     |  |     |  +--ro remote-pe-address?
       |     |  |     |  |       inet:ip-address
       |     |  |     |  +--ro pw-id?                    uint32
       |     |  |     +--:(vpls)
       |     |  |     |  +--ro route-distinguisher?
       |     |  |     |  |       rt:route-distinguisher
       |     |  |     |  +--ro sender-ve-id?             uint16
       |     |  |     |  +--ro receiver-ve-id?           uint16
       |     |  |     +--:(mpls-mldp)
       |     |  |        +--ro (root-address)?
       |     |  |           +--:(ip-address)
       |     |  |           |  +--ro source-address?
       |     |  |           |  |       inet:ip-address
       |     |  |           |  +--ro group-ip-address?
       |     |  |           |          inet:ip-address
       |     |  |           +--:(vpn)
       |     |  |           |  +--ro as-number?
       |     |  |           |          inet:as-number
       |     |  |           +--:(global-id)
       |     |  |              +--ro lsp-id?             string
       |     |  +--ro system-info
       |     |  |  +--ro router-id?   rt:router-id
       |     |  +--ro ingress-intf-name?   if:interface-ref
       |     +--ro sequence-number?             uint64
       |     +--ro hop-cnt?                     uint8
       |     +--ro session-packet-statistics
       |     |  +--ro rx-packet-count?    uint32
       |     |  +--ro tx-packet-count?    uint32
       |     |  +--ro rx-bad-packet?      uint32
       |     |  +--ro tx-packet-failed?   uint32
       |     +--ro session-error-statistics
       |     |  +--ro packet-loss-count?          uint32
       |     |  +--ro loss-ratio?                 percentage
       |     |  +--ro packet-reorder-count?       uint32
       |     |  +--ro packets-out-of-seq-count?   uint32
       |     |  +--ro packets-dup-count?          uint32
       |     +--ro session-delay-statistics
       |     |  +--ro time-unit-value?       identityref
       |     |  +--ro min-delay-value?       uint32
       |     |  +--ro max-delay-value?       uint32
       |     |  +--ro average-delay-value?   uint32
       |     +--ro session-jitter-statistics
       |        +--ro unit-value?             identityref
       |        +--ro min-jitter-value?       uint32
       |        +--ro max-jitter-value?       uint32
       |        +--ro average-jitter-value?   uint32
       +---x path-discovery {cl-oam:path-discovery}?
          +---w input
          |  +---w destination-tp
          |  |  +---w tp-location-type    identityref
          |  |  +---w mac-address
          |  |  |  +---w mac-address    yang:mac-address
          |  |  +---w ipv4-address
          |  |  |  +---w ipv4-address    inet:ipv4-address
          |  |  +---w ipv6-address
          |  |  |  +---w ipv6-address    inet:ipv6-address
          |  |  +---w tp-attribute
          |  |  |  +---w tp-attribute-type?
          |  |  |  |       address-attribute-type
          |  |  |  +---w (tp-attribute-value)?
          |  |  |     +--:(ip-prefix)
          |  |  |     |  +---w ip-prefix?
          |  |  |     |          inet:ip-prefix
          |  |  |     +--:(bgp)
          |  |  |     |  +---w bgp?
          |  |  |     |          inet:ip-prefix
          |  |  |     +--:(tunnel)
          |  |  |     |  +---w tunnel-interface?         uint32
          |  |  |     +--:(pw)
          |  |  |     |  +---w remote-pe-address?
          |  |  |     |  |       inet:ip-address
          |  |  |     |  +---w pw-id?                    uint32
          |  |  |     +--:(vpls)
          |  |  |     |  +---w route-distinguisher?
          |  |  |     |  |       rt:route-distinguisher
          |  |  |     |  +---w sender-ve-id?             uint16
          |  |  |     |  +---w receiver-ve-id?           uint16
          |  |  |     +--:(mpls-mldp)
          |  |  |        +---w (root-address)?
          |  |  |           +--:(ip-address)
          |  |  |           |  +---w source-address?
          |  |  |           |  |       inet:ip-address
          |  |  |           |  +---w group-ip-address?
          |  |  |           |          inet:ip-address
          |  |  |           +--:(vpn)
          |  |  |           |  +---w as-number?
          |  |  |           |          inet:as-number
          |  |  |           +--:(global-id)
          |  |  |              +---w lsp-id?             string
          |  |  +---w system-info
          |  |     +---w router-id?   rt:router-id
          |  +---w source-interface      if:interface-ref
          |  +---w outbound-interface    if:interface-ref
          |  +---w vrf?
          |  |       cl-oam:routing-instance-ref
          |  +---w session-type?         enumeration
          |  +---w max-ttl?              uint8
          +--ro output
             +--ro response-list* [response-index]
             |  +--ro response-index           uint32
             |  +--ro protocol-id              identityref
             |  +--ro protocol-id-meta-data?   identityref
             |  +--ro status-code              identityref
             |  +--ro status-sub-code          identityref
             +--ro src-test-point
             |  +--ro ni?                 routing-instance-ref
             |  +--ro tp-location-type    identityref
             |  +--ro mac-address
             |  |  +--ro mac-address    yang:mac-address
             |  +--ro ipv4-address
             |  |  +--ro ipv4-address    inet:ipv4-address
             |  +--ro ipv6-address
             |  |  +--ro ipv6-address    inet:ipv6-address
             |  +--ro tp-attribute
             |  |  +--ro tp-attribute-type?
             |  |  |       address-attribute-type
             |  |  +--ro (tp-attribute-value)?
             |  |     +--:(ip-prefix)
             |  |     |  +--ro ip-prefix?
             |  |     |          inet:ip-prefix
             |  |     +--:(bgp)
             |  |     |  +--ro bgp?
             |  |     |          inet:ip-prefix
             |  |     +--:(tunnel)
             |  |     |  +--ro tunnel-interface?         uint32
             |  |     +--:(pw)
             |  |     |  +--ro remote-pe-address?
             |  |     |  |       inet:ip-address
             |  |     |  +--ro pw-id?                    uint32
             |  |     +--:(vpls)
             |  |     |  +--ro route-distinguisher?
             |  |     |  |       rt:route-distinguisher
             |  |     |  +--ro sender-ve-id?             uint16
             |  |     |  +--ro receiver-ve-id?           uint16
             |  |     +--:(mpls-mldp)
             |  |        +--ro (root-address)?
             |  |           +--:(ip-address)
             |  |           |  +--ro source-address?
             |  |           |  |       inet:ip-address
             |  |           |  +--ro group-ip-address?
             |  |           |          inet:ip-address
             |  |           +--:(vpn)
             |  |           |  +--ro as-number?
             |  |           |          inet:as-number
             |  |           +--:(global-id)
             |  |              +--ro lsp-id?             string
             |  +--ro system-info
             |     +--ro router-id?   rt:router-id
             +--ro dest-test-point
             |  +--ro ni?                 routing-instance-ref
             |  +--ro tp-location-type    identityref
             |  +--ro mac-address
             |  |  +--ro mac-address    yang:mac-address
             |  +--ro ipv4-address
             |  |  +--ro ipv4-address    inet:ipv4-address
             |  +--ro ipv6-address
             |  |  +--ro ipv6-address    inet:ipv6-address
             |  +--ro tp-attribute
             |  |  +--ro tp-attribute-type?
             |  |  |       address-attribute-type
             |  |  +--ro (tp-attribute-value)?
             |  |     +--:(ip-prefix)
             |  |     |  +--ro ip-prefix?
             |  |     |          inet:ip-prefix
             |  |     +--:(bgp)
             |  |     |  +--ro bgp?
             |  |     |          inet:ip-prefix
             |  |     +--:(tunnel)
             |  |     |  +--ro tunnel-interface?         uint32
             |  |     +--:(pw)
             |  |     |  +--ro remote-pe-address?
             |  |     |  |       inet:ip-address
             |  |     |  +--ro pw-id?                    uint32
             |  |     +--:(vpls)
             |  |     |  +--ro route-distinguisher?
             |  |     |  |       rt:route-distinguisher
             |  |     |  +--ro sender-ve-id?             uint16
             |  |     |  +--ro receiver-ve-id?           uint16
             |  |     +--:(mpls-mldp)
             |  |        +--ro (root-address)?
             |  |           +--:(ip-address)
             |  |           |  +--ro source-address?
             |  |           |  |       inet:ip-address
             |  |           |  +--ro group-ip-address?
             |  |           |          inet:ip-address
             |  |           +--:(vpn)
             |  |           |  +--ro as-number?
             |  |           |          inet:as-number
             |  |           +--:(global-id)
             |  |              +--ro lsp-id?             string
             |  +--ro system-info
             |     +--ro router-id?   rt:router-id
             +--ro sequence-number?             uint64
             +--ro hop-cnt?                     uint8
             +--ro session-packet-statistics
             |  +--ro rx-packet-count?    uint32
             |  +--ro tx-packet-count?    uint32
             |  +--ro rx-bad-packet?      uint32
             |  +--ro tx-packet-failed?   uint32
             +--ro session-error-statistics
             |  +--ro packet-loss-count?          uint32
             |  +--ro loss-ratio?                 percentage
             |  +--ro packet-reorder-count?       uint32
             |  +--ro packets-out-of-seq-count?   uint32
             |  +--ro packets-dup-count?          uint32
             +--ro session-delay-statistics
             |  +--ro time-unit-value?       identityref
             |  +--ro min-delay-value?       uint32
             |  +--ro max-delay-value?       uint32
             |  +--ro average-delay-value?   uint32
             +--ro session-jitter-statistics
             |  +--ro unit-value?             identityref
             |  +--ro min-jitter-value?       uint32
             |  +--ro max-jitter-value?       uint32
             |  +--ro average-jitter-value?   uint32
             +--ro path-verification
             |  +--ro flow-info?
             |  |       string
             |  +--ro session-path-verification-statistics
             |     +--ro verified-count?   uint32
             |     +--ro failed-count?     uint32
             +--ro path-trace-info
                +--ro path-trace-info-list* [index]
                   +--ro index                   uint32
                   +--ro ni?
                   |       routing-instance-ref
                   +--ro tp-location-type        identityref
                   +--ro mac-address
                   |  +--ro mac-address    yang:mac-address
                   +--ro ipv4-address
                   |  +--ro ipv4-address    inet:ipv4-address
                   +--ro ipv6-address
                   |  +--ro ipv6-address    inet:ipv6-address
                   +--ro tp-attribute
                   |  +--ro tp-attribute-type?
                   |  |       address-attribute-type
                   |  +--ro (tp-attribute-value)?
                   |     +--:(ip-prefix)
                   |     |  +--ro ip-prefix?
                   |     |          inet:ip-prefix
                   |     +--:(bgp)
                   |     |  +--ro bgp?
                   |     |          inet:ip-prefix
                   |     +--:(tunnel)
                   |     |  +--ro tunnel-interface?
                   |     |          uint32
                   |     +--:(pw)
                   |     |  +--ro remote-pe-address?
                   |     |  |       inet:ip-address
                   |     |  +--ro pw-id?
                   |     |          uint32
                   |     +--:(vpls)
                   |     |  +--ro route-distinguisher?
                   |     |  |       rt:route-distinguisher
                   |     |  +--ro sender-ve-id?
                   |     |  |       uint16
                   |     |  +--ro receiver-ve-id?
                   |     |          uint16
                   |     +--:(mpls-mldp)
                   |        +--ro (root-address)?
                   |           +--:(ip-address)
                   |           |  +--ro source-address?
                   |           |  |       inet:ip-address
                   |           |  +--ro group-ip-address?
                   |           |          inet:ip-address
                   |           +--:(vpn)
                   |           |  +--ro as-number?
                   |           |          inet:as-number
                   |           +--:(global-id)
                   |              +--ro lsp-id?
                   |                      string
                   +--ro system-info
                   |  +--ro router-id?   rt:router-id
                   +--ro timestamp-type?         identityref
                   +--ro timestamp-64bit
                   |  +--ro timestamp-sec?       uint32
                   |  +--ro timestamp-nanosec?   uint32
                   +--ro timestamp-80bit {ptp-long-format}?
                   |  +--ro timestamp-sec?       uint64
                   |  +--ro timestamp-nanosec?   uint32
                   +--ro ntp-timestamp-32bit
                   |       {ntp-short-format}?
                   |  +--ro timestamp-sec?       uint16
                   |  +--ro timestamp-nanosec?   uint16
                   +--ro icmp-timestamp-32bit {icmp-timestamp}?
                   |  +--ro timestamp-millisec?   uint32
                   +--ro ingress-intf-name?
                   |       if:interface-ref
                   +--ro egress-intf-name?
                   |       if:interface-ref
                   +--ro queue-depth?            uint32
                   +--ro transit-delay?          uint32
                   +--ro app-meta-data?          uint64

4. Модуль YANG для операций извлечения OAM

<CODE BEGINS> file "ietf-connectionless-oam-methods@2019-04-16.yang"
module ietf-connectionless-oam-methods {
  namespace
    "urn:ietf:params:xml:ns:yang:ietf-connectionless-oam-methods";
  prefix cloam-methods;

  import ietf-interfaces {
    prefix if;
  }
  import ietf-connectionless-oam {
    prefix cl-oam;
  }

  organization
    "IETF LIME Working Group";
  contact
    "WG Web:   <https://datatracker.ietf.org/wg/lime> 
     WG List:  <mailto:lmap@ietf.org> 

     Deepak Kumar <dekumar@cisco.com> 
     Qin Wu <bill.wu@huawei.com> 
     Srihari Raghavan <rihari@cisco.com> 
     Michael Wang <wangzitao@huawei.com> 
     Reshad Rahman <rrahman@cisco.com>"; 
  description
    "Этот модуль YANG задаёт операции RPC для OAM без организации
     соединений, используемые в рамках IETF независимо от протокола.
     Предполагается, что каждый протокол отображает соответствующие
     абстракции на свой естественный формат. Протоколы могут расширять
     модель данных YANG, включая зависящие от протокола элементы.

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

     Распространение и применение модуля в исходной или двоичной 
     форме с изменениями или без таковых разрешено в соответствии с
     лицензией Simplified BSD License, изложенной в параграфе 4.c
     IETF Trust's Legal Provisions Relating to IETF Documents
     (https://trustee.ietf.org/license-info). 

     Эта версия модуля YANG является частью RFC 8533, где правовые
     аспекты приведены более полно.";

  revision 2019-04-16 {
    description
      "Исходный выпуск.";
    reference
      "RFC 8533: Retrieval Methods YANG Data Model for the Management
       of Operations, Administration, and Maintenance (OAM)
       Protocols That Use Connectionless Communications";
  }

  identity protocol-id {
    description
      "Базовое отождествление для идентификатора протокола. Реестр 
       протоколов доступен по ссылке https://www.iana.org/protocols."; 
  }

  identity protocol-id-internet {
    base protocol-id;
    description
      "Идентификатор для протоколов Internet.";
  }

  identity protocol-id-proprietary {
    base protocol-id;
    description
      "Идентификатор для фирменных протоколов (например, IP SLA).";
  }

  identity protocol-id-sfc {
    base protocol-id;
    description
      "Идентификатор для цепочки функций службы (SFC).";
  }

  identity protocol-id-mpls {
    base protocol-id;
    description
      "Протокол MPLS.";
  }

  identity protocol-id-mpls-tp {
    base protocol-id;
    description
      "Протокол MPLS-TP.";
  }

  identity protocol-id-twamp {
    base protocol-id;
    description
      "Протокол TWAMP.";
  }

  identity protocol-id-bier {
    base protocol-id;
    description
      "Протокол BIER.";
  }

  identity status-code {
    description
      "Базовый идентификатор для кода состояния.";
  }

  identity success-reach {
    base status-code;
    description
      "Указывает доступность проверяемого адресата (см. RFC 7276).";
    reference
      "RFC 7276: An Overview of Operations, Administration, and
       Maintenance (OAM) Tools";
  }

  identity fail-reach {
    base status-code;
    description
      "Указывает недоступность проверяемого адресата (см. RFC 7276).";
    reference
      "RFC 7276: An Overview of Operations, Administration, and
       Maintenance (OAM) Tools";
  }

  identity success-path-verification {
    base status-code;
    description
      "Указывает успешную проверку пути (см. RFC 7276).";
    reference
      "RFC 7276: An Overview of Operations, Administration, and
       Maintenance (OAM) Tools";
  }

  identity fail-path-verification {
    base status-code;
    description
      "Указывает отказ при проверке пути (см. RFC 7276).";
    reference
      "RFC 7276: An Overview of Operations, Administration, and
       Maintenance (OAM) Tools";
  }

  identity status-sub-code {
    description
      "Субкод состояния IdentityBase.";
  }

  identity invalid-cc {
    base status-sub-code;
    description
      "Указывает, что сообщение Continuity Check недействительно
       (см. RFC 7276).";
    reference
      "RFC 7276: An Overview of Operations, Administration, and
       Maintenance (OAM) Tools";
  }

  identity invalid-pd {
    base status-sub-code;
    description
      "Указывает, что сообщение обнаружения пути недействительно
       (см. RFC 7276).";
    reference
      "RFC 7276: An Overview of Operations, Administration, and
       Maintenance (OAM) Tools";
  }

  identity protocol-id-meta-data {
    description
      "Базовый идентификатор для метаданных, соответствующих 
       идентификатору протокола.";
  }

  identity protocol-internet-number {
    base protocol-id-meta-data;
    description
      "Номер протокола IP для стандартных протоколов Internet
       (выделенные IANA номера протоколов Internet), помогающий при
       обработке протокола. Реестр протоколов доступен по ссылке
       https://www.iana.org/assignments/protocol-numbers."; 
  }

  grouping rpc-input-parameters {
    container destination-tp {
      uses cl-oam:tp-address;
      description
        "Целевая точка теста.";
    }
    leaf source-interface {
      type if:interface-ref;
      mandatory true;
      description
        "Интерфейс источника.";
    }
    leaf outbound-interface {
      type if:interface-ref;
      mandatory true;
      description
        "Выходной интерфейс.";
    }
    leaf vrf {
      type cl-oam:routing-instance-ref;
      description
        "Экземпляр виртуальной маршрутизации и пересылки (VRF).";
    }
    description
      "Группировка для входных параметров RPC.";
  }

  rpc continuity-check {
    if-feature "cl-oam:continuity-check";
    description
      "Операция Continuity Check RPC в соответствии с RFC 7276.";
    reference
      "RFC 7276: An Overview of Operations, Administration, and
       Maintenance (OAM) Tools";
    input {
      uses rpc-input-parameters;
      uses cl-oam:session-type {
        description
          "Если задан тип сессии, должно устанавливаться session-type
           по запросу.";
      }
      leaf count {
        type uint32 {
          range "0..4294967295" {
            description
              "Общее число пакетов, переданных отправителем. Счётчик 
               может сбрасываться (0) при создании и монотонно расти 
               монотонно до максимального значения 2^32-1 (4294967295),
               после чего снова сбрасывается в 0.";
          }
        }
        default "5";
        description
          "Число пакетов, которые будут переданы. По умолчанию 5.";
      }
      leaf ttl {
        type uint8;
        default "255";
        description
          "Значение TTL, используемое для ограничения срока действия
           пакетов с целью предотвращения петель. Значение TTL
           уменьшается при каждой пересылке пакета и при достижении 0
           пакет отбрасывается.";
      }
      leaf packet-size {
        type uint32 {
          range "64..10000";
        }
        default "64";
        description
          "Размер пакета сообщения Continuity Check в октетах 
           (по умолчанию 64).";
      }
    }
    output {
      container response-info {
        leaf protocol-id {
          type identityref {
            base protocol-id;
          }
          mandatory true;
          description
            "Протокол, используемый в сообщении Continuity Check. Это
             может быть стандартный (например, протоколы TCP/IP, MPLS
             и т. п.) или фирменный протокол.";
        }
        leaf protocol-id-meta-data {
          type identityref {
            base protocol-id-meta-data;
          }
          description
            "Необязательные метаданные, связанные с идентификатором
             протокола, например, номер стандартного протокола IP для
             помощи при обработке протокола.";
        }
        leaf status-code {
          type identityref {
            base status-code;
          }
          mandatory true;
          description
            "Код состояния для операции Continuity Check RPC. Это может
             быть базовый (например, код доступности или недоступности
             адресата, см. RFC 7276) или специализированный код.";
          reference
            "RFC 7276: An Overview of Operations, Administration, and
             Maintenance (OAM) Tools";
        }
        leaf status-sub-code {
          type identityref {
            base status-sub-code;
          }
          mandatory true;
          description
            "Необязательный субкод состояния операции Continuity Check
             RPC. Если базовый код состояния указывает доступность
             адресата, этот субкод задавать не требуется. Если базовый
             код указывает недоступность адресата, субкод может служить
             для уточнения причин. Это может быть базовый субкод
             (например, непригодность Continuity Check) или иной код
             ошибки, специфичный для протокола, использованного в 
             Continuity Checks. Например, если используется ICMP, можно
             указывать коды ошибок из RFC 4443 для указания причин,
             специфичных для ICMP. Эти коды могут задаваться в моделях
             для топологии.";
          reference
            "RFC 4443: Internet Control Message Protocol (ICMPv6) for 
             the Internet Protocol Version 6 (IPv6) Specification.";4
        }
        description
          "Код и субкод состояния для операции Continuity Check RPC.";
      }
      uses cl-oam:continuity-check-data;
    }
  }

  rpc path-discovery {
    if-feature "cl-oam:path-discovery";
    description
      "Операция RPC обнаружения пути в соответствии с RFC 7276.";
    reference
      "RFC 7276: An Overview of Operations, Administration, and
       Maintenance (OAM) Tools";
    input {
      uses rpc-input-parameters;
      uses cl-oam:session-type {
        description
          "Если задан тип сессии, это значение session-type должно
           устанавливаться по запросу.";
      }
      leaf max-ttl {
        type uint8;
        default "255";
        description
          "Максимальное значение TTL задаёт предельное число пересылок
           пакета, прежде чем он будет отброшен маршрутизатором.
           По умолчанию установлено значение 255.";
      }
    }
    output {
      list response-list {
        key "response-index";
        description
          "Список откликов при обнаружении пути.";
        leaf response-index {
          type uint32;
          mandatory true;
          description
            "Индекс отклика.";
        }
        leaf protocol-id {
          type identityref {
            base protocol-id;
          }
          mandatory true;
          description
            "Протокол, применяемый для обнаружения пути. Это может быть
             стандартный (например, протоколы TCP/IP, MPLS и т. п.) или
             фирменный протокол, указанный этим полем.";
        }
        leaf protocol-id-meta-data {
          type identityref {
            base protocol-id-meta-data;
          }
          description
            "Необязательные метаданные, связанные с идентификатором
             протокола, например, номер стандартного протокола IP для
             помощи при обработке протокола.";
        }
        leaf status-code {
          type identityref {
            base status-code;
          }
          mandatory true;
          description
            "Код состояния для операции Continuity Check RPC. Это может
             быть базовый (например, код доступности или недоступности
             адресата, см. RFC 7276) или специализированный код.";
        }
        leaf status-sub-code {
          type identityref {
            base status-sub-code;
          }
          mandatory true;
          description
            "Необязательный субкод состояния операции Continuity Check
             RPC. Если базовый код состояния указывает доступность
             адресата, этот субкод задавать не требуется. Если базовый
             код указывает недоступность адресата, субкод может служить
             для уточнения причин. Это может быть базовый субкод
             (например, непригодность Continuity Check) или иной код
             ошибки, специфичный для протокола, использованного в 
             Continuity Checks. Например, если используется ICMP, можно
             указывать коды ошибок из RFC 4443 для указания причин,
             специфичных для ICMP. Эти коды могут задаваться в моделях
             для топологии.";
          reference
            "RFC 4443: Internet Control Message Protocol (ICMPv6) for 
             the Internet Protocol Version 6 (IPv6) Specification.";5
        }
      }
      uses cl-oam:path-discovery-data;
    }
  }
}
<CODE ENDS>

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

Заданный этим документом модуль YANG определяет схему для данных, предназначенную для доступа через сеть с использованием протоколов управления, таких как NETCONF [RFC6241] или RESTCONF [RFC8040]. Нижним уровнем NETCONF служит защищённый транспорт с обязательной поддержкой SSH (Secure Shell) [RFC6242]. Нижним уровнем RESTCONF служит протокол HTTPS с обязательной поддержкой защиты на транспортном уровне (TLS) [RFC8446].

Модель доступа к конфигурации сети (NACM – Network Configuration Access Control Model) [RFC8341] обеспечивает возможность разрешить доступ лишь определённых пользователей NETCONF или RESTCONF к заранее заданному подмножеству операций NETCONF или RESTCONF и содержимого.

Некоторые из операций RPC в этом модуле YANG могут считаться чувствительными или уязвимыми в некоторых сетевых средах:

  • continuity-check генерирует Continuity Check;

  • path-discovery генерирует обнаружение пути.

Эти операции служат для извлечения данный из устройства, которому нужно выполнить команду OAM. Несанкционированный доступ к чувствительной информации в указанных выше узлах может использоваться для сетевой разведки или приводить к отказам в обслуживании (denial-of-service) на локальном устройстве и в сети.

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

Этот документ регистрирует URI в реестре IETF XML Registry [RFC3688]

   URI: urn:ietf:params:xml:ns:yang:ietf-connectionless-oam-methods
   Registrant Contact: The IESG.  XML: запрошенный URI является 
   пространством имён XML.

Этот документ регистрирует модуль YANG в реестре YANG Module Names [RFC6020].

   name: ietf-connectionless-oam-methods
   namespace:
      urn:ietf:params:xml:ns:yang:ietf-connectionless-oam-methods
   prefix: cloam-methods
   reference: RFC 8533

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

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

[RFC3688] Mealling, M., «The IETF XML Registry», BCP 81, RFC 3688, DOI 10.17487/RFC3688, January 2004, <https://www.rfc-editor.org/info/rfc3688>.

[RFC6020] Bjorklund, M., Ed., «YANG — A Data Modeling Language for the Network Configuration Protocol (NETCONF)», RFC 6020, DOI 10.17487/RFC6020, October 2010, <https://www.rfc-editor.org/info/rfc6020>.

[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., «Network Configuration Protocol (NETCONF)», RFC 6241, DOI 10.17487/RFC6241, June 2011, <https://www.rfc-editor.org/info/rfc6241>.

[RFC6242] Wasserman, M., «Using the NETCONF Protocol over Secure Shell (SSH)», RFC 6242, DOI 10.17487/RFC6242, June 2011, <https://www.rfc-editor.org/info/rfc6242>.

[RFC7011] Claise, B., Ed., Trammell, B., Ed., and P. Aitken, «Specification of the IP Flow Information Export (IPFIX) Protocol for the Exchange of Flow Information», STD 77, RFC 7011, DOI 10.17487/RFC7011, September 2013, <https://www.rfc-editor.org/info/rfc7011>.

[RFC792] Postel, J., «Internet Control Message Protocol», STD 5, RFC 792, DOI 10.17487/RFC0792, September 1981.

[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, «RESTCONF Protocol», RFC 8040, DOI 10.17487/RFC8040, January 2017, <https://www.rfc-editor.org/info/rfc8040>.

[RFC8341] Bierman, A. and M. Bjorklund, «Network Configuration Access Control Model», STD 91, RFC 8341, DOI 10.17487/RFC8341, March 2018, <https://www.rfc-editor.org/info/rfc8341>.

[RFC8446] Rescorla, E., «The Transport Layer Security (TLS) Protocol Version 1.3», RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.

[RFC8532] Kumar, D., Wang, M., Wu, Q., Ed., Rahman, R., and S. Raghavan, «Generic YANG Data Model for the Management of Operations, Administration, and Maintenance (OAM) Protocols That Use Connectionless Communications», RFC 8532, DOI 10.17487/RFC8532, April 2019, <https://www.rfc-editor.org/info/rfc8532>.

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

[RFC4443] Conta, A., Deering, S., and M. Gupta, Ed., «Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification», STD 89, RFC 4443, DOI 10.17487/RFC4443, March 2006, <https://www.rfc-editor.org/info/rfc4443>.

[RFC5880] Katz, D. and D. Ward, «Bidirectional Forwarding Detection (BFD)», RFC 5880, DOI 10.17487/RFC5880, June 2010, <https://www.rfc-editor.org/info/rfc5880>.

[RFC7276] Mizrahi, T., Sprecher, N., Bellagamba, E., and Y. Weingarten, «An Overview of Operations, Administration, and Maintenance (OAM) Tools», RFC 7276, DOI 10.17487/RFC7276, June 2014, <https://www.rfc-editor.org/info/rfc7276>.

[RFC8029] Kompella, K., Swallow, G., Pignataro, C., Ed., Kumar, N., Aldrin, S., and M. Chen, «Detecting Multiprotocol Label Switched (MPLS) Data-Plane Failures», RFC 8029, DOI 10.17487/RFC8029, March 2017, <https://www.rfc-editor.org/info/rfc8029>.

[RFC8340] Bjorklund, M. and L. Berger, Ed., «YANG Tree Diagrams», BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, <https://www.rfc-editor.org/info/rfc8340>.

[RFC8407] Bierman, A., «Guidelines for Authors and Reviewers of Documents Containing YANG Data Models», BCP 216, RFC 8407, DOI 10.17487/RFC8407, October 2018, <https://www.rfc-editor.org/info/rfc8407>.

[YANG-Push] Clemm, A., Voit, E., Prieto, A., Tripathy, A., Nilsen- Nygaard, E., Bierman, A., and B. Lengyel, «Subscription to YANG Datastores», Work in Progress6, draft-ietf-netconf-yang-push-22, February 2019.

Приложение A. Пример модуля расширения OAM без соединений

Ниже приведён пример возможных расширений модуля данных YANG ietf-connectionless-oam-methods, заданного в этом документе. Фрагмент кода, представленный ниже, дополняет модуль данных YANG ietf-connectionless-oam-methods атрибутами ICMP ping.

   augment "/cloam-methods:continuity-check"
   +"/cloam-methods:output"{
     container session-rtt-statistics{
      leaf min-rtt{
       type uint32;
    description
    "Минимальное время кругового обхода (RTT) для ping.";
      }
      leaf max-rtt{
       type uint32;
    description
    "Максимальное время кругового обхода (RTT) для ping.";
      }
      leaf avg-rtt{
       type uint32;
    description
     "Текущее среднее значение RTT для ping.";
      }
      description
      "Контейнер статистики RTT для ping.";
     }
   }

A.1. Пример модели новых процедур извлечения

Как было отмечено в разделе 1. Введение, можно задать новые процедуры, извлекающие те же данные, которые определены базовой моделью данных YANG для протоколов OAM без соединений. В этом приложении показано, как базовую модель для OAM без соединений для поддержки постоянного извлечения данных отдельно от процедур извлечения по запросам, описанных в разделе 3, т. е. сначала извлекается постоянный идентификатор (persistent-id) по сведениям о местоположении тестовой точки, затем экспортируются детали по persistent-id. Как параметры экспорта данных указаны IPFIX (Internet Protocol Flow Information Export) [RFC7011] и YANG-Push [YANG-Push], а в будущем могут добавляться иные варианты экспорта.

Показанный ниже модуль YANG example-cl-oam-persistent-methods предназначен для иллюстрации а не в качестве реального определения модели операций RPC для постоянного извлечения данных. Для краткости в модуле не соблюдаются некоторые рекомендации [RFC8407].

   module example-cl-oam-persistent-methods {
     namespace "http://example.com/cl-oam-persistent-methods";
     prefix pcloam-methods;

     import ietf-interfaces {
       prefix if;
     }
     import ietf-connectionless-oam {
       prefix cl-oam;
     }
     import ietf-yang-types {
       prefix yang;
     }

     identity export-method {
       description
         "Базовый идентификатор для метода экспорта.";
     }

     identity ipfix-export {
       base export-method;
       description
         "Экспорт на основе IPFIX. Конфигурация задаётся отдельно.";
     }

     identity yang-push-export {
       base export-method;
       description
         "Экспорт YANG-Push из draft-ietf-netconf-yang-push.";
     }

     identity protocol-id {
       description
         "Базовый идентификатор протокола.";
     }

     identity status-code {
       description
         "Базовый код состояния.";
     }

     identity success-reach {
       base status-code;
       description
         "Указывает доступность проверяемого адресата.";
     }

     identity fail-reach {
       base status-code;
       description
         "Указывает недоступность проверяемого адресата.";
     }

     identity success-path-verification {
       base status-code;
       description
         "Указывает успешную проверку пути.";
     }

     identity fail-path-verification {
       base status-code;
       description
         "Указывает отказ при проверке пути.";
     }

     identity status-sub-code {
       description
         "Base status-sub-code.";
     }

     identity invalid-cc {
       base status-sub-code;
       description
         "Указывает, что сообщение Continuity Check непригодно.";
     }

     identity invalid-pd {
       base status-sub-code;
       description
         "Указывает, что сообщение обнаружения пути непригодно.";
     }

     typedef export-method {
       type identityref {
         base export-method;
       }
       description
         "Метод экспорта.";
     }

     typedef change-type {
       type enumeration {
         enum create {
           description
             "Изменение в результате создания.";
         }
         enum delete {
           description
             "Изменение в результате удаления.";
         }
         enum modify {
           description
             "Изменение в результате обновления.";
         }
       }
       description
         "Возможны разные типы изменений.";
     }

     rpc cc-get-persistent-id {
       if-feature "cl-oam:continuity-check";
       description
         "Получает постоянную идентификацию Continuity Check 
          с заданными параметрами отображения на входа.";
       input {
         container destination-tp {
           uses cl-oam:tp-address;
           description
             "Целевая тестовая точка.";
         }
         uses cl-oam:session-type;
         leaf source-interface {
           type if:interface-ref;
           description
             "Интерфейс-источник.";
         }
         leaf outbound-interface {
           type if:interface-ref;
           description
             "Выходной интерфейс.";
         }
         leaf vrf {
           type cl-oam:routing-instance-ref;
           description
             "Экземпляр VRF.";
         }
       }
       output {
         container error-code {
           leaf protocol-id {
             type identityref {
               base protocol-id;
             }
             mandatory true;
             description
               "Применяемый протокол. Это может быть стандартный
                (например, TCP/IP, MPLS и т. п.) или фирменный протокол,
                указанный этим полем.";
           }
           leaf protocol-id-meta-data {
             type uint64;
             description
               "Необязательные метаданные, связанные с идентификатором 
                протокола, например, номер стандартного протокола IP,
                используемый в помощь при обработке протокола.";
           }
           leaf status-code {
             type identityref {
               base status-code;
             }
             mandatory true;
             description
               "Код состояния.";
           }
           leaf status-sub-code {
             type identityref {
               base status-sub-code;
             }
             mandatory true;
             description
               "Субкод для Continuity Check.";
           }
           description
             "Код и субкод состояния.";
         }
         leaf cc-persistent-id {
           type string;
           description
             "Идентификатор для действия в качестве cookie.";
         }
       }
     }

     rpc cc-persistent-get-export-details {
       if-feature "cl-oam:continuity-check";
       description
         "На основе постоянного идентификатора получает параметры
          конфигурации и детали, связанные с настроенным экспортом.";
       input {
         leaf cc-persistent-id {
           type string;
           description
             "Постоянный идентификатор для применения в качестве 
              ключа поиска.";
         }
       }
       output {
         container error-code {
           leaf protocol-id {
             type identityref {
               base protocol-id;
             }
             mandatory true;
             description
               "Применяемый протокол. Это может быть стандартный
                (например, TCP/IP, MPLS и т. п.) или фирменный протокол,
                указанный этим полем.";
           }
           leaf protocol-id-meta-data {
             type uint64;
             description
               "Необязательные метаданные, связанные с идентификатором 
                протокола, например, номер стандартного протокола IP,
                используемый в помощь при обработке протокола.";
           }
           leaf status-code {
             type identityref {
               base status-code;
             }
             mandatory true;
             description
               "Код состояния.";
           }
           leaf status-sub-code {
             type identityref {
               base status-sub-code;
             }
             mandatory true;
             description
               "Субкод для Continuity Check.";
           }
           description
             "Код и субкод состояния.";
         }
         leaf data-export-method {
           type export-method;
           description
             "Используемый тип экспорта.";
         }
         choice cc-trigger {
           description
             "Требуемые условия для периодической отправки или
              отправки при изменении.";
           case periodic {
             description
               "Периодические отчёты.";
             leaf period {
               type yang:timeticks;
               description
                 "Интервал времени между отчётами.";
             }
             leaf start-time {
               type yang:date-and-time;
               description
                 "Время начала отчётов.";
             }
           }
           case on-change {
             description
               "Отправка при изменении, а не периодически.";
             leaf all-data-on-start {
               type boolean;
               description
                 "Управляет передачей полного обновления при старте.";
             }
             leaf-list excluded-change {
               type change-type;
               description
                 "Изменения, которые не будут вызывать обновление.";
             }
           }
         }
       }
     }

     rpc pd-get-persistent-id {
       if-feature "cl-oam:path-discovery";
       description
         "Получает постоянную идентификацию обнаружения пути.";
       input {
         container destination-tp {
           uses cl-oam:tp-address;
           description
             "Целевая тестовая точка.";
         }
         uses cl-oam:session-type;
         leaf source-interface {
           type if:interface-ref;
           description
             "Интерфейс-источник.";
         }
         leaf outbound-interface {
           type if:interface-ref;
           description
             "Выходной интерфейс.";
         }
         leaf vrf {
           type cl-oam:routing-instance-ref;
           description
             "VRF";
         }
       }
       output {
         list response-list {
           key "response-index";
           description
             "Список откликов на обнаружение пути.";
           leaf response-index {
             type uint32;
             mandatory true;
             description
               "Индекс отклика.";
           }
           leaf protocol-id {
             type identityref {
               base protocol-id;
             }
             mandatory true;
             description
               "Применяемый протокол. Это может быть стандартный
                (например, TCP/IP, MPLS и т. п.) или фирменный протокол,
                указанный этим полем.";
           }
           leaf protocol-id-meta-data {
             type uint64;
             description
               "Необязательные метаданные, связанные с идентификатором 
                протокола, например, номер стандартного протокола IP,
                используемый в помощь при обработке протокола.";
           }
           leaf status-code {
             type identityref {
               base status-code;
             }
             mandatory true;
             description
               "Код состояния для постоянных сведений обнаружения пути";
           }
           leaf status-sub-code {
             type identityref {
               base status-sub-code;
             }
             mandatory true;
             description
               "Субкод для постоянных сведений обнаружения пути";
           }
           leaf pd-persistent-id {
             type string;
             description
               "Идентификатор для действия в качестве cookie.";
           }
         }
       }
     }

     rpc pd-persistent-get-export-details {
       if-feature "cl-oam:path-discovery";
       description
         "На основе постоянного идентификатора получает параметры
          конфигурации и детали, связанные с настроенным экспортом.";
       input {
         leaf cc-persistent-id {
           type string;
           description
             "Постоянный идентификатор для применения в качестве 
              ключа поиска.";
         }
       }
       output {
         list response-list {
           key "response-index";
           description
             "Список откликов при обнаружении пути.";
           leaf response-index {
             type uint32;
             mandatory true;
             description
               "Индекс отклика.";
           }
           leaf protocol-id {
             type identityref {
               base protocol-id;
             }
             mandatory true;
             description
               "Применяемый протокол. Это может быть стандартный
                (например, TCP/IP, MPLS и т. п.) или фирменный протокол,
                указанный этим полем.";
           }
           leaf protocol-id-meta-data {
             type uint64;
             description
               "Необязательные метаданные, связанные с идентификатором 
                протокола, например, номер стандартного протокола IP,
                используемый в помощь при обработке протокола.";
           }
           leaf status-code {
             type identityref {
               base status-code;
             }
             mandatory true;
             description
               "Код состояния для создания постоянного обнаружения
                путей.";
           }
           leaf status-sub-code {
             type identityref {
               base status-sub-code;
             }
             mandatory true;
             description
               "Субкод состояния для создания постоянного обнаружения
                путей.";
           }
           leaf data-export-method {
             type export-method;
             description
               "Тип экспорта.";
           }
           choice pd-trigger {
             description
               "Требуемые условия для периодической отправки или
                отправки при изменении.";
             case periodic {
               description
                 "Периодические отчёты.";
               leaf period {
                 type yang:timeticks;
                 description
                   "Интервал времени между отчётами.";
               }
               leaf start-time {
                 type yang:date-and-time;
                 description
                   "Время начала отчётов.";
               }
             }
             case on-change {
               description
                 "Отправка при изменении, а не периодически.";
               leaf all-data-on-start {
                 type boolean;
                 description
                   "Управляет передачей полного обновления при старте.";
               }
               leaf-list excluded-change {
                 type change-type;
                 description
                   "Изменения, которые не будут вызывать обновления.";
               }
             }
           }
         }
       }
     }
   }

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

Авторы благодарны Elwyn Davies, Alia Atlas, Brian E. Carpenter, Greg Mirsky, Adam Roach, Alissa Cooper, Eric Rescorla, Ben Campbell, Benoit Claise, Kathleen Moriarty, Carlos Pignataro, Benjamin Kaduk и другим за подробные рецензии, комментарии и предложения по улучшению документа.

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

Deepak Kumar
CISCO Systems
510 McCarthy Blvd.
Milpitas, CA 95035
United States of America
Email: dekumar@cisco.com
 
Michael Wang
Huawei Technologies, Co., Ltd
101 Software Avenue, Yuhua District
Nanjing 210012
China
Email: wangzitao@huawei.com
 
Qin Wu (editor)
Huawei
101 Software Avenue, Yuhua District
Nanjing, Jiangsu 210012
China
Email: bill.wu@huawei.com
 
Reshad Rahman
CISCO Systems
2000 Innovation Drive
Kanata, Ontario K2K 3E8
Canada
Email: rrahman@cisco.com
 
Srihari Raghavan
CISCO Systems
Tril Infopark Sez, Ramanujan IT City
Neville Block, 2nd floor, Old Mahabalipuram Road
Chennai, Tamil Nadu 600113
India
Email: srihari@cisco.com

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

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

nmalykh@protokols.ru

1Operations, Administration, and Maintenance — эксплуатация, администрирование, обслуживание.

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

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

4В оригинале ошибочно указано The IETF Administrative Oversight Committee (IAOC) Member Selection Guidelines and Process. Прим. перев.

5В оригинале ошибочно указано The IETF Administrative Oversight Committee (IAOC) Member Selection Guidelines and Process. Прим. перев.

6Опубликовано в RFC 8641. Прим. перев.

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

RFC 8531 Generic YANG Data Model for Connection-Oriented Operations, Administration, and Maintenance (OAM) Protocols

Internet Engineering Task Force (IETF)                          D. Kumar
Request for Comments: 8531                                         Cisco
Category: Standards Track                                          Q. Wu
ISSN: 2070-1721                                                  M. Wang
                                                                  Huawei
                                                              April 2019

Generic YANG Data Model for Connection-Oriented Operations, Administration, and Maintenance (OAM) Protocols

Базовая модель данных YANG для ориентированных на соединения протоколов OAM

PDF

Аннотация

Этот документ представляет базовую модель данных YANG для ориентированных на соединения протоколов OAM. Документ обеспечивает не зависимую от технологии абстракцию основных конструкций OAM для таких протоколов. Представленная модель может быть расширена с учетом определяемых технологиями деталей. Это гарантирует однородность управления протоколами OAM и обеспечивает поддержку вложенных процессов OAM (т. е. выполнение функций OAM на разных уровнях через унифицированный интерфейс).

Модель данных YANG в этом документе соответствует архитектуре NMDA1.

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

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

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

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

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

Авторские права (Copyright (c) 2019) принадлежат 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).

1. Введение

OAM включает важные сетевые функции, которые позволяют операторам:

  1. отслеживать состояние сетевых коммуникаций (т. е. проверку доступности и связности);

  2. поиск неполадок (т. е. обнаружение отказов);

  3. контролировать соглашения об уровне обслуживания и производительность (т. е. управлять производительностью).

Обзор инструментов OAM представлен в [RFC7276]. За долгие годы было разработано множество инструментов для контроля отказов и управления производительностью.

Разные наборы инструментов OAM могут поддерживать как технологии на основе соединений, так и без них. В ориентированных на соединения технологиях соединение создается до начала передачи данных. После организации соединения не требуется передачи дополнительной управляющей информации (такой как сигналы или операции) для передачи пользовательских данных. В технологиях без организации соединений данные обычно передаются между взаимодействующими конечными точками без предварительного согласования, но нужны управляющие данные для указания получателя (например, [G.800]). Модель данных YANG для протоколов OAM без организации соединений задана в [RFC8532] и [IEEE802.1Q].

Контроль отказов в соединениях (CFM), как указано в [IEEE802.1Q], является четко определенным стандартом OAM, широко распространенным в сетях Ethernet. ITU-T [G.8013], MEF Forum (MEF) Service OAM [MEF-17], MPLS-TP4 [RFC6371] и TRILL [RFC7455] определяют механизмы OAM, основанные на модели управляемости CFM [IEEE802.1Q].

С учетом широкого распространения базовых концепций OAM, определенных в CFM [IEEE802.1Q], разумным шагом будет разработка унифицированной схемы управления для ориентированных на соединения решений OAM на базе этих концепций. В этом документе модель CFM [IEEE802.1Q] служит основой для расширения до технологически независимой модели и определения соответствующей модели данных YANG. Представленная здесь модель данных YANG служит базой для ориентированных на соединения протоколов OAM и поддерживает базовую проверку непрерывности, проверку связности и обнаружение пути (traceroute). Базовая модель YANG для ориентированных на соединения решений OAM разработана с возможностью расширения на другие технологии, основанные на соединениях. Зависимые от технологии узлы и команды (RPC) определяются в зависимых от технологии моделях данных YANG, которые используют и расширяют определенную здесь базовую модель. Например, расширяемые виртуальные ЛВС (VXLAN5), используют порт отправителя UDP для энтропии потока, а TRILL использует (a) MAC-адрес, (b) тег VLAN или метку Fine-Grained Label и/или (c) адрес IP для энтропии потока в хэшировании при выборе среди множества путей. С учетом этих различий соответствующие модели данных YANG будут определять подходящие структуры в качестве дополнения к представленной здесь базовой модели. Это решает три задачи — во-первых, каждая модель данных YANG сохраняется компактной и управляемой, во-вторых, такие модели можно разрабатывать независимо, и в-третьих, реализации могут ограничиваться поддержкой лишь нужного набора моделей YANG. Например, TRILL RBridge может ограничиться реализацией базовой модели данных и модели TRILL YANG.

Представленная здесь модель данных YANG генерируется на уровне управления. Инкапсуляция и конечные автоматы состояний могут различаться для каждого протокола OAM. Пользователь, желающий ввести программу проверки непрерывности работы (Continuity Check), Loopback или организовать сеанм мониторинга производительности, может сделать это независимо от базового протокола, технологии или конкретной реализации производителя.

В качестве примера рассмотрим случай, где в соединении между устройствами A возникает отказ B. Между A и B имеются мосты IEEE 802.1 a, b и c. Предположим, что эти мосты используют CFM [IEEE802.1Q]. Пользователь, увидев отказ, может решить, что следует выполнить проверку на более низком уровне в разных сегментах пути и запускает соответствующие средства проверки (Loopback Message) и изоляции (Looktrace Message) отказов, использующие общий API. Такая возможность детализации до нижнего уровня стека протоколов в конкретном сегменте пути для поиска точки отказа, называется вложенным процессом OAM. Это полезная концепция, которая обеспечивает эффективный поиск неполадок и процесс обслуживания. Представленная в документе модель данных OAM YANG, ориентированная на соединения, облегчает такой подход не требуя менять базовые протоколы.

Модель данных YANG в этом документе соответствует архитектуре сетевых хранилищ NMDA6, определенной в [RFC8342].

2. Используемые соглашения

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

Многие из применяемых в документе терминов (включая указанные в параграфах 2.1 и 2.2) относятся к сфере OAM. Этот документ не пытается объяснить эти термины и предполагает знакомство читателя с концепциями. Хороший обзор представлен в [IEEE802.1Q]. Термины OAM в работах IETF рассмотрены в [RFC6371].

2.1. Сокращения

CCM

Continuity Check Message — сообщение проверки непрерывности [IEEE802.1Q].

ECMP

Equal-Cost Multipath — множество равноценных путей.

LBM

Loopback Message — сообщение Loopback [IEEE802.1Q].

LTM

Linktrace Message — сообщение Linktrace [IEEE802.1Q].

MP

Maintenance Point — точка обслуживания [IEEE802.1Q].

MEP

Maintenance End Point — конечная точка обслуживания [RFC7174] (называется также Maintenance association End Point [IEEE802.1Q] и MEG End Point [RFC6371]).

MIP

Maintenance Intermediate Point — промежуточная точка обслуживания [RFC7174] (называется также Maintenance domain Intermediate Point [IEEE802.1Q] и MEG Intermediate Point [RFC6371]).

MA

Maintenance Association — ассоциация обслуживания [IEEE802.1Q] [RFC7174].

MD

Maintenance Domain — домен (область) обслуживания [IEEE802.1Q].

MEG

Maintenance Entity Group — группа объектов обслуживания [RFC6371].

MTV

Multi-destination Tree Verification Message — сообщение проверки дерева со множеством получателей.

OAM

Operations, Administration, and Maintenance — эксплуатация, администрирование, обслуживание [RFC6291].

TRILL

Transparent Interconnection of Lots of Links — прозрачное соединение множества каналов [RFC6325].

CFM

Connectivity Fault Management — обслуживание отказов в соединениях [RFC7174] [IEEE802.1Q].

RPC

Remote Procedure Call — вызов удаленной процедуры.

CC

Continuity Check — проверка непрерывности [RFC7276].

CV

Connectivity Verification — проверка связности [RFC7276].

2.2. Термины

Continuity Checks — проверка непрерывности

CC служит для проверки доступности адресата, поэтому называется также проверкой доступности.

Connectivity Verification — проверка связности

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

Proactive OAM – OAM в проактивном режиме

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

On-demand OAM – OAM по запросу

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

2.3. Диаграммы деревьев

В диаграммах деревьев применяется нотация, определенная в [RFC8340].

3. Архитектура базовой модели YANG для OAM на базе соединений

В этом документе определена базовая модель YANG для ориентированных на соединения протоколов OAM. Модель является базовой в том смысле, что другие технологии могут расширить ее с учетом зависящих от технологии потребностей. Базовая модель данных для ориентированных на соединения протоколов OAM служит корнем для других моделей данных OAM YANG. Это позволяет использовать разные протоколы OAM с использованием унифицированного набора API. Это также делает возможными вложенные процессы OAM. На рисунке 1 показаны связи разных моделей OAM YANG с базовой моделью YANG для ориентированных на соединения протоколов OAM. Эта базовая модель обеспечивает основу, от которой модели YANG для конкретных технологий могут наследовать те или иные конструкции без необходимости их переопределения.

                       +-----------+
                       |Connection-|
                       | Oriented  |
                       |  generic  |
                       | OAM YANG  |
                       +-+-+-+-+-+-+
                             |
                             |
                             |
     +------------------------------------------+
     |                       |                  |
+-+-+-+-+-+          +-+-+-+-+-+          +-+-+-+-+-+
| TRILL   |          | MPLS-TP |     . . .|  foo    |
|OAM YANG |          |OAM YANG |          |OAM YANG |
+-+-+-+-+-+          +-+-+-+-+-+          +-+-+-+-+-+
     |                    |                     |
     |                    |               +-+-+-+-+-+
     |                    |          . . .|  foo    |
     |                    |               |sub tech |
     |                    |               +-+-+-+-+-+
     |                    |                     |
     |                    |                     |
+---------------------------------------------------+
|                      Uniform API                  |
+---------------------------------------------------+

Рисунок 1. Связь модели OAM YANG с базовой моделью YANG.


4. Обзор ориентированной на соединения модели данных OAM YANG

В этом документе применяются концепции модели CFM [IEEE802.1Q] и структура, которые могут быть адаптированы для других протоколов OAM, ориентированных на соединения.

На вершине модели размещается домен обслуживания (MD). Каждый домен обслуживания связан с именем обслуживания (Maintenance Name) и уровнем домена (Domain Level).

В каждом MD имеется одна или множество ассоциаций обслуживания (MA). В TRILL ассоциация MA может соответствовать Fine-Grained Label.

В MA может быть две и более конечных точки обслуживания (MEP), которые задаются адресами, связанными с технологией. Представленная здесь модель YANG обеспечивает гибкость для поддержки разных схем адресации.

Команды представлены в протоколе управления, который ортогонален MD. В терминах YANG это команды RPC. Они обеспечивают унифицированные интерфейсы API для CC, CV, обнаружения пути (traceroute) и их эквивалентов, а также для других команд OAM.

Объекты OAM в определенной здесь базовой модели YANG будут явно или неявно настраиваться с помощью инструментов OAM. Эти инструменты ограничены набором OAM, указанным в параграфе 5.1 [RFC7276]. Для упрощения настройки «в одно касание» (zero-touch) этот документ определяет принятый по умолчанию режим OAM. Этот режим называется базовым (Base Mode) и задает принятые по умолчанию значения для каждого параметра модели (уровень MD, имя MA, адреса MEP и т. д.). Принятые по умолчанию значения зависят от технологии. Базовый режим для TRILL определен в [RFC7455], а базовые режимы для других технологий и будущие расширения, созданные в IETF, будут определены в соответствующих документах.

Важено отметить, что в модель YANG не требуется вносить изменений для поддержки Base Mode. Реализации, соответствующие этому документу, по умолчанию используют узлы данных применимой технологии. Узлы данных базовой модели доступны лишь для чтения (read-only).

4.1. Конфигурация MD

module: ietf-connection-oriented-oam
 +--rw domains
    +--rw domain* [technology md-name-string]
       +--rw technology        identityref
       +--rw md-name-string    md-name-string
       +--rw md-name-format?   identityref
       +--rw (md-name)?
       |  +--:(md-name-null)
       |     +--rw md-name-null? empty
       +--rw md-level?           md-level

Фрагмент иерархии данных домена OAM.


Контейнер domains является контейнером верхнего уровня в модуле gen-oam. Внутри этого контейнера поддерживаются отдельные списки для MD, индексируемые ключом md-name-string. Лист md-name-string имеет тип, выведенный из string. Могут включаться дополнительные форматы имен из [IEEE802.1Q] или иных стандартов путем связывания md-name-format с identity-ref. Лист md-name-format указывает формат добавленного md-name. Лист md-name представляется как конструкция choice/case. Это обеспечивает простоту дополнения.

4.2. Конфигурация MA

В данном MD может присутствовать одна или множество ассоциаций MA, представляемых в виде списка и индексируемых ma-name-string. Подобно md-name, могут добавляться форматы имен с помощью identity-ref и добавления подходящих операторов case в ma-name.

module: ietf-connection-oriented-oam
 +--rw domains
    +--rw domain* [technology md-name-string]
       .
       .
       +--rw mas
          +--rw ma* [ma-name-string]
             +--rw ma-name-string          ma-name-string
             +--rw ma-name-format?         identityref
             +--rw (ma-name)?
             |  +--:(ma-name-null)
             |     +--rw ma-name-null?     empty

Фрагмент иерархии MA.


4.3. Конфигурация MEP

В данной MA может быть одна или множество конечных точек обслуживания (MEP), представляемых списком в иерархии данных и индексируемых ключом mep-name.

module: ietf-connection-oriented-oam
 +--rw domains
    +--rw domain* [technology md-name-string]
       +--rw technology                  identityref
       .
       .
       +--rw mas
          +--rw ma* [ma-name-string]
             .
             .
             +--rw mep* [mep-name]
             |  +--rw mep-name         mep-name
             |  +--rw (mep-id)?
             |  |  +--:(mep-id-int)
             |  |     +--rw mep-id-int?      int32
             |  +--rw mep-id-format?   identityref
             |  +--rw (mep-address)?
             |  |  +--:(mac-address)
             |  |  |  +--rw mac-address?     yang:mac-address
             |  |  +--:(ip-address)
             |  |     +--rw ip-address?      inet:ip-address
             .          .
             .          .
             .          .

Фрагмент иерархии MEP.


4.4. Определения RPC

Модель RPC упрощает ввод команд на «сервере» (в данном случае на устройстве, которое должно выполнять команды OAM) и получение откликов. Определенная здесь модель RPC абстрагирует команды OAM независимо от технологии.

Для целей OAM определено несколько команд RPC. В этом параграфе для иллюстрации представлен фрагмент команды проверки непрерывности (CC). Полное описание иерархии данных приведено в параграфе 4.7, а модуль YANG описан в разделе 5.

   module: ietf-connection-oriented-oam
       +--rw domains
             +--rw domain* [technology md-name-string]
             +--rw technology        identityref
       .
       .
   rpcs:
     +---x continuity-check {continuity-check}?
     |  +---w input
     |  |  +---w technology?             identityref
     |  |  +---w md-name-string -> /domains/domain/md-name-string
     |  |  +---w md-level?      -> /domains/domain/md-level
     |  |  +---w ma-name-string -> /domains/domain/mas/ma/ma-name-string
     |  |  +---w cos-id?                 uint8
     |  |  +---w ttl?                    uint8
     |  |  +---w sub-type?               identityref
     |  |  +---w source-mep?    -> /domains/domain/mas/ma/mep/mep-name
     |  |  +---w destination-mep
     |  |  |  +---w (mep-address)?
     |  |  |  |  +--:(mac-address)
     |  |  |  |  |  +---w mac-address?     yang:mac-address
     |  |  |  |  +--:(ip-address)
     |  |  |  |     +---w ip-address?      inet:ip-address
     |  |  |  +---w (mep-id)?
     |  |  |  |  +--:(mep-id-int)
     |  |  |  |     +---w mep-id-int?      int32
     |  |  |  +---w mep-id-format?   identityref
     |  |  +---w count?                  uint32
     |  |  +---w cc-transmit-interval?   time-interval
     |  |  +---w packet-size?            uint32
     |  +--ro output
     |     +--ro (monitor-stats)?
     |        +--:(monitor-null)
     |           +--ro monitor-null?   empty
     +---x continuity-verification {connectivity-verification}?
     |  +---w input
     |  |  +---w md-name-string -> /domains/domain/md-name-string
     |  |  +---w md-level?      -> /domains/domain/md-level
     |  |  +---w ma-name-string -> /domains/domain/mas/ma/ma-name-string
     |  |  +---w cos-id?            uint8
     |  |  +---w ttl?               uint8
     |  |  +---w sub-type?          identityref
     |  |  +---w source-mep?    -> /domains/domain/mas/ma/mep/mep-name
     |  |  +---w destination-mep
     |  |  |  +---w (mep-address)?
     |  |  |  |  +--:(mac-address)
     |  |  |  |  |  +---w mac-address?     yang:mac-address
     |  |  |  |  +--:(ip-address)
     |  |  |  |     +---w ip-address?      inet:ip-address
     |  |  |  +---w (mep-id)?
     |  |  |  |  +--:(mep-id-int)
     |  |  |  |     +---w mep-id-int?      int32
     |  |  |  +---w mep-id-format?   identityref
     |  |  +---w count?             uint32
     |  |  +---w interval?          time-interval
     |  |  +---w packet-size?       uint32
     |  +--ro output
     |     +--ro (monitor-stats)?
     |        +--:(monitor-null)
     |           +--ro monitor-null?   empty
     +---x traceroute {traceroute}?
        +---w input
        |  +---w md-name-string -> /domains/domain/md-name-string
        |  +---w md-level?      -> /domains/domain/md-level
        |  +---w ma-name-string -> /domains/domain/mas/ma/ma-name-string
        |  +---w cos-id?             uint8
        |  +---w ttl?                uint8
        |  +---w command-sub-type?   identityref
        |  +---w source-mep?    -> /domains/domain/mas/ma/mep/mep-name
        |  +---w destination-mep
        |  |  +---w (mep-address)?
        |  |  |  +--:(mac-address)
        |  |  |  |  +---w mac-address?     yang:mac-address
        |  |  |  +--:(ip-address)
        |  |  |     +---w ip-address?      inet:ip-address
        |  |  +---w (mep-id)?
        |  |  |  +--:(mep-id-int)
        |  |  |     +---w mep-id-int?      int32
        |  |  +---w mep-id-format?   identityref
        |  +---w count?              uint32
        |  +---w interval?           time-interval
        +--ro output
           +--ro response* [response-index]
              +--ro response-index     uint8
              +--ro ttl?               uint8
              +--ro destination-mep
              |  +--ro (mep-address)?
              |  |  +--:(mac-address)
              |  |  |  +--ro mac-address?     yang:mac-address
              |  |  +--:(ip-address)
              |  |     +--ro ip-address?      inet:ip-address
              |  +--ro (mep-id)?
              |  |  +--:(mep-id-int)
              |  |     +--ro mep-id-int?      int32
              |  +--ro mep-id-format?   identityref
              +--ro mip {mip}?
              |  +--ro interface?     if:interface-ref
              |  +--ro (mip-address)?
              |     +--:(mac-address)
              |     |  +--ro mac-address?   yang:mac-address
              |     +--:(ip-address)
              |        +--ro ip-address?    inet:ip-address
              +--ro (monitor-stats)?
                 +--:(monitor-null)
                    +--ro monitor-null?      empty

Фрагмент иерархии RPC Call Continuity-Check.

4.5. Уведомления

Уведомления передаются при обнаружении и снятии условий дефекта и содержат имена MD и MA, тип дефекта (существующего в данный момент), идентификатор создавшей уведомление точки (generating-mepid) и сообщение defect-message с дополнительными деталями.

4.6. Статистика мониторинга

Группировка для статистики мониторинга применяется модулями YANG для конкретной технологии, которые дополняют базовую модель данных YANG для предоставления статистики с использованием похожих на OAM сообщений проверки непрерывности (CCM7), например, CCM transmit, CCM receive, CCM error и т. п.

4.7. Иерархия данных OAM

Ниже представлена полная иерархия данных, относящихся к ориентированной на соединения модели данных OAM YANG.

 module: ietf-connection-oriented-oam
     +--rw domains
        +--rw domain* [technology md-name-string]
           +--rw technology        identityref
           +--rw md-name-string    md-name-string
           +--rw md-name-format?   identityref
           +--rw (md-name)?
           |  +--:(md-name-null)
           |     +--rw md-name-null?     empty
           +--rw md-level?         md-level
           +--rw mas
              +--rw ma* [ma-name-string]
                 +--rw ma-name-string    ma-name-string
                 +--rw ma-name-format?   identityref
                 +--rw (ma-name)?
                 |  +--:(ma-name-null)
                 |     +--rw ma-name-null?     empty
                 +--rw (connectivity-context)?
                 |  +--:(context-null)
                 |     +--rw context-null?     empty
                 +--rw cos-id?           uint8
                 +--rw cc-enable?        boolean
                 +--rw mep* [mep-name]
                 |  +--rw mep-name         mep-name
                 |  +--rw (mep-id)?
                 |  |  +--:(mep-id-int)
                 |  |     +--rw mep-id-int?      int32
                 |  +--rw mep-id-format?   identityref
                 |  +--rw (mep-address)?
                 |  |  +--:(mac-address)
                 |  |  |  +--rw mac-address?     yang:mac-address
                 |  |  +--:(ip-address)
                 |  |     +--rw ip-address?      inet:ip-address
                 |  +--rw cos-id?          uint8
                 |  +--rw cc-enable?       boolean
                 |  +--rw session* [session-cookie]
                 |     +--rw session-cookie             uint32
                 |     +--rw destination-mep
                 |     |  +--rw (mep-id)?
                 |     |  |  +--:(mep-id-int)
                 |     |  |     +--rw mep-id-int?      int32
                 |     |  +--rw mep-id-format?   identityref
                 |     +--rw destination-mep-address
                 |     |  +--rw (mep-address)?
                 |     |     +--:(mac-address)
                 |     |     |  +--rw mac-address?   yang:mac-address
                 |     |     +--:(ip-address)
                 |     |        +--rw ip-address?    inet:ip-address
                 |     +--rw cos-id?                    uint8
                 +--rw mip* [name] {mip}?
                    +--rw name           string
                    +--rw interface?     if:interface-ref
                    +--rw (mip-address)?
                       +--:(mac-address)
                       |  +--rw mac-address?   yang:mac-address
                       +--:(ip-address)
                          +--rw ip-address?    inet:ip-address

   rpcs:
     +---x continuity-check {continuity-check}?
     |  +---w input
     |  |  +---w technology?             identityref
     |  |  +---w md-name-string -> /domains/domain/md-name-string
     |  |  +---w md-level?      -> /domains/domain/md-level
     |  |  +---w ma-name-string -> /domains/domain/mas/ma/ma-name-string
     |  |  +---w cos-id?                 uint8
     |  |  +---w ttl?                    uint8
     |  |  +---w sub-type?               identityref
     |  |  +---w source-mep?    -> /domains/domain/mas/ma/mep/mep-name
     |  |  +---w destination-mep
     |  |  |  +---w (mep-address)?
     |  |  |  |  +--:(mac-address)
     |  |  |  |  |  +---w mac-address?     yang:mac-address
     |  |  |  |  +--:(ip-address)
     |  |  |  |     +---w ip-address?      inet:ip-address
     |  |  |  +---w (mep-id)?
     |  |  |  |  +--:(mep-id-int)
     |  |  |  |     +---w mep-id-int?      int32
     |  |  |  +---w mep-id-format?   identityref
     |  |  +---w count?                  uint32
     |  |  +---w cc-transmit-interval?   time-interval
     |  |  +---w packet-size?            uint32
     |  +--ro output
     |     +--ro (monitor-stats)?
     |        +--:(monitor-null)
     |           +--ro monitor-null?   empty
     +---x continuity-verification {connectivity-verification}?
     |  +---w input
     |  |  +---w md-name-string -> /domains/domain/md-name-string
     |  |  +---w md-level?      -> /domains/domain/md-level
     |  |  +---w ma-name-string -> /domains/domain/mas/ma/ma-name-string
     |  |  +---w cos-id?            uint8
     |  |  +---w ttl?               uint8
     |  |  +---w sub-type?          identityref
     |  |  +---w source-mep?    -> /domains/domain/mas/ma/mep/mep-name
     |  |  +---w destination-mep
     |  |  |  +---w (mep-address)?
     |  |  |  |  +--:(mac-address)
     |  |  |  |  |  +---w mac-address?     yang:mac-address
     |  |  |  |  +--:(ip-address)
     |  |  |  |     +---w ip-address?      inet:ip-address
     |  |  |  +---w (mep-id)?
     |  |  |  |  +--:(mep-id-int)
     |  |  |  |     +---w mep-id-int?      int32
     |  |  |  +---w mep-id-format?   identityref
     |  |  +---w count?             uint32
     |  |  +---w interval?          time-interval
     |  |  +---w packet-size?       uint32
     |  +--ro output
     |     +--ro (monitor-stats)?
     |        +--:(monitor-null)
     |           +--ro monitor-null?   empty
     +---x traceroute {traceroute}?
        +---w input
        |  +---w md-name-string -> /domains/domain/md-name-string
        |  +---w md-level?      -> /domains/domain/md-level
        |  +---w ma-name-string -> /domains/domain/mas/ma/ma-name-string
        |  +---w cos-id?             uint8
        |  +---w ttl?                uint8
        |  +---w command-sub-type?   identityref
        |  +---w source-mep?    -> /domains/domain/mas/ma/mep/mep-name
        |  +---w destination-mep
        |  |  +---w (mep-address)?
        |  |  |  +--:(mac-address)
        |  |  |  |  +---w mac-address?     yang:mac-address
        |  |  |  +--:(ip-address)
        |  |  |     +---w ip-address?      inet:ip-address
        |  |  +---w (mep-id)?
        |  |  |  +--:(mep-id-int)
        |  |  |     +---w mep-id-int?      int32
        |  |  +---w mep-id-format?   identityref
        |  +---w count?              uint32
        |  +---w interval?           time-interval
        +--ro output
           +--ro response* [response-index]
              +--ro response-index     uint8
              +--ro ttl?               uint8
              +--ro destination-mep
              |  +--ro (mep-address)?
              |  |  +--:(mac-address)
              |  |  |  +--ro mac-address?     yang:mac-address
              |  |  +--:(ip-address)
              |  |     +--ro ip-address?      inet:ip-address
              |  +--ro (mep-id)?
              |  |  +--:(mep-id-int)
              |  |     +--ro mep-id-int?      int32
              |  +--ro mep-id-format?   identityref
              +--ro mip {mip}?
              |  +--ro interface?     if:interface-ref
              |  +--ro (mip-address)?
              |     +--:(mac-address)
              |     |  +--ro mac-address?   yang:mac-address
              |     +--:(ip-address)
              |        +--ro ip-address?    inet:ip-address
              +--ro (monitor-stats)?
                 +--:(monitor-null)
                    +--ro monitor-null?      empty

   notifications:
     +---n defect-condition-notification
     |  +--ro technology?         identityref
     |  +--ro md-name-string -> /domains/domain/md-name-string
     |  +--ro ma-name-string -> /domains/domain/mas/ma/ma-name-string
     |  +--ro mep-name?      -> /domains/domain/mas/ma/mep/mep-name
     |  +--ro defect-type?        identityref
     |  +--ro generating-mepid
     |  |  +--ro (mep-id)?
     |  |  |  +--:(mep-id-int)
     |  |  |     +--ro mep-id-int?      int32
     |  |  +--ro mep-id-format?   identityref
     |  +--ro (defect)?
     |     +--:(defect-null)
     |     |  +--ro defect-null?        empty
     |     +--:(defect-code)
     |        +--ro defect-code?        int32
     +---n defect-cleared-notification
        +--ro technology?         identityref
        +--ro md-name-string -> /domains/domain/md-name-string
        +--ro ma-name-string -> /domains/domain/mas/ma/ma-name-string
        +--ro mep-name?      -> /domains/domain/mas/ma/mep/mep-name
        +--ro defect-type?        identityref
        +--ro generating-mepid
        |  +--ro (mep-id)?
        |  |  +--:(mep-id-int)
        |  |     +--ro mep-id-int?      int32
        |  +--ro mep-id-format?   identityref
        +--ro (defect)?
           +--:(defect-null)
           |  +--ro defect-null?        empty
           +--:(defect-code)
              +--ro defect-code?        int32

Иерархия OAM.

5. Модуль OAM YANG

Этот модуль импортирует определения типов (typedef) из [RFC6991] и [RFC8343], а также ссылается на [RFC6371], [RFC6905] и [RFC7276].

   <CODE BEGINS> file "ietf-connection-oriented-oam@2019-04-16.yang"
module ietf-connection-oriented-oam {
  yang-version 1.1;
  namespace "urn:ietf:params:xml:ns:yang:ietf-connection-oriented-oam";
  prefix co-oam;

  import ietf-yang-types {
    prefix yang;
  }
  import ietf-inet-types {
    prefix inet;
  }
  import ietf-interfaces {
    prefix if;
  }

  organization
    "IETF LIME Working Group";
  contact
    "WG Web:    http://datatracker.ietf.org/wg/lime 
     WG List:   <mailto:lime@ietf.org> 
     Editor:    Deepak Kumar <dekumar@cisco.com> 
     Editor:    Qin Wu <bill.wu@huawei.com> 
     Editor:    Michael Wang <wangzitao@huawei.com>"; 
  description
    "Этот модуль YANG определяет базовую конфигурацию,
     статистику и RPC для ориентированных на соединения OAM,
     применяемых в IETF независимо от протокола. Абстракция
     функционального уровня не зависит от модели YANG.
     Предполагается, что каждый протокол отображает 
     соответствующие абстракции на их естественный формат.
     Каждый протокол может расширять модель YANG, определенную 
     здесь, для решения специфических задач.

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

     Распространение и использование модуля в исходном или двоичном
     формате, с изменениями или без таковых разрешено в соответствии 
     с условиями лицензии Simplified BSD License, изложенными в
     разделе 4.c документа IETF Trust's Legal Provisions применительно
     к документам IETF (http://trustee.ietf.org/license-info). 

     Эта версия модуля YANG является частью RFC 8531, где правовые
     аспекты изложены более полно.";

  revision 2019-04-16 {
    description
      "Первый выпуск.";
    reference
      "RFC 8531: Generic YANG Data Model for Connection-
       Oriented Operations, Administration, and Maintenance (OAM)
       Protocols";
  }

  feature connectivity-verification {
    description
      "Это свойство указывает, что сервер поддерживает команду
       OAM для проверки связности и возвращает отклик. Серверы,
       не анонсирующие эту возможность, не будут поддерживать
       выполнение команды проверки связности или модели RPC для
       такой команды.";
  }

  feature continuity-check {
    description
      "Это свойство указывает, что сервер поддерживает команду
       OAM CC и возвращает отклик. Серверы, не анонсирующие
       эту возможность, не будут поддерживать команду CC или 
       модель RPC для нее.";
  }

  feature traceroute {
    description
      "Это свойство указывает, что сервер поддерживает команду
       OAM traceroute и возвращает отклик. Серверы, не 
       анонсирующие  эту возможность, не будут поддерживать 
       команду traceroute или модель RPC для traceroute.";
  }

  feature mip {
    description
      "Это свойство показывает, что MIP требует явной настройки.";
  }
  identity technology-types {
    description
      "Базовое отождествление типов технологии (TRILL, MPLS-TP и т. п.).";
  }

  identity command-sub-type {
    description
      "Определяет субтипы различных команд RPC, например,
       TRILL OAM как указано в RFC 6905. В большинстве
       случаев это не обязательно.";
    reference
      "RFC 6905: Requirements for OAM in Transparent
       Interconnection of Lots of Links (TRILL)";
  }

  identity on-demand {
    base command-sub-type;
    description
      "Активизация по запросу указывает, что инструмент запускается
       вручную для поиска соответствующей аномалии.
       OAM по запросу требует лишь временной настройки конфигурации.";
    reference
      "RFC 7276: An Overview of Operations, Administration, and
       Maintenance (OAM) Tools";
  }

  identity proactive {
    base command-sub-type;
    description
      "Проактивный режим показывает, что инструмент работает непрерывно,
       сообщения передаются периодически, а ошибкой считается отсутствие 
       некоторого числа сообщения. Проактивный режим требует постоянной
       настройки конфигурации.";
    reference
      "RFC 7276: An Overview of Operations, Administration, and
       Maintenance (OAM) Tools";
  }

  identity name-format {
    description
      "Определяет формат имени, отличающийся от CFM (IEEE 802.1Q). 
       Предполагается, что формат имени является идентификационной
       ссылкой, которая будет расширена новыми типами.";
  }

  identity name-format-null {
    base name-format;
    description
      "Определяет формат как пустой (null).";
  }

  identity identifier-format {
    description
      "Отождествление identifier-format может быть дополнено для
       определения других форматов, применяемых в MEP-ID и пр.";
  }

  identity identifier-format-integer {
    base identifier-format;
    description
      "Определяет identifier-format как целое число.";
  }

  identity defect-types {
    description
      "Определяет различные типы дефектов, например,
       RDI8, потеря непрерывности.";
  }

  identity rdi {
    base defect-types;
    description
      "RDI указывает общее состояние точек MEP.";
  }

  identity remote-mep-defect {
    base defect-types;
    description
      "Указывает, что одна или несколько удаленных MEP
       сообщили об отказе.";
  }

  identity loss-of-continuity {
    base defect-types;
    description
      "Указывает, что в течение заданного интервала не было пакетов CC
       OAM от удаленной MEP (а в случае CV, это включает требование
       наличия уникального, зависящего от технологии идентификатора MEP).";
    reference
      "RFC 6371: Operations, Administration, and Maintenance
       Framework for MPLS-Based Transport Networks";
  }

  identity cv-defect {
    base defect-types;
    description
      "Этой функции следует поддерживать мониторинг между MEP, а
       также между MEP и MIP. При выполнении CV сообщения CC и
       CC-V9 должны однозначно указывать проверяемую MEG и
       MEP, передающую сообщение.";
    reference
      "RFC 6371: Operations, Administration, and Maintenance
       Framework for MPLS-Based Transport Networks";
  }

  identity invalid-oam-defect {
    base defect-types;
    description
      "Указывает, что было получено 1 или несколько непригодных 
       сообщений OAM, а интервал передачи сообщений OAM еще не
       истек (3,5 раза).";
  }

  identity cross-connect-defect {
    base defect-types;
    description
      "Указывает, что был получен 1 или несколько дефектов кросс-
       соединений (например, идентификатор сервиса не соответствует
       VLAN), а интервал передачи сообщений OAM еще не истек (3,5 раза).";
  }

  typedef mep-name {
    type string;
    description
      "Базовое административное имя для MEP.";
  }

  typedef time-interval {
    type decimal64 {
      fraction-digits 2;
    }
    units "milliseconds";
    description
      "Временной интервал между пакетами в мсек, который следует
       задавать не меньше 0. Нулевой интервал означает отсутствие
       передачи пакетов.";
  }

  typedef md-name-string {
    type string;
    description
      "Базовое административное имя для MD.";
  }

  typedef ma-name-string {
    type string;
    description
      "Базовое административное имя для MA.";
  }

  typedef oam-counter32 {
    type yang:zero-based-counter32;
    description
      "Определяет 32-битовый счетчик для OAM.";
  }

  typedef md-level {
    type uint32 {
      range "0..255";
    }
    description
      "Уровень домена обслуживания (MD). Некоторые протоколы 
       могут ограничивать уровень (например, от 0 до 7).";
  }

  grouping maintenance-domain-reference {
    description
      "Эта группировка однозначно указывает MD.";
    leaf maintenance-domain {
      type leafref {
        path "/co-oam:domains/co-oam:domain/co-oam:md-name-string";
      }
      description
        "Указание конкретного MD.";
    }
  }

  grouping maintenance-association-reference {
    description
      "Эта группировка однозначно указывает MA и 
       состоит из leafref maintenance-domain-reference 
       и maintenance-association.";
    uses maintenance-domain-reference;
    leaf maintenance-association {
      type leafref {
        path "/co-oam:domains/co-oam:domain[co-oam:md-name-string "
           + "= current()/../maintenance-domain]/co-oam:mas"
           + "/co-oam:ma/co-oam:ma-name-string";
      }
      description
        "Указание конкретной MA.";
    }
  }

  grouping maintenance-association-end-point-reference {
    description
      "Эта группировка однозначно указывает MA и 
       состоит из листьев-ссылок 
       maintenance-association-reference и
       a maintenance-association-end-point.";
    uses maintenance-association-reference;
    leaf maintenance-association-end-point {
      type leafref {
        path "/co-oam:domains/co-oam:domain[co-oam:md-name-string "
           + "= current()/../maintenance-domain]/co-oam:mas"
           + "/co-oam:ma[co-oam:ma-name-string = "
           + "current()/../maintenance-association]"
           + "/co-oam:mep/co-oam:mep-name";
      }
      description
        "Указание конкретной MEP.";
    }
  }

  grouping time-to-live {
    leaf ttl {
      type uint8;
      description
        "Время жизни.";
    }
    description
      "Группировка TTL.";
  }

  grouping defect-message {
    choice defect {
      case defect-null {
        description
          "Подстановка для случаев ненужности статуса дефектов.";
        leaf defect-null {
          type empty;
          description
            "Дефекты не определены и будут определяться в моделях
             для конкретных технологий.";
        }
      }
      case defect-code {
        description
          "Подстановка для отображения кода дефекта.";
        leaf defect-code {
          type int32;
          description
            "Значение кода дефекта зависит от технологии.";
        }
      }
      description
        "Варианты сообщения о дефекте.";
    }
    description
      "Сообщение о дефекте.";
  }

  grouping mep-address {
    choice mep-address {
      default "ip-address";
      case mac-address {
        leaf mac-address {
          type yang:mac-address;
          description
            "MAC-адрес.";
        }
        description
          "Адресация MEP на основе MAC-адреса.";
      }
      case ip-address {
        leaf ip-address {
          type inet:ip-address;
          description
            "IP-адрес.";
        }
        description
          "Адресация MEP на основе IP-адреса.";
      }
      description
        "Адресация MEP.";
    }
    description
      "Группировка для адреса MEP";
  }

  grouping mip-address {
    choice mip-address {
      default "ip-address";
      case mac-address {
        leaf mac-address {
          type yang:mac-address;
          description
            "MAC-адрес точки MIP";
        }
        description
          "Адресация MIP на основе MAC-адреса.";
      }
      case ip-address {
        leaf ip-address {
          type inet:ip-address;
          description
            "IP-адрес.";
        }
        description
          "Адресация MIP на основе IP-адреса .";
      }
      description
        "Адресация MIP.";
    }
    description
      "Адрес MIP.";
  }

  grouping maintenance-domain-id {
    description
      "Группировка, содержащая листья, достаточные 
       для идентификации MD.";
    leaf technology {
      type identityref {
        base technology-types;
      }
      mandatory true;
      description
        "Определяет технологию.";
    }
    leaf md-name-string {
      type md-name-string;
      mandatory true;
      description
        "Определяет базовое административное имя MD.";
    }
  }

  grouping md-name {
    leaf md-name-format {
      type identityref {
        base name-format;
      }
      description
        "Формат имени MD.";
    }
    choice md-name {
      case md-name-null {
        leaf md-name-null {
          when "derived-from-or-self(../md-name-format,"
             + "'name-format-null')" {
            description
              "Формат имени MD совпадает с пустым форматом.";
          }
          type empty;
          description
            "Пустое имя MD.";
        }
      }
      description
        "Имя MD.";
    }
    description
      "Имя MD.";
  }

  grouping ma-identifier {
    description
      "Группировка с листьями, достаточными для указания MA.";
    leaf ma-name-string {
      type ma-name-string;
      description
        "Строка имени MA.";
    }
  }

  grouping ma-name {
    description
      "MA name.";
    leaf ma-name-format {
      type identityref {
        base name-format;
      }
      description
        "Формат имени MA.";
    }
    choice ma-name {
      case ma-name-null {
        leaf ma-name-null {
          when "derived-from-or-self(../ma-name-format,"
             + "'name-format-null')" {
            description
              "MA.";
          }
          type empty;
          description
            "Пусто";
        }
      }
      description
        "Имя MA.";
    }
  }

  grouping mep-id {
    choice mep-id {
      default "mep-id-int";
      case mep-id-int {
        leaf mep-id-int {
          type int32;
          description
            "MEP ID в целочисленном формате.";
        }
      }
      description
        "MEP ID.";
    }
    leaf mep-id-format {
      type identityref {
        base identifier-format;
      }
      description
        "Формат MEP ID.";
    }
    description
      "MEP ID.";
  }

  grouping mep {
    description
      "Определяет элементы в MEP.";
    leaf mep-name {
      type mep-name;
      mandatory true;
      description
        "Базовое административное имя MEP.";
    }
    uses mep-id;
    uses mep-address;
  }

  grouping monitor-stats {
    description
      "Группировка для статистики мониторинга, дополняемая 
       другими при использовании этой компоненты.";
    choice monitor-stats {
      default "monitor-null";
      case monitor-null {
        description
          "Заменитель для случаев ненужности статистики 
           мониторинга.";
        leaf monitor-null {
          type empty;
          description
            "Статистика мониторинга не определена.";
        }
      }
      description
        "Определяет состояния монитора.";
    }
  }

  grouping connectivity-context {
    description
      "Группировка, определяющая контекст связности для MA,
       например, LSP для MPLS-TP. Будет дополняться каждым
       протоколом, использующим компоненту.";
    choice connectivity-context {
      default "context-null";
      case context-null {
        description
          "Замена на случая ненужности контекста.";
        leaf context-null {
          type empty;
          description
            "Контекст не определен.";
        }
      }
      description
        "Контекст связности.";
    }
  }

  grouping cos {
    description
      "Группировка для приоритета в отправляемых пакетах,
       например, в поле CoS для MPLS-TP.";
    leaf cos-id {
      type uint8;
      description
        "Идентификатор класса обслуживания (CoS).";
    }
  }

  grouping mip-grouping {
    uses mip-address;
    description
      "Группировка для настройки MIP.";
  }

  container domains {
    description
      "Содержит относящиеся к конфигурации данные. Внутри
       контейнера имеется список сбойных доменов. Каждый
       домен имеет список MA.";
    list domain {
      key "technology md-name-string";
      description
        "Определяет список доменов в модуле 
         ietf-connection-oriented-oam.";
      uses maintenance-domain-id;
      uses md-name;
      leaf md-level {
        type md-level;
        description
          "Определяет уровень MD.";
      }
      container mas {
        description
          "Содержит относящиеся к конфигурации данные. Внутри
           контейнера имеется список MA, каждая из которых
           имеет список MEP.";
        list ma {
          key "ma-name-string";
          uses ma-identifier;
          uses ma-name;
          uses connectivity-context;
          uses cos {
            description
              "Принятый по умолчанию класс обслуживания для MA.
               Список может быть переписан для отдельных MEP,
               сессий или операций.";
          }
          leaf cc-enable {
            type boolean;
            description
              "Указывает включена ли проверка CC.";
          }
          list mep {
            key "mep-name";
            description
              "Содержит список MEP.";
            uses mep;
            uses cos;
            leaf cc-enable {
              type boolean;
              description
                "Указывает включена ли проверка CC.";
            }
            list session {
              key "session-cookie";
              description
                "Сеанс мониторинга с конкретной удаленной точкой MEP.
                 В зависимости от протокола может представлять сообщения
                 CC от удаленной MEP (если протокол применяет групповые
                 CC), целевая точка, куда передаются индивидуальные
                 эхо-запросы CC или откуда принимаются отклики (если
                 протокол использует механизм запрос-отклик с
                 индивидуальной адресацией).";
              leaf session-cookie {
                type uint32;
                description
                  "Cookie для идентификации сессий при наличии множества
                   MEP или множества сессий с одной удаленной точкой MEP.";
              }
              container destination-mep {
                uses mep-id;
                description
                  "Целевая точка MEP.";
              }
              container destination-mep-address {
                uses mep-address;
                description
                  "Адрес целевой точки MEP.";
              }
              uses cos;
            }
          }
          list mip {
            if-feature "mip";
            key "name";
            leaf name {
              type string;
              description
                "Идентификатор точки MIP.";
            }
            leaf interface {
              type if:interface-ref;
              description
                "Интерфейс.";
            }
            uses mip-grouping;
            description
              "List for MIP.";
          }
          description
            "Список ассоциаций MA.";
        }
      }
    }
  }

  notification defect-condition-notification {
    description
      "При обнаружении дефекта передается такое уведомление.";
    leaf technology {
      type identityref {
        base technology-types;
      }
      description
        "Технология.";
    }
    leaf md-name-string {
      type leafref {
        path "/domains/domain/md-name-string";
      }
      mandatory true;
      description
        "Указывает MD, к которому относится дефект.";
    }
    leaf ma-name-string {
      type leafref {
        path "/domains/domain/mas/ma/ma-name-string";
      }
      mandatory true;
      description
        "Указывает MA, с которой связан дефект.";
    }
    leaf mep-name {
      type leafref {
        path "/domains/domain/mas/ma/mep/mep-name";
      }
      description
        "Указывает точку MEP, увидевшую дефект.";
    }
    leaf defect-type {
      type identityref {
        base defect-types;
      }
      description
        "Существующие в данный момент дефекты указанной MEP.";
    }
    container generating-mepid {
      uses mep-id;
      description
        "Указывает кто создал уведомление о дефекте или 0,
         если точка не известна.";
    }
    uses defect-message {
      description
        "Сообщение о дефекте с допонительными детялями.";
    }
  }

  notification defect-cleared-notification {
    description
      "Сообщение, передаваемое при устранении дефекта.";
    leaf technology {
      type identityref {
        base technology-types;
      }
      description
        "Технология.";
    }
    leaf md-name-string {
      type leafref {
        path "/domains/domain/md-name-string";
      }
      mandatory true;
      description
        "Указывает MD, к которому относился дефект.";
    }
    leaf ma-name-string {
      type leafref {
        path "/domains/domain/mas/ma/ma-name-string";
      }
      mandatory true;
      description
        "Указывает MA, с которой был связан дефект.";
    }
    leaf mep-name {
      type leafref {
        path "/domains/domain/mas/ma/mep/mep-name";
      }
      description
        "Указывает точку MEP, увидевшую дефект.";
    }
    leaf defect-type {
      type identityref {
        base defect-types;
      }
      description
        "Существующие в данный момент дефекты указанной MEP.";
    }
    container generating-mepid {
      uses mep-id;
      description
        "Указывает кто создал уведомление о дефекте или 0,
         если точка не известна.";
    }
    uses defect-message {
      description
        "Сообщение о дефекте с допонительными детялями.";
    }
  }

  rpc continuity-check {
    if-feature "continuity-check";
    description
      "Генерирует CC, как указано в таблице 4 RFC 7276.";
    input {
      leaf technology {
        type identityref {
          base technology-types;
        }
        description
          "Технология.";
      }
      leaf md-name-string {
        type leafref {
          path "/domains/domain/md-name-string";
        }
        mandatory true;
        description
          "Указывает MD, к которому относится дефект.";
      }
      leaf md-level {
        type leafref {
          path "/domains/domain/md-level";
        }
        description
          "Уровень MD.";
      }
      leaf ma-name-string {
        type leafref {
          path "/domains/domain/mas/ma/ma-name-string";
        }
        mandatory true;
        description
          "Указывает MA, с которой связан дефект.";
      }
      uses cos;
      uses time-to-live;
      leaf sub-type {
        type identityref {
          base command-sub-type;
        }
        description
          "Определяет различные типы команд.";
      }
      leaf source-mep {
        type leafref {
          path "/domains/domain/mas/ma/mep/mep-name";
        }
        description
          "Исходная точка MEP.";
      }
      container destination-mep {
        uses mep-address;
        uses mep-id {
          description
            "Применимо лишь в случае, когда целью является MEP.";
        }
        description
          "Целевая точка MEP.";
      }
      leaf count {
        type uint32;
        default "3";
        description
          "Число передаваемых сообщений CC.";
      }
      leaf cc-transmit-interval {
        type time-interval;
        description
          "Интервал времени между эхо-запросами.";
      }
      leaf packet-size {
        type uint32 {
          range "64..10000";
        }
        description
          "Размер пакетов CC в октетах.";
      }
    }
    output {
      uses monitor-stats {
        description
          "Статистика CC.";
      }
    }
  }

  rpc continuity-verification {
    if-feature "connectivity-verification";
    description
      "Генерация CV в соответствии с таблицей 4 в RFC 7276.";
    input {
      leaf md-name-string {
        type leafref {
          path "/domains/domain/md-name-string";
        }
        mandatory true;
        description
          "Указывает MD, к которому относится дефект.";
      }
      leaf md-level {
        type leafref {
          path "/domains/domain/md-level";
        }
        description
          "Уровень MD.";
      }
      leaf ma-name-string {
        type leafref {
          path "/domains/domain/mas/ma/ma-name-string";
        }
        mandatory true;
        description
          "Указывает MA, с которой связан дефект.";
      }
      uses cos;
      uses time-to-live;
      leaf sub-type {
        type identityref {
          base command-sub-type;
        }
        description
          "Определяет различные типы команд.";
      }
      leaf source-mep {
        type leafref {
          path "/domains/domain/mas/ma/mep/mep-name";
        }
        description
          "MEP-источник.";
      }
      container destination-mep {
        uses mep-address;
        uses mep-id {
          description
            "Применимо лишь в случае, когда целью является MEP.";
        }
        description
          "Целевая точка MEP.";
      }
      leaf count {
        type uint32;
        default "3";
        description
          "Число передаваемых сообщений CV.";
      }
      leaf interval {
        type time-interval;
        description
          "Интервал времени между эхо-запросами.";
      }
      leaf packet-size {
        type uint32 {
          range "64..10000";
        }
        description
          "Размер пакетов CV в октетах.";
      }
    }
    output {
      uses monitor-stats {
        description
          "Статистика CV.";
      }
    }
  }

  rpc traceroute {
    if-feature "traceroute";
    description
      "Генерирует Traceroute или Path Trace и отклики.
       В RFC 7276 указываются имена инструментов - для MPLS-TP OAM
       - это Route Tracing, а для TRILL OAM - Path Tracing. Начинает
       с TTL = 1 и увеличивает значение на 1 для каждого интервала, 
       пока не будет достигнут адресат или максимальное значение TTL.";
    input {
      leaf md-name-string {
        type leafref {
          path "/domains/domain/md-name-string";
        }
        mandatory true;
        description
          "Указывает MD, к которому относится дефект.";
      }
      leaf md-level {
        type leafref {
          path "/domains/domain/md-level";
        }
        description
          "Уровень MD.";
      }
      leaf ma-name-string {
        type leafref {
          path "/domains/domain/mas/ma/ma-name-string";
        }
        mandatory true;
        description
          "Указывает MA, с которой связан дефект.";
      }
      uses cos;
      uses time-to-live;
      leaf command-sub-type {
        type identityref {
          base command-sub-type;
        }
        description
          "Определяет различные типы команд.";
      }
      leaf source-mep {
        type leafref {
          path "/domains/domain/mas/ma/mep/mep-name";
        }
        description
          "MEP-источник.";
      }
      container destination-mep {
        uses mep-address;
        uses mep-id {
          description
            "Применимо лишь в случае, когда целью является MEP.";
        }
        description
          "Целевая точка MEP.";
      }
      leaf count {
        type uint32;
        default "1";
        description
          "Число передаваемых проб traceroute. В протоколах, где 
           передаются раздельные сообщения для каждого TTL, - это
           число пакетов, переданных с каждым значением TTL.";
      }
      leaf interval {
        type time-interval;
        description
          "Интервал времени между эхо-запросами.";
      }
    }
    output {
      list response {
        key "response-index";
        leaf response-index {
          type uint8;
          description
            "Произвольный индекс для отклика. В протоколах, где 
             гарантируется лишь один отклик для каждого TTL, 
             значение TTL может служить индексом откликов.";
        }
        uses time-to-live;
        container destination-mep {
          description
            "Точка MEP, от которой получен отклик.";
          uses mep-address;
          uses mep-id {
            description
              "Применимо лишь в случае, когда целью является MEP.";
          }
        }
        container mip {
          if-feature "mip";
          leaf interface {
            type if:interface-ref;
            description
              "Интерфейс MIP.";
          }
          uses mip-address;
          description
            "Точка MIP, отвечающая на traceroute";
        }
        uses monitor-stats {
          description
            "Статистика traceroute.";
        }
        description
          "Список откликов.";
      }
    }
  }
}

   <CODE ENDS>

6. Базовый режим

Базовый режим (принят по умолчанию, см. раздел 4) определяет принятую по умолчанию конфигурацию, которая должна присутствовать в устройстве, соответствующем данному документу. Base Mode позволяет пользователям получить опыт настройки «в одно касание». Некоторые параметры требуют задаваемого настройкой определения.

6.1. Адрес MEP

В базовом режиме работы адресом MEP по умолчанию служит IP-адрес интерфейса, где размещается MEP.

6.2. MEP ID для базового режима

В базовом режиме каждое устройство создает одну точку MEP, связанную с виртуальным портом OAM без физического уровня (NULL PHY). MEP-ID для этой точки MEP имеет значение 0 (см. разъяснение ниже).

MEP-ID по умолчанию является 2-октетным полем. Оно не применяется в линии (проводе) кроме случаев использования CCM. Важно иметь метод автоматического выведения MEP-ID для базового режима без участия пользователя. IP-адрес не подходит для этого, поскольку поле MEP-ID имеет меньший размер. Для базового режима работы по умолчанию выбрано значение MEP-ID = 0.

Пакеты CCM используют MEP-ID в поле данных (payload). CCM недопустимо применять в базовом режиме, поэтому CCM должны быть запрещены в MA для Base Mode.

Если CCM требуется, пользователи должны настроить отдельную MA и присвоить уникальные идентификаторы соответствующим MEP.

CFM [IEEE802.1Q] определяет MEP-ID как целое число без знака со значением от 1 до 8191. В этом документе предлагается расширить диапазон значений до 0 — 65535. Значение 0 резервируется для MEP-ID в базовом режиме работы и его недопустимо применять в других случаях.

6.3. Ассоциация обслуживания (MA)

Идентификаторы MA (MA-ID) [IEEE802.1Q] имеют гибкий формат и включают две части — имя MD и краткое имя MA. В базовом режиме работы значением имени MD должна быть строка символов «GenericBaseMode» (включая кавычки). Формат Short MA Name включает 2-октетный целочисленный формат (значение 3 в поле Short MA Format [IEEE802.1Q]) и имя Short MA со значением 65532 (0xFFFC).

7. Применимость модели YANG для OAM на основе соединений

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

В этом разделе показана возможность применения ориентированной на соединения модели данных YANG OAM для таких технологий, как TRILL и MPLS-TP. Отметим, что здесь преведено лишь несколько фрагментов связанных с технологиями расширений. Полные расширения модели должны быть разработаны в соответствующих протоколах.

7.1. Расширение базовой модели данных YANG для TRILL OAM

Модуль TRILL OAM YANG [TRILL-YANG-OAM] является дополнением ориентированного на соединения модуля OAM для настройки и RPC.

Кроме того, для модуля TRILL OAM YANG нужна также поддержка базового модуля TRILL ([TRILL-YANG]), поскольку они тесно связаны между собой.

Конфигурационные расширения для ориентированного на соединения модуля OAM включают расширение для настройки MD, типа технологии, настройки MA, Connectivity-Context, настройки MEP и ECMP. В расширении RPC команды проверки связности и обнаружения пути дополняются связанными с TRILL параметрами.

7.1.1. Расширение MD Configuration

Конфигурационные параметры уровня MD являются управляющей информацией, которая может наследоваться в модели TRILL OAM с использованием значений базовой модели в качестве принятых по умолчанию. Например, в качестве имени домена может быть задано значение area-ID для случая TRILL OAM. Кроме того, на уровне MD (т. е. корневом) узел данных домена может быть дополнен типом технологии.

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

7.1.1.1. Расширение Technology Type

В базовой модели не определен тип технологии TRILL. Поэтому требуется расширение для определения этого типа в модели TRILL OAM. Тип trill определен как элемент, дополняющий базовое определение technology-types в модели.

      identity trill{
       base co-oam:technology-types;
       description
        "trill type";
      }

7.1.2. Расширение MA Configuration

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

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

7.1.2.1. Расширение Connectivity-Context

В TRILL OAM примером контекста связности является 12-битовое значение VLAN ID или 24-битовое значение Fine-Grained Label. Ориентированная на соединения базовая модель включает заменитель для context-id. Это позволяет другим технологиям легко дополнить заменитель и включить связанное с технологией расширение. Приведенный ниже фрагмент показывает пример дополнения контекста связности путем включения VLAN ID или Fine-Grained Label.

      augment /co-oam:domains/co-oam:domain
   /co-oam:mas/co-oam:ma/co-oam:connectivity-context:
            +--:(connectivity-context-vlan)
            |  +--rw connectivity-context-vlan?   vlan
            +--:(connectivity-context-fgl)
               +--rw connectivity-context-fgl?    fgl

7.1.3. Расширение MEP Configuration

Определение конфигурации MEP в базовой модели уже поддерживает настройку интерфейса MEP с адресом MAC или IP. Кроме того, адрес MEP можно представить с помощью 2-октетного RBridge Nickname в TRILL OAM. Поэтому модель TRILL OAM дополняет конфигурацию MEP базовой модели дополнительной возможностью задания адреса.

   augment /co-oam:domains/co-oam:domain
   /co-oam:mas/co-oam:ma/co-oam:mep/co-oam:mep-address:
            +--:( mep-address-trill)
            |  +--rw mep-address-trill?  tril-rb-nickname

В дополнение к этому на уровне MEP (т. е. третьем) узел данных MEP может быть дополнен расширением ECMP.

7.1.3.1. Расширение ECMP

Поскольку TRILL поддерживает ECMP при выборе пути, энтропия потока в TRILL определяется как 96-октетное поле в Layer-Independent OAM Management расширения модели LIME10 для TRILL OAM. Фрагмент дерева приведен ниже.

      augment /co-oam:domains/co-oam:domain
   /co-oam:mas/co-oam:ma/co-oam:mep:
               +--rw flow-entropy-trill?   flow-entropy-trill
      augment /co-oam:domains/co-oam:domain
   /co-oam:mas/co-oam:ma/co-oam:mep/co-oam:session:
               +--rw flow-entropy-trill?   flow-entropy-trill

7.1.4. Расширение RPC

В модели данных TRILL OAM YANG команды RPC для проверки связности и обнаружения пути предполагаются с учетом требований TRILL. Приведенный ниже фрагмент описывает расширение TRILL OAM RPC.

      augment /co-oam:continuity-check/co-oam:input:
            +--ro (out-of-band)?
            |  +--:(ipv4-address)
            |  |  +--ro ipv4-address?      inet:ipv4-address
            |  +--:(ipv6-address)
            |  |  +--ro ipv6-address?      inet:ipv6-address
            |  +--:(trill-nickname)
            |     +--ro trill-nickname?    tril-rb-nickname
            +--ro diagnostic-vlan?   boolean
      augment /co-oam:continuity-check/co-oam:input:
               +--ro flow-entropy-trill?   flow-entropy-trill
      augment /co-oam:continuity-check/co-oam:output:
            +--ro upstream-rbridge?   tril-rb-nickname
            +--ro next-hop-rbridge*   tril-rb-nickname
      augment /co-oam:path-discovery/co-oam:input:
            +--ro (out-of-band)?
            |  +--:(ipv4-address)
            |  |  +--ro ipv4-address?      inet:ipv4-address
            |  +--:(ipv6-address)
            |  |  +--ro ipv6-address?      inet:ipv6-address
            |  +--:(trill-nickname)
            |     +--ro trill-nickname?    tril-rb-nickname
            +--ro diagnostic-vlan?   boolean
      augment /co-oam:path-discovery/co-oam:input:
               +--ro flow-entropy-trill?   flow-entropy-trill
      augment /co-oam:path-discovery/co-oam:output/co-oam:response:
            +--ro upstream-rbridge?   tril-rb-nickname
            +--ro next-hop-rbridge*   tril-rb-nickname

7.2. Расширение базовой модели YANG для MPLS-TP OAM

Модуль MPLS-TP OAM YANG может дополнять ориентированный на соединения модуль OAM некоторыми детялями, связанными с технологией. В [MPLS-TP-OAM-YANG] представлена модель данных YANG для MPLS-TP OAM.

Конфигурационные расширения базовой модели OAM включают расширение для настройки MD, тип и субтип технологии, расширения для настройки MA и MEP.

7.2.1. Расширение MD Configuration

Конфигурационные параметры уровня MD являются управляющей информацией, которая может наследоваться в модели MPLS-TP OAM с использованием значений базовой модели в качестве принятых по умолчанию. Например, в качестве имени домена может быть задано значение area-ID или номер автономной системы провайдера (ASN11) [RFC6370] для случая MPLS-TP OAM. Кроме того, на уровне MD (т. е. корневом) узел данных домена может быть дополнен типом и субтипом технологии.

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

7.2.1.1. Расширение Technology Type

Тип технологии MPLS-TP не определен в базовой модели, поэтому требуется расширение для определения этого типа в модели MPLS-TP OAM. Тип mpls-tp определен как элемент, дополняющий базовое определение technology-types в модели.

       identity mpls-tp{
             base co-oam:technology-types;
             description
              "mpls-tp type";
            }
7.2.1.2. Расширение Technology Subtype

Поскольку в MPLS-TP применяются разные типы инкапсуляции (такие как IP/UDP и PW-ACH), в модели MPLS-TP OAM определен узел данных technology-sub-type для идентификации используемого типа инкапсуляции. С помощью этого узла определены субтипы для инкапсуляции IP/UDP и PW-ACH, а также могут быть определены другие субтипы. Приведенный ниже фрагмент показывает пример определения нескольких типов.

   identity technology-sub-type {
         description
         "Некоторые реализации могут применять другие типы 
          инкапсуляции (IP/UDP, PW-ACH и т. п.). Вместо
          задания отдельной модели для каждого типа определен
          субтип технологии для указания инкапсуляции. Этот
          тип указывается на уровне MA."; }

              identity technology-sub-type-udp {
                base technology-sub-type;
                description
                  "Субтип для инкапсуляции IP/UDP.";
              }

              identity technology-sub-type-ach {
                base technology-sub-type;
                description
                  "Субтип для инкапсуляции PW-ACH.";
              }
              }

         augment "/co-oam:domains/co-oam:domain"
               + "/co-oam:mas/co-oam:ma" {
                leaf technology-sub-type {
                  type identityref {
                    base technology-sub-type;
                  }
                }
              }

7.2.2. Расширение MA Configuration

Конфигурационные параметры уровня MA являются управляющей информацией, которая может наследоваться в модели MPLS-TP OAM с использованием значений базовой модели в качестве принятых по умолчанию. Примерами MA Name являются MPLS-TP LSP MEG_ID, MEG Section ID, MEG PW ID [RFC6370].

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

7.2.3. Расширение MEP Configuration

В MPLS-TP идентификатором MEP-ID служит значение метки с переменным размером в случае инкапсуляции G-ACH или 2-октетное целое число без знака при инкапсуляции IP/UDP. Одним из вариантов MEP-ID в MPLS-TP является LSP_MEP_ID [RFC6370]. В ориентированной на соединения базовой модели MEP-ID определен как узел choice/case, который может поддерживать значения int32 и такие же значения применяются в MPLS-TP. В дополнение к этому на уровне MEP (третий уровень) узел данных MEP может быть дополнен расширением для сессии или интерфейса.

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

Описанный здесь модуль YANG определяет схему для данных, которые предназначены для доступа с помощью протоколов сетевого управления, таких как NETCONF [RFC6241] или RESTCONF [RFC8040]. Нижним уровнем NETCONF является защищенный транспорт с обязательной поддержкой протокола SSH12 [RFC6242]. Нижним уровнем RESTCONF служит HTTPS с обязательной поддержкой протокола TLS [RFC8446].

Модель управления доступом к конфигурации сети [RFC8341] обеспечивает способы ограничить доступ определенных пользователей NETCONF или RESTCONF предопределенным подмножеством операций и содержимого NETCONF или RESTCONF.

Множество узлов данных в модуле YANG доступны для чтения, создания и удаления (значение config true, принятое по умолчанию). Эти узлы могут считаться деликатными в некоторых сетевых средах. Запись в такие узлы (например, edit-config) без соответствующей защиты может оказывать негативное влияние на работу сети. К таким узлам и субдеревьям относятся:

   /co-oam:domains/co-oam:domain/
   /co-oam:domains/co-oam:domain/co-oam:mas/co-oam:ma
   /co-oam:domains/co-oam:domain/co-oam:mas/co-oam:ma/co-oam:mep
   /co-oam:domains/co-oam:domain/co-oam:mas/co-oam:ma/co-oam:mep/co-oam:session

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

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

Этот документ регистрирует URI в реестре IETF XML Registry [RFC3688], куда внесены приведенные ниже данные.

     URI: urn:ietf:params:xml:ns:yang:ietf-connection-oriented-oam
     Registrant Contact: The IESG.
     XML: N/A; the requested URI is an XML namespace.

Документ регистрирует модуль YANG в реестре YANG Module Names [RFC6020].

  name:         ietf-connection-oriented-oam
  namespace:    urn:ietf:params:xml:ns:yang:ietf-connection-oriented-oam
  prefix:       co-oam
  reference:    RFC 8531

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

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

[IEEE802.1Q] IEEE, «IEEE Standard for Local and Metropolitan Area Networks-Bridges and Bridged Networks», IEEE Std 802.1Q.

[RFC2119] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC3688] Mealling, M., «The IETF XML Registry», BCP 81, RFC 3688, DOI 10.17487/RFC3688, January 2004, <https://www.rfc-editor.org/info/rfc3688>.

[RFC6020] Bjorklund, M., Ed., «YANG — A Data Modeling Language for the Network Configuration Protocol (NETCONF)», RFC 6020, DOI 10.17487/RFC6020, October 2010, <https://www.rfc-editor.org/info/rfc6020>.

[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., «Network Configuration Protocol (NETCONF)», RFC 6241, DOI 10.17487/RFC6241, June 2011, <https://www.rfc-editor.org/info/rfc6241>.

[RFC6242] Wasserman, M., «Using the NETCONF Protocol over Secure Shell (SSH)», RFC 6242, DOI 10.17487/RFC6242, June 2011, <https://www.rfc-editor.org/info/rfc6242>.

[RFC6370] Bocci, M., Swallow, G., and E. Gray, «MPLS Transport Profile (MPLS-TP) Identifiers», RFC 6370, DOI 10.17487/RFC6370, September 2011, <https://www.rfc-editor.org/info/rfc6370>.

[RFC6991] Schoenwaelder, J., Ed., «Common YANG Data Types», RFC 6991, DOI 10.17487/RFC6991, July 2013, <https://www.rfc-editor.org/info/rfc6991>.

[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, «RESTCONF Protocol», RFC 8040, DOI 10.17487/RFC8040, January 2017, <https://www.rfc-editor.org/info/rfc8040>.

[RFC8174] Leiba, B., «Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words», BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8341] Bierman, A. and M. Bjorklund, «Network Configuration Access Control Model», STD 91, RFC 8341, DOI 10.17487/RFC8341, March 2018, <https://www.rfc-editor.org/info/rfc8341>.

[RFC8343] Bjorklund, M., «A YANG Data Model for Interface Management», RFC 8343, DOI 10.17487/RFC8343, March 2018, <https://www.rfc-editor.org/info/rfc8343>.

[RFC8446] Rescorla, E., «The Transport Layer Security (TLS) Protocol Version 1.3», RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.

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

[G.800] «Unified functional architecture of transport networks», ITU-T Recommendation G.800, 2016.

[G.8013] «OAM functions and mechanisms for Ethernet based networks», ITU-T Recommendation G.8013/Y.1731, 2013.

[MEF-17] MEF Forum, «Service OAM Requirements & Framework — Phase 1», MEF 17, April 2007.

[MPLS-TP-OAM-YANG] Zhang, L., Zheng, L., Aldrin, S., and G. Mirsky, «YANG Data Model for MPLS-TP Operations, Administration, and Maintenance (OAM)», Work in Progress, draft-zhang-mpls-tp-yang-oam-05, October 2017.

[RFC6291] Andersson, L., van Helvoort, H., Bonica, R., Romascanu, D., and S. Mansfield, «Guidelines for the Use of the «OAM» Acronym in the IETF», BCP 161, RFC 6291, DOI 10.17487/RFC6291, June 2011, <https://www.rfc-editor.org/info/rfc6291>.

[RFC6325] Perlman, R., Eastlake 3rd, D., Dutt, D., Gai, S., and A. Ghanwani, «Routing Bridges (RBridges): Base Protocol Specification», RFC 6325, DOI 10.17487/RFC6325, July 2011, <https://www.rfc-editor.org/info/rfc6325>.

[RFC6371] Busi, I., Ed. and D. Allan, Ed., «Operations, Administration, and Maintenance Framework for MPLS-Based Transport Networks», RFC 6371, DOI 10.17487/RFC6371, September 2011, <https://www.rfc-editor.org/info/rfc6371>.

[RFC6905] Senevirathne, T., Bond, D., Aldrin, S., Li, Y., and R. Watve, «Requirements for Operations, Administration, and Maintenance (OAM) in Transparent Interconnection of Lots of Links (TRILL)», RFC 6905, DOI 10.17487/RFC6905, March 2013, <https://www.rfc-editor.org/info/rfc6905>.

[RFC7174] Salam, S., Senevirathne, T., Aldrin, S., and D. Eastlake 3rd, «Transparent Interconnection of Lots of Links (TRILL) Operations, Administration, and Maintenance (OAM) Framework», RFC 7174, DOI 10.17487/RFC7174, May 2014, <https://www.rfc-editor.org/info/rfc7174>.

[RFC7276] Mizrahi, T., Sprecher, N., Bellagamba, E., and Y. Weingarten, «An Overview of Operations, Administration, and Maintenance (OAM) Tools», RFC 7276, DOI 10.17487/RFC7276, June 2014, <https://www.rfc-editor.org/info/rfc7276>.

[RFC7455] Senevirathne, T., Finn, N., Salam, S., Kumar, D., Eastlake 3rd, D., Aldrin, S., and Y. Li, «Transparent Interconnection of Lots of Links (TRILL): Fault Management», RFC 7455, DOI 10.17487/RFC7455, March 2015, <https://www.rfc-editor.org/info/rfc7455>.

[RFC8340] Bjorklund, M. and L. Berger, Ed., «YANG Tree Diagrams», BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, <https://www.rfc-editor.org/info/rfc8340>.

[RFC8342] Bjorklund, M., Schoenwaelder, J., Shafer, P., Watsen, K., and R. Wilton, «Network Management Datastore Architecture (NMDA)», RFC 8342, DOI 10.17487/RFC8342, March 2018, <https://www.rfc-editor.org/info/rfc8342>.

[RFC8532] Kumar, D., Wang, M., Wu, Q., Ed., Rahman, R., and S. Raghavan, «Generic YANG Data Model for the Management of Operations, Administration, and Maintenance (OAM) Protocols That Use Connectionless Communications», RFC 8532, DOI 10.17487/RFC8532, April 2019, <https://www.rfc-editor.org/info/rfc8532>.

[TRILL-YANG] Weiguo, H., Yizhou, L., Kumar, D., Durrani, M., Zhai, H., and L. Xia, «TRILL YANG Data Model», Work in Progress, draft-ietf-trill-yang-04, December 2015.

[TRILL-YANG-OAM] Kumar, D., Senevirathne, T., Finn, N., Salam, S., Xia, L., and H. Weiguo, «YANG Data Model for TRILL Operations, Administration, and Maintenance (OAM)», Work in Progress, draft-ietf-trill-yang-oam-05, March 2017.

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

Giles Heron предложил разработать модель данных YANG в качестве пути создания унифицированного набора OAM API и этот документ во многом вдохновлен этим преддложением. Alexander Clemm дал много ценных советов, комментариев и замечаний, которые помогли улучшить представленную здесь модель YANG.

Carlos Pignataro, David Ball, Mahesh Jethanandani, Benoit Claise, Ladislav Lhotka, Jens Guballa, Yuji Tochio, Gregory Mirsky, Huub van Helvoort, Tom Taylor, Dapeng Liu, Mishael Wexler и Adi Molkho внесли важный вклад в разработку этого документа.

Участники работы

Tissa Senevirathne

Consultant

Email: tsenevir@gmail.com

Norman Finn

CISCO Systems

510 McCarthy Blvd

Milpitas, CA 95035

United States of America

Email: nfinn@cisco.com

Samer Salam

CISCO Systems

595 Burrard St. Suite 2123

Vancouver, BC V7X 1J1

Canada

Email: ssalam@cisco.com

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

Deepak Kumar

CISCO Systems

510 McCarthy Blvd

Milpitas, CA 95035

United States of America

Email: dekumar@cisco.com

Qin Wu

Huawei

101 Software Avenue, Yuhua District

Nanjing, Jiangsu 210012

China

Email: bill.wu@huawei.com

Michael Wang

Huawei Technologies, Co., Ltd

101 Software Avenue, Yuhua District

Nanjing 210012

China

Email: wangzitao@huawei.com


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

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

nmalykh@protokols.ru


1Network Management Datastore Architecture — архитектура хранилища данных сетевого управления.

2Internet Engineering Task Force.

3Internet Engineering Steering Group.

4MPLS Transport Profile — транспортный профиль MPLS.

5Virtual eXtensible Local Area Network.

6Network Management Datastore Architecture — архитектура хранилища данных конфигурации сети.

7Continuity Check Message.

8Remote Defect Indication — индикация удаленного дефекта.

9Connectivity Verification.

10Multi-Layer Environment — многоуровневое расширение.

11Autonomous System Number.

12Secure Shell — защищенная оболочка.

Рубрика: RFC | Комментарии к записи RFC 8531 Generic YANG Data Model for Connection-Oriented Operations, Administration, and Maintenance (OAM) Protocols отключены