RFC 7935 The Profile for Algorithms and Key Sizes for Use in the Resource Public Key Infrastructure

Internet Engineering Task Force (IETF)                         G. Huston
Request for Comments: 7935                            G. Michaelson, Ed.
Obsoletes: 6485                                                    APNIC
Category: Standards Track                                    August 2016
ISSN: 2070-1721

Профиль алгоритмов и размеров ключей для использования в RPKI

The Profile for Algorithms and Key Sizes for Use in the Resource Public Key Infrastructure

PDF

Тезисы

Этот документ задает алгоритмы, их параметры, форматы асимметричных ключей, размеры асимметричных ключей и формат подписи для абонентов инфраструктуры открытых ключей ресурсов (RPKI1), создающих цифровые подписи для сертификатов, спосков отзыва сертификатов (CRL2), пожписанных объектов CMS3 и запросов сертификатов, а также для зависимых от инфраструктуры сторон (RP4), которые проверяют эти подписи.

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

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

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

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

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

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

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

Оглавление

Исключено в версии HTML.

1. Введение

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

  • алгоритмы и параметры цифровых подписей;

  • алгоритмы и параметры хэширования;

  • форматы открытых и секретных ключей;

  • формат подписи,

используемые абонентами инфраструктуры RPKI [RFC6480], которые используют цифровые подписи для сертификатов, CRL [RFC5280], подписанных объектов CMS [RFC5652] (например ROA7) [RFC6482] и манифестов [RFC6486]), а также запросов сертификатов [RFC2986] [RFC4211]. Зависимые от инфраструктуры стороны (RP) также используют заданные здесь алгоритмы для проверки цифровых подписей абонентов RPKI [RFC6480].

Профили и спецификации RPKI, где содержатся ссылки на RFC 6485, теперь указывают на этот документ. К таким документам относятся [RFC6484] (политика сертификации (CP8) в RPKI), [RFC6487] (профиль сертификатов RPKI), [RFC6480] (архитектура RPKI) и [RFC6488] (шаблон подписанных объектов для RPKI). Предполагается знакомство читателя с этими документами.

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

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

2. Алгоритмы

В RPKI используется два криптографических алгоритма.

  • Алгоритмом цифровой подписи в сертификатах, CRL, подписанных объектах CMS и запросах сертификатов является RSA Public-Key Cryptography Standards (PKCS) #1 версии 1.5 (иногда его называют RSASSA-PKCS1-v1_5) из параграфа 8.2 [RFC3447].

  • Алгоритмом хэширования для сертификатов, CRL, подписанных объектов CMS и запросов сертификатов является SHA-256 [SHS] (см. примечание ниже).

    Примечание. Исключением является применение алгоритма SHA-1 [SHS] при генерации в CA идентификаторов организации (generate) и ключа субъекта [RFC6487].

В сертификатах, CRL и запросах сертификатов алгоритмы хэширования и цифровой подписи указываются совместно (например, RSA PKCS #1 v1.5 with SHA-256 или проще RSA with SHA-256). Для них должен использоваться OID9 sha256WithRSAEncryption из [RFC4055].

OID размещается в перечисленных ниже местах:

для сертификатов OID указывается в полях signature и signatureAlgorithm [RFC4055];

для CRL идентификатор OID указывается в поле signatureAlgorithm [RFC4055];

в запросах сертификатов OID указывается в поле signatureAlgorithm PKCS #10 [RFC2986] или в поле CRMF10 POPOSigningKey algorithmIdentifier [RFC4211].

В CMS SignedData алгоритмы хэширования (дайджест сообщения) и цифровой подписи указываются раздельно. В полях SignedData digestAlgorithms и SignerInfo digestAlgorithm должны указываться алгоритм и параметры SHA-256 (как определено в [RFC5754]). При генерации объектов CMS SignedData в поле SignerInfo signatureAlgorithm должны указываться идентификатор объекта и параметры rsaEncryption [RFC3370]. Реализации RPKI должны воспринимать значения rsaEncryption или sha256WithRSAEncryption для поля SignerInfo signatureAlgorithm при проверке объектов CMS SignedData (для совместимости с объектами, созданными реализациями, которые соответствуют [RFC6485]).

3. Форматы пар асимметричных ключей

Ключевые пары RSA, используемые для расчета подписей, должны иметь 2048-битовый модуль (modulus) и показатель (public exponent — e) 65537.

3.1. Формат открытых ключей

Открытый ключ субъекта помещается в структуру subjectPublicKeyInfo [RFC5280], имеющую два поля — algorithm и subjectPublicKey. Назначение этих полей и их структура описаны ниже.

algorithm (имеет тип AlgorithmIdentifier)

В поле algorithm должен использоваться идентификатор для RSA PKCS #1 v1.5 с SHA-256 как указано в разделе 5 [RFC4055]. Значение для связанных параметров должно использоваться для поля parameters.

subjectPublicKey

Для кодирования поля subjectPublicKey в сертификате должна использоваться структура RSAPublicKey как указано в [RFC4055].

3.2. Формат секретных ключей

Формат секретного ключа определяется локальной политикой.

4. Формат подписи

Структура поля signature для сертификата описана в параграфе 1.2 [RFC4055]. Структура поля signature в SignerInfos объектов CMS SignedData описана в [RFC5652].

5. Дополнительные требования

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

Процедуры перехода к новым размерам ключей и алгоритмам описаны в [RFC6916].

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

Одноименные разделы [RFC4055], [RFC5280] и [RFC6487] применимы к сертификатам и CRL. Такие же разделы [RFC2986], [RFC4211] и [RFC6487] применимы к запросам сертификатов. Аналогичный раздел [RFC5754] применим для подписанных объектов CMS. Данная спецификация не вносит новых проблем безопасности.

7. Отличия от RFC 6485

Это обновление включает незначительные технические обновления [RFC6485], которые не считаются связанными ошибками. В процессе обновления также были учтены замеченные ошибки и внесены разные поправки.

В разделе 2 [RFC6485] значение sha256WithRSAEncryption указано в качестве OID для использования в поле SignerInfo signatureAlgorithm подписанных объектов CMS (SignedObjects). Однако имеющиеся реализации используют для этого поля rsaEncryption OID (поддержка rsaEncryption в сторонних криптографических библиотеках лучше, нежели для sha256WithRSAEncryption возможно в результате того, что в [RFC3370] поддержка rsaEncryption указана обязательной, а поддержка OID для RSA и алгоритма подписи совместно — опциональной).

Вместо того, чтобы требовать от имеющихся реализаций перехода на sha256WithRSAEncryption, данный документ изменен с учетом сложившейся практики. Это не меняет криптографический алгоритм, а меняет лишь идентификатор (в отличие от сертификатов, CRL и запросов сертификатов, подписанные объекты CMS имеют отдельное поле для идентификатора алгоритма хэширования и это поле должно содержать id-sha256 OID в соответствии с разделом 2).

Для предотвращения проблем совместимости от RP по прежнему требуется воспринимать идентификаторы sha256WithRSAEncryption, если они встречаются.

Другие изменения перечислены ниже.

  • Исправлены опечатки и внесены незначительные редакторские правки.

  • Исправлены ссылки ([RFC5652] взамен [RFC3370], [RFC3447] взамен [RFC4055]).

  • Добавлены ссылки во Введение.

  • Внесена корректировка для поля CRMF POPOSigningKey в разделе 2 (algorithmIdentifier вместо signature).

  • Добавлены запросы сертификатов в упоминания сертификатов, CRL и подписанных объектов CMS.

  • Заменен текст в разделе 5 с указанием процедуры, определенной в [RFC6916] (смена алгорита).

  • Слова «подписанный объект» заменены повсюду словами «подписанный объект CMS».

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

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

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

[RFC2986] Nystrom, M. and B. Kaliski, «PKCS #10: Certification Request Syntax Specification Version 1.7», RFC 2986, DOI 10.17487/RFC2986, November 2000, <http://www.rfc-editor.org/info/rfc2986>.

[RFC3370] Housley, R., «Cryptographic Message Syntax (CMS) Algorithms», RFC 3370, DOI 10.17487/RFC3370, August 2002, <http://www.rfc-editor.org/info/rfc3370>.

[RFC3447] Jonsson, J. and B. Kaliski, «Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1», RFC 3447, DOI 10.17487/RFC3447, February 2003, <http://www.rfc-editor.org/info/rfc3447>.

[RFC4055] Schaad, J., Kaliski, B., and R. Housley, «Additional Algorithms and Identifiers for RSA Cryptography for use in the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile», RFC 4055, DOI 10.17487/RFC4055, June 2005, <http://www.rfc-editor.org/info/rfc4055>.

[RFC4211] Schaad, J., «Internet X.509 Public Key Infrastructure Certificate Request Message Format (CRMF)», RFC 4211, DOI 10.17487/RFC4211, September 2005, <http://www.rfc-editor.org/info/rfc4211>.

[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, <http://www.rfc-editor.org/info/rfc5280>.

[RFC5652] Housley, R., «Cryptographic Message Syntax (CMS)», STD 70, RFC 5652, DOI 10.17487/RFC5652, September 2009, <http://www.rfc-editor.org/info/rfc5652>.

[RFC5754] Turner, S., «Using SHA2 Algorithms with Cryptographic Message Syntax», RFC 5754, DOI 10.17487/RFC5754, January 2010, <http://www.rfc-editor.org/info/rfc5754>.

[RFC6480] Lepinski, M. and S. Kent, «An Infrastructure to Support Secure Internet Routing», RFC 6480, DOI 10.17487/RFC6480, February 2012, <http://www.rfc-editor.org/info/rfc6480>.

[RFC6484] Kent, S., Kong, D., Seo, K., and R. Watro, «Certificate Policy (CP) for the Resource Public Key Infrastructure (RPKI)», BCP 173, RFC 6484, DOI 10.17487/RFC6484, February 2012, <http://www.rfc-editor.org/info/rfc6484>.

[RFC6487] Huston, G., Michaelson, G., and R. Loomans, «A Profile for X.509 PKIX Resource Certificates», RFC 6487, DOI 10.17487/RFC6487, February 2012, <http://www.rfc-editor.org/info/rfc6487>.

[RFC6488] Lepinski, M., Chi, A., and S. Kent, «Signed Object Template for the Resource Public Key Infrastructure (RPKI)», RFC 6488, DOI 10.17487/RFC6488, February 2012, <http://www.rfc-editor.org/info/rfc6488>.

[SHS] National Institute of Standards and Technology (NIST), «FIPS Publication 180-3: Secure Hash Standard», FIPS Publication 180-3, October 2008.

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

[RFC6482] Lepinski, M., Kent, S., and D. Kong, «A Profile for Route Origin Authorizations (ROAs)», RFC 6482, DOI 10.17487/RFC6482, February 2012, <http://www.rfc-editor.org/info/rfc6482>.

[RFC6485] Huston, G., «The Profile for Algorithms and Key Sizes for Use in the Resource Public Key Infrastructure (RPKI)», RFC 6485, DOI 10.17487/RFC6485, February 2012, <http://www.rfc-editor.org/info/rfc6485>.

[RFC6486] Austein, R., Huston, G., Kent, S., and M. Lepinski, «Manifests for the Resource Public Key Infrastructure (RPKI)», RFC 6486, DOI 10.17487/RFC6486, February 2012, <http://www.rfc-editor.org/info/rfc6486>.

[RFC6916] Gagliano, R., Kent, S., and S. Turner, «Algorithm Agility Procedure for the Resource Public Key Infrastructure (RPKI)», BCP 182, RFC 6916, DOI 10.17487/RFC6916, April 2013, <http://www.rfc-editor.org/info/rfc6916>.

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

Авторы подтверждают использование в этом документе материалов, содержащихся в черновых вариантах документов RPKI Certificate Policy [RFC6484] и профиля сертификатов ресурсов [RFC6487]. Спасибо соавторам этих двух документов, а именно, — Stephen Kent, Derrick Kong, Karen Seo, Ronald Watro, George Michaelson и Robert Loomans. Указанные в этом документе ограничения для размеров ключей взяты из комментариев Stephen Kent и рецензии David Cooper. Дополнительную рецензию для этого документа предоставил Sean Turner.

Andrew Chi и David Mandelberg обнаружили проблему, рассмотренную в этой замене документа [RFC6485]. Изменения включают также результаты дискуссии между Rob Austein и Matt Lepinski в списке рассылки рабочей группы SIDR. Richard Hansen внес множество предложений, включенных в этот документ.

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

Geoff Huston

APNIC

Email: gih@apnic.net

George Michaelson (редактор)

APNIC

Email: ggm@apnic.net


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

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

nmalykh@gmail.com

1Resource Public Key Infrastructure.

2Certificate Revocation List.

3Cryptographic Message Syntax — синтаксис криптографических сообщений.

4Relying party.

5Internet Engineering Task Force.

6Internet Engineering Steering Group.

7Route Origin Authorization — полномочния на создание маршрутов.

8Certificate Policy.

9Object Identifier — идентификатор объекта.

10Certificate Request Message Format — формат сообщений с запросом сертификата.




RFC 7951 JSON Encoding of Data Modeled with YANG

Internet Engineering Task Force (IETF)                         L. Lhotka
Request for Comments: 7951                                        CZ.NIC
Category: Standards Track                                    August 2016
ISSN: 2070-1721

JSON Encoding of Data Modeled with YANG

Кодирование JSON для данных, моделируемых в YANG

PDF

Тезисы

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

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

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

Документ является результатом работы IETF3 и представляет согласованный взгляд сообщества IETF. Документ прошел открытое обсуждение и был одобрен для публикации IESG4. Не все одобренные IESG документы претендуют на статус Internet Standard (раздел 2 в RFC 7841).

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

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

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

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

Оглавление

Исключено в версии HTML.

1. Введение

Протокол NETCONF5 [RFC6241] использует XML [XML] для кодирования данных на своем уровне содержимого (Content Layer). Другие протоколы могут предпочесть другое кодирование, сохраняя преимущества YANG [RFC7950] для моделирования данных.

Например, протокол RESTCONF [RESTCONF] поддерживает кодирование XML (тип носителя application/yang.data+xml) и JSON (application/yang.data+json).

Спецификация языка моделирования YANG 1.1 [RFC7950] определяет только кодирование XML для деревьев данных, т. е. данных конфигурации и состояния, входных и выходных параметры операций RPC и действий, а также уведомлений. Цель этого документа заключается в определении правил кодирования тех же данных в форме текста JSON [RFC7159].

2. Термины и обозначения

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

Ниже приведены термины, определенные в [RFC7950].

  • action — действие;

  • anydataлюбые данные;

  • anyxmlлюбые данные XML;

  • augmentдополнение;

  • containerконтейнер;

  • data nodeузел данных;

  • data treeдерево данных;

  • identityотождествление;

  • instance identifierидентификатор экземпляра;

  • leaf — лист;

  • leaf-list — лист-список;

  • list — список;

  • module — модуль;

  • RPC operation — операция RPC;

  • submodule — субмодуль.

Ниже приведены термины, определенные в [RFC6241].

  • configuration data — данные конфигурации;

  • notification — уведомление;

  • state data — данные состояния.

3. Свойства кодирования JSON

Этот документ определяет кодирование JSON для деревьев YANG и их субдеревьев. Во всех случаях предполагается, что структура верхнего уровня с кодированием данных JSON является объектом.

Экземпляры улов данных YANG (leaf, container, leaf-list, list, anydata и anyxml) кодируются как элементы (member) объекта JSON, т. е. пары «имя — значение». В разделе 4 определено формирование имен, а в следующих разделах рассматриваются значения. Правила кодирования идентичны для всех типов деревьев данных, т. е. данных конфигурации и состояния, параметров операций RPC, действий и уведомлений.

За исключением кодирования anydata (параграф 5.5), правила этого документа применимы и в YANG 1.0 [RFC6020].

В отличие от содержимого элементов XML, значения JSON содержат лишь часть информации о типе (число, строка, логический). Кодирование JSON определено так, что эта информация никогда не противоречит типу данных соответствующего листа или листа списка YANG.

За исключением anyxml и узлов anydata без схемы, можно сопоставить дерево данных в кодировке JSON с кодировкой XML, определенной в [RFC7950], и наоборот. Однако для таких преобразования требуется модель данных YANG.

Для обеспечения максимальной совместимости реализаций, использующих разные анализаторы JSON, правила кодирования JSON, насколько это возможно, следуют ограничениям I-JSON (Internet JSON) профиля [RFC7493]. Более подробно соответствие I-JSON рассматривается в разделе 7.

4. Имена и пространства имен

Имя элемента объекта JSON должно иметь одну из приведенных ниже форм.

  • Простая (simple) форма совпадает с идентификатором соответствующего узла данных YANG.

  • Форма с указанием пространства имен (namespace-qualified) использует перед идентификатором узла префикс в виде имени модуля, в котором был определен узел данных. Префикс отделяется от имени двоеточием (:).

Имя модуля определяет пространство имен для всех узлов данных, определенных в модуле. Если узел данных определен в субмодуле, в полном (namespace-qualified) имени элемента указывается имя основного модуля, к которому относится субмодуль.

Синтаксис ABNF [RFC5234] для имен элемента, показан на рисунке 1, а создание identifier определено в разделе 14 [RFC7950].

member-name = [identifier ":"] identifier

Рисунок 1. Создание ABNF для имени элемента JSON

Имя элемента с пространством имен должно применяться для всех элементов объекта JSON верхнего уровня, а также в тех случаях, когда пространства имен узла данных и его родителя отличаются. В остальных случаях должна применяться простая форма имен элементов.

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

   module example-foomod {

     namespace "http://example.com/foomod";

     prefix "foomod";

     container top {
       leaf foo {
         type uint8;
       }
     }
   }

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

   {
     "example-foomod:top": {
       "foo": 54
     }
   }

Отметим, что элемент объекта верхнего уровня использует полное имя, а для листа foo применяется простое, поскольку этот лист определен в одном модуле с родительским контейнером top.

Предположим, что контейнер top дополнен из другого модуля example-barmod, как показано ниже.

   module example-barmod {

     namespace "http://example.com/barmod";

     prefix "barmod";

     import example-foomod {
       prefix "foomod";
     }

     augment "/foomod:top" {
       leaf bar {
         type boolean;
       }
     }
   }

Действительные конфигурационные данные в кодировке JSON, содержащие оба лисат, могут иметь вид

   {
     "example-foomod:top": {
       "foo": 54,
       "example-barmod:bar": true
     }
   }

Имя листа bar использует идентификатор пространства имен, поскольку его родитель определен в другом модуле.

Явные идентификаторы пространства имен иногда требуются при кодировании значений identityref и instance-identifier. В этом случае применяется определенная выше форма namespace-qualified. Более подробное описание дано в параграфах 6.8 и 6.11.

5. Кодирование экземпляров узлов данных YANG

Каждый экземпляр узла данных кодируется как пара «имя — значение», где имя формируется из идентификатора узла данных с использованием правил раздела 4. Значение зависит от категории узла данных, как описано ниже.

Для символов должна применяться кодировка UTF-8.

5.1. Узел leaf

Экземпляр листа (leaf) кодируется парой «имя — значение», где значением может быть строка, число, литерал true или false, а также специальный массив [null], в зависимости от типа листа (правила кодирования типов даны в разделе 6).

Ниже приведен пример для узла leaf.

   leaf foo {
     type uint8;
   }

Действительное кодирование JSON имеет вид

   "foo": 123

5.2. Узел container

Экземпляр контейнера кодируется парой «имя — объект», а дочерние узлы контейнера — как элементы объекта.

Например, для определения контейнера

   container bar {
     leaf foo {
       type uint8;
     }
   }

Действительное кодирование JSON имеет вид

   "bar": {
     "foo": 123
   }

5.3. Узел leaf-list

Лист список кодируется парой «имя — массив» и элементами массива являются значения того или иного скалярного типа, которым может быть строка, число, литерал true или false, а также специальный массив [null], в зависимости от типа leaf-list (правила кодирования типов даны в разделе 6).

Порядок элементов массива следует тем же правилам, которые применяются для элементов XML, представляющих записи leaf-list при кодировании XML. В частности, должны соблюдаться свойства ordered-by (параграф 7.7.7 в [RFC7950]).

Например, для определения leaf-list

   leaf-list foo {
     type uint8;
   }

Действительное кодирование JSON имеет вид

   "foo": [123, 0]

5.4. Узел list

Экземпляр списка (list) кодируется парой «имя — массив» и элементами массива являются объекты JSON.

Порядок элементов массива следует тем же правилам, которые применяются для элементов XML, представляющих записи списка при кодировании XML. В частности, должны соблюдаться свойства ordered-by (параграф 7.7.7 в [RFC7950]).

В отличии от кодирования XML, где ключи списка должны предшествовать всем «братским» (sibling) элементам в записи списка и сохранять порядок, заданный моделью данных, в записи списка с кодированием JSON может применяться произвольный порядок, поскольку объекты JSON являются неупорядоченным набором элементов.

Например, для определения списка

   list bar {
     key foo;
     leaf foo {
       type uint8;
     }
     leaf baz {
       type string;
     }
   }

Действительное кодирование JSON имеет вид

   "bar": [
     {
       "foo": 123,
       "baz": "zig"
     },
     {
       "baz": "zag",
       "foo": 0
     }
   ]

5.5. Узел anydata

Узел anydata служит контейнером для произвольного набора узлов, которые иначе бы выглядели обычными данными модели YANG. Модель данных для содержимого anydata может (но не обязана) быть известной во время выполнения (runtime). При неизвестной модели преобразование экземпляров с кодированием JSON в кодирование XML, определенное в [RFC7950] может оказаться невозможным.

Экземпляр anydata кодируется как container, т. е. парой «имя — объект». Требование возможности моделирования содержимого anydata с помощью YANG предполагает перечисленные ниже правила для текста JSON внутри объекта.

  • Это должен быть действительный текст I-JSON [RFC7493].

  • Все имена элементов объекта должны соответствовать ABNF на рисунке 1.

  • Любой массив JSON содержит лишь уникальные скалярные значения (как leaf-list, см. параграф 5.3) или только объекты (как list, см. параграф Section 5.4).

  • Значение null разрешено лишь в одноэлементном массиве [null], соответствующем кодированию постого (empty) типа (см. параграф 6.9).

Например, для определения anydata

   anydata data;

Действительное кодирование JSON имеет вид

   "data": {
     "ietf-notification:notification": {
       "eventTime": "2014-07-29T13:43:01Z",
       "example-event:event": {
         "event-class": "fault",
         "reporting-entity": {
           "card": "Ethernet0"
         },
         "severity": "major"
       }
     }
   }

5.6. Узел anyxml

Экземпляр anyxml кодируется в JSON парой «имя-значение» и значение должно соблюдать ограничения I-JSON.

Например, для определения anyxml

   anyxml bar;

Действительное кодирование JSON имеет вид

   "bar": [true, null, true]

5.7. Объекты метаданных

Помимо экземпляров узлов данных YANG документ JSON может включать специальные элементы, имена которых начинаются с символа @ (коммерческое AT). Такие элементы служат для специальных целей, таких как кодирование метаданных [RFC7952]. Точный синтаксис и семантика таких элементов выходят за рамки документа.

6. Представление типов YANG в значениях JSON

Тип значения JSON в экземпляре узла данных leaf или leaf-list зависит от типа этого узла данных, как описано в следующих параграфах.

6.1. Численные типы

Значения int8, int16, int32, uint8, uint16 и uint32 представляются числом JSON (number).

Значения int64, uint64 и decimal64 представляются строкой JSON, содержимое которой является лексическим представлением соответствующего типа YANG, как указано в параграфах 9.2.1 и 9.3.1 [RFC7950].

Например, если бы типом листа foo из параграфа 5.1 был uint64 вместо uint8, экземпляр бы имел вид

   "foo": "123"

Специальная обработка 64-битовых чисел следует из рекомендаций I-JSON для кодирования чисел, выходящих за пределы диапазона двойной точности IEEE 754-2008 [IEEE754-2008], в форме строк (параграф 2.2 в [RFC7493]).

6.2. Тип string

Значение типа string представляется строкой JSON (string) в соответствии с правилами кодирования строк JSON.

6.3. Тип boolean

Логический тип (boolean) представляется в JSON литералом «true» или «false».

6.4. Тип enumeration

Перечисляемое значение (enumeration) представляются строкой JSON, которае являются одним из имен, назначенных оператором enum в YANG.

Это идентично лексическому представлению типа enumeration в XML (см. параграф 9.6 в [RFC7950]).

6.5. Тип bits

Значение bits представляется строкой JSON — последовательностью разделенных пробелами имен битов, которые нужно установить. Имена битов назначаются операторами bit в YANG.

Это идентично лексическому представлению типа bits, определенному в параграфе 9.7 [RFC7950].

6.6. Тип binary

Значение binary представляется строкой JSON — кодированием base64 для произвольных двоичных данных.

Это идентично лексическому представлению типа binary в XML (см. параграф 9.8 в [RFC7950]).

6.7. Тип leafref

Значение leafref представляется с использованием правил для типа leaf, на который указывает leafref.

6.8. Тип identityref

Значение identityref представляется строкой — именем отождествления. Если identity определено в разных модулях с злом leaf, содержащим значение identityref, должна применяться форма namespace-qualified (раздел 4). В остальных случаях разрешены обе формы.

Например, для представленного ниже семантического модуля

   module example-mod {
     ...
     import ietf-interfaces {
       prefix if;
     }
     ...
     leaf type {
       type identityref {
         base "if:interface-type";
       }
     }
   }

Действительный экземпляр листа type может иметь вид

   "type": "iana-if-type:ethernetCsmacd"

Идентификатор пространства имен iana-if-type в этом случае требуется, поскольку отождествление ethernetCsmacd не определено в одном модуле с листом type.

6.9. Тип empty

Значение empty представляется как [null], т. е. массив с единственным литералом «null». В этом документе [null] считается неделимым (atomic) скалярным значением.

Это кодирование типа empty выбрано вместо использования просто «null» для упрощения работы с пустыми листьями в языках программирования общего назначения, где значение null для элемента считается отсутствием элемента.

Например, для определения листа

   leaf foo {
     type empty;
   }

Действительный экземпляр имеет вид

   "foo": [null]

6.10. Тип union

Значение типа union кодируется как значение любого из входящих в объединение типов.

При проверке пригодности значения union информация о типе в кодировании JSON также должна учитываться. Синтаксис JSON обеспечивает способы преобразования типа члена объединения, которых нет в кодировании XML.

Например, рассмотрим приведенное ниже определение YANG.

   leaf bar {
     type union {
       type uint16;
       type string;
     }
   }

В RESTCONF [RESTCONF] можно установить значение bar с помощью типа носителя application/yang.data+xml

   <bar>13.5</bar>

поскольку значение может интерпретироваться как строка, т. е. второй член объединения. Однако при использовании носителя application/yang.data+json будет ошибкой указать

   "bar": 13.5

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

И наоборот, значение

   "bar": "1"

интерпретируется как строка.

6.11. Тип instance-identifier

Значение instance-identifier кодируется строкой аналогично лексическому представлению в XML (параграф 9.13.2 в [RFC7950]). Однако кодирование пространства имен instance-identifier следует правилам раздела 4.

  • Имя самого левого (верхнего уровня) узла данных всегда имеет форму namespace-qualified.

  • Имена других узлов данных имеют форму namespace-qualified, если узел и его родитель определены в разных моделях, иначе применяется простая форма. Правило относится и к именам узлов в предикатах.

Например,

   /ietf-interfaces:interfaces/interface[name='eth0']/ietf-ip:ipv4/ip

указывает пригодное значение instance-identifier, поскольку узлы interfaces, interface и name определены в модуле ietf-interfaces, а ipv4 и ip — в модуле ietf-ip.

7. Соответствие I-JSON

I-JSON [RFC7493] задает профиль ограничений для JSON, гарантирующий максимальную совместимость протоколов, использующих JSON в своих сообщениях, независимо от применяемых в реализации кодеров и декодеров JSON. Определенное в этом документе кодирование по возможности следует требованиям и рекомендациям I-JSON .

В частности, гарантируются перечисленные ниже свойства.

  • Кодировка символоа UTF-8.

  • Уникальность имен элементов в одном объекте JSON.

  • Независимость от порядка элементов объекта JSON.

  • Надежное преобразование всех типов чисел, поддерживаемых YANG (см. параграф 6.1).

Определенное здесь кодирование JSON отличается от I-JSON только для представления типа binary. Для совместимости с кодированием XML применяется схема base64 (параграф 6.6), а I-JSON рекомендует base64url.

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

Этот документ определяет дополнительное кодирование для данных, моделируемых на языке YANG, и не добавляет проблем безопасности к рассмотренным в разделе 17 [RFC7950].

Документ не определяет механизмов подписывания или шифрования данных, моделируемых с помощью YANG. При обычных условиях безопасность и целостность данных обеспечивается используемыми протоколами управления, такими как NETCONF [RFC6241] и RESTCONF [RESTCONF]. Если этого не достаточно, следует рассмотреть другие механизмы, такие как криптография на основе открытых ключей PKCS6 #7 [RFC2315] или JOSE7 [RFC7515] [RFC7516].

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

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

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

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

[RFC5234] Crocker, D., Ed. and P. Overell, «Augmented BNF for Syntax Specifications: ABNF», STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <http://www.rfc-editor.org/info/rfc5234>.

[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, <http://www.rfc-editor.org/info/rfc6241>.

[RFC7159] Bray, T., Ed., «The JavaScript Object Notation (JSON) Data Interchange Format», RFC 71598, DOI 10.17487/RFC7159, March 2014, <http://www.rfc-editor.org/info/rfc7159>.

[RFC7493] Bray, T., Ed., «The I-JSON Message Format», RFC 7493, DOI 10.17487/RFC7493, March 2015, <http://www.rfc-editor.org/info/rfc7493>.

[RFC7950] Bjorklund, M., Ed., «The YANG 1.1 Data Modeling Language», RFC 7950, DOI 10.17487/RFC7950, August 2016, <http://www.rfc-editor.org/info/rfc7950>.

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

[IEEE754-2008] IEEE, «IEEE Standard for Floating-Point Arithmetic», IEEE 754-2008, DOI 10.1109/IEEESTD.2008.4610935, 2008, <http://standards.ieee.org/findstds/standard/754-2008.html>.

[RESTCONF] Bierman, A., Bjorklund, M., and K. Watsen, «RESTCONF Protocol», Work in Progress, draft-ietf-netconf-restconf-169, August 2016.

[RFC2315] Kaliski, B., «PKCS #7: Cryptographic Message Syntax Version 1.5», RFC 2315, DOI 10.17487/RFC2315, March 1998, <http://www.rfc-editor.org/info/rfc2315>.

[RFC6020] Bjorklund, M., Ed., «YANG — A Data Modeling Language for the Network Configuration Protocol (NETCONF)», RFC 6020, DOI 10.17487/RFC6020, October 2010, <http://www.rfc-editor.org/info/rfc6020>.

[RFC7223] Bjorklund, M., «A YANG Data Model for Interface Management», RFC 7223, DOI 10.17487/RFC7223, May 2014, <http://www.rfc-editor.org/info/rfc7223>.

[RFC7515] Jones, M., Bradley, J., and N. Sakimura, «JSON Web Signature (JWS)», RFC 7515, DOI 10.17487/RFC7515, May 2015, <http://www.rfc-editor.org/info/rfc7515>.

[RFC7516] Jones, M. and J. Hildebrand, «JSON Web Encryption (JWE)», RFC 7516, DOI 10.17487/RFC7516, May 2015, <http://www.rfc-editor.org/info/rfc7516>.

[RFC7952] Lhotka, L., «Defining and Using Metadata with YANG», RFC 7952, DOI 10.17487/RFC7952, August 2016, <http://www.rfc-editor.org/info/rfc7952>.

[XML] 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, <http://www.w3.org/TR/2008/REC-xml-20081126>.

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

Показанный ниже документ JSON представляет те же данные, которые приведены в качестве отклика на запрос NETCONF <get> в Приложении D к [RFC7223]. Модель данных объединяет два модуля YANG — ietf-interfaces и ex-vlan (пример модуля в Приложении C к [RFC7223]). Поддерживается свойство if-mib, определенное в модуле ietf-interfaces.

   {
     "ietf-interfaces:interfaces": {
       "interface": [
         {
           "name": "eth0",
           "type": "iana-if-type:ethernetCsmacd",
           "enabled": false
         },
         {
           "name": "eth1",
           "type": "iana-if-type:ethernetCsmacd",
           "enabled": true,
           "ex-vlan:vlan-tagging": true
         },
         {
           "name": "eth1.10",
           "type": "iana-if-type:l2vlan",
           "enabled": true,
           "ex-vlan:base-interface": "eth1",
           "ex-vlan:vlan-id": 10
         },
         {
           "name": "lo1",
           "type": "iana-if-type:softwareLoopback",
           "enabled": true
         }
       ]
     },
     "ietf-interfaces:interfaces-state": {
       "interface": [
         {
           "name": "eth0",
           "type": "iana-if-type:ethernetCsmacd",
           "admin-status": "down",
           "oper-status": "down",
           "if-index": 2,
           "phys-address": "00:01:02:03:04:05",
           "statistics": {
             "discontinuity-time": "2013-04-01T03:00:00+00:00"
           }
         },
         {
           "name": "eth1",
           "type": "iana-if-type:ethernetCsmacd",
           "admin-status": "up",
           "oper-status": "up",
           "if-index": 7,
           "phys-address": "00:01:02:03:04:06",
           "higher-layer-if": [
             "eth1.10"
           ],
           "statistics": {
             "discontinuity-time": "2013-04-01T03:00:00+00:00"
           }
         },
         {
           "name": "eth1.10",
           "type": "iana-if-type:l2vlan",
           "admin-status": "up",
           "oper-status": "up",
           "if-index": 9,
           "lower-layer-if": [
             "eth1"
           ],
           "statistics": {
             "discontinuity-time": "2013-04-01T03:00:00+00:00"
           }
         },
         {
           "name": "eth2",
           "type": "iana-if-type:ethernetCsmacd",
           "admin-status": "down",
           "oper-status": "down",
           "if-index": 8,
           "phys-address": "00:01:02:03:04:07",
           "statistics": {
             "discontinuity-time": "2013-04-01T03:00:00+00:00"
           }
         },
         {
           "name": "lo1",
           "type": "iana-if-type:softwareLoopback",
           "admin-status": "up",
           "oper-status": "up",
           "if-index": 1,
           "statistics": {
             "discontinuity-time": "2013-04-01T03:00:00+00:00"
           }
         }
       ]
     }
   }

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

Автор благодарен Andy Bierman, Martin Bjorklund, Dean Bogdanovic, Balazs Lengyel, Juergen Schoenwaelder и Phil Shafer за их полезные замечания и предложения.

Адрес автора

Ladislav Lhotka

CZ.NIC

Email: lhotka@nic.cz


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

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

nmalykh@protocols.ru

1Remote Procedure Call — вызов удаленной процедуры.

2JavaScript Object Notation — обозначение объектов JavaScript.

3Internet Engineering Task Force.

4Internet Engineering Steering Group.

5Network Configuration Protocol — протокол настройки конфигурации сети.

6Public-Key Cryptography Standards — стандарты шифрования с открытыми ключами.

7JSON Object Signing and Encryption — подписывание и шифрование объектов JSON.

8Заменен RFC 8259. Прим. перев.

9Документ опубликован в RFC 8040. Прим. перев.




RFC 7938 Use of BGP for Routing in Large-Scale Data Centers

Internet Engineering Task Force (IETF)                       P. Lapukhov
Request for Comments: 7938                                      Facebook
Category: Informational                                        A. Premji
ISSN: 2070-1721                                          Arista Networks
                                                        J. Mitchell, Ed.
                                                             August 2016

Использование BGP для маршрутизации в крупных распределенных ЦОД

Use of BGP for Routing in Large-Scale Data Centers

PDF

Тезисы

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

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

Документ не содержит спецификации Internet Standards Track и публикуется с информационными целями.

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

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

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

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

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

Оглавление

Исключено в версии HTML.

1. Введение

Документ описывает практическое решение по маршрутизации в крупных распределенных центрах обработки данных (ЦОД). Такие центры, называемые также hyper-scale или warehouse-scale, могут содержать сотни тысяч серверов. Для организации сетей такого масштаба операторам приходиться пересматривать сетевые решения и используемые платформы.

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

Эксперименты и широкое тестирование показали, что протокол EBGP3 [RFC4271] хорошо подходит в качестве автономного протокола маршрутизации для такого типа ЦОД. Это отличается от традиционных проектов ЦОД, которые могут использовать простую древовидную топологию и базироваться на расширении доменов L24 через множество сетевых устройств. В документе подробно рассмотрены требования, которые привели к такому выбору, и представлены детали маршрутизации EBGP, а также представлены идеи для дальнейшего развития.

В этом документе впервые представлен обзор требований к устройству сети и проблем крупных ЦОД. Затем традиционные сетевые топологии ЦОД сравниваются с сетями Clos [CLOS1953], которые масштабируются по горизонтали. Далее подробно рассматриваются аргументы для выбора EBGP с топологией Clos как наиболее подходящего протокола маршрутизации, соответствующего требованиям и устройству сети. В заключение рассматриваются некоторые дополнительные соображения и варианты устройства. Предполагается близкое знакомство читателя с протоколом BGP для планирования и реализации описанного здесь решения.

2. Требования к устройству сети

В этом разделе описываются и суммируются требования к устройству сетей для крупных ЦОД.

2.1. Пропускная способность и картина трафика

Основной задачей при построении сети для большого числа серверов являются выполнение требований приложений к пропускной способности и задержкам. До недавнего времени было принято рассматривать основную часть трафика, входящего в ЦОД и выходящего из него, как трафик «север-юг». Традиционной топологии «дерево» было достаточно для размещения таких потоков даже при значительной «переподписке» между уровнями сети. Если требовалась дополнительная пропускная способность, она добавлялась путем «увеличения» элементов сети, например, обновления интерфейсных плат в устройствах или коммутаторах, а также установки устройств с более высокой плотностью портов.

Сегодня многие приложения на хостах крупных ЦОД создают большой объем трафика между серверами, который не выходит из ЦОД и обычно называется трафиком «восток-запад». Примерами могут служить компьютерные кластеры типа Hadoop [HADOOP], репликация данных между приложениями или перенос виртуальных машин. Масштабирование пропускной способности для таких систем на основе традиционных древовидных топологий становится слишком дорогим или просто невозможным физически (например, по причине ограниченной плотности портов в коммутаторах).

2.2. Минимизация капитальных затрат

Капитальные затраты (CAPEX5), связанные с сетевой инфраструктурой, обычно составляют 10-15% общей стоимости ЦОД [GREENBERG2009]. Величина в денежном выражении достаточно велика, поэтому постоянно приходится снижать стоимость отдельных элементов сети. Для этого обычно используется два способа:

  • унификация элементов и предпочтительным использованием однотипных или даже одинаковых устройств, позволяющая снизить расходы на закупку, поддержку и инвентаризацию;

  • снижение расходов за счет использования конкуренции между производителями.

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

2.3. Минимизация операционных расходов

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

Важным аспектом минимизации операционных расходов (OPEX6) является снижение размера домена отказов в сети. Известно, что сети Ethernet чувствительны к широковещательным и обычным (unicast) «штормам» трафика, которые могут существенно влиять на производительность и доступность сети. Использование полностью маршрутизируемой системы значительно снижает размеро домена отказов на уровне данных, ограничивая его нижним уровнем иерархии сети. Однако при этом возникает проблема отказов в распределенном уровне управления. Это требует более простых и компактных протоколов уровня управления для упрощения протокольных взаимодействий , снижающего вероятность отказов. Минимизация требований к программным функциям, как описано выше для CAPEX, снижает также требования к тестированию и обучению.

2.4. Организация трафика

В любом ЦОД балансировка нагрузки является одной из важных задач, решаемых сетевыми устройствами. Традиционно балансировщики реализуются в виде отдельных устройств на пути пересылки трафика. При росте сети возникает проблема масштабирования балансировщиков. Предпочтительной будет возможность горизонтального масштабирования балансировщиков путем добавления унифицированных узлов и распределения трафика между ними. В таких ситуациях идеальным выбором будет использование самой сетевой инфраструктуры для распределения трафика между этими узлами. Для решения этой задачи может использоваться комбинация anycast-анонсов префиксов [RFC4786] и функциональности ECMP7. Для более тонкого распределения нагрузки преимуществом будет возможность организации трафика на уровне этапа маршрутизации (per-hop). Например, преимуществом будет прямое управления набором ECMP next-hop для anycast-префиксов на каждом уровне иерархии сети.

2.5. Суммарные требования

В этом параграфе приведен список требований, очерченных в предыдущих параграфах.

  • REQ1. Выбор топологии с возможностью «горизонтального» масштабирования путем добавления каналов и устройств одного типа без обновления самих элементов сети.

  • REQ2. Определение небольшого набора программных функций/протоколов, поддерживаемых многими производителями сетевого оборудования.

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

  • REQ4. Минимизация доменов отказа оборудования и программ.

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

3. Обзор топологий ЦОД

В этом разделе приведен обзор двух базовых вариантов повтроения ЦОД и иерархический (на базе «дерева») и основанный на топологии Clos.

          +------+  +------+
          |      |  |      |
          |      |--|      |           Уровень 1
          |      |  |      |
          +------+  +------+
            |  |      |  |
  +---------+  |      |  +----------+
  | +-------+--+------+--+-------+  |
  | |       |  |      |  |       |  |
+----+     +----+    +----+     +----+
|    |     |    |    |    |     |    |
|    |-----|    |    |    |-----|    | Уровень 2
|    |     |    |    |    |     |    |
+----+     +----+    +----+     +----+
   |         |          |         |
   |         |          |         |
   | +-----+ |          | +-----+ |
   +-|     |-+          +-|     |-+    Уровень 3
     +-----+              +-----+
      | | |                | | |
  <- Серверы ->        <- Серверы ->

Рисунок 1. Типичная топология сети ЦОД.


3.1. Традиционная топология ЦОД

В сетевой отрасли распространенное решение для ЦОД обычно выглядит подобно дереву (корнем вверх) с избыточными соединениями и тремя уровнями иерархии — ядро, агрегирование/распределение и доступ (Рисунок 1). Для удовлетворения требований к пропускной способности каждый вышележащий уровень от серверов в направлении выхода из ЦОД или WAN, имеет более высокую плотность портов и пропускную способность , а ядро служит «транком» для древовидной структуры. Для единообразия терминологии в этом документе уровни обозначаются Уровень (Tier) 1, Уровень 2 и Уровень 3 вместо терминов ядро (core), агрегирование (aggregation) и доступ (access).

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

3.2. Сетевая топология Clos

В этом разделе описано устройство сети с горизонтально масштабируемой топологией в больших ЦОД в соответствии с REQ1.

3.2.1. Обзор

Общепринятым решение для горизонтально масштабируемой топологии является «сфальцованная» топология Clos, которую называют также fat-tree (например, [INTERCON] и [ALFARES2008]). Эта топология использует нечетное число ступеней (stage), иногда называемых размерностями (dimension) и обычно строится на базе однородных элементов (например, коммутаторов с одинаковым числом портов). Поэтому выбор такой топологии Clos соответствует требованиям REQ1 и REQ2. На рисунке 2 below приведен пример 3-ступенчатой топологии Clos (3 ступени учитывают уровень 2 дважды при трассировке потока пакетов).

+-------+
|       |----------------------------+
|       |------------------+         |
|       |--------+         |         |
+-------+        |         |         |
+-------+        |         |         |
|       |--------+---------+-------+ |
|       |--------+-------+ |       | |
|       |------+ |       | |       | |
+-------+      | |       | |       | |
+-------+      | |       | |       | |
|       |------+-+-------+-+-----+ | |
|       |------+-+-----+ | |     | | |
|       |----+ | |     | | |     | | |
+-------+    | | |     | | |   ---------> M каналов
Уровень 1      | | |     | | |     | | |
           +-------+ +-------+ +-------+
           |       | |       | |       |
           |       | |       | |       | Уровень 2
           |       | |       | |       |
           +-------+ +-------+ +-------+
             | | |     | | |     | | |
             | | |     | | |   ---------> N каналов
             | | |     | | |     | | |
             O O O     O O O     O O O   Серверы

Рисунок 2. 3-ступенчатая «сфальцованная» топология Clos.


Такую топологию часто называют сетью Leaf and Spine (листья и ствол), где термином Spine обозначают среднюю ступень топологии Clos (уровень 1), Leaf — ступени ввода и вывода (уровень 2). Для единообразия в документе для обозначения этих уровней используется обозначение Tier (уровень) n.

3.2.2. Свойства топологии Clos

Ниже перечислены основные свойства топологии Clos.

  • Топология является полностью неблокируемой, точнее порты не создают друг другу помех при M >= N, а в остальных случаях работают с переподпиской N/M. Здесь M и N — счетчики восходящего и нисходящего портов, соответственно, для коммутатора уровня 2 на рисунке 2.

  • использование этой топологии требует поддержки уровней данных и правления для ECMP с числом вариантов не менее M.

  • Коммутаторы уровня 1 имеют в точности один путь к каждому серверу. Это важное свойство делает обобщение маршрутов в данной топологии опасным (см. 8.2. Обобщение маршрутов в топологии Clos).

  • Трафик между серверами распределяется (балансируется) по всем возможным путям с использованием ECMP.

3.2.3. Масштабирование топологии Clos

Топологию Clos можно масштабировать путем увеличения плотности портов в устройствах или путем добавления новых «ступеней», например, как в 5-ступенчатой топологии Clos, показанной на рисунке 3.

Небольшой пример топологии на рисунке 3 образован устройствами, имеющими по 4 порта. В этом документе набор напрямую соединенных устройств уровней 2 и 3 вместе с подключенными к ним серверами будет называться кластером. Например, устройства DEV A, B, C, D и серверы, подключенные к DEV A и B, на рисунке 3 образуют кластер. Концепция кластеров может быть полезна также при рассмотрении отдельного блока развертывания или поддержки, который может работать на другой частоте, нежели остальная часть топологии.

На практике уровень 3 в сети, который обычно образован стоечными коммутаторами ToR8, обычно работает с переподпиской, чтобы обеспечить возможность установки большего числа серверов в ЦОД при выполнении требований разных типов приложений к пропускной способности. Основной причиной ограничения переподписки на одном уровне сети является упрощение разработки приложений, которым в ином случае пришлось бы учитывать множество пулов пропускной способности — в стойке (уровень 3), между стойками (уровень 2) и между кластерами (уровень 1). Поскольку переподписка не связана напрямую с устройством маршрутизации, она больше не рассматривается в этом документе.

                                    Уровень 1
                                     +-----+
          Кластер                    |     |
 +----------------------------+   +--|     |--+
 |                            |   |  +-----+  |
 |                  Уровень 2 |   |           | Уровень 2
 |                   +-----+  |   |  +-----+  |  +-----+
 |     +-------------| DEV |------+--|     |--+--|     |-------------+
 |     |       +-----|  C  |------+  |     |  +--|     |-----+       |
 |     |       |     +-----+  |      +-----+     +-----+     |       |
 |     |       |              |                              |       |
 |     |       |     +-----+  |      +-----+     +-----+     |       |
 |     | +-----------| DEV |------+  |     |  +--|     |-----------+ |
 |     | |     | +---|  D  |------+--|     |--+--|     |---+ |     | |
 |     | |     | |   +-----+  |   |  +-----+  |  +-----+   | |     | |
 |     | |     | |            |   |           |            | |     | |
 |   +-----+ +-----+          |   |  +-----+  |          +-----+ +-----+
 |   | DEV | | DEV |          |   +--|     |--+          |     | |     |
 |   |  A  | |  B  | Уровень 3|      |     |   Уровень 3 |     | |     |
 |   +-----+ +-----+          |      +-----+             +-----+ +-----+
 |     | |     | |            |                            | |     | |
 |     O O     O O            |                            O O     O O
 |       Серверы              |                               Серверы
 +----------------------------+

Рисунок 3. 5-ступенчатая топология Clos.


3.2.4. Управление размером уровней топологии Clos

Если размер сети ЦОД невелик, можно вдвое снизить число коммутаторов на уровнях 1 и 2 топологии Clos. Для разъяснения этого рассмотрим уровень 1 в качестве примера. Каждое устройство уровня 2 подключено к одной группе устройств уровня 1. Если половина портов на каждом устройстве уровня 1 не используется, можно уменьшить число устройств уровня 1 просто подключая к одному устройству уровня 1 два восходящих канала от устройства уровня 2, которые раньше были подключены к разным устройствам уровня 1. Этот метод обеспечивает сохранение пропускной способности при снижении числа устройств уровня 1 (и CAPEX). Платой за такую экономию будет снижение вдвое максимального числа серверов в ЦОД.

В этом примере устройства уровня 2 используют два параллельных канала для соединения с каждым устройством уровня 1. При отказе одного из этих каналов другой примет на себя весь трафик, что может привести к значительной перегрузке и снижению качества обслуживания, если процедура определения пути не учитывает пропускную способность, поскольку число восходящих устройств уровня 1 может быть больше 2. Для решения проблемы можно объединять параллельные соединения в группы LAG9 (например, [IEEE8023AD]), с широко известными настройками, которые будут отключать (down) всю группу при отказе одного канала. Можно также использовать эквивалентный метод «общей судьбы» (fate sharing) на параллельных каналах вместо LAG. В результате из двух (или более) отказавших каналов будет распределен между оставшимися путями по числу устройств уровня 1. В примере для простоты используется 2 канала и наличие большего числа соединений будет снижать влияние отказа на снижение пропускной способности.

4. Обзор маршрутизации в ЦОД

В этом разделе приведен обзор трех основных вариантов организации сетей ЦОД — L2, L3 и гибрид L2/L3.

4.1. Вариант L2

Поначалу большинство ЦОД строились на основе протокола остовного дерева (STP), определенной стандартом 10[IEEE8021D-1990], для создания беспетлевой топологии с использованием одного из традиционных вариантов, описанных в параграфе 3.1. В то время многие коммутаторы ЦОД не поддерживали протоколы маршрутизации L3 или для поддержки этих протоколов требовались дополнительные лицензии, что влияло на выбор решения. Хотя с тех пор было внесено множество усовершенствований типа протокола RSTP11 в последней версии стандарта [IEEE8021D-2004] и MST12 из [IEEE8021Q], которые ускорили схождение и улучшили балансировку нагрузки в больших сетях, множество базовых аспектов протокола продолжает ограничивать его применимость в крупных ЦОД. Протокол STP и его новые варианты используют подход «активный-резервный» при выборе пути, а это усложняет развертывание масштабируемых по горизонтали топологий, описанных в параграфе 3.2. Кроме того, операторы накопили большой опыт обработки крупных отказов, связанных с некорректными кабельными соединиениями, ошибками настройки и программными проблемами на отдельном устройстве. Такие отказы обычно влияют на весь домен STP и устранение неполадок сложно из-за самой природы протокола. По этой причине и в связи с тем, что почти весь трафик ЦОД относится к протоколу IP, требующему наличия протокола маршрутизации L3 на границе сети для внешних соединений, организация сетей на основе STP обычно не позволяет выполнить все требования операторов крупных ЦОД. Различные усовершенствования протоколов объединения каналов типа [IEEE8023AD], обычно называемого M-LAG13, позволили использовать решения L2 с путями «активный-активный» с сохранением протокола STP для предотвращения петель. Основным недостатком такого подхода является отсутствие возможности линейного масштабирования более чем вдвое для большинства реализаций, отсутствие стандартизованных реализаций и возможность синхронного отказа нескольких устройств.

Следует отметить появившуюся недавно возможность построения больших сетей L2 с горизонтальным масштабированием без STP на основе протокола TRILL14 [RFC6325]. TRILL решает множество проблем STP в сетях крупных ЦОД, однако небольшое число реализаций и необходимость использовать специфическое оборудование с поддержкой этого протокола ограничивают применимость и повышают стоимость таких решений.

Кроме того ни базовая спецификация TRILL, ни подход M-LAG не решают полностью проблему единого домена широковещания, которая возникает для любого решения L2 на базе Ethernet. Были предложены расширения TRILL для решения этой проблемы прежде всего на основе подходов, рассмотренных в [RFC7067], но это еще сильнее ограничивает число доступных интеоперабельных реализаций. Поэтому у решений на базе TRILL возникают сложности с выполнением требований REQ2, REQ3 и REQ4.

4.2. Гибридный вариант L2/L3

Операторы стремились ограничить влияние отказов на уровне данных и строить крупномасштабные топологии на основе протоколов маршрутизации на уровне 1 или 2 с делением доменов L2 на множество более мелких субдоменов. Это позволило масштабировать ЦОД, но добавило сложности, связанные с управлением множеством сетевых протоколов. По перечисленным ниже причинам операторы сохранили L2 на уровне доступа (Tier 3) или на уровнях доступа и агрегирования (Tier 3 и Tier 2).

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

  • Бесшовное перемещение виртуальных машин, которым требуется сохранение адреса IP при переносе на другой коммутатор Tier 3.

  • Упрощение адресации IP (меньшее число подсетей IP) для ЦОД.

  • Балансировка нагрузки приложений может требовать прямой доступности на уровне L2 для выполнения некоторых функций типа L2 DSR15 (см. [L3DSR]).

  • Сохраняющееся различие CAPEX для коммутаторов L2 и L3.

4.3. Вариант L3

Сетевые проекты, опускающие маршрутизацию IP на уровень (Tier) 3, также обрели популярность. Основным преимуществом таких решений является повышение уровня стабильности и расширяемости сети в результате ограничения размеров доменов широковещания L2. Обычно в таких случаях основным протоколом маршрутизации является тот или иной протокол внутреннего шлюза (IGP16) типа OSPF17 [RFC2328]. ЦОДы растут в размерах и число серверов может достигать десятков тысяч, поэтому полностью маршрутизируемые решения становятся привлекательными.

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

5. Устройство протокола маршрутизации

В этом разделе приведена мотивация выбора EBGP в качестве единственного протокола маршрутизации для сетей ЦОД, работающих на основе L3 и топологии Clos. Даны также практические рекомендации по организации сетей на базе EBGP.

5.1. Выбор EBGP в качестве протокола маршрутизации

Выполнение требования REQ2 отдает преимущества выбору единственного протокола маршрутизации в результате упрощения и снижения числа зависимостей. Хотя в таких ситуациях чаще опираются на протоколы IGP, иногда дополняемые EBGP для граничных устройств WAN или IBGP18 внутри сети, в этом документе предлагается использовать лишь EBGP.

Хотя протокол используется практически повсюду в междоменной маршрутизации Internet и поддерживается многими производителями и сообществами сервис-провайдеров, он по ряду перечисленных ниже причин (некоторые из них связаны между собой) обычно не используется в качестве основного протокола маршрутизации ЦОД.

  • BGP считается протоколом для сетей WAN и редко рассматривается для сетей предприятий или ЦОД.

  • Считается, что в BGP маршруты сходятся гораздо медленней, чем в IGP.

  • Крупномасштабные системы BGP обычно используют IGP для определения BGP next-hop, поскольку не все узлы в топологии IBGP соединены между собой напрямую.

  • BGP считается требующим трудоемкой настройки конфигурации и не поддерживающим автоматическое обнаружение соседей.

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

  • BGP менее сложен в части устройства протокола — внутренние структуры данных и машина состояний проще чем для большинства IGP на основе состояния канала типа OSPF. Например, вместо реализации отношений смежности, их поддержки и/или управления потоком данных BGP просто опирается на обеспечиваемые протоколом TCP возможности. Это позволяет выполнить требования REQ2 и REQ3.

  • Информационные издержки BGP (лавинные рассылки) меньше по сравнению с IGP по состоянию каналов. Поскольку каждый маршрутизатор BGP рассчитывает и распространяет лишь выбранные лучшие пути, отказ в сети маскируется (обходится), как только узел BGP найдет альтернативный путь, который имеется в топологиях с высокой симметрией (типа Clos), выбранных для решения на основе лишь EBGP. Напротив, распространение события в IGP по состоянию канала занимает всю область, независимо от типа отказа. По этой причине BGP лучше подходит для выполнения требований REQ3 и REQ4. Следует также отметить, что все распространенные IGP по состоянию каналов периодически обновляют маршрутную информацию, тогда как BGP не ограничивает срок действия состояния маршрутизации, хотя это редко влияет на современные уровни управления в маршрутизаторах.

  • BGP поддерживает сторонние (определяемые рекурсивно) next hop. Это позволяет манипулировать множеством путей без использования ECMP или на основе пересылки по определенным приложениями путям за счет организации партнерской сессии с приложением «контроллер» которое может вносить в систему маршрутную информацию для выполнения требования REQ5. Протокол OSPF обеспечивает похожую функциональность за счет использования концепций типа «адреса пересылки» (Forwarding Address), но это сложнее в реализации и значительно менее управляемо в плане области распространения информации.

  • Используя четко определенную схему выделения ASN и стандартное определение петель в AS_PATH, можно управлять «охотой BGP на пути» (BGP path hunting [JAKMA2008]) и игнорировать сложные нежелательные пути. Пример работающей схемы выделения ASN представлен в параграфе 5.2. В IGP по состоянию каналов достижение этой цели требует поддержки множества экземпляров/топологий/процессов, что не всегда возможно в ЦОД и достаточно сложно для настройки и поиска неполадок. Применение традиционной схемы с одним доменом лавинной рассылки, которая используется в большинстве вариантов ЦОД, при некоторых отказах может приводить к нежелательным длинным путям, например, проходящим через множество устройств Tier 2.

  • Конфигурация EBGP с минимальной политикой маршрутизации проще в плане поиска и устранения неполадок в сети. В большинстве реализаций просто увидеть содержимое BGP Loc-RIB и сравнить его с базой RIB19 в маршрутизаторе. Также в большинстве реализаций оператор может видеть структуры Adj-RIB-In и Adj-RIB-Out каждого соседа BGP что позволяет легко сопоставить входящую и исходящую информацию NLRI на обеих сторонах сессии BGP. Таким образом, BGP соответствует требованию REQ3.

5.2. Конфигурация EBGP для топологии Clos

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

5.2.1. Рекомендации по настройке EBGP и пример схемы ASN

На рисунке 4 представлен пример схемы выделения ASN. При выделении могут использоваться приведенные ниже рекомендации.

  • Одноэтапные (single-hop) сессии EBGP организуются через прямые соединения «точка-точка», связывающие узлы сети, сессии с множеством интервалов (multi-hop) или loopback не применяются даже при наличии множества соединений между парой узлов.

  • Используются частные ASN из диапазона 64512-65534 для предотвращения конфликтов ASN.

  • Один номер ASN выделяется для всех устройств уровня 1 в топологии Clos.

  • Каждому набору устройств уровня 2 в одном кластере выделяется уникальное значение ASN.

  • Каждому устройству уровня 3 (например, ToR) выделяется уникальный номер ASN.

                             ASN 65534
                            +---------+
                            | +-----+ |
                            | |     | |
                          +-|-|     |-|-+
                          | | +-----+ | |
               ASN 646XX  | |         | |  ASN 646XX
              +---------+ | |         | | +---------+
              | +-----+ | | | +-----+ | | | +-----+ |
  +-----------|-|     |-|-+-|-|     |-|-+-|-|     |-|-----------+
  |       +---|-|     |-|-+ | |     | | +-|-|     |-|---+       |
  |       |   | +-----+ |   | +-----+ |   | +-----+ |   |       |
  |       |   |         |   |         |   |         |   |       |
  |       |   |         |   |         |   |         |   |       |
  |       |   | +-----+ |   | +-----+ |   | +-----+ |   |       |
  | +-----+---|-|     |-|-+ | |     | | +-|-|     |-|---+-----+ |
  | |     | +-|-|     |-|-+-|-|     |-|-+-|-|     |-|-+ |     | |
  | |     | | | +-----+ | | | +-----+ | | | +-----+ | | |     | |
  | |     | | +---------+ | |         | | +---------+ | |     | |
  | |     | |             | |         | |             | |     | |
+-----+ +-----+           | | +-----+ | |           +-----+ +-----+
| ASN | |     |           +-|-|     |-|-+           |     | |     |
|65YYY| | ... |             | |     | |             | ... | | ... |
+-----+ +-----+             | +-----+ |             +-----+ +-----+
  | |     | |               +---------+               | |     | |
  O O     O O              <- Servers ->              O O     O O

Рисунок 4. Схема BGP ASN для 5-ступенчатой топологии Clos.


5.2.2. Частное применение ASN

Исходный диапазон Private Use ASN [RFC6996] ограничен 1023 уникальными номерами ASN. Поскольку достаточно очевидно, что число устройств в сети превышает это значение, требуется решение проблемы. Одним из вариантов является повторное использование ASN, выделенных устройствам Tier 3 в разных кластерах. Например, частные ASN 65001, 65002 … 65032 могут применяться в каждом отдельном кластере и назначаться устройствам Tier 3.

Чтобы предотвратить подавление маршрутов механизмом детектирования петель AS_PATH в BGP, восходящие сессии EBGP на устройствах Tier 3 должны настраиваться с функцией Allowas-in [ALLOWASIN], что позволяет устройству воспринимать в анонсах свой номер ASN. Хотя эта функция не стандартизована, она поддерживается оборудованием многих производителей. Добавление этой функции не повышает вероятность возникновения маршрутных петель, поскольку атрибуты AS_PATH будут добавляться маршрутизаторами на каждом уровне топологии, а размер AS_PATH является ранним способом «отбрасывания лишнего» (early tie breaker) в процессе выбора пути BGP. Дополнительная защита от петель обеспечивается устройствами уровня 1, которые не будут воспринимать маршруты со своим номером ASN. Устройства Tier 2 не имеют прямой связности между собой.

Другим решением этой проблемы является использование 4-октетных ASN [RFC6793], которые обеспечивают значительное расширение пространства Private Use ASN (см. [IANA.AS]). Применение 4-октетных ASN усложняет реализацию BGP и это следует сравнивать со сложностью повторного использования ASN при выборе решения для удовлетворения требований REQ3 и REQ4. Важно понимать, что 4-октетные номера AS поддерживаются не всеми производителями и это может ограничивать выбор оборудования для ЦОД. Если такие номера поддерживаются, следует обеспечить удаление частных ASN на внешних соединениях (параграф 5.2.4), если это требуется.

5.2.3. Анонсирование префиксов

Топология Clos включает множество соединений «точка-точка» и связанных с ними префиксов. Анонсирование всех этих маршрутов в BGP может перегружать таблицы FIB20 в сетевых устройствах. Анонсирование каналов может также значительно нагружать уровень управления BGP при расчете путей. Ниже описаны два возможных решения задачи.

  • Не анонсировать никакие соединения «точка-точка» в BGP. Поскольку в решениях на базе EBGP адрес next-hop меняется на каждом устройстве, удаленные сети автоматически становятся доступными через аносирующих партнеров EBGP и для таких префиксов не требуется доступность. Однако это может осложнять мониторинг, например, популярная утилита traceroute будет указывать такие адреса IP как недоступные.

  • Анонсировать соединения «точка-точка» с обобщением на каждом устройстве. Для этого потребуется согласованная схема адресации, например выделение блока последовательных адресов IP на устройство Tier 1 и Tier 2 для использования на интерфейсах «точка-точка» с нижележащими уровнями (адреса для восходящих интерфейсов уровня 2 будут выделяться из блока адресов устройства Tier 1 и т. д.).

Серверные подсети на устройствах Tier 3 должны анонсироваться в BGP без обобщения маршрутов на устройствах уровня 2 и 1. Обобщение подсетей в топологии Clos приводит к возникновению маршрутных «черных дыр» при отказе одного канала (например, между устройствами Tier 2 и Tier 3), поэтому его следует избегать. Использование партнерских соединений внутри одного уровня для решения проблемы «черных дыр» путем создания «обходных путей» нежелательно по причине усложнения O(N2) соединений между партнерами и неоправданного расхода портов на устройствах. Альтернативой полносвязной сети соединений между партнерами является использование более простой топологии обхода, например, «кольца», описанного в [FB4POST], но это добавляет этапы пересылки и ограничено по пропускной способности. Для обеспечения работы BGP могут потребоваться специальные настройки. В параграфе 8.2 описан менее изощренный метод для ограниченного обобщения маршрутов в сетях Clos и связанные с ним компромиссы.

5.2.4. Внешние соединения

Можно использовать выделенный кластер (или кластеры) в топологии Clos для соединения с краевыми устройствами WAN21 или маршрутизаторами WAN. Устройства уровня 3 в таком кластере заменяются маршрутизаторами WAN и партнерские отношения EBGP снова будут использоваться, хотя маршрутизаторы WAN будут скорей всего относиться к публичным ASN, если для сети требуется соединение с Internet. Устройства уровня 2 в таком выделенном кластере далее будут называться граничными маршрутизаторами (Border Routers). Эти устройства выполняют некоторые специальные функции, описанные ниже.

  • Сокрытие топологической информации при анонсировании путей маршрутизаторам WAN, т. е. удаление частных ASN [RFC6996] из атрибутов AS_PATH. Это обычно делается для предотвращения конфликтов ASN между разными ЦОД, а также для выравнивания размера AS_PATH, передаваемых в WAN для WAN ECMP применительно к anycast-перфиксам, созданным в топологии. Для этого как правило применяется зависящая от реализации функция BGP, которую обычно называют «удаление частных AS» (Remove Private AS). В зависимости от реализации этой функции следует вырезать непрерывные цепочки частных ASN из атрибутов AS_PATH до анонсирования пути соседу. Это предполагает, что все ASN, используемые для внутренней нумерации в ЦОД, относятся к диапазонам частных номеров. Процесс вырезания частных ASN пока не стандартизован (см. [REMOVAL]). Однако большинство реализаций на практике следуют рекомендациям [VENDOR-REMOVE-PRIVATE-AS], что вполне достаточно для целей этого документа.

  • Создание принятого по умолчанию маршрута для устройств ЦОД. Это единственное место, где может быть создан такой маршрут, поскольку объединение маршрутов является рискованной задачей для немодифицированной топологии Clos. В дополнение к этому граничные маршрутизаторы могут просто ретранслировать полученный от маршрутизаторов WAN маршрут, принятый по умолчанию. Анонсирование принятого по умолчанию маршрута от граничных маршрутизаторов требует соединения всех этих маршрутизаторов с восходящими маршрутизаторами WAN для обеспечения устойчивости к отказам отдельных каналов, создающим «черные дыры» для трафика. Для предотвращения «черных дыр» в ситуациях, когда все сессии EBGP с маршрутизаторами WAN рвутся на данном устройстве одновременно, желательно заново анонсировать используемый по умолчанию маршрут вместо создания нового маршрута, принятого по умолчанию, с использованием усложненных схем условного расчета маршрута, предлагаемых отдельными реализациями [CONDITIONALROUTE].

5.2.5. Обобщение маршрутов на границе

Зачастую желательно объединить информацию о достижимости сетей до ее анонсирования в WAN по причине большого числа префиксов IP, исходящих из ЦОД при использовании полностью маршрутизируемого решения. Например, сеть с 2000 устройств Tier 3 будет давать не менее 2000 анонсов серверных подсетей в BGP вместе с префиксами инфраструктуры. Однако, как указано в параграфе 5.2.3, предлагаемое решение не позволяет обобщать маршруты по причине нехватки партнерских соединений внутри каждого уровня.

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

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

  • Устройства Tier 1 могут иметь дополнительные физические каналы в направлении граничных маршрутизаторов (которые являются устройствами Tier 2 с точки зрения уровня 1). В частности, если нужна защита от отказа отдельного канала или узла, каждое устройство Tier 1 следует соединить по крайней мере с двумя граничными маршрутизаторами. Это потребует дополнительных портов в устройствах уровня 1 и граничных маршрутизаторах, в результате чего нарушится унификация устройств, поскольку они будут отличаться от других устройств в Clos. Это также уменьшит число портов, доступных для «обычных» коммутаторов Tier 2 и, следовательно, число кластеров, которые можно будет соединить через уровень 1.

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

6. Вопросы ECMP

В этом разделе рассматривается функциональность множества равноценных путей (ECMP) для топологии Clos и некоторые специальные требования.

6.1. Базовый механизм ECMP

ECMP представляет собой фундаментальный механизм распределения нагрузки в топологии Clos. Эффективно каждое устройство нижнего уровня будет использовать все подключенные к нему напрямую устройства вышележащего уровня для распределения трафика, направленного в один префикс IP. Число путей ECMP между любыми двумя устройствами Tier 3 в топологии Clos равно числу устройств на средней ступени (Tier 1). Например, рисунок 5 показывает топологию, где устройство A на уровне 3 имеет 4 пути доступа к серверам X и Y через устройства B и C на уровне 2 и устройства 1, 2, 3 и 4 на уровне 1.

Требование ECMP предполагает, что реализация BGP должна поддерживать множество разветвляющихся путей на выходе вплоть до максимального числа устройств, напрямую подключенных к любому порту в восходящем или нисходящем направлении. Обычно в такой топологии это число не превышает половины от числа портов устройства. Например, разветвление ECMP на 32 направления будет требовать создания сети Clos с использованием 64-портовых устройств. Граничным маршрутизаторам могут потребоваться дополнительные разветвления для подключения множества устройств Tier 1, если реализовано описанное в параграфе 5.2.5 обобщение маршрутов на граничных маршрутизаторах. Если оборудование не поддерживает требуемой широты ECMP, можно использовать группировку соединений на канальном уровне (агрегирование каналов L2) для создания «иерархического» ECMP (комбинация L3 ECMP и L2 ECMP) для компенсации ограниченного ветвления. Однако это повышает риск «поляризации» потоков, поскольку снижается энтропия на второй ступени ECMP.

                           Уровень 1
                            +-----+
                            | DEV |
                         +->|  1  |--+
                         |  +-----+  |
               Уровень 2 |           | Уровень 2
                +-----+  |  +-----+  |  +-----+
  +------------>| DEV |--+->| DEV |--+--|     |-------------+
  |       +-----|  B  |--+  |  2  |  +--|     |-----+       |
  |       |     +-----+     +-----+     +-----+     |       |
  |       |                                         |       |
  |       |     +-----+     +-----+     +-----+     |       |
  | +-----+---->| DEV |--+  | DEV |  +--|     |-----+-----+ |
  | |     | +---|  C  |--+->|  3  |--+--|     |---+ |     | |
  | |     | |   +-----+  |  +-----+  |  +-----+   | |     | |
  | |     | |            |           |            | |     | |
+-----+ +-----+          |  +-----+  |          +-----+ +-----+
| DEV | |     |Уровень 3 +->| DEV |--+ Уровень 3|     | |     |
|  A  | |     |             |  4  |             |     | |     |
+-----+ +-----+             +-----+             +-----+ +-----+
  | |     | |                                     | |     | |
  O O     O O            <- Серверы ->            X Y     O O

Рисунок 5. Дерево разветвления (Fan-Out Tree) ECMP от A к X и Y.


Большинство реализаций BGP объявляют равноценность путей с точки зрения ECMP, если они соответствуют требованиям параграфа 9.1.2.2 [RFC4271] до п. (e) включительно. В предлагаемом решении нет нижележащего IGP, поэтому стоимость IGP принимается равной 0 или в противном случае может применяться одинаковое значение для всех путей и правил, требуемое для выравнивания атрибутов BGP (таких, как MULTI_EXIT_DISC (MED) и код источника), которые могут меняться у разных производителей. В силу исторических причин лучше не использовать 0 в качестве уравнивающего значения MED (описание этого и другая полезная информация BGP приведены в [RFC4277]). Маршрутные петли маловероятны вследствие использования процесса выбора лучшего пути BGP (который предпочитает наименьший размер AS_PATH), а более длинные пути через устройства Tier 1 (которые не разрешают в пути свой ASN) невозможны.

6.2. BGP ECMP через множество AS

Для распределения нагрузки приложений желательно анонсировать один и тот же префикс от множества устройств Tier 3. С точки зрения других устройств такой префикс будет иметь пути BGP с разными атрибутами AS_PATH одинакового размера. Поэтому реализации BGP должны поддерживать распределение нагрузки между такими путями. Это свойство иногда называют multipath relax или multipath multiple-AS и оно эффективно обеспечивает ECMP через разные соседние ASN, если другие атрибуты совпадают, как описанно в предыдущем параграфе.

6.3. Взвешенный ECMP

Может оказаться желательной реализация устройством «взвешенного» ECMP для того, чтобы передавать больше трафика через отдельные ветви ECMP. Это может быть полезно при компенсации отказов в сети или для передачи большего объема через пути с большей пропускной способностью. Префиксы, которым нужен взвешенный ECMP, будут вноситься с использованием удаленного узла BGP (центральный агент) через multi-hop-сессию, как будет описано в параграфе 8.1. Если реализация поддерживает это, распределение весов между путями BGP может быть передано с использованием метода, описанного в [LINK].

6.4. Согласованное хэширование

Часто желательно, чтобы функция хэширования для ECMP была согласованной (см. [CONS-HASH]) для минимизации воздействия на поток изменения близости next-hop при добавлении или удалении следующего интервала в группе ECMP. Это может применяться для устройств, работающих в качестве балансировщиков, отображающих потоки в направлении множества получателей, — в этом случае потеря или добавление получателя не окажет негативного влияния на существующие потоки. Одна из конкретных рекомендаций по реализации согласованного хэширования представлена в [RFC2992], хотя возможны и другие варианты. Эта функциональность может естественным путем комбинироваться со взвешенным ECMP, при этом влияние смены следующего интервала будет пропорционально весу данного next-hop. Обратной стороной согласованного хэширования является рост использования аппаратных ресурсов, поскольку для ее реализации обычно нужно больше ресурсов (например, пространства TCAM22).

7. Схождение маршрутов

В этом разделе рассматриваются свойства схождения маршрутов для предложенного решения. Отмечено, что достижимо схождение за доли секунды, если реализация поддерживает быструю деактивацию сессий EBGP и своевременно обновляет RIB и FIB при отказе связанного канала.

7.1. Время обнаружения отказов

BGP обычно опирается на IGP для обхода отказавших каналов и узлов внутри AS и реализует основанный на опросе или событиях механизм получения обновлений о смене состояний IGP. Предложенный вариант маршрутизации не использует IGP, поэтому для обнаружения отказов остается тайм-аутBGP keep-alive (или иной механизм keep-alive) или триггеры отказа каналов.

Опора исключительно на пакеты BGP keep-alive может привести к значительной задержке схождения до многих секунд (во многих реализациях BGP минимальное значение таймера удержания BGP составляет 3 секунды). Однако многие реализации BGP могут закрывать локальные партнерские сессии EBGP в ответ на событие link down (канал отключен) на исходящем интерфейсе партнерской сессии BGP. Это свойство иногда называют fast fallover (быстрое «падение»). Поскольку каналы в современных ЦОД представляют собой преимущественно оптические соединения «точка-точка», отказ физического интерфейса часто обнаруживается за миллисекунды и инициирует пересчет маршрутов BGP.

Каналы Ethernet могут поддерживать стандарты сигнализации и детектирования отказов типа CFM23, описанного в [IEEE8021Q], это делает детектирование отказов более надежным. Кроме того, некоторые платформы могут поддерживать BFD24 [RFC5880], позволяющее обнаруживать отказы каналов и сообщать о них процессу BGP за доли секунды. Однако использование любого из этих методов предъявляет дополнительные требования к фирменным программам и, возможно, оборудованию, а также может противоречить REQ1. До недавнего времени ([RFC7130]) метод BFD также не поддерживал детектирования отказов одного канала в LAG, что ограничивало его применимость.

7.2. Время распространения событий

В предлагаемом решении следует учитывать влияние BGP MinRouteAdvertisementIntervalTimer (таймер MRAI), как указано в параграфе 9.2.1.1 [RFC4271]. По стандарту реализации BGP должны разделять последовательные сообщения BGP UPDATE интервалом не менее MRAI, который часто задается в конфигурации. На начальные сообщения BGP UPDATE после события, связанного с отзывом маршрута, этот таймер обычно не влияет. Таймер MRAI может существенно задерживать схождение когда узел BGP «ждет» получения от партнеров нового пути и не имеет локальной резервной копии информации о путях.

В топологии Clos каждый узел EBGP обычно имеет один путь (устройства Tier 2 не воспринимают пути от других устройств Tier 2 в том же кластере, поскольку у них тот же номер ASN) или N путей для одного префикса, где N имеет достаточно большое значение, например 32 (разветвление ECMP на следующий уровень). Поэтому при отказе канала к другому устройству, от которого получен путь, резервного пути не будет совсем (например, с точки зрения коммутатора Tier 2, теряющего соединение с устройством Tier 3) либо он будет легко доступен в BGP Loc-RIB (например, с точки зрения устройства Tier 2, теряющего соединение с коммутатором Tier 1). В первом случае анонс отзыва BGP будет распространяться без задержки и вызовет пересчет маршрутов на затронутых устройствах. Во втором случае лучший путь будет оцениваться заново и локальная группа ECMP, соответствующая новому значению next-hop, будет изменена. Если путь BGP был ранее лучшим, «неявный отзыв» будет передаваться в сообщении BGP UPDATE, как описано в варианте b параграфа 3.1 [RFC4271] по причине изменения атрибута BGP AS_PATH.

7.3. Влияние разветвлений топологии Clos

Топология Clos имеет большие разветвления, которые могут в некоторых случаях влиять на схождение Up→Down, как описано в этом параграфе. В случае отказа канала между устройствами уровней 3 и 2, устройство Tier 2 будет передавать сообщения BGP UPDATE всем восходящим устройствам 1, отзывая затронутые префиксы. Устройства Tier 1, в свою очередь, будут ретранслировать эти сообщения своим нисходящим устройствам Tier 2 (исключая инициатора). Устройствам Tier 2 кроме инициатора UPDATE следует дождаться пока все восходящие устройства Tier 1 передадут сообщение UPDATE и только после этого удалять префиксы и передавать соответствующие сообщения UPDATE в нисходящем направлении подключенным устройствам Tier 3. Если исходное устройство Tier 2 или ретранслирующие устройства Tier 1 вносят ту или иную задержку в распространение сообщений UPDATE, в результате может возникнуть «рассеяние» UPDATE, которое может длиться многие секунды. Для предотвращения этого реализации BGP должны поддерживать «группы обновления» (update groups). Группа обновления определяется как набор соседей с общей выходной политикой — локальный узел будет синхронно передавать обновления BGP членам группы.

Влияние такого «рассеяния» возрастает с ростом разветвления топологии и может расти также во время схождения. У некоторых операторов может возникнуть соблазн использовать подавление маршрутных осцилляций (route flap dampening), которое производители включают для снижения воздействия на уровень управления быстрых осцилляций префиксов. Однако в результате известных проблем с ложными срабатываниями в таких реализациях (особенно при таких «рассеянных» событиях), не рекомендуется пользоваться этой функцией в предложенном решении. Дополнительную информацию о подавлении маршрутных осцилляций и связанных с ним изменением в реализациях можно найти в [RFC7196].

7.4. Область влияния отказа

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

BGP ведет себя подобно протоколам distance-vector в том смысле, что соседям передается только лучший путь с точки зрения локального маршрутизатора. Поэтому часть отказов маскируется, если локальный узел незамедлительно нашел резервный путь и больше не передал никаких обновлений. Отметим, что в худшем случае все устройства в ЦОД будут отзывать префикс полностью или обновят группы ECMP в своих FIB. Однако многие отказы не связаны со столь широким охватом. Есть два основных типа отказов, для которых зона влияния может быть сужена.

  • Отказ канала между устройствами Tier 2 и Tier 1. В этом случае устройство уровня 2 будет обновлять затронутые группы ECMP, удаляя отказавший канал. Здесь не нужно передавать новую информацию нисходящим устройствам Tier 3, пока путь не был выбран в качестве лучшего процессом BGP — в этом случае требуется передать лишь «неявный отзыв» и это не должно влиять на пересылку. Затронутое устройство Tier 1 потеряет лишь путь к отдельному кластеру и будет отзывать соответствующие префиксы. Этот процесс отзыва префиксов будет влиять лишь на устройства Tier 2, напрямую подключенные к затронутому устройству уровня 1. Устройства Tier 2, получившие сообщение BGP UPDATE с отзывом префиксов, будут просто обновлять свои группы ECMP. Устройства уровня 3 не будут вовлечены в процесс повторного схождения.

  • Отказ устройства Tier 1. В этом случае все устройства уровня 2, напрямую подключенные к отказавшему узлу, будут обновлять свои группы ECMP для всех префиксов IP из нелокального кластера. Устройство Tier 3 и в этом случае не будут вовлечены в процесс повторного схождения, но могут получать «неявные отзывы», как указано выше.

Даже при таких отказах, которые требуют перепрограммировать множество IP префиксов в FIB, следует отметить, что эти префиксы будут относиться к одной группе ECMP на устройстве Tier 2. Поэтому для реализации с иерархической базой FIB потребуется единственное изменение в FIB. Иерархической здесь считается FIB, в которой информация next-hop хранится отдельно от таблицы префиксов и в последней содержатся лишь указатели на соответствующие данные пересылки. Описание иерархий FIB и быстрого схождения приведено в [BGP-PIC].

Хотя BGP обеспечивает в некоторых случаях уменьшение зоны влияния отказа, дополнительное уменьшение этой зоны с помощью обобщения не всегда доступно в предложенном решении, поскольку обобщение маршрутов может создавать маршрутные «черные дыры», как было отмечено выше. Поэтому худшим вариантом зоны влияния отказа является уровень управления сети в целом, например в случае отказа на канале между устройствами уровня 2 и 3. Число затронутых отказом префиксов здесь будет много меньше, чем при отказе на верхних уровнях топологии Clos. Столь обширная зона влияния отказа является не результатом выбора решения на основе EBGP, а скорее свойством топологии Clos.

7.5. Микропетли в маршрутизации

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

Для снижения влияния таких микропетель на коммутаторах уровней 2 и 1 можно задать статические маршруты discard или null, которые будут более конкретными по сравнению с принятым по умолчанию маршрутом для утраченного префикса во время схождения. Для коммутаторов Tier 2 отбрасывающий (discard) маршрут должен быть обобщением, включающим все серверные подсети нижележащих устройств Tier 3. Для устройств уровня 1 маршрут отбрасывания следует делать обобщением, включающим подсети серверов, выделенные для всего ЦОД. Эти discard-маршруты будут иметь предпочтение лишь во время схождения, пока устройство ищет более конкретные префиксы через новый путь.

8. Дополнительные варианты

8.1. Вставка стороннего маршрута

BGP позволяет «стороннему» партнеру (т. е. подключенному напрямую узла BGP) внедрять маршруты в любой точке сетевой топологии во исполнение требования REQ5. Это можно реализовать путем организации multi-hop-сессий BGP с некоторыми или даже всеми устройствами в рамках топологии. Кроме того широкое распространение путей BGP [RFC6774] можно использовать для вставки множества BGP next-hop для одного префикса с целью упрощения балансировки трафика или использовать свойство BGP ADD-PATH [RFC7911], если реализация поддерживает его. К сожалению во многих реализациях обнаружено, что ADD-PATH поддерживает IBGP только в тех случаях, для которых это свойство было изначально оптимизировано. Это ограничивает партнерство third-party только устройствами IBGP.

Для реализации внедрения маршрутов в предлагаемом решении сторонний узел BGP может быть партнером коммутаторов уровня 3 и 1, внедряя один и тот же префикс, но используя специальный набор BGP next-hop для устройств Tier 1. Предполагается что эти next-hop рекурсивно преобразуются через BGP и могут быть, например, IP-адресами устройств Tier 3. Получаемые в результате таблицы пересылки могут обеспечивать желаемое распределение трафика между разными кластерами.

8.2. Обобщение маршрутов в топологии Clos

Как было отмечено выше, обобщение маршрутов в предложенной топологии Clos невозможно, поскольку оно делает сеть уязвимой к маршрутным «черным дырам» при отказах отдельных каналов. Основная проблема заключается в ограниченном числе избыточных путей между элементами сети (например, существует единственный путь между любой парой устройств уровней 1 и 3). Однако некоторые операторы могут счесть агрегирование маршрутов желательным для повышения стабильности уровня управления.

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

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

8.2.1. «Свертывание» устройств уровня 1

Для добавления путей между устройствами Tier 1 и Tier 3 устройства уровня 2 группируются попарно и пары подключаются к одной группе устройств Tier 1. Это логически эквивалентно «свертыванию» (collapsing) устройств Tier 1 в группу половинного размера с объединением каналов на «свернутых» устройствах. Результат такого свертывания показан на рисунке 6. Например, в этой топологии устройства DEV C и DEV D подключены к одному набору устройств Tier 1 (DEV 1 и DEV 2), тогда как до этого они были подключены к разным группам устройств Tier 1.

               Уровень 2    Уровень 1    Уровень 2
                +-----+      +-----+      +-----+
  +-------------| DEV |------| DEV |------|     |-------------+
  |       +-----|  C  |--++--|  1  |--++--|     |-----+       |
  |       |     +-----+  ||  +-----+  ||  +-----+     |       |
  |       |              ||           ||              |       |
  |       |     +-----+  ||  +-----+  ||  +-----+     |       |
  | +-----+-----| DEV |--++--| DEV |--++--|     |-----+-----+ |
  | |     | +---|  D  |------|  2  |------|     |---+ |     | |
  | |     | |   +-----+      +-----+      +-----+   | |     | |
  | |     | |                                       | |     | |
+-----+ +-----+                                   +-----+ +-----+
| DEV | | DEV |                                   |     | |     |
|  A  | |  B  | Уровень 3               Уровень 3 |     | |     |
+-----+ +-----+                                   +-----+ +-----+
  | |     | |                                       | |     | |
  O O     O O             <- Серверы ->             O O     O O

Рисунок 6. 5-ступенчатая топология Clos.


Для такого решения устройства Tier 2 можно настроить на анонсирование устройствам уровня 3 лишь принятого по умолчанию маршрута. При отказе канала между устройствами Tier 2 и Tier 3 трафик будет перемаршрутизирован через второй доступный путь, известный коммутатору Tier 2. Пока еще невозможно анонсировать сводный маршрут, включающий префиксы для одного кластера от устройств Tier 2, поскольку каждое из них имеет лишь один путь вниз к этому префиксу. Для решения задачи потребуются двудомные серверы. Отметим также, что это решение устойчиво лишь к отказам одного канала. При отказе двух каналов, изолирующем устройство Tier 2 от всех путей к конкретному устройству Tier 3, возникнет «черная дыра» в маршрутизации.

Результатом предложенного изменения топологии будет снижение числа портов на устройствах Tier 1. Это ограничит максимальное число подключенных устройств Tier 2 и в результате будет ограничивать общий размер сети ЦОД. Для более крупной сети потребуются устройства Tier 1 с более высокой плотностью портов.

Другой проблемой является перебалансировка трафика при отказах каналов. Поскольку имеется два пути от Tier 1 к Tier 3, отказ канала между коммутаторами уровней 1 и 2 приведе к тому, что весь трафик отказавшего канала будет перенесен на оставшийся путь. Это приведет к удвоению загрузки оставшегося канала.

8.2.2. Простое виртуальное агрегирование

Совершенно иной путь к обобщению маршрутов возможен в том случае, когда основной целью является снижение размера FIB, что позволит уровню управления распространять всю маршрутную информацию. Во-первых, легко заметить, что множество префиксов, часть из которых менее конкретна, использует общий набор next-hop (одна группа ECMP). Например, с точки зрения устройств Tier 3 все маршруты, полученные от восходящих устройств Tier 2 (включая принятый по умолчанию маршрут), будут использовать один набор BGP next-hop при условии отсутствия отказов в сети. Это позволяет использовать методы, похожие на описанный в [RFC6769] и устанавливать в FIB только наименее конкретный маршрут, игнорируя более конкретные, если они используют тот же набор next-hop. Например, при нормальной работе сети в FIB нужно включать лишь принятый по умолчанию маршрут.

Кроме того, если устройства Tier 2 настроены с обобщенными префиксами, включающими префиксы всех подключенных к ним устройств Tier 3, такая же логика применима для устройств Tier 1 путем включения коммутаторов Tier 2/Tier 3 в разные кластеры. Эти обобщенные маршруты позволят отдавать более конкретные префиксы устройствам Tier 1, что позволит детектировать рассогласование наборов next-hop при отказе отдельного канала и менять набор next-hop для конкретного префикса.

Повторим, что этот метод не снижает число состояний на уровне управления (т. е. размер BGP UPDATEs, BGP Loc-RIB), но позволяет более эффективно использовать FIB за счет нахождения более конкретных префиксов и использования их набора next-hop для менее конкретного префикса.

8.3. Маскирование сообщений ICMP Unreachable

В этом параграфе рассматриваются некоторые эксплуатационные аспекты отказа от анонсирования префиксов каналов «точка-точка» в BGP, отмеченные в параграфе 5.2.3. Влияние этого решения может проявиться при использовании популярной утилиты traceroute. В частности, IP-адреса, отображаемые программой, будут включать и адреса каналов «точка-точка», которые при таком решении недоступны для подключения. Это несколько усложняет поиск неполадок.

Одним из способов решения этой проблемы является использование подсистемы DNS для создания «реверсных» записей для IP-адресов таких каналов «точка-точка» с именами как для адреса петлевого интерфейса (loopback). Связность в этом случает может быть обеспечена путем преобразования «основного» IP-адреса устройства, например, его интерфейса Loopback, который всегда анонсируется в BGP. Однако это создает зависимость от подсистемы DNS, которая может оказаться недоступно во время отказов.

Другим вариантом является маскирование устройством адресов IP, т. е. замена IP-адреса отправителя в соответствующих сообщениях ICMP «основным» адресом устройства. В частности, такая замена требуется в сообщениях ICMP Destination Unreachable Message (тип 3) с кодом 3 (порт недоступен) и ICMP Time Exceeded (тип 11) с кодом 0 для корректной работы программы traceroute. При таком маскировании пробные пакеты traceroute, передаваемые устройствам, всегда будут приводит к отправке откликов с «основного» IP-адреса устройства, что позволит оператору увидеть «доступный» IP-адрес устройства. Недостатком этого подхода является сокрытие «точки входа» в устройство. Если устройство поддерживает [RFC5837], оно сможет предоставить информацию о входном интерфейсе даже при возврате пакетов с «основного» адреса IP.

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

Рассмотренное здесь решение не создает новых проблем безопасности. Общие вопросы безопасности BGP рассмотрены в [RFC4271] и [RFC4272]. Поскольку домен ЦОД относится к одному оператору, в этом документе предполагается наличие фильтрации для предотвращения атак на сессии BGP извне. Для большинства реализаций это будет более подходящим вариантом, чем использование управления ключами для TCP MD5, описанное в [RFC2385], или реализациями опции аутентификации TCP [RFC5925]. Можно также использовать обобщенный механизм защиты с помощью TTL [RFC5082] для предотвращения подмены сессий BGP.

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

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

[RFC4271] Rekhter, Y., Ed., Li, T., Ed., and S. Hares, Ed., «A Border Gateway Protocol 4 (BGP-4)», RFC 4271, DOI 10.17487/RFC4271, January 2006, <http://www.rfc-editor.org/info/rfc4271>.

[RFC6996] Mitchell, J., «Autonomous System (AS) Reservation for Private Use», BCP 6, RFC 6996, DOI 10.17487/RFC6996, July 2013, <http://www.rfc-editor.org/info/rfc6996>.

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

[ALFARES2008] Al-Fares, M., Loukissas, A., and A. Vahdat, «A Scalable, Commodity Data Center Network Architecture», DOI 10.1145/1402958.1402967, August 2008, <http://dl.acm.org/citation.cfm?id=1402967>.

[ALLOWASIN] Cisco Systems, «Allowas-in Feature in BGP Configuration Example», February 2015, <http://www.cisco.com/c/en/us/support/docs/ip/border-gateway-protocol-bgp/112236-allowas-in-bgp-config-example.html>.

[BGP-PIC] Bashandy, A., Ed., Filsfils, C., and P. Mohapatra, «BGP Prefix Independent Convergence», Work in Progress, draft-ietf-rtgwg-bgp-pic-02, August 2016.

[CLOS1953] Clos, C., «A Study of Non-Blocking Switching Networks», The Bell System Technical Journal, Vol. 32(2), DOI 10.1002/j.1538-7305.1953.tb01433.x, March 1953.

[CONDITIONALROUTE] Cisco Systems, «Configuring and Verifying the BGP Conditional Advertisement Feature», August 2005, <http://www.cisco.com/c/en/us/support/docs/ip/border-gateway-protocol-bgp/16137-cond-adv.html>.

[CONS-HASH] Wikipedia, «Consistent Hashing», July 2016, <https://en.wikipedia.org/w/index.php?title=Consistent_hashing&oldid=728825684>.

[FB4POST] Farrington, N. and A. Andreyev, «Facebook’s Data Center Network Architecture», May 2013, <http://nathanfarrington.com/papers/facebook-oic13.pdf>.

[GREENBERG2009] Greenberg, A., Hamilton, J., and D. Maltz, «The Cost of a Cloud: Research Problems in Data Center Networks», DOI 10.1145/1496091.1496103, January 2009, <http://dl.acm.org/citation.cfm?id=1496103>.

[HADOOP] Apache, «Apache Hadoop», April 2016, <https://hadoop.apache.org/>.

[IANA.AS] IANA, «Autonomous System (AS) Numbers», <http://www.iana.org/assignments/as-numbers>.

[IEEE8021D-1990] IEEE, «IEEE Standard for Local and Metropolitan Area Networks: Media Access Control (MAC) Bridges», IEEE Std 802.1D, DOI 10.1109/IEEESTD.1991.101050, 1991, <http://ieeexplore.ieee.org/servlet/opac?punumber=2255>.

[IEEE8021D-2004] IEEE, «IEEE Standard for Local and Metropolitan Area Networks: Media Access Control (MAC) Bridges», IEEE Std 802.1D, DOI 10.1109/IEEESTD.2004.94569, June 2004, <http://ieeexplore.ieee.org/servlet/opac?punumber=9155>.

[IEEE8021Q] IEEE, «IEEE Standard for Local and Metropolitan Area Networks: Bridges and Bridged Networks», IEEE Std 802.1Q, DOI 10.1109/IEEESTD.2014.6991462, <http://ieeexplore.ieee.org/servlet/opac?punumber=6991460>.

[IEEE8023AD] IEEE, «Amendment to Carrier Sense Multiple Access With Collision Detection (CSMA/CD) Access Method and Physical Layer Specifications — Aggregation of Multiple Link Segments», IEEE Std 802.3ad, DOI 10.1109/IEEESTD.2000.91610, October 2000, <http://ieeexplore.ieee.org/servlet/opac?punumber=6867>.

[INTERCON] Dally, W. and B. Towles, «Principles and Practices of Interconnection Networks», ISBN 978-0122007514, January 2004, <http://dl.acm.org/citation.cfm?id=995703>.

[JAKMA2008] Jakma, P., «BGP Path Hunting», 2008, <https://blogs.oracle.com/paulj/entry/bgp_path_hunting>.

[L3DSR] Schaumann, J., «L3DSR — Overcoming Layer 2 Limitations of Direct Server Return Load Balancing», 2011, <https://www.nanog.org/meetings/nanog51/presentations/Monday/NANOG51.Talk45.nanog51-Schaumann.pdf>.

[LINK] Mohapatra, P. and R. Fernando, «BGP Link Bandwidth Extended Community», Work in Progress, draft-ietf-idr-link-bandwidth-06, January 2013.

[REMOVAL] Mitchell, J., Rao, D., and R. Raszuk, «Private Autonomous System (AS) Removal Requirements», Work in Progress, draft-mitchell-grow-remove-private-as-04, April 2015.

[RFC2328] Moy, J., «OSPF Version 2», STD 54, RFC 2328, DOI 10.17487/RFC2328, April 1998, <http://www.rfc-editor.org/info/rfc2328>.

[RFC2385] Heffernan, A., «Protection of BGP Sessions via the TCP MD5 Signature Option», RFC 2385, DOI 10.17487/RFC2385, August 1998, <http://www.rfc-editor.org/info/rfc2385>.

[RFC2992] Hopps, C., «Analysis of an Equal-Cost Multi-Path Algorithm», RFC 2992, DOI 10.17487/RFC2992, November 2000, <http://www.rfc-editor.org/info/rfc2992>.

[RFC4272] Murphy, S., «BGP Security Vulnerabilities Analysis», RFC 4272, DOI 10.17487/RFC4272, January 2006, <http://www.rfc-editor.org/info/rfc4272>.

[RFC4277] McPherson, D. and K. Patel, «Experience with the BGP-4 Protocol», RFC 4277, DOI 10.17487/RFC4277, January 2006, <http://www.rfc-editor.org/info/rfc4277>.

[RFC4786] Abley, J. and K. Lindqvist, «Operation of Anycast Services», BCP 126, RFC 4786, DOI 10.17487/RFC4786, December 2006, <http://www.rfc-editor.org/info/rfc4786>.

[RFC5082] Gill, V., Heasley, J., Meyer, D., Savola, P., Ed., and C. Pignataro, «The Generalized TTL Security Mechanism (GTSM)», RFC 5082, DOI 10.17487/RFC5082, October 2007, <http://www.rfc-editor.org/info/rfc5082>.

[RFC5837] Atlas, A., Ed., Bonica, R., Ed., Pignataro, C., Ed., Shen, N., and JR. Rivers, «Extending ICMP for Interface and Next-Hop Identification», RFC 5837, DOI 10.17487/RFC5837, April 2010, <http://www.rfc-editor.org/info/rfc5837>.

[RFC5880] Katz, D. and D. Ward, «Bidirectional Forwarding Detection (BFD)», RFC 5880, DOI 10.17487/RFC5880, June 2010, <http://www.rfc-editor.org/info/rfc5880>.

[RFC5925] Touch, J., Mankin, A., and R. Bonica, «The TCP Authentication Option», RFC 5925, DOI 10.17487/RFC5925, June 2010, <http://www.rfc-editor.org/info/rfc5925>.

[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, <http://www.rfc-editor.org/info/rfc6325>.

[RFC6769] Raszuk, R., Heitz, J., Lo, A., Zhang, L., and X. Xu, «Simple Virtual Aggregation (S-VA)», RFC 6769, DOI 10.17487/RFC6769, October 2012, <http://www.rfc-editor.org/info/rfc6769>.

[RFC6774] Raszuk, R., Ed., Fernando, R., Patel, K., McPherson, D., and K. Kumaki, «Distribution of Diverse BGP Paths», RFC 6774, DOI 10.17487/RFC6774, November 2012, <http://www.rfc-editor.org/info/rfc6774>.

[RFC6793] Vohra, Q. and E. Chen, «BGP Support for Four-Octet Autonomous System (AS) Number Space», RFC 6793, DOI 10.17487/RFC6793, December 2012, <http://www.rfc-editor.org/info/rfc6793>.

[RFC7067] Dunbar, L., Eastlake 3rd, D., Perlman, R., and I. Gashinsky, «Directory Assistance Problem and High-Level Design Proposal», RFC 7067, DOI 10.17487/RFC7067, November 2013, <http://www.rfc-editor.org/info/rfc7067>.

[RFC7130] Bhatia, M., Ed., Chen, M., Ed., Boutros, S., Ed., Binderberger, M., Ed., and J. Haas, Ed., «Bidirectional Forwarding Detection (BFD) on Link Aggregation Group (LAG) Interfaces», RFC 7130, DOI 10.17487/RFC7130, February 2014, <http://www.rfc-editor.org/info/rfc7130>.

[RFC7196] Pelsser, C., Bush, R., Patel, K., Mohapatra, P., and O. Maennel, «Making Route Flap Damping Usable», RFC 7196, DOI 10.17487/RFC7196, May 2014, <http://www.rfc-editor.org/info/rfc7196>.

[RFC7911] Walton, D., Retana, A., Chen, E., and J. Scudder, «Advertisement of Multiple Paths in BGP», RFC 7911, DOI 10.17487/RFC7911, July 2016, <http://www.rfc-editor.org/info/rfc7911>.

[VENDOR-REMOVE-PRIVATE-AS] Cisco Systems, «Removing Private Autonomous System Numbers in BGP», August 2005, <http://www.cisco.com/en/US/tech/tk365/technologies_tech_note09186a0080093f27.shtml>.

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

Эта публикация обобщает работу многих людей, принимавших участие в разработке, тестировании и развертывании предложенного варианта устройства сетей, среди которых были George Chen, Parantap Lahiri, Dave Maltz, Edet Nkposong, Robert Toomey и Lihua Yuan. Авторы благодарны Linda Dunbar, Anoop Ghanwani, Susan Hares, Danny McPherson, Robert Raszuk и Russ White за рецензирование документа и отклики на него, а также Mary Mitchell за предложения по грамматике и стилю.

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

Petr Lapukhov

Facebook

1 Hacker Way

Menlo Park, CA 94025

United States of America

Email: petr@fb.com

Ariff Premji

Arista Networks

5453 Great America Parkway

Santa Clara, CA 95054

United States of America

Email: ariff@arista.com

URI: http://arista.com/

Jon Mitchell (editor)

Email: jrmitche@puck.nether.net


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

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

nmalykh@gmail.com

1Internet Engineering Task Force.

2Internet Engineering Steering Group.

3External BGP.

4Layer 2 — канальный уровень.

5Capital Expenditures.

6Operational Expenditure.

7Equal Cost Multipath — множество равноценных путей.

8Top-of-Rack — наверху стойки.

9Link aggregation group — группа объединения каналов.

10Spanning Tree Protocol.

11Rapid Spanning Tree Protocol — ускоренный протокол STP.

12Multiple Spanning Tree Protocol — множество экземпляров остовного дерева STP.

13Multi-Chassis Link-Aggregation — объединение каналов от нескольких устройств (шасси).

14Transparent Interconnection of Lots of Links — прозрачное соединение большого числа каналов.

15Direct Server Return.

16Interior Gateway Protocol.

17Open Shortest Path First — сначала кратчайший путь.

18Internal BGP — внутренний BGP.

19Routing Information Base — база маршрутной информации.

20Forwarding Information Base — база информации о пересылке.

21Wide Area Network — распределенная (глобальная) сеть.

22Ternary Content-Addressable Memory — троичная ассоциативная память.

23Connectivity Fault Management — контроль отказов связности.

24Bidirectional Forwarding Detection — двухстороннее детектирование пересылки.




RFC 7962 Alternative Network Deployments: Taxonomy, Characterization, Technologies, and Architectures

Internet Research Task Force (IRTF)                      J. Saldana, Ed.
Request for Comments: 7962                        University of Zaragoza
Category: Informational                                   A. Arcia-Moret
ISSN: 2070-1721                                  University of Cambridge
                                                                B. Braem
                                                                  iMinds
                                                         E. Pietrosemoli
                                                    The Abdus Salam ICTP
                                                         A. Sathiaseelan
                                                 University of Cambridge
                                                              M. Zennaro
                                                    The Abdus Salam ICTP
                                                             August 2016

 

Развертывание дополнительных сетей — систематизация, характеристики, топология, архитектура

Alternative Network Deployments:

Taxonomy, Characterization, Technologies, and Architectures

PDF

Тезисы

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

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

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

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

Этот документ не является спецификацией какого-либо стандарта Internet (Internet Standards Track) и публикуется с информационными целями.

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

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

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

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

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

Оглавление

Исключено в версии HTML.

1. Введение

Одной из целей исследовательской группы IRTF GAIA4 является документирование и публикация сведений о результатах исследований и опыте развертывания для широкого круга читателей [GAIA]. В соответствии с этой целью данный документ предлагает классификацию дополнительных сетей (Alternative Network Deployment). Рассматривается множество моделей доступа в сеть, разработанных в последнее десятилетие для подключения к Internet, для которых топология, архитектура, управление и бизнес-модели отличаются от так называемых «основных сетей» (mainstream), в которых компании развертывают инфраструктуру для пользователей, оплачивающих услуги доступа в сеть.

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

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

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

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

1.1. Основные сети

В этом документе термин «основные сети» (mainstream networks) означает сети со следующими характеристиками:

  • в части масштаба это обычно крупные сети, распространяющиеся на целые регионы;

  • вертикальное управление сетью и централизованная модель;

  • значительные инвестиции в инфраструктуру;

  • пользователи сети не участвуют в разработке, развертывании, эксплуатации и управлении;

  • права собственности на сеть не принадлежат ее пользователям.

1.2. Дополнительные сети

Термин «дополнительные сети» (Alternative Network), предложенный в этом документе, относится к сетям, характеристики которых отличаются от характеристик основных сетей. Отметим здесь некоторые из них:

  • сравнительно небольшой масштаб (например, меньше целых регионов);

  • децентрализованное администрирование;

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

  • пользователи могут участвовать в создании, развертывании, поддержке и обслуживании сетей;

  • владельцами сетей зачастую являются пользователи.

2. Используемые термины

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

  • «Глобальный север» (Global north) и «глобальный юг» (global south). Хотя в терминологии описания уровней развития разных стран нет общего согласия, здесь будет применяться термин «глобальный юг» применительно к странам со сравнительно низкими жизненными стандартами. Такое деление обычно служит для отражения базовых экономических условий в разных странах. Обычно Японию в Азии, Канаду и США в Северной Америке, Австралию и Новую Зеландию в Океании, а также Европа в целом рассматриваются как «развитые» регионы [UN] и применительно к ним будет использоваться термин «глобальный север».

  • «Цифровой разрыв» (Digital Divide). При оценке состояния развития цифровых технологий в стране принимается во внимание ряд аспектов: инфраструктура (наличие и доступность), сектор ICT6 (человеческий фактор и технологическая индустрия), компьютерная грамотность, правовая и нормативная база, информационное наполнение и услуги. Недостаточное развитие в одном или нескольких указанных направлениях будем называть «цифровым разрывом» (Digital Divide) [Norris]. Следует отметить, что такой разрыв может наблюдаться не только между разными странами, но и между зонами в одной стране, несмотря на ее уровень развития в целом.

  • Городские и сельские территории. Не существует общепринятых определений сельской местности (rural) и города (urban), каждая страна и различные международные организации трактуют эти термины по своему, принимая во внимание число жителей, плотность заселения, расстояния между домами [UNStats]. В контексте сетей основным различием являются расстояния между потребителями, обычно определяемое плотностью населения, а также удаленность от ближайшей точки доступа в Internet (протяженность «средней мили» (middle mile) или транспортного подключения). В некоторых регионах с малой средней плотностью населения практически все потенциальные потребители могут быть сконцентрированы в небольших компактных поселениях, а в других регионах они могут сравнительно равномерно распределяться по всей территории.

  • Потребности. В экономике они описывают желание и возможность потребителей покупать за определенную цену некий товар или услугу.

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

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

  • Свободные, открытые и нейтральные сети. Принципы таких сетей перечислены ниже [Baig].

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

    • Вы можете понимать сеть, знать ее компоненты и распространять информацию об этих механизмах и принципах.

    • Вы имеете право предлагать информационное содержимое и услуги в сеть на своих условиях.

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

3. Сценарии развертывания дополнительных сетей

Разные исследования показывают, что около 60% населения планеты не имеют доступа [Sprague] [InternetStats]. Эти люди распределены по планете неравномерно — на «глобальном юге» доступ в сеть по данным 2014 г. имеет всего 31% населения, тогда как в странах «глобального севера» эта доля достигает 80% [WorldBank2016]. Это послужило одной из причин включения цели «значительно улучшить доступ к информационным и коммуникационным технологиям, а также стремиться обеспечить универсальный и недорогой доступ в Internet для наименее развитых стран в 2020 г.» в качестве одной из целей устойчивого развития (SDG7) [SDG], указанной, как «Goal 9. Build resilient infrastructure, promote inclusive and sustainable industrialization and foster innovation8

В целях настоящего документа различия между «глобальным севером» и «глобальным югом» в части ICT оцениваются в плане:

  • доступности внутренней и международной канальной емкости (полосы), а также оборудования;

  • сложности оплаты услуг и устройств, требуемых для доступа к ICT;

  • нестабильности и/или нехватки электропитания;

  • нехватки квалифицированного персонала;

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

В этом контексте деятельность ВВУИО9 [WSIS] направлена на «построение ориентированного на интересы людей, открытого для всех и направленного на развитие информационного общества, в котором каждый мог бы создавать информацию и знания, иметь к ним доступ, пользоваться и обмениваться ими, с тем чтобы дать отдельным лицам, общинам и народам возможность в полной мере реализовать свой потенциал, содействуя своему устойчивому развитию и повышая качество своей жизни». ВВУИО также призывает «правительства, частный сектор, общественные и международные организации» прилагать усилия по преодолению «цифрового разрыва».

Некоторые из дополнительных сетей развернуты на территориях с недостаточным уровнем обслуживания, где сами граждане могут быть вынуждены принимать активное участие в разработке и реализации решений ICT. Однако дополнительные сети (например, [Baig]) присутствуют и в странах «глобального севера» в виде альтернативы коммерческим сетям, обслуживаемым крупными операторами.

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

3.1. Городские и сельские территории

Отмеченные в предыдущем параграфе различия наблюдаются не только между странами, но и внутри стран. Особенно заметны эти различия для сельских территорий, в которых живет около 55% населения планеты [IFAD2011] и около 78% населения стран «глобального юга» [ITU2011]. По данным Всемирного банка (World Bank) разрыв между городскими и сельскими территориями уменьшается в плане мобильной телефонной связи, но продолжает увеличиваться в плане доступа в Internet» [WorldBank2016].

Хотя полное обобщение не представляется возможным, имеются некоторые общие причины, препятствующие традиционным операторам предоставлять доступ в сельских регионах и служащие стимулом для развертывания на таких территориях альтернативных инфраструктур [Brewer] [Nungu] [Simo_c]. Например, отмечены значительные задержки [Johnson_b], которые в отдельные часы могут достигать нескольких секунд.

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

  • низкий уровень доходов, связанный с тем, что местная экономика базируется в основном на натуральном сельском хозяйстве, фермерстве, рыболовстве;

  • нехватка или отсутствие базовой инфраструктуры, включая электричество, воду, дороги;

  • низкая плотность населения и значительная удаленность или труднодоступность населенных пунктов;

  • слабое развитие социальных услуг, включая здравоохранение и образование;

  • нехватка образованного и опытного технического персонала и высокая текучесть кадров, связанная с возможностью получить более интересную и перспективную работу в других местах [McMahon];

  • высокая стоимость доступа в Internet [Mathee];

  • суровая окружающая среда, вызывающая отказы в работе электронных устройств [Johnson_a], ведущие к снижению надежности работы сетей.

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

3.2. Топологические варианты дополнительных сетей

Дополнительные сети, считающиеся самоуправляемыми и самоподддерживающимися, используют разные топологические модели [Vega_a]. Обычно рост таких сетей происходит спонтанно и органично, т.е масштабы сети расширяются без конкретной стратегии планирования и развертывания, а ядро маршрутизации в таких сетях имеет тенденцию роста по степенному закону. Кроме того, эти сети обычно включают множество разнотипных устройств, объединенных общей целью свободного подключения при увеличении области покрытия и надежности сети. Хотя эти характеристики повышают энтропию сети (например, за счет увеличения числа протоколов маршрутизации), они обычно обеспечивают недорогое решение для эффективного увеличения размеров сети. Одним из примеров таких сетей может служить Guifi.net [Vega_a], которая по числу узлов в последнее десятилетие обеспечивала экспоненциальный рост.

Зачастую сельские области в таких сетях соединены по междугородным каналам и/или через беспроводные многосвязные сети (wireless mesh networks), которые, в свою очередь, обеспечивают Internet-подключения к соответствующим компаниям или организациям.

В городских районах, напротив, пользователям обычно нужна общая среда с мобильным доступом. Поскольку такие территории обычно входят в зоны покрытия коммерческих ISP, предоставление беспроводного доступа виртуальными операторами типа [Fon] может расширять «пользовательскую емкость» сети. Другие решения типа «виртуальных публичных сетей» (Virtual Public Network) [Sathiaseelan_a] могут также расширять спектр услуг.

4. Критерии классификации

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

4.1. Потребители сетевых услуг

Участниками (потребителями услуг) дополнительных сетей могут быть:

  • сообщества пользователей;

  • представители общественности;

  • частные компании;

  • сторонники коллективных моделей;

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

  • исследовательские или научные организации.

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

4.2. Назначение сети

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

Ниже приведен неполный список преимуществ, которые могут обеспечивать дополнительные сети:

  • расширение покрытия в областях с низким уровнем обслуживания (пользователи и сообщества);

  • обеспечение приемлемого доступа в Internet для всех;

  • снижение стартовых капиталовложений (для сети и конечных пользователей);

  • привлечение дополнительных средств (помимо традиционного финансирования оператором);

  • снижение операционных расходов (транспортные соединения и сетевое администрирование);

  • расширение опыта и обеспечение возможности для экспериментов и обучения;

  • упрощение адаптации (например, компьютерной грамотности, образованности в целом, актуальности);

  • предоставление дополнительных услуг в случаях природных катастроф и других экстремальных ситуаций;

  • построение сообщества, социальная сплоченность, улучшение качества жизни;

  • возможность экспериментов с разными моделями владения и управления для сетевой инфраструктуры в целом;

  • рост осведомленности о политических дискуссиях по таким вопросам, как сетевой нейтралитет, распространение знаний, доступ к ресурсам и много другое.

Отметим, что различающиеся цели дополнительных сетей могут быть заявлены более или менее явно и могут меняться с течением времени в зависимости от внутренней динамики и внешних обстоятельств. Например, сеть Red Hook WIFI в Бруклине [Redhook] начиналась, как сеть сообщества и фокусировалась в основном на предоставлении локальных услуг в зданиях сообщества [TidePools], но получила впоследствии широкую известность за счет того, что сыграла ключевую роль в качестве дополнительного сервиса во время урагана [Tech] [NYTimes].

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

4.3. Модель управления и устойчивости

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

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

4.4. Развернутые технологии

  • Стандартные сети Wi-Fi. Многие дополнительные сети работают на основе стандартов IEEE 802.11 [IEEE.802.11] с использованием функции DCF10.

  • Сеть с протяженными соединениями на основе Wi-Fi (WiLD11). Такие сети могут использовать технологию CSMA/CA12 или TDMA13 MAC14 [Simo_b].

  • TDMA. Эта технология может комбинироваться с Wi-Fi нестандартным путем [airMAX], позволяя клиентам передавать и принимать данные с использованием заранее выделенных временных интервалов (timeslot).

  • Системы 802.16 WiMax15 [IEEE.802.16] для работы на открытых (не лицензируемых) частотах.

  • Динамические спектральные решения (например, на основе свободных телевизионных частот). Набор выделенных для телевидения и не используемых на данной территории частот, которыми могут воспользоваться вторичные пользователи (например, IEEE 802.11af [IEEE.802.11AF] или 802.22 [IEEE.802.22]).

  • Спутниковые каналы также могут применяться для покрытия значительных территорий, как предложено в проекте RIFE (https://rife-project.eu/).

  • Недорогие оптико-волоконные системы также могут применяться для связи между домовладениями.

4.5. Типовое применение

Сценарии развертывания дополнительных сетей можно разделить на:

  • городские/сельские территории;

  • страны «глобального юга»/»глобального севера».

5. Классификация дополнительных сетей

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

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

5.1. Общественные сети

Таблица 1. Характеристики сетей сообществ

Сфера охвата сети

сообщество.

Цели создания

могут присутствовать все цели, отмеченные в параграфе 4.2.

Модель управления и устойчивости

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

Технологии

Wi-Fi [IEEE.802.11] (стандартные и нестандартные) и оптические волокна.

Типовое применение

городские и сельские территории.


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

  • Могут создаваться и расти естественными путями, открыты для участия всех, согласных с открытым соглашением об участии. Члены сообщества обычно непосредственно вносят свои активные (иногда пассивные) элементы сетевой инфраструктуры. Сеть растет за счет добавления новых хостов и каналов.

  • Информация о создании и поддержке сети, а также ее владельцах является открытой и децентрализованной. В сетях разных сообществ можно наблюдать разные уровни централизации. В некоторых сетях может использоваться общая платформа (например, web-сайт), с помощью которой выполняется та или иная координация действий. Обычно имеются члены сообщества с соответствующими полномочиями для организации непосредственного организационного контроля за общей организацией сети (например, адреса IP, маршрутизация и т. п..) в рамках всего сообщества (а не только своего оборудования).

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

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

Такие сети растут естественным путем, поскольку они формируются за счет объединения узлов, принадлежащих разным пользователям. Достаточно минимального управления сетью в плане координации адресов IP, маршрутизации и т. п. Некоторые примеры общественных сетей описаны в работе [Braem]. Технологический анализ общественных сетей в [Vega_b] фокусируется на технологическом разнообразии, топологических характеристиках, развитии сетей с течением времени, отказоустойчивости и надежности, а также доступности сетевых услуг.

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

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

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

Большинство общественных сетей соответствуют определению свободных сетей (Free Network), приведенному в параграфе 2.

5.2. Провайдеры беспроводного доступа в Internet (WISP16)

Таблица 2. Характеристики сетей WISP

Сфера охвата сети

компания.

Цели создания

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

Модель управления и устойчивости

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

Технологии

беспроводные (например, [IEEE.802.11], [IEEE.802.16] и нелицензируемые частоты).

Типовое применение

сельская местность (имеются и городские реализации).


Провайдеры WISP предоставляют на коммерческой основе услуги беспроводного доступа в Internet и/или телефонной связи через сеть Internet (VoIP17). Такие операторы чаще всего встречаются на территориях, где нет услуг традиционных телекоммуникационных компаний и ISP. Провайдеры WISP используют в основном беспроводные каналы типа «точка-много точек» на основе открытых (не лицензируемых) частот, но могут работать и в лицензируемых частотных диапазонах. Применение лицензированных частот распространено на территориях, где свободных нелицензируемых частот нет, либо они не обеспечивают достаточной для коммерческих услуг надежности.

Большинство WISP являются локальными компаниями, создаваемыми для заполнения рыночных брешей. Есть небольшое, но растущее число WISP (типа [Airjaldi] в Индии), которые из локальных переросли в региональные.

Начиная с 2006 г. стало возможным создание «облачных» WISP на базе оборудования таких компаний, как [Meraki], [OpenMesh] и др. Однако до недавнего времени все такие провайдеры работали на рынках «глобального севера». В 2014 «облачные» услуги WISP начали появляться и на рынках «глобального юга» [Everylayer].

5.3. Модель с совместно используемой инфраструктурой

Таблица 3. Характеристики сетей с общей инфраструктурой

Сфера охвата сети

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

Цели создания

устранение барьера капиталовложений (для операторов); снижение операционных расходов (переносятся на сообщество); расширение областей покрытия.

Модель управления и устойчивости

сообщество передает оператору в аренду существующую инфраструктуру.

Технологии

беспроводные соединения на нелицензируемых частотах, мобильные фемто-соты, сети WiLD [WiLD] и недорогие оптические волокна.

Типовое применение

сельские территории, большей частью в регионах «глобального юга».


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

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

Одним из ярких примеров потенциала модели с совместно используемой инфраструктурой сегодня является развертывание услуг 3G в сельской местности, где имеются широкополосные общественные сети. Благодаря использованию фемтосот (компактные и недорогие базовые станции сотовой связи) обеспечивается полнофункциональное техническое решение для недорогого покрытия 3G с использованием Internet в качестве обратного канала. Если пользователь или группа пользователей имеют сеть IP, подключенную к Internet каналом с достаточной пропускной способностью, установка фемтосот около пользователей обеспечивает преимущества как оператору, так и пользователям, которые получают более качественное покрытие, а оператору не требуется организация дорогостоящей транзитной инфраструктуры. Хотя эта парадигма разрабатывалась для улучшения сетевого покрытия внутри зданий, решение подходит для организации 3G-покрытия в необслуживаемых сельских районах с невысокой плотностью населения (например, в деревнях), где число одновременных пользователей и размер области обслуживания достаточно малы и подходят для использования фемтосот. Порождаемый такой фемтосотой трафик можно без проблем транспортировать через широковещательную сеть.

Некоторые реальные примеры можно видеть в проекте TUCAN3G, где была развернута демонстрационная сеть в двух регионах амазонских лесов в Перу [Simo_d]. В этих сетях [Simo_a] оператор и несколько сельских кооперативов объединили свои усилия для организации доступа через сельские сети, построенные на базе каналов WiLD [WiLD]. В этих случаях сети относятся к общедоступной системе здравоохранения и были развернуты с участием международных фондов сотрудничества в области телемедицины. Публикации, обосновывающие целесообразность такого подхода, можно найти на упомянутом web-сайте.

5.4. Сети с совместным использованием беспроводных систем

Таблица 4. Характеристики сетей с совместным использованием беспроводных систем

Сфера охвата сети

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

Цели создания

совместное использование подключений и ресурсов

Модель управления и устойчивости

пользователи сообща расходуют сетевые ресурсы при координации со стороны виртуального оператора (VNO); могут применяться разные модели в зависимости от природы VNO

Технологии

Wi-Fi [IEEE.802.11]

Типовое применение

городские и сельские территории


Такую сеть можно определить, как совокупность узлов, владельцы которых связаны общим интересом (например, связность, ресурсы, периферийные устройства), независимо от их физического расположения. Такие сети следуют простой модели — домашний маршрутизатор поддерживает две беспроводных сети, одна из которых обычно используется владельцем, а другая отдана в общее пользование. Небольшая часть пропускной способности выделяется для публичной сети, чтобы любой близко расположенный пользователь мог подключиться к сети. Некоторые примеры таких сетей описаны в [PAWS] и [Sathiaseelan_c]. Другим примером могут служить сети, создаваемые и поддерживаемые городским самоуправлением (например, [Heer]). Openwireless movement (https://openwireless.org/) также продвигает идею совместного использования частных беспроводных сетей.

Некоторые компании [Fon] также продвигают маршрутизаторы Wi-Fi с двойным доступом — одна сеть для личного пользования, другая для общего. Реализация адекватных правил AAA18 позволяет пользователям подключаться к сети разными способами — можно купить маршрутизатор, отдав другим пользователям возможность подключения к его внешней сети, а можно просто подключаться ко всем маршрутизаторам сообщества. Некоторые пользователи могут даже получать тот или иной доход при каждом подключении других пользователей к их точке доступа Wi-Fi. Пользователи, не входящие в сообщество, могут просто покупать возможность доступа в сеть. Некоторые традиционные операторы связи сотрудничают с такими сообществами, добавляя функциональность, требуемую для создания двух сетей доступа в своих беспроводных маршрутизаторах. Описание таких случаев можно найти в [Shi].

Ниже кратко описаны элементы, вовлеченные в работу сетей этого типа.

  • Интерес. Параметр, способный обеспечить степень (цену) привлекательности узла в конкретном месте, в определенное время.

  • Ресурсы. Физические или виртуальные элементы системы (например, пропускная способность, энергия, данные) и устройства.

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

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

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

  • Сетевой оператор. Организации, заинтересованные в сдаче в аренду неиспользуемых мощностей [Sathiaseelan_b] по невысокой цене виртуальным операторам VNO.

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

5.5. Сети сельских коммунальных кооперативов

Таблица 5. Характеристики сетей сельских коммунальных кооперативов

Сфера охвата сети

Сельский кооператив

Цели создания

предоставление услуг на не обслуживаемых территориях и снижение капиталовложений для обеспечения доступа в Internet

Модель управления и устойчивости

кооперативы заключают партнерские соглашения с ISP, которые управляют сетью

Технологии

кабельные (оптика) и беспроводные

Типовое применение

сельская местность


Кооперативы в сфере коммунального хозяйства (utility cooperative) обеспечивают своим членам предоставление коммунальных услуг. Например, в США сельские кооперативы обеспечивают электроснабжение, начиная с 1930-х годов, прежде всего в регионах, где крупные операторы электросетей не обеспечивают сервиса по причине недостаточной эффективности капиталовложений. Аналогично этому во многих регионах с малой плотностью населения традиционные ISP типа телефонных компаний или операторов сетей кабельного телевидения не предлагают услуг доступа или обеспечивают лишь низкоскоростные каналы DSL. Некоторые сельские кооперативы, занимающиеся электроснабжением, начали прокладку оптических линий для своих приложений smart grid и в процессе этого поняли, что могут обеспечивать своим членам широкополосный доступ почти без дополнительных расходов [Cash]. В некоторых из таких случаев кооперативы электроснабжения заключили партнерские соглашения с местными ISP для обеспечения своим членам доступа в Internet [Carlson]. Дополнительную информацию о таких кооперативах и управлении ими можно найти в [NewMexico] и [Mitchell].

5.6. Тестовые и исследовательские сети

Таблица 6. Характеристики тестовых сетей

Сфера охвата сети

исследовательские и научные организации

Цели создания

исследования

Модель управления и устойчивости

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

Технологии

кабельные и беспроводные

Типовое применение

городские и сельские территории


В некоторых случаях инициатором создания сети является не сообщество, а исследовательская организация (например, университет), создающая сеть с целью проведения тех или иных исследований [Samanta] [Bernardi].

Администрирование таких сетей на начальном этапе в большинстве случаев централизовано (научная организация), но может стать позднее децентрализованным, когда другие организации или люди станут участвовать в процессах управления (см., например [Rey]).

6. Используемые технологии

6.1. Кабельные

Во многих странах («глобального севера» и «глобального юга») наблюдаются случаи, когда национальные сервис-провайдеры не хотят заниматься обслуживанием мелких или удаленных поселений. В некоторых случаях население таких изолированных мест создает свои оптические сети. Примерами могут служить Lowenstedt в Германии [Lowenstedt], а также некоторые части сети Guifi.net [Cerda-Alabern].

6.2. Беспроводные

Большинство дополнительных сетей работают на основе тех или иных беспроводных технологий [WNDW]. Ниже рассмотрены варианты и тенденции применения этих технологий в дополнительных сетях.

6.2.1. Протоколы MAC для беспроводных каналов

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

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

6.2.1.1. 802.11 (Wi-Fi)

Наиболее интересен стандарт 802.11 a/b/g/n/ac, определяющий протокол для беспроводных ЛВС (Wireless LAN) и известный также как Wi-Fi. Первый вариант стандарта (a/b) был выпущен в 1999 году и поддерживал скорости до 54 Мбит/с. Последний вариант стандарта (802.11ac) выпущен в 2013 году и позволяет работать со скоростями до 866,7 Мбит/с. В 2012 году был введен стандарт IEEE 802.11, объединивший все предшествующие поправки [IEEE.802.11]. Документ можно загрузить с сайта IEEE Standards Association [IEEE].

В качестве протокола MAC для 802.11 используется CSMA/CA, который был разработан для коротких дистанций — передатчик ожидает приема подтверждения каждого отправленного unicast-пакета и при отсутствии такого подтверждения в течение некоторого времени, повторяет передачу. Для работы 802.11 на длинных каналах некоторые параметры MAC пришлось изменить links [Simo_b]. Но даже после таких изменений увеличение протяженности соединений ведет к значительному снижению производительности. По этой причине многие производители в дополнение к стандарту CSMA/CA предлагали другие методу управления доступом к среде для своего оборудования 802.11, предназначенного для работы вне помещений. В этих фирменных протоколах MAC обычно использовался тот или иной вариант TDMA. Недорогое оборудование, использующее такие методы, обеспечивает высокую производительность даже на расстояниях более 100 километров.

Разные спецификации 802.11 работают в различных частотных диапазонах. 802.11b/g/n использует диапазон 2,4 ГГц, а 802.11a/n/ac — 5 ГГц. Эта особенность в некоторых дополнительных сетях применяется для разделения обычных и «магистральных» узлов.

  • Обычные маршрутизаторы работают в домах, офисах и местах общего пользования в диапазоне частот 2,4 ГГц.

  • Специальные маршрутизаторы используют обычное ПО, но поддерживают также возможность широковещания и приема в диапазоне 5 ГГц для организации соединений «точка-точка». Это полезно для создания опорной сети, соединяющей соседние устройства при невозможности организовать между ними соединение в диапазоне 2,4 ГГц, и обеспечивают узлам 2,4 ГГц надежное и стабильное соединение с остальной сетью.

6.2.1.2. Технологии мобильной связи

Система GSM22 от ETSI также используется в дополнительных сетях в качестве одной из технологий канального уровня, как описано в [Mexican], [Village] и [Heimerl]. Были открыты проекты GSM с открытым кодом типа OpenBTS (http://openbts.org) и OpenBSC (http://openbsc.osmocom.org/trac/) при участии ряда компаний, таких как [Rangenetworks], [Endaga] и [YateBTS]. Это позволяет разворачивать службы голосовой связи, SMS и доступа в Internet через дополнительные сети с обратным каналом на базе IP.

Доступ в Internet обычно ограничен сравнительно невысокими скоростями (см., например, [Osmocom]). Однако развитие стандартов 3GPP23), а также наблюдаемые тенденции в направлении интеграции с функциональностью 4G [Spectrum] [YateBTS] и 5G [Openair] могут обеспечить значительный рост доступных скоростей.

В зависимости от доступности частотных диапазонов и других факторов работа на лицензируемых диапазонах может обеспечивать преимущества по сравнению с высокочастотными системами Wi-Fi в плане распространения сигналов и, следовательно, области покрытия. Другими благоприятными факторами для технологий 3GPP (в частности. GSM) являются малая стоимость и низкое энергопотребление мобильных устройств, что может играть важную роль в сообществах с низким уровнем доходов.

6.2.1.3. Динамическое использование свободных частот

В некоторых дополнительных сетях используются частоты телевидения [Lysko] в диапазонах метровых и дециметровых волн, которые не заняты телевизионными компаниями. Для таких сетей нужно специальное оборудование, которое может детектировать свободные телевизионные частоты (либо из базы данных, либо по анализу спектра), чтобы не создавалось помех телевизионному вещанию. Для эффективного выделения свободных частот сетевым устройствам используются специальные приемники (cognitive radio), которые могут менять частоту и метод модуляции в соответствии со строгими требованиями для вторичного применения телевизионных частот.

Термин «свободные частоты» (White Spaces) используется обычно для обозначения не занятых телевизионных частот (TV White Spaces), поскольку для вторичного применения обычно служат метровый и дециметровый диапазон телевизионных частот. Имеется два основных стандарта работы на свободных телевизионных частотах — (i) IEEE 802.11af [IEEE.802.11AF], являющийся адаптацией стандарта 802.11 для телевизионных частот, и (ii) IEEE 802.22 [IEEE.802.22] для дальней связи в сельских районах.

6.2.1.3.1. 802.11af

802.11af [IEEE.802.11AF] является измененной версией стандарта 802.11 для работы на свободных телевизионных частотах с использованием технологии cognitive radio для предотвращения частотных конфликтов. Этот стандарт, введенный в действие в феврале 2014 года, часто называют White-Fi или Super Wi-Fi. 802.11af содержит множество усовершенствований стандартов серии 802.11, включая недавние нововведения 802.11ac типа 4 связанных каналов, четырех пространственных потоков и высокоскоростной модуляции 256 QAM24 с улучшенным проникновением внутри помещений и покрытием вне помещений. Максимальная скорость передачи данных составляет 426,7 Мбит/с для стран с каналами 6/7 МГц и 568,9 Мбит/с для стран с каналами 8 МГц. Зона покрытия обычно имеет радиус 1 км, хотя возможно увеличение дальности за счет снижения скорости и использования антенн с большим усилением.

Устройства делятся на разрешающие (enabling) станции (точка доступа — AP) и зависимые станции (клиент). Разрешающим станциям предоставлены полномочия управления работой зависимых станций и безопасного доступа в базы данных геолокации. После того, как разрешающая станция получает список доступных каналов, она может анонсировать зависимым станциям доступный канал, по которому они будут работать в дальнейшем. 802.11af также использует зарегистрированный сервер местоположений, представляющий собой базу данных с местами расположения и рабочими параметрами всех разрешающих станций.

6.2.1.3.2. 802.22

Стандарт 802.22 [IEEE.802.22] разработан специально для коммуникаций в сельской местности при больших расстояниях на свободных телевизионных частотах и был введен в действие в июле 2011 года. Стандарт похож на 802.16 (WiMax) [IEEE.802.16], но в дополнение поддерживает технологию поиска свободных частот cognitive radio. Максимальная пропускная способность 802.22 составляет 22,6 Мбит/с на один канал с полосой 8 МГц при использовании модуляции 64-QAM. Дальность с принятой по умолчанию схемой MAC составляет 30 км и может быть увеличена до 100 при использовании специальных методов контроля доступа к среде. Уровень MAC в 802.22 специально доработан с учетом большой протяженности соединений, в частности слоты кадра, рассчитанные на более дальнодействующее оборудование CPE25, передаются до слотов для CPE, работающих на коротких дистанциях.

Базовые станции должны иметь приемник GPS26 и подключение к Internet для запросов к геолокационной базе свободных частот. Когда базовая станция получает разрешенные для использования телевизионные каналы, она выбирает предпочтительный канал для связи с устройствами CPE. Стандарт также включает специальный механизм маркеров (beacon), позволяющий базовым станциям 802.22 узнавать о наличии базовых станций других сетей.

7. Вышележащие уровни

7.1. Сетевой уровень (L3)

7.1.1. Адресация IP

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

Многие дополнительные сети начали свою работу около 2000 г. К тому времени спецификация IPv6 уже была завершена, но в большинстве дополнительных сетей используется IPv4. Опрос [Avonts] показал, что переход на IPv6 является проблемой для сетей сообществ. Однако некоторые из таких сетей уже перешли на новый протокол (например, ninux.org).

7.1.2. Протоколы маршрутизации

Как было отмечено выше, в дополнительный сетях зачастую используются различающиеся на канальном уровне (L2) устройства. Соединения между разнотипными устройствами не гарантируются и стабильность каналов может существенно меняться с течением времени. Для решения этой проблемы в некоторых из дополнительных сетей применяются протоколы маршрутизации для сетей MANET27, хотя в других сетях применяются традиционные протоколы маршрутизации. В некоторых сетях параллельно используется множество протоколов маршрутизации. Например, внутри отдельных «островов» могут применяться mesh-протоколы, а между «островами» — традиционные.

7.1.2.1. Традиционные протоколы маршрутизации

Протокол BGP28, определенный в [RFC4271], используется во многих дополнительных сетях большого размера, благодаря предсказуемости его поведения и масштабируемости.

Аналогичными причинами обусловлено использование в более мелких сетях протокола OSPF29, определенного в [RFC2328].

7.1.2.2. Mesh Routing Protocols

В множестве дополнительных сетей используются фирменные версии протокола OLSR30 [RFC3626]. В рамках открытого проекта [OLSR] этот протокол был расширен путем добавления метрики ETX 31[Couto] и других функций, востребованных в дополнительных сетях (в частности, беспроводных). В некоторых общественных сетях используется [Barz] новая версия протокола OLSRv2 [RFC7181].

B.A.T.M.A.N.32 Advanced [Seither] представляет собой «протокол маршрутизации канального уровня» (L2), который создает сети с мостами и поддерживает плавные переходы клиентов между беспроводными точками доступа.

В некоторых сетях используется также протокол BMX633 [Neumann_a], работающий на основе IPv6 и пытающийся применять социальную структуру дополнительных сетей.

Babel [RFC6126] представляет собой протокол на основе дистантного вектора (distance-vector) с предотвращением петель, обеспечивающий отказоустойчивость и эффективность в кабельных и беспроводных mesh-сетях.

В работе [Neumann_b] представлены результаты исследования трех протоколов маршрутизации для mesh-сетей (BMX6, OLSR, Babel) в части масштабируемости, производительности и стабильности.

7.2. Транспортный уровень

7.2.1. Управление трафиком при совместном использовании сетевых ресурсов

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

Это одна из основных проблем тех, кто предоставляет ресурсы в общее пользование, и она имеет несколько решений. В некоторых случаях адекватный механизм активного управления очередями (AQM34) с поддержкой политики LBE35 [RFC6297] позволяет защитить предоставившего ресурс в общее пользование. Для обеспечения поведения LBE требуется подобающая настройка общеизвестных механизмов типа ECN36 [RFC3168], RED37 [RFC7567] или более новых механизмов AQM, обеспечивающих малые задержки, типа CoDel38 [CoDel] и PIE39 [PIE].

7.3. Обеспечиваемые услуги

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

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

  • доступ к Web-страницам;

  • электронная почта;

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

  • доступ к файлам по протоколу FTP (например, распространение программ или цифровых документов);

  • телефонная связь VoIP (например, SIP);

  • совместное использование файлов (P2P — Peer-to-Peer);

  • видео-камеры с публичным доступом;

  • DNS;

  • игровые серверы;

  • обмен сообщениями Jabber;

  • служба погоды;

  • мониторинг сети;

  • видеоконференции и потоковое видео;

  • радиовещание;

  • доски объявлений;

  • локальные облачные службы.

По причине ограничений в пропускной способности некоторые службы (совместное использование файлов, VoIP и т. п.) могут не поддерживаться в дополнительных сетях. В некоторых из таких случаев для пользователей web могут применяться прокси-серверы.

Для дополнительных сетей был разработан ряд специализированных услуг:

  • партнерские связи и VPN между сетями и (например, https://wiki.freifunk.net/IC-VPN);

  • ориентированные на сообщество порталы (например, http://tidepools.co/);

  • платформы для развертывания, мониторинга и обслуживания сетей;

  • совместное использование VoIP в нескольких сетях для снижения расходов на международную связь;

  • сенсорные сети и встроенные в устройства датчики;

  • общественное теле- и радиовещание

В некоторых дополнительных сетях могут предоставляться и другие услуги (например, местные wiki на порталах сообществ типа https://localwiki.org), которые повышают уровень полезности дополнительных сетей, хотя и не разрабатывались специально для них.

7.3.1. Использование VPN

Некоторые «микро-ISP» могут использовать сеть в качестве обратного канала для предоставления доступа в Internet путем организации VPN между клиентской машиной и машиной с доступом в Internet.

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

7.3.2. Другие возможности

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

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

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

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

[Airjaldi] AirJaldi Networks, «Airjaldi Service», 2015, <https://airjaldi.com/>.

[airMAX] Ubiquiti Networks, Inc., «airMAX», 2016, <https://www.ubnt.com/broadband/>.

[Avonts] Avonts, J., Braem, B., and C. Blondia, «A Questionnaire based Examination of Community Networks», IEEE 9th International Conference on Wireless and Mobile Computing, Networking and Communications (WiMob), pp. 8-15, DOI 10.1109/WiMOB.2013.6673333, October 2013.

[Baig] Baig, R., Roca, R., Freitag, F., and L. Navarro, «guifi.net, a crowdsourced network infrastructure held in common», Computer Networks, Vol. 90, Issue C, pp. 150-165, DOI 10.1016/j.comnet.2015.07.009, October 2015.

[Barz] Barz, C., Fuchs, C., Kirchhoff, J., Niewiejska, J., and H. Rogge, «OLSRv2 for Community Networks», Computer Networks, Vol. 93, Issue P2, pp. 324-341, December 2015, <http://dx.doi.org/10.1016/j.comnet.2015.09.022>.

[Bernardi] Bernardi, B., Buneman, P., and M. Marina, «Tegola Tiered Mesh Network Testbed in Rural Scotland», Proceedings of the 2008 ACM workshop on Wireless networks and systems for developing regions, pp. 9-16, DOI 10.1145/1410064.1410067, 2008.

[Braem] Braem, B., Baig Vinas, R., Kaplan, A., Neumann, A., Vilata i Balaguer, I., Tatum, B., Matson, M., Blondia, C., Barz, C., Rogge, H., Freitag, F., Navarro, L., Bonicioli, J., Papathanasiou, S., and P. Escrich, «A Case for Research with and on Community Networks», ACM SIGCOMM Computer Communication Review, Vol. 43, Issue 3, pp. 68-73, DOI 10.1145/2500098.2500108, July 2013.

[Brewer] Brewer, E., Demmer, M., Du, B., Ho, M., Kam, M., Nedevschi, S., Pal, J., Patra, R., Surana, S., and K. Fall, «The Case for Technology in Developing Regions», IEEE Computer Society, Vol. 38, Issue 6, pp. 25-38, DOI 10.1109/MC.2005.204, 2005.

[Carlson] Carlson, S. and C. Mitchell, «RS Fiber: Fertile Fields for New Rural Internet Cooperative», Institute for Local Self-Reliance and Next Century Cities, April 2016, <https://ilsr.org/wp-content/uploads/downloads/2016/04/rs-fiber-report-2016.pdf>.

[Cash] Cash, C., «CO-MO’S D.I.Y. Model for Building Broadband», National Rural Electric Cooperative Association (NRECA), November 2015, <http://remagazine.coop/co-mo-broadband/>.

[Cerda-Alabern] Cerda-Alabern, L., «On the topology characterization of Guifi.net», Proceedings of the IEEE 8th International Conference on Wireless and Mobile Computing, Networking and Communications (WiMob), pp. 389-396, DOI 10.1109/WiMOB.2012.6379103, October 2012.

[CoDel] Nichols, K., Jacobson, V., McGregor, A., and J. Iyengar, «Controlled Delay Active Queue Management», Work in Progress, draft-ietf-aqm-codel-04, June 2016.

[Couto] De Couto, D., Aguayo, D., Bicket, J., and R. Morris, «A high-throughput path metric for multi-hop wireless routing», Wireless Networks, Vol. 11, Issue 4, pp. 419-434, DOI 10.1007/s11276-005-1766-z, July 2005.

[Endaga] Alleven, M., «Endaga raises $1.2M to help it bring cellular to remote villages», FierceWireless Tech News, December 2014, <http://www.fiercewireless.com/tech/story/endaga-raises-12m-help-it-bring-cellular-remote-villages/2014-12-03>.

[Everylayer] Everylayer, Inc. (ранее Volo Broadband), «Everylayer», 2015, <http://www.everylayer.com/>.

[Fon] Fon, «Fon is the Global WiFi Network», 2014, <https://corp.fon.com/en>.

[GAIA] Internet Research Task Force, «Charter: Global Access to the Internet for All Research Group (GAIA)», 2016, <https://irtf.org/gaia>.

[Heer] Heer, T., Hummen, R., Viol, N., Wirtz, H., Gotz, S., and K. Wehrle, «Collaborative municipal Wi-Fi networks-challenges and opportunities», 8th IEEE International Conference on Pervasive Computing and Communications Workshops (PERCOM Workshops), pp. 588-593, DOI 10.1109/PERCOMW.2010.5470505, 2010.

[Heimerl] Heimerl, K., Shaddi, H., Ali, K., Brewer, E., and T. Parikh, «Local, sustainable, small-scale cellular networks», In ICTD 2013, Cape Town, South Africa, DOI 10.1145/2516604.2516616, 2013.

[IEEE] Institute of Electrical and Electronics Engineers (IEEE), «IEEE Standards Association», <https://standards.ieee.org/>.

[IEEE.802.11] IEEE, «IEEE Standard for Information technology—Telecommunications and information exchange between systems Local and metropolitan area networks—Specific requirements Part 11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications», IEEE 802.11-2012, DOI 10.1109/ieeestd.2012.6178212, April 2012, <http://standards.ieee.org/getieee802/download/802.11-2012.pdf>.

[IEEE.802.11AF] IEEE, «IEEE Standard for Information technology — Telecommunications and information exchange between systems — Local and metropolitan area networks — Specific requirements — Part 11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) specifications — Amendment 5: Television White Spaces (TVWS) Operation», IEEE 802.11af-2013, DOI 10.1109/ieeestd.2014.6744566, February 2014, <http://standards.ieee.org/getieee802/download/802.11af-2013.pdf>.

[IEEE.802.16] IEEE, «IEEE Standard for Information technology — Telecommunications and information exchange between systems — Broadband wireless metropolitan area networks (MANs) — IEEE Standard for Air Interface for Broadband Wireless Access Systems», IEEE 802.16-2012, DOI 10.1109/ieeestd.2012.6272299, August 2012, <http://standards.ieee.org/getieee802/download/802.16-2012.pdf>.

[IEEE.802.22] IEEE, «IEEE Standard for Information technology—Local and metropolitan area networks—Specific requirements—Part 22: Cognitive Wireless RAN Medium Access Control (MAC) and Physical Layer (PHY) specifications: Policies and procedures for operation in the TV Bands», IEEE 802.22-2011, DOI 10.1109/ieeestd.2011.5951707, July 2011, <http://ieeexplore.ieee.org/servlet/opac?punumber=5951705>.

[IFAD2011] International Fund for Agricultural Development (IFAD), «Rural Poverty Report 2011», ISBN 978-92-9072-200-7, 2011.

[InternetStats] Internet World Stats, «World Internet Users and 2015 Population Stats», <http://www.internetworldstats.com/stats.htm>.

[ITU2011] International Telecommunication Union, «World Telecommunication/ICT Indicators Database — 2011», <http://www.itu.int/en/ITU-D/Statistics/Pages/publications/wtid.aspx>.

[Johnson_a] Johnson, D. and K. Roux, «Building Rural Wireless Networks: Lessons Learnt and Future Directions», In Proceedings of the ACM workshop on Wireless networks and systems for developing regions, pp. 17-22, DOI 10.1145/1410064.1410068, 2008.

[Johnson_b] Johnson, D., Pejovic, V., Belding, E., and G. van Stam, «Traffic Characterization and Internet Usage in Rural Africa», In Proceedings of the 20th International Conference Companion on World Wide Web, pp. 493-502, DOI 10.1145/1963192.1963363, 2011.

[Lowenstedt] Huggler, J., «German villagers set up their own broadband network», June 2014, <http://www.telegraph.co.uk/news/worldnews/europe/germany/10871150/German-villagers-set-up-their-own-broadband-network.html>.

[Lysko] Lysko, A., Masonta, M., Mofolo, M., Mfupe, L., Montsi, L., Johnson, D., Mekuria, F., Ngwenya, D., Ntlatlapa, N., Hart, A., Harding, C., and A. Lee, «First large TV white spaces trial in South Africa: A brief overview», 6th International Congress on Ultra Modern Telecommunications and Control Systems and Workshops (ICUMT), pp. 407-414, DOI 10.1109/ICUMT.2014.7002136, October 2014.

[Mathee] Mathee, K., Mweemba, G., Pais, A., Stam, V., and M. Rijken, «Bringing Internet connectivity to rural Zambia using a collaborative approach», International Conference on Information and Communication Technologies and Development, pp. 1-12, DOI 10.1109/ICTD.2007.4937391, 2007.

[McMahon] McMahon, R., Gurstein, M., Beaton, B., Donnell, S., and T. Whiteducke, «Making Information Technologies Work at the End of the Road», Journal of Information Policy, Vol. 4, pp. 250-269, DOI 10.5325/jinfopoli.4.2014.0250, 2014.

[Meraki] Cisco Systems, «Meraki», 2016, <https://www.meraki.com/>.

[Mexican] Varma, S., «Ignored by big companies, Mexican village creates its own mobile service», August 2013, <http://timesofindia.indiatimes.com/world/rest-of-world/Ignored-by-big-companies-Mexican-village-creates-its-own-mobile-service/articleshow/22094736.cms>.

[Mitchell] Mitchell, C., «Broadband At the Speed of Light: How Three Communities Built Next-Generation Networks», Institute for Local Self-Reliance (ILSR), April 2012, <http://ilsr.org/wp-content/uploads/2012/04/muni-bb-speed-light.pdf>.

[Neumann_a] Neumann, A., Lopez, E., and L. Navarro, «An evaluation of BMX6 for community wireless networks», In IEEE 8th International Conference on Wireless and Mobile Computing, Networking and Communications (WiMob), pp. 651-658, DOI 10.1109/WiMOB.2012.6379145, 2012.

[Neumann_b] Neumann, A., Lopez, E., and L. Navarro, «Evaluation of mesh routing protocols for wireless community networks», Computer Networks, Vol. 93, Part 2, pp. 308-323, December 2015, <http://dx.doi.org/10.1016/j.comnet.2015.07.018>.

[NewMexico] New Mexico Department of Information Technology, «Broadband Guide for Electric Utilities», CTC Technology & Energy, Version 1, April 2015, <http://www.doit.state.nm.us/broadband/reports/NMBBP_FiberGuide_ElectricUtilities.pdf>.

[Norris] Norris, P., «Digital Divide: Civic Engagement, Information Poverty, and the Internet Worldwide», Cambridge University Press, ISBN 0521807514, 2001.

[Nungu] Nungu, A., Knutsson, B., and B. Pehrson, «On Building Sustainable Broadband Networks in Rural Areas», Technical Symposium at ITU Telecom World, pp. 135-140, October 2011.

[NYTimes] Gall, C. and J. Glanz, «U.S. Promotes Network to Foil Digital Spying», The New York Times, April 2014, <http://www.nytimes.com/2014/04/21/us/us-promotes-network-to-foil-digital-spying.html?_r=1>.

[OLSR] OLSR.org, «OLSR», 2016, <http://www.olsr.org/>.

[Openair] OpenAirInterface, «OpenAirInterface: 5G software alliance for democratising wireless innovation», 2016, <http://www.openairinterface.org/>.

[OpenMesh] Open Mesh, «Open Mesh», 2016, <http://www.open-mesh.com/>.

[Osmocom] Open Source Mobile Communications (Osmocom), «Cellular Infrastructure», GPRS bitrates, 2016, <https://osmocom.org/projects/osmopcu/wiki/GPRS_bitrates>.

[PAWS] Sathiaseelan, A., Crowcroft, J., Goulden, M., Greiffenhagen, C., Mortier, R., Fairhurst, G., and D. McAuley, «Public Access WiFi Service (PAWS)», Digital Economy All Hands Meeting, University of Aberdeen, October 2012.

[PIE] Pan, R., Natarajan, P., Baker, F., and G. White, «PIE: A Lightweight Control Scheme To Address the Bufferbloat Problem», Work in Progress, draft-ietf-aqm-pie-09, August 2016.

[Pietrosemoli] Pietrosemoli, E., Zennaro, M., and C. Fonda, «Low cost carrier independent telecommunications infrastructure», Global Information Infrastructure and Networking Symposium, pp. 1-4, DOI 10.1109/GIIS.2012.6466655, December 2012.

[Rangenetworks] Range Networks, «Range Networks», 2016, <http://www.rangenetworks.com>.

[Redhook] Red Hook WIFI, «Red Hook WIFI, a project of the Red Hook Initiative», 2016, <http://redhookwifi.org/>.

[Rey] Rey-Moreno, C., Bebea-Gonzalez, I., Foche-Perez, I., Quispe-Taca, R., Linan-Benitez, L., and J. Simo-Reigadas, «A telemedicine WiFi network optimized for long distances in the Amazonian jungle of Peru», Proceedings of the 3rd Extreme Conference on Communication: The Amazon Expedition, Article No. 9, DOI 10.1145/2414393.2414402, 2011.

[RFC1918] Rekhter, Y., Moskowitz, B., Karrenberg, D., de Groot, G., and E. Lear, «Address Allocation for Private Internets», BCP 5, RFC 1918, DOI 10.17487/RFC1918, February 1996, <http://www.rfc-editor.org/info/rfc1918>.

[RFC2328] Moy, J., «OSPF Version 2», STD 54, RFC 2328, DOI 10.17487/RFC2328, April 1998, <http://www.rfc-editor.org/info/rfc2328>.

[RFC3168] Ramakrishnan, K., Floyd, S., and D. Black, «The Addition of Explicit Congestion Notification (ECN) to IP», RFC 3168, DOI 10.17487/RFC3168, September 2001, <http://www.rfc-editor.org/info/rfc3168>.

[RFC3626] Clausen, T., Ed. and P. Jacquet, Ed., «Optimized Link State Routing Protocol (OLSR)», RFC 3626, DOI 10.17487/RFC3626, October 2003, <http://www.rfc-editor.org/info/rfc3626>.

[RFC4271] Rekhter, Y., Ed., Li, T., Ed., and S. Hares, Ed., «A Border Gateway Protocol 4 (BGP-4)», RFC 4271, DOI 10.17487/RFC4271, January 2006, <http://www.rfc-editor.org/info/rfc4271>.

[RFC6126] Chroboczek, J., «The Babel Routing Protocol», RFC 6126, DOI 10.17487/RFC6126, April 2011, <http://www.rfc-editor.org/info/rfc6126>.

[RFC6297] Welzl, M. and D. Ros, «A Survey of Lower-than-Best-Effort Transport Protocols», RFC 6297, DOI 10.17487/RFC6297, June 2011, <http://www.rfc-editor.org/info/rfc6297>.

[RFC7181] Clausen, T., Dearlove, C., Jacquet, P., and U. Herberg, «The Optimized Link State Routing Protocol Version 2», RFC 7181, DOI 10.17487/RFC7181, April 2014, <http://www.rfc-editor.org/info/rfc7181>.

[RFC7567] Baker, F., Ed. and G. Fairhurst, Ed., «IETF Recommendations Regarding Active Queue Management», BCP 197, RFC 7567, DOI 10.17487/RFC7567, July 2015, <http://www.rfc-editor.org/info/rfc7567>.

[Samanta] Samanta, V., Knowles, C., Wagmister, J., and D. Estrin, «Metropolitan Wi-Fi Research Network at the Los Angeles State Historic Park», The Journal of Community Informatics, Vol. 4, No. 1, May 2008, <http://ci-journal.net/index.php/ciej/article/viewArticle/427>.

[Sathiaseelan_a] Sathiaseelan, A., Rotsos, C., Sriram, C., Trossen, D., Papadimitriou, P., and J. Crowcroft, «Virtual Public Networks», In IEEE 2013 Second European Workshop on Software Defined Networks (EWSDN) pp. 1-6, DOI 10.1109/EWSDN.2013.7, October 2013.

[Sathiaseelan_b] Sathiaseelan, A. and J. Crowcroft, «LCD-Net: Lowest Cost Denominator Networking», ACM SIGCOMM Computer Communication Review, Vol. 43, No. 2, April 2013, <http://dx.doi.org/10.1145/2479957.2479966>.

[Sathiaseelan_c] Sathiaseelan, A., Mortier, R., Goulden, M., Greiffenhagen, C., Radenkovic, M., Crowcroft, J., and D. McAuley, «A Feasibility Study of an In-the-Wild Experimental Public Access WiFi Network», Proceedings of the Fifth ACM Symposium on Computing for Development, pp. 33-42, DOI 10.1145/2674377.2674383, 2014.

[SDG] United Nations, «Sustainable Development Goals», Sustainable Development Knowledge Platform, 2015, <https://sustainabledevelopment.un.org/?menu=1300>.

[Seither] Seither, D., Koenig, A., and M. Hollick, «Routing performance of Wireless Mesh Networks: A practical evaluation of BATMAN advanced», IEEE 36th Conference on Local Computer Networks (LCN), pp. 897-904, DOI 10.1109/LCN.2011.6115569, October 2011.

[Shi] Shi, J., Gui, L., Koutsonikolas, D., Qiao, C., and G. Challen, «A Little Sharing Goes a Long Way: The Case for Reciprocal Wifi Sharing», HotWireless ’15 Proceedings of the 2nd International Workshop on Hot Topics in Wireless, DOI 10.1145/2799650.2799652, September 2015.

[Simo_a] Simo-Reigadas, J., Morgado, E., Municio, E., Prieto-Egido, I., and A. Martinez-Fernandez, «Assessing IEEE 802.11 and IEEE 802.16 as backhaul technologies for rural 3G femtocells in rural areas of developing countries», Proceedings of EUCNC, 2014.

[Simo_b] Simo-Reigadas, J., Martinez-Fernandez, A., Ramos-Lopez, J., and J. Seoane-Pascual, «Modeling and Optimizing IEEE 802.11 DCF for Long-Distance Links», IEEE Transactions on Mobile Computing, Vol. 9, Issue 6, pp. 881-896, DOI 10.1109/TMC.2010.27, 2010.

[Simo_c] Simo-Reigadas, J., Martinez-Fernandez, A., Osuna, P., Lafuente, S., and J. Seoane-Pascual, «The Design of a Wireless Solar-Powered Router for Rural Environments Isolated from Health Facilities», IEEE Wireless Communications, Vol. 15, Issue 3, pp. 24-30, DOI 0.1109/MWC.2008.4547519, June 2008.

[Simo_d] Simo-Reigadas, J., Municio, E., Morgado, E., Castro, E., Martinez-Fernandez, A., Solorzano, L., and I. Prieto-Egido, «Sharing low-cost wireless infrastructures with telecommunications operators to bring 3G services to rural communities», Computer Networks, Vol. 93, Issue P2, pp. 245-259, December 2015, <http://dx.doi.org/10.1016/j.comnet.2015.09.006>.

[Spectrum] Laursen, L., «Software-Defined Radio Will Let Communities Build Their Own 4G Networks», November 2015, <http://spectrum.ieee.org/telecom/wireless/softwaredefined-radio-will-let-communities-build-their-own-4g-networks>.

[Sprague] Sprague, K., Grijpink, F., Manyika, J., Moodley, L., Chappuis, B., Pattabiraman, K., and J. Bughin, «Offline and falling behind: Barriers to Internet adoption», McKinsey and Company, August 2014.

[Tech] Kazansky, B., «In Red Hook, Mesh Network Connects Sandy Survivors Still Without Power», November 2012, <http://techpresident.com/news/23127/red-hook-mesh-network-connects-sandy-survivors-still-without-power>.

[TidePools] Baldwin, J., «TidePools: Social WiFi», Parsons, the New School for Design, Doctoral dissertation, Master thesis, 2011, <http://www.scribd.com/doc/94601219/TidePools-Social-WiFi-Thesis>.

[UN] United Nations Statistics Division (UNSD), «Composition of macro geographical (continental) regions, geographical sub-regions, and selected economic and other groupings», October 2013, <http://unstats.un.org/unsd/methods/m49/m49regin.htm#ftnc>.

[UNStats] United Nations Statistics Division (UNSD), «Urban and total population by sex: 1996-2005», Table 6 — Demographic Yearbook 2005, <http://unstats.un.org/unsd/demographic/products/dyb/dyb2005/notestab06.pdf>.

[Vega_a] Vega, D., Cerda-Alabern, L., Navarro, L., and R. Meseguer, «Topology patterns of a community network: Guifi.net», IEEE 8th International Conference on Wireless and Mobile Computing, Networking and Communications (WiMob), pp. 612-619, DOI 10.1109/WiMOB.2012.6379139, October 2012.

[Vega_b] Vega, D., Baig, R., Cerda-Alabern, L., Medina, E., Meseguer, R., and L. Navarro, «A technological overview of the guifi.net community network», Computer Networks, Vol. 93, Issue P2, pp. 260-278, December 2015, <http://dx.doi.org/10.1016/j.comnet.2015.09.023>.

[Village] Heimerl, K. and E. Brewer, «The Village Base Station», Proceedings of the 4th ACM Workshop on Networked Systems for Developing Regions, Article No. 14, DOI 10.1145/1836001.1836015, 2010.

[WiLD] Patra, R., Nedevschi, S., Surana, S., Sheth, A., Subramanian, L., and E. Brewer, «WiLDNet: Design and Implementation of High Performance WiFi Based Long Distance Networks», NSDI, Vol. 1, No. 1, pp. 1, April 2007.

[WNDW] WNDW, «Wireless Networking in the Developing World, 3rd Edition», The WNDW Project, 2013, <http://wndw.net>.

[WorldBank2016] World Bank, «World Development Report 2016: Digital Dividends», Washington, DC: The World Bank, ISBN 978-1-4648-0672-8, DOI 10.1596/978-1-4648-0671-1, 2016, <http://www-wds.worldbank.org/external/default/WDSContentServer/WDSP/IB/2016/01/13/090224b08405ea05/2_0/Rendered/PDF/World0developm0000digital0dividends.pdf>.

[WSIS] International Telecommunications Union, «Declaration of Principles. Building the Information Society: A global challenge in the new millennium», WSIS-03 / GENEVA / DOC / 4-E, December 2003, <http://www.itu.int/wsis>.

[YateBTS] YateBTS, «YateBTS», 2016, <http://yatebts.com/>.

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

Эта работа частично финансировалась в рамках проекта Еврокомиссии CONFINE (FP7 — 288535). Работу Arjuna Sathiaseelan и Andres Arcia Moret финансировали в рамках проекта EU H2020 RIFE (Grant Agreement no: 644663). Работу Jose Saldana финансировали по проекту EU H2020 Wi-5 (Grant Agreement no: 644262).

Редактор и авторы этого документа хотят выразить свою благодарность за написание, обзор и обсуждение текста Panayotis Antoniadis, Paul M. Aoki, Roger Baig, Jaume Barcelo, Steven G. Huter, Aldebaro Klautau, Rohan Mahy, Vesna Manojlovic, Mitar Milutinovic, Henning Schulzrinne, Rute Sofia и Dirk Trossen.

Отдельная благодарность руководителям рабочей группы GAIA Mat Ford и Arjuna Sathiaseelan за их поддержку и руководство.

Участники разработки документа

Leandro Navarro
U. Politecnica Catalunya
Jordi Girona, 1-3, D6
Barcelona 08034
Spain
Phone: +34 93 401 6807
Email: leandro@ac.upc.edu

Carlos Rey-Moreno
University of the Western Cape
Robert Sobukwe road
Bellville 7535
South Africa
Phone: +27 (0)21 959 2562
Email: crey-moreno@uwc.ac.za

Ioannis Komnios
Democritus University of Thrace
Department of Electrical and Computer Engineering
Kimmeria University Campus
Xanthi 67100
Greece
Phone: +306945406585
Email: ikomnios@ee.duth.gr

Steve Song
Network Startup Resource Center
Lunenburg, Nova Scotia
Canada
Phone: +1 902 529 0046
Email: stevesong@nsrc.org

David Lloyd Johnson
Meraka, CSIR
15 Lower Hope St
Rosebank 7700
South Africa
Phone: +27 (0)21 658 2740
Email: djohnson@csir.co.za

Javier Simo-Reigadas
Escuela Tecnica Superior de Ingenieria de Telecomunicacion
Campus de Fuenlabrada
Universidad Rey Juan Carlos
Madrid
Spain
Phone: +34 91 488 8428
Fax: +34 91 488 7500
Email: javier.simo@urjc.es

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

Jose Saldana (редактор)
University of Zaragoza
Dpt. IEC Ada Byron Building
Zaragoza 50018
Spain
Phone: +34 976 762 698
Email: jsaldana@unizar.es

Andres Arcia-Moret
University of Cambridge
15 JJ Thomson Avenue
Cambridge FE04
United Kingdom
Phone: +44 (0) 1223 763610
Email: andres.arcia@cl.cam.ac.uk

Bart Braem
iMinds
Gaston Crommenlaan 8 (bus 102)
Gent 9050
Belgium
Phone: +32 3 265 38 64
Email: bart.braem@iminds.be

Ermanno Pietrosemoli
The Abdus Salam ICTP
Via Beirut 7
Trieste 34151
Italy
Phone: +39 040 2240 471
Email: ermanno@ictp.it

Arjuna Sathiaseelan
University of Cambridge
15 JJ Thomson Avenue
Cambridge CB30FD
United Kingdom
Phone: +44 (0)1223 763781
Email: arjuna.sathiaseelan@cl.cam.ac.uk

Marco Zennaro
The Abdus Salam ICTP
Strada Costiera 11
Trieste 34100
Italy
Phone: +39 040 2240 406
Email: mzennaro@ictp.it

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

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

nmalykh@gmail.com


1Wireless Internet Service Provider.

2Internet Research Task Force.

3Global Access to the Internet for All Research Group.

4Global Access to the Internet for All — глобальный доступ Internet для всех.

5Wireless Internet Service Provider — поставщик услуг беспроводного доступа в Internet.

6Information and Communications Technology — информационные и коммуникационные технологии.

7Sustainable Development Goals — цели устойчивого развития.

8Goal 9. Build resilient infrastructure, promote inclusive and sustainable industrialization and foster innovation — Цель 9. Построение отказоустойчивой инфраструктуры, содействие всесторонней и устойчивой индустриализации, а также стимулирование инноваций.

9World Summit of the Information Society — Всемирная Встреча на высшем уровне по вопросам Информационного Общества.

10Distributed Coordination Function — функция распределенной координации.

11Wi-Fi-based Long Distance.

12Carrier Sense Multiple Access with Collision Avoidance — множественный доступ в детектированием несущей и предотвращением конфликтов.

13Time Division Multiple Access — множественный доступ с разделением во времени.

14Media Access Control — контроль доступа к среде передачи

15Worldwide Interoperability for Microwave Access.

16Wireless Internet Service Provider.

17Voice over Internet.

18Authentication, Authorization, and Accounting — аутентификация, проверка полномочий и учет.

19Application Service Provider.

20Media Access Control — управление доступом к среде.

21European Telecommunications Standards Institute — Европейский институт телекоммуникационных стандартов.

22Global System for Mobile Communications — глобальная система для мобильной связи.

23Third Generation Partnership Project — проект партнерства третьего поколения.

24Quadrature Amplitude Modulation — квадратурная амплитудная модуляция.

25Consumer Premises Equipment — оборудование, установленное у пользователей.

26Global Positioning System — глобальная система позиционирования.

27Mobile Ad Hoc Network

28Border Gateway Protocol — протокол граничного шлюза.

29Open Shortest Path First — сначала кратчайший путь.

30Optimized Link State Routing — оптимизированная маршрутизация по состоянию каналов.

31Expected Transmission Count — ожидаемое число передач.

32Better Approach To Mobile Ad Hoc Networking.

33BatMan-eXperimental Version 6.

34Active Queue Management.

35Less-than-Best-Effort.

36Explicit Congestion Notification — упреждающее уведомление о перегрузке.

37Random Early Detection — случайное упреждающее детектирование.

38Controlled Delay — контролируемая задержка.

39Proportional Integral controller Enhanced.

40Internet Relay Chat.




RFC 7950 (часть 5)

Часть 4


13. YIN

Модуль YANG может быть преобразован в другой основанный на XML формат, называемый YIN. Преобразованный модуль называется модулем YIN. В этом разделе описаны правила прямого и обратного преобразования между двумя форматами.

Форматы YANG и YIN содержат эквивалентную информацию, но используют разные обозначения. Нотация YIN позволяет разработчикам представлять модули данных YANG в формате XML, что дает возможность использования богатого набора инструментов XML для фильтрации и проверки данных, автоматизированной генерации кода и других задач. Могут применяться инструменты типа XSLT или валидаторов XML.

Преобразование между YANG и YIN не меняет информационного содержимого модели. Комментарии и пробельные символы не сохраняются.

13.1. Формальное определение YIN

Между ключевыми словами YANG и элементами YIN существует взаимно-однозначное соответствие. Локальное имя элемента YIN идентично соответствующему ключевому слову YANG. Это означает, в частности, что корневым элементом документа YIN всегда будет <module> или <submodule>.

Элементы YIN, соответствующие ключевым словам YANG, отоносятся к пространству имен, идентификатор URI которого имеет значение urn:ietf:params:xml:ns:yang:yin:1.

Элементы YIN, соответствующие ключевым словам расширений, относятся к пространству имен модуля YANG, в котором ключевое слово было объявлено с помощью оператора extension.

Имена всех элементов YIN должны быть надлежащим образом определены в их пространствах имен (выше) с использованием стандартных механизмов [XML-NAMES], т. е. атрибутов xmlns и xmlns:xxx.

Аргумент оператора YANG представляется в YIN атрибутом XML или субэлементом элемента keyword. Отображения для ключевых слов YANG приведены в таблице 1. Для расширений отображение аргумента задается оператором extension (параграф 7.19) и приведенными ниже правилами.

  • Если аргумент представлен атрибутом, этот атрибут не имеет пространства имен.

  • Если аргумент представлен элементом, он определяется тем же пространством имен, что и его родительский элемент keyword.

  • Если аргумент представлен элементом, он должен быть первым потомком элемента keyword.

Субоператоры операторов YANG представляются как (дополнительные) потомки элемента keyword, а их относительный порядок должен совпадать с порядком субоператоров в YANG.

Комментарии YANG могут преобразовываться в комментарии XML.

Таблица 1. Отображение аргументов операторов YANG.

Ключевое слово

Имя аргумента

yin-element

action

name

false

anydata

name

false

anyxml

name

false

argument

name

false

augment

target-node

false

base

name

false

belongs-to

module

false

bit

name

false

case

name

false

choice

name

false

config

value

false

contact

text

true

container

name

false

default

value

false

description

text

true

deviate

value

false

deviation

target-node

false

enum

name

false

error-app-tag

value

false

error-message

value

true

extension

name

false

feature

name

false

fraction-digits

value

false

grouping

name

false

identity

name

false

if-feature

name

false

import

module

false

include

module

false

input

<no argument>

n/a

key

value

false

leaf

name

false

leaf-list

name

false

length

value

false

list

name

false

mandatory

value

false

max-elements

value

false

min-elements

value

false

modifier

value

false

module

name

false

must

condition

false

namespace

uri

false

notification

name

false

ordered-by

value

false

organization

text

true

output

<no argument>

n/a

path

value

false

pattern

value

false

position

value

false

prefix

value

false

presence

value

false

range

value

false

reference

text

true

refine

target-node

false

require-instance

value

false

revision

date

false

revision-date

date

false

rpc

name

false

status

value

false

submodule

name

false

type

name

false

typedef

name

false

unique

tag

false

units

name

false

uses

name

false

value

value

false

when

condition

false

yang-version

value

false

yin-element

value

false

13.1.1. Пример использования

Приведенный ниже модуль YANG

     module example-foo {
       yang-version 1.1;
       namespace "urn:example:foo";
       prefix "foo";

       import example-extensions {
         prefix "myext";
       }

       list interface {
         key "name";
         leaf name {
           type string;
         }

         leaf mtu {
           type uint32;
           description "The MTU of the interface.";
           myext:c-define "MY_MTU";
         }
       }
     }

где расширение c-define определено в параграфе 7.19.3, преобразуется в YIN вида

     <module name="example-foo"
             xmlns="urn:ietf:params:xml:ns:yang:yin:1"
             xmlns:foo="urn:example:foo"
             xmlns:myext="urn:example:extensions">

       <namespace uri="urn:example:foo"/>
       <prefix value="foo"/>

       <import module="example-extensions">
         <prefix value="myext"/>
       </import>

       <list name="interface">
         <key value="name"/>
         <leaf name="name">
           <type name="string"/>
         </leaf>
         <leaf name="mtu">
           <type name="uint32"/>
           <description>
             <text>The MTU of the interface.</text>
           </description>
           <myext:c-define name="MY_MTU"/>
         </leaf>
       </list>
     </module>

14. Грамматика ABNF для YANG

В YANG почти все операторы являются неупорядоченными. Грамматика ABNF [RFC5234] [RFC7405] определяет канонический порядок. Для улучшения читаемости модулей рекомендуется размещать предложения (clause) в этом порядке.

В грамматике ABNF неупорядоченные операторы отмечены комментариями.

Предполагается, что сканер заменит комментарий YANG одиночным символом пробела.

   <CODE BEGINS> file "yang.abnf"

   module-stmt         = optsep module-keyword sep identifier-arg-str
                         optsep
                         "{" stmtsep
                             module-header-stmts
                             linkage-stmts
                             meta-stmts
                             revision-stmts
                             body-stmts
                         "}" optsep

   submodule-stmt      = optsep submodule-keyword sep identifier-arg-str
                         optsep
                         "{" stmtsep
                             submodule-header-stmts
                             linkage-stmts
                             meta-stmts
                             revision-stmts
                             body-stmts
                         "}" optsep

   module-header-stmts = ;; эти операторы могут присутствовать в любом порядке
                         yang-version-stmt
                         namespace-stmt
                         prefix-stmt

   submodule-header-stmts =
                         ;; эти операторы могут присутствовать в любом порядке
                         yang-version-stmt
                         belongs-to-stmt

   meta-stmts          = ;; эти операторы могут присутствовать в любом порядке
                         [organization-stmt]
                         [contact-stmt]
                         [description-stmt]
                         [reference-stmt]

   linkage-stmts       = ;; эти операторы могут присутствовать в любом порядке
                         *import-stmt
                         *include-stmt

   revision-stmts      = *revision-stmt

   body-stmts          = *(extension-stmt /
                           feature-stmt /
                           identity-stmt /
                           typedef-stmt /
                           grouping-stmt /
                           data-def-stmt /
                           augment-stmt /
                           rpc-stmt /
                           notification-stmt /
                           deviation-stmt)

   data-def-stmt       = container-stmt /
                         leaf-stmt /
                         leaf-list-stmt /
                         list-stmt /
                         choice-stmt /
                         anydata-stmt /
                         anyxml-stmt /
                         uses-stmt

   yang-version-stmt   = yang-version-keyword sep yang-version-arg-str
                         stmtend

   yang-version-arg-str = < a string that matches the rule >
                          < yang-version-arg >

   yang-version-arg    = "1.1"

   import-stmt         = import-keyword sep identifier-arg-str optsep
                         "{" stmtsep
                             ;; эти операторы могут присутствовать в любом порядке
                             prefix-stmt
                             [revision-date-stmt]
                             [description-stmt]
                             [reference-stmt]
                         "}" stmtsep

   include-stmt        = include-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [revision-date-stmt]
                              [description-stmt]
                              [reference-stmt]
                          "}") stmtsep

   namespace-stmt      = namespace-keyword sep uri-str stmtend

   uri-str             = < a string that matches the rule >
                         < URI in RFC 3986 >

   prefix-stmt         = prefix-keyword sep prefix-arg-str stmtend

   belongs-to-stmt     = belongs-to-keyword sep identifier-arg-str
                         optsep
                         "{" stmtsep
                             prefix-stmt
                         "}" stmtsep

   organization-stmt   = organization-keyword sep string stmtend

   contact-stmt        = contact-keyword sep string stmtend

   description-stmt    = description-keyword sep string stmtend

   reference-stmt      = reference-keyword sep string stmtend

   units-stmt          = units-keyword sep string stmtend

   revision-stmt       = revision-keyword sep revision-date optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [description-stmt]
                              [reference-stmt]
                          "}") stmtsep

   revision-date       = date-arg-str

   revision-date-stmt  = revision-date-keyword sep revision-date stmtend

   extension-stmt      = extension-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [argument-stmt]
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                          "}") stmtsep

   argument-stmt       = argument-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              [yin-element-stmt]
                          "}") stmtsep

   yin-element-stmt    = yin-element-keyword sep yin-element-arg-str
                         stmtend

   yin-element-arg-str = < a string that matches the rule >
                         < yin-element-arg >

   yin-element-arg     = true-keyword / false-keyword

   identity-stmt       = identity-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              *if-feature-stmt
                              *base-stmt
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                          "}") stmtsep

   base-stmt           = base-keyword sep identifier-ref-arg-str
                         stmtend

   feature-stmt        = feature-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              *if-feature-stmt
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                          "}") stmtsep

   if-feature-stmt     = if-feature-keyword sep if-feature-expr-str
                         stmtend

   if-feature-expr-str = < a string that matches the rule >
                         < if-feature-expr >

   if-feature-expr     = if-feature-term
                           [sep or-keyword sep if-feature-expr]

   if-feature-term     = if-feature-factor
                           [sep and-keyword sep if-feature-term]

   if-feature-factor   = not-keyword sep if-feature-factor /
                         "(" optsep if-feature-expr optsep ")" /
                         identifier-ref-arg

   typedef-stmt        = typedef-keyword sep identifier-arg-str optsep
                         "{" stmtsep
                             ;; эти операторы могут присутствовать в любом порядке
                             type-stmt
                             [units-stmt]
                             [default-stmt]
                             [status-stmt]
                             [description-stmt]
                             [reference-stmt]
                          "}" stmtsep

   type-stmt           = type-keyword sep identifier-ref-arg-str optsep
                         (";" /
                          "{" stmtsep
                              [type-body-stmts]
                          "}") stmtsep

   type-body-stmts     = numerical-restrictions /
                         decimal64-specification /
                         string-restrictions /
                         enum-specification /
                         leafref-specification /
                         identityref-specification /
                         instance-identifier-specification /
                         bits-specification /
                         union-specification /
                         binary-specification

   numerical-restrictions = [range-stmt]

   range-stmt          = range-keyword sep range-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [error-message-stmt]
                              [error-app-tag-stmt]
                              [description-stmt]
                              [reference-stmt]
                           "}") stmtsep

   decimal64-specification = ;; эти операторы могут присутствовать в любом порядке
                             fraction-digits-stmt
                             [range-stmt]

   fraction-digits-stmt = fraction-digits-keyword sep
                          fraction-digits-arg-str stmtend

   fraction-digits-arg-str = < a string that matches the rule >
                             < fraction-digits-arg >

   fraction-digits-arg = ("1" ["0" / "1" / "2" / "3" / "4" /
                               "5" / "6" / "7" / "8"])
                         / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9"

   string-restrictions = ;; эти операторы могут присутствовать в любом порядке
                         [length-stmt]
                         *pattern-stmt

   length-stmt         = length-keyword sep length-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [error-message-stmt]
                              [error-app-tag-stmt]
                              [description-stmt]
                              [reference-stmt]
                           "}") stmtsep

   pattern-stmt        = pattern-keyword sep string optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [modifier-stmt]
                              [error-message-stmt]
                              [error-app-tag-stmt]
                              [description-stmt]
                              [reference-stmt]
                           "}") stmtsep

   modifier-stmt       = modifier-keyword sep modifier-arg-str stmtend

   modifier-arg-str    = < a string that matches the rule >
                         < modifier-arg >

   modifier-arg        = invert-match-keyword

   default-stmt        = default-keyword sep string stmtend

   enum-specification  = 1*enum-stmt

   enum-stmt           = enum-keyword sep string optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              *if-feature-stmt
                              [value-stmt]
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                           "}") stmtsep

   leafref-specification =
                         ;; эти операторы могут присутствовать в любом порядке
                         path-stmt
                         [require-instance-stmt]

   path-stmt           = path-keyword sep path-arg-str stmtend

   require-instance-stmt = require-instance-keyword sep
                            require-instance-arg-str stmtend

   require-instance-arg-str = < a string that matches the rule >
                              < require-instance-arg >

   require-instance-arg = true-keyword / false-keyword

   instance-identifier-specification =
                         [require-instance-stmt]

   identityref-specification =
                         1*base-stmt

   union-specification = 1*type-stmt

   binary-specification = [length-stmt]

   bits-specification  = 1*bit-stmt

   bit-stmt            = bit-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              *if-feature-stmt
                              [position-stmt]
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                          "}") stmtsep

   position-stmt       = position-keyword sep
                         position-value-arg-str stmtend

   position-value-arg-str = < a string that matches the rule >
                            < position-value-arg >

   position-value-arg  = non-negative-integer-value

   status-stmt         = status-keyword sep status-arg-str stmtend

   status-arg-str      = < a string that matches the rule >
                         < status-arg >

   status-arg          = current-keyword /
                         obsolete-keyword /
                         deprecated-keyword

   config-stmt         = config-keyword sep
                         config-arg-str stmtend

   config-arg-str      = < a string that matches the rule >
                         < config-arg >

   config-arg          = true-keyword / false-keyword

   mandatory-stmt      = mandatory-keyword sep
                         mandatory-arg-str stmtend

   mandatory-arg-str   = < a string that matches the rule >
                         < mandatory-arg >

   mandatory-arg       = true-keyword / false-keyword

   presence-stmt       = presence-keyword sep string stmtend

   ordered-by-stmt     = ordered-by-keyword sep
                         ordered-by-arg-str stmtend

   ordered-by-arg-str  = < a string that matches the rule >
                         < ordered-by-arg >

   ordered-by-arg      = user-keyword / system-keyword

   must-stmt           = must-keyword sep string optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [error-message-stmt]
                              [error-app-tag-stmt]
                              [description-stmt]
                              [reference-stmt]
                           "}") stmtsep

   error-message-stmt  = error-message-keyword sep string stmtend

   error-app-tag-stmt  = error-app-tag-keyword sep string stmtend

   min-elements-stmt   = min-elements-keyword sep
                         min-value-arg-str stmtend

   min-value-arg-str   = < a string that matches the rule >
                         < min-value-arg >

   min-value-arg       = non-negative-integer-value

   max-elements-stmt   = max-elements-keyword sep
                         max-value-arg-str stmtend

   max-value-arg-str   = < a string that matches the rule >
                         < max-value-arg >

   max-value-arg       = unbounded-keyword /
                         positive-integer-value

   value-stmt          = value-keyword sep integer-value-str stmtend

   integer-value-str   = < a string that matches the rule >
                         < integer-value >

   grouping-stmt       = grouping-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                              *(typedef-stmt / grouping-stmt)
                              *data-def-stmt
                              *action-stmt
                              *notification-stmt
                          "}") stmtsep

   container-stmt      = container-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [when-stmt]
                              *if-feature-stmt
                              *must-stmt
                              [presence-stmt]
                              [config-stmt]
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                              *(typedef-stmt / grouping-stmt)
                              *data-def-stmt
                              *action-stmt
                              *notification-stmt
                          "}") stmtsep

   leaf-stmt           = leaf-keyword sep identifier-arg-str optsep
                         "{" stmtsep
                             ;; эти операторы могут присутствовать в любом порядке
                             [when-stmt]
                             *if-feature-stmt
                             type-stmt
                             [units-stmt]
                             *must-stmt
                             [default-stmt]
                             [config-stmt]
                             [mandatory-stmt]
                             [status-stmt]
                             [description-stmt]
                             [reference-stmt]
                          "}" stmtsep

   leaf-list-stmt      = leaf-list-keyword sep identifier-arg-str optsep
                         "{" stmtsep
                             ;; эти операторы могут присутствовать в любом порядке
                             [when-stmt]
                             *if-feature-stmt
                             type-stmt stmtsep
                             [units-stmt]
                             *must-stmt
                             *default-stmt
                             [config-stmt]
                             [min-elements-stmt]
                             [max-elements-stmt]
                             [ordered-by-stmt]
                             [status-stmt]
                             [description-stmt]
                             [reference-stmt]
                          "}" stmtsep

   list-stmt           = list-keyword sep identifier-arg-str optsep
                         "{" stmtsep
                             ;; эти операторы могут присутствовать в любом порядке
                             [when-stmt]
                             *if-feature-stmt
                             *must-stmt
                             [key-stmt]
                             *unique-stmt
                             [config-stmt]
                             [min-elements-stmt]
                             [max-elements-stmt]
                             [ordered-by-stmt]
                             [status-stmt]
                             [description-stmt]
                             [reference-stmt]
                             *(typedef-stmt / grouping-stmt)
                             1*data-def-stmt
                             *action-stmt
                             *notification-stmt
                          "}" stmtsep

   key-stmt            = key-keyword sep key-arg-str stmtend

   key-arg-str         = < a string that matches the rule >
                         < key-arg >

   key-arg             = node-identifier *(sep node-identifier)

   unique-stmt         = unique-keyword sep unique-arg-str stmtend

   unique-arg-str      = < a string that matches the rule >
                         < unique-arg >

   unique-arg          = descendant-schema-nodeid
                         *(sep descendant-schema-nodeid)

   choice-stmt         = choice-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [when-stmt]
                              *if-feature-stmt
                              [default-stmt]
                              [config-stmt]
                              [mandatory-stmt]
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                              *(short-case-stmt / case-stmt)
                          "}") stmtsep

   short-case-stmt     = choice-stmt /
                         container-stmt /
                         leaf-stmt /
                         leaf-list-stmt /
                         list-stmt /
                         anydata-stmt /
                         anyxml-stmt

   case-stmt           = case-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [when-stmt]
                              *if-feature-stmt
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                              *data-def-stmt
                          "}") stmtsep

   anydata-stmt        = anydata-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [when-stmt]
                              *if-feature-stmt
                              *must-stmt
                              [config-stmt]
                              [mandatory-stmt]
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                           "}") stmtsep

   anyxml-stmt         = anyxml-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [when-stmt]
                              *if-feature-stmt
                              *must-stmt
                              [config-stmt]
                              [mandatory-stmt]
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                           "}") stmtsep

   uses-stmt           = uses-keyword sep identifier-ref-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [when-stmt]
                              *if-feature-stmt
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                              *refine-stmt
                              *uses-augment-stmt
                          "}") stmtsep

   refine-stmt         = refine-keyword sep refine-arg-str optsep
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              *if-feature-stmt
                              *must-stmt
                              [presence-stmt]
                              *default-stmt
                              [config-stmt]
                              [mandatory-stmt]
                              [min-elements-stmt]
                              [max-elements-stmt]
                              [description-stmt]
                              [reference-stmt]
                            "}" stmtsep

   refine-arg-str      = < a string that matches the rule >
                         < refine-arg >

   refine-arg          = descendant-schema-nodeid

   uses-augment-stmt   = augment-keyword sep uses-augment-arg-str optsep
                         "{" stmtsep
                             ;; эти операторы могут присутствовать в любом порядке
                             [when-stmt]
                             *if-feature-stmt
                             [status-stmt]
                             [description-stmt]
                             [reference-stmt]
                             1*(data-def-stmt / case-stmt /
                                action-stmt / notification-stmt)
                          "}" stmtsep

   uses-augment-arg-str = < a string that matches the rule >
                          < uses-augment-arg >

   uses-augment-arg    = descendant-schema-nodeid

   augment-stmt        = augment-keyword sep augment-arg-str optsep
                         "{" stmtsep
                             ;; эти операторы могут присутствовать в любом порядке
                             [when-stmt]
                             *if-feature-stmt
                             [status-stmt]
                             [description-stmt]
                             [reference-stmt]
                             1*(data-def-stmt / case-stmt /
                                action-stmt / notification-stmt)
                          "}" stmtsep

   augment-arg-str     = < a string that matches the rule >
                         < augment-arg >

   augment-arg         = absolute-schema-nodeid

   when-stmt           = when-keyword sep string optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [description-stmt]
                              [reference-stmt]
                           "}") stmtsep

   rpc-stmt            = rpc-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              *if-feature-stmt
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                              *(typedef-stmt / grouping-stmt)
                              [input-stmt]
                              [output-stmt]
                          "}") stmtsep

   action-stmt         = action-keyword sep identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              *if-feature-stmt
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                              *(typedef-stmt / grouping-stmt)
                              [input-stmt]
                              [output-stmt]
                          "}") stmtsep

   input-stmt          = input-keyword optsep
                         "{" stmtsep
                             ;; эти операторы могут присутствовать в любом порядке
                             *must-stmt
                             *(typedef-stmt / grouping-stmt)
                             1*data-def-stmt
                         "}" stmtsep

   output-stmt         = output-keyword optsep
                         "{" stmtsep
                             ;; эти операторы могут присутствовать в любом порядке
                             *must-stmt
                             *(typedef-stmt / grouping-stmt)
                             1*data-def-stmt
                         "}" stmtsep

   notification-stmt   = notification-keyword sep
                         identifier-arg-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              *if-feature-stmt
                              *must-stmt
                              [status-stmt]
                              [description-stmt]
                              [reference-stmt]
                              *(typedef-stmt / grouping-stmt)
                              *data-def-stmt
                          "}") stmtsep

   deviation-stmt      = deviation-keyword sep
                         deviation-arg-str optsep
                         "{" stmtsep
                             ;; эти операторы могут присутствовать в любом порядке
                             [description-stmt]
                             [reference-stmt]
                             (deviate-not-supported-stmt /
                               1*(deviate-add-stmt /
                                  deviate-replace-stmt /
                                  deviate-delete-stmt))
                         "}" stmtsep

   deviation-arg-str   = < a string that matches the rule >
                         < deviation-arg >

   deviation-arg       = absolute-schema-nodeid

   deviate-not-supported-stmt =
                         deviate-keyword sep
                         not-supported-keyword-str stmtend

   deviate-add-stmt    = deviate-keyword sep add-keyword-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [units-stmt]
                              *must-stmt
                              *unique-stmt
                              *default-stmt
                              [config-stmt]
                              [mandatory-stmt]
                              [min-elements-stmt]
                              [max-elements-stmt]
                          "}") stmtsep

   deviate-delete-stmt = deviate-keyword sep delete-keyword-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [units-stmt]
                              *must-stmt
                              *unique-stmt
                              *default-stmt
                          "}") stmtsep

   deviate-replace-stmt = deviate-keyword sep replace-keyword-str optsep
                         (";" /
                          "{" stmtsep
                              ;; эти операторы могут присутствовать в любом порядке
                              [type-stmt]
                              [units-stmt]
                              [default-stmt]
                              [config-stmt]
                              [mandatory-stmt]
                              [min-elements-stmt]
                              [max-elements-stmt]
                          "}") stmtsep

   not-supported-keyword-str = < a string that matches the rule >
                               < not-supported-keyword >

   add-keyword-str     = < a string that matches the rule >
                         < add-keyword >

   delete-keyword-str  = < a string that matches the rule >
                         < delete-keyword >

   replace-keyword-str = < a string that matches the rule >
                         < replace-keyword >

   ;; представляет использование расширения
   unknown-statement   = prefix ":" identifier [sep string] optsep
                         (";" /
                          "{" optsep
                              *((yang-stmt / unknown-statement) optsep)
                           "}") stmtsep

   yang-stmt           = action-stmt /
                         anydata-stmt /
                         anyxml-stmt /
                         argument-stmt /
                         augment-stmt /
                         base-stmt /
                         belongs-to-stmt /
                         bit-stmt /
                         case-stmt /
                         choice-stmt /
                         config-stmt /
                         contact-stmt /
                         container-stmt /
                         default-stmt /
                         description-stmt /
                         deviate-add-stmt /
                         deviate-delete-stmt /
                         deviate-not-supported-stmt /
                         deviate-replace-stmt /
                         deviation-stmt /
                         enum-stmt /
                         error-app-tag-stmt /
                         error-message-stmt /
                         extension-stmt /
                         feature-stmt /
                         fraction-digits-stmt /
                         grouping-stmt /
                         identity-stmt /
                         if-feature-stmt /
                         import-stmt /
                         include-stmt /
                         input-stmt /
                         key-stmt /
                         leaf-list-stmt /
                         leaf-stmt /
                         length-stmt /
                         list-stmt /
                         mandatory-stmt /
                         max-elements-stmt /
                         min-elements-stmt /
                         modifier-stmt /
                         module-stmt /
                         must-stmt /
                         namespace-stmt /
                         notification-stmt /
                         ordered-by-stmt /
                         organization-stmt /
                         output-stmt /
                         path-stmt /
                         pattern-stmt /
                         position-stmt /
                         prefix-stmt /
                         presence-stmt /
                         range-stmt /
                         reference-stmt /
                         refine-stmt /
                         require-instance-stmt /
                         revision-date-stmt /
                         revision-stmt /
                         rpc-stmt /
                         status-stmt /
                         submodule-stmt /
                         typedef-stmt /
                         type-stmt /
                         unique-stmt /
                         units-stmt /
                         uses-augment-stmt /
                         uses-stmt /
                         value-stmt /
                         when-stmt /
                         yang-version-stmt /
                         yin-element-stmt

   ;; Число элементов
   range-arg-str       = < a string that matches the rule >
                         < range-arg >

   range-arg           = range-part *(optsep "|" optsep range-part)

   range-part          = range-boundary
                         [optsep ".." optsep range-boundary]

   range-boundary      = min-keyword / max-keyword /
                         integer-value / decimal-value

   ;; Размеры
   length-arg-str      = < a string that matches the rule >
                         < length-arg >

   length-arg          = length-part *(optsep "|" optsep length-part)

   length-part         = length-boundary
                         [optsep ".." optsep length-boundary]

   length-boundary     = min-keyword / max-keyword /
                         non-negative-integer-value

   ;; Даты
   date-arg-str        = < a string that matches the rule >
                         < date-arg >

   date-arg            = 4DIGIT "-" 2DIGIT "-" 2DIGIT

   ;; Идентификаторы узлов схемы
   schema-nodeid       = absolute-schema-nodeid /
                         descendant-schema-nodeid

   absolute-schema-nodeid = 1*("/" node-identifier)

   descendant-schema-nodeid =
                         node-identifier
                         [absolute-schema-nodeid]

   node-identifier     = [prefix ":"] identifier

   ;; Идентификаторы экземпляров
   instance-identifier = 1*("/" (node-identifier
                                 [1*key-predicate /
                                  leaf-list-predicate /
                                  pos]))

   key-predicate       = "[" *WSP key-predicate-expr *WSP "]"

   key-predicate-expr  = node-identifier *WSP "=" *WSP quoted-string

   leaf-list-predicate = "[" *WSP leaf-list-predicate-expr *WSP "]"

   leaf-list-predicate-expr = "." *WSP "=" *WSP quoted-string

   pos                 = "[" *WSP positive-integer-value *WSP "]"

   quoted-string       = (DQUOTE string DQUOTE) / (SQUOTE string SQUOTE)

   ;; путь leafref
   path-arg-str        = < a string that matches the rule >
                         < path-arg >

   path-arg            = absolute-path / relative-path

   absolute-path       = 1*("/" (node-identifier *path-predicate))

   relative-path       = 1*("../") descendant-path

   descendant-path     = node-identifier
                         [*path-predicate absolute-path]

   path-predicate      = "[" *WSP path-equality-expr *WSP "]"

   path-equality-expr  = node-identifier *WSP "=" *WSP path-key-expr

   path-key-expr       = current-function-invocation *WSP "/" *WSP
                         rel-path-keyexpr

   rel-path-keyexpr    = 1*(".." *WSP "/" *WSP)
                         *(node-identifier *WSP "/" *WSP)
                         node-identifier

   ;; Ключевые слова, применяемые для регистро-чувствительных строк (RFC 7405)

   ;; Операторы
   action-keyword           = %s"action"
   anydata-keyword          = %s"anydata"
   anyxml-keyword           = %s"anyxml"
   argument-keyword         = %s"argument"
   augment-keyword          = %s"augment"
   base-keyword             = %s"base"
   belongs-to-keyword       = %s"belongs-to"
   bit-keyword              = %s"bit"
   case-keyword             = %s"case"
   choice-keyword           = %s"choice"
   config-keyword           = %s"config"
   contact-keyword          = %s"contact"
   container-keyword        = %s"container"
   default-keyword          = %s"default"
   description-keyword      = %s"description"
   deviate-keyword          = %s"deviate"
   deviation-keyword        = %s"deviation"
   enum-keyword             = %s"enum"
   error-app-tag-keyword    = %s"error-app-tag"
   error-message-keyword    = %s"error-message"
   extension-keyword        = %s"extension"
   feature-keyword          = %s"feature"
   fraction-digits-keyword  = %s"fraction-digits"
   grouping-keyword         = %s"grouping"
   identity-keyword         = %s"identity"
   if-feature-keyword       = %s"if-feature"
   import-keyword           = %s"import"
   include-keyword          = %s"include"
   input-keyword            = %s"input"
   key-keyword              = %s"key"
   leaf-keyword             = %s"leaf"
   leaf-list-keyword        = %s"leaf-list"
   length-keyword           = %s"length"
   list-keyword             = %s"list"
   mandatory-keyword        = %s"mandatory"
   max-elements-keyword     = %s"max-elements"
   min-elements-keyword     = %s"min-elements"
   modifier-keyword         = %s"modifier"
   module-keyword           = %s"module"
   must-keyword             = %s"must"
   namespace-keyword        = %s"namespace"
   notification-keyword     = %s"notification"
   ordered-by-keyword       = %s"ordered-by"
   organization-keyword     = %s"organization"
   output-keyword           = %s"output"
   path-keyword             = %s"path"
   pattern-keyword          = %s"pattern"
   position-keyword         = %s"position"
   prefix-keyword           = %s"prefix"
   presence-keyword         = %s"presence"
   range-keyword            = %s"range"
   reference-keyword        = %s"reference"
   refine-keyword           = %s"refine"
   require-instance-keyword = %s"require-instance"
   revision-keyword         = %s"revision"
   revision-date-keyword    = %s"revision-date"
   rpc-keyword              = %s"rpc"
   status-keyword           = %s"status"
   submodule-keyword        = %s"submodule"
   type-keyword             = %s"type"
   typedef-keyword          = %s"typedef"
   unique-keyword           = %s"unique"
   units-keyword            = %s"units"
   uses-keyword             = %s"uses"
   value-keyword            = %s"value"
   when-keyword             = %s"when"
   yang-version-keyword     = %s"yang-version"
   yin-element-keyword      = %s"yin-element"

   ;; Прочие ключевые слова
   add-keyword              = %s"add"
   current-keyword          = %s"current"
   delete-keyword           = %s"delete"
   deprecated-keyword       = %s"deprecated"
   false-keyword            = %s"false"
   invert-match-keyword     = %s"invert-match"
   max-keyword              = %s"max"
   min-keyword              = %s"min"
   not-supported-keyword    = %s"not-supported"
   obsolete-keyword         = %s"obsolete"
   replace-keyword          = %s"replace"
   system-keyword           = %s"system"
   true-keyword             = %s"true"
   unbounded-keyword        = %s"unbounded"
   user-keyword             = %s"user"
   and-keyword              = %s"and"
   or-keyword               = %s"or"
   not-keyword              = %s"not"

   current-function-invocation = current-keyword *WSP "(" *WSP ")"

   ;; Базовые правила
   prefix-arg-str      = < a string that matches the rule >
                         < prefix-arg >

   prefix-arg          = prefix

   prefix              = identifier

   identifier-arg-str  = < a string that matches the rule >
                         < identifier-arg >

   identifier-arg      = identifier

   identifier          = (ALPHA / "_")
                         *(ALPHA / DIGIT / "_" / "-" / ".")

   identifier-ref-arg-str = < a string that matches the rule >
                            < identifier-ref-arg >

   identifier-ref-arg  = identifier-ref

   identifier-ref      = [prefix ":"] identifier

   string              = < an unquoted string, as returned by >
                         < the scanner, that matches the rule >
                         < yang-string >

   yang-string         = *yang-char
   ;; любой символ Unicode или ISO/IEC 10646, включая табуляцию, 
   ;; возврат каретки и перевод строки, но исключая другие управляющие
   ;; символы C0, суррогатные блоки и «несимволы»
   yang-char = %x09 / %x0A / %x0D / %x20-D7FF /
                               ; исключить суррогатные блоки %xD800-DFFF
              %xE000-FDCF /    ; исключить несимвольные коды %xFDD0-FDEF
              %xFDF0-FFFD /    ; исключить несимвольные коды %xFFFE-FFFF
              %x10000-1FFFD /  ; исключить несимвольные коды %x1FFFE-1FFFF
              %x20000-2FFFD /  ; исключить несимвольные коды %x2FFFE-2FFFF
              %x30000-3FFFD /  ; исключить несимвольные коды %x3FFFE-3FFFF
              %x40000-4FFFD /  ; исключить несимвольные коды %x4FFFE-4FFFF
              %x50000-5FFFD /  ; исключить несимвольные коды %x5FFFE-5FFFF
              %x60000-6FFFD /  ; исключить несимвольные коды %x6FFFE-6FFFF
              %x70000-7FFFD /  ; исключить несимвольные коды %x7FFFE-7FFFF
              %x80000-8FFFD /  ; исключить несимвольные коды %x8FFFE-8FFFF
              %x90000-9FFFD /  ; исключить несимвольные коды %x9FFFE-9FFFF
              %xA0000-AFFFD /  ; исключить несимвольные коды %xAFFFE-AFFFF
              %xB0000-BFFFD /  ; исключить несимвольные коды %xBFFFE-BFFFF
              %xC0000-CFFFD /  ; исключить несимвольные коды %xCFFFE-CFFFF
              %xD0000-DFFFD /  ; исключить несимвольные коды %xDFFFE-DFFFF
              %xE0000-EFFFD /  ; исключить несимвольные коды %xEFFFE-EFFFF
              %xF0000-FFFFD /  ; исключить несимвольные коды %xFFFFE-FFFFF
              %x100000-10FFFD  ; исключить несимвольные коды %x10FFFE-10FFFF

   integer-value       = ("-" non-negative-integer-value) /
                          non-negative-integer-value

   non-negative-integer-value = "0" / positive-integer-value

   positive-integer-value = (non-zero-digit *DIGIT)

   zero-integer-value  = 1*DIGIT

   stmtend             = optsep (";" / "{" stmtsep "}") stmtsep

   sep                 = 1*(WSP / line-break)
                         ; безусловный разделитель

   optsep              = *(WSP / line-break)

   stmtsep             = *(WSP / line-break / unknown-statement)

   line-break          = CRLF / LF

   non-zero-digit      = %x31-39

   decimal-value       = integer-value ("." zero-integer-value)

   SQUOTE              = %x27
                         ; одинарная кавычка

   ;; Основные правила из RFC 5234
   ALPHA               = %x41-5A / %x61-7A
                         ; A-Z / a-z

   CR                  = %x0D
                         ; возврат каретки

   CRLF                = CR LF
                         ; Стандарт новой строки в Internet

   DIGIT               = %x30-39
                         ; 0-9

   DQUOTE              = %x22
                         ; двойная кавычка

   HTAB                = %x09
                         ; горизонтальная табуляция

   LF                  = %x0A
                         ; перевод строки

   SP                  = %x20
                         ; пробел

   WSP                 = SP / HTAB
                         ; пустое пространство (пробел)

   <CODE ENDS>

15. Отклики NETCONF об ошибках, связанных с YANG

Множество откликов NETCONF об ошибках определено для ошибок, связанных с обработкой модели данных. Если имеющий отношение к делу оператор YANG имеет субоператор error-app-tag, этот оператор заменяет принятое по умолчанию значение, описанное ниже.

15.1. Сообщение для данных, нарушающих unique

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

     error-tag:      отказ операции
     error-app-tag:  данные не уникальны
     error-info:     <non-unique>: содержит экземпляр идентификатора,
                     указывающий на лист, нарушающий ограничение unique.
                     Этот элемент указывает 1 раз для каждого не 
                     уникального leaf.

                     Элемент <non-unique> относится к пространству имен 
                     YANG urn:ietf:params:xml:ns:yang:1.

15.2. Сообщение для данных, нарушающих max-elements

Если операция NETCONF будет создавать конфигурацию, где узел list или leaf-list включает слишком много элементов, должна возвращаться описанная ниже ошибка.

     error-tag:      отказ операции
     error-app-tag:  слишком много элементов

Эта ошибка возвращается однократно и error-path указывает узел списка, даже при возникновении более одного избыточного потомка.

15.3. Сообщение для данных, нарушающих min-elements

Если операция NETCONF будет создавать конфигурацию, где узел list или leaf-list включает слишком мало элементов, должна возвращаться описанная ниже ошибка.

     error-tag:      отказ операции
     error-app-tag:  слишком мало элементов

Эта ошибка возвращается однократно и error-path указывает узел списка, даже при возникновении более одного недостающего потомка.

15.4. Сообщение для данных, нарушающих must

Если операция NETCONF будет создавать конфигурацию, где нарушены ограничения, заданные оператором must, должна возвращаться описанная ниже ошибка, если нет конкретного субоператора error-app-tag для оператора must.

     error-tag:      отказ операции
     error-app-tag:  нарушение must

15.5. Сообщение для данных, нарущающих require-instance

Если операция NETCONF будет создавать конфигурацию, где лист типа instance-identifier или leafref с оператором require-instance, имеющим значение true, указывает на несуществующий экземпляр, должна возвращаться описанная ниже ошибка.

     error-tag:      данные отсутствуют
     error-app-tag:  требуется экземпляр
     error-path:     путь к instance-identifier или leafref.

15.6. Сообщение для данных, нарушающих обязательный choice

Если операция NETCONF будет создавать конфигурацию, где не существует узлов в обязательном выборе (choice), должна возвращаться описанная ниже ошибка.

     error-tag:      данные отсутствуют
     error-app-tag:  отсутствует choice
     error-path:     путь к элементу с отсутствующим choice.
     error-info:     <missing-choice>: имя отсутствующего обязательного
                     оператора choice.

                     Элемент <missing-choice> относится к пространству имен 
                     YANG urn:ietf:params:xml:ns:yang:1.

15.7. Сообщение для данных, нарушающих insert

Если в <edit-config> используется insert и атрибут key или value для узла list или leaf-list и key или value указывает несуществующий экземпляр, должна возвращаться описанная ниже ошибка.

     error-tag:      bad-attribute
     error-app-tag:  missing-instance

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

Этот документ регистрирует один идентификатор URN для возможности из реестра Network Configuration Protocol (NETCONF) Capability URNs.

Индекс

Идентификатор возможности

:yang-library

urn:ietf:params:netconf:capability:yang-library:1.0

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

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

Применимы соображения по части безопасности, рассмотренные для протокола NETCONF (раздел 9 в [RFC6241]).

Данные, моделируемые в YANG, могут содержать деликатную информацию. RPC и уведомления, определенные в YANG могут служить для переноса деликатной информации.

Имеются вопросы безопасности, связанные с использованием данных, моделируемых в YANG. Такие вопросы следует рассматривать в документах, описывающих модели данных и документах для интерфейсом, применяемых для работы с данными (например, в документах NETCONF).

Данные, моделируемые в YANG, зависят от:

  • безопасности передающей инфраструктуры, используемой для обмена деликатной информацией;

  • безопасности приложений, которые хранят и выпускают такую деликатную информацию;

  • адекватности механизмов аутентификации и контроля доступа для ограничения доступа к данным.

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

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

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

[ISO.10646] International Organization for Standardization, «Information Technology — Universal Multiple-Octet Coded Character Set (UCS)», ISO Standard 10646:2014, 2014.

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

[RFC3629] Yergeau, F., «UTF-8, a transformation format of ISO 10646», STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003, <http://www.rfc-editor.org/info/rfc3629>.

[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, «Uniform Resource Identifier (URI): Generic Syntax», STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <http://www.rfc-editor.org/info/rfc3986>.

[RFC4648] Josefsson, S., «The Base16, Base32, and Base64 Data Encodings», RFC 4648, DOI 10.17487/RFC4648, October 2006, <http://www.rfc-editor.org/info/rfc4648>.

[RFC5234] Crocker, D., Ed., and P. Overell, «Augmented BNF for Syntax Specifications: ABNF», STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <http://www.rfc-editor.org/info/rfc5234>.

[RFC5277] Chisholm, S. and H. Trevino, «NETCONF Event Notifications», RFC 5277, DOI 10.17487/RFC5277, July 2008, <http://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, <http://www.rfc-editor.org/info/rfc6241>.

[RFC7405] Kyzivat, P., «Case-Sensitive String Support in ABNF», RFC 7405, DOI 10.17487/RFC7405, December 2014, <http://www.rfc-editor.org/info/rfc7405>.

[RFC7895] Bierman, A., Bjorklund, M., and K. Watsen, «YANG Module Library», RFC 7895, DOI 10.17487/RFC7895, June 2016, <http://www.rfc-editor.org/info/rfc7895>.

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

[XML-NAMES] Bray, T., Hollander, D., Layman, A., Tobin, R., and H. Thompson, «Namespaces in XML 1.0 (Third Edition)», World Wide Web Consortium Recommendation REC-xml-names-20091208, December 2009, <http://www.w3.org/TR/2009/REC-xml-names-20091208>.

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

[XSD-TYPES] Biron, P. and A. Malhotra, «XML Schema Part 2: Datatypes Second Edition», World Wide Web Consortium Recommendation REC-xmlschema-2-20041028, October 2004, <http://www.w3.org/TR/2004/REC-xmlschema-2-20041028>.

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

[CoMI] van der Stok, P. and A. Bierman, «CoAP Management Interface», Work in Progress, draft-vanderstok-core-comi-09, March 2016.

[IEEE754-2008] IEEE, «IEEE Standard for Floating-Point Arithmetic», IEEE 754-2008, DOI 10.1109/IEEESTD.2008.4610935, 2008, <http://standards.ieee.org/findstds/standard/754-2008.html>.

[RESTCONF] Bierman, A., Bjorklund, M., and K. Watsen, «RESTCONF Protocol», Work in Progress1, draft-ietf-netconf-restconf-16, August 2016.

[RFC2578] McCloghrie, K., Ed., Perkins, D., Ed., and J. Schoenwaelder, Ed., «Structure of Management Information Version 2 (SMIv2)», STD 58, RFC 2578, DOI 10.17487/RFC2578, April 1999, <http://www.rfc-editor.org/info/rfc2578>.

[RFC2579] McCloghrie, K., Ed., Perkins, D., Ed., and J. Schoenwaelder, Ed., «Textual Conventions for SMIv2», STD 58, RFC 2579, DOI 10.17487/RFC2579, April 1999, <http://www.rfc-editor.org/info/rfc2579>.

[RFC3780] Strauss, F. and J. Schoenwaelder, «SMIng — Next Generation Structure of Management Information», RFC 3780, DOI 10.17487/RFC3780, May 2004, <http://www.rfc-editor.org/info/rfc3780>.

[RFC4844] Daigle, L., Ed., and Internet Architecture Board, «The RFC Series and RFC Editor», RFC 4844, DOI 10.17487/RFC4844, July 2007, <http://www.rfc-editor.org/info/rfc4844>.

[RFC6020] Bjorklund, M., Ed., «YANG — A Data Modeling Language for the Network Configuration Protocol (NETCONF)», RFC 6020, DOI 10.17487/RFC6020, October 2010, <http://www.rfc-editor.org/info/rfc6020>.

[RFC6643] Schoenwaelder, J., «Translation of Structure of Management Information Version 2 (SMIv2) MIB Modules to YANG Modules», RFC 6643, DOI 10.17487/RFC6643, July 2012, <http://www.rfc-editor.org/info/rfc6643>.

[RFC6991] Schoenwaelder, J., Ed., «Common YANG Data Types», RFC 6991, DOI 10.17487/RFC6991, July 2013, <http://www.rfc-editor.org/info/rfc6991>.

[RFC7951] Lhotka, L., «JSON Encoding of Data Modeled with YANG», RFC 7951, DOI 10.17487/RFC7951, August 2016, <http://www.rfc-editor.org/info/rfc7951>.

[XPATH2.0] Berglund, A., Boag, S., Chamberlin, D., Fernandez, M., Kay, M., Robie, J., and J. Simeon, «XML Path Language (XPath) 2.0 (Second Edition)», World Wide Web Consortium Recommendation REC-xpath20-20101214, December 2010, <http://www.w3.org/TR/2010/REC-xpath20-20101214>.

[XSLT] Clark, J., «XSL Transformations (XSLT) Version 1.0», World Wide Web Consortium Recommendation REC-xslt-19991116, November 1999, <http://www.w3.org/TR/1999/REC-xslt-19991116>.

[YANG-Guidelines] Bierman, A., «Guidelines for Authors and Reviewers of YANG Data Model Documents», Work in Progress, draft-ietf-netmod-rfc6087bis-07, July 2016.

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

Редактор благодарит перечисленных ниже людей, которые предоставили полезные комментарии к предварительным вариантам этого документа: Mehmet Ersue, Washam Fan, Joel Halpern, Per Hedeland, Leif Johansson, Ladislav Lhotka, Lionel Morand, Gerhard Muenz, Peyman Owladi, Tom Petch, Randy Presuhn, David Reid, Jernej Tuljak, Kent Watsen, Bert Wijnen, Robert Wilton и Dale Worley.

Участники работы

Ниже перечислены люди, внесшие существенный вклад в разработку исподного документа YANG:

  • Andy Bierman (YumaWorks)

  • Balazs Lengyel (Ericsson)

  • David Partain (Ericsson)

  • Juergen Schoenwaelder (Jacobs University Bremen)

  • Phil Shafer (Juniper Networks)

Адрес автора

Martin Bjorklund (редактор)

Tail-f Systems

Email: mbj@tail-f.com


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

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

nmalykh@gmail.com

1Работа опубликована в RFC 8040. Прим. перев.

 




RFC 7950 (часть 4)

Часть 3


8. Ограничения

8.1. Ограничения для данных

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

  • Если ограничение задано для данных конфигурации, оно должно выполняться в дереве данных конфигурации.

  • Если ограничение задано для данных состояния, оно должно выполняться в дереве данных состояния.

  • Если ограничение задано для содержимого уведомления, оно должно выполняться в дереве данных уведомления.

  • Если ограничение задано для входных параметров RPC или операции (action), оно должно выполняться при вызове RPC или операции.

  • Если ограничение задано для выходных параметров RPC или операции (action), оно должно выполняться в откликах RPC или операции.

Приведенные ниже условия должны соблюдаться (true) для всех деревьев данных:

  • все значения данных листа (leaf) должны соответствовать ограничениям типа для листа, включая ограничения определенные для этого типа свойствами range, length и pattern;

  • все листья ключей (key leaf) должны присутствовать для всех элементов списка;

  • узлы должны присутствовать не более чем в одном варианте (case) во всех операторах choice;

  • не должно присутствовать узлов с меткой if-feature, если выражение if-feature определяется сервером как false.

  • не должно присутствовать узлов с оператором when, если условие when преобразуется в дереве данных в значение false.

Приведенные ниже условия должны соблюдаться (true) для действительного дерева данных:

  • все ограничения must должны давать значение true;

  • все ограничения на целостность ссылок, заданные оператором path, должны соблюдаться;

  • все ограничения unique для списков должны соблюдаться;

  • ограничения оператора mandatory выполняются для листьев (leaf) и выбора (choice), если узел или любой из его предков не имеет условия when или выражения if-feature, дающего значение false;

  • ограничения операторов min-elements и max-elements выполняются для списков (list) и узлов leaf-list, если узел или любой из его предков не имеет условия when или выражения if-feature, дающего значение false.

Рабочее хранилище конфигурации всегда должно быть действительным (пригодным).

8.2. Изменение данных конфигурации

  • Если запрос создает узлы данных конфигурации в рамках оператора выбора (choice), все существующие узлы из других вариантов выбора удаляются сервером.

  • Если запрос изменяет данные конфигурации так, что в любом узле выражение when дает результат false, сервер удаляет из дерева данных узлы с выражениями when.

8.3. Модель применения ограничений NETCONF

Для данных конфигурации имеется три «окна», где ограничения должны применяться:

  • в процессе анализа содержимого (payload) RPC;

  • в процессе выполнения операции <edit-config>;

  • в процессе проверки пригодности (validation).

Каждый из этих вариантов рассматривается в последующих параграфах.

8.3.1. Анализ данных

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

  • Если значение данных листа (leaf) не соответствует ограничениям типа листа, включая определенные свойствами range, length и pattern, сервер должен ответить сообщением <rpc-error> с тегом <error-tag> invalid-value, а также error-app-tag (параграф 7.5.4.2) и error-message (параграф 7.5.4.1), связанными с ограничениями, если они имеются.

  • Если все ключи элемента списка отсутствуют, сервер должен передать <error-tag> с missing-element в сообщении <rpc-error>.

  • Если присутствуют данные для нескольких вариантов (case) оператора выбора choice, сервер должен передать <error-tag> с bad-element в сообщении <rpc-error>.

  • Если данные для узла имеют метку if-feature, а выражение if-feature дает значение false на сервере, сервер должен передать <error-tag> с unknown-element в сообщении <rpc-error>.

  • Если присутствуют данные для узла с оператором when, который дает значение false, сервер должен передать <error-tag> с unknown-element в сообщении <rpc-error>.

  • Если при обработке вставки узла значения атрибутов before и after не подходят для типа ключевых листьев, сервер должен передать <error-tag> с bad-attribute в сообщении <rpc-error>.

  • Если атрибуты before и after появляются в каком-либо списке, для которого свойство ordered-by имеет значение user, сервер должен передать <error-tag> с unknown- attribute в сообщении <rpc-error>.

8.3.2. Обработка NETCONF <edit-config>

После анализа входных данных сервер NETCONF выполняет операцию <edit-config>, применяя данные к хранилищу конфигурации. В течение этой обработки должны детектироваться следующие ошибки:

  • запросы на удаление не существующих данных;

  • запросы на создание уже имеющихся данных;

  • запросы вставки с параметрами before или after, указывающими отсутствующие элементы;

  • запросы на изменение для узлов с оператором when, дающим значение false; в этом случае сервер должен передать <error-tag> с unknown-element в сообщении <rpc-error>.

8.3.3. Проверка пригодности

По завершении обработки хранилища данных окончательное содержимое должно соответствовать всем ограничениям пригодности. Эта проверка выполняется в разное время в зависимости от хранилища данных. Если хранилище является рабочим (running) или стартовым (startup), ограничения должны применяться в конце операции <edit-config> или <copy-config>. Если хранилище является «будущим» (candidate), применение ограничений откладывается до вызова операции <commit> или <validate>.

9. Встроенные типы

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

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

Различные встроенные типы и производные от них позволяют организовать разные субтипы для ограничения размера и соответствия строкам регулярных выражений (параграфы 9.4.4 и 9.4.5), а также ограничения диапазонов числовых значений (параграф 9.2.4).

Лексическое представление значений некоторых типов применяется в кодировании XML и при задании принятых по умолчанию значений и числовых диапазонов в модулях YANG.

9.1. Каноническое представление

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

Когда сервер передает данные в представлении XML, он должен использовать каноническую форму, определенную в этом разделе. Другие представления могут использовать иные варианты. Отметим однако, что значения в дереве данных концептуально храняться в каноническом представлении, как указано здесь. В частности, оценка выражений XPath выполняется с использованием канонической формы, если тип данных имеет такую форму. Если у типа данных нет канонической формы, формат значения должен соответствовать лексическому представлению типа данных, но точный формат зависит от реализации.

Некоторые типы имеют лексическое представление, которое зависит от кодирования, например от контекста XML. Такие типы не имеют канонической формы.

9.2. Целочисленные встроенные типы

Язык YANG использует встроенные целочисленные типы int8, int16, int32, int64, uint8, uint16, uint32 и uint64. Они представляют числа разной размерности со знаком или без него:

int8 представляет целые числа от -128 до 127, включительно;

int16 представляет целые числа от -32768 до 32767, включительно;

int32 представляет целые числа от -2147483648 до 2147483647, включительно;

int64 представляет целые числа от -9223372036854775808 до 9223372036854775807, включительно;

uint8 представляет целые числа от 0 до 255, включительно;

uint16 представляет целые числа от 0 до 65535, включительно;

uint32 представляет целые числа от 0 до 4294967295, включительно;

uint64 представляет целые числа от 0 до 18446744073709551615, включительно.

9.2.1. Лексическое представление

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

Для удобства при задании используемого по умолчанию целочисленного значения в модуле YANG может применяться другое лексическое представление с использованием шестнадцатеричной или восьмеричной записи. Шестнадцатеричное представление начинается с необязательного знака (+ или -), за которым следует пара символов 0x, а далее последовательность шестнадцатеричных цифр, в которой могут использоваться символы верхнего или нижнего регистра (a — f, A — F). Восьмеричное представления начинается с необязательного знака (+ или -), за которым следует символ 0 и последовательность восьмеричных цифр (0 — 7).

Отметим, что принятое по умолчанию значение в модуле YANG, которое начинается с нуля (0), интерпретируется как восьмеричное число. В представлении XML все числа считаются десятичными и нули в начале значение допускаются.

Примеры:

     // пригодные значения
     +4711                       // допустимое положительное значение
     4711                        // допустимое положительное значение
     -123                        // допустимое отицательное значение
     0xf00f                      // допустимое положительное шестнадцатеричное значение
     -0xf                        // допустимое отицательное шестнадцатеричное значение
     052                         // допустимое положительное восьмеричное значение

     // непригодные значения
     - 1                         // недопустимый пробел

9.2.2. Каноническая форма

Каноническая форма положительного целого числа не включает знака +. Нули в начале последовательности цифр не допускаются. Нулевое значение представляется одним символом 0.

9.2.3. Ограничения

Все целые числа могут ограничиваться с помощью оператора range (параграф 9.2.4).

9.2.4. Оператор range

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

Диапазон задается явным значением или включительной нижней границей, за которой следуют два символа точки (..) и включительное значение верхней границы. Возможно задание множества значений или диапазонов, разделенных символом |. При задании множеств диапазонов они должны быть не пересекающимися и должны указываться в порядке роста значений. Если ограничение range применяется к типу, который уже имеет такие ограничения, новое ограничение должно соответствовать имеющемуся или быть более сильным (т. е. повышающим нижнюю или/и снижающим верхнюю границу, удаляющим явно заданные значения или расщепляющим диапазон на поддиапазоны с зазорами между ними). Каждое явное значение и граница диапазона в выражении range должно соответствовать ограничиваемому типу или быть одним из специальных значений min или max (минимальное и максимальное допустимые значения для типа, соответственно).

Синтаксис выражения range формально определяется правилом range-arg в разделе 14.

9.2.4.1. Субоператоры для range

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

error-app-tag

7.5.4.2

0..1

error-message

7.5.4.1

0..1

reference

7.21.4

0..1

9.2.5. Пример использования
     typedef my-base-int32-type {
       type int32 {
         range "1..4 | 10..20";
       }
     }

     typedef my-type1 {
       type my-base-int32-type {
         // допустимое ограничение диапазона
         range "11..max"; // 11..20
       }
     }

     typedef my-type2 {
       type my-base-int32-type {
         // недопустимое ограничение диапазона
         range "11..100";
       }
     }

9.3. Встроенный тип decimal64

Встроенный тип decimal64 представляет подмножество действительных чисел, которые могут быть выражены последовательностями десятичных цифр. Пространство значений decimal64 представляет собой подмножество значений, которые могут быть получены путем умножения 64-битового целого числа со знаком на отрицательную степень числа 10 (т. е. значения вида i * 10-n, где i — значение типа integer64, n — целое число от 1 до 18, включительно).

9.3.1. Лексическое представление

Значение decimal64 лексически представляется необязательным знаком (+ или -), за которым следует набор десятичных цифр, а за ним может следовать символ точки (.) в качестве разделителя целой и дробной части и цепочка десятичных цифр дробной части. Если знак не указан, по умолчанию предполагается +.

9.3.2. Каноническая форма

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

9.3.3. Ограничения

Тип decimal64 может быть ограничен с помощью оператора range (параграф 9.2.4).

9.3.4. Оператор fraction-digits

Оператор fraction-digits, который служит субоператором для type, должен присутствовать для типа decimal64. Он принимает в качестве аргумента целое число от 1 до 18, включительно. Это значение управляет разностью между смежными значениями decimal64 путем ограничения пространства значений, которое выражается как i * 10-n, n — число цифр дробной части.

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

Цифр после запятой

Минимум

Максимум

1

-922337203685477580.8

922337203685477580.7

2

-92233720368547758.08

92233720368547758.07

3

-9223372036854775.808

9223372036854775.807

4

-922337203685477.5808

922337203685477.5807

5

-92233720368547.75808

92233720368547.75807

6

-9223372036854.775808

9223372036854.775807

7

-922337203685.4775808

922337203685.4775807

8

-92233720368.54775808

92233720368.54775807

9

-9223372036.854775808

9223372036.854775807

10

-922337203.6854775808

922337203.6854775807

11

-92233720.36854775808

92233720.36854775807

12

-9223372.036854775808

9223372.036854775807

13

-922337.2036854775808

922337.2036854775807

14

-92233.72036854775808

92233.72036854775807

15

-9223.372036854775808

9223.372036854775807

16

-922.3372036854775808

922.3372036854775807

17

-92.23372036854775808

92.23372036854775807

18

-9.223372036854775808

9.223372036854775807

9.3.5. Пример использования

     typedef my-decimal {
       type decimal64 {
         fraction-digits 2;
         range "1 .. 3.14 | 10 | 20..max";
       }
     }

9.4. Встроенный тип string

Встроенный тип string представляет в языке YANG текстовые строки, предназначенные для человека. Допустимо использование символов кодировок Unicode и ISO/IEC 10646 [ISO.10646], включая табуляцию, возврат каретки и перевод строки, но исключая управляющие символы C0, суррогатные блоки и несимволы (noncharacter). Синтаксис string формально определяется правилом yang-string в разделе 14.

9.4.1. Лексическое представление

Значение string лексически представляется символьными данными в формате XML.

9.4.2. Каноническая форма

Каноническая форма совпадает с лексическим представлением. Нормализация Unicode для string не применяется.

9.4.3. Ограничения

Строка (string) может быть ограничена операторами length (параграф 9.4.4) и pattern (параграф 9.4.5).

9.4.4. Оператор length

Оператор length, который является необязательным субоператором для type, принимает в качестве аргумента строку с выражением размера. Оператор служит для ограничения встроенных типов string и binary, а также производных от них.

Оператор length ограничивает число символов Unicode в строке.

Диапазон размеров задается явным значением1 или включительной нижней границей, за которой следуют два символа точки (..) и включительное значение верхней границы. Возможно задание множества значений или диапазонов, разделенных символом |. При задании множеств диапазонов они должны быть не пересекающимися и должны указываться в порядке роста значений. Использование отрицательных значений недопустимо. Если ограничение диапазона применяется к типу, который уже имеет такие ограничения, новое ограничение должно соответствовать имеющемуся или быть более сильным (т. е. повышающим нижнюю или/и снижающим верхнюю границу, удаляющим явно заданные значения или расщепляющим диапазон на поддиапазоны с зазорами между ними). Значение размера представляет собой неотрицательное целое число или одно из специальных значений min или max (минимальное и максимальное допустимые значения для типа, соответственно). От реализаций не требуется поддержка размеров больше 18446744073709551615.

Синтаксис выражения length формально описывается правилом length-arg в разделе 14.

9.4.4.1. Субоператоры для length

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

error-app-tag

7.5.4.2

0..1

error-message

7.5.4.1

0..1

reference

7.21.4

0..1

9.4.5. Оператор pattern

Оператор pattern, который является необязательным субоператором для type, принимает в качестве аргумента строку регулярного выражения, в соответствии с определением [XSD-TYPES]. Он служит для ограничения встроенного типа string и производных от него типов, значениями, которые соответствуют шаблону pattern.

Если тип (type) имеет множество операторов pattern, выражения объединяются логической операцией AND (И), т. е. строка должна соответствовать всем выражениям.

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

9.4.5.1. Субоператоры для pattern

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

error-app-tag

7.5.4.2

0..1

error-message

7.5.4.1

0..1

modifier

9.4.6

0..1

reference

7.21.4

0..1

9.4.6. Оператор modifier

Оператор modifier, который является необязательным субоператором для pattern, принимает в качестве аргумента строку invert-match.

Если в шаблоне присутствует модификатор invert-match, тип ограничивается значениями, не соответствующими шаблону.

9.4.7. Пример использования

Для приведенного ниже определения типа

     typedef my-base-str-type {
       type string {
         length "1..255";
       }
     }

приемлемо уточнение

     type my-base-str-type {
       // допустимое уточнение размера
       length "11 | 42..max"; // 11 | 42..255
     }

а приведенное ниже уточнение недопустимо

     type my-base-str-type {
       // недопустимое уточнение размера
       length "1..999";
     }

Для определенного ниже типа

     type string {
       length "0..4";
       pattern "[0-9a-fA-F]*";
     }

приведенные ниже строки будут соответствовать ограничению

     AB          // допустимо
     9A00        // допустимо

а две следующих строки не будут

     00ABAB      // недопустимо, слишком длинное
     xx00        // недопустимо, непригодные символы

Для типа

     type string {
       length "1..max";
       pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*';
       pattern '[xX][mM][lL].*' {
         modifier invert-match;
       }
     }

приведенная ниже строка будет соответствовать ограничению

     enabled     // допустимо

а следующие строки не соответствуют

     10-mbit     // недопустимо, начинается с числа
     xml-element // недопустимо, начинается с недопустимой последовательности xml

9.5. Встроенный тип boolean

Встроенный тип boolean представляет логические значения.

9.5.1. Лексическое представление

Лексическое представление типа boolean имеет два значения true и false, которые должны указываться символами нижнего регистра.

9.5.2. Каноническая форма

Каноническая форма совпадает с лексическим представлением.

9.5.3. Ограничения

Тип boolean не может быть ограничен.

9.6. Встроенный тип enumeration

Встроенный тип enumeration представляет значения из набора заданных имен.

9.6.1. Лексическое представление

Лексическим представлением значения enumeration является строка назначенного имени.

9.6.2. Каноническая форма

Канонической формой является строка назначенного имени.

9.6.3. Ограничения

Тип enumeration может быть ограничен с помощью одного или нескольких операторов enum (параграф 9.6.4), которые указывают подмножество значений базового типа.

9.6.4. Оператор enum

Оператор enum, который является субоператором для type, должен присутствовать для типа enumeration. Он может использоваться несколько раз для задания каждого назначенного имени типа enumeration. Оператор принимает в качестве аргумента строку назначенного имени. Недопустимо указание пустых строк (нулевой размер), а также недопустимо добавление пробельных символов (любые символы Unicode со свойством White_Space) в начале или в конце назначенного имени. Следует избегать использования в именах управляющих кодов Unicode.

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

Назначенные имена в enumeration должны быть уникальными.

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

9.6.4.1. Субоператоры для enum

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

if-feature

7.20.2

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

value

9.6.4.2

0..1

9.6.4.2. Оператор value

Необязательный оператор value используется для связывания целочисленного значения с назначенным именем для enum. Это должно быть целое число из диапазона от -2147483648 до 2147483647 и значение должно быть уникальным в рамках типа enumeration.

Если значение не задано, оно будет назначаться автоматически. В таких случаях при первом определении будет назначаться значение (0), а противном случае будет назначаться значение, превышающее на единицу максимальное из использованных значений enum (т. е максимальное значение, заданное явно или неявно до текущего субоператора enum в родительском операторе type).

Отметим, что присутствие if-feature в операторе enum не влияет на автоматически присваиваемые значения.

Если текущее максимальное значение составляет 2147483647, значение enum должно быть задано для субоператоров enum, следующих за текущим максимальным значением.

Когда существующий тип enumeration ограничен, оператор value должен иметь такое же значение как в базовом типе или отсутствовать и в этом случае значение также совпадет с базовым типом.

9.6.5. Пример использования

     leaf myenum {
       type enumeration {
         enum zero;
         enum one;
         enum seven {
           value 7;
         }
       }
     }

Лексическое представление листа myenum со значением seven будет иметь вид

     <myenum>seven</myenum>

Для приведенного определения типа (typedef)

     typedef my-base-enumeration-type {
       type enumeration {
         enum white {
           value 1;
         }
         enum yellow {
           value 2;
         }
         enum red {
           value 3;
         }
       }
     }

следующее уточнение будет допустимо

     type my-base-enumeration-type {
       // допустимое уточнение enum
       enum yellow;
       enum red {
         value 3;
       }
     }

а приведенное ниже уточнение недопустимо.

     type my-base-enumeration-type {
       // недопустимое уточнение enum
       enum yellow {
         value 4; // недопустимое значение
       }
       enum black; // недопустимое добавление нового имени
     }

В следующем примере показано, как enum можно пометить тегом if-feature, делающим значение допустимым лишь для серверов, анонсирующих соответствующую функцию.

     type enumeration {
       enum tcp;
       enum ssh {
         if-feature ssh;
       }
       enum tls {
         if-feature tls;
       }
     }

9.7. Встроенный тип bits

Встроенный тип bits представляет набор битов. Т. е. значение bits служит набором флагов, указанных целочисленными значениями позиции с отсчетом от 0. Каждому биту назначено имя.

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

9.7.1. Ограничения

Тип bits может быть ограничен с помощью оператора bit (параграф 9.7.4).

9.7.2. Лексическое представление

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

9.7.3. Каноническая форма

В канонической форме значения битов разделяются одним символом пробела и упорядочиваются по их позициям (параграф 9.7.4.2).

9.7.4. Оператор bit

Оператор bit, который служит субоператором для type, должен присутствовать для типа bits. Он используется многократно для каждого именованного бита типа bits. Оператор принимает в качестве аргумента строку с назначенным именем бита, за которой следует блок субоператоров с дополнительной информацией. Для назначенных имен используется такой же синтаксис, как для идентификаторов (параграф 6.2).

Назначенные имена в типе bits должны быть уникальными.

9.7.4.1. Субоператоры для bit

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

if-feature

7.20.2

0..n

position

9.7.4.2

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

9.7.4.2. Оператор position

Необязательный оператор position принимает в качестве аргумента неотрицательное целое число, которое задает позицию бита в предполагаемом битовом поле. Значение position должно лежать в диапазоне от 0 до 4294967295 и должно быть уникальным в данном типе bits.

Если позиция бита не задана, она назначается автоматически. Если субоператор bit задан в первый раз, присваивается значение 0, в противном случае присваивается значение на 1 больше текущего максимального значения битовой позиции (т. е. битовой позиции, явно или неявно заданной до текущего субоператора bit в родительском операторе type).

Отметим, что присутствие if-feature в операторе enum не влияет на автоматически присваиваемые значения.

Если текущее максимальное значение составляет 4294967295, битовая позиция должна быть задана для субоператоров bit, следующих за текущим максимальным значением.

Когда существующий тип bits ограничен, оператор position должен иметь такое же значение как в базовом типе или отсутствовать и в этом случае значение также совпадет с базовым типом.

9.7.5. Пример использования

Для приведенных ниже typedef и leaf

     typedef mybits-type {
       type bits {
         bit disable-nagle {
           position 0;
         }
         bit auto-sense-speed {
           position 1;
         }
         bit ten-mb-only {
           position 2;
         }
       }
     }

     leaf mybits {
       type mybits-type;
       default "auto-sense-speed";
     }

Лексическое представление листа с битовыми полями disable-nagle и ten-mb-only будет иметь вид

     <mybits>disable-nagle ten-mb-only</mybits>

Ниже показано допустимое уточнение этого типа

     type mybits-type {
       // допустимое уточнение bit
       bit disable-nagle {
         position 0;
       }
       bit auto-sense-speed {
         position 1;
       }
     }

А следующее уточнение недопустимо

     type mybits-type {
       // недопустимое уточнение bit
       bit disable-nagle {
         position 2; // недопустимая позиция
       }
       bit hundred-mb-only; // недопустимое добавление нового имени
     }

9.8. Встроенный тип binary

Встроенный тип binary представляет любые двоичные данные, т. е. последовательность октетов.

9.8.1. Ограничения

Тип binary может быть ограничен с помощью оператора length (параграф 9.4.4). Размер значения типа binary указывает число октетов.

9.8.2. Лексическое представление

Значения binary представляются с использованием схемы кодирования base64 (раздел 4 в [RFC4648]).

9.8.3. Каноническая форма

Каноническая форма значения binary следует правилам кодирования base64 [RFC4648].

9.9. Встроенный тип leafref

Встроенный тип leafref ограничен пространством значений некого узла leaf или leaf-list в дереве схемы и может быть дополнительно ограничен соответствующими экземплярами узлов в дереве данных. Субоператор path (параграф 9.9.2) служит для указания узла leaf или leaf-list в дереве схемы. Пространством значений ссылающегося узла является пространство значений узла, на который указывает ссылка.

Если свойство require-instance (параграф 9.9.3) имеет значение true, должен существовать узел в дереве данных, или узел, использующий принятое по умолчанию значение (параграфы 7.6.1 и 7.7.2), для указанного узла leaf или leaf-list в дереве схемы с таким же значением, как leafref в действительном дереве данных.

Если ссылающийся узел представляет данные конфигурации и свойство require-instance (параграф 9.9.3) имеет значение true, указанный ссылкой узел также должен представлять конфигурацию.

Недопустимы замкнутые цепочки ссылок leafrefs.

Если лист, на который указывает leafref, зависит от одной или нескольких функций (параграф 7.20.2), узел leaf с типом leafref также должен зависеть от того же набора функций.

9.9.1. Ограничения

Тип leafref может быть ограничен с помощью оператора require-instance (параграф 9.9.3).

9.9.2. Оператор path

Оператор path, являющийся субоператором для type, должен присутствовать для типа leafref. Оператор принимает в качестве аргумента строку, которая должна указывать на узел leaf или leaf-list.

Синтаксис аргумента path является подмножеством сокращенного синтаксиса XPath. Предикаты служат лишь для ограничения значений узлов ключей для элементов списка. Каждый предикат содержит в точности одну проверку равенства на ключ и может присутствовать множество смежных предикатов, если список имеет множество ключей. Синтаксис формально определен правилом path-arg в разделе 14.

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

Выражение path дает набор узлов (возможно пустой). Если свойство require-instance имеет значение true, набор узлов должен быть непустым.

Выражение XPath в операторе path концептуально оценивается в перечисленных ниже вариантах контекста в дополнение к приведенному в параграфе 6.4.1 определению:

  • если оператор path определен внутри typedef, узлом контекста будет узел leaf или leaf-list в дереве данных, который ссылается на typedef;

  • в противном случае узлом контекста является узел в дереве данных для которого определен оператор path.

9.9.3. Оператор require-instance

Оператор require-instance, который является субоператором для type, может присутствовать для типов instance-identifier и leafref. Он принимает в качестве аргумента значение true или false. Если оператор отсутствует, по умолчанию принимается значение true.

Если require-instance имеет значение true, это означает, что экземпляр, на который указывается ссылка, должен существовать, чтобы данные были действительны. Ограничения применяются в соответствии с правилами раздела 8.

Если require-instance имеет значение false, это значит, что экземпляр, на который указывает ссылка, может существовать в действительных данных.

9.9.4. Лексическое представление

Значение leafref лексически представляется так же, как представляет свое значение узел leaf, на который указывает ссылка.

9.9.5. Каноническая форма

Каноническая форма leafref совпадает с канонической формой листа (leaf) на который указывает ссылка.

9.9.6. Пример использования

Для приведенного ниже списка

     list interface {
       key "name";
       leaf name {
         type string;
       }
       leaf admin-status {
         type admin-status;
       }
       list address {
         key "ip";
         leaf ip {
           type yang:ip-address;
         }
       }
     }

leafref указывает на существующий интерфейс

     leaf mgmt-interface {
       type leafref {
         path "../interface/name";
       }
     }

Ниже представлен соответствующий фрагмент XML.

     <interface>
       <name>eth0</name>
     </interface>
     <interface>
       <name>lo</name>
     </interface>

     <mgmt-interface>eth0</mgmt-interface>

Приведенный ниже оператор leafrefs указывает на существующий адрес интерфейса.

     container default-address {
       leaf ifname {
         type leafref {
           path "../../interface/name";
         }
       }
       leaf address {
         type leafref {
           path "../../interface[name = current()/../ifname]"
              + "/address/ip";
         }
       }
     }

Соответствующий фрагмент XML имеет вид

     <interface>
       <name>eth0</name>
       <admin-status>up</admin-status>
       <address>
         <ip>192.0.2.1</ip>
       </address>
       <address>
         <ip>192.0.2.2</ip>
       </address>
     </interface>
     <interface>
       <name>lo</name>
       <admin-status>up</admin-status>
       <address>
         <ip>127.0.0.1</ip>
       </address>
     </interface>

     <default-address>
       <ifname>eth0</ifname>
       <address>192.0.2.2</address>
     </default-address>

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

     list packet-filter {
       key "if-name filter-id";
       leaf if-name {
         type leafref {
           path "/interface/name";
         }
       }
       leaf filter-id {
         type uint32;
       }
       ...
     }

Соответствующий фрагмент XML имеет вид

     <interface>
       <name>eth0</name>
       <admin-status>up</admin-status>
       <address>
         <ip>192.0.2.1</ip>
       </address>
       <address>
         <ip>192.0.2.2</ip>
       </address>
     </interface>

     <packet-filter>
       <if-name>eth0</if-name>
       <filter-id>1</filter-id>
       ...
     </packet-filter>
     <packet-filter>
       <if-name>eth0</if-name>
       <filter-id>2</filter-id>
       ...
     </packet-filter>

Приведенное ниже уведомление определяет два leafrefs для ссылки на существующий лист admin-status

     notification link-failure {
       leaf if-name {
         type leafref {
           path "/interface/name";
         }
       }
       leaf admin-status {
         type leafref {
           path "/interface[name = current()/../if-name]"
              + "/admin-status";
         }
       }
     }

Ниже приведен пример соответствующего уведомления XML.

     <notification
       xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
       <eventTime>2008-04-01T00:01:00Z</eventTime>
       <link-failure xmlns="urn:example:system">
         <if-name>eth0</if-name>
         <admin-status>up</admin-status>
       </link-failure>
     </notification>

9.10. Встроенный тип identityref

Встроенный тип identityref служит для ссылок на существующие отождествления (параграф 7.18).

9.10.1. Ограничения

Тип identityref не может быть ограничен.

9.10.2. Оператор base для identityref

Оператор base, который является субоператором для type, должен присутствовать хотя бы однократно для типа identityref. Аргументом служит имя отождествления, определенное оператором identity. Если в имени отождествления имеется префикс, это говорит о том, что отождествление определено в модуле, который импортирован с этим префиксом. В остальных случаях отождествление с совпадающим именем должно быть определено в текущем модуле или включенном в него субмодуле.

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

9.10.3. Лексическое представление

Тип identityref лексически представляется как полное имя указанной ссылки в соответствии с [XML-NAMES]. Если префикс отсутствует, пространством имен identityref будет принятое по умолчанию пространство имен для элемента, содержащего значение identityref.

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

Строковое значение узла типа identityref в выражении must или when XPath является полным именем отождествления с присутствием префикса. Если указанное ссылкой отождествление определено в импортированном модуле, префикс в строковом значении является префиксом, определенным в соответствующем операторе import. В остальный случаях префикс в строковом значении является префиксом текущего модуля.

9.10.4. Каноническая форма

Поскольку лексическая форма зависит от контекста XML, в котором это значение имеет место, этот тип не имеет канонической формы.

9.10.5. Пример использования

С определениями отождествлений из параграфа 7.18.3 и приведенным ниже модулем

     module example-my-crypto {
       yang-version 1.1;
       namespace "urn:example:my-crypto";
       prefix mc;

       import "example-crypto-base" {
         prefix "crypto";
       }

       identity aes {
         base "crypto:crypto-alg";
       }

       leaf crypto {
         type identityref {
           base "crypto:crypto-alg";
         }
       }

       container aes-parameters {
         when "../crypto = 'mc:aes'";
         ...
       }
     }

Пример кодирования листа crypto для отождествления des3, определенного в модуле des будет иметь вид

     <crypto xmlns:des="urn:example:des">des:des3</crypto>

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

     <crypto xmlns:x="urn:example:des">x:des3</crypto>

Если значение листа crypto вместо модуля aes определено в модуле example-my-crypto, кодирование может иметь вид

     <crypto xmlns:mc="urn:example:my-crypto">mc:aes</crypto>

или с использованием принятого по умолчанию пространства имен

     <crypto>aes</crypto>

9.11. Встроенный тип empty

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

Тип empty не может иметь принятого по умолчанию значения.

9.11.1. Ограничения

Тип empty не может быть ограничен.

9.11.2. Лексическое представление

Не применимо.

9.11.3. Каноническая форма

Не применима.

9.11.4. Пример использования

Для показанного ниже листа

     leaf enable-qos {
       type empty;
     }

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

     <enable-qos/>

9.12. Встроенный тип union

Встроенный тип union представляет значение, которое соответствует типу одного из членов объединения.

Когда указан тип union, должен присутствовать оператор type (параграф 7.4). Он используется многократно для задания типа каждого члена объединения. Оператор принимает один аргумент, являющийся строкой с именам типа.

В объединение могут входить встроенные и производные типы.

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

Любое значение, принятое по умолчанию, или свойство units, определенное в типах членов, не наследуется типом union.

9.12.1. Ограничения

Тип union не может иметь ограничений. Однако каждый из входящих в объединение типов может иметь ограничения, определенные в разделе 9.

9.12.2. Лексическое представление

Лексическим представлением типа union является значение, которое соответствует представлению одного (любого) из входящих в объединение типов.

9.12.3. Каноническая форма

Каноническая форма значения union совпадает с канонической формой значения типа, входящего в объединение.

9.12.4. Пример использования

Ниже приведен пример объединения (union) типов int32 и enumeration.

     type union {
       type int32;
       type enumeration {
         enum "unbounded";
       }
     }

Следует соблюдать осторожность в тех случаях, когда член объединения имеет тип leafref, в котором свойство require-instance (параграф 9.9.3) имеет значение true. Если лист такого типа указывает существующий экземпляр, значение leaf должно заново проверяться на пригодность при удалении указанного экземпляра. Например, в приведенном ниже определении

     list filter {
       key name;
       leaf name {
         type string;
       }
       ...
     }

     leaf outbound-filter {
       type union {
         type leafref {
           path "/filter/name";
         }
         type enumeration {
           enum default-filter;
         }
       }
     }

предполагается, что в в списке filter существует элемент с именем http и лист outbound-filter имеет это значение

     <filter>
       <name>http</name>
     </filter>
     <outbound-filter>http</outbound-filter>

Если фильтр http будет удален, значение листа outbound-filter не будет соответствовать leafref и проверяется следующий тип в объединении. Текущее значение (http) не относится к типу enumeration, поэтому результирующая конфигурация будет недействительной.

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

9.13. Встроенный тип instance-identifier

Встроенный тип instance-identifier служит для однозначной идентификации конкретного экземпляра узла в дереве данных.

Синтаксис для instance-identifier является подмножеством сокращенного синтаксиса XPath и формально определен правилом instance-identifier в разделе 14. Тип применяется для однозначной идентификации узлов в дереве данных. Предикаты применяются только для задания значений ключевых узлов элементов списка, значений элементов leaf-list или позиционных индексов в списках без ключей. Для идентификации элементов списка с ключами каждый предикат состоит из одной проверки равенства на ключ и каждый ключ должен иметь соответствующие предикат. Если ключ имеет тип empty, он представляется пустой строкой («»).

Если лист типа instance-identifier представляет данные конфигурации и свойство require-instance (параграф 9.9.3) имеет значение true, узел, на который он ссылается, также должен представлять конфигурацию. Такой лист ограничивает пригодные данные. Узлы всех таких листьев должны указывать существующие узлы или узлы leaf или leaf-list, использующие принятые по умолчанию значения (параграфы 7.6.1 и 7.7.2), для того, чтобы данные были пригодны. Это ограничение применяется в соответствии с правилами раздела 8.

Выражение instance-identifier XPath концептуально проверяется в контексте корневого узла доступного дерева в дополнение к определению параграфа 6.4.1.

9.13.1. Ограничения

Тип instance-identifier может быть ограничен с помощью оператора require-instance (параграф 9.9.3).

9.13.2. Лексическое представление

Значение instance-identifier лексически представляется в форме строки. Все имена узлов в значении instance-identifier должны быть полными с явными префиксами пространства имен и эти префиксы должны быть заявлены в области действия пространства имен XML в элементе XML для instance-identifier.

Все префиксы, используемые в представлении, являются локальными для каждого экземпляра кодирования. Это означает, что instance-identifier может по разному кодироваться разными реализациями.

9.13.3. Каноническая форма

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

9.13.4. Пример использования

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

     /* instance-identifier для container */
     /ex:system/ex:services/ex:ssh

     /* instance-identifier для leaf */
     /ex:system/ex:services/ex:ssh/ex:port

     /* instance-identifier для элемента списка */
     /ex:system/ex:user[ex:name='fred']

     /* instance-identifier для leaf в элементе списка */
     /ex:system/ex:user[ex:name='fred']/ex:type

     /* instance-identifier для элемента списка с двумя ключами */
     /ex:system/ex:server[ex:ip='192.0.2.1'][ex:port='80']

     /* instance-identifier для элемента списка, где второй ключ 
        (enabled) имеет тип empty */
     /ex:system/ex:service[ex:name='foo'][ex:enabled='']

     /* instance-identifier для элемента leaf-list */
     /ex:system/ex:services/ex:ssh/ex:cipher[.='blowfish-cbc']

     /* instance-identifier для элемента списка без ключей */
     /ex:stats/ex:port[3]

10. Функции XPath

Этот документ определяет две базовых функции XPath и пять функций XPath для конкретных типов YANG. Подписи функций заданы с исползованием синтаксиса, применяемого в [XPATH].

10.1. Функция для набора узлов

10.1.1. current()

     node-set current()

Функция current() не принимает входных параметров и возвращает набор узлов с узлом начального контекста в качестве единственного члена.

10.1.1.1. Пример использования

Для списка

     list interface {
       key "name";
       ...
       leaf enabled {
         type boolean;
       }
       ...
     }

показанный ниже лист (leaf) определяет выражение must, которое обеспечивает активность (enable) указанного интерфейса

     leaf outgoing-interface {
       type leafref {
         path "/interface/name";
       }
       must '/interface[name=current()]/enabled = "true"';
     }

10.2. Функция для строк

10.2.1. re-match()

     boolean re-match(string subject, string pattern)

Функция re-match() возвращает значение true, если строка subject соответствует регулярному выражению pattern. В остальных случаях возвращается значение false.

Функция re-match() проверяет соответствие строки заданному регулярному выражению. Используемое регулярное выражение является регулярным выражением XML Schema [XSD-TYPES]. Отметим, что это неявно включает закрепление регулярного выражения в начале и в конце.

10.2.1.1. Пример использования

Выражение

     re-match("1.22.333", "\d{1,3}\.\d{1,3}\.\d{1,3}")

возвращает значение true.

Для подсчета всех логических интерфейсов с именами eth0.<number> можно задать

     count(/interface[re-match(name, "eth0\.\d+")])

10.3. Функция для типов leafref и instance-identifier

10.3.1. deref()

     node-set deref(node-set nodes)

Функция deref() следует по ссылке, указанной первым узлом из числа заданных параметром nodes, и возвращает узлы, на который он ссылается.

Если первый узел имеет тип instance-identifier, функция возвращает набор узлов, содержащий единственный узел, на который ссылается идентификатор экземпляра, при наличии такого узла. Если такого узла нет, возвращается пустой набор.

Если первый узел имеет тип leafref, функция возвращает набор, содержащий узлы, на которые ссылается leafref. В частности, набор включает узлы, выбранные субоператором path (параграф 9.9.2) для leafref, которые имеет такое же значение, как первый узел аргумента.

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

10.3.1.1. Пример использования
     list interface {
       key "name type";
       leaf name { ... }
       leaf type { ... }
       leaf enabled {
         type boolean;
       }
       ...
     }

     container mgmt-interface {
       leaf name {
         type leafref {
           path "/interface/name";
         }
       }
       leaf type {
         type leafref {
           path "/interface[name=current()/../name]/type";
         }
         must 'deref(.)/../enabled = "true"' {
           error-message
             "The management interface cannot be disabled.";
         }
       }
     }

10.4. Функции для типа identityref

10.4.1. derived-from()

     boolean derived-from(node-set nodes, string identity)

Функция derived-from() возвращает значение true, если любой из узлов, заданных аргументом nodes, является узлом типа identityref и его значением является отождествление, произведенное из (параграф 7.18.2) заданного аргументом identity. В остальных случаях функция возвращает false.

Параметр identity является строкой, соответствующей правилу identifier-ref в разделе 14. Если отождествление имеет префикс, это говорит об отождествлении, определенном в модуле, который импортирован с этим префиксом, или в локальном модуле, если это его префикс. Если префикс отсутствует, параметр identity указывает отождествление, определенное в текущем модуле или его субмодулях.

10.4.1.1. Пример использования
     module example-interface {
       yang-version 1.1;

       ...
       identity interface-type;

       identity ethernet {
         base interface-type;
       }

       identity fast-ethernet {
         base ethernet;
       }

       identity gigabit-ethernet {
         base ethernet;
       }

       list interface {
         key name;
         ...
         leaf type {
           type identityref {
             base interface-type;
           }
         }
         ...
       }

       augment "/interface" {
         when 'derived-from(type, "exif:ethernet")';
         // базовые определения Ethernet
       }
       ...
     }

10.4.2. derived-from-or-self()

     boolean derived-from-or-self(node-set nodes, string identity)

Функция derived-from-or-self() возвращает значение true, если любой из узлов, заданных аргументом nodesЮ является узлом типа identityref и его значением является отождествление, которое совпадает с отождествлением, заданным аргументом identity, или порождено от такого отождествления (параграф 7.18.2). Иначе возвращается false.

Параметром identity является строка, соответствующая правилу identifier-ref в разделе 14. Если отождествление имеет префикс, он указывает, что отождествление определено в модуле, импортированном с данным префиксом, или в локальном модуле, если префикс совпадает с префиксом локального модуля. Если префикса нет, аргумент identity указывает отождествление, определенное в текущем модуле или включенном в него субмодуле.

10.4.2.1. Пример использования

Модуль, определенный в параграфе 10.4.1.1 может также иметь

       augment "/interface" {
         when 'derived-from-or-self(type, "exif:fast-ethernet");
         // определения FastEthernet
       }

10.5. Функции для типа enumeration

10.5.1. enum-value()

     number enum-value(node-set nodes)

Функция enum-value() проверяет, является ли первый узел из числа указанных аргументом nodes узлом типа enumeration и возвращает его целочисленное значение enum. Если параметр nodes пуст или первый узел из nodes не относится к типу enumeration, функция возвращает NaN (не число).

10.5.1.1. Пример использования

Для модели данных

     list alarm {
       ...
       leaf severity {
         type enumeration {
           enum cleared {
             value 1;
           }
           enum indeterminate {
             value 2;
           }
           enum minor {
             value 3;
           }
           enum warning {
             value 4;
           }
           enum major {
             value 5;
           }
           enum critical {
             value 6;
           }
         }
       }
     }

приведенное ниже выражение XPath выбирает только сигналы с уровнем важности major и выше

     /alarm[enum-value(severity) >= 5]

10.6. Функции для типа bits

10.6.1. bit-is-set()

     boolean bit-is-set(node-set nodes, string bit-name)

Функция bit-is-set() возвращает значение true, если первый из узлов, указанных аргументом nodes имеет тип bits и флаг bit-name в нем установлен (1). Иначе возвращается значение false.

10.6.1.1. Пример использования

Если интерфейс описывается узлом флагов flags

     leaf flags {
       type bits {
         bit UP;
         bit PROMISCUOUS
         bit DISABLED;
       }
      }

приведенное ниже выражение XPath может служить для выбора активных интерфейсов (флаг UP установлен)

     /interface[bit-is-set(flags, "UP")]

11. Обновление модулей

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

При публикации обновления должен использоваться новый оператор revision (параграф 7.1.9), помещаемый перед имеющимися операторами revision. Если в модуле нет операторов revision, такой оператор должен просто добавляться для обозначения нового выпуска. Кроме того, должны быть внесены все требуемые изменения в операторы metadata, включая organization и contact (параграфы 7.1.7 и 7.1.8).

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

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

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

  • Для типа enumeration могут быть добавлены новые элементы enum с сохранением значения для существующих элементов. Отметим, что вставка новго элемента перед существующим или изменение порядка имеющихся элементов будут приводить к смене значений существующих элементов, если числовые значения для них не были назначены явно.

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

  • Операторы range, length или pattern могут расширять пространство разрешенных значений.

  • Может быть добавлен оператор default для листа (leaf), который не имел принятого по умолчанию значения (напрямую или опосредовано через его тип).

  • Может быть добавлен оператор units.

  • Может быть добавлен или изменен оператор reference.

  • Оператор must может быть удален или его ограничения ослаблены.

  • Оператор when может быть удален или его ограничения ослаблены.

  • Оператор mandatory может быть удален или значение true заменено на false.

  • Оператор min-elements может быть удален или изменен, чтобы требовать меньше элементов.

  • Оператор max-elements может быть удален или изменен, чтобы разрешить больше элементов.

  • Оператор description может быть добавлен или уточнен без изменения семантики определения.

  • Оператор base может быть добавлен в identity.

  • Оператор base может быть удален из типа identityref, пока в том остается хотя бы один оператов base.

  • Могут быть добавлены новые операторы typedef, grouping, rpc, notification, extension, feature и identity.

  • Могут быть добавлены операторы определения данных, если они не добавляют обязательных узлов (раздел 3) к имеющимся узлам или на верхнем уровне модуля или субмодуля, а также не создают для тех условных зависимостей от новой функции (т. е. if-feature с указанием новой функции).

  • Могут быть добавлены варианты case.

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

  • Оператор if-feature может быть удален, если его узел не является обязательным (раздел 3).

  • Оператор status может быть добавлен или значение его изменено с current на deprecated или obsolete, а также с deprecated на obsolete.

  • Оператор type может быть заменен другим оператором type, который не меняет синтаксис и семантику типа. Например, определение типа inline может быть заменено на typedef, но тип int8 нельзя заменить на int16, поскольку это меняет синтаксис.

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

  • Модуль может быть разделен на несколько субмодулей или часть субмодулей может быть удалена, если определения модуля не изменятся (за исключением разрешенных здесь изменений).

  • Оператор prefix может быть изменен при условии корректировки всех локальных применений этого префикса.

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

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

12. Сосуществование с YANG версии 1

Модулю YANG версии 1.1 недопустимо включать субмодуль YANG версии 1, а модулю YANG версии 1 недопустимо включать субмодуль YANG версии 1.1.

Модулю или субмодулю YANG версии 1 недопустимо импортировать модуль YANG версии 1.1 по выпуску.

Модуль или субмодуль YANG версии 1.1 может импортировать модуль YANG версии 1 по выпуску.

Если модуль A (YANG версии 1) испортирует модуль B без указания выпуска и модуль B обновлен до YANG 1.1, сервер может одновременно реализовать оба модуля (A и B). В таких случаях сервер NETCONF должен анонсировать оба модуля, используя правила, определенные в параграфе 5.6.4, также ему следует анонсировать модуль A и последний выпуск модуля B, в котором еще указан YANG версии 1, в соответствии с правилами [RFC6020].

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

1В этом случае точки и верхняя граница диапазона не указываются. Прим. перев.




RFC7950 (часть 3)

Часть 2


7.8. Оператор list

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

Записи списка однозначно идентифицируются значениями ключей списка, если эти ключи определены.

7.8.1. Субоператоры для list

Субоператор

Параграф

Число элементов

action

7.15

0..n

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

config

7.21.1

0..1

container

7.5

0..n

description

7.21.3

0..1

grouping

7.12

0..n

if-feature

7.20.2

0..n

key

7.8.2

0..1

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

max-elements

7.7.6

0..1

min-elements

7.7.5

0..1

must

7.5.3

0..n

notification

7.16

0..n

ordered-by

7.7.7

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

typedef

7.3

0..n

unique

7.8.3

0..n

uses

7.13

0..n

when

7.21.5

0..1

7.8.2. Оператор key

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

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

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

Все листья ключа в списке должны иметь то же значение config, что и сам список.

Синтаксис строки key формально определен правилом key-arg в разделе 14.

7.8.3. Оператор unique

Оператор unique служит задает ограничения для пригодных элементов списка и принимает аргумент в форме строки с разделенными пробелами идентификаторами узлов из списка схемы, которые должны быть заданы в форме потомков (правило descendant-schema-nodeid в разделе 14). Каждый из этих идентификаторов узлов схемы должен указывать лист.

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

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

Синтаксис строки unique формально определен правилом unique-arg из раздела 14.

7.8.3.1. Пример использования

Для показанного ниже списка

     list server {
       key "name";
       unique "ip port";
       leaf name {
         type string;
       }
       leaf ip {
         type inet:ip-address;
       }
       leaf port {
         type inet:port-number;
       }
     }

приведенная ниже конфигурация будет непригодной

     <server>
       <name>smtp</name>
       <ip>192.0.2.1</ip>
       <port>25</port>
     </server>

     <server>
       <name>http</name>
       <ip>192.0.2.1</ip>
       <port>25</port>
     </server>

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

     <server>
       <name>smtp</name>
       <ip>192.0.2.1</ip>
       <port>25</port>
     </server>

     <server>
       <name>http</name>
       <ip>192.0.2.1</ip>
     </server>

     <server>
       <name>ftp</name>
       <ip>192.0.2.1</ip>
     </server>

7.8.4. Операторы дочерних узлов списка

Внутри списка операторы container, leaf, list, leaf-list, uses, choice, anydata и anyxmls могут служить для определения дочерних узлов списка.

7.8.5. Правила представления XML

Список представляется набором элементов XML по одному на каждый элемент списка. Локальное имя каждого элемента является идентификатором списка, а пространством имен служит пространство имен XML для модуля (параграф 7.1.3). Элемента XML, включающего список целиком, нет.

Узлы ключей списка представляются в форме субэлементов идентификаторов списка в том же порядке, как они определены в операторе key.

Остальная часть дочерних узлов списка представляется в виде субэлементов для элемента списка после ключей. Если список определяет входные или выходные параметры RPC или операции (action), субэлементы кодируются в том же порядке, как они определены в операторе list. В стальных случаях порядок может быть произвольным.

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

Элементы XML, представляющие элементы списка, должны указываться в заданном пользователем порядке, если список имеет тип ordered-by user. В противном случае порядок зависит от реализации. Элементы XML, представляющие элементы списка, могут чередоваться с элементами братских (sibling) списков, если список не определяет входные или выходные параметры RPC или операции.

7.8.6. Операции NETCONF <edit-config>

Элементы списка можно создавать, удалять, заменять и изменять с помощью операции <edit-config> с использованием атрибута operation в элементе XML для списка. В каждом случае значения всех ключей служат для однозначной идентификации элементов списка. Если для элемента списка не заданы все ключи, возвращается ошибка missing-element.

В упорядоченных пользователем списках атрибуты insert и key в пространстве имен YANG XML (параграф 5.3.1) могут служить для управления местом размещения элемента в списке. Они могут применяться в операциях create для вставки новых элементов, а также в операциях merge или replace для вставки нового элемента или перемещения существующего.

Атрибут оператора insert может принимать значения first, last, before и after. Для значений before и after должен также указываться атрибут key, задающий имеющийся в списке элемент. Значение атрибута key является ключом, задающим полный идентификатор экземпляра (параграф 9.13) для элемента списка.

Если атрибут insert не задан для операции create, по умолчанию элемент добавляется в конец списка (last).

Если несколько элементов упорядоченного пользователем списка меняются в одном запросе <edit-config>, элементы изменяются по одному в порядке размещения элементов XML в запросе.

В командах <copy-config> и <edit-config> с операцией replace, покрывающей весь список, порядок в списке совпадает с порядком элементов XML в запросе.

При обработке сервером NETCONF запроса <edit-config> для узла list выполняются приведенные ниже правила.

  • Если задана операция merge или replace, элемент списка создается при его отсутствии. Если элемент списка уже существует и имеются атрибуты insert и key, элемент перемещается в соответствии со значениями этих атрибутов. Если элемент списка существует, но атрибутов insert и key нет, элемент списка не перемещается.

  • Если задана операция create, элемент списка создается при его отсутствии, а в случае наличия элемента возвращается ошибка data-exists.

  • Если задана операция delete, элемент списка удаляется при его наличии, а в случае отсутствия элемента возвращается ошибка data-missing.

7.8.7. Пример использования

Для списка

     list user {
       key "name";
       config true;
       description
         "This is a list of users in the system.";

       leaf name {
         type string;
       }
       leaf type {
         type string;
       }
       leaf full-name {
         type string;
       }
     }

Соответствующий экземпляр XML будет иметь вид

     <user>
       <name>fred</name>
       <type>admin</type>
       <full-name>Fred Flintstone</full-name>
     </user>

Создание нового пользователя barney

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config">
             <user nc:operation="create">
               <name>barney</name>
               <type>admin</type>
               <full-name>Barney Rubble</full-name>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

Изменение роли пользователя fred на superuser

     <rpc message-id="102"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config">
             <user>
               <name>fred</name>
               <type>superuser</type>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

Для упорядоченного пользователем списка

     list user {
       description
         "This is a list of users in the system.";
       ordered-by user;
       config true;

       key "first-name surname";

       leaf first-name {
         type string;
       }
       leaf surname {
         type string;
       }
       leaf type {
         type string;
       }
     }

Приведенный ниже фрагмент будет использоваться для добавления нового пользователя barney после пользователя fred

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:yang="urn:ietf:params:xml:ns:yang:1">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config"
                xmlns:ex="urn:example:config">
             <user nc:operation="create"
                   yang:insert="after"
                   yang:key="[ex:first-name='fred']
                             [ex:surname='flintstone']">
               <first-name>barney</first-name>
               <surname>rubble</surname>
               <type>admin</type>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

Приведенный ниже фрагмент будет служить для размещения пользователя barney перед пользователем fred

     <rpc message-id="102"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:yang="urn:ietf:params:xml:ns:yang:1">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config"
                xmlns:ex="urn:example:config">
             <user nc:operation="merge"
                   yang:insert="before"
                   yang:key="[ex:name='fred']
                             [ex:surname='flintstone']">
               <first-name>barney</first-name>
               <surname>rubble</surname>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

7.9. Оператор choice

Оператор choice определяет набор вариантов, из которых в дереве данных в каждый момент может присутствовать только один. Аргументом оператора является идентификатор, за которым следует блок субоператоров с детальной информацией о выборе. Идентификатор служит для указания узла choice в дереве схемы. В дереве данных узлов choice не существует.

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

Поскольку в дереве данных в любой момент может действовать только один из вариантов выбора, создание узла в одном из вариантов (case) неявно удаляет все узлы из других вариантов. Если запрос создает узел из case, сервер будет удалять все имеющиеся узлы, определенные другими вариантами в этом операторе choice.

7.9.1. Субоператоры для choice

Субоператор

Параграф

Число элементов

anydata

7.10

0..n

anyxml

7.11

0..n

case

7.9.2

0..n

choice

7.9

0..n

config

7.21.1

0..1

container

7.5

0..n

default

7.9.3

0..1

description

7.21.3

0..1

if-feature

7.20.2

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

mandatory

7.9.4

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

when

7.21.5

0..1

7.9.2. Оператор case для выбора

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

Идентификатор служит для указания узла case в дереве схемы. Узлов case не существует в дереве данных.

Внутри case могут применяться операторы anydata, anyxml, choice, container, leaf, list, leaf-list и uses для определения потомков узла case. Идентификаторы всех дочерних узлов должны быть уникальными для всех вариантов case в данном choice. Ниже приведен пример недопустимого выбора.

     choice interface-type {     // Это неприемлемо в YANG
       case a {
         leaf ethernet { ... }
       }
       case b {
         container ethernet { ...}
       }
     }

Для сокращения оператор case может быть опущен, если вариант содержит один оператор anydata, anyxml, choice, container, leaf, list или leaf-list. В таких случаях узел case продолжает существовать в дереве схемы и его идентификатором служит идентификатор дочернего узла. Идентификаторы узлов схемы (параграф 6.5) всегда должны явно включать идентификаторы узлов case. Выражение

     choice interface-type {
       container ethernet { ... }
     }

эквивалентно

     choice interface-type {
       case ethernet {
         container ethernet { ... }
       }
     }

Каждый идентификатор case должен быть уникальным в рамках choice.

7.9.2.1. Субоператоры для case

Субоператор

Параграф

Число элементов

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

container

7.5

0..n

description

7.21.3

0..1

if-feature

7.20.2

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

uses

7.13

0..n

when

7.21.5

0..1

7.9.3. Субоператор default для выбора

Оператор default указывает вариант (case), который следует применять по умолчанию, если нет дочерних узлов ни у одного из вариантов choice. Аргументом служит идентификатор заданного по умолчанию варианта (case). Если оператор default не задан, используемого по умолчанию варианта не будет.

Оператор default недопустимо включать в оператор выбора (choice), где для mandatory задано значение true.

Используемый по умолчанию вариант важен только при рассмотрении операторов default в дочерних узлах вариантов (т. е. принятых по умолчанию значений leaf и leaf-list, а также используемых по умолчанию вариантов вложенных операторов choice). Принятые по умолчанию значения и варианты вложенных choice в потомках заданного по умолчанию варианта используются при отсутствии узлов в любом из вариантов (case).

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

Принятые по умолчанию значения дочерних узлов case используются лишь в тех случаях, когда один из таких узлов присутствует в варианте (case) или вариант задан в качестве принятого по умолчанию. Если нет ни одного из дочерних узлов варианта и вариант не задан в качестве принятого по умолчанию, заданные по умолчанию значения дочерних узлов варианта игнорируются.

В приведенном ниже примере выбор (choice) указывает по умолчанию вариант interval и принятое по умолчанию значение будет использоваться, если нет ни одного из листьев daily, time-of-day и manual. Если узел daily присутствует, будет использовано значение, принятое по умолчанию для узла time-of-day.

     container transfer {
       choice how {
         default interval;
         case interval {
           leaf interval {
             type uint16;
             units minutes;
             default 30;
           }
         }
         case daily {
           leaf daily {
             type empty;
           }
           leaf time-of-day {
             type string;
             units 24-hour-clock;
             default "01.00";
           }
         }
         case manual {
           leaf manual {
             type empty;
           }
         }
       }
     }

7.9.4. Оператор mandatory для выбора

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

Если оператор не задан, по умолчанию предполагается значение false.

Поведение ограничений зависит от типа ближайшего предка choice в дереве схемы, который не является контейнером отсутствия (параграф 7.5.1):

  • если такого предка нет в дереве схемы, ограничение применяется;

  • в противном случае, если предок является узлом case, ограничение применяется при наличии любого другого узла от этого варианта (case);

  • в остальных случаях ограничение применяется при наличии узла-предка.

Далее ограничения применяются в соответствии с правилами раздела 8.

7.9.5. Правила представления XML

Узлы choice и case не видны в XML.

Дочерние узлы выбранного варианта (case) должны представляться в том же порядке, как они были определены в операторе case, если это часть определения входных или выходных параметров RPC или action.

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

7.9.6. Пример использования

Для приведенного ниже примера

     container protocol {
       choice name {
         case a {
           leaf udp {
             type empty;
           }
         }
         case b {
           leaf tcp {
             type empty;
           }
         }
       }
     }

Соответствующий экземпляр XML будет иметь вид

     <protocol>
       <tcp/>
     </protocol>

Для смены протокола TCP на UDP может служить приведенный ниже фрагмент.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config">
             <protocol>
               <udp nc:operation="create"/>
             </protocol>
           </system>
         </config>
       </edit-config>
     </rpc>

7.10. Оператор anydata

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

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

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

Узел anydata не может быть дополнен (параграф 7.17).

Узел anydata отсутствует в дереве данных или содержится там в одном экземпляре.

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

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

7.10.1. Субоператоры для anydata

Субоператор

Параграф

Число элементов

config

7.21.1

0..1

description

7.21.3

0..1

if-feature

7.20.2

0..n

mandatory

7.6.5

0..1

must

7.5.3

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

when

7.21.5

0..1

7.10.2. Правила представления XML

Узел anydata представляется в виде элемента XML. Локальное имя элемента является идентификатором anydata, а пространством имен служит пространство имен XML для модуля (параграф 7.1.3). Значением узла anydata является множество узлов, которые представляются субэлементами XML для элемента anydata.

7.10.3. Операции NETCONF <edit-config>

Узел anydata рассматривается, как «непрозрачный» (opaque) блок данных. Эти данные могут изменяться лишь целиком.

Любые атрибуты operation, представленные в субэлементах узла anydata, игнорируются сервером NETCONF.

При обработке сервером NETCONF запроса <edit-config> для узла anydata выполняются приведенные ниже правила.

  • Если задана операция merge или replace, узел создается при его отсутствии, а в качестве значения устанавливаются субэлементы узла anydata из данных XML для RPC.

  • Если задана операция create, узел создается при его отсутствии, а в качестве значения устанавливаются субэлементы узла anydata из данных XML для RPC. В случае наличия узла возвращается ошибка data-exists.

  • Если задана операция delete, узел удаляется при его наличии, а в случае отсутствия узла возвращается ошибка data-missing.

7.10.4. Пример использования

Ниже приведен пример использования оператора anydata.

     list logged-notification {
       key time;
       leaf time {
         type yang:date-and-time;
       }
       anydata data;
     }

Приведенный фрагмент является пригодным представлением экземпляра списка.

     <logged-notification>
       <time>2014-07-29T13:43:12Z</time>
       <data>
         <notification
           xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
           <eventTime>2014-07-29T13:43:01Z</eventTime>
           <event xmlns="urn:example:event">
             <event-class>fault</event-class>
             <reporting-entity>
               <card>Ethernet0</card>
             </reporting-entity>
             <severity>major</severity>
           </event>
         </notification>
       </data>
     </logged-notification>

7.11. Оператор anyxml

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

Оператор anyxml служит для представления неизвестного блока данных XML, на который не накладывается каких-либо ограничений. Это может быть полезно, например, в откликах RPC. Примером может служить параметр <filter> в операции <get-config> протокола NETCONF.

Узел anyxml не может быть дополнен (параграф 7.17).

Узел anyxml отсутствует в дереве данных или содержится там в одном экземпляре.

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

Следует отметить, что в YANG версии 1 оператор anyxml был единственным оператором для моделирования неизвестной иерархии данных. Во многих случаях такие неизвестные данные реально моделировались в YANG, но конкретная модель данных YANG не была известна в момент разработки. В таких случаях рекомендуется использовать оператор anydata (параграф 7.10) вместо anyxml.

7.11.1. Субоператоры для anyxml

Субоператор

Параграф

Число элементов

config

7.21.1

0..1

description

7.21.3

0..1

if-feature

7.20.2

0..n

mandatory

7.6.5

0..1

must

7.5.3

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

when

7.21.5

0..1

7.11.2. Правила представления XML

Узел anyxml представляется в виде элемента XML. Локальное имя элемента является идентификатором anyxml, а пространством имен служит пространство имен XML для модуля (параграф 7.1.3). Значение узла anyxml представляется в качестве содержимого XML для этого элемента.

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

7.11.3. Операции NETCONF <edit-config>

Узел anyxml рассматривается, как «непрозрачный» (opaque) блок данных. Эти данные могут изменяться лишь целиком.

Любые атрибуты operation, представленные в субэлементах узла anyxml, игнорируются сервером NETCONF.

При обработке сервером NETCONF запроса <edit-config> для узла anyxml выполняются приведенные ниже правила.

  • Если задана операция merge или replace, узел создается при его отсутствии, а в качестве значения устанавливается содержимое XML узла anyxml в данных XML для RPC.

  • Если задана операция create, узел создается при его отсутствии, а в качестве значения устанавливается содержимое XML узла anyxml в данных XML для RPC. В случае наличия узла возвращается ошибка data-exists.

  • Если задана операция delete, узел удаляется при его наличии, а в случае отсутствия узла возвращается ошибка data-missing.

7.11.4. Пример использования

Для оператора anyxml

     anyxml html-info;

Ниже приведены два варианта корректного представления одного значения anyxml.

      <html-info>
        <p xmlns="http://www.w3.org/1999/xhtml">
          This is <em>very</em> cool.
        </p>
      </html-info>

      <html-info>
        <x:p xmlns:x="http://www.w3.org/1999/xhtml">
          This is <x:em>very</x:em> cool.
        </x:p>
      </html-info>

7.12. Оператор grouping

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

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

Группировка напоминает структуры (structure) или записи (record) в традиционных языках программирования.

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

Если группировка определена на верхнем уровне модуля или субмодуля YANG, идентификатор группировки должен быть уникальным в рамках модуля.

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

Если группировка определяет узел action или notification в своей иерархии, этот узел не может применяться в любом контексте (параграфы 7.15 и 7.16).

7.12.1. Субоператоры для grouping

Субоператор

Параграф

Число элементов

action

7.15

0..n

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

container

7.5

0..n

description

7.21.3

0..1

grouping

7.12

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

notification

7.16

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

typedef

7.3

0..n

uses

7.13

0..n

7.12.2. Пример использования

     import ietf-inet-types {
       prefix "inet";
     }

     grouping endpoint {
       description "A reusable endpoint group.";
       leaf ip {
         type inet:ip-address;
       }
       leaf port {
         type inet:port-number;
       }
     }

7.13. Оператор uses

Оператор uses применяется для ссылок на определения группировок (grouping) и принимает один аргумент, задающий имя группировки.

Эффект ссылки uses на группировку заключается в том, что определенные группировкой узлы копируются в текущее дерево схемы, а затем обновляются в соответствии с операторами refine и augment.

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

7.13.1. Субоператоры для uses

Субоператор

Параграф

Число элементов

augment

7.17

0..n

description

7.21.3

0..1

if-feature

7.20.2

0..n

reference

7.21.4

0..1

refine

7.13.2

0..n

status

7.21.2

0..1

when

7.21.5

0..1

7.13.2. Оператор refine

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

Строка аргумента представляет собой идентификатор узла-потомка в схеме (параграф 6.5).

Оператор позволяет выполнить перечисленные ниже уточнения.

  • Узел leaf или choice может получить используемое по умолчанию значение или обновить имеющееся.

  • Узел leaf-list может получить набор используемых по умолчанию значений или обновить имеющиеся (т. е. новый набор будет установлен взамен прежнего).

  • Любой узел может получить специализированную строку описания (description).

  • Любой узел может получить специализированную строку ссылки (reference).

  • Любой узел может получить другой оператор config.

  • Узел leaf, anydata, anyxml или choice может получить другой оператор mandatory.

  • Контейнер может получить оператор presence.

  • Узел leaf, leaf-list, list, container, anydata или anyxml может получить дополнительные выражения must.

  • Узел leaf-list или list может получить другие операторы min-elements или max-elements.

  • Узел leaf, leaf-list, list, container, choice, case, anydata или anyxml может получить дополнительные выражения if-feature.

  • Любой узел может получить уточненные расширения, если те поддерживают уточнение (параграф 7.19).

7.13.3. Правила представления XML

Каждый узел в группировке представляется, как будто он был определен здесь (inline), даже если он импортирован из другого модуля с иным пространством имен XML.

7.13.4. Пример использования

Для использования группировки endpoint, определенной в параграфе 7.12.2, при определении сервера HTTP в каком-то другом модуле можно задать

     import example-system {
       prefix "sys";
     }

     container http-server {
       leaf name {
         type string;
       }
       uses sys:endpoint;
     }

Соответствующий экземпляр XML будет иметь вид

     <http-server>
       <name>extern-web</name>
       <ip>192.0.2.1</ip>
       <port>80</port>
     </http-server>

Если на сервере HTTP по умолчанию следует применять порт 80, можно добавить оператор default.

     container http-server {
       leaf name {
         type string;
       }
       uses sys:endpoint {
         refine port {
           default 80;
         }
       }
     }

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

     list server {
       key "ip port";
       leaf name {
         type string;
       }
       uses sys:endpoint;
     }

Ниже приведен пример с ошибкой.

     container http-server {
       uses sys:endpoint;
       leaf ip {          // недопустимо - идентификатор ip применяется дважды
         type string;
       }
     }

7.14. Оператор rpc

Оператор rpc служит для определения операций вызова удаленной процедуры (RPC). Он принимает один аргумент в форме идентификатора, за которым следует блок субоператоров, определяющих операцию вызова удаленной процедуры. Аргумент является именем RPC.

Оператор rpc определяет узел rpc в дереве схемы. Для узла rpc в схеме также определяются дочерние узлы input и output в пространстве имен модуля.

7.14.1. Субоператоры для rpc

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

grouping

7.12

0..n

if-feature

7.20.2

0..n

input

7.14.2

0..1

output

7.14.3

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

typedef

7.3

0..n

7.14.2. Оператор input

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

Если лист в дереве input имеет оператор mandatory со значением true, этот лист должен присутствовать в вызове RPC.

Если лист в дереве input имеет принятое по умолчанию значение, сервер должен использовать это значение в случаях, описанных в параграфе 7.6.1. В таких ситуациях сервер должен вести себя так, будто при вызове RPC принятое по умолчанию значение листа было передано в качестве входного параметра.

Если узел leaf-list в дереве input имеет одно или несколько принятых по умолчанию значений, сервер должен использовать эти значения в случаях, описанных в параграфе 7.7.2. В таких ситуациях сервер должен вести себя так, будто узел leaf-list был представлен при вызове RPC с принятыми по умолчанию значениями.

Поскольку дерево input не помещается в какое-либо хранилище данных, все операторы config для узлов этого дерева игнорируются.

Если любой из узлов имеет оператор when, который дает значение false, такой узел недопустимо включать в дерево input.

7.14.2.1. Субоператоры для input

Субоператор

Параграф

Число элементов

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

container

7.5

0..n

grouping

7.12

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

must

7.5.3

0..n

typedef

7.3

0..n

uses

7.13

0..n

7.14.3. Оператор output

Необязательный оператор output служит для определения выходных значений операции RPC и не имеет аргументов. Субоператоры для output определяют узлы-потомки узла output определяемой операции.

Если лист дерева имеет оператор mandatory со значением true, лист должен присутствовать в отклике RPC.

Если лист в дереве output имеет принятое по умолчанию значение, клиент должен использовать это значение в случаях, описанных в параграфе 7.6.1. В таких ситуациях клиент должен вести себя так, будто принятое по умолчанию значение листа присутствует в выводе RPC.

Если узел leaf-list в дереве output имеет одно или несколько принятых по умолчанию значений, клиент должен использовать эти значений в случаях, описанных в параграфе 7.7.2. В таких ситуациях клиент должен вести себя так, будто в выходе RPC присутствует leaf-list с принятыми по умолчанию значениями.

Поскольку дерево output не помещается в какое-либо хранилище данных, все операторы config для узлов дерева output игнорируются.

Если любой из узлов имеет оператор when, выражение которого дает значение false, такой узел недопустимо включать в дерево output.

7.14.3.1. Субоператоры для output

Субоператор

Параграф

Число элементов

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

container

7.5

0..n

grouping

7.12

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

must

7.5.3

0..n

typedef

7.3

0..n

uses

7.13

0..n

7.14.4. Правила представления NETCONF XML

Узел rpc представляется как дочерний элемент XML элемента <rpc> в соответствии с группой подстановки rpcOperation [RFC6241]. Локальное имя элемента является идентификатором rpc, а его пространство имен — пространством имен XML для модуля (параграф 7.1.3).

Входные параметры представляются дочерними элементами XML для элемента XML узла rpc в том же порядке, как они были определены в операторе input.

Если после успешного вызова RPC не было возвращено выходных параметров, <rpc-reply> содержит только элемент <ok/>, определенный в [RFC6241]. Если выходные параметры присутствуют, они кодируются как дочерние элементы элемента <rpc-reply>, определенного в [RFC6241], с тем же порядком, который был определен в операторе output.

7.14.5. Пример использования

Приведенный ниже пример определяет операцию RPC.

     module example-rock {
       yang-version 1.1;
       namespace "urn:example:rock";
       prefix "rock";

       rpc rock-the-house {
         input {
           leaf zip-code {
             type string;
           }
         }
       }
     }

Соответствующие экземпляры XML для полных rpc и rpc-reply приведены ниже.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <rock-the-house xmlns="urn:example:rock">
         <zip-code>27606-0100</zip-code>
       </rock-the-house>
     </rpc>

     <rpc-reply message-id="101"
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <ok/>
     </rpc-reply>

7.15. Оператор action

Оператор action служит для определения операции, подключенной к конкретному контейнеру или списку. Оператор принимает в качестве аргумента идентификатор узла, за которым следует блок субоператоров с информацией об операции. Аргумент является именем операции (action).

Оператор action определяет узел action в дереве схемы. Для узла action определяются также дочерние узлы схемы с именами input и output. Эти узлы определяются в пространстве имен модуля.

Действие недопустимо определять в rpc, другом действии или уведомлении (notification), т. е. узлу action недопустимо иметь в дереве схемы родительский узел типа rpc, action или notification. Это означает, что будет ошибкой, если группировка будет включать узел action в своей иерархии, которая используется для того, чтобы определить уведомление.

Узлу action недопустимо иметь в качестве родителя узел, который является списком без оператора key.

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

Различие между action и rpc заключается в том, что операция привязана к узлу в хранилище данных, а rpc нет. При вызове операции задается узел в хранилище данных вместе с именем операции и входными параметрами.

7.15.1. Субоператоры для action

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

grouping

7.12

0..n

if-feature

7.20.2

0..n

input

7.14.2

0..1

output

7.14.3

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

typedef

7.3

0..n

7.15.2. Правила представления NETCONF XML

При вызове операции элемент с локальным именем action в пространстве имен urn:ietf:params:xml:ns:yang:1 (параграф 5.3.1) представляется в виде дочернего элемента XML для элемента <rpc>, определенного в [RFC6241], как указано группой подстановки rpcOperation в [RFC6241].

Элемент <action> содержит иерархию узлов, указывающую узел в хранилище данных. Он должен включать все контейнеры и списки на прямом пути от верхнего уровня до списка или контейнера, включающего операцию (action). Для списков все листья ключей также должны включаться. Внутренний (innermost) контейнер или список содержит элемент XML, который передает имя определенной операции. Внутри этого элемента входные параметры представляются дочерними элементами XML в том же порядке, какой был задан в операторе input.

В одном элементе <rpc> может быть вызвана только одна операция. Если в <rpc> присутствует более одной операции, сервер должен вернуть <rpc-error> с тегом <error-tag>, имеющим значение bad-element.

Если вызов операции завершился успешно и не было возвращено выходных параметров, <rpc-reply> содержит только элемент <ok/>, определенный в [RFC6241]. Если выходные параметры присутствуют, они кодируются как дочерние элементы элемента <rpc-reply>, определенного в [RFC6241], с тем же порядком, который был определен в операторе output.

7.15.3. Пример использования

Приведенный ниже пример определяет операцию сброса одного сервера в серверной ферме.

     module example-server-farm {
       yang-version 1.1;
       namespace "urn:example:server-farm";
       prefix "sfarm";

       import ietf-yang-types {
         prefix "yang";
       }

       list server {
         key name;
         leaf name {
           type string;
         }
         action reset {
           input {
             leaf reset-at {
               type yang:date-and-time;
               mandatory true;
              }
            }
            output {
              leaf reset-finished-at {
                type yang:date-and-time;
                mandatory true;
              }
            }
          }
        }
      }

Ниже представлены соответствующие экземпляры XML для полных rpc и rpc-reply.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <action xmlns="urn:ietf:params:xml:ns:yang:1">
         <server xmlns="urn:example:server-farm">
           <name>apache-1</name>
           <reset>
             <reset-at>2014-07-29T13:42:00Z</reset-at>
           </reset>
         </server>
       </action>
     </rpc>

     <rpc-reply message-id="101"
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <reset-finished-at xmlns="urn:example:server-farm">
         2014-07-29T13:42:12Z
       </reset-finished-at>
     </rpc-reply>

7.16. Оператор notification

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

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

Уведомления недопустимо определять в rpc, action или другом узле notification, т. е. уведомлениям недопустимо иметь в качестве узла-предка в дереве схемы rpc, action, notification node. Например, это может возникать в случаях, когда группировка (grouping) содержащая уведомление, будет использована при определении rpc.

Уведомлениям недопустимо иметь в качестве предка узел списка (list) без оператора key.

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

Если лист в дереве уведомления имеет оператор mandatory со значением true, этот лист должен присутствовать в экземплярах уведомления.

Если лист в дереве уведомления имеет принятое по умолчанию значение, клиент должен использовать это значение в случаях, описанных в параграфе 7.6.1. К таких ситуациях клиент должен вести себя так, будто лист присутствует в экземпляре уведомления с принятым по умолчанию значением.

Если leaf-list в дереве уведомления имеет одно или несколько принятых по умолчанию значений, клиент должен использовать эти значения в случаях, описанных в параграфе 7.7.2. В таких ситуациях клиент должен вести себя так, будто leaf-list с принятыми по умолчанию значениями присутствует в экземпляре notification.

Поскольку дерево notification не включается в какое-либо хранилище данных, все операторы config для узлов дерева notification игнорируются.

7.16.1. Субоператоры для notification

Субоператор

Параграф

Число элементов

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

container

7.5

0..n

description

7.21.3

0..1

grouping

7.12

0..n

if-feature

7.20.2

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

must

7.5.3

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

typedef

7.3

0..n

uses

7.13

0..n

7.16.2. Правила представления NETCONF XML

Узел notification, определенный на верхнем уровне модуля, кодируется как дочерний элемент XML для элемента <notification>, определенного в NETCONF Event Notifications [RFC5277]. Локальное имя элемента является идентификатором уведомления, а его пространством имен является пространство имен XML для модуля (параграф 7.1.3).

Когда узел notification определяется как потомок узла данных, элемент <notification>, определенный в [RFC5277], содержит иерархию узлов, указывающих узел данных в хранилище. Она должна включать включать все контейнеры и списки на прямом пути от верхнего уровня до списка или контейнера, содержащего уведомление (notification). Для списков все листья ключей также должны включаться. Внутренний (innermost) контейнер или список содержит элемент XML, который передает имя определенного уведомления.

Дочерние узлы уведомления кодируются как субэлементы элемента XML для узла notification в любом порядке.

7.16.3. Пример использования

Приведенный ниже пример определяет уведомление на верхнем уровне модуля.

     module example-event {
       yang-version 1.1;
       namespace "urn:example:event";
       prefix "ev";

       notification event {
         leaf event-class {
           type string;
         }
         leaf reporting-entity {
           type instance-identifier;
         }
         leaf severity {
           type string;
         }
       }
     }

Соответствующий экземпляр элемента XML для полного уведомления имеет вид

     <notification
       xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
       <eventTime>2008-07-08T00:01:00Z</eventTime>
       <event xmlns="urn:example:event">
         <event-class>fault</event-class>
         <reporting-entity>
           /ex:interface[ex:name='Ethernet0']
         </reporting-entity>
         <severity>major</severity>
       </event>
     </notification>

Следующий пример определяет уведомление в узле данных.

     module example-interface-module {
       yang-version 1.1;
       namespace "urn:example:interface-module";
       prefix "if";

       container interfaces {
         list interface {
           key "name";
           leaf name {
             type string;
           }
           notification interface-enabled {
             leaf by-user {
               type string;
             }
           }
         }
       }
     }

Соответствующий экземпляр элемента XML для полного уведомления имеет вид

     <notification
       xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
       <eventTime>2008-07-08T00:01:00Z</eventTime>
       <interfaces xmlns="urn:example:interface-module">
         <interface>
           <name>eth1</name>
           <interface-enabled>
             <by-user>fred</by-user>
           </interface-enabled>
         </interface>
       </interfaces>
     </notification>

7.17. Оператор augment

Оператор augment позволяет модулю или субмодулю добавить узлы к дереву схемы, определенному во внешнем модуле, текущем модуле и его субмодулях, или к узлам из группировки в операторе uses. Аргументом оператора служит строка, указывающая узел в дереве схемы. Этот узел называется целью добавления. Целевой узел должен быть узлом типа container, list, choice, case, input, output или notification. К нему добавляются узлы, указанные с субоператорах, следующих за оператором augment.

Строка дополнения является идентификатором узла схемы (параграф 6.5). Если оператор augment относится к верхнему уровню модуля или субмодуля, должна применяться абсолютная форма (правило absolute-schema-nodeid в разделе 14) идентификатора узла схемы. Если augment является субоператором для uses, должна применяться наследуемая (descendant) форма (правило descendant-schema-nodeid в разделе 14).

Если целевой узел имеет тип container, list, case, input, output или notification, внутри оператора augment могут применяться субоператоры container, leaf, list, leaf-list, uses и choice.

Если целевой узел является контейнером или списком, внутри оператора augment могут применяться субоператоры action и notification.

Если целевой узел является выбором (choice), внутри оператора augment могут применяться субоператоры case в полной или сокращенной (параграф 7.9.2) форме.

Оператору augment недопустимо добавлять множество узлов с одним именем из одного модуля в один целевой узел.

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

В приведенном ниже примере показано корректное добавление узла interface с mandatory-leaf, поскольку дополнение зависит от поддержки some-new-iftype. Старый клиент не знает этого типа, поэтому он не будет выбирать его и в результате не будет добавлять обязательный узел данных.

     module example-augment {
       yang-version 1.1;
       namespace "urn:example:augment";
       prefix mymod;

       import ietf-interfaces {
         prefix if;
       }

       identity some-new-iftype {
          base if:interface-type;
       }

       augment "/if:interfaces/if:interface" {
          when 'derived-from-or-self(if:type, "mymod:some-new-iftype")';

          leaf mandatory-leaf {
             mandatory true;
             type string;
          }
       }
     }

7.17.1. Субоператоры для augment

Субоператор

Параграф

Число элементов

action

7.15

0..n

anydata

7.10

0..n

anyxml

7.11

0..n

case

7.9.2

0..n

choice

7.9

0..n

container

7.5

0..n

description

7.21.3

0..1

if-feature

7.20.2

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

notification

7.16

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

uses

7.13

0..n

when

7.21.5

0..1

7.17.2. Правила представления XML

Все узлы данных, определенные в операторе augment, задаются как элементы XML, определенные в пространстве имен XML модуля, где указан оператор augment.

При добавлении узла дополняющие потомки кодируются в виде субэлементов дополняемого узла в любом порядке.

7.17.3. Пример использования

В пространстве имен urn:example:interface-module

     container interfaces {
       list ifEntry {
         key "ifIndex";

         leaf ifIndex {
           type uint32;
         }
         leaf ifDescr {
           type string;
         }
         leaf ifType {
           type iana:IfType;
         }
         leaf ifMtu {
           type int32;
         }
       }
     }

В пространстве имен urn:example:ds0

     import example-interface-module {
       prefix "if";
     }
     augment "/if:interfaces/if:ifEntry" {
       when "if:ifType='ds0'";
       leaf ds0ChannelNumber {
         type ChannelNumber;
       }
     }

Пример соответствующего экземпляра XML приведен ниже.

     <interfaces xmlns="urn:example:interface-module"
                 xmlns:ds0="urn:example:ds0">
       <ifEntry>
         <ifIndex>1</ifIndex>
         <ifDescr>Flintstone Inc Ethernet A562</ifDescr>
         <ifType>ethernetCsmacd</ifType>
         <ifMtu>1500</ifMtu>
       </ifEntry>
       <ifEntry>
         <ifIndex>2</ifIndex>
         <ifDescr>Flintstone Inc DS0</ifDescr>
         <ifType>ds0</ifType>
         <ds0:ds0ChannelNumber>1</ds0:ds0ChannelNumber>
       </ifEntry>
     </interfaces>

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

     augment /ex:system/ex:protocol/ex:name {
       case c {
         leaf smtp {
           type empty;
         }
       }
     }

Соответствующий экземпляр XML будет иметь вид

     <ex:system>
       <ex:protocol>
         <ex:tcp/>
       </ex:protocol>
     </ex:system>

или

     <ex:system>
       <ex:protocol>
         <other:smtp/>
       </ex:protocol>
     </ex:system>

7.18. Оператор identity

Оператор identity служит для определения нового уникального в глобальном масштабе, абстрактного отождествления без конкретного типа. Единственной целью создания такого отождествления является обозначение его имени, семантики и существования. Отождествление может быть определено «с нуля» или произведено на основе одного или нескольких базовых отождествлений. Аргументом identity является идентификатор, указывающий имя этого отождествления, за которым следует блок субоператоров с информацией об отождествлении.

Для определения отождествлений в модели данных может применяться встроенный тип данных identityref (параграф 9.10).

7.18.1. Субоператоры для identity

Субоператор

Параграф

Число элементов

base

7.18.2

0..n

description

7.21.3

0..1

if-feature

7.20.2

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

7.18.2. Оператор base

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

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

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

Создание производных отождествлений имеет следующие свойства:

  • нерефлексивность (отождествление не выводится из самого себя);

  • транзитивность (если отождествление B является производным от A, а C — производным от B, то C является также производным от A).

7.18.3. Пример использования

     module example-crypto-base {
       yang-version 1.1;
       namespace "urn:example:crypto-base";
       prefix "crypto";

       identity crypto-alg {
         description
           "Base identity from which all crypto algorithms
            are derived.";
       }

       identity symmetric-key {
         description
           "Base identity used to identify symmetric-key crypto
            algorithms.";
         }

       identity public-key {
         description
           "Base identity used to identify public-key crypto
            algorithms.";
         }
     }

     module example-des {
       yang-version 1.1;
       namespace "urn:example:des";
       prefix "des";

       import "example-crypto-base" {
         prefix "crypto";
       }

       identity des {
         base "crypto:crypto-alg";
         base "crypto:symmetric-key";
         description "DES crypto algorithm.";
       }

       identity des3 {
         base "crypto:crypto-alg";
         base "crypto:symmetric-key";
         description "Triple DES crypto algorithm.";
       }
     }

7.19. Оператор extension

Оператор extension позволяет определять новые операторы для языка YANG. Определение нового оператора может импортироваться и использоваться другими модулями.

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

Расширение может применяться подобно обычным операторам YANG с именем оператора, за которым следует аргумент, если он был определен оператором extension, а также может следовать блок субоператоров. Имя оператора создается путем объединения префикса модуля, в котором было определено расширение, двоеточия (:) и ключевого слова расширения без пробелов между ними. Субоператоры расширения определяются оператором extension, с использованием механизмов, выходящих за рамки данной спецификации. Синтаксически субоператоры должны быть операторами YANG, включая расширения, определенные с использованием операторов extension. Операторы YANG в расширениях должны следовать синтаксическим правила раздела 14.

Расширение может разрешать уточнение (параграф 7.13.2) и отклонения (параграф 7.20.3.2), но механизм для этого выходит за рамки спецификации.

7.19.1. Субоператоры для extension

Субоператор

Параграф

Число элементов

argument

7.19.2

0..1

description

7.21.3

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

7.19.2. Оператор argument

Необязательный оператор argument принимает строку имени аргумента для ключевого слова (расширения). Если оператор argument не задан, ключевое слово будет использоваться без аргументов.

Имя аргумента используется в отображении YIN, где оно служит атрибутом XML или именем элемента в зависимости от субоператора yin-element в этом операторе argument.

7.19.2.1. Субоператор для argument

Субоператор

Параграф

Число элементов

yin-element

7.19.2.2

0..1

7.19.2.2. Оператор yin-element

Необязательный оператор yin-element принимает в качестве аргумента строку true или false. Этот оператор показывает, отображается ли argument в элемент или атрибут XML при преобразовании в YIN (раздел 13).

Если оператор yin-element не задан, по умолчанию предполагается значение false.

7.19.3. Пример использования

Определение расширения может иметь вид

     module example-extensions {
       yang-version 1.1;
       ...

       extension c-define {
         description
           "Takes as an argument a name string.
            Makes the code generator use the given name
            in the #define.";
         argument "name";
       }
     }

Использование расширения может иметь вид

     module example-interfaces {
       yang-version 1.1;

       ...
       import example-extensions {
         prefix "myext";
       }
       ...

       container interfaces {
         ...
         myext:c-define "MY_INTERFACES";
       }
     }

7.20. Операторы, связанные с соответствием спецификации

В этом разделе определены операторы, связанные с совместимостью, как описано в параграфе 5.6.

7.20.1. Оператор feature

Оператор feature служит для определения механизма, с помощью которого часть схемы помечается, как условная. Определяется имя функции, на которое можно потом ссылаться в операторах if-feature (параграф 7.20.2). Узлы схемы, помеченные оператором if-feature, игнорируются сервером, если он не поддерживает заданное в операторе feature выражение. Это позволяет сделать часть модуля YANG условной, в зависимости от возможностей сервера. Модель может представлять возможности сервера внутри себя, что делает ее более эффективной и позволяет серверам выступать в различных ролях.

Аргументом оператора feature является имя новой функции (возможности), которое выбирается в соответствии с правилами для идентификаторов, приведенными в параграфе 6.2. Это имя используется в операторах if-feature для привязки узлов схемы к данной функции.

В приведенном ниже примере функция local-storage представляет способность сервера локально сохранять сообщения syslog на том или ином его устройстве. Эта функция используется для того, чтобы сделать лист local-storage-limit условным, в зависимости от наличия на сервере локального хранилища. Если сервер не укажет поддержку этой функции, узел local-storage-limit не будет поддерживаться.

     module example-syslog {
       yang-version 1.1;

       ...
       feature local-storage {
         description
           "This feature means that the server supports local
            storage (memory, flash, or disk) that can be used to
            store syslog messages.";
       }

       container syslog {
         leaf local-storage-limit {
           if-feature local-storage;
           type uint64;
           units "kilobyte";
           config false;
           description
             "The amount of local storage that can be
              used to hold syslog messages.";
         }
       }
     }

Оператор if-feature может использоваться в разных местах синтаксиса YANG. Определения с пометкой if-feature игнорируются, если сервер не поддерживает данную функцию.

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

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

7.20.1.1. Субоператоры для feature

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

if-feature

7.20.2

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

7.20.2. Оператор if-feature

Оператор if-feature делает родительский оператор условным. Аргументом является логическое выражение с именами функций. В этом выражении имя функции считается истинным (true) тогда и только тогда, когда эта функция поддерживается сервером. Родительский оператор выполняется серверами в том случае, когда логическое выражение истинно (true).

Синтаксис логических выражений if-feature формально определен правилом if-feature-expr в разделе 14. Скобки служат для группировки выражений. При вычислении используется порядок действий: группировка (скобки), not, and, or.

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

Листу, являющемуся ключом списка, недопустимо включать операторы if-feature.

7.20.2.1. Пример использования

В этом примере контейнер target реализуется в том случае, когда функция outbound-tls или outbound-ssh поддерживается сервером.

     container target {
       if-feature "outbound-tls or outbound-ssh";
       ...
     }

Приведенные ниже примеры эквивалентены.

     if-feature "not foo or bar and baz";
     if-feature "(not foo) or (bar and baz)";

7.20.3. Оператор deviation

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

Строка аргумента указывает абсолютный идентификатор узла схемы (параграф 6.5).

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

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

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

Взамен этих вариантов YANG позволяет серверам указать неподдерживаемые части базового модуля или показать использование для их поддержки другого синтаксиса. Делается это с помощью оператора deviation.

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

7.20.3.1. Субоператоры для deviation

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

deviate

7.20.3.2

1 — n

reference

7.21.4

0..1

7.20.3.2. Оператор deviate

Оператор deviate указывает отклонение реализации сервера для целевого узла от исходного определения. Аргумент оператора может принимать значение not-supported, add, replace или delete.

Значение not-supported показывает, что целевой узел не реализован на этом сервере.

Значение add добавляет свойства целевому узлу. Свойства для добавления указываются субоператорами оператора deviate. Если свойство может появляться только один раз, его существование в целевом узле недопустимо.

Значение replace заменяет свойства целевого узла. Свойства для замены указываются субоператорами оператора deviate. Заменяемое свойство должно существовать у целевого узла.

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

Субоператор

Параграф

Число элементов

config

7.21.1

0..1

default

7.6.4, 7.7.4

0..n

mandatory

7.6.5

0..1

max-elements

7.7.6

0..1

min-elements

7.7.5

0..1

must

7.5.3

0..n

type

7.4

0..1

unique

7.8.3

0..n

units

7.3.3

0..1

Если целевой узел имеет свойство, заданное расширением, возможность отклонения для этого свойства определяется расширением (см параграф 7.19).

7.20.3.3. Пример использования

В этом примере сервер информирует клиентское приложение о том, что он не поддерживает службу daytime RFC 867.

     module example-deviations {
       yang-version 1.1;
       namespace "urn:example:deviations";
       prefix md;

       import example-base {
         prefix base;
       }

       deviation /base:system/base:daytime {
         deviate not-supported;
       }
       ...
     }

Сервер будет анонсировать оба модуля example-base и example-deviations.

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

     deviation /base:system/base:user/base:type {
       deviate add {
         default "admin"; // новые пользователи по умолчанию являются администраторами
       }
     }

В следующем примере сервер ограничивает число серверов имен до 3.

     deviation /base:system/base:name-server {
       deviate replace {
         max-elements 3;
       }
     }

Если исходное определение имело вид

     container system {
       must "daytime or time";
       ...
     }

сервер может удалить ограничение must

     deviation /base:system {
       deviate delete {
         must "daytime or time";
       }
     }

7.21. Субоператоры общего назначения

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

7.21.1. Оператор config

Оператор config принимает в качестве аргумента строку true или false. Если config имеет аргумент true, определение представляет конфигурацию. Узлы данных, представляющие конфигурацию, являются частью хранилища конфигурации.

Если config имеет аргумент false, определение представляет данные состояния. Узлы данных, представляющих состояние, не входят в хранилище конфигурации.

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

Если верхний узел не включает config, по умолчанию используется значение true.

Если для узла config имеет значение false, ни один из нижележащих узлов не может иметь config со значением true.

7.21.2. Оператор status

Оператор status принимает в качестве аргумента одно из значений current, deprecated или obsolete:

  • current означает, что определение является текущим и действует;

  • deprecated указывает устаревшее определение, которое, тем не менее, разрешено использовать для обеспечения совместимости с имеющимися реализациями;

  • obsolete указывает отмененное определение, которое не следует применять в новых реализациях и/или может быть удалено.

Если оператор status не задан, по умолчанию предполагается значение current.

Определению типа current недопустимо ссылаться на определения типа deprecated или obsolete в том же модуле.

Определению типа deprecated недопустимо ссылаться на определения типа obsolete в том же модуле.

Например, приведенное ниже определение недействительно.

     typedef my-type {
       status deprecated;
       type int32;
     }
     leaf my-leaf {
       status current;
       type my-type; // не пригоден, поскольку my-type отменен
     }

7.21.3. Оператор description

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

7.21.4. Оператор reference

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

Например, typedef для типа данных uri может иметь вид

     typedef uri {
       type string;
       reference
         "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax";
       ...
     }

7.21.5. Оператор when

Оператор when делает условным родительский оператор определения данных. Узел, определенный родительским оператором, будет действительным только при выполнении условия, заданного оператором when. Аргументом оператора является выражение XPath (параграф 6.4), которое служит для формального задания условий. Если выражение XPath дает значение true для конкретного экземпляра, узел, определенный родительским оператором, будет действительным.

Листьям, являющимся ключами списка, недопустимо включать оператор when.

Если лист-ключ определен в группировке, используемой в списке, оператору uses недопустимо включать when.

Дополнительная информация приведена в параграфе 8.3.2.

Выражение XPath оценивается в описанном ниже контексте, дополняющем определение параграфа 6.4.1.

  • Если оператор when является потомком оператора augment, узлом контекста является целевой узел дополнения (augment) в дереве данных, когда целевой узел является узлом данных. В противном случае узлом контекста является узел ближайшего предка целевого узла, который является узлом данных. Если такого узла нет, узлом контекста будет корневой узел. Доступное дерево предварительно изменяется в процессе обработки выражения XPath путем удаления всех экземпляров (если они имеются) узлов, добавленных оператором augment.

  • Если оператор when является потомком оператора uses, choice или case, узлом контекста является ближайший предок узла с оператором when, который является узлом данных. Если такого узла нет, узлом контекста будет корневой узел. Доступное дерево предварительно изменяется в процессе обработки выражения XPath путем удаления всех экземпляров (если они имеются) узлов, добавленных оператором uses, choice или case.

  • Если оператор when является потомком любого оператора определения, доступное дерево предварительно изменяется в процессе обработки выражения XPath путем замены всех экземпляров узла данных, для которого определен оператор when, фиктивным узлом с тем же именем, но без значения и потомков. Если таких экземпляров нет, фиктивный узел создается. Узлом контекста будет этот фиктивный узел.

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

Если выражение XPath ссылается на любой узел, который также имеет связанные операторы when, значения для этих операторов when должны проверяться в первую очередь. Круговые зависимости между выражениями when недопустимы.

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

 


Часть 4




RFC7950 (часть 2)

Часть 1


6. Синтаксис YANG

Синтаксис YANG похож на применяемый в SMIng [RFC3780] и языках программирования типа C и C++. Синтаксис в стиле C был осознанно выбран для удобочитаемости, поскольку YANG считает более важным фактором время и усилия читателей моделей YANG, нежели разработчиков модулей и инструментальных средств. Этот раздел посвящен описанию синтаксиса YANG.

Допустимыми символами для модулей YANG являются символы Unicode и ISO/IEC 10646 [ISO.10646], включая символы табуляции, возврата каретки и перевода строки, но исключая другие управляющие символы C0, суррогатные блоки и коды, не являющиеся символами. Синтаксис символов формально определен правилом yang-char раздела 14.

Модули и субмодули YANG сохраняются в файлах с использованием кодировки UTF-8 [RFC3629].

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

6.1. Лексический разбор

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

6.1.1. Комментарии

Для комментариев применяется стиль C++. Одиночная строка комментария начинается символами // и заканчивается как все строки. Комментарий блока строк начинается с последовательности /* и завершается последовательностью */.

Отметим, что внутри строк, заключенных в кавычки (параграф 6.1.3), указанные последовательности символов никогда не интерпретируются как начало и завершение комментария.

6.1.2. Маркеры

Маркером (token) в YANG считается ключевое слово, строка, точка с запятой (;) и фигурные скобки ({ и }). Строка может быть заключена в кавычки. Ключевое слово — это одно из ключевых слов YANG, определенных в этом документе, или идентификатор префикса, за которым следует двоеточие (:) и ключевое слово расширения языка. Регистр символов в ключевых словах принимается во внимание. Формальное определение идентификаторов дано в параграфе 6.2.

6.1.3. Кавычки

Строкой без кавычек считается любая последовательность символов без пробелов, табуляторов, перевода строки или возврата каретки, одинарных или двойных кавычек, точки с запятой (;), фигурных скобок ({ или }) или комментариев (//, /*, */).

Отметим, что любое из ключевых слов может включаться в строку без кавычек.

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

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

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

Строка в одинарных кавычках (‘ ‘) сохраняет значение каждого символа. Символ одинарных кавычек не может использоваться в таких строках даже вместе с символом \.

Внутри строк в двойных кавычках (» «) символ \ имеет специальное значение, которое зависит от следующего непосредственно за ним символа:

\n новая строка;

\t символ табуляции;

\» символ двойной кавычки;

\\ одиночный символ \.

Использование других символов после \ недопустимо.

Если после строки в кавычках следует символ сложения (+) и другая строка в кавычках, эти строки объединяются в одну (конкатенация). Между строкой в кавычках и знаком + могут включаться пробелы, разрыв строки и комментарии.

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

6.1.3.1. Примеры кавычек

Ниже приведен набор эквивалентных строк.

     hello
     "hello"
     'hello'
     "hel" + "lo"
     'hel' + "lo"

Далее показаны несколько строк специального назначения.

     "\""  - строка, содержащая двойную кавычку
     '"'   - строка, содержащая двойную кавычку
     "\n"  - строка, содержащая символы новой строки
     '\n'  - строка, содержащая символ \, за которым следует символ n

Ниже приведены два примера недопустимых строк.

     ''''  - строка в одинарных кавычках не может включать одинарные кавычки
     """   - символ двойных кавычек должен использовать префикс \

Две приведенных ниже строки эквивалентны.

         "first line
            second line"

     "first line\n" + "  second line"

6.2. Идентификаторы

Идентификаторы служат для указания различных элементов YANG по именам. Каждый идентификатор начинается с буквы кода ASCII (в верхнем или нижнем регистре) или символа подчеркивания, а далее могут следовать дополнительные буквы, цифры, символы подчеркивания, дефиса и точки в кодировке ASCII. Реализации должны поддерживать идентификаторы размером до 64 символов и могут поддерживать более длинные идентификаторы. Регистр символов в идентификаторах принимается во внимание. Синтаксис идентификаторов формально определен правилом identifier в разделе 14. Идентификаторы могут задаваться в форме строк в кавычках и без кавычек.

6.2.1. Идентификаторы и пространства имен

Каждый идентификатор действителен в пространстве имен, которое зависит от типа определяемого элемента YANG. Все идентификаторы в одном пространстве имен должны быть уникальными.

  • Все имена модулей и субмодулей используют общее глобальное пространство имен модулей.

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

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

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

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

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

  • Все узлы типа leaf, leaf-list, list, container, choice, rpc, action, notification, anydata и anyxml, определенные (напрямую или с помощью оператора uses) в родительском узле или на верхнем уровне модуля и его субмодулей, используют общее пространство имен. Это пространство охватывает родительский узел или модуль, если родительский узел не относится к типу case. В последнем случае пространство имен охватывает ближайшего предка, не являющегося узлом типа case или choice.

  • Все узлы case внутри choice используют общее пространство имен идентификаторов. Это пространство охватывает родительский узел choice.

В YANG разрешены ссылки вперед (упреждающие).

6.3. Операторы

Модуль YANG содержит последовательность операторов. Каждый оператор начинается с ключевого слова, за которым могут следовать аргументы, а затем символ ; или блок субоператоров, заключенный в фигурные скобки ({ })

     statement = keyword [argument] (";" / "{" *statement "}")

Аргумент является строкой (параграф 6.1.2).

6.3.1. Расширения языка

Модуль может задавать расширения языка YANG с помощью ключевого слова extension (параграф 7.19). Расширения могут импортироваться другими модулями с помощью оператора import (параграф 7.1.5). При использовании импортированного расширения ключевое слово расширения должно указываться с префиксом, который применялся для импорта модуля расширения. Если расширение применяется в определившем его модуле, ключевое слово расширения должно указываться с префиксом этого модуля.

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

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

6.4. Вычисление XPath

Язык YANG опирается на язык путей XML (XPath1) 1.0 [XPATH] в качестве нотации для задания связей и зависимостей между узлами. Реализации не обязаны включать интерпретатор XPath, но они должны гарантировать выполнение требований, представленных в модели данных. Способ исполнения этого зависит от реализации. Выражения XPath должны быть корректны синтаксически, а все используемые префиксы должны присутствовать в контексте XPath (параграф 6.4.1). Реализация может сделать это вручную вместо использования выражения XPath напрямую.

Модель данных, применяемая в выражении XPath, совпадает с используемой в XPath 1.0 [XPATH] с тем же расширением для потомка корневого узла, что применяется в XSLT 1.0 (параграф 3.1 в [XSLT]). Это означает, в частности, что корневой узел может иметь любое число элементов в качестве своих потомков.

Для дерева данных не существует порядка документов. Реализация должна выбрать тот или иной порядок, но этот выбор определяется самой реализацией. Это означает, что выражениям XPath в модулях YANG не следует предполагать конкретный порядок документов.

Числовые значения в XPath 1.0 являются действительными числами IEEE 754 [IEEE754-2008] с двойной точностью (параграф 3.5 в [XPATH]). Это значит, что некоторые значения типов int64, uint64 и decimal64 (параграфы 9.2 и 9.3) не могут быть точно представлены в выражениях XPath. Поэтому следует проявлять осторожность при использовании 64-битовых числовых значений в выражениях XPath. В частности, проверки, использующие равенство, могут давать неожиданные результаты.

Для примера рассмотрим выражение

     leaf lxiv {
       type decimal64 {
         fraction-digits 18;
       }
       must ". <= 10";
     }

Экземпляр листа lxiv, имеющий значение 10,0000000000000001, пройдет такую проверку.

6.4.1. Контекст XPath

Все выражения YANG XPath используют приведенное ниже определение контекста XPath.

  • Набор деклараций пространства имен представляет собой набор всех пар префиксов операторов import и пространств имен в модуле, где задано выражение XPath, и всех префиксов операторов prefix для пространства имен URI оператора.

  • Имена без префикса пространства имен относятся к тому же пространству, что идентификатор текущего узла. Внутри группировки это пространство зависит от того, где группировка используется (параграф 7.13). Внутри typedef это пространство зависит от того, где typedef упоминается. Если typedef определен и упоминается в группировке, пространство зависит от того, где группировка используется (параграф 7.13).

  • Библиотека функций — это основная библиотека, определенная в [XPATH], и функции, заданные в разделе 10.

  • Набор привязок переменных пуст.

Механизм обработки имен без префиксов приспособлен из XPath 2.0 [XPATH2.0] и помогает упростить выражения XPath в YANG. Неоднозначности возникать не может, поскольку идентификаторы узлов YANG всегда являются квалифицированными именами с непустым URI пространства имен.

Доступное дерево зависит от того, где определен оператор с выражением XPath.

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

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

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

  • Если выражение XPath определено в субоператоре для оператора input в rpc или action, доступным деревом будет RPC или экземпляр операции, все данные на сервере и рабочее хранилище конфигурации. Корневой узел имеет в качестве своих потомков все узлы данных верхнего уровня во всех модулях. Дополнительно, для RPC корневой узел также имеет узел, представляющий операцию RPC, которая будет определена, как потомок. Узел, представляющий операцию, которая будет определена, имеет в качестве своих потомков входные параметры операции.

  • Если выражение XPath определено в субоператоре для output в rpc или action, доступным деревом будет RPC или экземпляр операции, все данные на сервере и рабочее хранилище конфигурации. Корневой узел имеет в качестве своих потомков все узлы данных верхнего уровня во всех модулях. Дополнительно, для RPC корневой узел также имеет узел, представляющий операцию RPC, которая будет определена, как потомок. Узел, представляющий операцию, которая будет определена, имеет в качестве своего потомка входные параметры операции.

В доступном дереве существуют все листья (leaf) и листья-списки (leaf-list) с принятыми по умолчанию значениями (параграфы 7.6.1 и 7.7.2).

Если узел, который существует в доступном дереве, имеет контейнер отсутствия (non-presence container) в качестве потомка, контейнер отсутствия существует также в доступном дереве.

Узел контекста меняется в зависимости от выражения YANG XPath и указывается там, где определен оператор YANG с выражением XPath.

6.4.1.1. Примеры

Рассмотрим показанный ниже модуль

     module example-a {
       yang-version 1.1;
       namespace urn:example:a;
       prefix a;
       container a {
         list b {
           key id;
           leaf id {
             type string;
           }
           notification down {
             leaf reason {
               type string;
             }
           }
           action reset {
             input {
               leaf delay {
                 type uint32;
               }
             }
             output {
               leaf result {
                 type string;
               }
             }
           }
         }
       }
       notification failure {
         leaf b-ref {
           type leafref {
             path "/a/b/id";
           }
         }
       }
     }

И дерево данных, заданное в XML.

     <a xmlns="urn:example:a">
       <b>
         <id>1</id>
       </b>
       <b>
         <id>2</id>
       </b>
     </a>

Доступным деревом для уведомления down на /a/b[id=»2″] будет

     <a xmlns="urn:example:a">
       <b>
         <id>1</id>
       </b>
       <b>
         <id>2</id>
         <down>
           <reason>error</reason>
         </down>
       </b>
     </a>
     // здесь возможны другие узлы верхнего уровня

Доступным деревом для операции вызова reset на /a/b[id=»1″] с параметром when, имеющим значение 10, будет

     <a xmlns="urn:example:a">
       <b>
         <id>1</id>
         <reset>
           <delay>10</delay>
         </reset>
       </b>
       <b>
         <id>2</id>
       </b>
     </a>
     // здесь возможны другие узлы верхнего уровня

Доступным деревом для вывода этой операции будет

     <a xmlns="urn:example:a">
       <b>
         <id>1</id>
         <reset>
           <result>ok</result>
         </reset>
       </b>
       <b>
         <id>2</id>
       </b>
     </a>
     // здесь возможны другие узлы верхнего уровня

Доступным деревом для уведомления failure может быть

     <a xmlns="urn:example:a">
       <b>
         <id>1</id>
       </b>
       <b>
         <id>2</id>
       </b>
     </a>
     <failure>
       <b-ref>2</b-ref>
     </failure>
     // здесь возможны другие узлы верхнего уровня

6.5. Идентификатор узла схемы

Идентификатор узла схемы представляет собой строку, указывающую узел в дереве схемы. Он имеет две формы — абсолютную и наследуемую (descendant), которые определены правилами absolute-schema-nodeid и descendant-schema-nodeid в разделе 14. Идентификатор узла схемы состоит из пути идентификаторов, разделенных символами дробной черты (/). В абсолютном идентификаторе первым символом является /, а за ним следует узел схемы верхнего уровня в локальном или импортированном модуле.

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

Например, для указания дочернего узла b узла верхнего уровня a может использоваться строка /a/b.

7. Операторы YANG

В этом разделе описаны все операторы YANG.

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

     description "Some text." {
       ex:documentation-flag 5;
     }

7.1. Оператор module

Оператор module определяет имя модуля и собирает воедино все относящиеся к модулю операторы. Аргументом оператора module является имя модуля, за которым следует блок субоператоров с дополнительной информацией о модуле. Имя модуля служит его идентификатором (параграф 6.2).

Имена модулей, публикуемые в RFC [RFC4844], должны выделяться IANA (раздел 14 в [RFC6020]).

Частные (фирменные) имена модулей назначаются владеющей модулем организацией без централизованной регистрации. Рекомендации по выбору имен для модулей приведены в параграфе 5.1.

Модуль обычно имеет показанную ниже структуру.

     module <module-name> {

       // данные заголовка
       <оператор yang-version>
       <оператор namespace>
       <оператор prefix>

       // данные о привязках
       <операторы import>
       <операторы include>

       // метаданные
       <оператор organization>
       <оператор contact>
       <оператор description>
       <оператор reference>
       // история выпусков
       <операторы revision>

       // определения модуля
       <другие операторы>
     }

7.1.1. Субоператоры для module

Субоператор

Параграф

Число элементов

anydata

7.10

0..n

anyxml

7.11

0..n

augment

7.17

0..n

choice

7.9

0..n

contact

7.1.8

0..1

container

7.5

0..n

description

7.21.3

0..1

deviation

7.20.3

0..n

extension

7.19

0..n

feature

7.20.1

0..n

grouping

7.12

0..n

identity

7.18

0..n

import

7.1.5

0..n

include

7.1.6

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

namespace

7.1.3

1

notification

7.16

0..n

organization

7.1.7

0..1

prefix

7.1.4

1

reference

7.21.4

0..1

revision

7.1.9

0..n

rpc

7.14

0..n

typedef

7.3

0..n

uses

7.13

0..n

yang-version

7.1.2

1

7.1.2. Оператор yang-version

Оператор yang-version указывает версию языка YANG, использованную при разработке модуля. Аргументом оператора является строка. Для модулей YANG, определенных на основе данной спецификации, она должна иметь значение 1.1.

Модуль или субмодуль, не включающий оператора yang-version или содержащий оператор с аргументом 1, разработан с использованием языка YANG версии 1, определенной в [RFC6020].

Обработка операторов yang-version со значением версии, отличающимся от 1.1 (определена здесь), выходит за рамки данной спецификации. Любой документ, определяющий более высокий номер версии, должен описать совместимость этой версии с более ранними.

Совместимость YANG версий 1 и 1.1 рассматривается в разделе 12.

7.1.3. Оператор namespace

Оператор namespace указывает пространство имен XML, в котором все определенные модулем идентификаторы представляются в XML (за исключением идентификаторов узлов данных, а также узлов action и notification внутри группировок — см. параграф 7.13). Аргументом оператора namespace служит идентификатор URI пространства имен.

См. также параграф 5.3. Пространства имен XML.

7.1.4. Оператор prefix

Оператор prefix служит для определения префикса, связанного с модулем и его пространством имен. Аргументом оператора prefix является строка префикса, которая применяется для доступа к модулю. Строка префикса может использоваться для ссылок на содержащиеся в модуле определения (например, if:ifName). Префикс является идентификатором (параграф 6.2).

При использовании в операторе module субоператор prefix определяет префикс, предлагаемый для использования при импорте этого модуля.

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

При использовании в операторе import субоператор prefix указывает префикс, используемый для доступа к определениям в импортируемом модуле. При использовании ссылок на операторы из импортируемого модуля за строкой префикса этого модуля следует двоеточие (:) и идентификатор (например if:ifIndex). Для удобочитаемости модулей YANG определенный модулем префикс следует использовать при импорте модуля, если это не вызывает конфликтов. При возникновении конфликта когда импортируются два разных модуля, имеющих одинаковые префиксы, хотя бы один из них должен импортироваться с другим префиксом.

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

7.1.5. Оператор import

Оператор import делает доступными операторы из другого модуля или субмодуля. Аргументом оператора служит имя импортируемого модуля, за которым следует блок субоператоров с данными импорта. Импортирующий модуль может:

  • использовать любые группировки (grouping) и определения типов (typedef), заданные на верхнем уровне импортированного модуля и его субмодулей;

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

  • использовать любой узел из дерева схемы импортированного модуля в операторах must, path и when или в качестве целевого узла в операторах augment и deviation.

Обязательный субоператор prefix задает префикс для импортируемого модуля в области действия импортирующего модуля и его субмодулей. Для импорта разных модулей можно использовать множество операторов import.

При наличии необязательного субоператора revision-date любые typedef, grouping, extension, feature и identity, указанные в определениях локального модуля, берутся из заданного выпуска импортируемого модуля. Если указанного выпуска импортируемого модуля не существует, возникает ошибка. При отсутствии субоператора revision-date выпуск импортируемого модуля будет неизвестен.

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

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

prefix

7.1.4

1

reference

7.21.4

0..1

revision-date

7.1.5.1

0..1

7.1.5.1. Оператор revision-date для оператора import

Субоператор revision-date используется в операторе import для указания выпуска импортируемого модуля.

7.1.6. Оператор include

Оператор include делает содержимое субмодуля доступным в родительском модуле. Аргументом оператора служит имя включаемого модуля. В модули можно включать лишь относящиеся к ним субмодули, указанные оператором belongs-to (параграф 7.2.2).

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

Для совместимости с YANG версии 1 в субмодули можно включать другие субмодули, относящиеся к тому же модулю, но это не требуется делать в YANG версии 1.1 (параграф 5.1).

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

Недопустимо включение в модуль множества выпусков одного субмодуля.

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

reference

7.21.4

0..1

revision-date

7.1.5.1

0..1

7.1.7. Оператор organization

Оператор organization указывает сторону, ответственную за этот модуль. Аргументом оператора является строка с текстовым описанием организации, под эгидой которой был разработан модуль.

7.1.8. Оператор contact

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

7.1.9. Оператор revision

Оператор revision указывает историю изменения модуля, включая его начальный выпуск. Последовательность операторов revision детализирует изменения в определении модуля. Аргументом оператора служит строка даты в формате YYYY-MM-DD (год-месяц-число), за которой следует блок субоператоров с информацией о выпуске. Модулю следует включать по крайней мере один оператор revision. Для каждого опубликованного выпуска следует добавлять новый оператор в начале последовательности, чтобы все выпуски перечислялись в обратном хронологическом порядке.

7.1.9.1. Субоператоры для revision

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

reference

7.21.4

0..1

7.1.10. Пример использования

Приведенный ниже пример основан на [RFC6991].

     module example-system {
       yang-version 1.1;
       namespace "urn:example:system";
       prefix "sys";

       import ietf-yang-types {
         prefix "yang";
         reference "RFC 6991: Common YANG Data Types";
       }

       include example-types;

       organization "Example Inc.";
       contact
         "Joe L. User

          Example Inc.
          42 Anywhere Drive
          Nowhere, CA 95134
          USA

          Phone: +1 800 555 0100
          Email: joe@example.com";

       description
         "The module for entities implementing the Example system.";

       revision 2007-06-09 {
         description "Initial revision.";
       }

       // далее следуют определения ...
     }

7.2. Оператор submodule

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

Оператор submodule задает имя субмодуля и группирует все операторы, относящиеся к этому субмодулю. Аргументом оператора submodule является имя субмодуля, за которым следует блок операторов с информацией о субмодуле. Имя субмодуля является идентификатором (параграф 6.2).

Имена субмодулей, публикуемые в RFC [RFC4844], должны выделяться IANA (раздел 14 в [RFC6020]).

Частные (фирменные) имена субмодулей назначаются владеющими модулями организациями без централизованной регистрации. Рекомендации по выбору имен для субмодулей приведены в параграфе 5.1.

Субмодуль обычно имеет показанную ниже структуру.

     submodule <module-name> {

       <оператор yang-version>

       // идентификация модуля
       <оператор belongs-to>

       // операторы привязок
       <операторы import>

       // метаданные
       <оператор organization>
       <оператор contact>
       <оператор description>
       <оператор reference>

       // история выпусков
       <операторы revision>

       // определения субмодуля
       <другие операторы>
     }

7.2.1. Субоператоры для submodule

Субоператор

Параграф

Число элементов

anydata

7.10

0..n

anyxml

7.11

0..n

augment

7.17

0..n

belongs-to

7.2.2

1

choice

7.9

0..n

contact

7.1.8

0..1

container

7.5

0..n

description

7.21.3

0..1

deviation

7.20.3

0..n

extension

7.19

0..n

feature

7.20.1

0..n

grouping

7.12

0..n

identity

7.18

0..n

import

7.1.5

0..n

include

7.1.6

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

notification

7.16

0..n

organization

7.1.7

0..1

reference

7.21.4

0..1

revision

7.1.9

0..n

rpc

7.14

0..n

typedef

7.3

0..n

uses

7.13

0..n

yang-version

7.1.2

1

7.2.2. Оператор belongs-to

Оператор belongs-to указывает модуль, к которому субмодуль относится. Аргументом оператора является имя модуля.

Субмодуль должен включаться только в модуль, к которому он относится или в его субмодули.

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

Субоператор

Параграф

Число элементов

prefix

7.1.4

1

7.2.3. Пример использования

     submodule example-types {
       yang-version 1.1;
       belongs-to "example-system" {
         prefix "sys";
       }

       import ietf-yang-types {
         prefix "yang";
       }

       organization "Example Inc.";
       contact
         "Joe L. User

          Example Inc.
          42 Anywhere Drive
          Nowhere, CA 95134
          USA

          Phone: +1 800 555 0100
          Email: joe@example.com";

       description
         "This submodule defines common Example types.";

       revision "2007-06-09" {
         description "Initial revision.";
       }

       // далее следуют определения ...
     }

7.3. Оператор typedef

Оператор typedef определяет новый тип, который может применяться локально в модуле или субмодуле, а также в других модулях, импортирующих данный, в соответствии с правилами, описанными в параграфе 5.5. Новый тип называется производным (derived), а тип, на основе которого он создан, — базовым. Все производные типы можно отследить по цепочке до встроенного типа YANG.

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

В качестве имени производного типа недопустимо использовать какое-либо из имен встроенных типов YANG. Если typedef определяется на верхнем уровне модуля или субмодуля YANG, имя определяемого типа должно быть уникальным в данном модуле.

7.3.1. Субоператоры для typedef

Субоператор

Параграф

Число элементов

default

7.3.4

0..1

description

7.21.3

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

type

7.3.2

1

units

7.3.3

0..1

7.3.2. Оператор type

Обязательный оператор type определяет базовый тип, на основе которого создается производный (параграф 7.4).

7.3.3. Оператор units

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

7.3.4. Оператор default

Оператор default принимает аргумент в виде строки с принятым по умолчанию значением для нового типа.

Заданное оператором default значение должно быть пригодным для типа, указанного в операторе type.

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

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

7.3.5. Пример использования

     typedef listen-ipv4-address {
       type inet:ipv4-address;
       default "0.0.0.0";
     }

7.4. Оператор type

Оператор type принимает один аргумент в форме строки с именем встроенного типа YANG (раздел 9) или производного типа (параграф 7.3), за которым может следовать блок субоператоров, используемых для дополнительных ограничений типа.

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

7.4.1. Субоператоры для type

Субоператор

Параграф

Число элементов

base

7.18.2

0..n

bit

9.7.4

0..n

enum

9.6.4

0..n

fraction-digits

9.3.4

0..1

length

9.4.4

0..1

path

9.9.2

0..1

pattern

9.4.5

0..n

range

9.2.4

0..1

require-instance

9.9.3

0..1

type

7.4

0..n

7.5. Оператор container

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

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

7.5.1. Контейнеры

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

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

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

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

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

YANG называет контейнеры этого типа контейнерами присутствия (presence container) и они обозначаются оператором presence, который принимает в качестве аргумента текстовую строку, указывающую смысл присутствия узла.

Например, контейнер ssh может включать возможность входа на сервер по протоколу SSH3, но может также включать любые связанные с SSH конфигурационные «кнопки», такие как скорость соединения или число попыток.

Оператор presence (параграф 7.5.5) служит для представления смысла наличия контейнера в дереве данных.

7.5.2. Субоператоры для container

Субоператор

Параграф

Число элементов

action

7.15

0..n

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

config

7.21.1

0..1

container

7.5

0..n

description

7.21.3

0..1

grouping

7.12

0..n

if-feature

7.20.2

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

must

7.5.3

0..n

notification

7.16

0..n

presence

7.5.5

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

typedef

7.3

0..n

uses

7.13

0..n

when

7.21.5

0..1

7.5.3. Оператор must

Необязательный оператор must принимает один аргумент в виде строки с выражением XPath (параграф 6.4). Он используется для формального выражения ограничений на пригодные данные. Ограничение применяется в соответствии с правилами, указанными в разделе 8.

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

Чтобы данные считались пригодными, проверка всех таких ограничений должна давать значение true.

Выражения XPath концептуально оцениваются в описанном ниже контексте, дополняющем определение параграфа 6.4.1.

  • Если оператор must является субоператором notification, узел контекста представляет уведомление в доступном дереве.

  • Если оператор must является субоператором input, узел контекста представляет операцию в доступном дереве.

  • Если оператор must является субоператором output, узел контекста представляет операцию в доступном дереве.

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

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

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

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

7.5.4. Субоператоры для must

Субоператор

Параграф

Число элементов

description

7.21.3

0..1

error-app-tag

7.5.4.2

0..1

error-message

7.5.4.1

0..1

reference

7.21.4

0..1

7.5.4.1. Оператор error-message

Необязательный оператор error-message принимает в качестве аргумента строку. Если оценка ограничений дает значение false, строка передается как <error-message> в сообщении NETCONF <rpc-error>.

7.5.4.2. Оператор error-app-tag

Необязательный оператор error-app-tag принимает в качестве аргумента строку. Если оценка ограничений дает значение false, строка передается как <error-app-tag> в сообщении NETCONF <rpc-error>.

7.5.4.3. Пример использования must и error-message
     container interface {
       leaf ifType {
         type enumeration {
           enum ethernet;
           enum atm;
         }
       }
       leaf ifMTU {
         type uint32;
       }
       must 'ifType != "ethernet" or ifMTU = 1500' {
         error-message "An Ethernet MTU must be 1500";
       }
       must 'ifType != "atm" or'
          + ' (ifMTU <= 17966 and ifMTU >= 64)' {
         error-message "An ATM MTU must be 64 .. 17966";
       }
     }

7.5.5. Оператор presence

Оператор presence указывает смысл присутствия оператора container в дереве данных. Он принимает в качестве аргумента строку с текстовым описанием смысла присутствия узла.

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

Дополнительная информация приведена в параграфе 7.5.1.

7.5.6. Операторы дочерних узлов контейнера

Внутри контейнера операторы container, leaf, list, leaf-list, uses, choice, anydata и anyxmls могут применяться для определения дочерних узлов контейнера.

7.5.7. Правила представления XML

Узел container представляется в виде элемента XML. Локальное имя элемента служит идентификатором контейнера, а его пространство имен совпадает с пространством имен XML для модуля (параграф 7.1.3).

Дочерние узлы контейнера представляются как субэлементы элемента container. Если контейнер определяет входные или выходные параметры RPC или операции (action), эти субэлементы представляются в том же порядке, в котором они определены в операторе container. В остальных случаях субэлементы могут представляться в любом порядке.

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

Если контейнер отсутствия не имеет дочерних узлов, его можно не включать с представление XML.

7.5.8. Операции NETCONF <edit-config>

Контейнеры могут создаваться, удаляться, заменяться и изменяться с помощью операции <edit-config> с атрибутом operation (параграф 7.2 в [RFC6241]) в элементе XML этого контейнера.

Если узел-конейнер не имеет оператора presence и последний дочерний узел удален, сервер NETCONF может удалить этот контейнер.

При обработке сервером NETCONF запроса <edit-config> выполняются следующие правила:

  • если задана операция merge или replace, узел создается при его отсутствии;

  • если задана операция create, узел создается при его отсутствии, а в случае наличия узла возвращается ошибка data-exists;

  • если задана операция delete, узел удаляется при его наличии, а в случае отсутствия узла возвращается ошибка data-missing.

7.5.9. Пример использования

Для приведенного ниже определения контейнера

     container system {
       description
         "Contains various system parameters.";
       container services {
         description
           "Configure externally available services.";
         container "ssh" {
           presence "Enables SSH";
           description
             "SSH service-specific configuration.";
           // more leafs, containers, and stuff here...
         }
       }
     }

соответствующий экземпляр XML будет иметь вид

     <system>
       <services>
         <ssh/>
       </services>
     </system>

Присутствие элемента <ssh> разрешает использовать SSH.

Удаление контейнера с помощью <edit-config> имеет вид

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config">
             <services>
               <ssh nc:operation="delete"/>
             </services>
           </system>
         </config>
       </edit-config>
     </rpc>

7.6. Оператор leaf

Оператор leaf служит для определения листа (leaf node) в дереве схемы. Он принимает один аргумент, являющийся идентификатором, за которым следует блок субоператоров, детализирующих информацию листа.

Узел leaf имеет значение, но не имеет дочерних узлов в дереве данных. Концептуально значение листа в дереве данных всегда имеет каноническую форму (параграф 9.1).

Узлы типа leaf являются необязательными и могут присутствовать во множестве экземпляров.

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

7.6.1. Значение листа по умолчанию

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

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

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

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

В этих случаях говорят, что используется принятое по умолчанию значение.

Отметим, что принятое по умолчанию значение не применяется, если лист или любой из его предков имеет условие when или выражение if-feature, дающее в результате значение false.

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

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

7.6.2. Субоператоры для leaf

Субоператор

Параграф

Число элементов

config

7.21.1

0..1

default

7.6.4

0..1

description

7.21.3

0..1

if-feature

7.20.2

0..n

mandatory

7.6.5

0..1

must

7.5.3

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

type

7.6.3

1

units

7.3.3

0..1

when

7.21.5

0..1

7.6.3. Оператор type

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

7.6.4. Оператор default

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

Значение оператора default должно соответствовать типу листа, заданному оператором type.

Оператор default недопустимо включать для узлов, где в качестве значения mandatory установлено true.

Определение принятого по умолчанию значения недопустимо помечать оператором if-feature. Например, ниже представлено неприемлемое определение.

     leaf color {
       type enumeration {
         enum blue { if-feature blue; }
         ...
       }
       default blue; // недопустимо, поскольку значение enum является условным
     }

7.6.5. Оператор mandatory

Необязательный оператор mandatory принимает в качестве аргумента строку true или false и задает ограничения для пригодных данных. Если значение оператора не задано, по умолчанию используется false.

Если для mandatory установлено значение true, поведение ограничений зависит от типа ближайшего предка leaf в дереве схемы, который не является контейнером отсутствия (параграф 7.5.1):

  • если такого предка нет в дереве схемы, leaf должен существовать;

  • в противном случае, если предок имеет тип case, leaf должен существовать при наличии в дереве данных хотя бы одного узла из case;

  • в остальных случаях leaf должен существовать, если узел-предок существует в дереве данных.

Эти ограничения применяются в соответствии с правилами раздела 8.

7.6.6. Правила представления XML

Узел leaf представляется в виде элемента XML. Локальное имя элемента является идентификатором листа, а его пространством имен является пространство имен XML для модуля (параграф 7.1.3).

Значение узла leaf представляется в XML в соответствии с типом и передается элементу в виде символов.

Пример представления дан в параграфе 7.6.8.

7.6.7. Операции NETCONF <edit-config>

При обработке сервером NETCONF запроса <edit-config> для узла leaf выполняются следующие правила:

  • если задана операция merge или replace, узел создается при его отсутствии и для него устанавливается значение, найденное в данных XML RPC;

  • если задана операция create, узел создается при его отсутствии, а в случае наличия узла возвращается ошибка data-exists;

  • если задана операция delete, узел удаляется при его наличии, а в случае отсутствия узла возвращается ошибка data-missing.

7.6.8. Пример использования

Ниже приведен оператор leaf, помещенный в контейнер ssh (параграф 7.5.9):

     leaf port {
       type inet:port-number;
       default 22;
       description
         "The port to which the SSH server listens.";
     }

Пример соответствующего экземпляра XML будет иметь вид

     <port>2022</port>

Для установки значения leaf с помощью <edit-config> служит

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config">
             <services>
               <ssh>
                 <port>2022</port>
               </ssh>
             </services>
           </system>
         </config>
       </edit-config>
     </rpc>

7.7. Оператор leaf-list

Оператор leaf служит для определения простой скалярной переменной того или иного типа, а оператор leaf-list — для определения массива определенного типа. Оператор leaf-list принимает в качестве параметра идентификатор, за которым следует блок субоператоров с детальной информацией о leaf-list.

В данных конфигурации все значения в leaf-list должны быть уникальными.

Определения используемых по умолчанию значений недопустимо помечать операторами if-feature.

Концептуально значения в дереве данных должны иметь каноническую форму (параграф 9.1).

7.7.1. Упорядочение

YANG поддерживает два стиля упорядочения элементов в узлах list и leaf-list. Во многих списках порядок элементов не влияет на реализацию конфигурации списка и сервер может сортировать элементы по своему усмотрению. Строка description для списка может предложить порядок для разработчиков сервера. В языке YANG такой стиль называется системным упорядочением (system ordered), а списки помечаются оператором ordered-by system.

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

В другом стиле списков порядок имеет значение для реализации конфигурации списка и пользователь отвечает за упорядочение элементов, а сервер этот порядок поддерживает. В YANG такие списки называются упорядоченными пользователем (user ordered) и указываются оператором ordered-by user.

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

YANG обеспечивает в операции NETCONF <edit-config> многочисленные возможности, позволяющие контролировать порядок элементов в списках упорядочиваемых пользователем. Элементы списка могут вставляться или перемещаться, помещаться в начало или конец списка, а также в определенную позицию перед указанным элементом или после него.

Оператор ordered-by описан в параграфе 7.7.7.

7.7.2. Принятые по умолчанию значения leaf-list

Значения leaf-list, принятые по умолчанию, сервер использует при отсутствии узла leaf-list в дереве данных. Применение этих значений зависит от ближайшего предка leaf-list в дереве схемы, который не является контейнером отсутствия (параграф 7.5.1):

  • если в дереве схемы нет таких предков, должны использоваться принятые по умолчанию значения;

  • в противном случае, если предок является узлом case, принятые по умолчанию значения должны применяться, когда любой узел из case присутствует в дереве данных или узел case является принятым по умолчанию вариантом выбора (choice), а других узлов из case в дереве данных нет;

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

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

Отметим, что при наличии у leaf-list или любого из его предков условия when или выражения if-feature со значением false принятые по умолчанию значения не используются.

Когда принятые по умолчанию значение используются, сервер должен вести себя так, будто leaf-list присутствует в дереве данных и имеет значения, совпадающие с принятыми по умолчанию.

Если leaf-list имеет один или множество операторов default, принятыми по умолчанию значениями для leaf-list являются значения операторов default, а если порядок leaf-list задан пользователем, эти значения применяются в порядке операторов default. В остальных случаях, если тип leaf-list имеет принятое по умолчанию значение, а leaf-list не имеет операторов min-element со значением не меньше 1, принятым по умолчанию значением leaf-list будет принятое по умолчанию значение одного из экземпляров его типа. Во всех остальных случаях leaf-list не имеет принятого по умолчанию значения.

7.7.3. Субоператоры для leaf-list

Субоператор

Параграф

Число элементов

config

7.21.1

0..1

default

7.7.4

0..n

description

7.21.3

0..1

if-feature

7.20.2

0..n

max-elements

7.7.6

0..1

min-elements

7.7.5

0..1

must

7.5.3

0..n

ordered-by

7.7.7

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

type

7.4

1

units

7.3.3

0..1

when

7.21.5

0..1

7.7.4. Субоператор default для leaf-list

Необязательный оператор default принимает один параметр с принятым по умолчанию значением для leaf-list.

Значение оператора default должно быть пригодно для типа, заданного оператрором type для leaf-list.

Оператор default недопустимо включать для узлов, в которых min-elements имеет значение не меньше 1.

7.7.5. Оператор min-elements

Необязательный оператор min-elements принимает в качестве аргумента неотрицательное целое число, которое задает ограничения для количества элементов списка. Действительный список leaf-list или list должен иметь по меньшей мере min-elements элементов.

Если оператор min-elements не присутствует, по умолчанию принимается значение 0.

Поведение ограничений зависит от типа ближайшего предка leaf-list или list в дереве схемы, который не является контейнером отсутствия (параграф 7.5.1):

  • если такого предка нет в дереве схемы, ограничения применяются;

  • в противном случае, если предок является узлом case, ограничения применяются при наличии любого другого узла от этого case;

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

Далее ограничения применяются в соответствии с правилами раздела 8.

7.7.6. Оператор max-elements

Необязательный оператор max-elements принимает в качестве аргумента положительное целое число или строку unbounded (не ограничено), которые ограничивают число пригодных элементов списка. Действительный список leaf-list или list всегда имеет не более max-elements элементов.

При отсутствии оператора max-elements по умолчанию используется значение unbounded.

Ограничения оператора max-elements применяются в соответствии с правилами раздела 8.

7.7.7. Оператор ordered-by

Оператор ordered-by определяет источник упорядочения элементов списка — пользователь или система. Аргументом оператора может быть строка system или user. При отсутствии оператора применяется system.

Этот оператор игнорируется, если список представляет данные состояния, выходные параметры RPC или содержимое уведомления.

Дополнительная информация приведена в параграфе 7.7.1.

7.7.7.1. Системное упорядочение

Элементы списка упорядочиваются системой (ordered-by system). Строка оператора description для списка может предлагать порядок сортировки для разработчиков серверных реализаций. Если этого нет, приложение выбирает порядок сортировки по своему усмотрению. Реализациям следует применять для одинаковых данных один и тот же порядок, независимо от места расположения данных. Использование определенного порядка позволяет выполнять сравнение с помощью простых средств, таких как diff.

Этот порядок применяется по умолчанию.

7.7.7.2. Упорядочение пользователем

Элементы списка упорядочиваются пользователем (ordered-by user). В NETCONF управление порядком осуществляется с помощью специальных атрибутов XML в запросе <edit-config> (параграф 7.7.9).

7.7.8. Правила представления XML

Узел leaf-list представляется последовательностью элементов XML. Локальное имя каждого элемента служит идентификатором leaf-list, а в качестве пространства имен используется пространство имен XML для модуля (параграф 7.1.3).

Значение каждого элемента leaf-list представляется в XML в соответствии с типом и передается в элемент XML как символьные данные.

Элементы XML, представляющие элементы leaf-list, должны размещаться в порядке, заданном пользователем, если leaf-list имеет атрибут ordered-by user. В противном случае порядок зависит от реализации. Элементы XML, представляющие элементы leaf-list, могут чередоваться с элементами братских (sibling) leaf-list, если leaf-list не определяет входные или выходные параметры RPC или операции.

Пример представлен в параграфе 7.7.10.

7.7.9. Операции NETCONF <edit-config>

Элементы leaf-list можно создавать и удалять, но нельзя изменить с помощью <edit-config> путем использования атрибута operation в элементе XML узла leaf-list.

В упорядоченном пользователем leaf-list атрибуты insert и value в пространстве имен YANG XML (параграф 5.3.1) могут служить для управления местом вставки элемента в leaf-list. Они могут применяться в операции create для создания нового элемента в leaf-list, а также в операциях merge или replace для вставки нового элемента или перемещения существующего.

Атрибут оператора insert может принимать значения first, last, before и after. Для значений before и after должен также указываться атрибут value, задающий имеющуюся в leaf-list запись.

Если атрибут insert не задан для операции create, по умолчанию элемент добавляется в конец списка (last).

Если несколько элементов упорядоченного пользователем leaf-list меняются в одном запросе <edit-config>, элементы изменяются по одному в порядке размещения элементов XML в запросе.

В командах <copy-config> и <edit-config> с операцией replace, покрывающей весь список leaf-list, порядок в leaf-list совпадает с порядком элементов XML в запросе.

При обработке сервером NETCONF запроса <edit-config> для узла leaf-list выполняются следующие правила:

  • если задана операция merge или replace, узел создается при его отсутствии;

  • если задана операция create, узел создается при его отсутствии, а в случае наличия узла возвращается ошибка data-exists;

  • если задана операция delete, узел удаляется при его наличии, а в случае отсутствия узла возвращается ошибка data-missing.

7.7.10. Пример использования

     leaf-list allow-user {
       type string;
       description
         "A list of user name patterns to allow.";
     }

Соответствующий экземпляр XML имеет вид

     <allow-user>alice</allow-user>
     <allow-user>bob</allow-user>

Для создания в списке нового элемента с использованием принятой по умолчанию для <edit-config> операции merge

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config">
             <services>
               <ssh>
                 <allow-user>eric</allow-user>
               </ssh>
             </services>
           </system>
         </config>
       </edit-config>
     </rpc>

Для упорядоченного пользователем списка leaf-list

     leaf-list cipher {
       type string;
       ordered-by user;
       description
         "A list of ciphers.";
     }

Приведенный ниже фрагмент может служить для вставки нового шифра blowfish-cbc после 3des-cbc

     <rpc message-id="102"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:yang="urn:ietf:params:xml:ns:yang:1">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config">
             <services>
               <ssh>
                 <cipher nc:operation="create"
                         yang:insert="after"
                         yang:value="3des-cbc">blowfish-cbc</cipher>
               </ssh>
             </services>
           </system>
         </config>
       </edit-config>
     </rpc>

1XML Path Language.

2Synchronous Optical Network — синхронная оптическая сеть.

3Secure SHell — защищенная командная оболочка.

 




RFC 7950 The YANG 1.1 Data Modeling Language

Internet Engineering Task Force (IETF)                 M. Bjorklund, Ed.
Request for Comments: 7950                                Tail-f Systems
Category: Standards Track                                    August 2016
ISSN: 2070-1721

Язык моделирования данных YANG 1.1

The YANG 1.1 Data Modeling Language

PDF

Тезисы

YANG представляет собой язык моделирования данных, применяемый в моделях конфигурационных данных, данных состояния, вызовов удаленных процедур (RPC1) и уведомлениях для протоколов управления сетями. Этот документ описывает синтаксис и семантику языка YANG версии 1.1. Эта версия устраняет неоднозначности и дефекты, обнаруженные в исходной спецификации языка YANG. Имеется незначительное число несовместимостей с языком YANG версии 1. Документ также задает отображения YANG на протокол управления конфигурацией сети NETCONF2.

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

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

Документ является результатом работы IETF3 и представляет согласованный взгляд сообщества IETF. Документ прошел открытое обсуждение и был одобрен для публикации IESG4. Не все одобренные IESG документы претендуют на статус Internet Standard (раздел 2 в RFC 7841).

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

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

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

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

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

Оглавление

Исключено в версии HTML.

1. Введение

YANG представляет собой язык моделирования данных, изначально разработанный для работы с конфигурационными параметрами и данными состояния протокола настройки конфигурации сети NETCONF, вызовов удаленных процедур NETCONF RPC и уведомлений NETCONF [RFC6241]. С момента публикации YANG версии 1 [RFC6020] язык применялся или был предложен для использования также в других протоколах (например, RESTCONF [RESTCONF] и CoMI5 [CoMI]). Кроме того, было предложено кодирование, отличающееся от XML (например, JSON [RFC7951]).

В этом документе описывается синтаксис и семантика языка YANG версии 1.1. Описано также представление модулей YANG на расширяемом языке разметки XML6 [XML] и использование операций NETCONF для манипулирования данными. Возможно использование и других протоколов, но это выходит за рамки спецификации.

В документе [YANG-Guidelines] приведены некоторые рекомендации по разработке моделей данных YANG.

Следует подчеркнуть, что этот документ не отменяет RFC 6020 [RFC6020].

1.1. Основные отличия от RFC 6020

Этот документ определяет версию 1.1 языка YANG, которая исправляет неточности и дефекты исходной спецификации языка YANG [RFC6020].

Ниже перечислены изменения, не совместимые с YANG версии 1.

  • Изменены правила интерпретации escape-символов внутри двойных кавычек. Это изменение не совместимо с YANG версии 1 и при переходе к версии 1.1 модули, использующие непригодные в новой версии последовательности символов, должны быть изменены в соответствии с новыми правилами. Подробности приведены в параграфе 6.1.3.

  • Строки, не заключенные в кавычки, не могут включать символы одинарных или двойных кавычек. Это изменение не совместимо с YANG версии 1 и при переходе к версии 1.1 модули, использующие непригодные в новой версии последовательности символов, должны быть изменены в соответствии с новыми правилами. Подробности приведены в параграфе 6.1.3.

  • Конструкции when и if-feature не применимы в списке ключей. Это изменение не совместимо с YANG версии 1 и при переходе к версии 1.1 модули, использующие непригодные в новой версии конструкции, должны быть удалены для соответствия новым правилам.

  • Определены допустимые в модулях YANG символы. При переходе к версии 1.1 все символы, ставшие непригодными, должны быть удалены. Подробности приведены в разделе 6.

  • Запрещено использование несимвольных кодов (noncharacter) во встроенном типе string. Это изменение оказывает влияние на работу протоколов на базе YANG.

Ниже перечислены другие изменения, внесенные в язык YANG.

  • Номер версии YANG 1 заменен на 1.1.

  • Оператор yang-version стал обязательным в версии YANG 1.1.

  • Расширен синтаксис if-feature для использования логических выражений с именами функций.

  • Разрешено использовать if-feature в bit, enum и identity.

  • Разрешено использовать if-feature в refine.

  • Разрешено использовать choice в качестве сокращенного оператора case (параграф 7.9.2).

  • Добавлен субоператор modifier в оператор pattern (параграф 9.4.6).

  • Разрешено использовать must в input, output и notification.

  • Разрешено использовать require-instance в leafref.

  • Разрешено использовать description и reference в import и include.

  • Разрешен импорт множества выпусков модуля.

  • Разрешено использовать augment для добавления условно обязательных узлов (параграф 7.17).

  • Добавлен набор функций XPath7 в разделе 10.

  • Уточнен XPath дерева контекста в параграфе 6.4.1.

  • Определено строковое значение identityref в выражениях XPath (параграф 9.10).

  • Уточнено значение неожиданных имен в leafrefs определений типов (typedefs) (параграфы 6.4.1 и 9.9.2).

  • Разрешено создание идентификационных данных (identity) из множества базовых отождествлений (параграфы 7.18 и 9.10).

  • Разрешено применять перечисляемые (enumeration) и биты (bit) в качестве субтипов (параграфы 9.6 и 9.7).

  • Разрешены принятые по умолчанию значения leaf-list (параграф 7.7.2).

  • Разрешены совпадающие (не уникальные) значения в leaf-list, не относящихся к конфигурации (параграф 7.7).

  • В грамматике применяется синтаксис регистро-чувствительных строк (как в [RFC7405]).

  • Изменен механизм анонсирования модулей (параграф 5.6.4).

  • Изменены правила области действия для определений в субмодулях. Субмодуль сейчас может указывать на все определения во всех субмодулях, относящихся к тому же модулю, без применения оператора include.

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

  • Разрешено привязывать уведомления к узлам данных.

  • Добавлен оператор определения данных anydata (параграф 7.10), который рекомендуется применять взамен anyxml, когда данные могут моделироваться в YANG.

  • Разрешены типы empty и leafref в объединениях (union).

  • Разрешен тип empty в ключах (key).

  • Удалено ограничение, не позволявшее идентификаторам начинаться с символов «xml».

Ниже приведено изменение, внесенное в отображение для протокола NETCONF.

  • Сервер анонсирует поддержку модулей YANG 1.1, используя ietf-yang-library [RFC7895] вместо ее перечисления в списке возможностей сообщения <hello>.

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

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

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

Ниже приведены определения используемых в документе терминов.

action — действие

Операция, определенная для узла в дереве данных.

anydata — любые данные

Узел данных, который может содержать неизвестный набор узлов, которые могут моделироваться языком YANG, за исключением anyxml.

anyxml — любые данные XML

Узел данных, который может содержать любой неизвестный блок (chunk) данных XML.

augment — дополнение

Добавляет новые узлы схемы к ранее определенному узлу.

base type — базовый тип

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

built-in type — встроенный тип

Тип данных YANG, определенный в самом языке YANG (например, uint32 или string).

choice — выбор

Узел схемы, где действует лишь один из указанных вариантов.

client — клиент

Объект, который может иметь доступ к определенным YANG данным на сервере с использованием того или иного сетевого протокола.

conformance — соответствие

Степень точности соблюдения сервером модели данных.

container — контейнер

Внутренний узел данных, существующий в дереве не более чем в одном экземпляре. Контейнер не имеет значения, но имеет набор дочерних узлов.

data definition statement — оператор определения данных

Оператор, определяющий новые узлы данных, один из операторов container, leaf, leaf-list, list, choice, case, augment, uses, anydata и anyxml.

data model — модель данных

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

data node — узел данных

Узел в дереве схемы, который может быть помещен в дерево данных, ддин из container, leaf, leaf-list, list, anydata и anyxml.

data tree — дерево данных

Воплощенное дерево любых данных, промоделированных с помощью YANG, например, конфигурационные параметры, данные состояния, комбинация данных конфигурации и состояния, входные данные операции или RPC, выходные данные операции или RPC, уведомление.

derived type — производный тип

Тип, определенный на основе встроенного (например, uint32) или другого производного типа.

extension — расширение

Расширение добавляет к операторам не включенную в YANG семантику. Оператор extension определяет новые операторы для выражения этой семантики.

feature — функция, возможность

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

grouping — группировка

Набор многократно используемых (reusable) узлов схемы, который может применяться локально в модуле или в других модулях, импортирующих его. Оператор grouping не является оператором определения данных, поэтому он не задает каких-либо узлов в дереве схемы.

identifier — идентификатор

Строка, используемая для указания различных элементов YANG по именам.

identity — отождествление

Уникальное в глобальном масштабе, абстрактное и не типизованное имя.

instance identifier — идентификатор экземпляра

Механизм для идентификации конкретных узлов в дереве данных.

interior node — внутренний узел

Узел в иерархии, который не является листом (leaf).

leaf — лист

Узел данных, который существует в дереве данных в количестве не более одного экземпляра. Лист имеет значение, но не имеет дочерних узлов.

leaf-list — лист-список

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

list — список

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

mandatory node — обязательный узел

Один из перечисленных ниже вариантов:

    • узел leaf, choice, anydata или anyxml с оператором mandatory, имеющим значение true;
    • узел list или leaf-list с оператором min-elements, имеющим значение больше 0;
    • узел container без оператора presence, имеющий в качестве потомка хотя бы один обязательный узел.

module — модуль

Модуль YANG определяет иерархии узлов схемы. Со своими и импортированными или включенными из любого источника определениями модуль является самодостаточным и «компилируемым».

non-presence container — контейнер отсутствия

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

presence container — контейнер присутствия

Контейнер, само присутствие которого имеет некий смысл (значение).

RPC

Вызов удаленной процедуры.

RPC operation — операция RPC

Вызов конкретной удаленной процедуры (RPC).

schema node — узел схемы

Узел в дереве схемы — action, container, leaf, leaf-list, list, choice, case, rpc, input, output, notification, anydata или anyxml.

schema node identifier — идентификатор узла схемы

Механизм для указания конкретного узла в дереве схемы.

schema tree — дерево схемы

Определение иерархии, заданное внутри модуля.

server — сервер

Объект, обеспечивающий клиентам доступ к определенным в YANG данным через тот или иной протокол сетевого управления.

server deviation — отклонение (в поведении) сервера

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

submodule — субмодуль

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

top-level data node — узел данных верхнего уровня

Узел данных, не имеющий других узлов данных между собой и оператором module или submodule.

uses — использует

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

value space — пространство значений

Применительно к типу данных — набор значений, разрешенных для этого типа. Для экземпляра leaf или leaf-list — пространство значений его типа данных.

Перечисленные ниже термины определены в [RFC6241]:

  • конфигурационные данные (configuration data);

  • конфигурационное хранилище (configuration datastore);

  • хранилище данных (datastore);

  • данные состояния (state data).

При моделировании в YANG хранилище данных реализуется в виде экземпляра дерева данных.

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

3.1. О примерах

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

4. Обзор языка YANG

Этот раздел, не являющийся нормативным, содержит ознакомительный обзор языка YANG.

4.1. Функциональный обзор

Язык YANG был разработан для моделирования данных в протоколе NETCONF. Модуль YANG определяет иерархии данных, которые могут применяться в операциях на основе NETCONF, включая параметры конфигурации, данные состояния, RPC и уведомления. Это позволило полностью описать данные, передаваемые между клиентами и серверами NETCONF. Хотя это и выходит за рамки спецификации, YANG можно использовать и с другими протоколами.

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

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

Модели данных YANG могут описывать ограничения, применяемые к данным, задавая присутствие или значения узлов в зависимости от наличия или значения других узлов в и