RFC 9476 The .alt Special-Use Top-Level Domain

Internet Engineering Task Force (IETF)                         W. Kumari
Request for Comments: 9476                                        Google
Category: Standards Track                                     P. Hoffman
ISSN: 2070-1721                                                    ICANN
                                                          September 2023

The .alt Special-Use Top-Level Domain

Специальный домен верхнего уровня .alt

PDF

Аннотация

Этот документ резервирует метку домена верхнего уровня (Top-Level Domain или TLD) alt для использования вне контекста DNS. В документ также включены рекомендации и указания для разработчиков, создающих дополнительные пространства имён.

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

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

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

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

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

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

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

1. Введение

Многим протоколам Internet требуется именование сущностей (объектов). Широкое распространение получили имена в стиле DNS (последовательность меток, разделённых точками) даже в системах, не входящих в глобальную систему DNS, администрируемую IANA. Этот документ резервирует метку верхнего уровня alt (сокращение от alternative) как доменное имя специального назначения [RFC6761]. Эту метку можно применять в качестве последней (правой) части имени для указания того, что данное имя не имеет корня в глобальной DNS и его не следует преобразовывать по протоколу DNS.

Далее в документе метка верхнего уровня alt указывается как .alt в соответствии с принятой для имён DNS практикой.

Как указано в параграфе 3.1, агентство IANA добавило имя .alt в реестр Special-Use Domain Name в соответствии с документом <https://www.iana.org/domains/reserved>.

Описанные в документе методы предназначены для решения некоторых вопросов, рассмотренных в [RFC8244], где приведены дополнительные сведения о доменных именах специального назначения и связанных с ними вопросов.

В этом документе выбрано имя .alt, а не что-то вроде alt.arpa, чтобы использующим такие имена системам не нужно было беспокоиться о распознавании родителя имени при утечке имени в сеть Internet. Исторически некоторые системы желают использовать не связанные с DNS имена, чтобы они не были частью DNS и .alt подходит для этого.

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

Этот документ предполагает знакомство с терминологией DNS [RFC8499] и определяет ряд дополнительных терминов.

DNS name — имя DNS

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

DNS context — контекст DNS

Пространство имён, привязанное к уникальному в глобальном масштабе корню DNS и администрируемое IANA. Это пространство или контекст обычного применения DNS.

non-DNS context — отличный от DNS контекст

Любое другое (альтернативное) пространство имён.

Pseudo-TLD — псевдо-TLD

Метка, присутствующая в полном доменном имени в позиции TLD и не относящаяся к глобальной системе DNS. Термин не является уничижительным.

TLD

См. определение в разделе 2 [RFC8499].

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

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

2. Пространство имён .alt

Этот документ резервирует метку .alt для использования в качестве неуправляемого (централизованно) пространства имён псевдо-TLD. Метку .alt можно применять в любом доменном имени как псевдо-TLD для обозначения того, что это пространство имён не относится к DNS и имена не следует искать в контексте DNS.

В этом документе .alt служит для представления псевдо-TLD в формате DNS, что соответствует суффиксу 0x03616c7400 в «проводном» формате DNS. Форматы сигналов в линии для других протоколов (не DNS) могут отличаться.

Поскольку имена в зоне .alt относятся к другому пространству имён, они не имеют значения (смысла) в обычном контексте DNS. Заглушкам (stub) и рекурсивным распознавателям DNS не нужно искать их в контексте DNS.

Распознаватели DNS, обслуживающие одновременно DNS и другие протоколы, могут рассматривать .alt подобно DNS-записи из реестра Transport-Independent Locally-Served DNS Zone, который является частью реестра IANA Locally-Served DNS Zones, за исключением того, что .alt всегда служит для обозначения имён, распознаваемых протоколами, отличными от DNS. Отметим, что этот документ не запрашивает добавления .alt в эти реестры, поскольку .alt в соответствии с этой спецификацией не является именем DNS.

Использование .alt в качестве псевдо-TLD не задаёт способ обработки имени протоколом, не относящимся к DNS. Для максимальной совместимости с имеющимися приложениями предлагается (но не требуется) не относящимся к DNS протоколам, которые используют .alt, следовать синтаксису DNS. Если такой протокол применяет в линии протокол, похожий на протокол DNS, он может (но не обязан) добавлять в конец имени пустую (null) метку. Документ не вносит каких-либо предложений в части работы с «проводным» форматом имён для протоколов, не относящихся к DNS.

Желающие создать новое альтернативное пространство имён могут сделать это, используя псевдо-TLD .alt. Этот документ не задаёт ни реестра, ни модели управления для пространства имён .alt, поскольку оно не управляется ни IETF, ни IANA. Не существует гарантии однозначного сопоставления между именами и механизмами их распознавания. Смягчение или разрешение конфликтов в пространствах имён иерархии .alt выходят за рамки этого документа и компетенции IETF. Пользователям рекомендуется учитывать связанные с этим риски при использовании таких имён.

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

Отправка корневым серверам трафика, который будет заведомо вызывать отклик NXDOMAIN, например, запросов для имён с суффиксом .alt, ведёт к расходу ресурсов как на распознавателях, так и на корневых серверах. Кэширующие распознаватели, активно использующие кэширование с проверкой DNSSEC ([RFC8198]), могут смягчать эту проблему, синтезируя негативные отклики из кэшированных записей NSEC для имён в .alt. Аналогично, кэширующие распознаватели, применяющие минимизацию QNAME ([RFC9156]), будут сокращать объем трафика ненужного трафика на корневые серверы, поскольку негативные отклики будут возвращаться для всех имён иерархии .alt.

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

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

3.1. Реестр Special-Use Domain Name

Агентство IANA добавило имя .alt в реестр Special-Use Domain Name [RFC6761] со ссылкой на этот документ (RFC).

3.2. Резервирование доменных имён

Этот раздел создан для выполнения требований [RFC6761]. Поставленные в [RFC6761] вопросы в основном рассчитаны на систему распознавания DNS и некоторые из них не являются актуальными.

  1. Пользователи могут (но не обязаны) считать имена из псевдо-TLD .alt имеющими особое значение.

  2. Предполагается, что прикладные программы, использующие пространство имён в иерархии псевдо-TLD .alt, имеют свои правила обработки имён, возможно в специализированных интерфейсах API, библиотеках и/или прикладных программах. В прикладных программах, не предназначенных специально для использования имён из псевдо-TLD .alt, не ожидается распознавания таких имён как имеющих особое значение.

  3. Предполагается, что разработчики API и библиотек, предназначенных для распознавания имён из псевдо-TLD .alt как имеющих особое значение, выполняют соответствующее преобразование (распознавание) таких имён. Конкретный механизм используемый в API и библиотеках для распознавания имён зависит от применяемой системы распознавания. В обычных API и библиотеках распознавания DNS не предполагается особая обработка имён из псевдо-TLD .alt.

  4. Кэширующим серверам DNS не следует считать имена из псевдо-TLD .alt особыми и не следует применять для них специальную обработку.

  5. Полномочным серверам DNS не следует считать имена из псевдо-TLD .alt особыми и не следует применять для них специальную обработку.

  6. Операторы серверов DNS будут относиться к именам из псевдо-TLD .alt как к именам из прочих TLD, не относящихся к глобальной системе DNS. Операторы серверов DNS могут знать, что имена с суффиксом .alt не являются именами DNS, а запросы для этих имён проникают в контекст DNS. Такая информация может быть полезна для поддержки или отлаживания.

  7. Реестры и регистраторы DNS не могут регистрировать имена из псевдо-TLD .alt, поскольку их не нет в корне глобальной системы DNS.

4. Вопросы приватности

Этот документ резервирует суффикс .alt в качестве индикатора того, что имя не относится к DNS. К сожалению, запросы для таких имён несомненно будут проникать в DNS. Это общая проблема альтернативных пространств имён, не ограничивающаяся именами с суффиксом .alt.

Например, example.alt может вызывать проблемы приватности для имён из этого пространства, попавших в Internet. Кроме того, если имя с суффиксом .alt достаточно уникально, долговечно и часто попадает в глобальную систему DNS, независимо от того, как оно создано, имя может действовать подобно web cookie со всеми вытекающими из этого последствиями для идентификации (в том числе, повторной).

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

Поскольку имена из псевдо-TLD .alt явно находятся вне контекста DNS, для них невозможно полагаться на соображения безопасности, связанные с DNS. Требуется соблюдать осторожность при сопоставлении псевдо-TLD с соответствующей системой распознавания (не DNS) для обеспечения защиты, предоставляемой этой системой.

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

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

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

[RFC6761] Cheshire, S. and M. Krochmal, «Special-Use Domain Names», RFC 6761, DOI 10.17487/RFC6761, February 2013, <https://www.rfc-editor.org/info/rfc6761>.

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

[RFC8244] Lemon, T., Droms, R., and W. Kumari, «Special-Use Domain Names Problem Statement», RFC 8244, DOI 10.17487/RFC8244, October 2017, <https://www.rfc-editor.org/info/rfc8244>.

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

[RFC8198] Fujiwara, K., Kato, A., and W. Kumari, «Aggressive Use of DNSSEC-Validated Cache», RFC 8198, DOI 10.17487/RFC8198, July 2017, <https://www.rfc-editor.org/info/rfc8198>.

[RFC8499] Hoffman, P., Sullivan, A., and K. Fujiwara, «DNS Terminology», BCP 219, RFC 8499, DOI 10.17487/RFC8499, January 2019, <https://www.rfc-editor.org/info/rfc8499>.

[RFC9156] Bortzmeyer, S., Dolmans, R., and P. Hoffman, «DNS Query Name Minimisation to Improve Privacy», RFC 9156, DOI 10.17487/RFC9156, November 2021, <https://www.rfc-editor.org/info/rfc9156>.

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

Спасибо Joe Abley, Mark Andrews, Erik Auerswald, Roy Arends, Ray Bellis, Vittorio Bertola, Marc Blanchet, John Bond, Stéphane Bortzmeyer, David Cake, Vint Cerf, David Conrad, Steve Crocker, Vladimir Cunat, Brian Dickson, Ralph Droms, Robert Edmonds, Patrik Fältström, Bernd Fix, Christian Grothoff, Olafur Gudmundsson, Ted Hardie, Bob Harold, Wes Hardaker, Geoff Huston, Joel Jaeggli, John C Klensin, Eliot Lear, Barry Leiba, Ted Lemon, Edward Lewis, John Levine, George Michaelson, Ed Pascoe, Libor Peltan, Jim Reid, Martin Schanzenbach, Ben Schwartz, Arturo Servin, Peter Thomassen, Paul Vixie, Duane Wessels, Paul Wouters, Suzanne Woolf за их отклики.

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

Спасибо Rob Wilton, который был ответственным руководителем направления (Responsible AD) для этого документа.

Andrew Sullivan был автором документа с момента принятия (2015 г.) до версии 14 (2021 г.).

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

Warren Kumari
Google
1600 Amphitheatre Parkway
Mountain View, CA 94043
United States of America
Email: warren@kumari.net
 
Paul Hoffman
ICANN
Email: paul.hoffman@icann.org

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

nmalykh@protokols.ru


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

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

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

Масштабирование сетевого стека Linux

PDF

По материалам ядра Linux [1] [2]

Введение

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

  • RSS: Receive Side Scaling — масштабирование на приёмной стороне.

  • RPS: Receive Packet Steering — распределение принимаемых пакетов (начиная с ядра 2.6.35).

  • RFS: Receive Flow Steering — распределение принимаемых потоков (начиная с ядра 2.6.35).

  • Accelerated Receive Flow Steering — ускоренное распределение принимаемых потоков (начиная с ядра 2.6.35).

  • XPS: Transmit Packet Steering — распределение передаваемых пакетов (начиная с ядра 2.6.38).

RSS

Современные сетевые адаптеры (NIC) поддерживают несколько очередей дескрипторов приёма и передачи (множество очередей — multi-queue). На приёме NIC может помещать пакеты в разные очереди для распределения нагрузки между процессорами (CPU). Сетевой адаптер распределяет пакеты, применяя к каждому из них фильтр, относящий пакет к одному из небольшого числа логических потоков. Пакеты каждого потока направляются в свою приёмную очередь, а эти очереди могут обрабатываться разными CPU. Этот механизм обычно называют масштабированием не приёмной стороне (Receive-side Scaling или RSS). Целью RSS и других методов масштабирования является однородное повышение производительности. Распределение между множеством очередей может также применяться для приоритизации трафика, но это не является основной задачей описываемых методов.

Применяемым в RSS фильтром обычно является функция свёртки (хэш — hash) для заголовков сетевого и/или транспортного уровня, например, хэш-значение для полей адресов IP и портов TCP в заголовке пакета. В наиболее распространённой аппаратной реализации RSS применяется таблица перенаправления со 128 записями, каждая из которых содержит номер очереди. Приёмная очередь для пакета определяется маскированием 7 младших битов рассчитанного для пакета хэш-значения (обычно Toeplitz-хэш [3]), задающим ключ для таблицы перенаправления, и считыванием соответствующей записи из таблицы.

Некоторые современные NIC позволяют направлять пакеты в разные очереди на основе программируемых фильтров. Например, пакеты для web-сервера на порту TCP 80 могут направляться в его собственную приёмную очередь. Такие фильтры (n-tuple) можно настраивать с помощью утилиты ethtool с командой —config-ntuple.

Конфигурация RSS

Драйверы NIC с поддержкой нескольких очередей обычно предоставляют параметр модуля ядра, задающий число аппаратных очередей. Например, в драйвере bnx2x это параметр num_queues. Типичная конфигурация RSS включает 1 приёмную очередь для каждого CPU, если устройство поддерживает достаточно очередей, или хотя бы 1 очередь на область (domain) памяти — набор CPU, использующих общий уровень памяти (L1, L2, узел NUMA и т. п.).

Таблица перенаправления устройства RSS, которая определяет очередь по маске хэш-значения, обычно программируется при инициализации драйвера. По умолчанию пакеты равномерно распределяются по очередям, но таблицу перенаправления можно извлечь и изменить во время работы с помощью утилиты ethtool (команды —show-rxfh-indir и —set-rxfh-indir). Изменение таблицы позволяет задать для очередей разный вес. Ниже приведён пример принятой по умолчанию таблицы для сетевого адаптера ‎I210 Gigabit Network Connection (драйвер igh).

# ethtool --show-rxfh-indir enp4s0 
RX flow hash indirection table for enp4s0 with 4 RX ring(s): 
  0:      0     0     0     0     0     0     0     0 
  8:      0     0     0     0     0     0     0     0 
 16:      0     0     0     0     0     0     0     0 
 24:      0     0     0     0     0     0     0     0 
 32:      1     1     1     1     1     1     1     1 
 40:      1     1     1     1     1     1     1     1 
 48:      1     1     1     1     1     1     1     1 
 56:      1     1     1     1     1     1     1     1 
 64:      2     2     2     2     2     2     2     2 
 72:      2     2     2     2     2     2     2     2 
 80:      2     2     2     2     2     2     2     2 
 88:      2     2     2     2     2     2     2     2 
 96:      3     3     3     3     3     3     3     3 
104:      3     3     3     3     3     3     3     3 
112:      3     3     3     3     3     3     3     3 
120:      3     3     3     3     3     3     3     3 
RSS hash key: 
Operation not supported 
RSS hash function: 
 toeplitz: on 
 xor: off 
 crc32: off

Конфигурация RSS IRQ

С каждой приёмной очередью связано своё значение прерывания (IRQ), которое NIC использует для уведомления CPU при поступлении новых пакетов в данную очередь. Сигнальным путём для устройств PCIe служат указываемые сообщениями прерывания (message signaled interrupt или MSI-X), которые могут маршрутизироваться конкретному CPU. Активное сопоставление очередей с IRQ можно узнать из файла /proc/interrupts. По умолчанию IRQ может обрабатываться любым CPU. Поскольку обработка прерывания, связанного с приёмом, включает достаточно большую часть обработки пакета, целесообразно распределять приёмные прерывания между CPU. Настройка близости (affinity) для IRQ описана в приложении «Близость SMP IRQ». В некоторых системах используется демон irqbalance, который динамически оптимизирует назначение IRQ и может менять заданные вручную настройки.

Рекомендуемая конфигурация

RSS следует включать, когда задержки играют важную роль или обработка прерываний является узким местом. Распределение нагрузки между CPU сокращает размер очереди. Для сетей с малыми задержками оптимально задавать число очередей равным числу CPU в системе или устанавливать максимальное для NIC значение, если оно меньше числа процессоров. Наиболее эффективной высокоскоростной конфигурацией является конфигурация с наименьшим числом приёмных очередей, в которой ни одна из этих очередей не переполняется из полной загрузки CPU, поскольку в принятом по умолчанию режиме с включённым слиянием (coalescing) прерываний, суммарное число прерываний (а значит, и объём работы) растёт с каждой добавочной очередью.

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

RPS

Распределение (направление) принимаемых пакетов (Receive Packet Steering или RPS) логически является программной реализацией RSS. Программная реализация ведёт к более позднему вызову в пути данных. RSS выбирает очередь и, следовательно, CPU где будет работать обработчик аппаратных прерывания, а RPS выбирает CPU для протокольной обработки над обработчиком прерываний. Для этого пакет помещается в очередь невыполненных заданий (backlog queue) выбранного CPU и активирует CPU для выполнения работы. RPS имеет некоторые преимущества по сравнению с RSS:

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

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

Первым шагом при определении целевого CPU для RPS является расчёт хэш-значения для потока по адресам и/или порта (2-tuple или 4-tuple в зависимости от протокола), которое связывается с пакетом. Хэш-значение предоставляется оборудованием или рассчитывается сетевым стеком. Поддерживающее хэширование оборудование может передать хэш в приёмном дескрипторе для пакета и обычно это будет то же значение, которое применяется для RSS (например, Toeplitz). Хэш сохраняется в поле skb->hash и может использоваться в стеке в качестве хэш-значения для потока.

Каждая аппаратная очередь приёма имеет список связанных CPU, которым RPS может передавать пакеты для обработки. Для каждого принятого пакета вычисляется индекс списка на основе хэш-значения по модулю в соответствии с размером списка. Указанный индексом CPU выбирается для обработки пакета и тот помещается в конец очереди невыполненных заданий CPU. В конце нижней половины процедуры обработки межпроцессорные прерывания IPI передаются всем CPU, для которых имеются пакеты в очереди невыполненных заданий. IPI активирует исполнение ожидающей работы соответствующими CPU и все пакеты из очередей обрабатываются в сетевом стеке.

Конфигурация RPS

Для работы RPS требуется ядро, собранное с опцией CONFIG_RPS (включена по умолчанию для SMP). Однако по умолчанию RPS не включается и требуется явное включение. Список CPU, которым RPS может пересылать трафик для каждой приёмной очереди задаётся файлом в /sys/class/net/<dev>/queues/rx-<n>/rps_cpus, где <dev> — имя сетевого интерфейса, <n> — номер очереди. Этот файл содержит битовую карту CPU. Распределение RPS отключено при нулевом значении (принято по умолчанию) и в этом случае пакеты обрабатываются прерывающим CPU. Описание битовых карт привязки CPU дано в Приложении «Близость SMP IRQ».

Рекомендуемая конфигурация

Для устройства с одной очередью в типичной конфигурации RPS файл rps_cpus указывает CPU в одном домене памяти с прерывающим CPU. Если локальность NUMA не является проблемой, могут быть указаны все CPU в системе. При высокой частоте прерываний может оказаться разумным исключение прерывающего CPU из карты, поскольку это ядро уже выполняет большой объем работы.

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

Ограничения для потоков в RPS

RPS распределяет обработку приёма в ядре между CPU без нарушения порядка пакетов. При отправке всех пакетов одного потока на одно ядро (CPU) возникает дисбаланс нагрузки на CPU, если скорости потоков различаются. Крайним случаем является доминирование в трафике одного потока. Такое поведение, особенно на серверах с множеством одновременных подключений говорит о некорректной настройке или наличии атаки на службу (Denial of Service или DoS) с использованием обманных адресов источников.

Ограничение для потоков (Flow Limit) является необязательной функцией RPS, которая отдаёт приоритет небольшим потокам при конкуренции за CPU путём отбрасывания пакетов в больших потоках немного раньше, чем в мелких. Эта функция применяется лишь в случаях, когда целевой CPU для RPS или RFS близок к насыщению. Когда очередь входящих пакетов CPU достигает половины своего максимального размера (sysctl net.core.netdev_max_backlog), ядро запускает счётчики пакетов по потокам для последних 256 пакетов. Если при поступлении нового пакета поток превышает установленное ограничение (по умолчанию половина прибывающих пакетов), этот пакет отбрасывается. Пакеты из других потоков по-прежнему отбрасываются лишь при достижении netdev_max_backlog. Пока размер входной очереди ниже заданного порога, пакеты не отбрасываются, поэтому ограничение потоков не разрывает соединения сразу и связность сохраняется даже для больших потоков.

Интерфейс

Возможность ограничения для потоков по умолчанию включена в ядро (CONFIG_NET_FLOW_LIMIT), но само ограничение по умолчанию выключено. Ограничения задаются независимо для каждого CPU (чтобы избежать конфликтов блокировки и кэширования) и включаются для CPU установкой соответствующего бита маски в sysctl net.core.flow_limit_cpu_bitmap. Используется тот же формат маски, как в rps_cpus (см. выше) при вызове из procfs

/proc/sys/net/core/flow_limit_cpu_bitmap

Скорость на уровне потока рассчитывается путём хэширования каждого пакета в ячейку (bucket) хэш-таблицы и инкрементирования счётчика по ячейкам. Применяется та же функция хэширования, что и для выбора CPU в RPS, но число ячеек может быть значительно больше числа CPU, поэтому для ограничения потоков применяется более точная идентификация, чтобы сократить число ложных срабатываний. По умолчанию таблица содержит 4096 ячеек (bucket). Значение можно изменить через sysctl net.core.flow_limit_table_len. Это значение применяется лишь при создании новой таблицы и смена значения не меняет активные таблицы.

Рекомендуемая конфигурация

Ограничения для потоков полезны в системах с большим числом одновременных соединений, где наличие соединения, занимающего CPU на 50%, указывает проблему. В таких средах следует включать функцию ограничения для потоков на всех CPU, обрабатывающих приёмные (rx) прерывания (как установлено в /proc/irq/CPU#/smp_affinity).

Работа функции зависит от того, насколько размер очереди входных пакетов превышает порог ограничения для потоков (50%) + размер истории потока (256). В экспериментах хорошо зарекомендовала себя установка для net.core.netdev_max_backlog значения 1000 или 10000.

RFS

RPS распределяет пакеты на основе хэш-значений, что обеспечивает хорошее распределение нагрузки, но не учитывает местоположение приложений. Эта задача решается с помощью распределения (направления) потоков (Receive Flow Steering или RFS). Целью RFS является повышение скорости обращений к кэшу данных путём направления обработки пакетов в ядре на CPU, где запущен поток (thread) приложения, являющегося получателем пакета. В RFS применяются те же механизмы, что и в RPS, для постановки пакетов в очередь невыполненных заданий другого CPU и активизации этого CPU.

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

Глобальная таблица потоков rps_sock_flow_table указывает желаемый CPU для потоков — CPU, обрабатывающий поток в пользовательском пространстве. Каждое значение в таблице является индексом CPU, который обновляется при вызовах recvmsg и sendmsg (в частности, inet_recvmsg(), inet_sendmsg() и tcp_splice_read()).

Когда планировщик переносит поток (thread) на другой CPU при наличии принятых пакетов у прежнего CPU, порядок доставки пакетов может нарушаться. Для предотвращения этого в RFS применяется вторая таблица потоков для отслеживания остающихся пакетов в каждом потоке. Таблица rps_dev_flow_table создаётся для каждой аппаратной очереди приёма каждого устройства. В каждой ячейке таблицы содержится индекс CPU и счётчик. Индекс CPU представляет текущий CPU в очередь которого помещаются пакеты этого потока для последующей обработки ядром. В идеальном случае обработка в ядре и пользовательском пространстве выполняется одним CPU, поэтому индекс CPU в обеих таблицах совпадает. Если планировщик недавно перенёс поток (thread) пользовательского пространства, а ядро всё ещё имеет в очереди пакеты для обработки на прежнем CPU, индексы будут различаться.

Счётчик в rps_dev_flow_table указывает длину необработанной очереди текущего CPU в момент последней постановки в очередь пакета из этого потока. В каждой очереди невыполненных заданий имеется головной счётчик, инкрементируемый при извлечении пакета из очереди. Хвостовой счётчик вычисляется как сумма значения головного счётчика и размера очереди. Иными словами, счётчик в rps_dev_flow[i] указывает последний пакет потока i, который был помещён в очередь текущего назначенного CPU для потока i (значение i выбирается по хэшу и несколько потоков могут иметь одинаковое значение i).

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

  • Значение головного счётчика очереди текущего CPU не меньше записанного значения хвостового счётчика в rps_dev_flow[i].

  • Текущий CPU не установлен (>= nr_cpu_ids).

  • Текущий CPU отключён (offline).

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

Конфигурация RFS

RFS поддерживается лишь в ядрах с включённой опцией CONFIG_RPS (включена по умолчанию для SMP), однако не будет применяться без явного включения в конфигурации. Число записей в глобальной таблице потоков задаётся в файле /proc/sys/net/core/rps_sock_flow_entries, в таблицах по потокам — в файлах /sys/class/net/<dev>/queues/rx-<n>/rps_flow_cnt

Рекомендуемая конфигурация

Число записей в обоих типах таблиц должно быть задано до включения RFS для приёмной очереди с округлением вверх до ближайшей степени 2. Предлагаемое число потоков зависит от ожидаемого в любой момент числа активных соединений, которое может быть значительно меньше числа открытых соединений. Опыт показывает, что rps_sock_flow_entries = 32768 достаточно хорошо подходит для серверов со средней загрузкой.

Для устройства с одной очередью значение rps_flow_cnt для очереди обычно устанавливается равным rps_sock_flow_entries. Для устройств с несколькими очередями значение rps_flow_cnt для каждой очереди может задаваться как rps_sock_flow_entries/N, где N — число очередей. Например, при rps_sock_flow_entries = 32768 и 16 очередями приёма для rps_flow_cnt каждой очереди можно задать значение 2048.

Accelerated RFS

Accelerated RFS по отношению к RFS — то же, что RSS для RPS — механизм распределения нагрузки с аппаратным ускорением, использующий программное состояние для распределения потоков в зависимости от местоположения (CPU) потока (thread) приложения, потребляющего пакеты каждого потока. Ускоренному RFS следует работать лучше RFS, поскольку пакеты передаются напрямую CPU, локальному для потребляющего данные потока (thread). Целевым CPU будет процессор (CPU), на котором выполняется приложение, или, в крайнем случае, CPU, локальный по отношению в CPU потока (thread) приложения с иерархии кэширования.

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

Аппаратная очередь для потока выводится из CPU, записанного в rps_dev_flow_table. Стек обращается к сопоставлению CPU с аппаратными очередями, которое поддерживает драйвер NIC. Это автоматически создаваемое обратное отображение таблицы близости IRQ в файле /proc/interrupts. Драйверы могут использовать функции библиотеки ядра cpu_rmap (обратное отображение близости CPU) для заполнения этого сопоставления. Для каждого CPU в сопоставлении устанавливается очередь, ближайшая к обрабатывающему CPU по местоположению кэша.

Конфигурация Accelerated RFS

Accelerated RFS поддерживается лишь ядрами, собранными с опцией CONFIG_RFS_ACCEL, а поддержка механизма обеспечивается NIC и драйвером. Требуется также включить фильтрацию ntuple с помощью ethtool. Сопоставление CPU с очередями автоматически выводится из близости IRQ, заданной драйвером для каждой приёмной очереди, поэтому дополнительной настройки конфигурации не требуется.

Рекомендуемая конфигурация

Этот механизм следует включать, когда нужно использовать RFS и NIC поддерживает аппаратное ускорение.

XPS

Распределение (направление) передачи пакетов (Transmit Packet Steering или XPS) — это механизм интеллектуального выбора очереди передачи для использования при отправке пакетов через устройство с несколькими очередями. Это можно обеспечить путём записи двух типов сопоставлений — отображения CPU на аппаратные очереди или отображения приёмных очередей на аппаратные очереди передачи.

  1. XPS с использованием отображения CPU.

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

  1. XPS с использованием сопоставления очередей.

    Это отображение применяется для выбора очереди передачи на основе конфигурации карты приёмных очередей, заданной администратором. Набор приёмных очередей можно сопоставить с набором очередей передачи (многие со многими), хотя обычно применяется сопоставление 1:1. Это позволяет передавать пакеты в одну ассоциацию очередей для приёма и передачи. Такой подход полезен при интенсивном опросе многопотоковой (multi-threaded) рабочей нагрузки, где возникают проблемы с привязкой конкретного CPU к конкретному потоку (thread) приложения. Потоки (thread) приложений не привязываются к CPU и каждый поток (thread) обслуживает пакеты, полученные в одной очереди. Номер приёмной очереди хэшируется в сокете соединения. В этой модели отправка пакетов в очередь передачи, соответствующую связанной очереди приёма позволяет снизить издержки CPU. Работа по завершению передачи фиксируется в той же ассоциации очередей, которую опрашивает данное приложение. Это избавляет от издержек, связанных с запуском прерывания на другом CPU. Когда приложение очищает пакеты в процессе опроса, завершение передачи может обрабатываться вместе с опросом в контексте того же потока (thread), что снижает задержку.

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

Выбранная для передачи определённого потока очередь сохраняется в соответствующей структуре сокета для потока (например, соединения TCP). Эта очередь применяется для последующих пакетов, передаваемых в этот поток, чтобы предотвратить нарушение порядка пакетов (out of order или ooo). Такой подход также сокращает издержки, связанные с вызовами get_xps_queues() для пакетов потока. Для предотвращения переупорядочения пакетов очередь для последующих пакетов потока можно поменять лишь при установке для пакета в потоке skb->ooo_okay. Этот флаг указывает, что в потоке нет оставшихся пакетов и очередь передачи можно сменить без риска нарушения порядка. За установку флага ooo_okay отвечает транспортный уровень. Например, TCP устанавливает этот флаг, когда все данные для соединения подтверждены.

Конфигурация XPS

XPS поддерживается только ядрами, собранными с опцией CONFIG_XPS (задана по умолчанию для SMP). При наличии опции в ядре работа XPS зависит от включения и конфигурации XPS при инициализации устройства. Сопоставление CPU с очередями передачи можно посмотреть и изменить через файл /sys/class/net/<dev>/queues/tx-<n>/xps_cpus, сопоставление приёмных очередей с очередями передачи — через файл /sys/class/net/<dev>/queues/tx-<n>/xps_rxqs, где <dev> указывает имя сетевого интерфейса, а <n> — номер очереди передачи.

Рекомендуемая конфигурация

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

При выборе очереди передачи по приёмной очереди нужно явно настроить для XPS сопоставление приёмных очередей с очередями передачи. Если сопоставление приёмных очередей с передающими не задано, очередь передачи выбирается на основе сопоставления с CPU.

Ограничение скорости по очередям передачи (TX)

Для аппаратного ограничения скорости передачи применяется атрибут max-rate, указывающий максимальную скорость в Мбит/с и задаваемый в файле /sys/class/net/<dev>/queues/tx-<n>/tx_maxrate, где <dev> указывает имя сетевого интерфейса, а <n> — номер очереди передачи. Нулевое значение, принятое по умолчанию, отключает ограничение.

Приложение

Близость SMP IRQ

Файлы /proc/irq/<IRQ#>/smp_affinity и /proc/irq/<IRQ#>/smp_affinity_list указывают CPU, разрешённые для данного IRQ#. Битовая маска (smp_affinity) и список процессоров (smp_affinity_list) указывают разрешённые CPU. Отключать все CPU не разрешается, а если контроллер IRQ не поддерживает IRQ значение будет неизменным и разрешает все CPU.

Файл /proc/irq/default_smp_affinity задаёт принятую по умолчанию маску близости, применяемую для всех неактивных IRQ. После выделения (активации) IRQ для его битовой маски близости устанавливается принятое по умолчанию значение, которое можно изменить через указанные выше файлы. По умолчанию применяется маска 0xffffffff.

Ниже приведён пример ограничения IRQ44 (eth0) процессорами CPU0-3, а затем процессорами CPU4-7 (на системе SMP с 8 ядрами).

# cat /proc/irq/44/smp_affinity
ffffffff

# echo 0f > /proc/irq/44/smp_affinity
# cat /proc/irq/44/smp_affinity
0000000f

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

# ping -f 172.16.77.3
PING 172.16.77.3 (172.16.77.3): 56 data bytes
...
--- 172.16.77.3 ping statistics ---
6029 packets transmitted, 6027 packets received, 0% packet loss
round-trip min/avg/max = 0.1/0.1/0.4 ms

Посмотрим статистику использования ядер для прерывания IRQ44

# cat /proc/interrupts | grep 'CPU\|44:'
        CPU0       CPU1       CPU2       CPU3      CPU4       CPU5        CPU6       CPU7
44:       1068       1785       1785       1783         0          0           0         0    IO-APIC-level  eth1

Как можно видеть из приведённой выше статистики прерывание IRQ44 передавалось только первым 4 ядрам (0-3). Перенаправим затем IRQ на CPU(4-7).

# echo f0 > /proc/irq/44/smp_affinity
# cat /proc/irq/44/smp_affinity
000000f0

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

# ping -f 172.16.77.3
PING 172.16.77.3 (172.16.77.3): 56 data bytes
..
--- 172.16.77.3 ping statistics ---
2779 packets transmitted, 2777 packets received, 0% packet loss
round-trip min/avg/max = 0.1/0.5/585.4 ms

Статистика использования ядер для IRQ44 будет иметь вид

# cat /proc/interrupts | grep 'CPU\|44:'
        CPU0       CPU1       CPU2       CPU3      CPU4       CPU5        CPU6       CPU7
44:       1068       1785       1785       1783      1784       1069        1070       1069   IO-APIC-level  eth1

Из приведённого вывода можно видеть, что значения счётчиков доставки IRQ44 изменились лишь для 4 последних ядер, а счётчики для CPU0-3 не изменились.

Литература

[1] Tom Herbert, Willem de Bruijn, Scaling in the Linux Networking Stack (https://www.kernel.org/doc/html/latest/networking/scaling.html)

[2] Ingo Molnar, Max Krasnyansky, SMP IRQ affinity (https://www.kernel.org/doc/html/latest/core-api/irq/irq-affinity.html)

[3] Hugo Krawczyk, New Hash Functions for Message Authentication (https://link.springer.com/content/pdf/10.1007/3-540-49264-x_24.pdf)


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

nmalykh@protokols.ru


1Inter-processor interrupt или IPI.

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

RFC 9408 A YANG Network Data Model for Service Attachment Points (SAPs)

Internet Engineering Task Force (IETF)                 M. Boucadair, Ed.
Request for Comments: 9408                                        Orange
Category: Standards Track                            O. Gonzalez de Dios
ISSN: 2070-1721                                               Telefonica
                                                              S. Barguil
                                                                   Nokia
                                                                   Q. Wu
                                                                  Huawei
                                                                V. Lopez
                                                                   Nokia
                                                               June 2023

A YANG Network Data Model for Service Attachment Points (SAPs)

Модель данных YANG для точек присоединения к сервису (SAP)

PDF

Аннотация

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

Этот документ дополняет модель данных ietf-network из RFC 8345, добавляя в неё концепцию точек подключения к сервису (Service Attachment Point или SAP). SAP — это опорная точка сети, к которой могут подключаться сетевые услуги, такие как виртуальные частные сети сетевого (Layer 3 Virtual Private Network или L3VPN) и канального (Layer 2 Virtual Private Network или L2VPN) уровня. К одной точке SAP может быть привязана 1 или несколько служб. В модели данных SAP поддерживаются интерфейсы между пользователем и сетью (User-to-Network Interface или UNI) и между сетями (Network-to-Network Interface или NNI).

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

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

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

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

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

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

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

1. Введение

Сервис-провайдеры предлагают своим клиентам множество сетевых услуг, включая виртуальные частные сети (Virtual Private Network или VPN), программно определяемые распределенные сети (Software-Defined Wide-Area Network или SD-WAN) с наложением [BGP-SDWAN-USAGE] и сетевые срезы (slice) [IETF-NETWORK-SLICES]. Для рационализации общих операций и повышения уровня автоматизации процедур предоставления услуг сервис-провайдерам нужно поддерживать представления о местах возможного доступа клиентов к услугам. Такое представление может служить, например, для обеспечения данными подразделения, отвечающего за обработку заказов на обслуживание, проверку доступности услуг, отслеживание охвата по услугам и т. п. (см., например, параграф 3.2 в [RFC8969]). Для этого в данном документе вводится концепция точек присоединения к сервису (Service Attachment Point или SAP).

SAP представляют собой опорные точки сети, где сетевые услуги могут быть предоставлены клиентам. Например, эта концепция служит для принятия решений о точках присоединения и предоставления услуг в модели услуг виртуальной частной сети на сетевом (Layer 3 VPN Service Model или L3SM) [RFC8299] или канальном (Layer 2 VPN Service Model (L2SM) [RFC8466] уровне. Она может также применяться для нахождения точек предоставления услуг клиентам по конфигурации сети, описанной в моделях сетевого (Layer 3 VPN Network Model или L3NM) [RFC9182] и канального (Layer 2 VPN Network Model или L2NM) [RFC9291] уровня.

Этот документ определяет сетевую модель YANG () для представления, управления и контроля SAP. Модель дополняет в модуль ietf-network [RFC8345] концепцию SAP. В разделе представлен пример использования модели. Этот документ разъясняет назначение и область действия сетевой модели SAP, а также её связь с другими моделями ().

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

В документе не применяются какие-либо допущения об услугах, предоставляемых сетью её пользователям. Службы VPN (например, L3VPN3 или L2VPN4) [RFC4026] применяются в качестве иллюстраций (см. приложения A и B).

С учётом того, что интерфейсы между пользователем и сетью (User-to-Network Interface или UNI) и между сетями (Network-to-Network Interface или NNI) широко используются операторами для указания точек раздела при предоставлении услуг, этот документ поддерживает UNI SAP и NNI SAP. Примеры использования опорных точек UNI и NNI даны в [MEF6], [MEF17], [RFC6004], [RFC6215], для NNI в контексте VPN — в Приложении C.

Модель данных YANG в разделе 6 соответствует архитектуре хранилищ данных управления сетью (Network Management Datastore Architecture или NMDA) [RFC8342].

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

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

В документе предполагается знание читателем концепций [RFC6241], [RFC7950], [RFC8345], [RFC8309], поскольку в документе применяются термины из этих RFC.

В этом документе применяется графическое представление деревьев данных, определённое в [RFC8340].

Термин «модель сети» (network model) здесь применяется в соответствии с определением в параграфе 2.1 [RFC8969].

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

Service provider — поставщик услуг, сервис-провайдер

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

Attachment Circuit (AC) — устройство присоединения

Канал, соединяющий краевое устройство клиента (Customer Edge или CE) с краевым устройством провайдера (Provider Edge или PE).

Customer Edge (CE) — краевое устройство клиента

Оборудование, предоставленное отдельному клиенту и напрямую соединённое с одним или несколькими PE через AC. Устройства CE обычно размещаются у клиента. CE может применяться для одной услуги (например, L3VPN), хотя может поддерживаться и несколько VPN, если они имеют отдельные AC. В качестве CE может служить маршрутизатор, мост, коммутатор и т. п.

Provider Edge (PE) — краевое устройство провайдера

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

Service Attachment Points (SAPs) — точки присоединения к сервису

Абстракция опорных точек сети (например, обращённая к PE сторона AC или обращённая к CE сторона AC при управлении CE со стороны провайдера), где сетевые услуги предоставляются или могут предоставляться клиентам. Точка SAP может связана с одним или несколькими AC.

3. Пример использования сетевой модели SAP

Операции управления у сервис-провайдера могут быть автоматизированы с использованием разных способов, таких как интерфейсы на основе модулей YANG [RFC8969] [RFC6241] [RFC8040]. С этой точки зрения и с учётом архитектуры, показанной на рисунке , целью этого документа является предоставление механизма на основе интерфейса YANG для отображения абстрактного представления сети от сетевого контроллера до уровня организации обслуживания с упором на точки предоставления услуг клиентам. Модель также служит для отыскания опорных точек сети, где услуги будут предоставляться клиентам. Для услуг, которым нужны ресурсы партнерских сетей модель также служит для раскрытия NNI.

                   +-----------------+
                   |      Клиент     |
                   +--------+--------+
Модели обслуживания клиентов|
   (например, L3SM, L2SM)   |
                   +--------+--------+
                   |  Организация    |
                   |  обслуживания   |
                   +------+---+------+
     Модели сетей         |   | Модель сети SAP
  (например, L3NM, L2NM)  |   |
                   +------+---+------+
                   |   Контроллер    |
                   |      сети       |
                   +--------+--------+
                            |
      +---------------------+---------------------+
      |                    Сеть                   |
      +-------------------------------------------+

Рисунок . Использование модели SAP.


В разделе 5 [RFC4026] приведён обзор блоков, которые обычно применяются для классификации сетей провайдеров.

Уровню организации (orchestration) сервиса не требуется знать детали устройства базовой сети (например, узлы P, см. параграф 5.3.1 в [RFC4026])). На рисунке приведено абстрактное представление сети с точки зрения организатора услуг. Однако этого представления недостаточно для предоставления уровню организации сервиса сведений для создания сетевых услуг. Топология сервиса должна обеспечивать возможность раскрыть набор узлов и связанные с ними точки присоединения, где могут быть предоставлены сетевые услуги.

.---------.          .---------.
|   PE1   |          |   PE2   |
'---------'          '---------'
           \        /
            \------/
            (      )
           (        )
            (      )
            /------\
           /         \
.---------.          .---------.
|   PE3   |          |   PE4   |
'---------'          '---------'

Рисунок . Абстрактная топология сети.


Как правило, уровень организации обслуживания, ориентируясь на UNI, будет видеть набор PE и интерфейсов (физических или логических) в сторону клиентов, к которым могут подключаться (или уже подключены) CE. Такие интерфейсы также называют UNI-N5 [RFC6215]. Уровень организации обслуживания может использовать такие интерфейсы для организации или предоставления запрошенных услуг. На рисунке дан пример сетевой топологии SAP, которая поддерживается контроллером сети и раскрывается оркестратору служб.

    .-+-. .-+-. .-+-.              .-+-.       .-+-.
  .-|sap|-|sap|-|sap|-.          .-|sap|-------|sap|-.
  | '---' '---' '---' |          | '---'       '---' |
.---.                 |          |                   |
|sap|      PE1        |          |         PE2       |
'---'                 |          |                   |
  |                   |          |                   |
  '-------------------'          '-------------------'

  .-------------------.          .-------------------.
  |                   |          |                   |
  |                   |          |                 .---.
  |         PE3       |          |        PE4      |sap|
  |                   |          |                 '---'
  | .---. .---. .---. |          | .---. .---. .---. |
  '-|sap|-|sap|-|sap|-'          '-|sap|-|sap|-|sap|-'
    '-+-' '-+-' '-+-'              '-+-' '-+-' '-+-'

Рисунок . Сетевая топология SAP.


Отдельная топология сети SAP может применяться для организации одного или нескольких типов услуг (например, L3VPN, Ethernet VPN — EVPN)). Контроллер сети может раскрывать типы услуг и связанными с ними интерфейсы через SAP.

                                                     .---.
                                                     |CE2|
                                                     '-+-'
                                                       |
           .-+-. .-+-. .-+-.             .-+-.       .-+-.
         .-|sap|-|sap|-|sap|-.         .-|sap|-------|sap|-.
         | '---' '---' '---' |         | '---'       '---' |
.---.  .---.                 |         |                   |
|CE1+--+sap|      PE1        |         |         PE2       |
'---'  '---'                 |         |                   |
         |                   |         |                   |
         '-------------------'         '-------------------'

         .-------------------.         .-------------------.
         |                   |         |                   |
         |                   |         |                 .---.  .---.
         |         PE3       |         |        PE4      |sap+--+CE5|
         |                   |         |                 '---'  '---'
         | .---. .---. .---. |         | .---. .---. .---. |
         '-|sap|-|sap|-|sap|-'         '-|sap|-|sap|-|sap|-'
           '-+-' '-+-' '-+-'             '-+-' '-+-' '-+-'
                         |                 |     |
                       .-+-.               |   .-+-.
                       |CE3+---------------'   |CE4|
                       '---'                   '---'

Рисунок . Топология сети с CE и AC.


Как показано на рисунке , уровень организации услуг будет иметь доступ к набору моделей обслуживания клиентов (например, L3SM или L2SM) на интерфейсах в сторону клиентов и набору моделей сетей (например, L3NM и модели данных топологии сети) на интерфейсах в сторону ресурсов. В таких случаях предполагается, что контроллер не знает о происходящем за PE в направлении CE и отвечает только за управление и контроль точек SAP и сетей между PE. Для сопоставления точек доставки из запросов услуг и SAP модель SAP может включать идентификатор партнерской точки (CE, сайта и т. п.).

В Приложении A приведён пример, отражающий топологию, показанную на рисунке .

4. Связи с другими моделями данных YANG

Модель сети SAP можно рассматривать как данные инвентаризации, связанные с точками SAP. Модель поддерживает опись обращённых к клиентам устройств в сети, основанной на [RFC8345]. На рисунке показаны связи сетевой модели SAP с другими моделями. Модель сети SAP дополняет модель сети из [RFC8345] и импортирует модель топологии сети из [RFC8345], а другие модели топологии, связанные с конкретной технологией (например, модель топологии TE6 [RFC8795] или топологии L3 [RFC8346]) дополняют модель топологии сети из [RFC8345].

               +-------------------------+
               |                         |
               | Абстрактная модель сети |
               |                         |
               +------------+------------+
                            |
                  +---------+---------+
                  |                   |
           +------V------+     +------V-------+
           | Абстрактная |     |  Модели для  |
           |  модель     |     |инвентаризации|
           |  топологии  |     |  (например,  |
           |   сети      |     |   модель     |
           |             |     |   сети SAP)  |
           +-----+-------+     +--------------+
                 |
     +-----------+-----------+
     |           |           |
+----V----+ +----V----+ +----V----+
|Модель   | |Модель   | |Модель   |
|топол. TE| |топол. L3| |топол. L2| ...
+---------+ +---------+ +---------+

Рисунок . Связь модели сети SAP с другими моделями.


SAP можно рассматривать как обращённые к клиенту точки завершения (termination point или TP) с предоставлением конкретных услуг. Различие между SAP и TP состоит в том, что канал завершается одной точкой TP (параграф 4.4.6 в [RFC8345]), тогда как AC может завершаться несколькими SAP. Кроме того, SAP не является точкой завершения туннеля (tunnel termination point или TTP, см. параграф 3.6 в [RFC8795]) или канала.

В контексте программно определяемых сетей (Software-Defined Networking или SDN) [RFC7149] [RFC7426] модель данных YANG SAP можно применять для обмена сведениями между элементами управления, чтобы поддерживать предоставление услуг VPN и управление ресурсами в соответствии с [RFC9182] и [RFC9291]. С помощью этой модели данных уровень организации услуг может узнать о доступных конечных точках (SAP) соединительных ресурсов базовой сети. Уровень организации обслуживания может определить конечные точки соединений для добавления в сервис L2VPN или L3VPN. С помощью других моделей данных (например, L3SM [RFC8299] или L2SM [RFC8466]) иерархические элементы управления могут оценить доступность сквозной связности IP или связности L2VPN и, следовательно, определить последовательность доменов и соединительных точек для использования.

Связанные с интерфейсами расширенные узлы данных не включены в модель SAP. Указанные в этой модели идентификаторы интерфейсов используются в качестве фильтров для установки или извлечения данные с использованием моделей данных устройств (например, [RFC7224]).

5. Дерево модуля SAP

Модель данных сети SAP ietf-sap-ntw создана на основе модуля ietf-network [RFC8345], дополненного узлами с SAP.

Структура модуля ietf-sap-ntw показана на рисунке .

   module: ietf-sap-ntw
     augment /nw:networks/nw:network/nw:network-types:
       +--rw sap-network!
          +--rw service-type*   identityref
     augment /nw:networks/nw:network/nw:node:
       +--rw service* [service-type]
          +--rw service-type                   identityref
          +--rw sap* [sap-id]
             +--rw sap-id                      string
             +--rw description?                string
             +--rw parent-termination-point?   nt:tp-id
             +--rw attachment-interface?       string
             +--rw interface-type?             identityref
             +--rw encapsulation-type?         identityref
             +--rw role?                       identityref
             +--rw allows-child-saps?          boolean
             +--rw peer-sap-id*                string
             +--ro sap-status
             |  +--ro status?        identityref
             |  +--ro last-change?   yang:date-and-time
             +--rw service-status
                +--rw admin-status
                |  +--rw status?        identityref
                |  +--rw last-change?   yang:date-and-time
                +--ro oper-status
                   +--ro status?        identityref
                   +--ro last-change?   yang:date-and-time

Рисунок . Структура дерева модуля YANG SAP.

Топология сети SAP может служить для предоставления 1 или нескольких типов услуг (service-type). Примеры поддерживаемых типов услуг приведены ниже.

  • L3VPN [RFC4364];

  • виртуальные частные ЛВС (Virtual Private LAN Service или VPLS) [RFC4761] [RFC4762];

  • Виртуальные частные линии (Virtual Private Wire Service или VPWS) [RFC8214];

  • Ethernet VPN на основе BGP MPLS [RFC7432];

  • VPWS в Ethernet VPN [RFC8214];

  • Магистральные мосты провайдера (Provider Backbone Bridging) в сочетании с Ethernet VPN (PBB-EVPN) [RFC7623]

  • EVPN на основе VXLAN7 [RFC8365];

  • виртуальные сети [RFC8453];

  • расширенные VPN (VPN+) [ENHANCED-VPN];

  • сетевые «срезы» (slice) [IETF-NETWORK-SLICES];

  • SD-WAN [BGP-SDWAN-USAGE];

  • базовая связность IP.

Эти типы услуг создаются на основе типов, уже заданных в [RFC9181], и дополнительных типов, определённых здесь. В будущих модулях YANG (включая пересмотр заданного здесь модуля YANG) при необходимости могут быть определены новые типы услуг.

Применение типов услуг, заданных в [RFC9181] означает упрощение сопоставления топологии SAP и соответствующих моделей сетей, которые применяются для предоставления конкретных услуг через сети провайдеров.

Для доступа к топологии SAP в соответствии с услугами могут применяться фильтры по типам услуг. Пример этого показан на рисунке в Приложении B.

Узел в топологии может поддерживать 1 или несколько типов услуг (service-type) из числа перечисленных в контейнере sap-network. Затем к каждому типу услуг привязывается список SAP, поддерживающих этот тип. Характеристики SAP приведены ниже.

sap-id

Идентификатор, однозначно указывающий SAP в рамках узла.
Одна точка SAP может присутствовать в разных типах услуг и в таком случае все они используют общий идентификатор SAP.
SAP, связанные с интерфейсами, где непосредственно размещаются службы, интерфейсы, которые готовы поддерживать субинтерфейсы для служб (ещё не активированные), или службы, уже созданные на субинтерфейсах, указываются в качестве SAP. На рисунке в Приложении B показано, как можно указать службы, способные размещать субинтерфейсы по службам.
Например, sap-id может быть идентификатором сети VPN, как определено в параграфе 7.6 [RFC9182]. Пример, иллюстрирующий применение этого атрибута при создании сервиса, представлен в Приложении D.

description

Текстовое описание SAP.

parent-termination-point

Ссылка на родительскую точку завершения, с которой связана точка SAP. В соответствии с параграфом 4.2 в [RFC8345] точка завершения служит окончанием канала на узле и может быть физическим портом, интерфейсом и т. п. Указанная родительская точка завершения предполагается обращённой в сторону клиента, а не ядра сети.
Этот атрибут может применяться, например, для связывания интерфейса с субинтерфейсами, поскольку все они могут быть указаны как SAP узла. Атрибут служит также для связывания SAP с физической топологией.
Этот узел может применяться, например, для отображения конечных точек IETF Network Slice [IETF-NETWORK-SLICES] на конечные точки служб/туннелей/путей в базовой сети.

attachment-interface

Ссылка на интерфейс, с которым связана точка SAP. Один интерфейс может поддерживать несколько служб. В зависимости от развёртывания идентификатор присоединения может отражать интерфейс соединения.
Например, этой ссылкой может служить любой из идентификаторов (l2-termination-point, local-bridge-reference, bearer-reference, lag-interface-id), определённых в параграфе 7.6.1 [RFC9182] или l3-termination-point, определённый в параграфе 7.6.2 [RFC9182]. Контроллер отвечает за обеспечение использования согласованных ссылок в SAP и моделях базовых устройств или иных механизмах инвентаризации устройств.

interface-type

Указывает тип порта, к которому привязана точка SAP — физический порт, петлевой интерфейс (loopback(, интерфейс агрегированного канала (Link Aggregation Group или LAG) [IEEE802.1AX], интерфейс интегрированной с мостом маршрутизации (Integrated Routing and Bridging или IRB) (например, [RFC9135]), интерфейс локального моста и т. п..
Сопоставление с конкретными типами интерфейсом в соответствии с [RFC7224] поддерживает контролёр. Это сопоставление применяется, например, при трансляции контроллером сетевой модели SAP в модели устройств (параграф 4.4 в [RFC8969]).

encapsulation-type

Тип инкапсуляции для интерфейса, указанного атрибутом attachment-interface (см. [RFC9181]). Этот узел данных применяется, например, для решения вопроса о возможности многократного использования имеющейся точки SAP для поддержки сервиса или создания нового субинтерфейса.

role

Указывает роль SAP (например, UNI или NNI). SAP наследует роль родительского интерфейса (parent- termination-point).

allows-child-saps

Значение true указывает, что интерфейс присоединения для этой точки SAP может поддерживать субинтерфейсы для служб. Возможность прямого присоединения к родительской точке SAP в дополнение к дочерним SAP зависит от службы.

peer-sap-id

Ссылки на удалённые точки AC. Этот идентификатор может (но не обязан) совпадать с идентификатором SAP, используемым в конфигурации партнёра. Использование идентичных идентификаторов упрощает сопоставление между запросом на обслуживание партнёра и локальной точкой SAP. Примерами таких ссылок являются идентификаторы сайтов (параграф 6.3 в [RFC8299]), точек разделения служб (Service Demarcation Point или SDP, см. параграф 3.2 в [IETF-NETWORK-SLICES]) и адреса IP граничных маршрутизаторов партнерских автономных систем (Autonomous System Border Router или ASBR).

sap-status

Указывает рабочее состояние SAP, значения состояний определены в [RFC9181].
Когда присутствует родительский интерфейс и субинтерфейс, но родительский интерфейс отключён, статус этого интерфейса имеет предпочтение перед статусом, указанным субинтерфесом.

service-status

Указывает административное и рабочее состояние для данной точки SAP. Эти сведения особенно полезны, когда одна точка SAP обеспечивает несколько служб, из которых активна лишь часть. Поэтому рабочему значению sap-status недопустимо влиять на административное значение service-status.
Значение oper-status для службы указывает её рабочее состояние, наблюдаемое в конкретной точке SAP, а не статус службы в масштабе сети с множеством SAP. Статус службы в масштабе сети можно определить с использованием соответствующей модели сети, например из числа указанных в параграфе 7.3 [RFC9182] или параграфе 7.3 [RFC9291].
Для оценки статуса предоставления услуг в данной точке SAP рекомендуется проверять административное и рабочее состояние (service-status) в дополение к sap-status. При этом контроллер сети (или оператор) может обнаруживать аномалии. Например, если служба административно включена для SAP, а sap-status для этой точки SAP указывает отключения (down), предполагается, что oper-status также указывает отключение (down). Отдельное получение рабочего состояния в таких условиях может применяться для обнаружения аномалий. Аналогичным способом можно сравнить административное и рабочее состояние для обнаружения относящихся к службе аномалий активации SAP. Например, активное рабочее состояние SAP для службы, объявленной неактивной для SAP административно, говорит о необходимости приведения наблюдаемого состояния службы с ожидаемым.

6. Модуль YANG SAP

Этот модуль импортирует типы из [RFC6991], [RFC8345], [RFC9181]. Узлы sap-entry и sap-list определены как группировки (grouping) для их использования в модулях YANG конкретных служб.

   <CODE BEGINS> file "ietf-sap-ntw@2023-06-20.yang"
   module ietf-sap-ntw {
     yang-version 1.1;
     namespace "urn:ietf:params:xml:ns:yang:ietf-sap-ntw";
     prefix sap;

     import ietf-network-topology {
       prefix nt;
       reference
         "RFC 8345: A YANG Data Model for Network
                    Topologies, Section 6.2";
     }
     import ietf-network {
       prefix nw;
       reference
         "RFC 8345: A YANG Data Model for Network
                    Topologies, Section 6.1";
     }
     import ietf-vpn-common {
       prefix vpn-common;
       reference
         "RFC 9181: A Common YANG Data Model for Layer 2 and Layer 3
                    VPNs";
     }
     import ietf-yang-types {
       prefix yang;
       reference
         "RFC 6991: Common YANG Data Types, Section 3";
     }

     organization
       "IETF OPSA (Operations and Management Area) Working Group";
     contact
       "WG Web:   <https://datatracker.ietf.org/wg/opsawg/> 
        WG List:  <mailto:opsawg@ietf.org> 

        Editor:   Mohamed Boucadair
                  <mailto:mohamed.boucadair@orange.com> 

        Author:   Oscar Gonzalez de Dios
                  <mailto:oscar.gonzalezdedios@telefonica.com> 

        Author:   Samier Barguil
                  <mailto:samier.barguil_giraldo@nokia.com> 

        Author:   Qin Wu
                  <mailto:bill.wu@huawei.com> 

        Author:   Victor Lopez
                  <mailto:victor.lopez@nokia.com>"; 
     description
       "Этот модуль YANG задаёт модель для представления, управления и
        контроля точек доступа к сервису (SAP) в сетевой топологии.

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

        Распространение и применение модуля в исходной или двоичной 
        форме с изменениями или без таковых разрешено в соответствии с
        лицензией Simplified BSD License, изложенной в параграфе 4.c
        IETF Trust's Legal Provisions Relating to IETF Documents
        (https://trustee.ietf.org/license-info). 

        Эта версия модуля YANG является частью RFC 9408, где правовые
        аспекты приведены более полно.";

     revision 2023-06-20 {
       description
         "Initial version.";
       reference
         "RFC 9408: A YANG Network Data Model for Service Attachment
                    Points (SAPs)";
     }

     identity virtual-network {
       base vpn-common:service-type;
       description
         "Виртуальная сеть - экземпляр логической сети, созданный 
          на основе физической сети.";
       reference
         "RFC 8453: Framework for Abstraction and Control of TE
                    Networks (ACTN)";
     }

     identity enhanced-vpn {
       base vpn-common:service-type;
       description
         "расширенная VPN (VPN+). Подход VPN+ основан на имеющихся
          технологиях VPN и TE с добавлением характеристик, нужных
          конкретным службам, в дополнение к традиционным VPN.";
       reference
         "draft-ietf-teas-enhanced-vpn:
            A Framework for Enhanced Virtual Private Network
            (VPN+)";
     }

     identity network-slice {
       base vpn-common:service-type;
       description
         "IETF Network Slice - топология логической сети, соединяющая
          множество конечных точек с использованием набора общих
          или выделенных сетевых ресурсов, служащих для достижения
          целей конкретной службы.";
       reference
         "draft-ietf-teas-ietf-network-slices:
            A Framework for IETF Network Slices";
     }

     identity sdwan {
       base vpn-common:service-type;
       description
         "Программно определяемая распределенная сеть (SD-WAN) 
          на основе PE.";
       reference
         "draft-ietf-bess-bgp-sdwan-usage:
            BGP Usage for SD-WAN Overlay Networks";
     }

     identity basic-connectivity {
       base vpn-common:service-type;
       description
         "Базовая связность IP, например, «плоская» связность, 
          обеспечиваемая для организаций через общую или выделенную
          инфраструктуру MPLS.";
     }

     identity interface-role {
       description
         "Базовый идентификатор роли интерфейса в сети.";
     }

     identity uni {
       base interface-role;
       description
         "Интерфейс между пользователем и сетью (UNI).";
     }

     identity nni {
       base interface-role;
       description
         "Интерфейс между сетями (NNI).";
     }

     identity interface-type {
       description
         "Базовый идентификатор для типа интерфейса.";
     }

     identity phy {
       base interface-type;
       description
         "Физический порт.";
     }

     identity loopback {
       base interface-type;
       description
         "Петлевой (loopback) интерфейс.";
     }

     identity lag {
       base interface-type;
       description
         "Интерфейс композитного канала (LAG).";
     }

     identity irb {
       base interface-type;
       description
         "Интерфейс интегрированного с маршрутизацией моста (IRB). Такие
          интерфейсы обычно соединяют элементы виртуальной маршрутизации
          и пересылки IP (IP-VRF) с доменом моста.";
     }

     identity local-bridge {
       base interface-type;
       description
         "Ссылка на локальный мост для размещения, например, реализаций,
          которым нужен внутренний мост. При использовании такого типа
          для идентификации интерфейса служит ссылка на локальный домен
          моста.";
     }

     identity logical {
       base interface-type;
       description
         "Указывает локальный интерфейс, который обычно служит для
          привязки сервиса. Этот тип применяется лишь при невозможности
          использовать более конкретный тип (loopback, lag, irb,
          local-bridge).";
     }

     grouping sap-entry {
       description
         "Сведения о точке присоединения к службе (SAP).";
       leaf sap-id {
         type string;
         description
           "Идентификатор, однозначно указывающий SAP.";
       }
       leaf description {
         type string;
         description
           "Текстовое описание SAP.";
       }
       leaf parent-termination-point {
         type nt:tp-id;
         description
           "Указывает родительскую точку завершения, к которой
            присоединена точка SAP. Это может быть физический порт,
            интерфейс и т. п.";
       }
       leaf attachment-interface {
         type string;
         description
           "Интерфейс, к которому привязана точка SAP.";
       }
       leaf interface-type {
         type identityref {
           base interface-type;
         }
         description
           "Тип интерфейса, к которому привязана точка SAP.";
       }
       leaf encapsulation-type {
         type identityref {
           base vpn-common:encapsulation-type;
         }
         description
           "Тип инкапсуляции интерфейса, к которому привязана 
            точка SAP.";
       }
       leaf role {
         type identityref {
           base interface-role;
         }
         description
           "Указывает роль SAP.";
       }
       leaf allows-child-saps {
         type boolean;
         description
           "Указывает, способен ли интерфейс этой точки SAP поддерживать
            субинтерфейсы для служб.";
       }
       leaf-list peer-sap-id {
         type string;
         description
           "Указывает идентификатор точки завершения партнёра (например,
            CE). Эти сведения могут служить для сопоставления, такого 
            как идентификация точки SAP, подключённой к конечной точке,
            указанной в запросе сервиса.";
       }
     }

     grouping sap-list {
       description
         "Сведения о SAP.";
       list sap {
         key "sap-id";
         description
           "SAP является обстракцией точки, с которой могут быть связаны
            сетевые службы, такие как L3VPN, L2VPN, сетевые срезы.";
         uses sap-entry;
         container sap-status {
           config false;
           description
             "Указывает рабочее состояние SAP независимо от 
              предоставляемых через эту точку услуг.";

           uses vpn-common:oper-status-timestamp;
         }
         container service-status {
           description
             "Указывает статус сервиса.";
           container admin-status {
             description
               "Административный статус сервиса.";
             leaf status {
               type identityref {
                 base vpn-common:administrative-status;
               }
               description
                 "Административный статус сервиса, предоставляемого
                  в SAP.";
             }
             leaf last-change {
               type yang:date-and-time;
               description
                 "Фактическая дата и время смены статуса сервиса.";
             }
           }
           container oper-status {
             config false;
             description
               "Рабочий статус сервиса, предоставляемого в SAP.";
             uses vpn-common:oper-status-timestamp;
           }
         }
       }
     }

     augment "/nw:networks/nw:network/nw:network-types" {
       description
         "Новый тип сети для сети SAP.";
       container sap-network {
         presence "Указывает тип сети SAP.";
         description
           "Наличие контейнера указывает сеть SAP.";
         leaf-list service-type {
           type identityref {
             base vpn-common:service-type;
           }
           description
             "Указывает набор поддерживаемых типов услуг.";
         }
       }
     }

     augment "/nw:networks/nw:network/nw:node" {
       when '../nw:network-types/sap:sap-network' {
         description
           "Параметры дополнения, применяемые лишь к сети SAP.";
       }
       description
         "Параметры SAP на уровне узла.";
       list service {
         key "service-type";
         description
           "Список поддерживаемых узлом типов услуг.";
         leaf service-type {
           type identityref {
             base vpn-common:service-type;
           }
           description
             "Тип сервиса.";
         }
         uses sap-list;
       }
     }
   }
   <CODE ENDS>

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

Этот документ регистрирует URI в субреестре ns реестра IETF XML Registry [RFC3688].

   URI:  urn:ietf:params:xml:ns:yang:ietf-sap-ntw
   Registrant Contact:  The IESG.
   XML:  N/A; запрошенный URI является пространством имён XML.

Документ регистрирует модуль YANG в суб реестре YANG Module Names [RFC6020] реестра YANG Parameters.

   Name:  ietf-sap-ntw
   Namespace:  urn:ietf:params:xml:ns:yang:ietf-sap-ntw
   Maintained by IANA?  N
   Prefix:  sap
   Reference:  RFC 9408

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

Заданный этим документом модуль YANG определяет схему для данных, предназначенную для доступа через сеть с использованием протоколов управления, таких как NETCONF [RFC6241] или RESTCONF [RFC8040]. Нижним уровнем NETCONF служит защищённый транспорт с обязательной поддержкой SSH (Secure Shell) [RFC6242]. Нижним уровнем RESTCONF служит протокол HTTPS с обязательной поддержкой защиты на транспортном уровне (TLS) [RFC8446].

Модель доступа к конфигурации сети (NACM – Network Configuration Access Control Model) [RFC8341] обеспечивает возможность разрешить доступ лишь определённых пользователей NETCONF или RESTCONF к заранее заданному подмножеству операций NETCONF или RESTCONF и содержимого.

В заданном здесь модуле данных YANG определено множество узлов данных, которые разрешают запись, создание и удаление (т. е. config true, как принято по умолчанию). Эти узлы могут быть конфиденциальными или уязвимыми в некоторых сетевых средах. Запись в такие узлы (например, edit-config) без должной защиты может негативно влиять на работу сети. Ниже перечислены ветви и узлы, которые могут быть конфиденциальны или уязвимы.

/nw:networks/nw:network/nw:node/sap:service/sap:sap

Эта ветвь задаёт конфигурацию узлов в модели сети SAP. Неожиданные изменения в ветви (например, связывание SAP с другой родительской точкой завершения) могут приводить к нарушению работы службы и/или некорректному поведению сети. Некорректное поведение возникает главным образом из-за конфигурации сети, не соответствующей предполагаемому оператором поведению (см., например, параграф 4.2.1 в [RFC8969]).

Некоторые из доступных для чтения узлов в этом модуле YANG могут быть конфиденциальны или уязвимы в той или иной сетевой среде. Важно контролировать доступ к таким объектам (например, get, get-config, notification). Ниже перечислены ветви и узлы, которые могут быть конфиденциальны или уязвимы.

/nw:networks/nw:network/nw:node/sap:service/sap:sap

Несанкционированный доступ к этой ветви может раскрывать сведения о рабочем состоянии узлов в модели сети SAP (например, отождествление клиента в peer-sap-id).

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, <https://www.rfc-editor.org/info/rfc2119>.

[RFC3688] Mealling, M., «The IETF XML Registry», BCP 81, RFC 3688, DOI 10.17487/RFC3688, January 2004, <https://www.rfc-editor.org/info/rfc3688>.

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

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

[RFC6242] Wasserman, M., «Using the NETCONF Protocol over Secure Shell (SSH)», RFC 6242, DOI 10.17487/RFC6242, June 2011, <https://www.rfc-editor.org/info/rfc6242>.

[RFC6991] Schoenwaelder, J., Ed., «Common YANG Data Types», RFC 6991, DOI 10.17487/RFC6991, July 2013, <https://www.rfc-editor.org/info/rfc6991>.

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

[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, «RESTCONF Protocol», RFC 8040, DOI 10.17487/RFC8040, January 2017, <https://www.rfc-editor.org/info/rfc8040>.

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

[RFC8341] Bierman, A. and M. Bjorklund, «Network Configuration Access Control Model», STD 91, RFC 8341, DOI 10.17487/RFC8341, March 2018, <https://www.rfc-editor.org/info/rfc8341>.

[RFC8345] Clemm, A., Medved, J., Varga, R., Bahadur, N., Ananthakrishnan, H., and X. Liu, «A YANG Data Model for Network Topologies», RFC 8345, DOI 10.17487/RFC8345, March 2018, <https://www.rfc-editor.org/info/rfc8345>.

[RFC8346] Clemm, A., Medved, J., Varga, R., Liu, X., Ananthakrishnan, H., and N. Bahadur, «A YANG Data Model for Layer 3 Topologies», RFC 8346, DOI 10.17487/RFC8346, March 2018, <https://www.rfc-editor.org/info/rfc8346>.

[RFC8446] Rescorla, E., «The Transport Layer Security (TLS) Protocol Version 1.3», RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.

[RFC8795] Liu, X., Bryskin, I., Beeram, V., Saad, T., Shah, H., and O. Gonzalez de Dios, «YANG Data Model for Traffic Engineering (TE) Topologies», RFC 8795, DOI 10.17487/RFC8795, August 2020, <https://www.rfc-editor.org/info/rfc8795>.

[RFC9181] Barguil, S., Gonzalez de Dios, O., Ed., Boucadair, M., Ed., and Q. Wu, «A Common YANG Data Model for Layer 2 and Layer 3 VPNs», RFC 9181, DOI 10.17487/RFC9181, February 2022, <https://www.rfc-editor.org/info/rfc9181>.

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

[BGP-SDWAN-USAGE] Dunbar, L., Guichard, J., Sajassi, A., Drake, J., Najem, B., Banerjee, A., and D. Carrel, «BGP Usage for SD-WAN Overlay Networks», Work in Progress, Internet-Draft, draft-ietf-bess-bgp-sdwan-usage-09, 7 April 2023, <https://datatracker.ietf.org/doc/html/draft-ietf-bess-bgp-sdwan-usage-09>.

[ENHANCED-VPN] Dong, J., Bryant, S., Li, Z., Miyasaka, T., and Y. Lee, «A Framework for Enhanced Virtual Private Network (VPN+)», Work in Progress, Internet-Draft, draft-ietf-teas-enhanced-vpn-12, 23 January 2023, <https://datatracker.ietf.org/doc/html/draft-ietf-teas-enhanced-vpn-12>.

[IEEE802.1AX] IEEE, «IEEE Standard for Local and Metropolitan Area Networks—Link Aggregation», IEEE Std 802.1AX-2020, DOI 10.1109/IEEESTD.2020.9105034, 2020, <https://doi.org/10.1109/IEEESTD.2020.9105034>.

[IETF-NETWORK-SLICES] Farrel, A., Ed., Drake, J., Ed., Rokui, R., Homma, S., Makhijani, K., Contreras, L.M., and J. Tantsura, «A Framework for IETF Network Slices», Work in Progress, Internet-Draft, draft-ietf-teas-ietf-network-slices-19, 21 January 2023, <https://datatracker.ietf.org/doc/html/draft-ietf-teas-ietf-network-slices-19>.

[MEF17] The Metro Ethernet Forum, «Technical Specification MEF 17, Service OAM Requirements & Framework — Phase 1», April 2007, <https://www.mef.net/wp-content/uploads/2015/04/MEF-17.pdf>.

[MEF6] The Metro Ethernet Forum, «Technical Specification MEF 6, Ethernet Services Definitions — Phase I», June 2004, <https://www.mef.net/Assets/Technical_Specifications/PDF/MEF_6.pdf>.

[RFC4026] Andersson, L. and T. Madsen, «Provider Provisioned Virtual Private Network (VPN) Terminology», RFC 4026, DOI 10.17487/RFC4026, March 2005, <https://www.rfc-editor.org/info/rfc4026>.

[RFC4364] Rosen, E. and Y. Rekhter, «BGP/MPLS IP Virtual Private Networks (VPNs)», RFC 4364, DOI 10.17487/RFC4364, February 2006, <https://www.rfc-editor.org/info/rfc4364>.

[RFC4761] Kompella, K., Ed. and Y. Rekhter, Ed., «Virtual Private LAN Service (VPLS) Using BGP for Auto-Discovery and Signaling», RFC 4761, DOI 10.17487/RFC4761, January 2007, <https://www.rfc-editor.org/info/rfc4761>.

[RFC4762] Lasserre, M., Ed. and V. Kompella, Ed., «Virtual Private LAN Service (VPLS) Using Label Distribution Protocol (LDP) Signaling», RFC 4762, DOI 10.17487/RFC4762, January 2007, <https://www.rfc-editor.org/info/rfc4762>.

[RFC6004] Berger, L. and D. Fedyk, «Generalized MPLS (GMPLS) Support for Metro Ethernet Forum and G.8011 Ethernet Service Switching», RFC 6004, DOI 10.17487/RFC6004, October 2010, <https://www.rfc-editor.org/info/rfc6004>.

[RFC6215] Bocci, M., Levrau, L., and D. Frost, «MPLS Transport Profile User-to-Network and Network-to-Network Interfaces», RFC 6215, DOI 10.17487/RFC6215, April 2011, <https://www.rfc-editor.org/info/rfc6215>.

[RFC7149] Boucadair, M. and C. Jacquenet, «Software-Defined Networking: A Perspective from within a Service Provider Environment», RFC 7149, DOI 10.17487/RFC7149, March 2014, <https://www.rfc-editor.org/info/rfc7149>.

[RFC7224] Bjorklund, M., «IANA Interface Type YANG Module», RFC 7224, DOI 10.17487/RFC7224, May 2014, <https://www.rfc-editor.org/info/rfc7224>.

[RFC7426] Haleplidis, E., Ed., Pentikousis, K., Ed., Denazis, S., Hadi Salim, J., Meyer, D., and O. Koufopavlou, «Software-Defined Networking (SDN): Layers and Architecture Terminology», RFC 7426, DOI 10.17487/RFC7426, January 2015, <https://www.rfc-editor.org/info/rfc7426>.

[RFC7432] Sajassi, A., Ed., Aggarwal, R., Bitar, N., Isaac, A., Uttaro, J., Drake, J., and W. Henderickx, «BGP MPLS-Based Ethernet VPN», RFC 7432, DOI 10.17487/RFC7432, February 2015, <https://www.rfc-editor.org/info/rfc7432>.

[RFC7623] Sajassi, A., Ed., Salam, S., Bitar, N., Isaac, A., and W. Henderickx, «Provider Backbone Bridging Combined with Ethernet VPN (PBB-EVPN)», RFC 7623, DOI 10.17487/RFC7623, September 2015, <https://www.rfc-editor.org/info/rfc7623>.

[RFC7951] Lhotka, L., «JSON Encoding of Data Modeled with YANG», RFC 7951, DOI 10.17487/RFC7951, August 2016, <https://www.rfc-editor.org/info/rfc7951>.

[RFC8214] Boutros, S., Sajassi, A., Salam, S., Drake, J., and J. Rabadan, «Virtual Private Wire Service Support in Ethernet VPN», RFC 8214, DOI 10.17487/RFC8214, August 2017, <https://www.rfc-editor.org/info/rfc8214>.

[RFC8299] Wu, Q., Ed., Litkowski, S., Tomotaki, L., and K. Ogaki, «YANG Data Model for L3VPN Service Delivery», RFC 8299, DOI 10.17487/RFC8299, January 2018, <https://www.rfc-editor.org/info/rfc8299>.

[RFC8309] Wu, Q., Liu, W., and A. Farrel, «Service Models Explained», RFC 8309, DOI 10.17487/RFC8309, January 2018, <https://www.rfc-editor.org/info/rfc8309>.

[RFC8340] Bjorklund, M. and L. Berger, Ed., «YANG Tree Diagrams», BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, <https://www.rfc-editor.org/info/rfc8340>.

[RFC8342] Bjorklund, M., Schoenwaelder, J., Shafer, P., Watsen, K., and R. Wilton, «Network Management Datastore Architecture (NMDA)», RFC 8342, DOI 10.17487/RFC8342, March 2018, <https://www.rfc-editor.org/info/rfc8342>.

[RFC8365] Sajassi, A., Ed., Drake, J., Ed., Bitar, N., Shekhar, R., Uttaro, J., and W. Henderickx, «A Network Virtualization Overlay Solution Using Ethernet VPN (EVPN)», RFC 8365, DOI 10.17487/RFC8365, March 2018, <https://www.rfc-editor.org/info/rfc8365>.

[RFC8453] Ceccarelli, D., Ed. and Y. Lee, Ed., «Framework for Abstraction and Control of TE Networks (ACTN)», RFC 8453, DOI 10.17487/RFC8453, August 2018, <https://www.rfc-editor.org/info/rfc8453>.

[RFC8466] Wen, B., Fioccola, G., Ed., Xie, C., and L. Jalil, «A YANG Data Model for Layer 2 Virtual Private Network (L2VPN) Service Delivery», RFC 8466, DOI 10.17487/RFC8466, October 2018, <https://www.rfc-editor.org/info/rfc8466>.

[RFC8969] Wu, Q., Ed., Boucadair, M., Ed., Lopez, D., Xie, C., and L. Geng, «A Framework for Automating Service and Network Management with YANG», RFC 8969, DOI 10.17487/RFC8969, January 2021, <https://www.rfc-editor.org/info/rfc8969>.

[RFC9135] Sajassi, A., Salam, S., Thoria, S., Drake, J., and J. Rabadan, «Integrated Routing and Bridging in Ethernet VPN (EVPN)», RFC 9135, DOI 10.17487/RFC9135, October 2021, <https://www.rfc-editor.org/info/rfc9135>.

[RFC9182] Barguil, S., Gonzalez de Dios, O., Ed., Boucadair, M., Ed., Munoz, L., and A. Aguado, «A YANG Network Data Model for Layer 3 VPNs», RFC 9182, DOI 10.17487/RFC9182, February 2022, <https://www.rfc-editor.org/info/rfc9182>.

[RFC9291] Boucadair, M., Ed., Gonzalez de Dios, O., Ed., Barguil, S., and L. Munoz, «A YANG Network Data Model for Layer 2 VPNs», RFC 9291, DOI 10.17487/RFC9291, September 2022, <https://www.rfc-editor.org/info/rfc9291>.

Приложение A. Пример упрощённой сети SAP

На рисунке показан пример топологии SAP, о которой сообщает контроллер сети. Этот пример отражает топологию, показанную на рисунке . Для каждой точки SAP представлен лишь минимальный набор сведений, в частности, не указаны узлы parent-termination-point, attachment-interface, interface-type, encapsulation-type, role. Точки SAP, способные предоставлять услуги, но ещё не активированные, указаны sap-status/status со значением ietf-vpn-common:op-down и service-status/admin-status/status со значением ietf-vpn-common:admin-down. SAP, где включено предоставление услуг указаны service-status/admin-status/status со значением ietf-vpn-common:admin-up и service-status/oper-status/status со значением ietf-vpn-common:op-up. Отметим, что указанные в разделе 5 аномалии не наблюдались для этих SAP. Тело сообщения на рисунка ниже представлено в кодировании JSON для данных YANG в соответствии с [RFC7951].

   {
     "ietf-network:networks": {
       "network": [
         {
           "network-types": {
             "ietf-sap-ntw:sap-network": {
               "service-type": [
                 "ietf-vpn-common:l3vpn",
                 "ietf-vpn-common:vpls"
               ]
             }
           },
           "network-id": "example:an-id",
           "node": [
             {
               "node-id": "example:pe1",
               "ietf-sap-ntw:service": [
                 {
                   "service-type": "ietf-vpn-common:l3vpn",
                   "sap": [
                     {
                       "sap-id": "sap#11",
                       "peer-sap-id": ["ce-1"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-up"
                         },
                         "oper-status": {
                           "status": "ietf-vpn-common:op-up"
                         }
                       }
                     },
                     {
                       "sap-id": "sap#12",
                       "sap-status": {
                         "status": "ietf-vpn-common:op-down"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-down"
                         }
                       }
                     },
                     {
                       "sap-id": "sap#13",
                       "sap-status": {
                         "status": "ietf-vpn-common:op-down"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-down"
                         }
                       }
                     },
                     {
                       "sap-id": "sap#14",
                       "sap-status": {
                         "status": "ietf-vpn-common:op-down"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-down"
                         }
                       }
                     }
                   ]
                 }
               ]
             },
             {
               "node-id": "example:pe2",
               "ietf-sap-ntw:service": [
                 {
                   "service-type": "ietf-vpn-common:l3vpn",
                   "sap": [
                     {
                       "sap-id": "sap#21",
                       "sap-status": {
                         "status": "ietf-vpn-common:op-down"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-down"
                         }
                       }
                     },
                     {
                       "sap-id": "sap#22",
                       "peer-sap-id": ["ce-2"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-up"
                         },
                         "oper-status": {
                           "status": "ietf-vpn-common:op-up"
                         }
                       }
                     }
                   ]
                 }
               ]
             },
             {
               "node-id": "example:pe3",
               "ietf-sap-ntw:service": [
                 {
                   "service-type": "ietf-vpn-common:l3vpn",
                   "sap": [
                     {
                       "sap-id": "sap#31",
                       "sap-status": {
                         "status": "ietf-vpn-common:op-down"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-down"
                         }
                       }
                     },
                     {
                       "sap-id": "sap#32",
                       "sap-status": {
                         "status": "ietf-vpn-common:op-down"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-down"
                         }
                       }
                     },
                     {
                       "sap-id": "sap#33",
                       "peer-sap-id": ["ce-3"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-up"
                         },
                         "oper-status": {
                           "status": "ietf-vpn-common:op-up"
                         }
                       }
                     }
                   ]
                 }
               ]
             },
             {
               "node-id": "example:pe4",
               "ietf-sap-ntw:service": [
                 {
                   "service-type": "ietf-vpn-common:l3vpn",
                   "sap": [
                     {
                       "sap-id": "sap#41",
                       "peer-sap-id": ["ce-3"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-up"
                         },
                         "oper-status": {
                           "status": "ietf-vpn-common:op-up"
                         }
                       }
                     },
                     {
                       "sap-id": "sap#42",
                       "peer-sap-id": ["ce-4"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-up"
                         },
                         "oper-status": {
                           "status": "ietf-vpn-common:op-up"
                         }
                       }
                     },
                     {
                       "sap-id": "sap#43",
                       "sap-status": {
                         "status": "ietf-vpn-common:op-down"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-down"
                         }
                       }
                     },
                     {
                       "sap-id": "sap#44",
                       "peer-sap-id": ["ce-5"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-up"
                         },
                         "oper-status": {
                           "status": "ietf-vpn-common:op-up"
                         }
                       }
                     }
                   ]
                 }
               ]
             }
           ]
         }
       ]
     }
   }

Рисунок . Пример упрощённой модели SAP.

Приложение B. Простой пример модели SAP — фильтр узлов

В примере на рисунке PE1 (с node-id example:pe1, как показано на рисунке ) имеет 2 физических интерфейса GE0/6/1 и GE0/6/4. Два субинтерфейса GE0/6/4.1 и GE0/6/4.2 связаны с физическим интерфейсом GE0/6/4. Представим, что организатору обслуживания раскрываются 4 SAP, сопоставленные с этими физическими интерфейсами и их субинтерфейсами.

.-------------------------.
|                 GE0/6/4 |
| PE1                .----+----.
|                    |sap#2    |GE0/6/4.1
|                    |      .--+--.
|                    |      |sap#3|
|                    |      '--+--'
|                    |         |GE0/6/4.2
|                    |      .--+--.
|                    |      |sap#4|
|                    |      '--+--'
|                    |         |
|                    +----+----+
|                         |
|                  GE0/6/1|
|                    .----+----.
|                    |sap#1    |
|                    '----+----'
|                         |
'-------------------------'

Рисунок . Пример PE и его интерфейсов.


Предположим, что для точки SAP, связанной с физическим интерфейсом GE0/6/1, сервис ещё не включён, а для SAP, связанных с физическим интерфейсом GE0/6/4, активированы службы VPLS и L3VPN на субинтерфейсах GE0/6/4.1 и GE0/6/4.2, соответственно. Точки sap#1 и sap#2 помечены как способные поддерживать службы на субинтерфейсах (allows-child-saps true).

Организатор служб может запросить у контроллера сети, например, какие услуги предоставляются на SAP узла PE1, передав запрос RESTCONF GET. На рисунке показан пример тела отклика на запрос RESTCONF, полученного от контроллера.

   {
     "ietf-sap-ntw:service": [
       {
         "service-type": "ietf-vpn-common:l3vpn",
         "sap": [
           {
             "sap-id": "sap#1",
             "description": "Готовы к размещению SAP",
             "attachment-interface": "GE0/6/1",
             "interface-type": "ietf-sap-ntw:phy",
             "role": "ietf-sap-ntw:uni",
             "allows-child-saps": true,
             "sap-status": {
               "status": "ietf-vpn-common:op-up"
             }
           },
           {
             "sap-id": "sap#2",
             "description": "Готовы к размещению SAP",
             "attachment-interface": "GE0/6/4",
             "interface-type": "ietf-sap-ntw:phy",
             "role": "ietf-sap-ntw:uni",
             "allows-child-saps": true,
             "sap-status": {
               "status": "ietf-vpn-common:op-up"
             }
           },
           {
             "sap-id": "sap#3",
             "description": "Описание первой точки SAP",
             "parent-termination-point": "GE0/6/4",
             "attachment-interface": "GE0/6/4.1",
             "interface-type": "ietf-sap-ntw:logical",
             "encapsulation-type": "ietf-vpn-common:vlan-type",
             "sap-status": {
               "status": "ietf-vpn-common:op-up"
             },
             "service-status": {
               "admin-status": {
                 "status": "ietf-vpn-common:admin-up"
               },
               "oper-status": {
                 "status": "ietf-vpn-common:op-up"
               }
             }
           }
         ]
       },
       {
         "service-type": "ietf-vpn-common:vpls",
         "sap": [
           {
             "sap-id": "sap#1",
             "description": "Готовы к размещению SAP",
             "attachment-interface": "GE0/6/1",
             "interface-type": "ietf-sap-ntw:phy",
             "role": "ietf-sap-ntw:uni",
             "allows-child-saps": true,
             "sap-status": {
               "status": "ietf-vpn-common:op-up"
             }
           },
           {
             "sap-id": "sap#2",
             "description": "Готовы к размещению SAP",
             "attachment-interface": "GE0/6/4",
             "interface-type": "ietf-sap-ntw:phy",
             "role": "ietf-sap-ntw:uni",
             "allows-child-saps": true,
             "sap-status": {
               "status": "ietf-vpn-common:op-up"
             }
           },
           {
             "sap-id": "sap#4",
             "description": "Другое описание",
             "parent-termination-point": "GE0/6/4",
             "attachment-interface": "GE0/6/4.2",
             "interface-type": "ietf-sap-ntw:logical",
             "encapsulation-type": "ietf-vpn-common:vlan-type",
             "sap-status": {
               "status": "ietf-vpn-common:op-up"
             },
             "service-status": {
               "admin-status": {
                 "status": "ietf-vpn-common:admin-up"
               },
               "oper-status": {
                 "status": "ietf-vpn-common:op-up"
               }
             }
           }
         ]
       }
     ]
   }

Рисунок . Пример тела отклика на запрос с фильтром узла.

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

   {
     "ietf-sap-ntw:service": [
       {
         "service-type": "ietf-vpn-common:l3vpn",
         "sap": [
           {
             "sap-id": "sap#1",
             "description": "Готовы к размещению SAP",
             "attachment-interface": "GE0/6/1",
             "interface-type": "ietf-sap-ntw:phy",
             "role": "ietf-sap-ntw:uni",
             "allows-child-saps": true,
             "sap-status": {
               "status": "ietf-vpn-common:op-up"
             }
           },
           {
             "sap-id": "sap#2",
             "description": "Готовы к размещению SAP",
             "attachment-interface": "GE0/6/4",
             "interface-type": "ietf-sap-ntw:phy",
             "role": "ietf-sap-ntw:uni",
             "allows-child-saps": true,
             "sap-status": {
               "status": "ietf-vpn-common:op-up"
             }
           },
           {
             "sap-id": "sap#3",
             "description": "Описание первой точки SAP",
             "parent-termination-point": "GE0/6/4",
             "attachment-interface": "GE0/6/4.1",
             "interface-type": "ietf-sap-ntw:logical",
             "encapsulation-type": "ietf-vpn-common:vlan-type",
             "sap-status": {
               "status": "ietf-vpn-common:op-up"
             },
             "service-status": {
               "admin-status": {
                 "status": "ietf-vpn-common:admin-up"
               },
               "oper-status": {
                 "status": "ietf-vpn-common:op-up"
               }
             }
           }
         ]
       }
     ]
   }

Рисунок . Примера тела отклика на запрос с фильтром сервиса.

Приложение C. Пример NNI SAP — Inter-AS VPN Option A

В разделе 10 [RFC4364] рассмотрено несколько вариантов расширения услуг VPN за пределы одной автономной системы (Autonomous System или AS). Для иллюстрации здесь выбран вариант Option A, но подобные примеры можно привести и для других вариантов.

В этом варианте граничный маршрутизатор автономной системы (ASBR) напрямую соединён с ASBR соседней AS. Эти 2 ASBR связаны через несколько физических или логических интерфейсов и на каждом из ASBR имеется хотя бы 1 субинтерфейс для каждой сети VPN, которой нужно передавать свои маршруты из одной AS в другую. Оба ASBR ведут себя как узлы PE, воспринимая соседа как CE. На рисунке показан упрощённый фрагмент топологии с двумя AS (A и B) с акцентом на каналы, соединяющие эти AS.

.--------------------.                      .--------------------.
|                    |                      |                    |
|              A  .--+--.                .--+--.  A              |
|              S  |     +================+     |  S              |
|              B  | (VRF1)----(VPN1)----(VRF1) |  B              |
|              R  |     |                |     |  R              |
|                 | (VRF2)----(VPN2)----(VRF2) |                 |
|              a  |     +================+     |  b              |
|              1  '--+--'                '--+--'  1              |
|     AS A           |                      |         AS B       |
|              A  .--+--.                .--+--.  A              |
|              S  |     +================+     |  S              |
|              B  | (VRF1)----(VPN1)----(VRF1) |  B              |
|              R  |     |                |     |  R              |
|                 | (VRF2)----(VPN2)----(VRF2) |                 |
|              a  |     +================+     |  b              |
|              2  '--+--'                '--+--'  2              |
|                    |                      |                    |
'--------------------'                      '--------------------'

Рисунок . Пример Inter-AS VPN (Option A).


На рисунке представлен пример тела сообщения, полученного от сетевого контроллера из AS A (с акцентом на интерфейсы NNI, показанные на рисунке ).

   {
     "ietf-network:networks": {
       "network": [
         {
           "network-types": {
             "ietf-sap-ntw:sap-network": {
               "service-type": [
                 "ietf-vpn-common:l3vpn"
               ]
             }
           },
           "network-id": "example:an-id",
           "node": [
             {
               "node-id": "example:asbr-a1",
               "ietf-sap-ntw:service": [
                 {
                   "service-type": "ietf-vpn-common:l3vpn",
                   "sap": [
                     {
                       "sap-id": "sap#11",
                       "description": "Родительский канал между AS link#1",
                       "role": "ietf-sap-ntw:nni",
                       "allows-child-saps": true,
                       "peer-sap-id": ["asbr-b1"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       }
                     },
                     {
                       "sap-id": "sap#12",
                       "description": "Родительский канал между AS link#2",
                       "role": "ietf-sap-ntw:nni",
                       "allows-child-saps": true,
                       "peer-sap-id": ["asbr-b1"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       }
                     },
                     {
                       "sap-id": "sap#13",
                       "description": "vpn1",
                       "role": "ietf-sap-ntw:nni",
                       "peer-sap-id": ["asbr-b1"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-up"
                         },
                         "oper-status": {
                           "status": "ietf-vpn-common:op-up"
                         }
                       }
                     },
                     {
                       "sap-id": "sap#14",
                       "description": "vpn2",
                       "role": "ietf-sap-ntw:nni",
                       "peer-sap-id": ["asbr-b1"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-up"
                         },
                         "oper-status": {
                           "status": "ietf-vpn-common:op-up"
                         }
                       }
                     }
                   ]
                 }
               ]
             },
             {
               "node-id": "example:asbr-a2",
               "ietf-sap-ntw:service": [
                 {
                   "service-type": "ietf-vpn-common:l3vpn",
                   "sap": [
                     {
                       "sap-id": "sap#11",
                       "description": "Родительский канал между AS link#1",
                       "role": "ietf-sap-ntw:nni",
                       "allows-child-saps": true,
                       "peer-sap-id": ["asbr-b2"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       }
                     },
                     {
                       "sap-id": "sap#12",
                       "description": "Родительский канал между AS link#2",
                       "role": "ietf-sap-ntw:nni",
                       "allows-child-saps": true,
                       "peer-sap-id": ["asbr-b2"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       }
                     },
                     {
                       "sap-id": "sap#21",
                       "description": "vpn1",
                       "role": "ietf-sap-ntw:nni",
                       "peer-sap-id": ["asbr-b2"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-up"
                         },
                         "oper-status": {
                           "status": "ietf-vpn-common:op-up"
                         }
                       }
                     },
                     {
                       "sap-id": "sap#22",
                       "description": "vpn2",
                       "role": "ietf-sap-ntw:nni",
                       "peer-sap-id": ["asbr-b2"],
                       "sap-status": {
                         "status": "ietf-vpn-common:op-up"
                       },
                       "service-status": {
                         "admin-status": {
                           "status": "ietf-vpn-common:admin-up"
                         },
                         "oper-status": {
                           "status": "ietf-vpn-common:op-up"
                         }
                       }
                     }
                   ]
                 }
               ]
             }
           ]
         }
       ]
     }
   }

Рисунок . Пример использования SAP для NNI.

Приложение D. Примеры применения модели SAP при создании услуг

В этом приложении приведены примеры использования модели SAP при организации услуг.

Пример топологии SAP представлен на рисунке и включает 4 PE с точками SAP, а также сведения о клиентах.

Предположим, что оператор хочет организовать услугу L3VPN между двумя PE (PE3 и PE4), обслуживающими 2 CE (CE6 и CE7). Для этого оператор будет запрашивать топологию SAP и получит отклик, похожий на показанный на рисунке . Этот отклик показывает, что SAP с идентификаторами присоединения sap#31 и sap#43 не имеют установленных служб. Это, в частности, следует из (1) административного статуса service-status ietf-vpn-common:admin-down, для всех услуг, поддерживаемых этими двумя SAP, и (2) отсутствия аномалий, отмеченных в разделе 5. После обнаружения «свободных» SAP проверяются узлы interface-type и encapsulation-type, чтобы убедиться в совместимости запрашиваемого сервиса L3VPN с характеристиками SAP. В случае совместимости значение attachment-id можно использовать как идентификатор доступа в сеть VPN в запросе L3NM create.

Похожий процесс можно применить для организации так называемого сервиса Inter-AS VPN Option A. В отличие от предыдущего примера, предположим, что оператор хочет организовать сервис L3VPN между парой PE (PE3 и PE4), относящихся к разным AS (PE3 принадлежит AS A, а PE4 — AS B). Интерфейсы NNI между этими AS представлены на рисунке . Оператор AS A будет запрашивать через контроллер своей AS топологию SAP и получит не только сведения, приведённые на рисунке , но и показанную на рисунке информацию об интерфейсах NNI. Оператор организует службу в AS A между PE3 и свободной, совместимой точкой SAP в ASBR A1. Такую же процедуру использует оператор AS B для организации службы в AS B между свободной, совместимой точкой SAP в ASBR B1 и PE4. Услуги могут предоставляться в обеих AS с использованием L3NM.

Предположим теперь, что вместо службы L3VPN оператор хочет организовать сервис L2VPN. Если interface-type является физическим портом, можно создать новую логическую точку SAP, используя модель SAP для удовлетворения потребностей службы (например, можно установить атрибут encapsulation-type ietf-vpn-common:vlan-type). После создания логической точки SAP её attachment-id применяется для организации экземпляра услуги L2NM (параграф 7.6 в [RFC9291]).

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

Спасибо Adrian Farrel, Daniel King, Dhruv Dhody, Benoit Claise, Bo Wu, Erez Segev, Raul Arco, Joe Clarke, Riyas Valiyapalathingal, Tom Petch, Olga Havel, Richard Roberts за их комментарии.

Спасибо Martin Björklund за рецензию YANG Doctors, Menachem Dodge за рецензию opsdir, Mach Chen за рецензию rtgdir, Linda Dunbar за рецензию genart и Ivaylo Petrov за рецензию secdir.

Особая благодарность Adrian Farrel за кураторскую (Shepherd) рецензию и Rob Wilton за тщательный обзор AD.

Спасибо Lars Eggert, Roman Danyliw, Zaheduzzaman Sarker за их комментарии при рецензировании в IESG.

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

Mohamed Boucadair (editor)
Orange
France
Email: mohamed.boucadair@orange.com
 
Oscar Gonzalez de Dios
Telefonica
Madrid
Spain
Email: oscar.gonzalezdedios@telefonica.com
 
Samier Barguil
Nokia
Madrid
Spain
Email: samier.barguil_giraldo@nokia.com
 
Qin Wu
Huawei
Yuhua District
101 Software Avenue
Nanjing
Jiangsu, 210012
China
Email: bill.wu@huawei.com
 
Victor Lopez
Nokia
Spain
Email: victor.lopez@nokia.com

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

nmalykh@protokols.ru


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

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

3Layer 3 Virtual Private Network — виртуальная частная сеть на сетевом уровне.

4Layer 2 Virtual Private Network — виртуальная частная сеть на канальном уровне.

5User-to-Network Interface, Network side — сетевая сторона интерфейса между пользователем и сетью.

6Traffic Engineering — организация (построение) трафика.

7Virtual eXtensible Local Area Network — виртуальная расширяемая ЛВС.

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

BTF

Формат BTF

PDF

Оригинал

1. Введение

BTF (BPF Type Format) — формат метаданных, представляющих отладочные сведения, связанные с программами и отображениями фильтров BPF. Изначально формат BTF служил для описания типов данных, а затем был расширен включением информации о функциях для определённых подпрограмм и сведений о строках в исходном коде.

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

Спецификация BTF состоит из двух частей:

  • API ядра;

  • формат файлов ELF.

API ядра — это соглашение между ядром и пользовательским пространством. Ядро проверяет BTF до применения. Формат ELF является соглашением пользовательского пространства между файлом ELF и загрузчиком libbpf.

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

2. Кодирование типов и строк BTF

В файле include/uapi/linux/btf.h приведено высокоуровневое определение кодирования типов и строк. Начало блока данных (blob) должно иметь вид

struct btf_header {
    __u16   magic;
    __u8    version;
    __u8    flags;
    __u32   hdr_len;

    /* Все смещения указаны в байтах от конца этого заголовка */
    __u32   type_off;       /* Смещение раздела типов      	*/
    __u32   type_len;       /* Размер раздела типов		*/
    __u32   str_off;        /* Смещение раздела строк      	*/
    __u32   str_len;        /* Размер раздела строк		*/
};

Поле magic имеет значение 0xeB9F, которое по разному представляется в системах с прямым (big-endian, от старшего к младшему) и обратным (little-endian, от младшего к старшему) порядком и может применяться при проверке генерации BTF для разных типов целевых систем. Заголовок btf_header предусматривает возможность расширения с помощью hdr_len = sizeof(struct btf_header) при генерации блобов (blob).

2.1 Кодирование строк

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

2.2 Кодирование типов

Идентификатор типа 0 зарезервирован для типа void. Раздел типов анализируется последовательно и идентификаторы назначаются каждому распознанному типу по порядку, начиная с 1. Поддерживаемые в настоящее время типы указаны ниже.

#define BTF_KIND_INT            1       /* Целое число	*/
#define BTF_KIND_PTR            2       /* Указатель      	*/
#define BTF_KIND_ARRAY          3       /* Массив        	*/
#define BTF_KIND_STRUCT         4       /* Структура       	*/
#define BTF_KIND_UNION          5       /* Объединение	*/
#define BTF_KIND_ENUM           6       /* Перечисляемые значения до 32 битов	*/
#define BTF_KIND_FWD            7       /* Forward      */
#define BTF_KIND_TYPEDEF        8       /* Определение типа	*/
#define BTF_KIND_VOLATILE       9       /* Переменная (Volatile)	*/
#define BTF_KIND_CONST          10      /* Константа	*/
#define BTF_KIND_RESTRICT       11      /* Ограничение	*/
#define BTF_KIND_FUNC           12      /* Функция		*/
#define BTF_KIND_FUNC_PROTO     13      /* Прототип функции	*/
#define BTF_KIND_VAR            14      /* Переменная     	*/
#define BTF_KIND_DATASEC        15      /* Раздел		*/
#define BTF_KIND_FLOAT          16      /* Число с плавающей запятой	*/
#define BTF_KIND_DECL_TAG       17      /* Тег объявления	*/
#define BTF_KIND_TYPE_TAG       18      /* Тег типа		*/
#define BTF_KIND_ENUM64         19      /* Перечисляемые значения до 64 битов	*/

Отметим, что раздел типов представляет отладочные сведения, а не просто типы, BTF_KIND_FUNC представляет не тип, а определённую подпрограмму.

Каждый тип включает указанные ниже общие данные.

struct btf_type {
    __u32 name_off;
    /* Набор информационных битов (info);
     * 0-15:  vlen (например, число элементов в структуре);
     * 16-23: не используются;
     * 24-28: тип (например, int, ptr, array и т. п.);
     * 29-30: не используются;
     * 31:    kind_flag, флаг типа, применяемый в настоящее время
     *        для STRUCT, UNION, FWD, ENUM и ENUM64.
     */
    __u32 info;
    /* Размер (size) используется INT, ENUM, STRUCT, UNION и ENUM64,
     * указывая размер описываемого типа.
     * Тип (type) используется PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
     * FUNC, FUNC_PROTO, DECL_TAG и TYPE_TAG, указывая type_id 
     * другого типа.
     */
    union {
            __u32 size;
            __u32 type;
    };
};

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

2.2.1 BTF_KIND_INT

name_off
-
любое допустимое смещение;
info.kind_flag
-
0;
info.kind
-
BTF_KIND_INT;
info.vlen
- 0;
size
-
размер в байтах, заданный целым числом (int).

После btf_type размещается поле u32 с показанной ниже структурой битов

#define BTF_INT_ENCODING(VAL)   (((VAL) & 0x0f000000) >> 24)
#define BTF_INT_OFFSET(VAL)     (((VAL) & 0x00ff0000) >> 16)
#define BTF_INT_BITS(VAL)       ((VAL)  & 0x000000ff)

BTF_INT_ENCODING представляет указанные ниже атрибуты

#define BTF_INT_SIGNED  (1 << 0)
#define BTF_INT_CHAR    (1 << 1)
#define BTF_INT_BOOL    (1 << 2)

BTF_INT_ENCODING() предоставляет дополнительные сведения о назначении типа int — наличие знака (signedness), char или bool. Кодирование char и bool полезно в основном для форматирования вывода. Для типа int можно указать не более одного назначения (кодировки).

BTF_INT_BITS() указывает фактическое число битов этого типа целого числа (int). Например, 4-битовое поле (bitfield) кодирует BTF_INT_BITS() = 4. Значение btf_type.size * 8 должно быть не меньше BTF_INT_BITS() для типа. Максимальное значение BTF_INT_BITS() составляет 128.

BTF_INT_OFFSET() указывает битовое смещение для расчёта значения этого целого числа. Например, элемент битовой структуры имеет:

  • смещение элемента btf от начала структуры — 100;
  • элемент btf указывает тип int;
  • тип int имеет BTF_INT_OFFSET() = 2 и BTF_INT_BITS() = 4.

Тогда в памяти структуры этот элемент будет занимать 4 бита, начиная с позиции 100 + 2 = 102.

Как вариант, для доступа к этому битовому полю можно использовать:

  • смещение элемента btf от начала структуры — 102;
  • элемент btf указывает тип int;
  • тип int имеет BTF_INT_OFFSET() = 0 и BTF_INT_BITS() = 4.

Исходным назначением BTF_INT_OFFSET() является обеспечение гибкости кодирования битовых полей. В настоящее время llvm и pahole генерируют BTF_INT_OFFSET() = 0 для всех типов int.

2.2.2 BTF_KIND_PTR

name_off — 0;
info.kind_flag — 0;
info.kind — BTF_KIND_PTR;
info.vlen — 0;
type — указатель.

После btf_type нет дополнительных данных.

2.2.3 BTF_KIND_ARRAY

name_off — 0;
info.kind_flag — 0;
info.kind — BTF_KIND_ARRAY;
info.vlen — 0;
size/type — 0, не используется.

После btf_type следует структура btf_array

struct btf_array {
    __u32   type;
    __u32   index_type;
    __u32   nelems;
};
type — тип элемента;
index_type — тип индекса;
nelems — число элементов в массиве (возможно, 0).

Поле index_type может иметь обычный целочисленный тип (u8, u16, u32, u64, unsigned __int128). Изначально index_type следовал DWARF, где имеется index_type для типа array. В настоящее время index_type применяется в BTF лишь для проверки типа.

Структура btf_array позволяет использовать цепочку типов элементов для создания многомерных массивов. Например, для int a[5][6] цепочку может представлять приведённая ниже информация о типах.

[1]: int
[2]: array, btf_array.type = [1], btf_array.nelems = 6 [3]: array, btf_array.type = [2], btf_array.nelems = 5

В настоящее время pahole и llvm сворачивают многомерные массивы в одномерные, например, для a[5][6] поле btf_array.nelems будет иметь значение 30. Это связано с тем, что первоначальным вариантом применения была печать отображения, где достаточно было выгрузки всего массива. По мере расширения применений BTF пакеты pahole и llvm могут быть изменены для генерации подобающего связанного представления многомерных массивов.

2.2.4 BTF_KIND_STRUCT и BTF_KIND_UNION

name_off — 0 или смещение действительного идентификатора C;
info.kind_flag — 0 или 1;
info.kind — BTF_KIND_STRUCT или BTF_KIND_UNION;
info.vlen — число элементов структуры или объединения;
info.size — размер структуры или объединения в байтах.

После btf_type следует info.vlen структур btf_member

struct btf_member {
    __u32   name_off;
    __u32   type;
    __u32   offset;
};
name_off — смещение действительного идентификатора C;
type — тип элемента;
offset — см. ниже.

Если флаг info.kind_flag не установлен (0), поле offset содержит лишь смещение элемента. Отметим, что базовым типом для битового поля может быть только int или enum. Если битовое поле имеет размер 32, базой может быть int или enum, при других размерах — только int и целочисленный тип BTF_INT_BITS() указывает размер битового поля.

При установленном (1) флаге kind_flag поле btf_member.offset содержит размер и смещение битового поля

#define BTF_MEMBER_BITFIELD_SIZE(val)   ((val) >> 24)
#define BTF_MEMBER_BIT_OFFSET(val)      ((val) & 0xffffff)

Если в этом случае базовым является тип int, это должно быть обычное целое число

BTF_INT_OFFSET() = 0.
BTF_INT_BITS() = {1, 2, 4, 8, 16} * 8.

Указанное ниже исправление (patch) в ядре добавляет kind_flag и разъясняет существование обоих режимов.

https://github.com/torvalds/linux/commit/9d5f9f701b1891466fb3dbb1806ad97716f95cc3#diff-fa650a64fdd3968396883d2fe8215ff3

2.2.6 BTF_KIND_ENUM

name_off — 0 или смещение действительного идентификатора C;
info.kind_flag — 0 для беззнакового, 1 для числа со знаком;
info.kind — BTF_KIND_ENUM
info.vlen — количество перечисляемых значений;
size — 1/2/4/8.

После btf_type следует info.vlen структур btf_enum

struct btf_enum {
    __u32   name_off;
    __s32   val;
};
name_off — смещение действительного идентификатора C;
val — любое значение.

Если исходное перечисляемое значение имеет знак и его размер меньше 4, значение будет расширено до 4 байтов (со знаком). Если размер равен 8, значение будет усечено до 4 байтов.

2.2.7 BTF_KIND_FWD

name_off — смещение действительного идентификатора C;
info.kind_flag — 0 для struct, 1 для union;
info.kind — BTF_KIND_FWD;
info.vlen — 0;
type — 0.

После btf_type нет дополнительных данных.

2.2.8 BTF_KIND_TYPEDEF

name_off — смещение действительного идентификатора C;
info.kind_flag — 0;
info.kind — BTF_KIND_TYPEDEF;
info.vlen — 0;
type — тип, который можно указать именем, заданным со смещением name_off.

После btf_type нет дополнительных данных.

2.2.9 BTF_KIND_VOLATILE

name_off — 0;
info.kind_flag — 0;
info.kind — BTF_KIND_VOLATILE;
info.vlen — 0;
type — тип с изменяемым классификатором.

После btf_type нет дополнительных данных.

2.2.10 BTF_KIND_CONST

name_off — 0;
info.kind_flag — 0;
info.kind — BTF_KIND_CONST
info.vlen — 0;
type — тип с постоянным классификатором.

После btf_type нет дополнительных данных.

2.2.11 BTF_KIND_RESTRICT

name_off — 0;
info.kind_flag — 0;
info.kind — BTF_KIND_RESTRICT;
info.vlen — 0;
type — тип с ограничительным классификатором.

После btf_type нет дополнительных данных.

2.2.12 BTF_KIND_FUNC

name_off — смещение действительного идентификатора C;
info.kind_flag — 0;
info.kind — BTF_KIND_FUNC;
info.vlen — компоновочные сведения (BTF_FUNC_STATIC, BTF_FUNC_GLOBAL или BTF_FUNC_EXTERN);
type — тип BTF_KIND_FUNC_PROTO.

После btf_type нет дополнительных данных.

BTF_KIND_FUNC определяет не тип, а подпрограмму (функцию), подпись которой определяет тип. Подпрограмма является экземпляром этого типа. На BTF_KIND_FUNC может указывать func_info в (ELF) или аргументы (ABI).

В настоящее время ядро поддерживает только привязки BTF_FUNC_STATIC и BTF_FUNC_GLOBAL.

2.2.13 BTF_KIND_FUNC_PROTO

name_off — 0;
info.kind_flag — 0;
info.kind — BTF_KIND_FUNC_PROTO;
info.vlen — число параметров;
type — тип возвращаемого значения.

После btf_type следует info.vlen структур btf_param

struct btf_param {
    __u32   name_off;
    __u32   type;
};

Если BTF_KIND_FUNC_PROTO указывается типом BTF_KIND_FUNC, поле btf_param.name_off должно указывать действительный идентификатор C, за исключением, возможно, последнего аргумента, представляющего переменную. Поле btf_param.type указывает тип параметра.

Если функция имеет переменное число аргументов, последний параметр кодируется с name_off = 0 и type = 0.

2.2.14 BTF_KIND_VAR

name_off — смещение действительного идентификатора C;
info.kind_flag — 0;
info.kind — BTF_KIND_VAR;
info.vlen — 0;
type — тип переменной.

После btf_type следует 1 структура btf_variable

struct btf_var {
    __u32   linkage;
};

В структуре btf_var элемент linkage может указывать статическую переменную (0) или глобальную переменную в разделах ELF (1)

В настоящее время LLVM поддерживает не все типы глобальных переменных, а лишь:

  • статические переменные с атрибутами раздела или без них;
  • глобальные переменные с атрибутами раздела.

Последний вариант предназначен для будущего извлечения идентификаторов типа «ключ-значение» из определения сопоставлений.

2.2.15 BTF_KIND_DATASEC

name_off — смещение действительного имени, связанного с переменной или одним из .data/.bss/.rodata;
info.kind_flag — 0;
info.kind — BTF_KIND_DATASEC;
info.vlen — число переменных;
size — общий размер раздела в байтах (0 во время компиляции, заменяется фактическим значением загрузчиками BPF, такими как libbpf).

После btf_type следует info.vlen структур btf_var_secinfo

struct btf_var_secinfo {
    __u32   type;
    __u32   offset;
    __u32   size;
};
type — тип переменной BTF_KIND_VAR;
offset — смещение переменной в разделе;
size — размер переменной в байтах.

2.2.16 BTF_KIND_FLOAT

name_off — любое действительное смещение;
info.kind_flag — 0;
info.kind — BTF_KIND_FLOAT;
info.vlen — 0;
size — размер типа float в байтах (2, 4, 8, 12 или 16).

После btf_type нет дополнительных данных.

2.2.17 BTF_KIND_DECL_TAG

name_off — смещение непустой строки;
info.kind_flag — 0;
info.kind — BTF_KIND_DECL_TAG;
info.vlen — 0;
type — struct, union, func, var или typedef.

После btf_type следует структура btf_decl_tag

struct btf_decl_tag {
    __u32   component_idx;
};

Поле name_off указывает строку атрибута btf_decl_tag, которая может иметь тип struct, union, func, var или typedef. Для типа var или typedef должно устанавливаться btf_decl_tag.component_idx = -1. Для трёх оставшихся типов устанавливается -1, если атрибут btf_decl_tag применяется непосредственно к struct, union или func. В ином случае атрибут применяется к элементу struct или union или аргументу функции и в поле btf_decl_tag.component_idx следует указывать фактический индекс (начиная с 0) элемента или аргумента.

2.2.18 BTF_KIND_TYPE_TAG

name_off — смещение непустой строки;
info.kind_flag — 0;
info.kind — BTF_KIND_TYPE_TAG;
info.vlen — 0;
type — тип с атрибутом btf_type_tag.

В настоящее время BTF_KIND_TYPE_TAG создаётся лишь для указательных типов и имеет цепочку типов

ptr -> [type_tag]*
    -> [const | volatile | restrict | typedef]*
    -> base_type

Тип pointer фактически может указывать на несколько (включая 0) type_tag, затем (необязательно) на const, volatile, restrict, typedef и в конце на базовый тип, которым может служить int, ptr, array, struct, union, enum, func_proto или float.

2.2.19 BTF_KIND_ENUM64

name_off — 0 или смещение действительного идентификатора C;
info.kind_flag — 0 для беззнакового, 1 для числа со знаком;
info.kind — BTF_KIND_ENUM64;
info.vlen — число перечисляемых (enum) значений;
size — 1, 2, 4 или 8.

После btf_type следует info.vlen структур btf_enum64

struct btf_enum64 {
    __u32   name_off;
    __u32   val_lo32;
    __u32   val_hi32;
};
name_off — смещение действительного идентификатора C;
val_lo32 — 32 младших бита 64-битового значения;
val_hi32 — 32 старших бита 64-битового
значения.

Если исходное значение enum имеет знак и его размер меньше 8, значение расширяется до 8 байтов (со знаком).

3. API ядра

Ниже указаны системные вызовы bpf, использующие BTF

  • BPF_BTF_LOAD — загрузка блока данных (blob) BTF в ядро.
  • BPF_MAP_CREATE — создание отображения с ключом btf и информацией о типе значения.
  • BPF_PROG_LOAD — загрузка программы с функцией btf и информацией о строке.
  • BPF_BTF_GET_FD_BY_ID — получение файлового дескриптора btf.
  • BPF_OBJ_GET_INFO_BY_FD — возврат btf, func_info, line_info и других сведений, относящихся к btf.

Типичный рабочий процесс показан ниже.

Приложение

    BPF_BTF_LOAD
        |
        v
    BPF_MAP_CREATE и BPF_PROG_LOAD
        |
        V
    ......

Инструмент самоанализа

    ......
    BPF_{PROG,MAP}_GET_NEXT_ID (get prog/map id)
        |
        V
    BPF_{PROG,MAP}_GET_FD_BY_ID (get a prog/map fd)
        |
        V
    BPF_OBJ_GET_INFO_BY_FD (get bpf_prog_info/bpf_map_info с btf_id)
        |                                     |
        V                                     |
    BPF_BTF_GET_FD_BY_ID (get btf_fd)         |
        |                                     |
        V                                     |
    BPF_OBJ_GET_INFO_BY_FD (get btf)          |
        |                                     |
        V                                     V
    Типы для красивого вывода, дампов подписей функций, сведений о строках и т. п.

3.1 BPF_BTF_LOAD

Загружает blob данных BTF в ядро. Блок данных, описанный в разделе , можно напрямую загрузить в ядро. В пользовательское пространство возвращается файловый дескриптор btf_fd.

3.2 BPF_MAP_CREATE

Отображение может быть создано с btf_fd и заданной парой «ключ-значение» для идентификатора типа

__u32   btf_fd;         	/* fd указывает тип данных BTF */
__u32   btf_key_type_id;     	/* BTF type_id для ключа */
__u32   btf_value_type_id;   	/* BTF type_id для значения */

В libbpf отображение может быть задано с дополнительной аннотацией, как показано ниже.

struct {
    __uint(type, BPF_MAP_TYPE_ARRAY);
    __type(key, int);
    __type(value, struct ipv_counts);
    __uint(max_entries, 4);
} btf_map SEC(".maps");

При синтаксическом анализе ELF libbpf может извлекать идентификаторы типа «ключ-значение» и автоматически назначить их атрибутам BPF_MAP_CREATE.

3.3 BPF_PROG_LOAD

При загрузке программы (prog_load) можно передать в ядро func_info и line_info с подобающими значениями указанных ниже атрибутов.

__u32           insn_cnt;
__aligned_u64   insns;
......
__u32           prog_btf_fd;    	/* fd с указанием типа данных BTF */
__u32           func_info_rec_size;	/* Размер bpf_func_info в пользовательском пространстве */
__aligned_u64   func_info;      	/* Сведения о функции */
__u32           func_info_cnt;  	/* Число записей bpf_func_info */
__u32           line_info_rec_size;	/* Размер bpf_line_info в пользовательском пространстве */
__aligned_u64   line_info;      	/* Сведения о строке */
__u32           line_info_cnt;  	/* Число записей bpf_line_info */

Элементы func_info и line_info являются массивами, как показано ниже.

struct bpf_func_info {
    __u32   insn_off; /* [0, insn_cnt - 1] */
    __u32   type_id;  /* Указывает тип BTF_KIND_FUNC */
};
struct bpf_line_info {
    __u32   insn_off; 		/* [0, insn_cnt - 1] */
    __u32   file_name_off; 	/* Смещение имени файла в таблице строк */
    __u32   line_off; 		/* Смещение строки исходного текста в таблице строк */
    __u32   line_col; 		/* Номер строки и позиция в ней */
};

Поле func_info_rec_size указывает размер записи func_info, а line_info_rec_size — размер каждой записи line_info. Передача размера записи в ядро позволяет позднее извлечь саму запись.

Ниже указаны требования к func_info
func_info[0].insn_off = 0;
значения func_info.insn_off строго возрастают по порядку и соответствуют границам функции bpf.
Ниже указаны требования к line_info:
первый элемент insn в каждой функции должен иметь запись line_info, указывающую на него;
line_info.insn_off строго возрастают по порядку.

Для line_info номера строк и позиций определяются, как показано ниже

#define BPF_LINE_INFO_LINE_NUM(line_col)        ((line_col) >> 10)
#define BPF_LINE_INFO_LINE_COL(line_col)        ((line_col) & 0x3ff)

3.4 BPF_{PROG,MAP}_GET_NEXT_ID

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

Команды системных вызовов bpf BPF_{PROG,MAP}_GET_NEXT_ID возвращают в пользовательское пространство все идентификаторы (по 1 на команду) программ или отображений bpf, чтобы инструменты могли проверить все программы и отображения.

3.5 BPF_{PROG,MAP}_GET_FD_BY_ID

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

3.6 BPF_OBJ_GET_INFO_BY_FD

После получения дескриптора программы или отображения инструмент самоанализа может получить от ядра подробные сведения, часть которых относится к BTF. Например, bpf_map_info возвращает btf_id и «ключ-значение» для идентификаторов типа, а bpf_prog_info возвращает btf_id, func_info и сведения о строке для оттранслированного байт-кода bpf, а также jited_line_info.

3.7 BPF_BTF_GET_FD_BY_ID

С помощью btf_id, полученного в bpf_map_info или bpf_prog_info системный вызов bpf BPF_BTF_GET_FD_BY_ID может извлечь файловый дескриптор btf. Затем с помощью команды BPF_OBJ_GET_INFO_BY_FD можно получить btf blob, исходно загруженный в ядро с помощью BPF_BTF_LOAD. С btf blob, bpf_map_info и bpf_prog_info инструмент самоанализа получает полные сведения о btf и может обеспечить красивый вывод пар «ключ-значение», дампов подписей функций и сведений о строка вместе с кодами byte/jit.

4. Формат файлов ELF

4.1 Раздел .BTF

Раздел .BTF содержит сведения о типах и строках в формате, описанном в .

4.2 Раздел .BTF.ext

Раздел .BTF.ext кодирует func_info и line_info, которые загрузчик должен обрабатывать перед отправкой в ядро. Спецификация раздела .BTF.ext задана в файлах tools/lib/bpf/btf.h и tools/lib/bpf/btf.c.

Ниже показан текущий заголовок раздела .BTF.ext.

struct btf_ext_header {
    __u16   magic;
    __u8    version;
    __u8    flags;
    __u32   hdr_len;

    /* Все смещения указаны в байтах от конца этого заголовк */
    __u32   func_info_off;
    __u32   func_info_len;
    __u32   line_info_off;
    __u32   line_info_len;
};

Это очень похоже на раздел .BTF, но вместо типов и строк этот раздел содержит записи func_info и line_info, формат которых описан в параграфе .

Организация func_info показана ниже.

func_info_rec_size
btf_ext_info_sec /* func_info для раздела 1 */
btf_ext_info_sec /* func_info для раздела 2 */
...

Поле func_info_rec_size задаёт размер структуры bpf_func_info при генерации .BTF.ext, а показанная ниже структура btf_ext_info_sec является набором func_info для каждого конкретного раздела ELF.

struct btf_ext_info_sec {
   __u32   sec_name_off; /* Смещение имени раздела */
   __u32   num_info;
   /* Далее следует num_info * record_size байтов */
   __u8    data[0];
};

Поле num_info должно быть больше 0. Организация line_info показана ниже.

line_info_rec_size
btf_ext_info_sec /* line_info для раздела 1 */
btf_ext_info_sec /* line_info для раздела 2 */
...

Поле line_info_rec_size указывает размер структуры bpf_line_info при генерации .BTF.ext.

Интерпретация bpf_func_info->insn_off и bpf_line_info->insn_off различается в API ядра и ELF API. Для API ядра insn_off указывает смещение инструкции в структурах bpf_insn. Для ELF API поле insn_off указывает смещение в байтах от начала раздела (btf_ext_info_sec->sec_name_off).

4.2 Раздел .BTF_ids

Раздел .BTF_ids кодирует значения BTF ID, которые используются в ядре. Раздел создаётся при компиляции ядра с помощью макросов, заданных в заголовочном файле include/linux/btf_ids.h. Затем код ядра может использоваться для создания списков и наборов (сортированных списков) значений BTF ID.

Макросы BTF_ID_LIST и BTF_ID определяют несортированный список значений BTF ID, как показано ниже.

BTF_ID_LIST(list)
BTF_ID(type1, name1)
BTF_ID(type2, name2)

Это даёт показанную ниже схему раздела .BTF_ids.

__BTF_ID__type1__name1__1:
.zero 4
__BTF_ID__type2__name2__2:
.zero 4

Определена переменная u32 list[] для доступа к списку.

Макрос BTF_ID_UNUSED определяет 4 нулевых байта, которые служат для задания в списке BTF_ID_LIST неиспользуемой записи, как показано ниже.

BTF_ID_LIST(bpf_skb_output_btf_ids)
BTF_ID(struct, sk_buff)
BTF_ID_UNUSED
BTF_ID(struct, task_struct)

Макросы BTF_SET_START и BTF_SET_END определяют сортированный список значений BTF ID и их числа, как показано ниже.

BTF_SET_START(set)
BTF_ID(type1, name1)
BTF_ID(type2, name2)
BTF_SET_END(set)

Это даёт показанную ниже схему раздела .BTF_ids.

__BTF_ID__set__set:
.zero 4
__BTF_ID__type1__name1__3:
.zero 4
__BTF_ID__type2__name2__4:
.zero 4

Определена структура btf_id_set set для доступа к этому списку.

В качестве имени typeX может использоваться struct, union, typedef, func и это служит фильтром при извлечении значения BTF ID.

Все списки и наборы BTF ID компилируются в раздел .BTF_ids и распознаются на этапе компоновки при сборке ядра с помощью инструмента resolve_btfids.

5. Применение BTF

5.1 Красивый вывод отображений с помощью bpftool

С помощью BTF отображения !ключ-значение! Можно выводить по полям, а не в форме необработанных байтов. Это особенно полезно для больших структур и структур с битовыми полями, например, для приведённого сопоставления.

enum A { A1, A2, A3, A4, A5 };
typedef enum A ___A;
struct tmp_t {
     char a1:4;
     int  a2:4;
     int  :4;
     __u32 a3:4;
     int b;
     ___A b1:4;
     enum A b2:4;
};
struct {
     __uint(type, BPF_MAP_TYPE_ARRAY);
     __type(key, int);
     __type(value, struct tmp_t);
     __uint(max_entries, 1);
} tmpmap SEC(".maps");

Команда bpftool позволяет вывести его в форме

[{
      "key": 0,
      "value": {
          "a1": 0x2,
          "a2": 0x4,
          "a3": 0x6,
          "b": 7,
          "b1": 0x8,
          "b2": 0xa
      }
  }
]

5.2 Дамп программы с помощью bpftool

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

$ bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
[...]
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_44a040bf25481309_test_long_fname_2:
; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
   0:   push   %rbp
   1:   mov    %rsp,%rbp
   4:   sub    $0x30,%rsp
   b:   sub    $0x28,%rbp
   f:   mov    %rbx,0x0(%rbp)
  13:   mov    %r13,0x8(%rbp)
  17:   mov    %r14,0x10(%rbp)
  1b:   mov    %r15,0x18(%rbp)
  1f:   xor    %eax,%eax
  21:   mov    %rax,0x20(%rbp)
  25:   xor    %esi,%esi
; int key = 0;
  27:   mov    %esi,-0x4(%rbp)
; if (!arg->sock)
  2a:   mov    0x8(%rdi),%rdi
; if (!arg->sock)
  2e:   cmp    $0x0,%rdi
  32:   je     0x0000000000000070
  34:   mov    %rbp,%rsi
; counts = bpf_map_lookup_elem(&btf_map, &key);
[...]

5.3 Журнал проверки

Ниже показано, как line_info может помочь при отладке.

   /* Код tools/testing/selftests/bpf/test_xdp_noinline.c изменён,
    * как показано ниже.
    */
   data = (void *)(long)xdp->data;
   data_end = (void *)(long)xdp->data_end;
   /*
   if (data + 4 > data_end)
           return XDP_DROP;
   */
   *(u32 *)data = dst->dst;

$ bpftool prog load ./test_xdp_noinline.o /sys/fs/bpf/test_xdp_noinline type xdp
    ; data = (void *)(long)xdp->data;
    224: (79) r2 = *(u64 *)(r10 -112)
    225: (61) r2 = *(u32 *)(r2 +0)
    ; *(u32 *)data = dst->dst;
    226: (63) *(u32 *)(r2 +0) = r1
    invalid access to packet, off=0 size=4, R2(id=0,off=0,r=0)
    R2 offset is outside of the packet

6. Генерация BTF

Сначала нужно установить pahole или llvm (8.0 или выше). Программа pahole служит конвертером dwarf в btf и пока не поддерживает .BTF.ext и тип BTF_KIND_FUNC. Например,

-bash-4.4$ cat t.c
struct t {
  int a:2;
  int b:3;
  int c:2;
} g;
-bash-4.4$ gcc -c -O2 -g t.c
-bash-4.4$ pahole -JV t.o

Файл t.o:

[1] STRUCT t kind_flag=1 size=4 vlen=3
        a type_id=2 bitfield_size=2 bits_offset=0
        b type_id=2 bitfield_size=3 bits_offset=2
        c type_id=2 bitfield_size=2 bits_offset=5
[2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED

Пакет llvm может генерировать .BTF и .BTF.ext напрямую с опцией -g лишь для цели bpf. Опция ассемблера (-S) позволяет представить кодирование BTF в формате ассемблера.

-bash-4.4$ cat t2.c
typedef int __int32;
struct t2 {
  int a2;
  int (*f2)(char q1, __int32 q2, ...);
  int (*f3)();
} g2;
int main() { return 0; }
int test() { return 0; }
-bash-4.4$ clang -c -g -O2 -target bpf t2.c
-bash-4.4$ readelf -S t2.o
  ......
  [ 8] .BTF              PROGBITS         0000000000000000  00000247
       000000000000016e  0000000000000000           0     0     1
  [ 9] .BTF.ext          PROGBITS         0000000000000000  000003b5
       0000000000000060  0000000000000000           0     0     1
  [10] .rel.BTF.ext      REL              0000000000000000  000007e0
       0000000000000040  0000000000000010          16     9     8
  ......
-bash-4.4$ clang -S -g -O2 -target bpf t2.c
-bash-4.4$ cat t2.s
  ......
        .section        .BTF,"",@progbits
        .short  60319                   # 0xeb9f
        .byte   1
        .byte   0
        .long   24
        .long   0
        .long   220
        .long   220
        .long   122
        .long   0                       # BTF_KIND_FUNC_PROTO(id = 1)
        .long   218103808               # 0xd000000
        .long   2
        .long   83                      # BTF_KIND_INT(id = 2)
        .long   16777216                # 0x1000000
        .long   4
        .long   16777248                # 0x1000020
  ......
        .byte   0                       # string offset=0
        .ascii  ".text"                 # string offset=1
        .byte   0
        .ascii  "/home/yhs/tmp-pahole/t2.c" # string offset=7
        .byte   0
        .ascii  "int main() { return 0; }" # string offset=33
        .byte   0
        .ascii  "int test() { return 0; }" # string offset=58
        .byte   0
        .ascii  "int"                   # string offset=83
  ......
        .section        .BTF.ext,"",@progbits
        .short  60319                   # 0xeb9f
        .byte   1
        .byte   0
        .long   24
        .long   0
        .long   28
        .long   28
        .long   44
        .long   8                       # FuncInfo
        .long   1                       # FuncInfo section string offset=1
        .long   2
        .long   .Lfunc_begin0
        .long   3
        .long   .Lfunc_begin1
        .long   5
        .long   16                      # LineInfo
        .long   1                       # LineInfo section string offset=1
        .long   2
        .long   .Ltmp0
        .long   7
        .long   33
        .long   7182                    # Line 7 Col 14
        .long   .Ltmp3
        .long   7
        .long   58
        .long   8206                    # Line 8 Col 14

7. Тестирование

Программа самотестирования BPF в ядре (tools/testing/selftests/bpf/prog_tests/btf.c) обеспечивает широкий набор связанных с BTF тестов.


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

nmalykh@protokols.ru


1Just In Time — «на лету», код, создаваемый в процессе исполнения.

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

RFC 9407 Tetrys: An On-the-Fly Network Coding Protocol

Internet Research Task Force (IRTF)                          J. Detchart
Request for Comments: 9407                                  ISAE-SUPAERO
Category: Experimental                                         E. Lochin
ISSN: 2070-1721                                                     ENAC
                                                                J. Lacan
                                                            ISAE-SUPAERO
                                                                 V. Roca
                                                                   INRIA
                                                               June 2023

Tetrys: An On-the-Fly Network Coding Protocol

Tetrys — протокол сетевого кодирования «на лету»

PDF

Аннотация

Этот документ описывает Tetrys — протокол сетевого кодирования «на лету» (on-the-fly), который можно применять для чувствительной к задержкам и потерям доставки через сеть с потерями. Tetrys может восстанавливаться после удаления данных с независимой от RTT задержкой, благодаря передаче кодированных пакетов. Этот документ представляет отчёт о результатах, полученных автором в процессе разработки и тестирования протокола Tetrys в реальных условиях.

Документ является результатом исследовательской группы NWCRG1 и соответствует таксономии NWCRG, описанной в RFC 8406.

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

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

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

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

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

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

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

1. Введение

Этот документ является результатом работы исследовательской группы NWCRG и выражает её согласованное мнение. Документ не является результатом или стандартом IETF.

Документ описывает протокол Tetrys выполняющий сетевое кодирование на лету, который может служить для доставки чувствительных к задержкам и потерям данных через сеть с потерями. Сетевые коды появились в начале 2000-х гг. [AHL-00] и служили для снятия ограничений при передаче через Internet (задержки, пропускная способность, потери пакетов). Хотя сетевые коды получили сравнительно малое распространение в сообществе Internet, использование кодов удаления на уровне приложений уже стандартизовано в рамках IETF рабочими группами RMT [RFC5052] [RFC5445] и FECFRAME [RFC8680]. Представленный здесь протокол можно считать расширением сетевого кодирования на стандартные протоколы индивидуального (unicast) транспорта, а в некоторых случаях также группового и anycast. Текущее предложение можно рассматривать как комбинацию сетевого кодирования стирания и механизмов обратной связи [Tetrys] [Tetrys-RT].

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

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

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

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

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

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

2. Определения, обозначения и сокращения

Используемые в документе обозначения основаны на таксономии NWCRG [RFC8406].

Source Symbol — символ источника

Символ, переносимый между входом и выходом сети.

Coded Symbol — кодированный символ

Линейная комбинация над конечным полем набора символов источника.

Source Symbol ID — идентификатор символа источника

Порядковый номер для идентификации символов источника.

Coded Symbol ID — идентификатор кодированного символа

Порядковый номер для идентификации кодированных символов.

Encoding Coefficients — коэффициенты кодирования

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

Encoding Vector — вектор кодирования

Набор коэффициентов кодирования и идентификаторов входных символов источника.

Source Packet — пакет источника

Пакет источника содержит символы источника с их идентификаторами.

Coded Packet — кодированный пакет

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

Input Symbol — входной символ

Символ на входе кодировщика Tetrys.

Output Symbol — выходной символ

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

Feedback Packet — пакет обратной связи

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

Elastic Encoding Window — эластичное окно кодирования

Буфер на стороне кодера, где хранятся все неподтвержденные пакеты источника из входного потока, вовлечённого в процесс кодировани.

Coding Coefficient Generator Identifier (CCGI) — идентификатор генератора коэффициентов кодирования

Уникальный идентификатор, который указывает функцию или алгоритм, разрешающие генерацию вектора кодирования.

Code Rate — степень кодирования

Отношение между числом входных и выходных символов.

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

3.1. Применение

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

3.2. Обзор

+----------+                +----------+
|          |                |          |
|Приложение|                |Приложение|
|          |                |          |
+----------+                +----------+
      |                           ^
      |  Символы          Символы |
      |  источника      источника |
      |                           |
      v                           |
+----------+                +----------+
|          | Выходные пакеты|          |
|  Кодер   |--------------->| Декодер  |
|  Tetrys  | Пакеты откликов| Tetrys   |
|          |<---------------|          |
+----------+                +----------+

Рисунок . Архитектура Tetrys.


Протокол Tetrys обладает несколькими важными функциональными возможностями. Обязательные функции включают:

  • кодирование «на лету»;

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

  • сигнализация для доставки, в частности, идентификаторов символов о окне кодирования и связанных коэффициентов кодирования, когда это значимо;

  • управления обратной связью;

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

  • создание и обработка заголовков Tetrys.

Необязательные функции включают:

  • оценку канала;

  • динамическую подстройку степени кодирования (code rate) и управление потоком данных;

  • управление контролем перегрузок, когда это приемлемо ().

Функциональность обеспечивается несколькими основными блоками.

Tetrys Building Block — блок Tetrys

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

Window Management Building Block — блок управления окном

Управляет окном кодирования у отправителя Tetrys.

Для упрощения добавления новых компонентов и служб в Tetrys включён механизм расширения заголовка, совместимый с транспортом многоуровневого кодирования (Layered Coding Transport или LCT) [RFC5651], ориентированной на негативные подтверждения надёжной групповой передачей (NACK-Oriented Reliable Multicast или NORM) [RFC5740] и моделью упреждающей коррекции ошибок (FEC Framework или FECFRAME) [RFC8680].

4. Базовые функции Tetrys

4.1. Кодирование

В начале передачи кодер Tetrys должен выбрать степень кодирования (code rate) для добавления избыточности, поскольку он не знает частоту потери пакетов в канале. В установившемся состоянии кодер Tetrys может генерировать кодированные символы при получении символов источника от приложения или какого-либо отклика от блоков декодирования в зависимости от степени кодирования.

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

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

4.2. Эластичное окно кодирования

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

Как разъяснено ниже, декодер Tetrys периодически передаёт отклики, указывающие принятые или декодированные символы источника. При получении отправителем сведений о приёме или декодировании получателем символа источника он удаляет этот символ из окна кодирования.

4.3. Декодирование

Для восстановления удалённого символа источника достаточно стандартного исключения по Гауссу, когда это позволяет ранг матрицы.

5. Формат пакетов

5.1. Формат базового заголовка

Все пакеты Tetrys используют общий формат базового заголовка ().

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   V   | C |S|     Reserved    |   HDR_LEN     |    PKT_TYPE   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Congestion Control Information (CCI, размер = 32*C битов)   |
|                          ...                                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Transport Session Identifier (TSI, размер = 32*S битов)    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             Расширения заголовка (если применимо)             |
|                          ...                                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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


Как отмечено выше, этот формат наследуется из формата заголовка LCT [RFC5651] с незначительными изменениями.

Номер версии Tetrys (V) — 4 бита

Указывает номер версии протокола Tetrys. Эта спецификация Tetrys задаёт версию 1.

Флаг контроля перегрузок (C) — 2 бита

Значение C = 0b00 указывает, что поле сведений контроля перегрузки (Congestion Control Information или CCI) имеет размер 0. C = 0b01 указывает, что поле CCI имеет размер 32 бита, C = 0b10 указывает CCI размером 64 бита, а C = 0b11 — 96 битов.

Флаг идентификатора транспортной сессии (S) — 1 бит

Число полных 32-битовых слов в поле TSI (0 или 1).

Reserved (Resv) — 9 битов

резервные биты, которые отправитель должен сбрасывать (0), а получатель должен игнорировать.

Размер заголовка (HDR_LEN) — 8 битов

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

Тип пакета Tetrys (PKT_TYPE) — 8 битов

Имеется 3 типа пакетов — PKT_TYPE_SOURCE (0b00), параграф 5.2, PKT_TYPE_CODED (0b01), параграф 5.3, и PKT_TYPE_WND_UPT (0b11) для пакетов обновления окна, параграф 5.4.

Congestion Control Information — сведения контроля перегрузки (CCI) — 0, 32, 64 или 96 битов

Служит для передачи сведения о контроле перегрузки и может включать, например, номера уровней, логических каналов и порядковые номера. Данная спецификация не задаёт обработку этого поля (opaque). Поле должно отсутствовать (о битов) при C = 0b00 и должно занимать 32 бита при C = 0b01, 64 — при C = 0b10, 96 — при C = 0b11.

Transport Session Identifier — идентификатор транспортной сессии (TSI) — 0 или 32 бита

TSI однозначно указывает сессию среди имеющихся с конкретным кодером Tetrys. Область действия TSI определяется IP-адресом отправителя, поэтому адрес отправителя и TSI совместно указывают сессию однозначно. Хотя TSI всегда однозначно указывает сессию совместно с IP-адресом отправителя, включение TSI в заголовок Tetrys зависит от того, что применяется в качестве значения TSI. Если базовым транспортом служит UDP, вместо TSI для сессии может служить 16-битовый номер порта UDP у отправителя. Если сетевой транспорт или иной уровень не задаёт базовый идентификатор TSI, значение TSI должно включаться в заголовок Tetrys.

5.1.1. Расширения заголовка

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

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

Имеется два формата расширений заголовка, показанных на рисунке .

  • Первый формат служит для расширений переменного размера с типами расширения заголовка (header extension type или HET) от 0 до 127.

  • Второй тип служит для расширений фиксированного размера (1 слово в 32 бита), использующих HET от 128 до 255.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  HET (<=127)  |       HEL     |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
.                                                               .
.              Header Extension Content (HEC)                   .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  HET (>=128)  |       Header Extension Content (HEC)          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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


Тип расширения заголовка (HET) — 8 битов

Этот документ задаёт несколько возможных типов, а новые типы могут вноситься будущими версиями спецификации. Значения HET от 0 до 127 служат для расширений заголовка с переменным размером, от 128 до 255 — для расширений заголовка размером 32 бита.

Размер расширения заголовка (HEL) — 8 битов

Число 32-битовых слов в расширении заголовка. Это поле должно присутствовать в расширениях переменного размера (HET от 0 до 127) и его недопустимо включать в расширения фиксированного размера (HET от 128 до 255).

Header Extension Content — содержимое расширения заголовка (HEC) — переменный размер

Содержимое расширения заголовка, формат которого зависит от типа расширения. Для расширений заголовка с фиксированным размером HEC = 24, для расширений переменного размера значение HEC указывает переменный размер, как задано полем HEL. Отметим, что размер расширения заголовка должен быть кратным 32 битам. Общий размер заголовка Tetrys, включая заголовок расширения и его необязательные поля, не может превышать 255 (32-битовых слов).

5.2. Формат пакета источника

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

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                      Common Packet Header                     /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Source Symbol ID                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                            Payload                            /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок . Формат пакета источника.


Common Packet Header

Базовый заголовок пакета, где указан тип 0b00.

Source Symbol ID

Порядковый номер символа источника.

Payload

Содержимое пакет (символ источника).

5.3. Формат кодированного пакета

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

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                      Common Packet Header                     /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Coded Symbol ID                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                         Encoding Vector                       /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Encoded Payload Size      |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
|                                                               |
/                            Payload                            /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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


Common Packet Header

Базовый заголовок пакета с типом 0b01.

Coded Symbol ID

Порядковый номер для идентификации кодированного символа.

Encoding Vector

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

Encoded Payload Size

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

Payload

Кодированный символ.

5.3.1. Вектор кодирования

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

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     EV_LEN    |  CCGI | I |C|V|    NB_IDS     |   NB_COEFS    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        FIRST_SOURCE_ID                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     b_id      |                                               |
+-+-+-+-+-+-+-+-+            id_bit_vector        +-+-+-+-+-+-+-+
|                                                 |   Padding   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                          coef_bit_vector        +-+-+-+-+-+-+-+
|                                                 |   Padding   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Рисунок . Формат вектора кодирования.


Размер вектора кодирования (EV_LEN) — 8 битов

Число 32-битовых слов.

Идентификатор генератора коэффициентов кодирования (CCGI) — 4 бита

Идентификатор для указания алгоритма или функции, применяемой для генерации коэффициентов. Поскольку CCGI включается в каждый кодированный вектор, значение может динамически меняться между генерацией двух кодированных символов. CCGI задают создание коэффициентов для генерации кодированных символов и должны быть известны всем кодерам и декодерам Tetrys. Заданные в этом документе две схемы RLC FEC используют конечные поля, определённые в параграфе 8.1 [RFC5510]. Элементы поля GF(2(m)) представлены полиномами с двоичными коэффициентами (т. е. над GF(2)) со степенью не выше m-1. Сложение двух элементов определяется как сложение двоичных полиномов в GF(2), которое эквивалентно побитовой операции XOR над двоичными представлениями этих элементов. При GF(2(8)) перемножение двух элементов является умножением по модулю данного неприводимого полинома степени 8. Для GF(2(8)) применяется неприводимый полином
         x(8) + x(4) + x(3) + x(2) + 1
При GF(2(4)) перемножение двух элементов является умножением по модулю данного неприводимого полинома степени . Для GF(2(4)) применяется неприводимый полином
         x(4) + x + 1
  • 0b00 — коэффициенты Vandermonde над конечным полем GF(2(4)) в виде alpha((source_symbol_id*coded-symbol_id) % 16), где alpha — корень примитивного полинома;
  • 0b01 — коэффициенты Vandermonde над конечным полем GF(2(8)) в виде alpha((source_symbol_id*coded-symbol_id) % 256), где alpha — корень примитивного полинома;
  • Предположим, что нужно создать кодированный символ 2 как линейную комбинацию символов 1, 2 и 4 с использованием CCGI = 0b01. Коэффициентами будут alpha((1 * 1) % 256), alpha((1 * 2) % 256) и alpha((1 * 4) % 256).

Формат хранения идентификаторов символов источника (I) — 2 бита

  • 0b00 — нет сведений об идентификаторе символа источника;
  • 0b01 — вектор кодирования содержит граничные блоки идентификаторов символов источника без сжатия;
  • 0b10 — вектор кодирования содержит сжатый список идентификаторов символов источника;
  • 0b11 — вектор кодирования содержит сжатые граничные блоки идентификаторов символов источника.

Хранение коэффициентов кодирования (C) — 1 бит

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

Наличие символов источника с кодированием переменного размера (V)

V = 0b01, если комбинация, указывающая вектор кодирования, содержит символы источника с переменным размером. В этом случае кодированные пакеты должны включать поле Encoded Payload Size.

NB_IDS

Число идентификаторов источника, сохранённых в векторе кодирования (зависит от I).

Число коэффициентов (NB_COEFS)

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

Первый идентификатор источника (FIRST_SOURCE_ID)

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

Число битов в каждом граничном блоке (b_id)

Число битов, требуемое для сохранения границы (edge).

Сведения об идентификаторах символов источника (id_bit_vector)

При I = 0b01 граничные блоки сохраняются как b_id * (NB_IDS * 2 — 1), при I = 0b10 граничные блоки сжимаются.

Коэффициенты (coef_bit_vector)

Коэффициенты, сохраняемые в зависимости от CCGI (4 или 8 битов на каждый коэффициент).

Padding

Заполнение для выравнивания размера вектора кодирования по 32-битовой границе (для ID и коэффициентов).

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

Для последующих параграфов возьмём пример генерации вектора кодирования для кодированного символа, являющегося линейной комбинацией символов источника с идентификаторами 1, 2, 3, 5, 6, 8, 9, 10 (краевые блоки [1..3], [5..6], [8..10]). Есть несколько способов сохранить идентификаторы символов источника в векторе кодирования.

  • Если сведения об идентификаторах символов источника не нужны, должно устанавливаться I = 0b00, а b_id и id_bit_vector не используются.

  • Если граничные блоки сохраняются без сжатия, должно устанавливаться I = 0b01. В этом случае устанавливается b_id = 32 (идентификатор символа содержит 32 бита), а список 32-битовых целых чисел без знака (1, 3, 4, 5, 6, 10) помещается в id_bit_vector.

  • Если идентификаторы символов источника сохраняются в виде списка со сжатием, должно устанавливаться I = 0b10. Этот случай описан в параграфе 5.3.1.1, но вместо сжатия граничных блоков сжимается весь список идентификаторов символов источника.

  • Если идентификаторы символов источника сохраняются со сжатием, должно устанавливаться I = 0b11 (см. ).

5.3.1.1. Сжатый список идентификаторов символов источника

Продолжим с определенным в предыдущем параграфе кодированным символом с идентификаторами символов источника в линейной комбинации [1..3], [5..6], [8..10]. Для сжатия и сохранения этого списка в векторе кодирования должна применяться приведённая ниже процедура.

  1. Первый элемент пакета (1) кодируется как first_source_id.

  2. Выполняется дифференциальное преобразование путём вычитания элемента ([3, 5, 6, 8, 10]) из последующего с использованием в качестве «нулевого» элемента значения first_source_id, это даёт список L = [2, 2, 1, 2, 2].

  3. Рассчитывается число битов (b), требуемое для сохранения элемента списка, как ceil(log2(max(L))), где max(L) — самый большой элемент в списке L. В нашем случае будет b = 2.

  4. Значение b записывается в соответствующее поле (b_id), а из элементов списка создаётся вектор вида b * [(2 * NB) — 1], где NB — число элементов. В результате получается вектор битов 10, 10, 01, 10, 10.

5.3.1.2. Декомпрессия идентификаторов символов источника

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

  1. Перестраивается список переданных элементов путём считывания вектора битов и b, а затем преобразования в десятичную форму [10, 10, 01, 10, 10] => [2, 2, 1, 2, 2].

  2. Выполняется обратное прежнему преобразование путём сложения элементов, начиная с first_source_id, т. е. [1, 1 + 2, (1 + 2) + 2, (1 + 2 + 2) + 1, …] => [1, 3, 5, 6, 8, 10].

  3. Перестраиваются блоки с использованием списка и first_source_id [1..3], [5..6], [8..10].

5.4. Формат пакета обновления окна

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

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                      Common Packet Header                     /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        nb_missing_src                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                   nb_not_used_coded_symb                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         first_src_id                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      plr      |   sack_size   |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
|                                                               |
/                          SACK Vector                          /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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


Common Packet Header

Базовый заголовок с полем типа пакета 0b10.

nb_missing_src

Число пропущенных символов источника у получателя с начала сессии.

nb_not_used_coded_symb

Число кодированных символов у получателя, которые ещё не использованы для декодирования (например, в линейной комбинации есть хотя бы 2 неизвестных символа источника).

first_src_id

Идентификатор первого символа источника для указания в векторе частичного подтверждения (SACK).

plr

Доля потерь, выраженная в процентах нормализованным 8-битовым целым числом без знака. Например, 2,5% будут представлены как floor(2,5 * 256/100) = 6. И обратно, если указано значение 6, соответствующая доля теряемых пакетов в процентах будет рассчитываться как 6*100/256 = 2,34%. Значение применяется при динамической степени кодирования (code rate) или для статистики. Выбор расчёта остаётся за декодером Tetrys и зависит от наблюдения за окном, но значение PLR следует просматривать перед декодированием.

sack_size

Размер вектора SACK в 32-битовых словах. Например, значение 2 указывает вектор SACK размером 64 бита.

SACK vector

Битовый вектор, указывающий символы, которые должны быть удалены из окна кодирования, начиная с идентификатора первого символа источника. В большинстве случаев эти символы уже получены приёмником. Иногда это может быть связано с невосстановимыми потерями (например, при всплеске числа потерь), когда лучше отбросить и отказаться от некоторых пакетов и удалить их из окна кодирования, чтобы можно было восстановить последующие пакеты. Первый символ источника (First Source Symbol или first_src_id) включается в этот вектор. Бит со значением 1 в позиции i означает, что этот пакет обновления окна удаляет из окна кодирования символ источника с номером first_src_id + i.

6. Темы исследований

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

6.1. Взаимодействие с контролем перегрузок

Tetrys и компоненты контроля перегрузок создают 2 отдельных канала (см. параграф 2.1 в [RFC9265]).

  • Канал Tetrys передаёт пакеты источника и кодированные пакеты (от отправителя к получателю), а также информацию от получателя к отправителю (например, сигналы о восстановленных символах, частоте потерь до и/или после декодирования и т. п.).

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

Ниже указаны темы, отмеченные и рассмотренные в [RFC9265], которые уже адаптированы в конкретных внедрениях Tetrys (на транспортном уровне, а также выше или ниже его).

  • Связанные с перегрузкой потери могут быть скрыты, если протокол Tetrys развернут ниже транспортного уровня без каких-либо мер предосторожности (т. е. Tetrys восстанавливает пакеты, потерянные из-за перегрузки маршрутизатора), что может существенно влиять на эффективность контроля перегрузок. Подход для предотвращения сокрытия таких сигналов представлен в разделе 5 [RFC9265].

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

  • Адаптация степени кодирования внутри Tetrys может оказывать сильное влияние на контроль перегрузки при ненадлежащем выполнении (см. ).

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

  • Защита нескольких потоков приложений внутри одного потока Tetrys вызывает дополнительные вопросы (см. ).

6.2. Адаптивная степень кодирования

Когда условия в сети (например, задержки и частота потерь) сильно меняются со временем, можно использовать адаптивную степень кодирования для динамического повышения или сокращения числа кодированных пакетов при передаче (т. е. добавления избыточности) с помощью специального алгоритма, такого как [A-FEC]. Стратегия различается в зависимости от уровня, где развёрнут протокол Tetrys (по отношению к транспортному уровню). Можно разделить стратегии на 2 класса — внедрение Tetrys на транспортном уровне и вне его (выше или ниже). Развёртывание внутри транспортного уровня означает возможность взаимодействия между транспортными механизмами, такими как восстановление при ошибках, контроль перегрузок и/или управление потоком данных. Внедрение Tetrys в транспортных протоколах без контроля перегрузки, таких как UDP, не дало бы никаких преимуществ перед внедрением за пределами транспортного уровня.

Влияние внедрения механизма FEC внутри транспортного уровня рассмотрено в разделе 4 [RFC9265], где исследуются вопросы взаимодействия контроля перегрузок и степени кодирования, а также влияние беспристрастности. Такая адаптация возможна в сочетании с механизмом контроля перегрузок протокола транспортного уровня, как предложено в [CTCP]. Это позволяет использовать отслеживаемые показатели контроля перегрузок (например, RTT, события перегрузки, текущий размер окна перегрузки) для адаптации степени кодирования с учётом рассчитанной скорости транспортной отправки. Смысл заключается в расчёте объёма ремонтного трафика, который не вызывает перегрузки. Такая связанная оптимизация обязательна для предотвращения захвата потоком всей доступной пропускной способности, как описано в [RMCAT-ADAPTIVE-FEC], где авторы отмечают, что коэффициент восстановления (repair ratio) следует повышать при одновременном снижении скорости передачи от источника.

Адаптация степени кодирования может выполняться вне транспортного уровня без учёта показателей этого уровня. В частности, это можно делать вместе с сетью, как предложено в [RED-FEC]. Авторы этой статьи предлагают механизм случайного раннего обнаружения (Random Early Detection) FEC в контексте передачи видео через беспроводную сеть. Вкратце, идея заключается в увеличении числа избыточных пакетов, когда очередь в точке доступа менее загружена, и наоборот. Предложена первая теоретическая попытка доставки видео с применением Tetrys [THAI]. Этот подход интересен тем, что он показывает взаимодействие между требованиями приложения и условиями в сети, а также объединяет сигналы о потребностях приложения и состоянии сети (т. е. ниже и выше транспортного уровня).

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

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

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

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

6.3. Использование Tetrys ниже уровня IP для туннелирования

Применение Tetrys для защиты агрегата потоков требует исследования вопроса восстановления дейтаграмм IP, потерянных при туннелировании. Применение избыточности без дифференциации потоков может противоречить требованиям по обслуживанию отдельных потоков, поскольку некоторые из них могут быть чувствительны к задержкам и их вариациям, а другие — к надёжности доставки. На практике блокировка в голове очереди (head-of-line) аналогично влияет на все потоки, несмотря на их разные потребности, что требует более продуманной стратегии в Tetrys.

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

Для начала следует осознать, что применение защиты FEC для потока данных не обеспечивает безопасности и даже повышает уровень риска. Ситуация с протоколом Tetrys похожа на использование других протоколов доставки содержимого в применением FEC и это хорошо описано в FECFRAME [RFC6363]. Этот раздел основан на данном документе и рассматривает дополнительные соображения, относящиеся к Tetrys, когда это уместно.

7.1. Постановка задачи

Целью атакующего может быть содержимое, протокол или сеть. Последствия будут существенно разными в зависимости от целей, таких как получение доступа к конфиденциальным сведениям, повреждение содержимого, компрометация кодера и/или декодера Tetrys, нарушение поведения сети. В частности, некоторые атаки направлены на отказ в обслуживании (Denial-of-Service или DoS) и их последствия могут ограничиваться одним узлом (например, декодером Tetrys) или влиять на все узлы, подключённые к соответствующей сети (например, делая потоки невосприимчивыми к сигналам перегрузки).

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

7.2. Атаки на поток данных

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

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

7.3. Атаки на сигнализацию

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

Злоумышленник, способный выборочно отбрасывать пакеты обратной связи (вместо их изменения), не сможет существенно повлиять на работу Tetrys, поскольку протокол по своей природе устойчив к таким потерям. Однако это будет вызывать побочные эффекты, такие как применение более крупных линейных систем (поскольку кодер Tetrys не сможет удалить полученные и декодированные пакеты из своей линейной системы), что ведёт к вычислительным издержкам на обеих сторонах (кодер и декодер).

7.4. Атаки на сеть

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

7.5. Базовые операции защиты

Tetrys может использовать IPsec/ESP [RFC4303] для защиты конфиденциальности и целостности, аутентификации источника и предотвращения повторного использования пакетов (replay). IPsec/ESP можно применять для защиты потоков данных Tetrys (в обоих направлениях) от злоумышленников, находящихся в промежуточных сетях или способных перехватывать, внедрять и повторно использовать легитимные пакеты.

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

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

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, <https://www.rfc-editor.org/info/rfc2119>.

[RFC4303] Kent, S., «IP Encapsulating Security Payload (ESP)», RFC 4303, DOI 10.17487/RFC4303, December 2005, <https://www.rfc-editor.org/info/rfc4303>.

[RFC5052] Watson, M., Luby, M., and L. Vicisano, «Forward Error Correction (FEC) Building Block», RFC 5052, DOI 10.17487/RFC5052, August 2007, <https://www.rfc-editor.org/info/rfc5052>.

[RFC5445] Watson, M., «Basic Forward Error Correction (FEC) Schemes», RFC 5445, DOI 10.17487/RFC5445, March 2009, <https://www.rfc-editor.org/info/rfc5445>.

[RFC5510] Lacan, J., Roca, V., Peltotalo, J., and S. Peltotalo, «Reed-Solomon Forward Error Correction (FEC) Schemes», RFC 5510, DOI 10.17487/RFC5510, April 2009, <https://www.rfc-editor.org/info/rfc5510>.

[RFC5651] Luby, M., Watson, M., and L. Vicisano, «Layered Coding Transport (LCT) Building Block», RFC 5651, DOI 10.17487/RFC5651, October 2009, <https://www.rfc-editor.org/info/rfc5651>.

[RFC5740] Adamson, B., Bormann, C., Handley, M., and J. Macker, «NACK-Oriented Reliable Multicast (NORM) Transport Protocol», RFC 5740, DOI 10.17487/RFC5740, November 2009, <https://www.rfc-editor.org/info/rfc5740>.

[RFC6363] Watson, M., Begen, A., and V. Roca, «Forward Error Correction (FEC) Framework», RFC 6363, DOI 10.17487/RFC6363, October 2011, <https://www.rfc-editor.org/info/rfc6363>.

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

[RFC8406] Adamson, B., Adjih, C., Bilbao, J., Firoiu, V., Fitzek, F., Ghanem, S., Lochin, E., Masucci, A., Montpetit, M., Pedersen, M., Peralta, G., Roca, V., Ed., Saxena, P., and S. Sivakumar, «Taxonomy of Coding Techniques for Efficient Network Communications», RFC 8406, DOI 10.17487/RFC8406, June 2018, <https://www.rfc-editor.org/info/rfc8406>.

[RFC8680] Roca, V. and A. Begen, «Forward Error Correction (FEC) Framework Extension to Sliding Window Codes», RFC 8680, DOI 10.17487/RFC8680, January 2020, <https://www.rfc-editor.org/info/rfc8680>.

[RFC9265] Kuhn, N., Lochin, E., Michel, F., and M. Welzl, «Forward Erasure Correction (FEC) Coding and Congestion Control in Transport», RFC 9265, DOI 10.17487/RFC9265, July 2022, <https://www.rfc-editor.org/info/rfc9265>.

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

[A-FEC] Bolot, J., Fosse-Parisis, S., and D. Towsley, «Adaptive FEC-based error control for Internet telephony», IEEE INFOCOM ’99, Conference on Computer Communications, New York, NY, USA, Vol. 3, pp. 1453-1460, DOI 10.1109/INFCOM.1999.752166, March 1999, <https://doi.org/10.1109/INFCOM.1999.752166>.

[AHL-00] Ahlswede, R., Cai, N., Li, S., and R. Yeung, «Network information flow», IEEE Transactions on Information Theory, Vol. 46, Issue 4, pp. 1204-1216, DOI 10.1109/18.850663, July 2000, <https://doi.org/10.1109/18.850663>.

[CTCP] Kim, M., Cloud, J., ParandehGheibi, A., Urbina, L., Fouli, K., Leith, D., and M. Medard, «Network Coded TCP (CTCP)», arXiv 1212.2291v3, April 2013, <https://arxiv.org/abs/1212.2291>.

[RED-FEC] Lin, C., Shieh, C., Chilamkurti, N., Ke, C., and W. Hwang, «A RED-FEC Mechanism for Video Transmission Over WLANs», IEEE Transactions on Broadcasting, Vol. 54, Issue 3, pp. 517-524, DOI 10.1109/TBC.2008.2001713, September 2008, <https://doi.org/10.1109/TBC.2008.2001713>.

[RMCAT-ADAPTIVE-FEC] Singh, V., Nagy, M., Ott, J., and L. Eggert, «Congestion Control Using FEC for Conversational Media», Work in Progress, Internet-Draft, draft-singh-rmcat-adaptive-fec-03, 20 March 2016, <https://datatracker.ietf.org/doc/html/draft-singh-rmcat-adaptive-fec-03>.

[Tetrys] Lacan, J. and E. Lochin, «Rethinking reliability for long-delay networks», International Workshop on Satellite and Space Communications, Toulouse, France, pp. 90-94, DOI 10.1109/IWSSC.2008.4656755, October 2008, <https://doi.org/10.1109/IWSSC.2008.4656755>.

[Tetrys-RT] Tournoux, P., Lochin, E., Lacan, J., Bouabdallah, A., and V. Roca, «On-the-Fly Erasure Coding for Real-Time Video Applications», IEEE Transactions on Multimedia, Vol. 13, Issue 4, pp. 797-812, DOI 10.1109/TMM.2011.2126564, August 2011, <http://dx.doi.org/10.1109/TMM.2011.2126564>.

[THAI] Tran Thai, T., Lacan, J., and E. Lochin, «Joint on-the-fly network coding/video quality adaptation for real-time delivery», Signal Processing: Image Communication, Vol. 29 Issue 4, pp. 449-461, DOI 10.1016/j.image.2014.02.003, April 2014, <https://doi.org/10.1016/j.image.2014.02.003>.

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

Во-первых, авторы хотят сердечно поблагодарить Marie-Jose Montpetit за постоянную помощь и поддержку Tetrys. Спасибо, Marie-Jo!

Авторы также благодарны членам рабочей группы NWCRG за многочисленные обсуждения кодирования «на лету», которые помогли завершить работу над этим документом.

Наконец, авторы хотели бы поблагодарить Colin Perkins за предоставленные комментарии и отзыв о документе.

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

Jonathan Detchart
ISAE-SUPAERO
BP 54032
10, avenue Edouard Belin
31055 Toulouse CEDEX 4
France
Email: jonathan.detchart@isae-supaero.fr
 
Emmanuel Lochin
ENAC
7, avenue Edouard Belin
31400 Toulouse
France
Email: emmanuel.lochin@enac.fr
 
Jerome Lacan
ISAE-SUPAERO
BP 54032
10, avenue Edouard Belin
31055 Toulouse CEDEX 4
France
Email: jerome.lacan@isae-supaero.fr
 
Vincent Roca
INRIA
Inovallee; Montbonnot
655, avenue de l’Europe
38334 St Ismier CEDEX
France
Email: vincent.roca@inria.fr

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

nmalykh@protokols.ru


1Coding for Efficient NetWork Communications Research Group — исследовательская группа по кодированию для эффективных сетевых коммуникаций.

2Internet Research Task Force — комиссия по исследовательским задачам Internet.

3Explicit Congestion Notification — явное уведомление о перегрузке.

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

Архитектура распределенного коммутатора (DSA)

Архитектура распределенного коммутатора

PDF

Оригинал

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

Принципы устройства

Подсистема DSA предназначалась в основном для поддержки коммутаторов Ethernet компании Marvell (MV88E6xxx, линейка Link Street), использующих Linux, но развилась и для поддержки продукции других производителей.

Исходным принципом разработки было сохранение возможности применять неизмененные инструменты Linux, такие как bridge, iproute2, ifconfig для настройки и опроса коммутирующих портов сетевого устройства или обычного сетевого устройства.

Коммутатор Ethernet обычно имеет множество портов на передней панели и 1 или несколько портов CPU или управления. Подсистема DSA в настоящее время полагается на наличие порта управления, соединённого с контроллером Ethernet, способным получать кадры Ethernet от коммутатора. Это очень распространённое решение для всех видов коммутаторов Ethernet в продукции для дома и небольшого офиса (Small Home and Office) — маршрутизаторах, шлюзах и даже стоечных коммутаторах (top-of-rack). Этот хост-контроллер Ethernet далее называется ведущим (master) и cpu в описании и коде DSA.

D в аббревиатуре DSA означает Distributed (распределенный), поскольку подсистема разрабатывается для обеспечения возможности настройки и управления каскадом коммутаторов с использованием восходящих и нисходящих каналов Ethernet между ними. Эти порты называются портами dsa в терминологии и коде DSA. Набор соединённых между собой коммутаторов называется деревом коммутаторов (switch tree).

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

Идеальным вариантом применения DSA является случай с поддержкой коммутатором Ethernet тега (switch tag), являющегося свойством оборудования, когда коммутатор помещает свой тег для каждого кадра Ethernet, получаемого или передаваемого в конкретные порты, чтобы помочь интерфейсу управления понять:

  • из какого порта поступил кадр;
  • по какой причини кадр был переслан;
  • как передать созданный CPU трафик в конкретные порты.

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

Отметим, что в настоящее время DSA не создаёт сетевых интерфейсов для портов cpu и dsa.

  • Портом cpu является сторона коммутатора Ethernet, обращённая к управляющему контроллеру, поэтому создание порта привело бы к дублированию функций, поскольку было бы 2 интерфейса для одного канала (conduit) master netdev и cpu netdev.
  • Портами dsa являются просто каналы (conduit) между двумя и более коммутаторами и, поскольку они могут служить корректными сетевыми интерфейсами, в этой модели имеют смысл лишь нисходящие интерфейсы и восходящий интерфейс верхнего уровня.

Протоколы для тегов коммутаторов

DSA поддерживает фирменные протоколы тегов многих производителей, программно определяемый протокол для тегов и режим без тегов (tag-less, DSA_TAG_PROTO_NONE). Точный формат зависит от производителя, но обычно теги содержат:

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

Все протоколы тегов включены в файлы net/dsa/tag_*.c и реализуют методы структуры dsa_device_ops, описанные ниже.

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

  1. Зависящий от коммутатора заголовок кадра размещается перед заголовком Ethernet, сдвигая вправо (с точки зрения первичного анализатора кадров DSA) поля MAC DA, MAC SA, EtherType и все данные L2 (payload).
  2. Зависящий от коммутатора заголовок кадра размещается перед полем EtherType, сохраняя позиции MAC DA и MAC SA с точки зрения первичного анализатора кадров DSA, но сдвигает поля EtherType и данные L2 вправо.
  3. Зависящий от коммутатора заголовок кадра размещается в конце пакета, сохраняя на месте все заголовки кадра и не меняя представление кадра с точки зрения первичного анализатора DSA.

Протокол тегов может помечать все кадры тегами коммутатора одного размера или применять теги переменного размера (например, пакеты с временными метками PTP могут требовать расширения тегов коммутатора, а также возможно использование тегов разного размера для передачи и приёма). В любом случае драйвер протокола тегов должен заполнять структуру dsa_device_ops::needed_headroom и/или dsa_device_ops::needed_tailroom, размер которой в октетах равен большему из размеров заголовка/трейлера в кадре. DSA автоматически корректирует MTU на первичном интерфейсе с учётом дополнительных полей, чтобы пользовательские порты DSA могли поддерживать стандартное значение MTU (размер данных L2) в 1500 октетов. Свойства needed_headroom и needed_tailroom применяются для запроса у сетевого стека (по возможности — best-effort) выделения пакетов с большим пространством, чтобы вталкивание тега коммутатора при передаче пакета не вызывало повторного выделения из-за нехватки памяти.

Хотя от приложений не ожидается синтаксический анализ связанных с DSA заголовков кадров, формат протокола тегов в линии представляет двоичный интерфейс приложений (Application Binary Interface или ABI), раскрываемый ядром пользовательскому пространству для декодирования (такой как libpcap). Драйвер протокола тегов должен помещать в поле proto структуры dsa_device_ops значение, однозначно описывающее характеристики требуемого взаимодействия между оборудованием коммутатора и драйвером пути данных — смещение каждого битового поля в заголовке кадра и любую обработку с учётом состояния, требуемую для работы с кадром как может требоваться, например, для меток времени PTP).

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

Отметим, что в некоторых случаях формат тегов, используемых коммутатором-листом (не соединён напрямую с CPU) отличается от формата, который видит сетевой стек. Примером этого могут служить деревья коммутаторов Marvell, где порт CPU можно настроить на использование формата DSA или Ethertype DSA (EDSA), а каналы DSA настроены на применение более короткого (без Ethertype) формата кадров DSA для снижения издержек при автономной пересылке пакетов. Если дерево коммутаторов DSA настроено для протокола тегов EDSA, операционная система по-прежнему будет видеть пакеты с тегами EDSA от листовых коммутаторов, которые помечают пакеты более короткими заголовками DSA. Это обусловлено тем, что коммутатор Marvell, напрямую соединённый с CPU настроен на преобразование тегов между DSA и EDSA (это просто добавление или удаление ETH_P_EDSA EtherType и некоторых октетов заполнения).

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

Протокол тегов присоединённого коммутатора DSA можно увидеть из атрибута sysfs dsa/tagging ведущего коммутатора DSA с помощью команды

cat /sys/class/net/eth0/dsa/tagging

Если оборудование и драйвер позволяют это, протокола тегов дерева коммутатора DSA можно сменить в процессе работы. Это делается путём записи имени нового протокола тегов в тот же атрибут устройства sysfs, который указан выше (DSA master и все подключённые порты коммутатора должны быть на это время переведены в состояние down).

Желательно, чтобы все протоколы тегов можно было протестировать с помощью макетного драйвера dsa_loop, который можно присоединить к любому сетевому интерфейсу. Цель заключается в том, чтобы любой сетевой интерфейс был способен передавать один и тот же пакет одним способом, а средству маркировки следует одинаково декодировать один и тот же пакет, независимо от драйвера, применяемого для пути управления в коммутаторе и драйвера, применяемого для DSA master.

Передача пакета осуществляется через вызов функции xmit. В переданной структуре sk_buff элемент *skb содержит указатель skb->data на skb_mac_header(skb), т. е. MAC-адрес получателя, а в переданной структуре net_device элемент *dev представляет виртуальный пользовательский сетевой интерфейс DSA, аппаратному «дубликату» которого должен быть направлен пакет (т. е. swp0). Задача этого метода состоит в подготовке skb так, чтобы коммутатор понимал, какой выходной порт использовать для пакета (и не передавал его в другие порты). Обычно это реализуется вталкиванием заголовка кадра. Проверка достаточности пространства в голове и хвосте skb не требуется при корректном указании needed_headroom и needed_tailroom, поскольку DSA гарантирует наличие свободного пространства перед вызовом этого метода.

Для приёма пакета служит функция rcv. В переданной структуре sk_buff элемент *skb содержит указатель skb->data на skb_mac_header(skb) + ETH_ALEN октетов, т. е. на место, где был бы первый октет EtherType, если бы в кадре не было тега. Роль этого метода заключается в использовании заголовка кадра, настройке skb->data для указания на реально первый октет EtherType и изменения skb->dev для указания виртуального пользовательского сетевого интерфейса DSA, соответствующего физическому порту коммутатора, на котором был получен пакет.

Поскольку протоколы тегов категории 1 и 2 нарушают программное (а чаще всего и аппаратное) разбиение пакета в DSA master, такие свойства, как RPS1 на DSA будут нарушены. Модель DSA справляется с этим, устанавливая ловушку в диссекторе потоков и сеняя смещение, по которому можно найти заголовок IP в кадре с тегом, как его видит DSA master. Это автоматизируется на основе значения overhead в протоколе тегов. Если не все пакеты имеют одинаковый размер, модуль работы с тегами может реализовать метод flow_dissect структуры dsa_device_ops и переопределить принятое по умолчанию поведение, задавая корректное смещение в каждом принятом пакете. Модули включения тегов в конец кадра не вызывают проблем для диссекторов потоков.

Выгрузка контрольных сумм должна работать с тегами категории 1 и 2, когда драйвер DSA master декларирует NETIF_F_HW_CSUM в vlan_features и просматривает csum_start и csum_offset. В этих случаях DSA меняет начало и смещения на величину размера тега. Если драйвер DSA master продолжает использовать устаревшее значение NETIF_F_IP_CSUM или NETIF_F_IPV6_CSUM в vlan_features, выгрузка может работать лишь при условии, когда оборудование выгрузки уже ожидает этот конкретный тег (возможно по соответствию производителя). Ведомые устройства DSA наследуют эти флаги от ведущего порта и драйвер корректно возвращается к программной обработке контрольных сумм, когда заголовок IP размещается не там, где его ждёт оборудование. Если описанная проверка неэффективна, пакеты могут проходить через сеть без подходящей контрольной суммы (в поле контрольной суммы будет указано значение для псевдозаголовка IP). Для категории 3, когда оборудование разгрузки не ждёт использования тегов коммутатора, контрольная сумма должна рассчитываться до вставки тега (т. е. в модуле работы с тегами). Иначе DSA будет включать концевой тег в расчёт (программный или аппаратный) контрольной суммы. Когда коммутатор вырежет тег при передаче, он оставит некорректную контрольную сумму на месте.

В силу разных причин (чаще всего из-за тегов категории 1, связанных с не понимающими DSA ведущими устройствами, может искажаться то, что ведущий считает MAC DA) протокол тегов может требовать от DSA работы в неразборчивом (promiscuous) режиме для приёма кадров независимо от значения MAC DA. Это можно сделать установкой свойства promisc_on_master в структуре dsa_device_ops. Отметим, что это предполагает драйвер ведущего устройства без поддержки DSA, что является нормой.

Ведущие сетевые устройства

Ведущие сетевые устройства — это обычные, не изменённые драйверы сетевых устройств Linux для интерфейсов Ethernet CPU/управления. Таким драйверам иногда может требоваться знать включён ли DSA (например, для включения или выключения конкретных свойств разгрузки), но подтверждена работа подсистемы DSA со стандартными для отрасли драйверами e1000e, mv643xx_eth и т. п. без внесения в них изменений. Такие сетевые устройства часто называют «канальными» (conduit), поскольку они служат каналом между процессором хоста и оборудованием коммутатора Ethernet.

Ловушки сетевого стека

При использовании master netdev с DSA в сетевой стек помещается небольшая ловушка для обработки подсистемой DSA используемого коммутатором Ethernet протокола тегов. DSA делает это путём регистрации в сетевом стеке конкретного (фиктивного) типа Ethernet (далее skb->protocol), который называют также ptype или packet_type. Ниже показана типичная последовательность приёма кадра Ethernet ведущим сетевым устройством (например, e1000e).

  1. Получение сигнала прерывания:
    • вызов функции приёма;
    • базовая обработка пакета (определение размера, статуса и т. п.);
    • подготовка пакета к обработке на уровне Ethernet вызовом функции eth_type_trans.
  2. net/ethernet/eth.c
    eth_type_trans(skb, dev)
            if (dev->dsa_ptr != NULL)
                    -> skb->protocol = ETH_P_XDSA
  3. drivers/net/ethernet/*
    netif_receive_skb(skb)
            -> итерации по зарегистрированным packet_type
                    -> вызов обработчика для ETH_P_XDSA, вызов dsa_switch_rcv()
  4. net/dsa/dsa.c
    -> dsa_switch_rcv()
            -> вызов зависящего от протокола тегов обработчика в net/dsa/tag_*.c
  5. net/dsa/tag_*.c
    • проверка и вырезание (протокола) тега для определения порта-источника;
    • нахождение сетевого устройства по порту;
    • вызов eth_type_trans() с ведомым сетевым устройством DSA;
    • вызов netif_receive_skb().

После этого ведомые сетевые устройства DSA получают обычные кадры Ethernet, которые может обрабатывать сетевой стек.

Ведомые сетевые устройства

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

  • вставку и удаление тега коммутатора (при наличии) при передаче и приёме через соответствующие порты;
  • запрос у коммутатора операций ethtool (статистика, состояние канала, WoL2, дампы регистров …);
  • управление внешним или внутренним PHY (канал, автосогласование и т. п.).

Эти ведомые сетевые устройства имеют указатели на пользовательские функции net_device_ops и ethtool_ops, что позволяет DSA вводить уровень разделения между сетевым стеком/ethtool и реализацией драйвера коммутатора.

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

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

При использовании нескольких портов CPU можно разместить устройство LAG (bonding/team) между ведомыми устройствами DSA и физическими DSA master. Устройство LAG также будет DSA master, но ведомые устройства LAG продолжают оставаться DSA master (просто с ними не связывается физический порт; это нужно для восстановления в случае потери LAG DSA master). Таким образом, путь данных LAG DSA master используется асимметрично. На RX обработчик ETH_P_XDSA, который вызывает dsa_switch_rcv(), вызывается редко (на физическом DSA master, LAG slave). Поэтому путь данных RX в LAG DSA master не используется. С другой стороны, TX работает линейно — dsa_slave_xmit вызывает dsa_enqueue_skb, а эта функция вызывает dev_queue_xmit в направлении LAG DSA master. Последняя вызывает dev_queue_xmit в направлении одного или другого физического DSA master и в обоих случаях пакет выходит из системы по аппаратному пути в направлении коммутатора.

Графическое представление

Вид DSA с точки зрения сетевого устройства показан на рисунке ниже.

             Не осведомлённое приложение
             открывает и привязывает сокет
                    |  ^
                    |  |
        +-----------v--|--------------------+
        |+------+ +------+ +------+ +------+|
        || swp0 | | swp1 | | swp2 | | swp3 ||
        |+------+-+------+-+------+-+------+|
        |      Драйвер коммутатора DSA      |
        +-----------------------------------+
                      |        ^
      Тег, добавленный|        | Тег, воспринятый
 драйвером коммутатора|        | драйвером коммутатора
                      v        |
        +-----------------------------------+
        |Неизменённый драйвер интерф. хоста | Программа
--------+-----------------------------------+-------------
        |       Интерфейс хоста (eth0)      | Оборудование
        +-----------------------------------+
                      |        ^
      Тег, воспринятый|        | Тег, добавленный
 оборудованием коммут.|        | оборудованием коммутатора
                      v        |
        +-----------------------------------+
        |            Коммутатор             |
        |+------+ +------+ +------+ +------+|
        || swp0 | | swp1 | | swp2 | | swp3 ||
        ++------+-+------+-+------+-+------++


Ведомая шина MDIO

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

Для коммутаторов Ethernet, имеющих внутренние и внешние шины MDIO, ведомую шину MII можно использовать для мультиплексирования и демультиплексирования операций чтений и записи MDIO в направлении внешних или внутренних устройств MDIO, к которым коммутатор может быть подключён, — внутренние и внешние PHY и даже внешние коммутаторы.

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

Структуры данных DSA определены в файлах include/net/dsa.h и net/dsa/dsa_priv.h.

  • Структура dsa_chip_data содержит данные конфигурации платформы для данного коммутирующего устройства. Эта структура описывает родительское устройство коммутатора, его адрес, а также различные свойства портов (имена, метки) и указывает таблицу маршрутизации (при каскадировании коммутаторов).
  • Структура dsa_platform_data содержит данные конфигурации платформы, которые могут указывать набор структур dsa_chip_data при каскадировании коммутаторов. Структура должна указывать ведущее сетевое устройство, к которому подключено это дерево коммутаторов.
  • Структура dsa_switch_tree назначенная ведущему сетевому устройству в dsa_ptr. Эта структура ссылается на структуру dsa_platform_data и указывает протокол тегов, поддерживаемый деревом коммутаторов, а также ловушки функций приёма и передачи, которые следует вызывать и сведения о подключённом напрямую коммутаторе (порт CPU). Для указания отдельных коммутаторов дерева применяется набор структур dsa_switch.
  • Структура dsa_switch описывает коммутирующее устройство в дереве, ссылаясь на dsa_switch_tree в качестве обратного указателя, а также указывает ведомые и ведущее сетевые устройства резервную структуру dsa_switch_ops.
  • Структура dsa_switch_ops содержит указатели на функции, описанные ниже.

Ограничения для устройств

Отсутствие сетевых устройств CPU/DSA

DSA в настоящее время не создаёт ведомых сетевых устройств для портов CPU и DSA, как указано выше. Это может вызывать проблемы в некоторых случаях:

  • невозможность извлечь значения счётчиков статистики порта CPU с использованием ethtool, что может осложнять отладку коммутаторов MDIO, подключённых через интерфейс xMII;
  • невозможность настроить для порта CPU параметры канала с помощью подключённого к нему контроллера Ethernet (см. http://patchwork.ozlabs.org/patch/509806/);
  • невозможность настроить конкретные VLAN ID и транковые VLAN между коммутаторами в каскаде.

Распространённые ошибки при использовании DSA

После того, как ведущее сетевое устройство настроено для DSA (dev->dsa_ptr отлично от NULL) и размещённый за ним коммутатор ожидает протокол тегов, этот сетевой интерфейс можно использовать лишь в качестве интерфейса «трубы» (conduit). Передача пакетов напрямую через этот интерфейс (например, создание сокета с использованием этого интерфейса) не потребует проходить через функцию передачи протокола тегов, поэтому ожидающий тег коммутатор Ethernet на другой стороне обычно будет отбрасывать такие пакеты.

Взаимодействия с другими подсистемами

Ниже указаны подсистемы, используемые DSA в настоящее время:

  • библиотека MDIO/PHY — drivers/net/phy/phy.c, mdio_bus.c
  • switchdev — net/switchdev/*
  • дерево устройств для различных функций of_*;
  • devlink — net/core/devlink.c.

Библиотека MDIO/PHY

Сетевые устройства, раскрываемые DSA, не обязательно сопрягаются с устройствами PHY (struct
phy_device, заданная в include/linux/phy.h), но подсистема DSA обрабатывает все возможные комбинации:

  • внутренние устройства PHY, встроенные в оборудование коммутаторов Ethernet;
  • внешние устройства PHY, подключённые через внутреннюю или внешнюю шину MDIO;
  • внутренние устройства PHY, подключённые через внутреннюю шину MDIO;
  • специальные устройства PHY без автоматического согласования и управления через: SFP, MoCA (fixed PHY).

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

  • При использовании дерева устройств (Device Tree) устройство PHY отыскивается с помощью стандартного свойства phy-handle и при обнаружении это устройство PHY и регистрируется функцией of_phy_connect().
  • Если используется дерево устройств и устройство PHY является «фиксированным» (т. е. соответствует определению PHY, управляемого не через MDIO, как указано в файле Documentation/devicetree/bindings/net/fixed-link.txt), PHY регистрируется и подключается «прозрачно» с использованием специального драйвера фиксированной шины MDIO.
  • Если устройство PHY встроено в коммутатор, как это часто бывает в автономных коммутаторах, PHY проверяется с использованием специальной шины MII, созданной DSA.

SWITCHDEV

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

Devlink

DSA регистрирует одно устройство devlink на физический коммутатор в модуле коммутации (fabric). Для каждого устройства devlink каждый физический порт (пользовательские порты, порты CPU, каналы DSA и неиспользуемые порты) раскрывается как порт devlink.

Драйверы DSA могут использовать указанные ниже свойства devlink.

Регионы

Отладочное средство, позволяющее пользовательскому пространству выводить определяемые драйвером области аппаратной информации в низкоуровневом двоичном формате. Поддерживаются глобальные регионы и регионы по портам. Возможен экспорт регионов devlink даже для данных, которые уже тем или иным способом раскрыты стандартным программам пользовательского пространства iproute2 (ip-link, bridge), такие как таблицы адресов и VLAN. Это может быть полезно, например, когда таблицы содержат связанные с оборудованием детали, которые не видны через абстракцию iproute2, или для проверки таблиц на портах, не являющихся пользовательскими, которые не видны iproute2, поскольку для них не регистрируются сетевые интерфейсы.

Параметры

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

Ресурсы

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

Общие буферы

Свойство QoS для настройки и разделения памяти и резервирования кадров по портам на входном и выходном направлении так, чтобы объёмный трафик с низким приоритетом не препятствовал обработке высокоприоритетного важного трафика.

Дополнительные сведения можно найти в файлах каталога Documentation/networking/devlink/.

Дерево устройств

В DSA имеется фиксированная привязка, описанная в файле Documentation/devicetree/bindings/net/dsa/dsa.txt. Вспомогательные функции библиотеки PHY/MDIO, такие как of_get_phy_mode(), of_phy_connect(), часто
применяются для запроса связанных с
PHY деталей по портам — соединения интерфейсов, размещение шины MDIO и т. п.

Разработка драйверов

Драйверы коммутаторов DSA должны реализовать структуру dsa_switch_ops,
содержащую описанные ниже элементы.

Проба, регистрация и срок действия устройства

Коммутаторы DSA являются обычными структурами device на шинах (платформа, SPI, I2C, MDIO и пр.). Платформа DSA не участвует в их зондировании ядром устройства.

Регистрация коммутатора с точки зрения драйвера означает передачу действительного указателя на структуру dsa_switch функции dsa_register_switch(), обычно из функции проверки драйвера коммутатора. Ниже указаны элементы предоставляемой структуры, которые должны иметь действительные значения:

  • ds->dev
    используется для синтаксического
    анализа данных узла OF или платформы;
  • ds->num_ports используется для создания списка портов этого коммутатора и проверки индексов портов, предоставляемых в узле OF;
  • ds->ops содержит указатель на структуру dsa_switch_ops, содержащую реализации методов ;
  • ds->priv — обратный указатель на частную структуру данных драйвера, которая может извлекаться во всех последующих обратных вызовах (callback) методов DSA.

Кроме того, могут указываться перечисленные ниже флаги структуры dsa_switch для задания конкретного поведения драйвера со стороны ядра DSA. Описание поведения приведено в комментариях к файлу include/net/dsa.h.

  • ds->vlan_filtering_is_global;
  • ds->needs_standalone_vlan_filtering;
  • ds->configure_vlan_while_not_filtering;
  • ds->untag_bridge_pvid;
  • ds->assisted_learning_on_cpu_port;
  • ds->mtu_enforcement_ingress;
  • ds->fdb_isolation.

DSA сохраняет внутри массив деревьев (групп) коммутаторов, являющийся глобальным для ядра, и связывает с деревом структуру dsa_switch при регистрации. Идентификатор дерева, с которым связан коммутатор, определяется первым числом u32 number свойства dsa,member узла OF коммутатора (0 при отсутствии). Идентификатор коммутатора в дереве определяется вторым числом u32 в том же свойстве OF (0 при отсутствии). Регистрация нескольких коммутаторов с совпадающими идентификаторами коммутатора и дерева некорректна и вызывает ошибку. При использовании данных платформы разрешён 1 коммутатор и одно дерево.

Для дерева с несколькими коммутаторами зондирование выполняется асимметрично. Первые N-1 вызывающих dsa_register_switch() лишь добавляют свои порты в список портов дерева (dst->ports) и каждый порт имеет обратный указатель на связанный с ним коммутатор (dp->ds). Эти коммутаторы заранее завершают свои вызовы dsa_register_switch(), поскольку функция dsa_tree_setup_routing_table() определяет, что дерево ещё не завершено (не все порты, указанные каналами DSA, присутствуют в списке портов дерева). Дерево становится полным, когда последний коммутатор вызывает dsa_register_switch() и это запускает эффективное продолжение инициализации (включая вызов ds->ops->setup()) для всех коммутаторов этого дерева, как часть контекста вызова функции зондирования последним коммутатором.

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

Для драйверов коммутаторов DSA обязательна реализация обратного вызова shutdown() соответствующей шины и вызов dsa_switch_shutdown() из неё (минимальный вариант полного демонтажа, выполняемого dsa_unregister_switch()). Причина заключается в том, что DSA сохраняет ссылку на ведущее сетевое устройство и при отвязывании (unbind) основного устройства при отключении ссылка DSA будет препятствовать завершению операции.

Должна вызываться функция dsa_switch_shutdown() или dsa_unregister_switch(), но не обе, и модель драйвера устройства разрешает вызывать метод шины remove(), даже если уже вызвана функция shutdown(). Поэтому ожидается реализация в драйверах метода взаимного исключения remove() и shutdown() путём установки drvdata = NULL после вызова любой из этих функций и проверка значения drvdata (NULL) перед выполнением какого-либо действия.

После вызова dsa_switch_shutdown() или dsa_unregister_switch() обратные вызовы через предоставленный указатель на dsa_switch_ops не могут выполняться и драйвер может освободить структуры данных, связанные с dsa_switch.

Настройка коммутатора

get_tag_protocol

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

change_tag_protocol

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

setup

Функция установки (setup) коммутатора, отвечающая за установку приватной структуры dsa_switch_ops со всем необходимым — планы регистров, прерывания, мьютексы, блокировки и т. п. Предполагается, что эта функция должным образом настроит конфигурацию коммутатора для отделения сетевых интерфейсов друг от друга, т. е. им следует быть изолировать самому оборудованию коммутатора, обычно путём создания для каждого VLAN ID по порту и разрешая пересылку лишь между портом CPU и конкретным портом. Не используемые платформой порты следует отключать. После вызова этой функции коммутатор предполагается полностью настроенным и готовым к выполнению запросов любого вида. Рекомендуется выполнять программный сброс коммутатора в этой функции настройки для исключения настроек, которые мог установить прежний программный агент, такой как начальный загрузчик или микрокод. Методом, отвечающим за отказ от всех применимых выделений или операций, выполненных здесь, является teardown.

port_setup и port_teardown

Методы для создания и удаления структур данных по портам. Они обязательны для таких операций, как регистрация и дерегистрация регионов портов devlink. Порт может быть удалён лишь в том случае, когда он был создан ранее. Порт может быть установлен на время зондирования, а затем сразу удалён, например, в случае отсутствия PHY. При этом зондирование коммутатора DSA продолжается без такого порта.

port_change_master

Метод, с помощью которого можно изменить связность (аффинность — ассоциация для целей завершения трафика) пользовательского порта и порта CPU. По умолчанию все пользовательские порты из дерева связаны с первым доступным портом CPU, имеющим смысл для данного порта (в большинстве случаев это означает, что все пользовательские порты в дереве связаны с одним портом CPU, за исключением топологии H, описанной в представлении 2c0b03258b8b). Аргумент port указывает индекс пользовательского порта, а master представляет новое ведущее устройство DSA master net_device. Порт CPU, связанный с новым ведущим, можно определить поиском в struct dsa_port *cpu_dp = master->dsa_ptr. Кроме того, ведущий может быть устройством LAG, в котором все ведому устройства являются физическими DSA master. Ведущие LAG DSA имеют действительный указатель master->dsa_ptr, однако он не уникален и является дубликатом dsa_ptr первого физического DSA (LAG slave). В случае LAG DSA последующий вызов port_lag_join будет выполняться отдельно для физических портов CPU, связанных с физическими DSA master, с запросом на создание аппаратной группы LAG, связанной с интерфейсом LAG.

Управление PHY и каналом

get_phy_flags

Некоторые коммутаторы имеют интерфейсы для различных типов Ethernet PHY. Если драйвер PHY библиотеки PHY нужны сведения, которые он не может получить сам (например, из регистров, отображённых на память коммутатора), этой функции следует возвращать 32-битовую маску «флагов», которые являются приватными для драйвера коммутатора и драйвера Ethernet PHY из каталога drivers/net/phy/*.

phy_read

Функция вызывается шиной MDIO ведомого DSA для считывания регистров MDIO порта коммутатора. При неудаче считывания функция возвращает 0xffff для каждой операции чтения. Для Ethernet PHY встроенных коммутаторов этой функции следует разрешать считывание статуса канала, результаты автосогласования, страницы партнёра по каналу и т. п.

phy_write

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

adjust_link

Функция вызывается библиотекой PHY, когда ведомое сетевое устройство присоединяется к устройству PHY. Функция отвечает за подобающую настройку параметров канала для порта коммутатора — скорости, дуплекса, паузы на основе представленных в phy_device значений.

fixed_link_update

Функция вызывается библиотекой PHY и, в частности, драйвером фиксированного PHY, спрашивающим у драйвера коммутатора параметры канала, которые невозможно согласовать автоматически или получить путём чтения регистров PHY через MDIO. Это особенно полезно для определённых типов оборудования, таких как QSGMII, MoCA или иные типы не управляемых через MDIO устройств PHY, где информация получается вне основного соединения.

Операции ethtool

get_strings

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

get_ethtool_stats

Функция ethtool для запроса статистики по порта. DSA накладывает статистику ведомых сетевых устройств на общую статистику — счётчики RX/TX из сетевого устройства со статистикой драйвера коммутатора по портам.

get_sset_count

Функция ethtool для запроса числа элементов статистики.

get_wol

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

set_wol

Функция ethtool для настройки Wake-on-LAN по портам.

set_eee

Функция ethtool для настройки параметров EEE (Green Ethernet) порта коммутатора, которая может вызывать библиотеку PHY для включения EEE на уровне PHY, если это уместно. Этой функции следует включать EEE на контроллере MAC и в логике обработки данных порта коммутатора.

get_eee

Функция ethtool для запроса настроек EEE порта коммутатора, которой следует возвращать состояние EEE контроллера MAC порта коммутатора и логики обработки данных, а также запрашивать у PHY текущие настройки EEE.

get_eeprom_len

Функция ethtool, возвращающая для данного коммутатора размер EEPROM в байтах.

get_eeprom

Функция ethtool, возвращающая для данного коммутатора содержимое EEPROM.

set_eeprom

Функция ethtool, записывающая указанные данные в EEPROM данного коммутатора.

get_regs_len

Функция ethtool, возвращающая для данного коммутатора размер регистров.

get_regs

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

Управление питанием

suspend

Функция, вызываемая устройством платформы DSA, когда система переходит в режим приостановки (suspend). Функции следует приостанавливать все действия коммутатора Ethernet, оставляя активными порты, участвующие в Wake-on-LAN, а также дополнительную логику пробуждения, если она поддерживается.

resume

Функция, вызываемая устройством платформы DSA при возобновлении работы системы (resume). Функции следует восстанавливать все действия коммутатора Ethernet и реконфигурировать коммутатор, чтобы он находился в полностью активном состоянии.

port_enable

Функция, вызываемая функцией ndo_open ведомого устройства DSA при административной активации порта. Функции следует полностью включать данный физический порт. DSA заботится о маркировке порта BR_STATE_BLOCKING, если порт входит в мост, и BR_STATE_FORWARDING — в противном случае, а также распространении этих изменений в оборудование.

port_disable

Функция, вызываемая функцией ndo_open ведомого устройства DSA при административном отключении порта. Функции следует полностью выключать данный физический порт. DSA заботится о маркировке порта BR_STATE_DISABLED и распространении этих изменений в оборудование, если отключенный порт входит в мост.

Адресные базы данных

Предполагается, что коммуникационное оборудование имеет таблицу для записей FDB, однако не все записи активны в каждый момент времени. База адресных данных является подмножеством (разделом) записей FDB, которые активны (могут быть сопоставлены с изучением адресов на RX или поиском в FDB на TX) в зависимости от состояния порта. В этом документе база адресных данных иногда называется идентификаторами фильтрации (FID или Filtering ID), хотя базовая реализация может выбрать все, что поддерживает оборудование. Например, все порты, принадлежащие мосту, не поддерживающему VLAN (в данный момент), предполагаются изучающими адреса отправителей в адресной базе, связанной драйвером с этим мостом (а не с другими мостами без поддержки VLAN). При пересылке и поиске в FDB пакета, принятого на порту моста без поддержки VLAN, следует обеспечивать возможность поиска не связанной с VLAN записи FDB с тем же MAC DA, что и в пакете, имеющуюся для другого порта того же моста. В тоже время, процесс поиска в FDB должен быть способен не найти (игнорировать) запись FDB с тем же MAC DA, что и в пакете, если эта запись указывает порт другого моста без поддержки VLAN (связана с другой базой адресов).

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

В этом контексте базе данных без VLAN соответствуют все пакеты независимо от VLAN ID (поиск лишь по адресу MAC), а в базе данных с VLAN сопоставление выполняется по VLAN ID из заголовка 802.1Q (или pvid, если тега нет).

На уровне моста записи FDB без поддержки VLAN имеют специальное значение VID 0, а в записях FDB с поддержкой VLAN идентификаторы VID отличны от 0. Отметим что не знающий о VLAN мост может иметь записи FDB с VLAN (ненулевой идентификатор VID), а мост с поддержкой VLAN может иметь записи FDB без VLAN. Как и аппаратные, программные мосты поддерживают раздельные базы адресных данных и выгружают в оборудование записи FDB, относящиеся к этим базам, через switchdev асинхронно относительно моментов их активации (деактивации).

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

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

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

DSA может выполнять фильтрацию адресов хостов для указанных ниже типов адресов.

  • Первичные индивидуальный MAC-адреса портов (dev->dev_addr). Эти адреса связаны с приватной базой адресов порта и драйвер уведомляется об их установке через port_fdb_add в направлении порта CPU.
  • Вторичные индивидуальные и групповые MAC-адреса портов (добавленные через dev_uc_add() и dev_mc_add()). Эти адреса тоже связаны с приватной базой адресов соответствующего пользовательского порта
  • Локальные/постоянные записи FDB моста (BR_FDB_LOCAL). Это MAC-адреса портов моста, для которых пакеты должны обрабатываться локально, без пересылки. Адреса связаны с базой данных этого моста.
  • Статические записи FDB моста, установленные для внешних (не DSA) интерфейсов, присутствующих в одном мосту с портами коммутатора DSA. Эти адреса также связаны с базой данных этого моста.
  • Динамически полученные записи FDB для внешних интерфейсов, присутствующих в одном мосту с портами коммутатора DSA, лишь при установке драйвером значения true для ds->assisted_learning_on_cpu_port. Адреса связаны с базой данных этого моста.

Для различных операций, описанных ниже, DSA предоставляет структуру dsa_db,
которая может иметь один из указанных
ниже типов.

DSA_DB_PORT

Устанавливаемая или удаляемая запись FDB (или MDB) для частной базы пользовательского порта db->dp.

DSA_DB_BRIDGE

Запись, относящаяся к одной из баз данных моста db->bridge. Предполагается, что драйвер разделяет базы без VLAN и базы на основе VID в этом мосту.

DSA_DB_LAG

Запись, относящаяся к адресной базе LAG db->lag. Отметим, что DSA_DB_LAG в настоящее время не используется, а в будущем может быть удалена.

Драйверам, использующим аргумент dsa_db в port_fdb_add, port_mdb_add и т. п., следует объявлять ds->fdb_isolation = true.

DSA связывает каждый выгруженный мост и каждую выгруженную группу LAG с идентификатором на основе 1 (struct
dsa_bridge :: num, struct dsa_lag :: id) для подсчёта адресов на совместно используемых портах. Драйверы могут использовать (piggyback) схему нумерации DSA (идентификатор считывается через db->bridge.num и db->lag.id) или реализовать свою схему.

Только драйверы, объявляющие поддержку изоляции FDB, уведомляются о записях FDB на порту CPU, относящихся в базам данных DSA_DB_PORT. Для совместимости адреса DSA_DB_BRIDGE сообщаются драйверам, даже не поддерживающим изоляцию FDB, однако в этом случае db->bridge.num и db->lag.id имеют значение 0 (чтобы указать отсутствие изоляции для целей подсчета).

Отметим, что от драйвера коммутатора не требуется реализация адресных баз данных для каждого автономного пользовательского порта. Поскольку записи FDB в приватных базах портов всегда указывают порт CPU, не возникает риска неверных решений о пересылке. В таких случаях все автономные порты могут пользоваться общей базой, но подсчёт ссылок на отфильтрованные хостом адреса(без удаления записей FDB для MAC-адресов порта, которые используются другими портами) возлагается на драйвер, поскольку DSA не знает, что базы портов на деле являются общими. Это можно обеспечить вызовом dsa_fdb_present_in_other_db() и dsa_mdb_present_in_other_db(). Недостатком является то, что списки входной (RX) фильтрации пользовательских портов фактически являются общими, а это означает, что пользовательский порт A может воспринять пакет с MAC DA, который не следует принимать, лишь потому, что этот MAC-адрес включён в RX-фильтр пользовательского порта B. Однако такие пакеты все равно будут отбрасываться программно.

Уровень моста

Выгрузка плоскости пересылки моста необязательна и обслуживается описанными ниже методами. Эти методы могут отсутствовать и возвращается -EOPNOTSUPP или ds->max_num_bridges может быть ненулевым и превышенным и в этом случае присоединение порта моста остаётся возможным, но пересылка пакетов будет выполняться программно, а порты программного моста должны быть настроены так же, как при автономной работе, т. е. все функции моста (изучение адресов и т. п.) должны быть отключены, а все принятые пакеты должны пересылаться лишь в порт CPU.

Порт начинает выгрузку плоскости пересылки после того, как он успешно выполняет метод port_bridge_join, и прекращает это делать после вызова port_bridge_leave. Выгрузка моста означает автономное изучение адресов (записей FDB) в соответствии с состоянием порта программного моста и автономную пересылку (или лавинную рассылку) полученных пакетов без вовлечения порта CPU. Это необязательно даже при выгрузке порта моста. Предполагается, что драйверы протокола тегов вызывают dsa_default_offload_fwd_mark(skb) для пакетов, которые уже пересылались автономно в домене пересылки входного порта коммутатора. DSA с помощью dsa_port_devlink_setup() считает все порты коммутатора, являющиеся частью одного дерева, относящимися к одному домену пересылки моста (способными автономно пересылать пакеты между собой).

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

Пакеты, для которых мост запрашивает такое поведение, называют пакетами плоскости данных и они имеют skb->offload_fwd_mark = true в функции xmit драйвера протокола тегов. Для пакетов плоскости данных выполняется поиск в FDB, аппаратное обучение на порту CPU, а состояние STP для порта не переопределяется. Кроме того, репликация пакетов плоскости данных (групповая и лавинная рассылка) обеспечивается оборудованием, а драйвер моста будет передавать 1 блок skb для каждого пакета, который может реплицироваться.

При включённой выгрузке TX-пересылки драйвер протокола тегов отвечает за внедрение пакетов в плоскость данных оборудования в направлении домена моста (FID), к которому относится порт. Порт может не понимать VLAN и в таком случае идентификатор FID должен совпадать с FID, используемым драйвером для адресной базы без VLAN, связанной с этим мостом. Мост может понимать VLAN и в этом случае гарантируется, что пакет имеет тег VLAN с VLAN ID, где мост обрабатывает этот пакет. Оборудование отвечает за снятие тега VID на выходных портах без тегов и сохранение его на выходных портах с тегами.

port_bridge_join

Функция уровня моста, вызываемая при добавлении в мост данного порта коммутатора. Этой функции следует делать все, что требуется на уровне коммутатора, чтобы разрешить добавление порта в соответствующий логический домен для приёма/передачи трафика других членов моста. Установка для аргумента tx_fwd_offload значения true ведёт к выгрузке и процесса TX-пересылки данного моста.

port_bridge_leave

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

port_stp_state_set

Функция уровня моста, вызываемая при расчёте статуса STP данного порта коммутатора уровнем моста. Статус порта следует передавать оборудованию коммутатора для пересылки, блокирования и изучения трафика.

port_bridge_flags

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

port_fast_age

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

Фильтрация VLAN в мостах

port_vlan_filtering

Функция уровня моста, вызываемая при включении или отключении на мосту фильтрации VLAN. Если на аппаратном уровне не требуется конкретных действий, этот обратный вызов (callback) можно не реализовать. При включении фильтрации VLAN оборудование должно быть запрограммировано на отклонение кадров 802.1Q, в которых VLAN ID выходит за рамки запрограммированных разрешённых отображений и правил VLAN ID. Если на порту коммутатора не запрограммировано PVID, должны отвергаться и кадры без тегов. При отключённой фильтрации коммутатор должен воспринимать любые кадры 802.1Q независимо от их VLAN ID, а также кадры без тегов.

port_vlan_add

Функция уровня моста, вызываемая при настройке VLAN (с тегами или без них) для данного порта коммутатора. Порт CPU становится членом VLAN лишь в том случае, когда порт другого (foreign) моста также входит в VLAN (и пересылка должна выполняться программно), или VLAN помещается в группу VLAN самого устройства моста для целей завершения (bridge vlan add dev br0 vid 100 self). Ссылки на VLAN общих (shared) портов учитываются и VLAN удаляется, если пользователей не остаётся. Драйвер не обязан вручную устанавливать VLAN на порту CPU.

port_vlan_del

Функция уровня моста, вызываемая при a VLAN is removed from the given switch port

port_fdb_add

Функция уровня моста, вызываемая при желании моста установить запись в базе пересылки FDB. На оборудовании коммутатора следует запрограммировать указанный адрес с VLAN ID в базе пересылки, связанной с этим VLAN ID.

port_fdb_del

Функция уровня моста, вызываемая при желании моста удалить запись из базы пересылки FDB. На оборудовании коммутатора следует запрограммировать удаление указанного MAC-адреса из VLAN ID, если он был отображён на данный порт в базе пересылки.

port_fdb_dump

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

port_mdb_add

Функция уровня моста, вызываемая при желании моста установить запись в групповой базе. На оборудовании коммутатора следует запрограммировать указанный адрес с VLAN ID в базе пересылки, связанной с этим VLAN ID.

port_mdb_del

Функция уровня моста, вызываемая при удалить запись из групповой базы. На оборудовании коммутатора следует запрограммировать удаление указанного MAC-адреса из VLAN ID, если он был отображён на данный порт в базе пересылки.

Агрегирование каналов

Агрегирование каналов реализовано в сетевом стеке Linux драйверами bonding и team, моделируемыми как виртуальные стековые сетевые интерфейсы. DSA может выгружать группы агрегирования каналов (link aggregation group или LAG) в оборудование, поддерживающее эту функцию, и поддерживать мосты между физическими портами и LAG, а также между LAG. Интерфейс bonding/team, содержащий несколько физических портов, представляет собой логический порт, хотя в настоящее время в DSA нет явной концепции логического порта. Поэтому события присоединения и отключения LAG от моста трактуются как присоединение или отключение всех отдельных физических портов данной группы LAG. Атрибуты (фильтрация VLAN, статус STP и т. п.) и объекты (VLAN, записи MDB) порта switchdev, выгруженные в LAG как порт моста, обрабатываются аналогично — DSA выгружает объект или атрибут порта switchdev для всех членов LAG. Статические записи FDB моста для LAG ещё не поддерживаются, поскольку API драйвера DSA не включает концепции идентификатора логического порта.

port_lag_join

Функция, вызываемая при добавлении данного порта в LAG. Драйвер может возвращать -EOPNOTSUPP
и в таких случаях DSA будет возвращаться к программной реализации, когда весь трафик из этого порта передаётся в CPU.

port_lag_leave

Функция, вызываемая при удалении данного порта из LAG и возвращающая порт в режим автономного.

port_lag_change

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

Драйверы, которым выгодно иметь идентификатор, связанный с каждой выгруженной группой LAG, могут заполнять значение ds->num_lag_ids из метода dsa_switch_ops::setup. LAG ID, связанный с интерфейсом bonding/team в этом случае может быть извлечён драйвером коммутатора DSA с помощью функции dsa_lag_id.

IEC 62439-2 (MRP)

Протокол резервирования среды (Media Redundancy Protocol или MRP) — это протокол управления топологией, оптимизированный для восстановления при отказах в кольцевых сетях, некоторые компоненты которого реализованы как функции драйвера моста. MRP использует управляющие PDU (Test, Topology, LinkDown/Up, Option), передаваемые по групповым MAC-адресам из диапазона 01:15:4e:00:00:0x с EtherType = 0x88e3. В зависимости от роли узла в кольце (MRM — Media Redundancy Manager, MRC — Media Redundancy Client, MRA — Media Redundancy Automanager) для некоторых MRP PDU может требоваться локальное завершение, для других же — пересылка. MRM может выигрывать от выгрузки в оборудование создания и передачи некоторых MRP PDU (Test).

Обычно экземпляр MRP может создаваться на базе любого сетевого интерфейса, однако в случае устройств с выгруженным путём данных, таких как DSA, требуется, чтобы оборудование (даже не поддерживающее MRP) было способно извлекать MRP PDU из модуля коммутации (fabric) до того, как драйвер сможет обработать их в программной реализации. На сегодняшний день в DSA нет драйверов, понимающих MRP, поэтому прослушиваются лишь минимальные объекты switchdev, требуемые для корректной работы программ, которые указаны ниже.

port_mrp_add и port_mrp_del

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

port_mrp_add_ring_role и port_mrp_del_ring_role

Функция, вызываемая при смене роли экземпляра MRP между MRM и MRC. Это определяет, какие MRP PDU следует захватывать (trap) программно, а какие — автономно пересылать.

IEC 62439-3 (HSR/PRP)

Протокол параллельного резервирования (Parallel Redundancy Protocol или PRP) обеспечивает резервирование сети путём дублирования и последовательной нумерации пакетов, передаваемых через 2 независимые сети L2 (которые не знают о наличии в конце пакетов тега PRP), и исключения дубликатов у получателя. Протокол бесшовного резервирования высокой доступности (High-availability Seamless Redundancy или HSR) использует похожие концепции, но все узлы, передающие резервный трафик, знают о тегах HSR (HSR использует заголовок с EtherType — 0x892f) и соединены в кольцо. HSR и PRP используют кадры наблюдения для мониторинга работоспособности сети и обнаружения узлов.

В Linux протоколы HSR и PRP реализованы в драйвере hsr, который создаёт виртуальный стековый сетевой интерфейс с двумя портами. Драйвер реализует лишь базовые роли узла с двойным подключением, реализующего HSR (Doubly Attached Node implementing HSR или DANH) или PRP (Doubly Attached Node implementing PRP или DANP), а роли RedBox и QuadBox не поддерживаются (поэтому мостовое соединения сетевого интерфейса hsr с физическим портом коммутатора не даёт ожидаемого результата).

Драйверу, способному выгружать некоторые функции DANP или DANH, следует объявлять соответствующие свойства netdev, как указано в файле Documentation/networking/netdev-features.rst. Кроме того, должны быть реализованы указанные ниже методы.

port_hsr_join

Функция, вызываемая при добавлении данного порта коммутатора в DANP/DANH. Драйвер может возвращать -EOPNOTSUPP и в таких случаях DSA будет возвращаться к программной реализации, когда весь трафик из этого порта передаётся в CPU.

port_hsr_leave

Функция, вызываемая при удалении данного порта коммутатора из DANP/DANH и возвращающая порт в режим автономного.

Продолжение работы

Объединение базы кода SWITCHDEV и DSA

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

Драйвер коммутатора Ethernet Broadcom RoboSwitch

Семейство коммутаторов Ethernet Broadcom RoboSwitch используется во многих маршрутизаторах xDSL, кабельных модемах и устройствах multimedia. Фактическая реализация поддерживает устройства BCM5325E, BCM5365, BCM539x, BCM53115 и BCM53125, а также BCM63XX.

Детали реализации

Файлы размещены в каталоге drivers/net/dsa/b53/ и реализуют драйвер DSA. Описание подсистемы и её функций приведено в файле Documentation/networking/dsa/dsa.rst.

Коммутатор, по возможности, настраивается на поддержку 4-байтовых тегов коммутатора Broadcom, которые коммутатор помещает в каждый пакет, пересылаемый на интерфейс CPU, а сетевому интерфейсу CPU следует вставлять аналогичный тег во все пакеты, поступающие в порт CPU. Формат тегов описан в файле net/dsa/tag_brcm.c.

Конфигурация устройства зависит от включения или отключения маркировки пакетов тегами.

Имена интерфейсов и примеры сетевой конфигурации соответствуют описанию в параграфе .

Конфигурация с поддержкой тегов

Желательно применять конфигурацию на основе тегов. Она не является специфической для драйвера DSA b53 и будет работать как и с другими драйверами DSA, поддерживающими теги (см . ).

Конфигурация без поддержки тегов

Более старые модели (5325, 5365) применяют иной формат тегов, который ещё не поддерживается. Для 539x и 531×5 требуется управляемый режим и особая обработка, которая также пока не поддерживается. В этих случаях теги не поддерживаются и коммутатору нужна другая конфигурация, несколько отличающаяся от описанной в параграфе .

Коммутатор b53 помечает тегами порт CPU во всех VLAN, поскольку иначе программирование VLAN без тегов PVID фактически изменит принятый по умолчанию идентификатор PVID порта CPU и сделает его безтеговым, что нежелательно.

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

Отдельный порт

Конфигурацию можно задать лишь через теги VLAN и настройку моста. По умолчанию применяется vid 1.

# Установка тегов для трафика на порту CPU
ip link add link eth0 name eth0.1 type vlan id 1
ip link add link eth0 name eth0.2 type vlan id 2
ip link add link eth0 name eth0.3 type vlan id 3

# Ведущий интерфейс должен быть поднят до ведомых портов.
ip link set eth0 up
ip link set eth0.1 up
ip link set eth0.2 up
ip link set eth0.3 up

# Активация ведомых интерфейсов
ip link set wan up
ip link set lan1 up
ip link set lan2 up

# Создание моста
ip link add name br0 type bridge

# Активация фильтров VLAN 
ip link set dev br0 type bridge vlan_filtering 1

# Добавление портов в мост
ip link set dev wan master br0
ip link set dev lan1 master br0
ip link set dev lan2 master br0

# Установка тегов для трафика на портах
bridge vlan add dev lan1 vid 2 pvid untagged
bridge vlan del dev lan1 vid 1
bridge vlan add dev lan2 vid 3 pvid untagged
bridge vlan del dev lan2 vid 1

# Настройка VLAN
ip addr add 192.0.2.1/30 dev eth0.1
ip addr add 192.0.2.5/30 dev eth0.2
ip addr add 192.0.2.9/30 dev eth0.3

# Активация моста
ip link set br0 up

Мост

# Установка тегов для трафика на порту CPU
ip link add link eth0 name eth0.1 type vlan id 1

# Ведущий интерфейс должен быть поднят до ведомых портов.
ip link set eth0 up
ip link set eth0.1 up

# Активация ведомых интерфейсов
ip link set wan up
ip link set lan1 up
ip link set lan2 up

# Создание моста
ip link add name br0 type bridge

# Активация фильтров VLAN 
ip link set dev br0 type bridge vlan_filtering 1

# Добавление портов в мост
ip link set dev wan master br0
ip link set dev lan1 master br0
ip link set dev lan2 master br0
ip link set eth0.1 master br0

# Настройка моста
ip addr add 192.0.2.129/25 dev br0

# Активация моста
ip link set dev br0 up

Шлюз

# Установка тегов для трафика на порту CPU
ip link add link eth0 name eth0.1 type vlan id 1
ip link add link eth0 name eth0.2 type vlan id 2

# Ведущий интерфейс должен быть поднят до ведомых портов.
ip link set eth0 up
ip link set eth0.1 up
ip link set eth0.2 up

# Активация ведомых интерфейсов
ip link set wan up
ip link set lan1 up
ip link set lan2 up

# Создание моста
ip link add name br0 type bridge

# Активация фильтров VLAN
ip link set dev br0 type bridge vlan_filtering 1

# Добавление портов в мост
ip link set dev wan master br0
ip link set eth0.1 master br0
ip link set dev lan1 master br0
ip link set dev lan2 master br0

# Установка тегов для трафика на портах
bridge vlan add dev wan vid 2 pvid untagged
bridge vlan del dev wan vid 1

# Настройка VLAN
ip addr add 192.0.2.1/30 dev eth0.2
ip addr add 192.0.2.129/25 dev br0

# Активация моста
ip link set br0 up

Драйвер коммутатора Ethernet Broadcom Starfighter 2

Аппаратные модули коммутаторов Ethernet Broadcom Starfighter 2 применяются в нескольких типах устройств:

  • шлюзы xDSL, такие как BCM63138;
  • приставки (Set Top Box) для потокового вещания и multimedia, такие как BCM7445;
  • кабельные модемы и домашние шлюзы, такие как BCM7145/BCM3390.

Коммутатор обычно имеет от 5 до 13 портов, обеспечивая ряд встроенных и настраиваемых интерфейсов:

  • 1 встроенный интерфейс Gigabit PHY;
  • 4 встроенных Gigabit PHY;
  • 4 внешних Gigabit PHY с мультиплексором MDIO;
  • встроенный MoCA PHY
  • несколько внешних интерфейсов MII/RevMII/GMII/RGMII;

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

Блок аппаратного коммутатора обычно имеет интерфейс с доступом MMIO и содержит набор регистров (субблоков):

  • SWITCH_CORE
    — общие регистры коммутатора;
  • SWITCH_REG
    — регистр внешних интерфейсов коммутатора;
  • SWITCH_MDIO
    — контроллер внешней шины MDIO (в SWITCH_CORE имеется ещё один для непрямого доступа к PHY);
  • SWITCH_INDIR_RW
    — блок вспомогательных 64-битовых регистров;
  • SWITCH_INTRL2_0/1
    — контроллеры прерываний L2;
  • SWITCH_ACB
    — блок управления допуском;
  • SWITCH_FCB
    — блок управления преодолением отказов.

Детали реализации

Драйвер находится в файле drivers/net/dsa/bcm_sf2.c и реализован как драйвер DSA. Подсистема и её функции описаны в файле Documentation/networking/dsa/dsa.rst.

Коммутатор SF2 настраивается на вставку 4-байтовых тегов коммутатора Broadcom, которые помещаются в каждый пакет, пересылаемый на интерфейс CPU, а сетевому интерфейсу CPU следует вставлять аналогичный тег во все пакеты, поступающие в порт CPU. Формат тегов описан в файле net/dsa/tag_brcm.c.

В целом драйвер SF2 является обычным драйвером DSA, но имеет некоторые особенности, описанные ниже.

Зондирование дерева устройств

Драйвер устройства платформы DSA зондируется с использованием специальной строки совместимости, представленной в файле net/dsa/dsa.c. Это связано с тем, что подсистема DSA в настоящее время регистрируется как драйвер устройства платформы. DSA предоставляет требуемые указатели device_node, которые становятся доступными функции установки драйвера устройства для организации ресурсов, таких как диапазоны регистров и прерывания. В настоящее время это работает очень хорошо, поскольку ни одной из используемых драйвером функций of_* не требуется привязка структуры device к структуре device_node, но в будущем это может измениться.

Опосредованный доступ к MDIO

Ограничения при разработке коммутаторов Broadcom требуют для внешних коммутаторов Broadcom, подключённых к SF2, использовать ведомую шину DSA MDIO для их настройки. По умолчанию адреса псевдо-PHY коммутатора SF2 и внешнего коммутатора будут отслеживать входящие транзакции MDIO, поскольку они находятся по одному адресу (30), что ведёт к «двойному» программированию. Использование DSA и установка ds->phys_mii_mask перенаправляют операции чтения и записи на адреса псевдо-PHY внешних коммутаторов Broadcom. В новых версиях оборудования SF2 добавлен настраиваемый адрес псевдо-PHY, что позволяет преодолеть это ограничение.

Мультимедиа через интерфейсы CoAxial (MoCA)

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

Интерфейсы MoCA поддерживаются с использованием фиксированных/эмулируемых устройств PHY библиотеки PHY и драйвер коммутатора регистрирует для таких PHY обратный вызов (callback) fixed_link_update,
который отражает состояние канала, полученное от обработчика прерываний.

Управление питанием

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

  • отключения внутренних буферов и памяти;
  • отключения логики обработки пакетов;
  • перевода встроенных PHY в режим IDDQ/low-power;
  • снижение тактовой частоты ядра коммутатора в зависимости от числа активных портов;
  • включение и анонсирование EEE;
  • отключение логики обработки данных RGMII при обрыве (down) канала связи.

Wake-on-LAN

Функция пробуждения из сети (Wake-on-LAN или WoL) в настоящее время реализована с использованием логики включения контроллера Ethernet MAC на процессоре хоста. При запросе Wake-on-LAN определяется пересечение запроса пользователя и возможностей WoL на интерфейсе Ethernet хоста и используется результат. При остановке и восстановлении работы на уровне системы в целом отключаются лишь порты, не участвующие в Wake-on-LAN.

Драйвер коммутатора Ethernet LAN9303

LAN9303 — это 3-портовый коммутатор Ethernet 10/100 Мбит/с со встроенными PHY для двух внешних портов Ethernet. Третий порт является интерфейсом RMII/MII для первичного сетевого интерфейса хоста (например, постоянного канала).

Детали драйвера

Драйвер реализован как драйвер DSA, см. Documentation/networking/dsa/dsa.rst. Привязки к дереву устройств описаны в файле Documentation/devicetree/bindings/net/dsa/lan9303.txt.

Управление LAN9303 возможно через MDIO и I2C, поддерживаемые драйвером.

При запуске драйвер настраивает устройство для предоставления двух раздельных сетевых интерфейсов (принятое по умолчанию состояние устройства DSA). Из-за аппаратных ограничений в этом режиме не поддерживается аппаратное изучение MAC-адресов.

Когда оба пользовательских порта присоединены к одному мосту, включается обычное аппаратное изучение MAC-адресов. Это означает, что индивидуальный трафик пересылается на аппаратном уровне. Широковещательные и групповые кадры пересылаются лавинно на аппаратном уровне. В этом режиме поддерживается также протокол STP. Драйвер поддерживает операции FDB/MDB, что означает поддержку протокола IGMP.

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

Ограничения драйвера

  • Не реализована поддержка фильтрации VLAN.
  • Оборудование не поддерживает связанные с VLAN записи FDB.

Драйвер коммутатора Ethernet NXP SJA1105

Обзор

NXP SJA1105 — это семейство из 10 автомобильных коммутаторов с управлением SPI:

  • SJA1105E — первое поколение без TTEthernet;
  • SJA1105T — первое поколение с TTEthernet;
  • SJA1105P — второе поколение без TTEthernet и SGMII;
  • SJA1105Q — второе поколение с TTEthernet, но без SGMII;
  • SJA1105R — второе поколение без TTEthernet, но с SGMII;
  • SJA1105S — второе поколение с TTEthernet и SGMII;
  • SJA1110A — третье поколение с TTEthernet, SGMII, встроенными PHY 100base-T1 и 100base-TX PHY;
  • SJA1110B — третье поколение с TTEthernet, SGMII, 100base-T1, 100base-TX;
  • SJA1110C — третье поколение с TTEthernet, SGMII, 100base-T1, 100base-TX;
  • SJA1110D — третье поколение с TTEthernet, SGMII, 100base-T1.

Поскольку коммутаторы являются компонентами автомобиля, их интерфейс настройки ориентирован на принцип «установил и забыл» с минимальным динамическим взаимодействием при работе. Для этого нужно создать статическую конфигурацию программными средствами, упаковать её с CRC и заголовками таблиц и передать через SPI. Статическая конфигурация состоит из нескольких таблиц, часть которых может изменяться (перенастраиваться) в процессе работы. Некоторые таблицы обязательны, другие — нет.

Таблица Обязательна Перенастройка
Планирование нет нет
Точки входа планирования При включённом планировании нет
Поиск VL нет нет
Правила VL При включённом поиске VL нет
Пересылка VL При включённом поиске VL нет
Поиск L2 нет нет
Правила L2 да нет
Поиск VLAN да да
Пересылка L2 да частичная (полная на P/Q/R/S)
Конфигурация MAC да частичная (полная на P/Q/R/S)
Параметры планирования При включённом планировании нет
Параметры точек входа планирования При включённом планировании нет
Параметры пересылки VL При включённой пересылке VL нет
Параметры поиска L2 нет частичная (полная на P/Q/R/S)
Параметры пересылки L2 да нет
Параметры синхронизации часов нет нет
Параметры AVB нет нет
Общие параметры да частичная
Смена тегов нет да
Параметры xMII да нет
SGMII нет да

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

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

Свойства коммутации

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

Оборудование помечает весь трафик тега VLAN по портам (pvid) или декодирует сведения о VLAN из тегов 802.1Q. Расширенная классификация VLAN не поддерживается. После определения тега VLAN кадры проверяются по правилам принадлежности и отбрасываются на входе, если они не соответствуют какой-либо VLAN. Это доступно в случае подключения портов коммутатора к мосту с vlan_filtering = 1.

Обычно оборудование не настраивается в части поддержки VLAN, но изменение TPID, по которому коммутатор ищет теги 802.1Q, позволяет сохранить семантику моста с vlan_filtering = 0 (принимать весь трафик, независимо от тегов), поэтому такой режим тоже поддерживается.

Поддерживается разделение портов коммутатора между несколькими мостами (например, 2 + 2), но всем мостам следует использовать общий уровень осведомлённости о VLAN (значение 0 или 1 для vlan_filtering у всех).

Поддерживается определение топологии и обнаружение петель с помощью протокола STP.

Выгрузка

Планирование с учётом времени

Коммутатор поддерживает вариант усовершенствований для планирования трафика, заданный в IEEE 802.1Q-2018 (ранее 802.1Qbv). Это означает возможность использования коммутатора для обеспечения детерминированной задержки приоритетного трафика, передаваемого вместе (in-band) с событием gate-open в сетевом планировании. Этой возможностью можно управлять через выгрузку tc-taprio (flags 2). Отличие от программной реализации taprio состоит в том, что последняя способна управлять лишь трафиком от CPU, не не пересылаемыми автономно потоками.

Устройство поддерживает 8 классов и отображает входящие кадры на один из них на основе битов VLAN PCP (при отсутствии VLAN используются принятые по умолчанию по портам). Как описано выше, в зависимости от значения vlan_filtering, поле EtherType, распознаваемое коммутатором как VLAN, может иметь значение 0x8100 или настраиваемое значение, используемое драйвером для тегов. Поэтому коммутатор игнорирует VLAN PCP при использовании в автономном режиме или в мосту с vlan_filtering=0, поскольку он не распознаёт EtherType 0x8100. В этих режимах внедрение в конкретную очередь на передачу (TX) возможно лишь для сетевых устройств DSA, которые на выходу включают теги в поле PCP. При vlan_filtering=1
поведение меняется на обратное, выгруженные потоки могут направляться в очереди TX на основе VLAN PCP, но сетевые устройства DSA уже не могут этого делать. Для внедрения кадров в аппаратную очередь TX при включённой поддержке VLAN требуется создать субинтерфейс VLAN на ведущем порту DSA и передавать обычные (0x8100) кадры с тегами VLAN в направлении коммутатора с соответствующей установкой VLAN PCP.

Трафик управления (с DMAC 01-80-C2-xx-xx-xx или 01-19-1B-xx-xx-xx) является исключением и коммутатор всегда обрабатывает его с фиксированным приоритетом без учёта битов VLAN PCP, если они установлены. Для трафика управления в настоящее время используется класс 7 (высший приоритет), который не настраивается в драйвере.

Ниже приведён пример настройки планирования с циклом 500 мсек на выходном порту swp5. Шлюз для управляющего трафика (7) открыт на 100 мсек, для остальных классов — на 400 мсек.

#!/bin/bash

set -e -u -o pipefail

NSEC_PER_SEC="1000000000"

gatemask() {
        local tc_list="$1"
        local mask=0

        for tc in ${tc_list}; do
                mask=$((${mask} | (1 << ${tc})))
        done

        printf "%02x" ${mask}
}

if ! systemctl is-active --quiet ptp4l; then
        echo "Please start the ptp4l service"
        exit
fi

now=$(phc_ctl /dev/ptp1 get | gawk '/clock time is/ { print $5; }')
# Фазовое выравнивание базового времени относительно начала следующей секунды.
sec=$(echo "${now}" | gawk -F. '{ print $1; }')
base_time="$(((${sec} + 1) * ${NSEC_PER_SEC}))"

tc qdisc add dev swp5 parent root handle 100 taprio \
        num_tc 8 \
        map 0 1 2 3 5 6 7 \
        queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 \
        base-time ${base_time} \
        sched-entry S $(gatemask 7) 100000 \
        sched-entry S $(gatemask "0 1 2 3 4 5 6") 400000 \
        flags 2

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

Маршрутизация (redirect, trap, drop)

Коммутатор способен выгружать основанное на потоках перенаправление в набор портов, заданных пользователем. В коммутаторе это реализовано путём использования виртуальных каналов (Virtual Link или VL) — концепции TTEthernet.

Коммутатор поддерживает для VL 2 типа ключей:

  • виртуальные каналы с поддержкой VLAN соответствуют MAC-адресу получателя, VLAN ID и VLAN PCP;
  • виртуальные каналы без поддержки VLAN соответствуют лишь MAC-адресу получателя.

Состояние осведомлённости моста о VLAN (vlan_filtering) не может быть изменено, пока установлены правила для VL. В одном правиле может применяться несколько действий. Если нужна лишь маршрутизация, драйвер создаёт «некритичный» виртуальный канал. Если список действий включает также tc-gate (см. ниже), виртуальный канал становится «критичным по времени» (извлекает буферы кадров из зарезервированного раздела памяти и т. п.).

Поддерживается 3 действия по маршрутизации: ловушка (trap), отбрасывание (drop) и перенаправление (redirect).

Пример 2. Передача кадров, полученных на swp2 с DA 42:be:24:9b:76:20, в CPU и swp3. Этот тип ключа (только DA) относится к отключённой поддержке VLAN на порту

tc qdisc add dev swp2 clsact
tc filter add dev swp2 ingress flower skip_sw dst_mac 42:be:24:9b:76:20 \
        action mirred egress redirect dev swp3 \
        action trap

Пример 2. Отбрасывание кадров, полученных на swp2 с DA of 42:be:24:9b:76:20, VID 100 и PCP 0

tc filter add dev swp2 ingress protocol 802.1Q flower skip_sw \
        dst_mac 42:be:24:9b:76:20 vlan_id 100 vlan_prio 0 action drop

Входные правила с учётом времени

Аппаратные возможности TTEthernet в коммутаторе могут быть ограничены для работы в соответствии с пунктом «Фильтрация и правила по потокам» (Per-Stream Filtering and Policing или PSFP) стандарта IEEE 802.1Q-2018 (ранее 802.1Qci). Это означает возможность жёсткого контроля допуска по времени для множества (до 1024) потоков, задаваемых MAC-адресом получателя, VLAN ID и VLAN PCP. Пакеты, полученные за пределами ожидаемого окна приёма, отбрасываются. Этой возможностью можно управлять путём выгрузки действия tc-gate. Поскольку действия по маршрутизации присущи виртуальным каналам в TTEthernet (явная маршрутизация критичного ко времени трафика без отдачи на откуп FDB, лавинной рассылке и т. п.), действие tc-gate не может возникать само по себе, если запросить у sja1105 выгрузку его. За этим действием должно следовать 1 или несколько действий redirect или trap.

Создадим, например, расписание tc-taprio, согласованное по фазе с расписанием tc-gate (часы должны быть синхронизированы стеком приложения 1588, но это выходит за рамки документа). Ни один из пакетов, доставленных отправителем, не будет отброшен. Отметим, что окно приёма больше окна передачи (в этом примере намного больше) для компенсации задержки распространения в канале (которую может определить стек приложения 1588).

Получатель (sja1105)

tc qdisc add dev swp2 clsact
now=$(phc_ctl /dev/ptp1 get | awk '/clock time is/ {print $5}') && \
        sec=$(echo $now | awk -F. '{print $1}') && \
        base_time="$(((sec + 2) * 1000000000))" && \
        echo "base time ${base_time}"
tc filter add dev swp2 ingress flower skip_sw \
        dst_mac 42:be:24:9b:76:20 \
        action gate base-time ${base_time} \
        sched-entry OPEN  60000 -1 -1 \
        sched-entry CLOSE 40000 -1 -1 \
        action trap

Отправитель

now=$(phc_ctl /dev/ptp0 get | awk '/clock time is/ {print $5}') && \
        sec=$(echo $now | awk -F. '{print $1}') && \
        base_time="$(((sec + 2) * 1000000000))" && \
        echo "base time ${base_time}"
tc qdisc add dev eno0 parent root taprio \
        num_tc 8 \
        map 0 1 2 3 4 5 6 7 \
        queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 \
        base-time ${base_time} \
        sched-entry S 01  50000 \
        sched-entry S 00  50000 \
        flags 2

Для планирования работы входных шлюзов применяется тот же механизм, что и для выгрузки tc-taprio, поэтому сохраняются ограничения, связанные с невозможностью одновременного (в течение одного интервала в 200 нсек) срабатывания двух шлюзов (tc-gate или tc-taprio).

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

tc qdisc add dev swp2 ingress_block 1 clsact
tc qdisc add dev swp3 ingress_block 1 clsact
tc filter add block 1 flower skip_sw dst_mac 42:be:24:9b:76:20 \
        action gate index 2 \
        base-time 0 \
        sched-entry OPEN 50000000 -1 -1 \
        sched-entry CLOSE 50000000 -1 -1 \
        action trap

Доступна также аппаратная статистика для каждого потока (pkts учитывает число отброшенных кадров, указывающее сумму кадров, отброшенных из-за временных ограничений, отсутствия портов назначения и превышения MTU). Счётчики байтов недоступны.

Ограничения

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

Ключи виртуальных каналов фиксированы {MAC DA, VLAN ID, VLAN PCP}, но драйвер запрашивает VLAN ID и VLAN PCP, если порт относится к мосту с поддержкой VLAN. В иных случаях драйвер автоматически указывает VLAN ID и VLAN PCP в зависимости от того, является порт автономным или относится к мосту без VLAN, и воспринимает лишь ключи tc-flower без поддержки VLAN (MAC DA).

Имеющиеся ключи tc-flower, выгруженные с использованием виртуальных каналов, перестают работать, при возникновении одного из указанных ниже обстоятельств:

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

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

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

Этот раздел основан на файле Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml и демонстрирует некоторые предостережения при работе с коммутаторами.

Роль RMII PHY и сигнализация по отдельному каналу

По спецификации RMII тактовые сигналы 50 МГц подаются от MAC или внешнего генератора (но не от PHY). Однако спецификация предоставляет достаточно свободы и устройства часто выходят за её пределы. Некоторые PHY идут наперекор спецификации и предоставляют вывод, на которых они подают сигнал 50 МГц, пытаясь быть полезными. Коммутатор SJA1105 настраивается только двоичным путём и в роли RMII MAC он тоже пытается управлять тактовым сигналом. Чтобы этого не происходило, коммутатор нужно перевести в режим RMII PHY, однако это ведёт к некоторым нежелательным последствиям. По спецификации RMII устройство PHY может передавать дополнительные внеполосные сигналы через RXD[1:0]. Практически это несколько дополнительных кодовых слов ((/J/ и /K/), передаваемых до преамбулы каждого кадра. В MAC нет такого механизма внеполосной сигнализации, определяемого спецификацией RMII. Поэтому при переводе порта SJA1105 в роль PHY для исключения двух источников тактовых сигналов неизбежно возникает соединение RMII PHY-to-PHY. Коммутатор SJA1105 полностью эмулирует интерфейс PHY и генерирует символы /J/ и /K/ перед преамбулой кадра, которые предполагаются непонятными для реального PHY. Поэтому PHY просто кодирует дополнительные символы, полученные от SJA1105 в роли PHY, в линию 100Base-Tx. На другом конце линии некоторые партнёры по каналу могут отбрасывать эти дополнительные символы, но другие могут «подавиться» ими и отбросить весь кадр Ethernet. Это выглядит как потеря пакета на некоторых каналах. Поэтому в режиме RMII коммутатор SJA1105 должен быть способен служить тактовым генератором при соединении с PHY.

RGMII стационарных каналов и внутренние задержки

Второе поколение устройств имеет настраиваемые линии задержки (часть MAC), которые можно использовать для организации корректного бюджета времени RGMII. При включении питания линии могут смещать часы Rx и Tx по фазе на величину от 73,8 до 101,7 градуса. Сложность заключается в том, что линии задержки нужно привязывать к тактовому сигналу со стабильной частотой. Это означает, что между тактовыми сигналами старой и новой частоты должно быть не менее 2 мксек тишины. В противном случае синхронизация теряется и линии задержки нужно сбрасывать (выключать и включать снова). В RGMII тактовая частота зависит от скорости канала (125 МГц для 1000 Мбит/с, 25 МГц для 100 Мбит/с и 2,5 МГц для 10 Мбит/с), которая может меняться в процессе автоматического согласования. В ситуации, когда порт коммутатора подключён к партнёру по стационарному каналу RGMII и состояние этого канала не контролируется Linux (например, другая микросхема SoC), линии задержки остаются разблокированными (и неактивными) без ручного вмешательства (ifdown/ifup на порту коммутатора). В результате этого в режиме RGMII внутренние задержки в коммутаторе будут надёжными лишь в случаях, когда скорость канала к партнёру не меняется или меняется согласованно с портом коммутатора (практически, обе стороны канала находятся под управлением одной системы Linux). В части изменения скорости стационарного канала следует помнить, что есть контроллеры Ethernet, которые при перезапуске устанавливают режим 100 Мбит/с и требуют смены тактовой частоты для перехода не гигабитную скорость.

Шина MDIO и управление PHY

SJA1105 не имеет шины MDIO и не выполняет автонастройки по основному каналу, поэтому от коммутационного устройства не поступает уведомлений о статусе канала. Плате нужно «перехватывать» (hook) PHY коммутатора, подключённые к какой-либо шине MDIO, доступной для Linux внутри системы (например, к шине MDIO ведущего DSA). Управление состоянием канала в этом случае выполняется драйвером «вручную» путём синхронизации (с помощью команд SPI) скорости канала MAC с установками, согласованными PHY.

SJA1110 поддерживает ведомую точку доступа MDIO, через которую с хоста можно обращаться к внутренним 100base-T1 PHY. Однако эта точка не используется драйвером, а доступ к внутренним PHY 100base-T1 и 100base-TX осуществляется через команды SPI, моделируемые в Linux как виртуальные шины MDIO.

Микроконтроллер, подключённый к порту 0 в SJA1110, имеет контроллер MDIO, работающий в режиме первичного (master), однако драйвер его не поддерживает, поскольку микроконтроллер отключается при работе драйвера Linux. Дискретным PHY, подключённым к портам коммутатора, следует иметь интерфейс MDIO, подключённый к контроллеру MDIO хост-системы, а не коммутатора, как в случае SJA1105.

Матрица совместимости портов

Матрица совместимости портов SJA1105 показана в таблице.

Порт SJA1105E/T SJA1105P/Q SJA1105R/S
0 xMII xMII xMII
1 xMII xMII xMII
2 xMII xMII xMII
3 xMII xMII xMII
4 xMII xMII SGMII

Матрица совместимости портов SJA1110 показана в следующей таблице.

Порт SJA1110A SJA1110B SJA1110C SJA1110D
0 RevMII (uC) RevMII (uC) RevMII (uC) RevMII (uC)
1 100base-TX или SGMII 100base-TX 100base-TX SGMII
2 xMII или SGMII xMII xMII xMII или SGMII
3 XMII, SGMII или 2500base-X XMII, SGMII или 2500base-X xMII SGMII или 2500base-X
4 SGMII или 2500base-X SGMII или 2500base-X SGMII или 2500base-X SGMII или 2500base-X
5 100base-T1 100base-T1 100base-T1 100base-T1
6 100base-T1 100base-T1 100base-T1 100base-T1
7 100base-T1 100base-T1 100base-T1 100base-T1
8 100base-T1 100base-T1
9 100base-T1 100base-T1
10 100base-T1

Настройка коммутатора из пользовательского пространства

Настройка конфигурации коммутатора DSA в настоящее время не интегрирована с основными пакетами настройки конфигурации сети и должна выполняться вручную.

Варианты конфигурации

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

Одиночный порт

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

Мост

Каждый порт коммутатора является частью одного настраиваемого моста Ethernet.

Шлюз

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

Все настройки выполняются с помощью команд iproute23.

Через DSA каждый порт коммутатора обслуживается как обычный интерфейс Linux Ethernet. Порт CPU в коммутаторе соединён с микросхемой Ethernet MAC. Соответствующий интерфейс Linux Ethernet называется ведущим (master), остальные — ведомыми. Чтобы ведомые интерфейсы могли принимать и передавать трафик, должен быть включён ведущий интерфейс. В ядрах до версии v5.12 состоянием ведущего интерфейса явно управлял пользователь, но в ядрах, начиная с v5.12, поведение изменилось:

  • при активации ведомого интерфейса DSA ведущий интерфейс активируется автоматически;
  • при отключении (down) ведущего интерфейса все ведомые интерфейсы DSA отключаются автоматически.

В этом документе используются указанные ниже интерфейсы Ethernet.

eth0

Ведущий интерфейс.

eth1

Второй ведущий интерфейс.

lan1

Ведомый интерфейс.

lan2

Второй ведомый интерфейс.

lan3

Третий ведомый интерфейс.

wan

Ведомый интерфейс, выделенный для восходящего трафика.

Другие интерфейсы Ethernet могут настраиваться аналогично. Адреса IP и сети указаны ниже.

Отдельный порт

  • lan1: 192.0.2.1/30 (192.0.2.0 — 192.0.2.3)
  • lan2: 192.0.2.5/30 (192.0.2.4 — 192.0.2.7)
  • lan3: 192.0.2.9/30 (192.0.2.8 — 192.0.2.11)

Мост

  • br0: 192.0.2.129/25 (192.0.2.128 — 192.0.2.255)

Шлюз

  • br0: 192.0.2.129/25 (192.0.2.128 — 192.0.2.255)
  • wan: 192.0.2.1/30 (192.0.2.0 — 192.0.2.3)

Конфигурация с поддержкой тегов

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

Отдельный порт
# Настройка каждого интерфейса.
ip addr add 192.0.2.1/30 dev lan1
ip addr add 192.0.2.5/30 dev lan2
ip addr add 192.0.2.9/30 dev lan3

# Для ядер до v5.12 ведущий интерфейс нужно активировать вручную
# до активации любого из ведомых портов.
ip link set eth0 up

# Активация ведомых интерфейсов.
ip link set lan1 up
ip link set lan2 up
ip link set lan3 up
Мост
# Для ядер до v5.12 ведущий интерфейс нужно активировать вручную
# до активации любого из ведомых портов.
ip link set eth0 up

# Активация ведомых интерфейсов.
ip link set lan1 up
ip link set lan2 up
ip link set lan3 up

# Создание моста.
ip link add name br0 type bridge

# Добавление портов моста.
ip link set dev lan1 master br0
ip link set dev lan2 master br0
ip link set dev lan3 master br0

# Настройка моста.
ip addr add 192.0.2.129/25 dev br0

# Активация моста
ip link set dev br0 up
Шлюз
# Для ядер до v5.12 ведущий интерфейс нужно активировать вручную
# до активации любого из ведомых портов.
ip link set eth0 up

# Активация ведомых интерфейсов.
ip link set wan up
ip link set lan1 up
ip link set lan2 up

# Настройка восходящего порта.
ip addr add 192.0.2.1/30 dev wan

# Создание моста.
ip link add name br0 type bridge

# Добавление портов моста.
ip link set dev lan1 master br0
ip link set dev lan2 master br0

# Настройка моста.
ip addr add 192.0.2.129/25 dev br0

# Активация моста.
ip link set dev br0 up

Конфигурация без поддержки тегов

Незначительная часть коммутаторов не способна использовать протокол тегов (DSA_TAG_PROTO_NONE). Их можно настраивать на основе VLAN.

Отдельный порт

Конфигурацию можно задать лишь через теги VLAN и организацию (setup) моста.

# Теги трафика на порту CPU.
ip link add link eth0 name eth0.1 type vlan id 1
ip link add link eth0 name eth0.2 type vlan id 2
ip link add link eth0 name eth0.3 type vlan id 3

# Для ядер до v5.12 ведущий интерфейс нужно активировать вручную
# до активации любого из ведомых портов.
ip link set eth0 up
ip link set eth0.1 up
ip link set eth0.2 up
ip link set eth0.3 up

# Активация ведомых интерфейсов.
ip link set lan1 up
ip link set lan2 up
ip link set lan3 up

# Создание моста.
ip link add name br0 type bridge

# Активация фильтров VLAN.
ip link set dev br0 type bridge vlan_filtering 1

# Добавление портов моста.
ip link set dev lan1 master br0
ip link set dev lan2 master br0
ip link set dev lan3 master br0

# Теги трафика на портах.
bridge vlan add dev lan1 vid 1 pvid untagged
bridge vlan add dev lan2 vid 2 pvid untagged
bridge vlan add dev lan3 vid 3 pvid untagged

# Настройка VLAN.
ip addr add 192.0.2.1/30 dev eth0.1
ip addr add 192.0.2.5/30 dev eth0.2
ip addr add 192.0.2.9/30 dev eth0.3

# Активация моста.
ip link set br0 up
Мост
# Теги трафика на порту CPU.
ip link add link eth0 name eth0.1 type vlan id 1

# Для ядер до v5.12 ведущий интерфейс нужно активировать вручную
# до активации любого из ведомых портов.
ip link set eth0 up
ip link set eth0.1 up

# Активация ведомых интерфейсов.
ip link set lan1 up
ip link set lan2 up
ip link set lan3 up

# Создание моста.
ip link add name br0 type bridge

# Активация фильтров VLAN.
ip link set dev br0 type bridge vlan_filtering 1

# Добавление портов моста.
ip link set dev lan1 master br0
ip link set dev lan2 master br0
ip link set dev lan3 master br0
ip link set eth0.1 master br0

# Теги трафика на портах.
bridge vlan add dev lan1 vid 1 pvid untagged
bridge vlan add dev lan2 vid 1 pvid untagged
bridge vlan add dev lan3 vid 1 pvid untagged

# Настройка моста.
ip addr add 192.0.2.129/25 dev br0

# Активация моста
ip link set dev br0 up
Шлюз
# Теги трафика на порту CPU.
ip link add link eth0 name eth0.1 type vlan id 1
ip link add link eth0 name eth0.2 type vlan id 2

# Для ядер до v5.12 ведущий интерфейс нужно активировать вручную
# до активации любого из ведомых портов.
ip link set eth0 up
ip link set eth0.1 up
ip link set eth0.2 up

# Активация ведомых интерфейсов.
ip link set wan up
ip link set lan1 up
ip link set lan2 up

# Создание моста.
ip link add name br0 type bridge

# Активация фильтров VLAN.
ip link set dev br0 type bridge vlan_filtering 1

# Добавление портов моста.
ip link set dev wan master br0
ip link set eth0.1 master br0
ip link set dev lan1 master br0
ip link set dev lan2 master br0

# Теги трафика на портах.
bridge vlan add dev lan1 vid 1 pvid untagged
bridge vlan add dev lan2 vid 1 pvid untagged
bridge vlan add dev wan vid 2 pvid untagged

# Настройка VLAN.
ip addr add 192.0.2.1/30 dev eth0.2
ip addr add 192.0.2.129/25 dev br0

# Активация моста.
ip link set br0 up

Управление базой пересылки (FDB)

В имеющихся коммутаторах DSA нет поддержки синхронизации программной базы FDB моста с аппаратными таблицами, поэтому управление этими таблицами выполняется раздельно — команда bridge fdb show запрашивает обе таблицы, а команды bridge fdb add и bridge fdb del применяются к одной или обеим таблицам в зависимости от флагой self и master.

В ядрах до v4.14 управление записями FDB моста поддерживалось DSA из пользовательского пространства лишь с помощью операций обхода моста (обновляют лишь аппаратную таблицу, но не FDB) с флагом self (необязателен).

bridge fdb add dev swp0 00:01:02:03:04:05 self static
# или
bridge fdb add dev swp0 00:01:02:03:04:05 static

Из-за ошибки реализация обхода моста в DSA не различала статические и локальные записи FDB (статические предназначены для пересылки, а локальные — для завершения в коммутаторе, т. е. передачи в порт хоста). Записи FDB с флагом self (явным или неявным) трактовались DSA как статические, даже будучи локальными.

# Приведённая ниже команда
bridge fdb add dev swp0 00:01:02:03:04:05 static
# ведёт себя для DSA как команда
bridge fdb add dev swp0 00:01:02:03:04:05 local
# или сокращённо, поскольку флаг local предполагается, если не задан static.
bridge fdb add dev swp0 00:01:02:03:04:05

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

В ядрах от v4.14 до v5.14 DSA поддерживает параллельно два режима добавления записей FDB в мост — рассмотренный выше обход моста и новый режим с использованием флага master, задающего установку записей FDB и в программный мост.

bridge fdb add dev swp0 00:01:02:03:04:05 master static

Начиная с ядра v5.14 в DSA была достигнута более тесная интеграция с программной FDB моста, а поддержка обхода моста (флаг self) была исключена. Это привело к указанным ниже изменениям.

# Это единственный способ добавления записи FDB, совместимый
# с ядрами, начиная с v4.14.
bridge fdb add dev swp0 00:01:02:03:04:05 master static
# Эта команда больше не является ошибочной и запись корректно
# считается локальной.
bridge fdb add dev swp0 00:01:02:03:04:05
# Эта команда больше не включает статическую запись FDB в оборудование.
bridge fdb add dev swp0 00:01:02:03:04:05 static

При разработке сценариев рекомендуется использовать флаги master и static для работы с записями FDB моста на интерфейсах коммутатора DSA.

Близость пользовательских портов к портам CPU

Обычно коммутатор DSA подключается к хосту через один интерфейс Ethernet, но при использовании дискретных микросхем коммутации оборудование может допускать использование нескольких портов для повышения пропускной способности при завершении трафика. DSA может использовать несколько портов CPU разными способами. Во-первых, можно статически назначить завершение трафика, связанного с неким пользовательским портом, определённому порту CPU. Таким способом пользовательское пространство может реализовать настраиваемые правила статического распределения нагрузки между пользовательскими портами, распределяя близость (affinity) в соответствии с доступными портами CPU. Во-вторых, можно распределять нагрузку между портами CPU на уровне пакетов, не задавая статического сопоставления пользовательских портов с портами CPU. Это можно реализовать, размещая ведущие DSA на интерфейсе LAG (bonding или team). DSA отслеживает это и создаёт зеркало такой программной группы LAG на портах CPU, обращённых к ведущим DSA, связанным с ведомым устройством LAG.

Для использования нескольких портов CPU в описании микрокода (дерево устройств) коммутатора требуется отметить все каналы между портами CPU и их DSA master с использованием ссылок (phandle) Ethernet. При запуске используется лишь 1 порт CPU и DSA (первый по порядку из описания микрокода, имеющий свойство Ethernet). Настройку системы для использования коммутатором других ведущих выполняет пользователь.

DSA использует механизм rtnl_link_ops (с типом dsa) для возможности смены DSA master пользовательского порта. Атрибут netlink IFLA_DSA_MASTER u32 содержит ifindex ведущего устройства, обслуживающего каждое ведомое устройство. DSA master должен быть действительным кандидатом на основе сведений об узле микрокода или интерфейсом LAG, содержащим только ведомые, являющиеся действительными кандидатами.

Ниже приведены манипуляции, доступные с помощью iproute2.

# Просмотр используемого DSA
ip -d link show dev swp0
    (...)
    dsa master eth0

# Статическое распределение порта CPU.
ip link set swp0 type dsa master eth1
ip link set swp1 type dsa master eth0
ip link set swp2 type dsa master eth1
ip link set swp3 type dsa master eth0

# Порты CPU в LAG, использующие явное назначение DSA master.
ip link add bond0 type bond mode balance-xor && ip link set bond0 up
ip link set eth1 down && ip link set eth1 master bond0
ip link set swp0 type dsa master bond0
ip link set swp1 type dsa master bond0
ip link set swp2 type dsa master bond0
ip link set swp3 type dsa master bond0
ip link set eth0 down && ip link set eth0 master bond0
ip -d link show dev swp0
    (...)
    dsa master bond0

# Порты CPU в LAG, полагающиеся на неявный перенос DSA master.
ip link add bond0 type bond mode balance-xor && ip link set bond0 up
ip link set eth0 down && ip link set eth0 master bond0
ip link set eth1 down && ip link set eth1 master bond0
ip -d link show dev swp0
    (...)
    dsa master bond0

Отметим, что для портов CPU в LAG использование атрибута netlink IFLA_DSA_MASTER не является обязательным, а DSA реагирует на изменение атрибута IFLA_MASTER у текущего ведущего устройства (eth0) и переносит все пользовательские порты на новый интерфейс верхнего уровня eth0
(bond0). Аналогично, при удалении bond0 с помощью RTM_DELLINK DSA переносит пользовательские порты, связанные с этим интерфейсом, на первое физическое устройство DSA master, выбираемое по описанию микрокода (фактически происходит возврат к начальной конфигурации).

В системе с числом физических портов CPU больше 2 возможно сочетание статической привязки пользовательских портов к портам CPU с LAG между DSA master. Невозможно статически назначить пользовательский порт в направлении DSA master, имеющего какие-либо интерфейсы верхнего уровня (включая устройства LAG, в этом случае ведущим всегда будет LAG).

Разрешается изменение близости пользовательского порта к DSA master (и порту CPU) для обеспечения динамического перераспределения в зависимости от трафика.

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


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

nmalykh@protokols.ru


1Receive Packet Steering — управление приёмом пакетов.

2Wake-on-LAN — пробуждение из ЛВС.

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

kas

Руководство пользователя kas

PDF

По материалам https://kas.readthedocs.io/en/latest/.

Этот инструмент предназначен для упрощения организации проектов на основе bitbake.

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

Основные свойства инструмента сборки включают:

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

Установка

Для работы с kas должны быть установлены пакеты:

  • Python 3
  • distro Python 3;
  • jsonschema Python 3;
  • PyYAML Python 3 (необязательно, служит для поддержки файлов yaml);
  • kconfiglib Python 3 (необязательно, служит для подключаемого модуля menu);
  • NEWT Python 3 distro (необязательно, служит для подключаемого модуля menu).

Для установки kas в репозиторий python site-package служит команда

$ sudo pip3 install .

Работа с пакетом

Имеется по меньшей мере 4 варианта работы с пакетом kas.

  • Локальная установка с помощью pip (обеспечивает поддержку команды kas).
  • Использование локального образа контейнера. Для этого загружается сценарий kas-container из репозитория kas, применяемый вместо команды kas. Версия сценария соответствует версии kas и образа kas.
  • Использование образа контейнера в сценариях интерпретатора команд. Для этого в сценарий включается строка ghcr.io/siemens/kas/kas[-isar][:<x.y>], запрашивающая образ контейнера в качестве рабочей среды. Доступные версии образов можно получить по ссылкам https://github.com/orgs/siemens/packages/container/kas%2Fkas/versions и https://github.com/orgs/siemens/packages/container/kas%2Fkas-isar/versions.
  • Использование оболочки run-kas. В этом случае в приведённых ниже примерах следует заменять kas на path/to/run-kas.

Для запуска сборки служит команда

$ kas build /path/to/kas-project.yml

Опытные пользователи bitbake могут использовать задаваемые вручную действия bitbake, например,

$ kas shell /path/to/kas-project.yml -c 'bitbake dosfsutils-native'

Пакет kas будет помещать загружаемые файлы и артефакты сборки в текущий каталог (откуда вызывается kas). Можно указать иной каталог с помощью переменной окружения KAS_WORK_DIR.

Примеры использования

  1. Начальная сборка (установка)
    $ mkdir $PROJECT_DIR
    $ cd $PROJECT_DIR
    $ git clone $PROJECT_URL meta-project
    $ kas build meta-project/kas-project.yml
  2. Обновление или новая сборка
    $ cd $PROJECT_DIR/meta-project
    $ git pull
    $ kas build kas-project.yml
  3. Интерактивная настройка конфигурации
    $ cd $PROJECT_DIR/meta-project
    $ kas menu
    $ kas build  # необязательно, если не вызывается через меню kas

Подключаемые модули

Субкоманды kas реализованы в форме подключаемых модулей (plugin), каждый из которых обычно поддерживает 1 команду.

build

Этот модуль реализует команду kas build. При выполнении команды kas извлекает (checkout) репозитории, организует среду сборки, а затем вызывает bitbake для сборки целей (target), указанных в файле конфигурации. Например, для сборки с конфигурацией из файла kas-project.yml служит команда

kas build kas-project.yml

checkout

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

kas checkout kas-project.yml

dump

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

При запуске с опцией —lock создаётся спецификация блокировки, содержащая лишь точные указания каждого репозитория. Это может быть полезно для фиксации плавающих веток при сохранении простого пути обновления. При задании вместе с опцией —inplace создаётся файл блокировки вместе (см. kas.includehandler.IncludeHandler).

Следует отметить, что

  • выгруженная конфигурация идентична семантически, но побитово;
  • все указанные репозитории извлекаются для устранения конфликтов;
  • все ссылки (refspec) преобразуются (resolv) до применения правок (patch).

Например, для вывода конфигурации, представляющей окончательную конфигурацию сборки kas-project.yml:target-override.yml можно ввести команду

kas dump kas-project.yml:target-override.yml > kas-project-expanded.yml

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

kas build kas-project-expanded.yml

Ниже представлен пример использования механизма блокировки (повторный вызов для воссоздания файла блокировки) для создания файла блокировки kas-project.lock.yml

kas dump --lock --inplace --update kas-project.yml

Созданный файл блокировки будет автоматически применяться для закрепления версии (ревизии)

kas build kas-project.yml

Отметим, что файлы блокировки следует регистрировать в системе контроля версий (VCS).

for-all-repos

Этот модуль реализует команду kas for-all-repos, при выполнении которой kas просматривает (checkout) указанные в выбранном файле конфигурации репозитории и выполняет для каждого заданную команду. Это может служить для запроса состояний репозиториев, автоматизации операций (таких как архивирование использованных при сборке уровней) или выполнения иных команд.

Например, для вывода хэш-значений представлений (commit), использованных в каждом репозитории из файла kas-project.yml (в предположении, что это репозитории git), можно воспользоваться командой

kas for-all-repos kas-project.yml 'git rev-parse HEAD'

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

  • KAS_REPO_NAME — имя текущего репозитория, определяемое свойством name или ключом этого репозитория в файле конфигурации.
  • KAS_REPO_PATH — путь к локальному каталогу, в котором хранится репозиторий, относительно каталога, откуда запускается kas.
  • KAS_REPO_URL — URL, откуда был извлечён репозиторий, или пустая строка, если в файле конфигурации нет удалённого URL.
  • KAS_REPO_REFSPEC — ссылка на спецификацию (refspec) для этого репозитория или пустая строка, если в файле конфигурации нет refspec.

menu

Этот модуль реализует команду kas menu, открывая меню конфигурации, как описано в файле Kconfig. Обрабатываются все имеющиеся файлы конфигурации с сохранёнными настройками, записывается окончательный выбор и вызывается модуль сборки (build plugin), если это запрошено пользователем. Для использования этого модуля нужен файл Kconfig. Меня может задавать указанные ниже типы переменных конфигурации, которые модуль будет транслировать в настройки kas.

  • Файлы конфигурации kas, которые будут включаться в создаваемую конфигурацию. Файлы берутся из строковых переменных kconfig с префиксом KAS_INCLUDE_.
  • Цели bitbake, которые нужно собрать с помощью создаваемой конфигурации. Цели берутся из строковых переменных kconfig с префиксом KAS_TARGET_.
  • Используемая система сборки build_system. Значение определяется статической переменной KAS_BUILD_SYSTEM (openembedded, oe или isar).
  • Переменные конфигурации bitbake, добавляемые к раздел local_conf_header создаваемой конфигурации. Остальные переменные kconfig (string, integer, hex) трактуются обычным способом.

Полное описание языка Kconfig доступно по ссылке https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html.

Модуль menu записывает выбранную конфигурацию в файл .config.yaml в рабочем каталоге kas, а также считывает прежний выбор, если такой файл уже имеется. Файл .config.yaml содержит выбранную конфигурацию (ключ menu_configuration), а также действующие настройки, которые могут использоваться при вызове kas
build или иных команд kas.

shell

Этот модуль реализует команду kas shell, просматривая (checkout) репозитории, организуя среду сборки и запуская в ней интерпретатор команд (shell). Это может служить для запуска bitbake вручную со своими опциями или выполнения таких команд, как runqemu. Например, для запуска оболочки в среде сборки проекта kas-project.yml можно использовать команду

kas shell kas-project.yml

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

kas shell kas-project.yml -c 'runqemu'

Конфигурация проекта

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

# Каждый файл должен иметь заголовок, предоставляющий kas сведения
# о контексте данного файла.
header:
  # Запись version в заголовке указывает, для какой версии формата
  # конфигурации создан файл. Это позволяет kas проверить совместимость.
  # Версия указывается целым числом, которое увеличивается при каждой
  # смене формата.
  version: x
# Машина указывается как в файле local.conf для bitbake.
machine: qemux86-64
# Имя дистрибутива (distro) как в файле local.conf для bitbake.
distro: poky
repos:
  # Эта запись включает репозиторий, где находится файл конфигурации
  # для bblayers.conf
  meta-custom:
  # Здесь указывается список уровней из репозитория poky для 
  # bblayers.conf
  poky:
    url: "https://git.yoctoproject.org/git/poky"
    refspec: 89e6c98d92887913cadf06b2adb97f26cde4849b
    layers:
      meta:
      meta-poky:
      meta-yocto-bsp:

Минимальный входной файл содержит разделы header, machine, distro и repos. Можно также включить в файл разделы bblayers_conf_header и local_conf_header, содержащие строки, добавляемые к заголовкам соответствующих файлов (bblayers.conf и local.conf).

bblayers_conf_header:
  meta-custom: |
    POKY_BBLAYERS_CONF_VERSION = "2"
    BBPATH = "${TOPDIR}"
    BBFILES ?= ""
local_conf_header:
  meta-custom: |
    PATCHRESOLVE = "noop"
    CONF_VERSION = "1"
    IMAGE_FSTYPES = "tar"

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

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

Включение файлов конфигурации из основного дерева

Возможно включение конфигурационных файлов kas из того же репозитория или уровня, как показано ниже.

header:
  version: x
  includes:
    - base.yml
    - bsp.yml
    - product.yml

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

Включение файлов из других репозиториев

Можно также включать конфигурационные файлы из других репозиториев, как показано ниже.

header:
  version: x
  includes:
    - repo: poky
      file: kas-poky.yml
    - repo: meta-bsp-collection
      file: hw1/kas-hw-bsp1.yml
    - repo: meta-custom
      file: products/product.yml
repos:
  meta-custom:
  meta-bsp-collection:
    url: "https://www.example.com/git/meta-bsp-collection"
    refspec: 3f786850e387550fdab836ed7e6dc881de23001b
    layers:
      # Кроме уровней, добавленных из этого репозитория в 
      # hw1/kas-hw-bsp1.yml, добавляется метауровень bsp.
      meta-custom-bsp:
  poky:
    url: "https://git.yoctoproject.org/git/poky"
    refspec: 89e6c98d92887913cadf06b2adb97f26cde4849b
    layers:
      # Если kas-poky.yml уже добавляет уровень meta-yocto-bsp и он 
      # не нужен в bblayer этого проекта, его можно переопределить
      meta-yocto-bsp: excluded

Местоположение файлов определяется относительно репозитория git.

Механизм включения собирает и объединяет содержимое сверху вниз (по файлу) и в глубину (структуры). Это означает, что установки из одного включённого файла могут быть переопределены последующими файлами, а установки из последнего включаемого файла — текущим файлом. При слиянии все словари объединяются рекурсивно с сохранением порядка, в котором записи добавляются в словарь. Это означает, что записи local_conf_header добавляются в файл local.conf в том же порядке, как они были указаны в других файлах конфигурации. Отметим, что порядок записей не сохраняется внутри одного включаемого файла, поскольку синтаксический анализатор создаёт обычные неупорядоченные словари.

Включение файлов конфигурации из команды

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

$ kas build kas-base.yml:debug-image.yml:board.yml

Это эквивалентно статическому включению, например, некого файла kas-combined.yml, показанного ниже.

header:
  version: x
  includes:
    - kas-base.yml
    - debug.image.yml
    - board.yml

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

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

Работа с файлами блокировки

В kas поддерживается применение файлов блокировки для привязывания репозиториев к точному указанию ссылок (refspec, например, ссылок SHA-1 для git). Таким образом, файл блокировки переопределяет лишь refspec, заданные в файле kas. При извлечении (checkout) kas проверяет наличие файла <filename>.lock.<ext> рядом с первым файлом, указанным в строке команды kas. Если такой файл имеется, kas добавляет имя этого файла в свою строку команды и выполняет запрошенную операцию.

Ниже приведён пример для файла kas/kas-isar.yml и соответствующего файла блокировки kas/kas-isar.lock.yml.

kas/kas-isar.yml:
# [...]
repos:
  isar: 
    url: https://github.com/ilbers/isar.git
    refspec: next
kas/kas-isar.lock.yml:
header:
  version: 14
overrides:
  repos:
    isar:
      refspec: 0336610df8bb0adce76ef8c5a921c758efed9f45

Модуль dump предоставляет вспомогательные функции для упрощения создания и обновления фалов блокировки.

Содержимое файла конфигурации

header: dict [обязательно]

Заголовок конфигурационного файла kas, содержащий сведения о контексте файла конфигурации.

version: integer [обязательно]

Позволяет kas проверить совместимость с файлом. Описание версий приведено в разделе Версии формата конфигурации.

includes: list [необязательно]

Список файлов конфигурации, на которых основан текущий файл. Эти файлы объединяются в порядке их указания и каждый следующий файл может переопределять установки любого из предшествующих. Текущий файл может переопределять установки включённых файлов. Элементы списка могут иметь 1 из двух типов:
    • item: string — указывает путь к файлу конфигурации kas от корня репозитория с текущим файлом;
    • item: dict — применяется для включения файлов из других репозиториев
      • repo: string [обязательно] — идентификатор репозитория, где размещается файл (репозиторий должен быть указан в словаре репозиториев как <repo-id>
      • file: string [обязательно] — путь к файлу от корня указанного репозитория.

build_system: string [необязательно]

Указывает систему сборки на основе bitbake (openembedded или oe, isar). При установке этой переменной поиск kas сценария инициализации ограничивается ограничивается репозиториями, заданными для oe-init-build-env и isar-init-build-env, соответственно. Если kas-container находит это свойство в файле конфигурации kas верхнего уровня, автоматически выбирается требуемый образ контейнера и режим вызова.

defaults: dict [необязательно]

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

repos: dict [необязательно]

Этот ключ может содержать принятые по умолчанию значения для некоторых свойств репозитория. Такие значения могут переопределяться установкой для свойства иного значения в данном репозитории.
  • refspec: string [необязательно] — задаёт принятое по умолчанию свойство refspec для всех репозиториев, где оно не переопределено.
  • patches: dict [необязательно] — этот ключ может содержать заданные по умолчанию значения некоторых свойств исправлений (patch) для репозитория. Эти значения можно переопределить установкой иного значения в данном исправлении.
    • repo: string [необязательно] — устанавливает применение принятого по умолчанию свойства repo ко всем исправлениям в репозитории, где оно не переопределено.

machine: string [необязательно]

Содержит значение переменной MACHINE, записываемое в файл local.conf. Значение можно переопределить через переменную KAS_MACHINE, по умолчанию задано значение qemux86-64.

distro: string [необязательно]

Содержит значение переменной DISTRO, записываемое в файл local.conf. Значение можно переопределить через переменную KAS_DISTRO, по умолчанию задано значение poky.

target: string [необязательно] or list [необязательно]

Указывает цель (или список целей) сборки с помощью bitbake. Значение можно переопределить через переменную KAS_TARGET, по умолчанию задано значение core-image-minimal. При указании нескольких целей в переменной разделителями целей служат символы пробела.

env: dict [необязательно]

Содержит имена переменных окружения с принятыми по умолчанию значениями или None. Эти переменные доступны bitbake через BB_ENV_EXTRAWHITE и могут быть переопределены переменными окружения, в котором запускается kas. В качестве значения может использоваться строка (string) или ничего (None). Строка задаёт принятое по умолчанию значение, а None ведёт лишь к добавлению переменной в BB_ENV_EXTRAWHITE и не меняет окружение запуска kas.

task: string [необязательно]

Указывает задачу для сборки с помощью bitbake. Может быть переопределена переменной KAS_TASK,
по умолчанию принято значение build.

repos: dict [необязательно]

Содержит определения всех доступных репозиториев и уровней.

<repo-id>: dict [необязательно]

Указывает репозиторий и уровни, которые следует включать в сборку. При значении None репозиторий, где размещён текущий файл конфигурации, определяется как <repo-id> и добавляется в качестве уровня сборки. Рекомендуется связывать <repo-id> с содержащим его репозиторием или уровнем для упрощения ссылок между проектами.
  • name: string [необязательно] — задаёт имя, с которым хранится репозиторий. При отсутствии параметра применяется значение <repo-id>.
  • url: string [необязательно] — url репозитория. Отсутствие параметра отменяет контроль версий.
  • type: string [необязательно] — тип репозитория для контроля версий (по умолчанию git,
    поддерживается также hg).
  • refspec: string [необязательно] — спецификация выпуска, который следует использовать. При наличии url без указания refspec получаемый выпуск (revision) зависит от принятых по умолчанию настроек контроля версий.
  • path: string [необязательно] — путь к сохранённому репозиторию. При отсутствии url и path применяется репозиторий, где размещён текущий файл конфигурации.
    При отсутствии url и наличии path запись ссылается на каталог, который указывает path. При наличии url и path значение path применяется для переопределения каталога checkout (по умолчанию kas_work_dir + repo.name). При указании в path относительного значения в начало добавляется kas_work_dir.
  • layers: dict [необязательно] — указывает уровни из данного репозитория, которые следует включить в bblayers.conf. При отсутствии параметра, значении None или пустом словаре в качестве уровня добавляется путь к самому репозиторию. Можно указать точку (.), если в качестве уровня следует добавить сам репозиторий. Это позволяет создавать комбинации вида
    repos:
      meta-foo:
        url: https://github.com/bar/meta-foo.git
        path: layers/meta-foo
        refspec: master
        layers:
          .:
          contrib:
    Приведённый фрагмент добавляет layers/meta-foo и layers/meta-foo/contrib из репозитория meta-foo в файл bblayers.conf.
  • <layer-path>: enum [необязательно] — добавляет уровень с <layer-path> от корневого каталога репозитория в файл bblayers.conf, если значение этого параметра не является одним из списка [disabled, excluded, n, no, 0, false]. Это позволяет переопределять включение уровня в загружаемых позднее файлах.

patches: dict [необязательно]

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

<patches-id>: dict [необязательно]

Одна из записей для правок с уникальным идентификатором, определяющим порядок применения правок.
  • repo: string [обязательно] — идентификатор репозитория, от которого идёт путь в данной записи.
  • path: string [обязательно] — путь к одному из patch-файлов или каталогу patchset в формате quilt.

overrides: dict [необязательно]

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

repos: dict [необязательно]

Задаёт сопоставление с записью репозитория верхнего уровня.
  • <repo-id>: dict [необязательно] — отображение на запись <repo-id>.
    • refspec: string [необязательно] — задаёт refspec для переопределения refspec соответствующего репозитория. Значение refspec должно быть распознаваемым (не включать branch или tag).

bblayers_conf_header: dict [необязательно]

Строки, которые следует добавлять в bblayers.conf перед включением какого-либо уровня.

<bblayers-conf-id>: string [необязательно]

Строка, добавляемая в bblayers.conf. Идентификатор записи (<bblayers-conf-id>) следует делать уникальным, если нужно добавлять строки, и можно применять строки, совпадающие со строками из других включаемых файлов, если запись следует переопределять. Строки добавляются в bblayers.conf по алфавитному порядку <bblayers-conf-id> для обеспечения детерминированной генерации конфигурационных файлов.

local_conf_header: dict [необязательно]

Строки, которые следует добавлять в local.conf.

<local-conf-id>: string [необязательно]

Строка, добавляемая в local.conf. Обработка выполняется так же, как для записей bblayers_conf_header.

menu_configuration:: dict [необязательно]

Указывает выбор пользователя для меню Kconfig в проекте. Каждая переменная соответствует переменной конфигурации Kconfig и может иметь тип string, boolean или integer. Содержимое этого ключа обычно поддерживается подключаемым модулем kas menu в файле .config.yaml.

Использование команд

Пакет kas служит инструментом для проектов на основе bitbake.

kas [-h] [--version] [-d] [-l {debug,info,warning,error,critical}]
           {build,checkout,dump,for-all-repos,shell,menu} …

Позиционные аргументы

build, checkout, dump, for-all-repos, shell, menu, а также субкоманда help.

Именованные аргументы

—version

Выводит номер версии программы и завершает работу.

-d, —debug

Включает запись отладочных сведений в системный журнал. Параметр устарел и заменён —log-level debug.

-l, —log-level

Возможные значения: debug, info (принято по умолчанию), warning, error, critical.

Субкоманды

build

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

kas build [-h] [--skip SKIP] [--force-checkout] [--update] [--target TARGET]
          [-c TASK]
          [config] [extra_bitbake_args …]

Позиционные аргументы

config

Файл конфигурации. По умолчанию применяется .config.yaml из каталога KAS_WORK_DIR.

extra_bitbake_args

Дополнительные аргументы для передачи bitbake (обычно требуется разделять с помощью —)

Именованные аргументы

—skip

Пропустить этапы сборки SKIP (по умолчанию список пуст).

—force-checkout

Всегда проверять желаемое значение refspec каждого репозитория, отбрасывая любые локальные изменения. По умолчанию отключено (False).

—update

Вносить (pull) новые изменения (upstream) для желаемого refspec, даже если они внесены (checked out) локально. По умолчанию отключено (False).

—target

Задаёт цель для сборки.

-c, —cmd, —task

Задаёт выполняемую задачу.

checkout

Извлекает все требуемые репозитории и организует каталог сборки в соответствии с файлом конфигурации.

kas checkout [-h] [--skip SKIP] [--force-checkout] [--update] [config]

Позиционные аргументы

config

Файл конфигурации. По умолчанию применяется .config.yaml из каталога KAS_WORK_DIR.

Именованные аргументы

—skip

Пропустить этапы сборки SKIP (по умолчанию список пуст).

—force-checkout

Всегда проверять желаемое значение refspec каждого репозитория, отбрасывая любые локальные изменения. По умолчанию отключено (False).

—update

Вносить (pull) новые изменения (upstream) для желаемого refspec, даже если они внесены (checked out) локально. По умолчанию отключено (False).

dump

Извлекает окончательную конфигурацию и выводит её на stdout. При обработке refspec она происходит до внесения правок (patch).

kas dump [-h] [--skip SKIP] [--force-checkout] [--update]
         [--format {yaml,json}] [--indent INDENT] [--resolve-refs]
         [--resolve-env | --lock] [-i]
         [config]

Позиционные аргументы

config

Файл конфигурации. По умолчанию применяется .config.yaml из каталога KAS_WORK_DIR.

Именованные аргументы

—skip

Пропустить этапы сборки SKIP (по умолчанию список пуст).

—force-checkout

Всегда проверять желаемое значение refspec каждого репозитория, отбрасывая любые локальные изменения. По умолчанию отключено (False).

—update

Вносить (pull) новые изменения (upstream) для желаемого refspec, даже если они внесены (checked out) локально. По умолчанию отключено (False).

—format

Задаёт формат вывода и может принимать значение yaml (по умолчанию) или json.

—indent

Отступ строк (число пробелов в начале), по умолчанию 4.

—resolve-refs

Заменять плавающие ссылки точными SHA. По умолчанию отключено (False).

—resolve-env

Устанавливает вместо принятого по умолчанию env указанное значение. По умолчанию отключено (False).

—lock

Создает файл блокировки с точными SHA. По умолчанию отключено (False).

-i, —inplace

Обновить файл блокировки (требует —lock). По умолчанию отключено (False).

for-all-repos

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

kas for-all-repos [-h] [--skip SKIP] [--force-checkout] [--update] [-E]
                  [config] command

Позиционные аргументы

config

Файл конфигурации. По умолчанию применяется .config.yaml из каталога KAS_WORK_DIR.

command

Строка, указывающая команду для выполнения

Именованные аргументы

—skip

Пропустить этапы сборки SKIP (по умолчанию список пуст).

—force-checkout

Всегда проверять желаемое значение refspec каждого репозитория, отбрасывая любые локальные изменения. По умолчанию отключено (False).

—update

Вносить (pull) новые изменения (upstream) для желаемого refspec, даже если они внесены (checked out) локально. По умолчанию отключено (False).

-E, —preserve-env

Сохранять текущий пользовательский блок окружения. По умолчанию отключено (False).

shell

Запускает интерпретатор команд (shell) в среде сборки.

kas shell [-h] [--skip SKIP] [--force-checkout] [--update] [-E] [-k]
          [-c COMMAND]
          [config]

Позиционные аргументы

config

Файл конфигурации. По умолчанию применяется .config.yaml из каталога KAS_WORK_DIR.

Именованные аргументы

—skip

Пропустить этапы сборки SKIP (по умолчанию список пуст).

—force-checkout

Всегда проверять желаемое значение refspec каждого репозитория, отбрасывая любые локальные изменения. По умолчанию отключено (False).

—update

Вносить (pull) новые изменения (upstream) для желаемого refspec, даже если они внесены (checked out) локально. По умолчанию отключено (False).

-E, —preserve-env

Сохранять текущий пользовательский блок окружения. По умолчанию отключено (False).

-k, —keep-config-unchanged

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

-c, —command

Выполнить указанную команду. По умолчанию команда не задана.

menu

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

kas menu [-h] [kconfig]

Позиционные аргументы

kconfig

Файл Kconfig (по умолчанию Kconfig).

Переменные окружения

KAS_WORK_DIR

Путь к рабочему каталогу kas. По умолчанию текущий рабочий каталог.

KAS_BUILD_DIR

Путь к каталогу сборки, по умолчанию ${KAS_WORK_DIR}/build.

KAS_REPO_REF_DIR

Путь к каталогу образцовых репозиториев, применяемых для клонирования. Чтобы пакет kas находил эти репозитории, они должны именоваться определенным способом — URL репозиториев транслируются, например, https://github.com/siemens/meta-iot2000.git преобразуется в имя github.com.siemens.meta-iot2000.git. Не найденные репозитории будут закрыты. В одном каталоге может работать одновременно
несколько экземпляров kas, если базовая файловая система совместима с POSIX.

KAS_DISTRO KAS_MACHINE KAS_TARGET KAS_TASK

Переопределяют соответствующие установки конфигурационного файла.

KAS_PREMIRRORS DISTRO_APT_PREMIRRORS

Задаёт варианты подстановки для URL репозиториев. Подобно bitbake PREMIRRORS, эта переменная состоит из записей, размещённых по одной в строке. Каждая запись задаёт регулярное выражение для сопоставления с URL и отделённую пробелом замену. Например, http://.*.someurl.io/ http://localmirror.net/

SSH_PRIVATE_KEY

Секретный ключ, который следует добавить во внутренний агент ssh (ключ не защищается паролем). Эта переменная полезна для серверов сборки CI, а на обычных машинах (desktop) лучше применять агент ssh, расположенный вне среды kas.

SSH_PRIVATE_KEY_FILE

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

SSH_AUTH_SOCK

Сокет аутентификации SSH, служащий для клонирования через SSH (альтернатива SSH_PRIVATE_KEY или SSH_PRIVATE_KEY_FILE).

DL_DIR SSTATE_DIR TMPDIR

Переменные окружения, передаваемые в среду bitbake.

http_proxy https_proxy ftp_proxy no_proxy

Определяют конфигурацию прокси для bitbake.

GIT_PROXY_COMMAND NO_PROXY

Задаёт прокси для естественной выборки git. Значение NO_PROXY преобразуется в сценарий OE oe-git-proxy.

SHELL

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

TERM

Опции терминала для подключаемого модуля shell.

AWS_CONFIG_FILE AWS_SHARED_CREDENTIALS_FILE

Путь к файлу конфигурации и свидетельствам (credential), которые копируются в домашний каталог kas.

GIT_CREDENTIAL_HELPER GIT_CREDENTIAL_USEHTTPPATH

Задаёт и настраивает вспомогательную функцию (helper) git для свидетельств в .gitconfig пользователя kas.

NETRC_FILE

Путь к файлу .netrc, который копируется в домашний каталог kas как .netrc.

CI_SERVER_HOST CI_JOB_TOKEN

Переменные окружения из gitlab CI, если .netrc настроен на разрешение выборки из экземпляра gitlab. Запись добавляется, если указан также файл NETRC_FILE. Отметим, что при наличии в файле записи для данного хоста многие инструменты будут использовать её.

BB_NUMBER_THREADS PARALLEL_MAKE

Переменные окружения для управления одновременной работой.

Версии формата конфигурации

1 (0.10)

Добавлен механизм включения и проверка версии.

2

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

3

Добавлен ключ task, позволяющий указать задачу для выполнения (bitbake
-c).

4

Добавлен ключ target, разрешающий список имён целей.

5

Использование целей multiconfig:* автоматически добавляет подобающие записи BBMULTICONFIG в файл local.conf.

6

Ключ env позволяет передать пользовательские переменные окружения для процесса сборки bitbake.

7

Свойство type для repos позволяет указать применяемую систему сборки.

8

Свойство patches для repos позволяет применить к репозиторию дополнительные изменения (patch).

9

Ключ defaults применяется для задания принятого по умолчанию значения свойство репозитория refspec и свойство исправлений repo. Эти значения применяются, если соответствующие свойства не заданы для репозитория или исправлений.

10

Добавлено свойство build_system для выбора системы сборки OE или Isar.

11

Строковый элемент includes теперь указывает путь относительно репозитория. Пути относительно файла поддерживаются с выдачей предупреждения. Файл bblayers.conf создаётся с принятыми по умолчанию значениями переменных BBPATH и BBFILES, которые можно переопределить через bblayers_conf_headers. Ключ menu_configuration сохраняет выбор, сделанный через kas menu, в файле конфигурации (ключ проверяется только этим модулем).

12

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

13

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

14

Запись overrides на верхнем уровне можно применять для фиксации плавающих refspec репозитория.


 

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

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

nmalykh@protokols.ru

Рубрика: Linux, RISC-V | Оставить комментарий

RFC 9406 HyStart++: Modified Slow Start for TCP

Internet Engineering Task Force (IETF)                P. Balasubramanian
Request for Comments: 9406                                     Confluent
Category: Standards Track                                       Y. Huang
ISSN: 2070-1721                                                 M. Olson
                                                               Microsoft
                                                                May 2023

HyStart++: Modified Slow Start for TCP

HyStart++ — изменённый алгоритм Slow Start для TCP

PDF

Аннотация

В этом документе описывается HyStart++ — простое изменение фазы замедленного старта для алгоритмов контроля перегрузки. Замедленный старт во многих случаях может приводить к превышению идеальной скорости передачи, вызывающему потерю пакетов и снижение производительности. В HyStart++ используется увеличение времени кругового обхода (round-trip delay) в качестве эвристических данных для нахождения точки выхода до возможного превышения скорости. Это также смягчает возникновение вариаций задержки (jitter), приводящих к преждевременному выходу из замедленного старта.

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

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

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

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

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

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

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

1. Введение

В [RFC5681] описан алгоритм замедленного старта для контроля перегрузок в протоколе TCP. Алгоритм замедленного старта применяется в случаях, когда окно перегрузок (congestion window или cwnd) становится меньше порога замедленного старта (slow start threshold или ssthresh). В процессе замедленного старта при отсутствии потерь пакетов протокол TCP экспоненциально увеличивает значение cwnd для определения пропускной способности сети (network capacity). Такой быстрый рост может приводить к тому, что скорость передачи станет выше идеальной и это приведёт к значительным потерям пакетов, которые не всегда можно восстановить.

HyStart++ строится на основе алгоритма Hybrid Start (HyStart), исходно описанного в [HyStart]. HyStart++ использует увеличение времени кругового обхода (round-trip delay) как сигнал для выхода из процедуры замедленного старта до того, как станут возможны потери в результате превышения скорости. Это один из двух алгоритмов, заданных в [HyStart] для поиска безопасной точки выхода из процедуры замедленного старта. После выхода из процедуры замедленного старта используется новая фаза консервативного замедленного старта (Conservative Slow Start или CSS) для решения вопроса, не был ли этот выход преждевременным и возобновления замедленного старта при преждевременному выходе. Такое смягчение повышает производительность при наличии вариаций задержки. Механизм HyStart++ снижает потери пакетов и их повторную передачу, повышая производительность в лабораторных условиях и работающих системах.

Хотя документ описывает HyStart++ для протокола TCP, механизм можно использовать и с другими транспортными протоколами, применяющими замедленный старт, такими как QUIC [RFC9002] или SCTP3 [RFC9260].

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

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

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

Чтобы помочь читателям, ниже приведены некоторые определения из [RFC5681].

SENDER MAXIMUM SEGMENT SIZE (SMSS) — максимальный размер сегмента для отправителя

Размер самого большого сегмента, который может быть передан отправителем. Это значение может определяться на основе максимального блока данных, передаваемого через сеть, алгоритма определения Path MTU [RFC1191, RFC4821], RMSS (см. следующее определение) и других факторов. Значение не включает размеры заголовков и опций TCP/IP.

RECEIVER MAXIMUM SEGMENT SIZE (RMSS) — максимальный размер сегмента для получателя

RMSS – размер максимального сегмента, который желает принимать получатель. Это значение задаётся в опции MSS, передаваемой хостом при организации соединения. Если опция MSS при организации соединения не была задана, используется значение 536 байтов [RFC1122]. Значение не включает размеры заголовков и опций TCP/IP.

RECEIVER WINDOW (rwnd) — размер окна принимающей стороны

Последнее анонсированное значение размера окна принимающей стороны.

CONGESTION WINDOW (cwnd) — размер окна насыщения (перегрузки)

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

4. Алгоритм HyStart++

4.1. Обзор

В [HyStart] заданы два алгоритма (Delay Increase и Inter-Packet Arrival), которые работают параллельно для определения момента, когда скорость передачи достигает предела возможностей сети (capacity). На практике алгоритм Inter-Packet Arrival не работает достаточно хорошо и не способен обнаруживать перегрузку заранее прежде всего в результате сжатия ACK. Идея алгоритма Delay Increase состоит в поиске скачков времени кругового обхода (round-trip time или RTT), которые указывают заполнение буферов в узком месте сети (bottleneck).

В HyStart++ отправитель TCP использует стандартный замедленный старт и алгоритм увеличения задержки (Delay Increase) для инициирования выхода из процедуры замедленного старта. Но вместо незамедлительного перехода от механизма slow start к предотвращению перегрузки (congestion avoidance), отправитель в течение нескольких интервалов RTT в фазе консервативного замедленного старта (CSS) для решения вопроса о своевременности выхода из процедуры замедленного старта. В процессе CSS окно перегрузок увеличивается экспоненциально, подобно обычной процедуре замедленного старта, но с меньшим показателем, что ведёт к менее агрессивному росту. Если RTT снижается в процессе CSS, считается что скачок RTT не был вызван перегрузкой, связанной с ростом скорости передачи сверх идеальной, и для соединения возобновляется замедленный старт. Если рост RTT продолжается в процессе CSS, соединение переходит в режим предотвращения перегрузки.

4.2. Детали алгоритма

В приведённом ниже псевдокоде предел L служит для управления энергичностью (aggressiveness) увеличения cwnd в стандартном механизме замедленного старта и CSS. Хотя прибытие ACK может заново подтверждать доставку произвольного числа байтов, алгоритм HyStart++ ограничивает число байтов, применяемых для увеличения cwnd значением L*SMSS.

При инициализации для lastRoundMinRTT и currentRoundMinRTT устанавливаются бесконечные значения, currRTT указывает значение RTT, полученное из входящего ACK, и при инициализации также устанавливается бесконечным.

   lastRoundMinRTT = infinity
   currentRoundMinRTT = infinity
   currRTT = infinity

HyStart++ определяет интервал (round) на основе порядковых номеров:

  • определяется windowEnd как порядковый номер, инициализируемый значением SND.NXT;

  • при подтверждении номера windowEnd (ACK) текущий интервал считается завершённым и снова устанавливается windowEnd = SND.NXT.

В начале каждого интервала при стандартном замедленном старте [RFC5681] и CSS инициализируются переменные, применяемые для расчёта минимального значения RTT в текущем интервале

   lastRoundMinRTT = currentRoundMinRTT
   currentRoundMinRTT = infinity
   rttSampleCount = 0

Для каждого прибывающего ACK при замедленном старте (N — число не подтверждённых ранее байтов, подтверждаемых данным ACK)

  • обновляется cwnd

     cwnd = cwnd + min(N, L * SMSS)
  • сохраняется минимальное наблюдавшееся значение RTT

     currentRoundMinRTT = min(currentRoundMinRTT, currRTT)
     rttSampleCount += 1

Для интервалов, в которых получено хотя бы N_RTT_SAMPLE значений RTT и текущие значения currentRoundMinRTT и lastRoundMinRTT действительны, проверяется, вызывает ли рост задержки выход из процедуры замедленного старта

   if ((rttSampleCount >= N_RTT_SAMPLE) AND
       (currentRoundMinRTT != infinity) AND
       (lastRoundMinRTT != infinity))
     RttThresh = max(MIN_RTT_THRESH,
       min(lastRoundMinRTT / MIN_RTT_DIVISOR, MAX_RTT_THRESH))
     if (currentRoundMinRTT >= (lastRoundMinRTT + RttThresh))
       cssBaselineMinRtt = currentRoundMinRTT
       выход из slow start и запуск CSS

Для каждого прибывающего ACK в CSS (N — число не подтверждённых ранее байтов, подтверждаемых данным ACK)

  • обновляется cwnd

   cwnd = cwnd + (min(N, L * SMSS) / CSS_GROWTH_DIVISOR)
  • сохраняется минимальное наблюдавшееся значение RTT

   currentRoundMinRTT = min(currentRoundMinRTT, currRTT)
   rttSampleCount += 1

Для интервалов CSS , в которых получено хотя бы N_RTT_SAMPLE значений RTT, проверяется, не стало ли значение minRTT текущего интервала ниже базового (cssBaselineMinRtt), что указывает на ложный выход из процедуры замедленного старта

   if (currentRoundMinRTT < cssBaselineMinRtt)
     cssBaselineMinRtt = infinity
     возобновление slow start, включая HyStart++

CSS продолжается не более CSS_ROUNDS интервалов. Если переход в CSS произошёл в середине интервала, неполный интервал учитывается.

По истечении CSS_ROUNDS интервалов запускается алгоритм предотвращения перегрузки установкой

   ssthresh = cwnd

При наличии потерь или маркеров явного уведомления о перегрузке (Explicit Congestion Notification или ECN) во время стандартной процедуры замедленного старта или CSS запускается механизм предотвращения перегрузки установкой

   ssthresh = cwnd

4.3. Настройка констант и другие соображения

Реализациям HyStart++ рекомендуется устанавливать приведённые ниже значения констант.

   MIN_RTT_THRESH = 4 мсек
   MAX_RTT_THRESH = 16 мсем
   MIN_RTT_DIVISOR = 8
   N_RTT_SAMPLE = 8
   CSS_GROWTH_DIVISOR = 4
   CSS_ROUNDS = 5
   L = бесконечность в режиме с «прореживанием», L = 8 в ином случае

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

Чувствительность к росту задержки определяется константами MIN_RTT_THRESH и MAX_RTT_THRESH. Меньшие значения MIN_RTT_THRESH могут вызывать необоснованный выход из процедуры slow start, большие значения MAX_RTT_THRESH — препятствовать выходу из slow start до момента возникновения потерь на путях с большим RTT.

MIN_RTT_DIVISOR — это доля4 RTT, применяемая для расчёта порога задержки. Меньшее значение повышает порог, снижая чувствительность к росту задержки.

Хотя от всех реализаций TCP требуется делать хотя бы 1 выборку RTT за каждый интервал, реализациям HyStart++ рекомендуется делать не меньше N_RTT_SAMPLE выборок RTT. Уменьшение N_RTT_SAMPLE будет снижать точность измерения RTT, а большие значения повышают точность за счёт роста издержек на обработку.

Для CSS_GROWTH_DIVISOR должно устанавливаться значение не меньше 2. Значение 1 приведёт к такому же поведению, как при обычном замедленном старте, значения больше 4 снижают энергичность алгоритма и могут снижать производительность.

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

«Прореживание» (pacing) пакетов [ASA00] является одним из возможных механизмов предотвращения значительных пиков трафика и связанного с этим ущерба. В реализации TCP с прореживанием следует устанавливать бесконечное значение L. Прореживание смягчает проблемы, связанные с пиками трафика и такая установка обеспечивает оптимальный рост cwnd в современной сети.

В реализациях TCP с прореживанием для смягчения влияния пиков трафика конечные значения L могут приводить к существенным проблемам производительности в высокоскоростных сетях по причине медленного роста cwnd. Для реализация TCP без прореживания значение L меньше 8 могут приводить к существенным проблемам производительности в высокоскоростных сетях по причине медленного роста cwnd, а значения больше 8 могут способствовать возникновению пиков трафика и соответствующему снижению производительности.

Реализациям следует использовать HyStart++ только в начальной процедуре slow start (когда ssthresh имеет начальное значение, произвольное в соответствии с [RFC5681]) и возвращаться к стандартной процедуре slow start в течение остального времени действия соединения. Это приемлемо, поскольку в последующих процедурах slow start используется обнаруженное значение ssthresh для выхода из процедуры замедленного старта и предотвращения проблемы превышения скорости. Реализация может использовать HyStart++ для увеличения restart window [RFC5681] после длительного бездействия.

В ограниченных приложениями сценариях, где объем находящихся в сети данных (in flight) может быть меньше произведения задержки на пропускную способность (bandwidth-delay product или BDP), снижая число выборок RTT, что может приводить к возврату в slow start. В таких случаях ожидается «колебание» между механизмами CSS и slow start, но такое поведение не будет приводить к преждевременному переходу в режим предотвращения перегрузки или превышению скорости по сравнению с обычным механизмом slow start.

5. Развёртывание и оценка производительности

Во время подготовки этого документа описанный здесь механизм HyStart++ был по умолчанию включён для всех соединений TCP в операционной системе Windows уже более 2 лет с отключённым прореживанием и L = 8.

В лабораторных измерениях с Windows TCP механизм HyStart++ показал улучшение пропускной способности, а также сокращение потери пакетов и повтора передачи по сравнению со стандартным механизмом slow start. Например, различные тесты на каналах 100 Мбит/с размером буфера, ограниченным произведением задержки на пропускную способность, механизм HyStart++ снижает объем повторно передаваемых данных на 50% (в байтах) и тайм-аут повтора (retransmission timeout или RTO) на 36%.

В тесте A/B, где сравнивалась реализация HyStart++ (на основе предварительной версии этого документа) со стандартным механизмом slow start в среде с большим числом устройств Windows из 52 миллиардов соединений TCP лишь 0,7% соединений переходили от 1 RTO к 0 RTO и ещё 0,7% — от 2 RTO к 1 RTO при использовании HyStart++. Этот тест не был сфокусирован на соединениях с отправкой большого объёма данных, где влияние может оказаться существенно сильнее. Планируется проведение дополнительных экспериментов для сбора данных.

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

HyStart++ улучшает механизм slow start и наследует соображения безопасности, отмеченные в [RFC5681].

Атакующий может вызвать преждевременный выход HyStart++ из процедуры замедленного старта и снизить производительность соединения TCP, например, путём отбрасывания пакетов данных или их подтверждения.

Атака ACK division, описанная в [SCWA99]Ю не влияет на HyStart++, поскольку расширение окна перегрузки для HyStart++ основано на числе вновь подтверждённых данных в каждом прибывающем ACK, а не на увеличении на конкретную константу при получении каждого ACK.

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

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

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, <https://www.rfc-editor.org/info/rfc2119>.

[RFC5681] Allman, M., Paxson, V., and E. Blanton, «TCP Congestion Control», RFC 5681, DOI 10.17487/RFC5681, September 2009, <https://www.rfc-editor.org/info/rfc5681>.

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

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

[ASA00] Aggarwal, A., Savage, S., and T. Anderson, «Understanding the performance of TCP pacing», Proceedings IEEE INFOCOM 2000, DOI 10.1109/INFCOM.2000.832483, March 2000, <https://doi.org/10.1109/INFCOM.2000.832483>.

[HyStart] Ha, S. and I. Rhee, «Taming the elephants: New TCP slow start», Computer Networks vol. 55, no. 9, pp. 2092-2110, DOI 10.1016/j.comnet.2011.01.014, June 2011, <https://doi.org/10.1016/j.comnet.2011.01.014>.

[RFC1122] Braden, R., Ed., «Requirements for Internet Hosts — Communication Layers», STD 3, RFC 1122, DOI 10.17487/RFC1122, October 1989, <https://www.rfc-editor.org/info/rfc1122>.

[RFC1191] Mogul, J. and S. Deering, «Path MTU discovery», RFC 1191, DOI 10.17487/RFC1191, November 1990, <https://www.rfc-editor.org/info/rfc1191>.

[RFC4821] Mathis, M. and J. Heffner, «Packetization Layer Path MTU Discovery», RFC 4821, DOI 10.17487/RFC4821, March 2007, <https://www.rfc-editor.org/info/rfc4821>.

[RFC9002] Iyengar, J., Ed. and I. Swett, Ed., «QUIC Loss Detection and Congestion Control», RFC 9002, DOI 10.17487/RFC9002, May 2021, <https://www.rfc-editor.org/info/rfc9002>.

[RFC9260] Stewart, R., Tüxen, M., and K. Nielsen, «Stream Control Transmission Protocol», RFC 9260, DOI 10.17487/RFC9260, June 2022, <https://www.rfc-editor.org/info/rfc9260>.

[SCWA99] Savage, S., Cardwell, N., Wetherall, D., and T. Anderson, «TCP congestion control with a misbehaving receiver», ACM SIGCOMM Computer Communication Review, vol. 29, issue 5, pp. 71-78, DOI 10.1145/505696.505704, October 1999, <https://doi.org/10.1145/505696.505704>.

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

В процессе обсуждения этой работы в почтовой конференции TCPM и на встречах рабочей группы были получены полезные комментарии и рецензии от (в алфавитном порядке фамилий) Mark Allman, Bob Briscoe, Neal Cardwell, Yuchung Cheng, Junho Choi, Martin Duke, Reese Enghardt, Christian Huitema, Ilpo Järvinen, Yoshifumi Nishida, Randall Stewart, Michael Tüxen.

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

Praveen Balasubramanian
Confluent
899 West Evelyn Ave
Mountain View, CA 94041
United States of America
Email: pravb.ietf@gmail.com
 
Yi Huang
Microsoft
One Microsoft Way
Redmond, WA 98052
United States of America
Phone: +1 425 703 0447
Email: huanyi@microsoft.com
 
Matt Olson
Microsoft
One Microsoft Way
Redmond, WA 98052
United States of America
Phone: +1 425 538 8598
Email: maolson@microsoft.com

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

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

nmalykh@protokols.ru

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

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

3Stream Control Transmission Protocol — протокол управления потоковой передачей.

4Результат деления. Прим. перев.

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

RFC 9375 A YANG Data Model for Network and VPN Service Performance Monitoring

Internet Engineering Task Force (IETF)                        B. Wu, Ed.
Request for Comments: 9375                                    Q. Wu, Ed.
Category: Standards Track                                         Huawei
ISSN: 2070-1721                                        M. Boucadair, Ed.
                                                                  Orange
                                                     O. Gonzalez de Dios
                                                              Telefonica
                                                                  B. Wen
                                                                 Comcast
                                                              April 2023

A YANG Data Model for Network and VPN Service Performance Monitoring

Модель данных YANG для мониторинга производительности сетей и служб VPN

PDF

Аннотация

Модель данных для сетевых топологий, заданная в RFC 8345, вносит вертикальные межуровневые взаимодействия между сетями, которые можно дополнить для других топологий сетей и служб. Этот документ определяет модуль YANG для мониторинга производительности (performance monitoring или PM) базовых сетей и наложенных служб VPN, который может применяться для отслеживания производительности сетей на обоих уровнях и управления ею.

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

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

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

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

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

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

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

1. Введение

В [RFC8969] описана модель автоматизации управления сетями и службами с помощью моделей данных YANG [RFC7950]. Там сказано, что модель телеметрических измерений следует связывать с моделями служб (таких как L3 VPN или L2 VPN) или сетей для мониторинга общей производительности сети и соглашений об уровне сервиса (Service Level Agreement или SLA).

Производительность служб VPN связана с изменениями производительности базовых сетей, обеспечивающих услуги VPN. Например, задержка в канале между устройствами на периметре (Provider Edge или PE) и в сети провайдера (Provider или P) и состояние потери пакетов на интерфейсах L2 и L3, соединяющих PE и граничные устройства клиента (Customer Edge или CE), напрямую влияют на производительность услуг VPN. Кроме того, интеграция данных о производительности L2/L3 VPN и сети позволяет оркестраторам выполнять согласованный мониторинг. Поэтому данный документ задаёт модуль YANG для мониторинга производительности (PM) сети и службы VPN. Модуль пригоден для мониторинга и управления производительностью сети на уровне топологии сети или топологии сервиса между сайтами VPN.

Базовую модель из раздела 5. Модуль YANG для мониторинга производительности сетей и VPN можно расширить включением связанных с технологией деталей, например, добавив статистику явных уведомлений о перегрузке (Explicit Congestion Notification или ECN) сетей L3 или служб VPN для поддержки зависящих от производительности приложений.

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

Модуль YANG, определённый здесь, предназначен для дополнения модели данных YANG для топологии сети, заданный в [RFC8345], и использует соответствующие типы YANG из [RFC6991], [RFC8345], [RFC8532], [RFC9181].

В Приложении A представлен набор примеров, иллюстрирующих применение модуля.

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

Ниже указаны используемые к этом документе термины, которые определены в [RFC7950].

  • Augment — дополнение.
  • Data model — модель данных.
  • Data node — узел данных.

Термины для описания моделей данных YANG приведены в [RFC7950].

Деревья представлены в этом документе с использованием нотации [RFC8340].

2.1. Сокращения

CE

Customer Edge — граничное оборудование коиента, как определено в [RFC4026].

L2VPN

Layer 2 Virtual Private Network — виртуальная частная сеть канального уровня, как определено в [RFC4026].

L3VPN

Layer 2 Virtual Private Network — виртуальная частная сеть сетевого уровня, как определено в [RFC4026].

L2NM

L2VPN Network Model — модель сети L2VPN.

L3NM

L3VPN Network Model — модель сети L3VPN.

MPLS

Multiprotocol Label Switching — многопротокольная коммутация по меткам.

OAM

Operations, Administration, and Maintenance — эксплуатация, администрирование, поддержка.

OSPF

Open Shortest Path First — сначала по кратчайшему пути.

OWAMP

One-Way Active Measurement Protocol — протокол активных измерений в одном направлении, заданный в [RFC4656].

P

Provider router — маршрутизатор провайдера, как определено в [RFC4026].

PE

Provider Edge — граничное устройство провайдера, как определено в [RFC4026].

PM

Performance Monitoring — мониторинг производительности.

SLA

Service Level Agreement — соглашение об уровне обслуживания.

TP

Termination Point — точка завершения, как определено в параграфе 4.2 [RFC8345].

TWAMP

Two-Way Active Measurement Protocol — протокол активных измерений в 2 направлениях, заданный в [RFC5357].

VPLS

Virtual Private LAN Service — служба виртуальных частных ЛВС, как определено в [RFC4026].

VPN

Virtual Private Network — виртуальная частная сеть.

3. Использование модели мониторинга производительности

Модели очень важны для автоматизации управления сетью (раздел 3 в [RFC8969]). В частности, нужны модели сети и служб, а также телеметрии производительности для отслеживания производительности сети в соответствии с требованиями сервиса (обычно указываются в SLA).

                     +---------------+
                     |    Клиент     |
                     +-------+-------+
                             |
Модели обслуживания клиентов |
                             |
                     +-------+---------+
                     |  Оркестратор    |
                     |     услуг       |
                     +------+-+--------+
                            | |
    Модели сетевого сервиса | | Модели PM для сети и VPN
                            | |
                     +------+-+--------+
                     |   Контроллер    |
                     |      сети       |
                     +-------+---------+
                             |
     +-----------------------+------------------------+
                           Сеть

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


Модель PM для сети и VPN может служить для раскрытия сведений о рабочей производительности вышележащему уровню, например, оркестратору или иному клиентскому приложению поддержки бизнеса (Business Support System или BSS) или эксплуатации (Operational Support System или OSS) через стандартные API управления сетью. На рисунке 1 показан пример использования многоуровневой архитектуры модели, описанной в [RFC8309].

Перед использованием модели контроллеру нужно обеспечить видимость топологии сети и VPN. Например, контроллер использовать сведения о сети от [RFC8345] и [YANG-SAP] или о VPN от модели L3VPN (L3VPN Network Model или L3NM) [RFC9182] и L2VPN (L2VPN Network Model или L2NM) [RFC9291]. После этого контроллер получает данные о производительности сети или VPN, агрегируя (или фильтруя) данные нижележащих уровней, собранные счётчиками мониторинга на вовлечённых устройствах.

Данные о производительности сети или VPN могут приходить из разных источников. Например, данные мониторинга производительности по каналам базовых сетей можно собирать с помощью методов измерения производительности сети, таких как активные измерения в одном (OWAMP) [RFC4656] или двух (TWAMP) [RFC5357] направлениях, простой протокол двухсторонних активных измерений (Simple Two-way Active Measurement Protocol или STAMP) [RFC8762], измерение потерь и задержек при многопротокольной коммутации по меткам (Multiprotocol Label Switching или MPLS) [RFC6374], In situ OAM (IOAM) [RFC9197]. Данные мониторинга производительности сети, отражающие качество работы сети или службы VPN (например, производительность сети между источником и получателем или между сайтами VPN) могут быть обработаны и агрегированы с использованием, например, сведений из базы данных организации трафика (Traffic Engineering Database или TED) [RFC7471] [RFC8570] [RFC8571] или крупномасштабной измерительной платформы (Large-Scale Measurement Platform или LMAP) [RFC8194].

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

3.1. Сбор данных через механизм публикации и подписки

Некоторые приложения, такие как приложения гарантий обслуживания, которые должны поддерживать постоянное представление рабочих данных и состояния, могут применять модель подписки, заданную в [RFC8641], для предоставления конкретных сведений о производительности сети или службы VPN от источника данных. Например, можно узнать от изменении топологии сети или VPN с помощью уведомлений об изменениях [RFC8641]. Для динамических данных PM (например, маршруты VRF3, записи MAC4, метрика каналов и интерфейсов), могут быть заданы свои уведомления, позволяющие получить более полные данные. Могут быть заданы периодические обновления [RFC8641] для получения данных о производительности в реальном масштабе времени. Для контроллеров и устройств поддерживающих историю производительности в интервале времени, может быть организовано воспроизведение (replay) уведомлений (см. [RFC5277] или [RFC8639]). Можно задать уведомления о сигналах тревоги (alarm) [RFC8632] при выходе показателей производительности за определённые пределы.

Источник данных может использовать модель мониторинга производительности сети или службы VPN, заданную в этом документе, и модель данных YANG-Push [RFC8641] для описания конкретных данных телеметрии.

3.2. Сбор данных по запросу

При получении моментального снимка (snapshot) данных производительности от топологии сети или службы VPN приложение для обеспечения гарантий обслуживания может извлекать сведения с использованием модели PM для сети или службы по протоколу настройки сети (Network Configuration Protocol или NETCONF) [RFC6241] или RESTCONF [RFC8040]. Например, заданный идентификатор link-id для VPN может служить фильтров запроса RESTCONF GET для извлечения данных VPN PM по каналу.

4. Описание модели данных YANG

В этом документе задан модуль YANG ietf-network-vpn-pm, дополняющий модули ietf-network и ietf-network-topology.

4.1. Связи между уровнями топологии

В [RFC8345] задана модель данных YANG для топологии и описи сетей и служб. Топология сервиса, описанная в [RFC8345], включает абстрактную топологию служб выше базовой топологии уровней L1, L2 и L3. Эта топология службы имеет базовые элементы для узлов, каналов и точек завершения. Типовой пример топологии представлен на риснке 3 в [RFC8345] с двумя службами VPN в общей топологии L3. Топология каждой службы VPN отображается на подмножество узлов топологии L3.

На рисунке 2 показан пример иерархии топологий с сопоставлением топологии двух служб VPN и базовой сети L3.

                     VPN 1                       VPN 2
          +------------------------+   +------------------------+
         /                        /   /                        /
        / S1C_[VN3]..........    /   /                        /
       /         \          :   /   / S2A_[VN1]____[VN3]_S2B /
      /           \         :  /   /        *        *      /
     /             \        :............ * ....     *     /
    / S1B_[VN2]____[VN1]_S1A /   /       *     :     *    /
   +---------:-------:------+   +-------*------:-----*---+
             :        :      * * *  * *        :     *
             :         :   *                   :     *
   Сайт-1A   :  +-------:-*--------------------:-----*-----+ Сайт-1C
     [CE1]___:_/_______[N1]___________________[N2]___*____/__[CE3]
             :/       / / \             _____//      *   /
   [CE5]_____:_______/ /    \     _____/     /     *    /
 Сайт-2A    /:        /       \  /          /    *     /
           / :                [N5]         /   *      /
          /   :     /       __/ \__       /  *       /
         /     :   /    ___/       \__   / *        /
Сайт-1B /       : / ___/              \ /*         /  Сайт-2B
[CE2]__/________[N4]__________________[N3]________/____[CE4]
      /                                          /
     +------------------------------------------+
                                     Топология L3
N   Узел
VN  Узел VPN
S   Сайт
CE  Граничное устройство клиента
__  Канал внутри сетевого уровня
:   Сопоставление топологии службы VPN 1 и топологии L3
*   Сопоставление топологии службы VPN 2 и топологии L3

Рисунок 2. Пример сопоставления топологии между VPN и базовой сетью.


VPN 1

Топология этой службы поддерживает соединения «звезда» (Hub-and-Spoke) для «клиента 1», обеспечивающие доступ на трёх сайтах — 1A, 1B, 1C. Эти сайты подключены к узлам, отображённым на узлы 1 (N1), 2 (N2) и 4 (N4) в базовой сети L3. Сайт-1A играет роль концентратора (Hub), 1B и 1C настроены как лучи (Spoke).

VPN 2

Топология этой службы обеспечивает соединения «каждый с каждым» для «клиента 2», обеспечивающие доступ на двух сайтах 2A и 2B. Эти сайты соединены с узлами, которые отображаются на узлы 1 (N1) и 3 (N3) в базовой сети L3.

На основе ассоциация между топологией обеих VPN и топологией базовой сети модуль YANG для PM сетей и служб VPN извлекает сведения о производительности из базовой сети и служб VPN. Например, модуль может отслеживать статистику PM для каналов и статистику портов в базовой сети (сети L1, L2, L3, OSPF). Он может также предоставлять статистику VPN PM, которые можно разделить на PM для туннеля VPN и узлов доступа VPN PE (Рисунок 3).

          +-----------------------------------------------------+
          |                                                     |
          |                      Канал VPN2                     |
          |              |<-------------------->|               |
          |              |                      |               |
          |      VPN2+---+---+              +---+---+VPN2       |
          |       TP1| VN1   |  Туннель PM  |  VN3  |TP2        |
          |       ---+ PE A  |==============|  PE B +----       |
          |vpn-access+-------+              +-------+ vpn-access|
          |-interface|                              | -interface|
          |          |##############################|           |
          |          |inter-vpn-access-interface PM |           |
          |                                                     |
          +-----------------------------------------------------+
          |                                                     |
          |                                                     |
   +----+ |        TP+-----+ Канал +---+ Канал +-----+TP        | +----+
   | CE4+-+----------+ N1  +-------+-N2+-------+  N3 +----------+-+CE5 |
   +----+ |       1-1+-----+1-2 2-1+---+2-2 3-1+-----+3-2       | +----+
          |                                                     |
          |                                                     |
          +-----------------------------------------------------+
N   Узел
VN  Узел VPN
TP  Точка завершения
-   Канал

Рисунок 3. Пример VPN PM.


На рисунке 3 приведён пример VPN PM и двух методов измерения VPN PM, включающих туннель VPN и интерфейс между VPN. VPN PM может также предоставлять статистику для интерфейсов доступа VPN, числа текущих маршрутов VRF или записей L2VPN MAC на узле VPN.

4.2. Добавление мониторинга производительности на уровне сети

Описанный ниже модуль может служить для мониторинга производительности базовых сетей и служб VPN, которые будут отдельными записями в списке сетей [RFC8345]. Различия определяются присутствием контейнера service. differences are as follows:

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

  • Наличие контейнера указывает мониторинг производительности службы VPN, заданной листом service-type, например, L3VPN или VPLS. Значения взяты из [RFC9181]. Когда экземпляр топологии сети содержит L3VPN или иные типы сетей L2VPN, он представляет экземпляр VPN способный отслеживать производительность.

Дерево YANG на рисунке 4 является частью дерева ietf-network-vpn-pm и определяет указанные ниже атрибуты сетевого уровня.

vpn-id

Указывает идентификатор службы VPN, определённый в [RFC9181]. Этот идентификатор служит для сопоставления статуса производительности с конфигурацией сетевой службы.

vpn-service-topology

Указывает тип топологии службы VPN. Эта модель поддерживает варианты any-to-any (каждый с каждым), hub-spoke (где концентраторы могут обмениваться трафиком) и hub-spoke-disjoint (концентраторы не могут обмениваться трафиком), взятые из [RFC9181]. Эти типы топологии служб VPN можно использовать для описания взаимодействий между сайтами VPN.
   module: ietf-network-vpn-pm
     augment /nw:networks/nw:network/nw:network-types:
       +--rw service!
          +--rw service-type            identityref
          +--rw vpn-id?                 vpn-common:vpn-id
          +--rw vpn-service-topology?   identityref

Рисунок 4. Дерево YANG сетевого уровня.

4.3. Добавление мониторинга производительности на уровне узла

Дерево YANG на рисунке 5 показывает связанную с узлом часть дерева ietf-network-vpn-pm. Для мониторинга производительности модуль задаёт указанные ниже атрибуты.

node-type

Указывает тип устройства — PE, P, или ASBR5, как определено в [RFC4026] и [RFC4364], чтобы можно было сообщать метрику производительности между двумя любыми узлами определённого типа.

entry-summary

Список наборов параметров статистики IPv4, IPv6 и MAC. Подробная статистика задаётся отдельно.

Для топологии службы VPN модуль определяет ещё один атрибут.

role

Указывает роль в конкретной топологии службы VPN. Роли взяты из [RFC9181] (например, any-to-any-role, spoke-role, hub-role).
     augment /nw:networks/nw:network/nw:node:
       +--rw node-type?       identityref
       +--ro entry-summary
          +--ro ipv4-num
          |  +--ro maximum-routes?        uint32
          |  +--ro total-active-routes?   uint32
          +--ro ipv6-num
          |  +--ro maximum-routes?        uint32
          |  +--ro total-active-routes?   uint32
          +--ro mac-num
             +--ro maximum-mac-entries?        uint32
             +--ro total-active-mac-entries?   uint32
     augment /nw:networks/nw:network/nw:node:
       +--rw role?   identityref

Рисунок 5. Дерево YANG на уровне узла.

4.4. Добавление мониторинга производительности на уровне канала и TP

Дерево YANG на рисунке 6 показывает связанную с каналами и точками завершениячасть дерева ietf-network-vpn-pm.

Каналы делятся на 2 типа — топологические (определены в [RFC8345]) и абстрактные каналы VPN между PE (определены в этом модуле).

Данные производительности для канала — это набор счётчиков и датчиков, сообщающих состояние производительности. Все эти показатели определены как односторонние (unidirectional).

     augment /nw:networks/nw:network/nt:link:
       +--rw perf-mon
          +--rw low-percentile?            percentile
          +--rw intermediate-percentile?   percentile
          +--rw high-percentile?           percentile
          +--rw measurement-interval?      uint32
          +--ro pm* [pm-type]
          |  +--ro pm-type          identityref
          |  +--ro pm-attributes
          |     +--ro start-time?                     yang:date-and-time
          |     +--ro end-time?                       yang:date-and-time
          |     +--ro pm-source?                      identityref
          |     +--ro one-way-pm-statistics
          |     |  +--ro loss-statistics
          |     |  |  +--ro packet-loss-count?   yang:counter64
          |     |  |  +--ro loss-ratio?          percentage
          |     |  +--ro delay-statistics
          |     |  |  +--ro unit-value?                     identityref
          |     |  |  +--ro min-delay-value?                yang:gauge64
          |     |  |  +--ro max-delay-value?                yang:gauge64
          |     |  |  +--ro low-delay-percentile?           yang:gauge64
          |     |  |  +--ro intermediate-delay-percentile?  yang:gauge64
          |     |  |  +--ro high-delay-percentile?          yang:gauge64
          |     |  +--ro jitter-statistics
          |     |     +--ro unit-value?                     identityref
          |     |     +--ro min-jitter-value?               yang:gauge64
          |     |     +--ro max-jitter-value?               yang:gauge64
          |     |     +--ro low-jitter-percentile?          yang:gauge64
          |     |     +--ro intermediate-jitter-percentile? yang:gauge64
          |     |     +--ro high-jitter-percentile?         yang:gauge64
          |     +--ro one-way-pm-statistics-per-class* [class-id]
          |        +--ro class-id             string
          |        +--ro loss-statistics
          |        |  +--ro packet-loss-count?   yang:counter64
          |        |  +--ro loss-ratio?          percentage
          |        +--ro delay-statistics
          |        |  +--ro unit-value?                     identityref
          |        |  +--ro min-delay-value?                yang:gauge64
          |        |  +--ro max-delay-value?                yang:gauge64
          |        |  +--ro low-delay-percentile?           yang:gauge64
          |        |  +--ro intermediate-delay-percentile?  yang:gauge64
          |        |  +--ro high-delay-percentile?          yang:gauge64
          |        +--ro jitter-statistics
          |           +--ro unit-value?                     identityref
          |           +--ro min-jitter-value?               yang:gauge64
          |           +--ro max-jitter-value?               yang:gauge64
          |           +--ro low-jitter-percentile?          yang:gauge64
          |           +--ro intermediate-jitter-percentile? yang:gauge64
          |           +--ro high-jitter-percentile?         yang:gauge64
          +--rw vpn-pm-type
             +--rw inter-vpn-access-interface
             |  +--rw inter-vpn-access-interface?   empty
             +--rw vpn-tunnel!
                +--ro vpn-tunnel-type?   identityref
     augment /nw:networks/nw:network/nw:node/nt:termination-point:
       +--ro pm-statistics
          +--ro last-updated?               yang:date-and-time
          +--ro inbound-octets?             yang:counter64
          +--ro inbound-unicast?            yang:counter64
          +--ro inbound-broadcast?          yang:counter64
          +--ro inbound-multicast?          yang:counter64
          +--ro inbound-discards?           yang:counter64
          +--ro inbound-errors?             yang:counter64
          +--ro inbound-unknown-protocol?   yang:counter64
          +--ro outbound-octets?            yang:counter64
          +--ro outbound-unicast?           yang:counter64
          +--ro outbound-broadcast?         yang:counter64
          +--ro outbound-multicast?         yang:counter64
          +--ro outbound-discards?          yang:counter64
          +--ro outbound-errors?            yang:counter64
          +--ro vpn-network-access* [network-access-id]
             +--ro network-access-id           vpn-common:vpn-id
             +--ro last-updated?               yang:date-and-time
             +--ro inbound-octets?             yang:counter64
             +--ro inbound-unicast?            yang:counter64
             +--ro inbound-broadcast?          yang:counter64
             +--ro inbound-multicast?          yang:counter64
             +--ro inbound-discards?           yang:counter64
             +--ro inbound-errors?             yang:counter64
             +--ro inbound-unknown-protocol?   yang:counter64
             +--ro outbound-octets?            yang:counter64
             +--ro outbound-unicast?           yang:counter64
             +--ro outbound-broadcast?         yang:counter64
             +--ro outbound-multicast?         yang:counter64
             +--ro outbound-discards?          yang:counter64
             +--ro outbound-errors?            yang:counter64

Рисунок 6. Ветви YANG для канала и точки завершения.

Для узлов данных link, указанных на рисунке 6, модуль YANG задаёт указанный ниже минимальный набор атрибутов производительности на уровне канала.

Параметры в процентилях

Модуль поддерживает указание параметров задержки и её вариаций в процентилях. Имеется три значения в процентилях для настройки разных уровней отчётности. Про умолчанию используется низкий (low, 10-й процентиль), средний (intermediate, 50-й процентиль) и высокий (high, 90-й процентиль). Настройка для процентиля значения 0.000 указывает, что клиент не заинтересован в получении соответствующего процентиля. Если такое значение задано для всех процентилей, для данного показателя не будут сообщаться узлы с процентилями (например, задержки и их вариации в одном направлении), а останутся лишь узлы пиковых и минимальных значений. Например, клиент может указать серверу, что он заинтересован в получении лишь высоких процентилей. Тогда для данного канала в заданные моменты start-time, end-time и measurement-interval будут сообщаться значения high-delay-percentile и high-jitter-percentile. Пример использования процентилей дап в Приложении A.3.

Интервал измерения (measurement-interval)

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

Время старта (start-time)

Время начала измерений производительности для статистики канала.

Время окончания (end-time)

Время окончания измерений производительности для статистики канала.

Источник данных PM (pm-source)

Указывает источник данных мониторинга производительности, например, состояние канала BGP (BGP — Link State или BGP-LS) [RFC8571]. Может собираться статистика абстрактных каналов VPN на основе механизмов VPN OAM, например, механизмов OAM из [RFC9182] или Ethernet OAM [ITU-T-Y-1731] из [RFC9291]. Кроме того, данные могут быть основаны на механизмах OAM базовой технологии, например, OAM туннеля GRE.

Статистика потерь

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

Статистика задержек

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

Статистика вариаций задержки

Набор атрибутов статистики вариаций задержки пакетов IP в одном направлении [RFC3393], которые служат для измерения сквозных вариаций между сайтами VPN или любыми двумя узлами сети. Могут указываться пиковые и минимальные значения или значения процентилей.

Статистика PM по классам (one-way-pm-statistics-per-class)

Односторонняя статистика PM по классам содержит статистику измерений для топологии физических или абстрактных каналов между VPN PE я данными именами class-id. Список задаётся отдельно от one-way-pm-statistics, используемой для сбора базовых показателей для неуказанных class-id.

Тип VPN PM (vpn-pm-type)

Указывает тип мониторинга производительности VPN — inter-vpn-access-interface PM или vpn-tunnel PM, которые являются распространёнными для VPN. Тип inter-VPN-access-interface PM служит для мониторинга производительности логических соединений VPN «точка-точка» (point-to-point) между исходным и целевым интерфейсами доступа VPN. Тип vpn-tunnel PM служит для мониторинга производительности туннелей VPN. Тип inter-VPN-access-interface PM включает мониторинг PE-PE, поэтому обычно применяется лишь 1 из этих двух методов. Тип inter-VPN-access-interface определён как пустой лист, который не привязан к какому-либо конкретному интерфейсу доступа VPN. Исходный и целевой интерфейсы доступа VPN для измерения могут быть добавлены (augment) при необходимости.

Тип туннеля VPN (vpn-tunnel-type)

Указывает тип протокола абстрактного канала VPN, такой как GRE или IP-in-IP. Лист указывает идентификатор базового транспорта (underlay-transport) заданный в [RFC9181], который определяет транспортную технологию для передачи трафика службы VPN. В случае нескольких типов туннелей между одной парой узлов VPN может создаваться отдельный канал для каждого типа туннеля.

Для узлов данных termination-point, показанных на рисунке 6, модуль задаёт показанный ниже минимальный набор параметров статистики.

Время последнего обновления (last-updated)

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

Входная статистика

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

Выходная статистика

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

Доступ в сеть VPN (vpn-network-access)

Список счётчиков доступа к сети VPN, определённых в L3NM [RFC9182] или L2NM [RFC9291]. При создании нескольких сетевых подключений VPN через один физический порт могут отслежтваться более детализированные показатели. Если точка TP связана лишь с одной VPN, этот список не требуется.

5. Модуль YANG для мониторинга производительности сетей и VPN

Модуль YANG ietf-network-vpn-pm использует определения типов из [RFC6991], [RFC8345], [RFC8532], [RFC9181].

   <CODE BEGINS> file "ietf-network-vpn-pm@2023-03-20.yang"
   module ietf-network-vpn-pm {
     yang-version 1.1;
     namespace "urn:ietf:params:xml:ns:yang:ietf-network-vpn-pm";
     prefix nvp;

     import ietf-yang-types {
       prefix yang;
       reference
         "RFC 6991: Common YANG Data Types";
     }
     import ietf-vpn-common {
       prefix vpn-common;
       reference
         "RFC 9181: A Common YANG Data Model for Layer 2 and
              Layer 3 VPNs";
     }
     import ietf-network {
       prefix nw;
       reference
         "RFC 8345: A YANG Data Model for Network
              Topologies, Section 6.1";
     }
     import ietf-network-topology {
       prefix nt;
       reference
         "RFC 8345: A YANG Data Model for Network
              Topologies, Section 6.2";
     }
     import ietf-lime-time-types {
       prefix lime;
       reference
         "RFC 8532: Generic YANG Data Model for the Management of
              Operations, Administration, and Maintenance (OAM)
              Protocols That Use Connectionless Communications";
     }

     organization
       "IETF OPSAWG (Operations and Management Area Working Group)";
     contact
       "WG Web:   <https://datatracker.ietf.org/wg/opsawg/> 
        WG List:  <mailto:opsawg@ietf.org>

        Editor: Bo Wu
             <lana.wubo@huawei.com> 

        Editor: Mohamed Boucadair
             <mohamed.boucadair@orange.com> 

        Editor: Qin Wu
             <bill.wu@huawei.com> 

        Author: Oscar Gonzalez de Dios
             <oscar.gonzalezdedios@telefonica.com> 

        Author: Bin Wen
             <bin_wen@comcast.com>"; 
     description
       "Этот модуль YANG задаёт модель для мониторинга 
        производительности сети или службы VPN.

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

        Распространение и применение модуля в исходной или двоичной 
        форме с изменениями или без таковых разрешено в соответствии с
        лицензией Simplified BSD License, изложенной в параграфе 4.c
        IETF Trust's Legal Provisions Relating to IETF Documents
        (https://trustee.ietf.org/license-info). 

        Эта версия модуля YANG является частью RFC 9375, где правовые
        аспекты приведены более полно.";

     revision 2023-03-20 {
       description
         "Исходная версия.";
       reference
         "RFC 9375: A YANG Data Model for Network and VPN Service
              Performance Monitoring";
     }

     identity node-type {
       description
         "Базовый идентификатор для типа узла";
     }

     identity pe {
       base node-type;
       description
         "Граничное устройство провайдера (PE) - устройство или набор
          устройств на границе сети провайдера, обеспечивающих 
          функциональность, требуемую для взаимодействия с клиентом.";
     }

     identity p {
       base node-type;
       description
         "Маршрутизатор провайдера - маршрутизатор в ядре сети, не 
          имеющий интерфейсов для прямого подключения клиентов.";
     }

     identity asbr {
       base node-type;
       description
         "Граничный маршрутизатор автономной системы (ASBR).";
       reference
         "RFC 4364: BGP/MPLS IP Virtual Private Networks (VPNs)";
     }

     identity pm-source-type {
       description
         "Базовый идентификатор, из которого выводятся конкретные типы
          механизмов мониторинга производительности.";
     }

     identity pm-source-bgpls {
       base pm-source-type;
       description
         "Указывает BGP-LS как источник данных PM.";
       reference
         "RFC 8571: BGP - Link State (BGP-LS) Advertisement of
              IGP Traffic Engineering Performance Metric
              Extensions";
     }

     identity pm-source-owamp {
       base pm-source-type;
       description
         "Указывает протокол OWAMP как источник данных PM.";
       reference
         "RFC 4656: A One-way Active Measurement Protocol (OWAMP)";
     }

     identity pm-source-twamp {
       base pm-source-type;
       description
         "Указывает протокол TWAMP как источник данных PM.";
       reference
         "RFC 5357: A Two-Way Active Measurement Protocol (TWAMP)";
     }

     identity pm-source-stamp {
       base pm-source-type;
       description
         "Указывает протокол STAMP как источник данных PM.";
       reference
         "RFC 8762: Simple Two-Way Active Measurement Protocol";
     }

     identity pm-source-y-1731 {
       base pm-source-type;
       description
         "Указывает Ethernet OAM Y.1731 как источник данных PM.";
       reference
         "ITU-T Y.1731: Operations, administration and
                maintenance (OAM) functions and mechanisms
                for Ethernet-based networks";
     }

     identity pm-source-ioam {
       base pm-source-type;
       description
         "Указывает IOAM как источник данных PM.";
       reference
         "RFC 9197: Data Fields for In Situ Operations, Administration,
              and Maintenance (IOAM)";
     }

     identity pm-type {
       description
         "<Базовый идентификатор для типа PM.";
     }

     identity pm-type-network-link {
       base pm-type;
       description
         "Указывает тип PM для канала в топологии сети.";
     }

     identity pm-type-vpn-inter-access {
       base pm-type;
       description
         "Указывает тип PM для логических соединений VPN «точка-точка»
          между исходным и целевым интерфейсами доступа VPN.";
     }

     identity pm-type-vpn-tunnel {
       base pm-type;
       description
         "Указывает тип PM для туннелей VPN.";
     }

     typedef percentage {
       type decimal64 {
         fraction-digits 5;
         range "0..100";
       }
       description
         "В процентах до 5 знаков после запятой.";
     }

     typedef percentile {
       type decimal64 {
         fraction-digits 3;
         range "0..100";
       }
       description
         "Процентиль - это значение от 0 до 100, имеющее до 3 знаков в
          дробной части, например, 10.000, 99.900, 99.990. Если для
          данного измерения односторонней задержки задан процентиль 
          95.000 и 95-й процентиль односторонней задержки составляет 2
          мсек, тогда 95 процентов значений выборки задержки будут иметь
          значение не больше 2 миллисекунд.";
     }

     grouping entry-summary {
       description
         "Сводная группировка записей, применяемая для дополнения 
          топологии сети.";
       container entry-summary {
         config false;
         description
           "Контейнер для сводки VPN или сети.";
         container ipv4-num {
           leaf maximum-routes {
             type uint32;
             description
               "Максимальное число маршрутов IPv4 для VPN или сети.";
           }
           leaf total-active-routes {
             type uint32;
             description
               "Общее число активных маршрутов IPv4 для VPN или сети.";
           }
           description
             "Параметры, относящиеся к IPv4.";
         }
         container ipv6-num {
           leaf maximum-routes {
             type uint32;
             description
               "Максимальное число маршрутов IPv6 для VPN или сети.";
           }
           leaf total-active-routes {
             type uint32;
             description
               "Общее число активных маршрутов IPv6 для VPN или сети.";
           }
           description
             "Параметры, относящиеся к IPv6.";
         }
         container mac-num {
           leaf maximum-mac-entries {
             type uint32;
             description
               "Максимальное число записей MAC для VPN или сети.";
           }
           leaf total-active-mac-entries {
             type uint32;
             description
               "Общее число активных записей MAC для VPN или сети.";
           }
           description
             "Статистика MAC.";
         }
       }
     }

     grouping link-loss-statistics {
       description
         "Группировка для статистики ошибок на канал.";
       container loss-statistics {
         description
           "Сводка потерь в одном направлении.";
         reference
           "RFC 4656: A One-way Active Measurement Protocol (OWAMP)
            ITU-T Y.1731: Operations, administration and
                  maintenance (OAM) functions and mechanisms
                  for Ethernet-based networks";
         leaf packet-loss-count {
           type yang:counter64;
           description
             "Общее число потерянных пакетов.";
         }
         leaf loss-ratio {
           type percentage;
           description
             "Доля потерянных пакетов в процентах от числа переданных.";
         }
       }
     }

     grouping link-delay-statistics {
       description
         "Группировка для статистики задержки на канал.";
       container delay-statistics {
         description
           "Сводка задержки в одном направлении.";
         reference
           "RFC 4656: A One-way Active Measurement Protocol (OWAMP)
            ITU-T Y.1731: Operations, administration and
                  maintenance (OAM) functions and mechanisms
                  for Ethernet-based networks";
         leaf unit-value {
           type identityref {
             base lime:time-unit-type;
           }
           default "lime:milliseconds";
           description
             "Единицы времени (возможны часы, минуты, секунды, 
              милли-, микро- и наносекунды).";
         }
         leaf min-delay-value {
           type yang:gauge64;
           description
             "Минимальная наблюдаемая односторонняя задержка.";
         }
         leaf max-delay-value {
           type yang:gauge64;
           description
             "Максимальная наблюдаемая односторонняя задержка.";
         }
         leaf low-delay-percentile {
           type yang:gauge64;
           description
             "Низкий процентиль наблюдаемой односторонней задержки
              для конкретного метода измерения.";
         }
         leaf intermediate-delay-percentile {
           type yang:gauge64;
           description
             "Средний процентиль наблюдаемой односторонней задержки
              для конкретного метода измерения.";
         }
         leaf high-delay-percentile {
           type yang:gauge64;
           description
             "Высокий процентиль наблюдаемой односторонней задержки
              для конкретного метода измерения.";
         }
       }
     }

     grouping link-jitter-statistics {
       description
         "Группировка для статистики вариаций задержки на канал.";
       container jitter-statistics {
         description
           "Сводка вариаций задержки в одном направлении.";
         reference
           "RFC 3393: IP Packet Delay Variation Metric
                for IP Performance Metrics (IPPM)
            RFC 4656: A One-way Active Measurement Protocol (OWAMP)
            ITU-T Y.1731: Operations, administration and
                  maintenance (OAM) functions and mechanisms
                  for Ethernet-based networks";
         leaf unit-value {
           type identityref {
             base lime:time-unit-type;
           }
           default "lime:milliseconds";
           description
             "Единицы времени (возможны часы, минуты, секунды, 
              милли-, микро- и наносекунды).";
         }
         leaf min-jitter-value {
           type yang:gauge64;
           description
             "Минимальные наблюдаемые вариации односторонней задержки.";
         }
         leaf max-jitter-value {
           type yang:gauge64;
           description
             "Максимальные наблюдаемые вариации односторонней задержки";
         }
         leaf low-jitter-percentile {
           type yang:gauge64;
           description
             "Низкий процентиль наблюдаемых вариаций односторонней 
              задержки.";
         }
         leaf intermediate-jitter-percentile {
           type yang:gauge64;
           description
             "Средний процентиль наблюдаемых вариаций односторонней 
              задержки.";
         }
         leaf high-jitter-percentile {
           type yang:gauge64;
           description
             "Высокий процентиль наблюдаемых вариаций односторонней 
              задержки.";
         }
       }
     }

     grouping tp-svc-telemetry {
       leaf last-updated {
         type yang:date-and-time;
         config false;
         description
           "Дата и время последнего обновления счетчиков.";
       }
       leaf inbound-octets {
         type yang:counter64;
         description
           "Общее число октетов, полученных интерфейсом, включая
            символы кадрирования.";
       }
       leaf inbound-unicast {
         type yang:counter64;
         description
           "Общее число входящих индивидуальных пакетов.";
       }
       leaf inbound-broadcast {
         type yang:counter64;
         description
           "Общее число входящих широковещательных пакетов.";
       }
       leaf inbound-multicast {
         type yang:counter64;
         description
           "Общее число входящих групповых пакетов.";
       }
       leaf inbound-discards {
         type yang:counter64;
         description
           "Число входящих пакетов, которые были отброшены, несмотря на
            отсутствие обнаруженных ошибок. Причинами отбрасывания могут
            быть освобождение буферного пространства, нехватка буферов
            и т. п.";
       }
       leaf inbound-errors {
         type yang:counter64;
         description
           "Общее число входящих пакетов с ошибками.";
       }
       leaf inbound-unknown-protocol {
         type yang:counter64;
         description
           "Чсило полученных интерфейсом пакетов, которые были отброшены 
            из-за неизвестного или не поддерживаемого протокола.";
       }
       leaf outbound-octets {
         type yang:counter64;
         description
           "Общее число октетов, переданных интерфейсом, включая
            символы кадрирования.";
       }
       leaf outbound-unicast {
         type yang:counter64;
         description
           "Общее число исходящих индивидуальных пакетов.";
       }
       leaf outbound-broadcast {
         type yang:counter64;
         description
           "Общее число исходящих широковещательных пакетов.";
       }
       leaf outbound-multicast {
         type yang:counter64;
         description
           "Общее число исходящих групповых пакетов.";
       }
       leaf outbound-discards {
         type yang:counter64;
         description
           "Число входящих пакетов, которые были отброшены, несмотря на
            отсутствие обнаруженных ошибок, препятствующих передача. 
            Причинами отбрасывания могут быть освобождение буферного 
            пространства, нехватка буферов и т. п.";
       }
       leaf outbound-errors {
         type yang:counter64;
         description
           "Общее число исходящих пакетов с ошибками.";
       }
       description
         "Группировка для телеметрии интерфейсов службы.";
     }

     augment "/nw:networks/nw:network/nw:network-types" {
       description
         "Определяет типы топологии службы.";
       container service {
         presence "Наличие контейнера указывает мониторинг 
                   производительности службы VPN, а отсутствие - 
                   мониторинг производительности сети.";
         description
           "Контейнер для службы VPN.";
         leaf service-type {
           type identityref {
             base vpn-common:service-type;
           }
           mandatory true;
           description
             "Указывает тип сервиса, например, L3VPN, VPLS.";
         }
         leaf vpn-id {
           type vpn-common:vpn-id;
           description
             "Идентификатор VPN.";
         }
         leaf vpn-service-topology {
           type identityref {
             base vpn-common:vpn-topology;
           }
           description
             "Топология службы VPN, например, hub-spoke, any-to-any,
              hub-spoke-disjoint.";
         }
       }
     }

     augment "/nw:networks/nw:network/nw:node" {
       description
         "Добавляет общие атрибуты для узла сети.";
       leaf node-type {
         type identityref {
           base node-type;
         }
         description
           "Тип узла, например, PE, P, ASBR.";
       }
       uses entry-summary;
     }

     augment "/nw:networks/nw:network/nw:node" {
       when '../nw:network-types/nvp:service' {
         description
           "Дополнение для PM службы VPN.";
       }
       description
         "Добавление атрибутов службы VPN узлу сети.";
       leaf role {
         type identityref {
           base vpn-common:role;
         }
         default "vpn-common:any-to-any-role";
         description
           "Роль узла в топологии службы VPN.";
       }
     }

     augment "/nw:networks/nw:network/nt:link" {
       description
         "Добавление атрибутов PM к каналу сетевой топологии.";
       container perf-mon {
         description
           "Контейнер для атрибутов PM.";
         leaf low-percentile {
           type percentile;
           default "10.000";
           description
             "Низкий процентиль для отчёта. Установка значения 0.000
              указывает, что клиент не заинтересован в получении.";
         }
         leaf intermediate-percentile {
           type percentile;
           default "50.000";
           description
             "Средний процентиль для отчёта. Установка значения 0.000
              указывает, что клиент не заинтересован в получении.";
         }
         leaf high-percentile {
           type percentile;
           default "95.000";
           description
             "Высокий процентиль для отчёта. Установка значения 0.000
              указывает, что клиент не заинтересован в получении.";
         }
         leaf measurement-interval {
           type uint32 {
             range "1..max";
           }
           units "seconds";
           default "60";
           description
             "Интервал измерений PM.";
         }
         list pm {
           key "pm-type";
           config false;
           description
             "Список PM по типам PM.";
           leaf pm-type {
             type identityref {
               base pm-type;
             }
             config false;
             description
               "Тип PM для измеренных атрибутов PM.";
           }
           container pm-attributes {
             description
               "Контейнер для атрибутов PM.";
             leaf start-time {
               type yang:date-and-time;
               config false;
               description
                 "Дата и время последнего начала измерения.";
             }
             leaf end-time {
               type yang:date-and-time;
               config false;
               description
                 "Дата и время последнего окончания измерения.";
             }
             leaf pm-source {
               type identityref {
                 base pm-source-type;
               }
               config false;
               description
                 "Инструмент OAM, используемый для сбора данных PM.";
             }
             container one-way-pm-statistics {
               config false;
               description
                 "Контейнер для атрибутов телеметрии канала.";
               uses link-loss-statistics;
               uses link-delay-statistics;
               uses link-jitter-statistics;
             }
             list one-way-pm-statistics-per-class {
               key "class-id";
               config false;
               description
                 "Список данных PM по классам обслуживания.";
               leaf class-id {
                 type string;
                 description
                   "Значение class-id служит для указания класса
                    обслужтвания. Эти идентификаторы находятся в
                    ведении локального администратора.";
               }
               uses link-loss-statistics;
               uses link-delay-statistics;
               uses link-jitter-statistics;
             }
           }
         }
       }
     }

     augment "/nw:networks/nw:network/nt:link/perf-mon" {
       when '../../nw:network-types/nvp:service' {
         description
           "Дополнение PM для службы VPN.";
       }
       description
         "Дополнение атрибутов PM службы VPN к каналу топологии сети.";
       container vpn-pm-type {
         description
           "Тип VPN PM логического одностороннего канала VPN 
            точка-точка.";
         container inter-vpn-access-interface {
           description
             "Указывает inter-vpn-access-interface PM, используемый для
              мониторинга производительности логических соединений VPN
              точка-точка между исходным и целевым интерфейсом доступа 
              VPN.";
           leaf inter-vpn-access-interface {
             type empty;
             description
               "Подстановка (placeholder) для inter-vpn-access-interface 
                PM, не связанного с конкретным интерфейсом доступа VPN.
                Исходный или целевой интерфейс доступ VPN можно
                добавить при необходимости.";
           }
         }
         container vpn-tunnel {
           presence "Включает PM для туннеля VPN.";
           description
             "Указывает PM туннеля VPN, используемый для мониторинга
              производительности туннелей VPN.";
           leaf vpn-tunnel-type {
             type identityref {
               base vpn-common:protocol-type;
             }
             config false;
             description
               "Указывает тип туннеля VPN, например, GRE, Geneve.";
           }
         }
       }
     }

     augment "/nw:networks/nw:network/nw:node/nt:termination-point" {
       description
         "Дополняет точку завершения топологии сети атрибутами PM.";
       container pm-statistics {
         config false;
         description
           "Контейнер для атрибутов PM точки завершения.";
         uses tp-svc-telemetry;
       }
     }

     augment "/nw:networks/nw:network/nw:node"
           + "/nt:termination-point/pm-statistics" {
       when '../../../nw:network-types/nvp:service' {
         description
           "Дополнения для PM службы VPN.";
       }
       description
         "Дополняет точку завершения топологии сети атрибутами PM 
          для службы VPN.";
       list vpn-network-access {
         key "network-access-id";
         description
           "Список PM на основе доступа в сеть VPN.";
         leaf network-access-id {
           type vpn-common:vpn-id;
           description
             "Ссылка на идентификатор доступа в сеть VPN.";
         }
         uses tp-svc-telemetry;
       }
     }
   }
   <CODE ENDS>

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

Заданный здесь модуль YANG определяет схему данных, предназначенных для доступа через протоколы управления сетью, такие как NETCONF [RFC6241] и RESTCONF [RFC8040]. Нижним уровнем для NETCONF является уровень защищённого транспорта с обязательно для реализации поддержкой Secure Shell (SSH) [RFC6242]. Нижним уровнем RESTCONF является HTTPS с обязательной реализацией защищённого транспорта TLS [RFC8446].

Модель управления доступом к конфигурации сети (Network Configuration Access Control Model или NACM) [RFC8341] обеспечивает средства для предоставления доступа лишь определенным пользователям NETCONF или RESTCONF к заранее заданному набору содержимого и протокольных операций NETCONF или RESTCONF.

В этом модуле данных YANG определено множество узлов данных, которые разрешают запись, создание и удаление (т. е. config true, как принято по умолчанию). Эти узлы могут быть конфиденциальными или уязвимыми в некоторых сетевых средах. Запись в такие узлы (например, edit-config) без должной защиты может негативно влиять на работу сети. Такие операции записи могут вести к неполноте или неточности измерений, что может влиять на видимость и решения, принимаемые на основе этих сведений. Ниже перечислены ветви и узлы, которые могут быть конфиденциальны или уязвимы.

Таблица 1. Возможные влияния записи в узлы.

Доступ

Узел

Возможное влияние

/nw:networks/nw:network/nw:network-types

write

service type

Отключение VPN PM

write

VPN identifier

Отключение VPN PM

write

VPN service topology

Сбор непригодных данных

/nw:networks/nw:network/nw:node

write

node type

Сбор непригодных данных

write

VPN topology role

Сбор непригодных данных

/nw:networks/nw:network/nw:link/nvp:perf-mon

write

percentile

Ритм передачи отчетов

write

measurement interval

Достоверность мониторинга

write

vpn-pm-type

Достоверность мониторинга

Некоторые из доступных для чтения узлов в этом модуле YANG могут быть конфиденциальны или уязвимы в той или иной сетевой среде. Важно контролировать доступ к таким объектам (например, get, get-config, notification). При их использовании нужно найти компромисс между конфиденциальностью и потребностями мониторинга производительности. Ниже перечислены ветви и узлы, которые могут быть конфиденциальны или уязвимы.

/nw:networks/nw:network/nw:node

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

/nw:networks/nw:network/nt:link/nvp:perf-mon/nvp:one-way-pm-statistics

Несанкционирование чтение этой ветви может раскрывать сведения рабочего состояния каналов базовой сети или абстрактных каналов VPN.

/nw:networks/nw:network/nw:node/nt:termination-point/nvp:pm-statistics

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

Этот модуль YANG не задаёт операций или действий, связанных с удалёнными вызовами процедур (Remote Procedure Call или RPC).

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

Агентство IANA зарегистрировало указанный ниже URI в субреестре ns реестра IETF XML Registry [RFC3688]

   URI:  urn:ietf:params:xml:ns:yang:ietf-network-vpn-pm
   Registrant Contact:  The IESG.
   XML:  N/A; запрошенный URI является пространством имён XML.

Агентство IANA зарегистрировало модуль YANG в субреестре YANG Module Names [RFC6020] реестра YANG Parameters

   Name:  ietf-network-vpn-pm
   Namespace:  urn:ietf:params:xml:ns:yang:ietf-network-vpn-pm
   Maintained by IANA:  N
   Prefix:  nvp
   Reference:  RFC 9375

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

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

[RFC3393] Demichelis, C. and P. Chimento, «IP Packet Delay Variation Metric for IP Performance Metrics (IPPM)», RFC 3393, DOI 10.17487/RFC3393, November 2002, <https://www.rfc-editor.org/info/rfc3393>.

[RFC3688] Mealling, M., «The IETF XML Registry», BCP 81, RFC 3688, DOI 10.17487/RFC3688, January 2004, <https://www.rfc-editor.org/info/rfc3688>.

[RFC4364] Rosen, E. and Y. Rekhter, «BGP/MPLS IP Virtual Private Networks (VPNs)», RFC 4364, DOI 10.17487/RFC4364, February 2006, <https://www.rfc-editor.org/info/rfc4364>.

[RFC4656] Shalunov, S., Teitelbaum, B., Karp, A., Boote, J., and M. Zekauskas, «A One-way Active Measurement Protocol (OWAMP)», RFC 4656, DOI 10.17487/RFC4656, September 2006, <https://www.rfc-editor.org/info/rfc4656>.

[RFC5357] Hedayat, K., Krzanowski, R., Morton, A., Yum, K., and J. Babiarz, «A Two-Way Active Measurement Protocol (TWAMP)», RFC 5357, DOI 10.17487/RFC5357, October 2008, <https://www.rfc-editor.org/info/rfc5357>.

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

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

[RFC6242] Wasserman, M., «Using the NETCONF Protocol over Secure Shell (SSH)», RFC 6242, DOI 10.17487/RFC6242, June 2011, <https://www.rfc-editor.org/info/rfc6242>.

[RFC6374] Frost, D. and S. Bryant, «Packet Loss and Delay Measurement for MPLS Networks», RFC 6374, DOI 10.17487/RFC6374, September 2011, <https://www.rfc-editor.org/info/rfc6374>.

[RFC6991] Schoenwaelder, J., Ed., «Common YANG Data Types», RFC 6991, DOI 10.17487/RFC6991, July 2013, <https://www.rfc-editor.org/info/rfc6991>.

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

[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, «RESTCONF Protocol», RFC 8040, DOI 10.17487/RFC8040, January 2017, <https://www.rfc-editor.org/info/rfc8040>.

[RFC8340] Bjorklund, M. and L. Berger, Ed., «YANG Tree Diagrams», BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, <https://www.rfc-editor.org/info/rfc8340>.

[RFC8341] Bierman, A. and M. Bjorklund, «Network Configuration Access Control Model», STD 91, RFC 8341, DOI 10.17487/RFC8341, March 2018, <https://www.rfc-editor.org/info/rfc8341>.

[RFC8345] Clemm, A., Medved, J., Varga, R., Bahadur, N., Ananthakrishnan, H., and X. Liu, «A YANG Data Model for Network Topologies», RFC 8345, DOI 10.17487/RFC8345, March 2018, <https://www.rfc-editor.org/info/rfc8345>.

[RFC8446] Rescorla, E., «The Transport Layer Security (TLS) Protocol Version 1.3», RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.

[RFC8532] Kumar, D., Wang, Z., Wu, Q., Ed., Rahman, R., and S. Raghavan, «Generic YANG Data Model for the Management of Operations, Administration, and Maintenance (OAM) Protocols That Use Connectionless Communications», RFC 8532, DOI 10.17487/RFC8532, April 2019, <https://www.rfc-editor.org/info/rfc8532>.

[RFC8571] Ginsberg, L., Ed., Previdi, S., Wu, Q., Tantsura, J., and C. Filsfils, «BGP — Link State (BGP-LS) Advertisement of IGP Traffic Engineering Performance Metric Extensions», RFC 8571, DOI 10.17487/RFC8571, March 2019, <https://www.rfc-editor.org/info/rfc8571>.

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

[RFC8762] Mirsky, G., Jun, G., Nydell, H., and R. Foote, «Simple Two-Way Active Measurement Protocol», RFC 8762, DOI 10.17487/RFC8762, March 2020, <https://www.rfc-editor.org/info/rfc8762>.

[RFC9181] Barguil, S., Gonzalez de Dios, O., Ed., Boucadair, M., Ed., and Q. Wu, «A Common YANG Data Model for Layer 2 and Layer 3 VPNs», RFC 9181, DOI 10.17487/RFC9181, February 2022, <https://www.rfc-editor.org/info/rfc9181>.

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

[ITU-T-Y-1731] ITU-T, «Operations, administration and maintenance (OAM) functions and mechanisms for Ethernet-based networks», ITU-T Recommendation G.8013/Y.1731, August 2015, <https://www.itu.int/rec/T-REC-Y.1731/en>.

[RFC4026] Andersson, L. and T. Madsen, «Provider Provisioned Virtual Private Network (VPN) Terminology», RFC 4026, DOI 10.17487/RFC4026, March 2005, <https://www.rfc-editor.org/info/rfc4026>.

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

[RFC7471] Giacalone, S., Ward, D., Drake, J., Atlas, A., and S. Previdi, «OSPF Traffic Engineering (TE) Metric Extensions», RFC 7471, DOI 10.17487/RFC7471, March 2015, <https://www.rfc-editor.org/info/rfc7471>.

[RFC8194] Schoenwaelder, J. and V. Bajpai, «A YANG Data Model for LMAP Measurement Agents», RFC 8194, DOI 10.17487/RFC8194, August 2017, <https://www.rfc-editor.org/info/rfc8194>.

[RFC8309] Wu, Q., Liu, W., and A. Farrel, «Service Models Explained», RFC 8309, DOI 10.17487/RFC8309, January 2018, <https://www.rfc-editor.org/info/rfc8309>.

[RFC8570] Ginsberg, L., Ed., Previdi, S., Ed., Giacalone, S., Ward, D., Drake, J., and Q. Wu, «IS-IS Traffic Engineering (TE) Metric Extensions», RFC 8570, DOI 10.17487/RFC8570, March 2019, <https://www.rfc-editor.org/info/rfc8570>.

[RFC8632] Vallin, S. and M. Bjorklund, «A YANG Data Model for Alarm Management», RFC 8632, DOI 10.17487/RFC8632, September 2019, <https://www.rfc-editor.org/info/rfc8632>.

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

[RFC8969] Wu, Q., Ed., Boucadair, M., Ed., Lopez, D., Xie, C., and L. Geng, «A Framework for Automating Service and Network Management with YANG», RFC 8969, DOI 10.17487/RFC8969, January 2021, <https://www.rfc-editor.org/info/rfc8969>.

[RFC9182] Barguil, S., Gonzalez de Dios, O., Ed., Boucadair, M., Ed., Munoz, L., and A. Aguado, «A YANG Network Data Model for Layer 3 VPNs», RFC 9182, DOI 10.17487/RFC9182, February 2022, <https://www.rfc-editor.org/info/rfc9182>.

[RFC9197] Brockners, F., Ed., Bhandari, S., Ed., and T. Mizrahi, Ed., «Data Fields for In Situ Operations, Administration, and Maintenance (IOAM)», RFC 9197, DOI 10.17487/RFC9197, May 2022, <https://www.rfc-editor.org/info/rfc9197>.

[RFC9291] Boucadair, M., Ed., Gonzalez de Dios, O., Ed., Barguil, S., and L. Munoz, «A YANG Network Data Model for Layer 2 VPNs», RFC 9291, DOI 10.17487/RFC9291, September 2022, <https://www.rfc-editor.org/info/rfc9291>.

[YANG-SAP] Boucadair, M., Ed., Gonzalez de Dios, O., Barguil, S., Wu, Q., and V. Lopez, «A YANG Network Model for Service Attachment Points (SAPs)», Work in Progress, Internet-Draft, draft-ietf-opsawg-sap-15, 18 January 2023, <https://datatracker.ietf.org/doc/html/draft-ietf-opsawg-sap-15>.

Приложение A. Иллюстративные примеры

A.1. Пример подписки для производительности VPN

Пример на рисунке 7 показывает, как клиент подписывается на сведения мониторинга производительности между узлами (node-id) A и B в топологии сети L3. Клиента интересуют параметры мониторинга сквозных потерь.

   POST /restconf/operations/ietf-subscribed-notifications:establish-\6
                                      subscription
   Host: example.com
   Content-Type: application/yang-data+json

   {
     "ietf-subscribed-notifications:input": {
       "stream-subtree-filter": {
         "ietf-network:networks": {
           "network": {
             "network-id": "example:VPN1",
             "ietf-network-vpn-pm:service": {
               "service-type": "ietf-vpn-common:l3vpn"
             },
             "node": [
               {
                 "node-id": "example:A",
                 "ietf-network-vpn-pm:node-type": "pe",
                 "termination-point": [
                   {
                     "tp-id": "example:1-0-1"
                   }
                 ]
               },
               {
                 "node-id": "example:B",
                 "ietf-network-vpn-pm:node-type": "pe",
                 "termination-point": [
                   {
                     "tp-id": "example:2-0-1"
                   }
                 ]
               }
             ],
             "ietf-network-topology:link": [
               {
                 "link-id": "example:A-B",
                 "source": {
                   "source-node": "example:A"
                 },
                 "destination": {
                   "dest-node": "example:B"
                 },
                 "ietf-network-vpn-pm:perf-mon": {
                   "pm": [
                     {
                       "pm-type": "pm-type-vpn-tunnel",
                       "pm-attributes": {
                         "one-way-pm-statistics": {
                           "loss-statistics": {
                             "packet-loss-count": {}
                           }
                         }
                       }
                     }
                   ],
                   "vpn-pm-type": {
                     "vpn-tunnel": {
                       "vpn-tunnel-type": "ietf-vpn-common:gre"
                     }
                   }
                 }
               }
             ]
           }
         },
         "ietf-yang-push:periodic": {
           "period": "500"
         }
       }
     }
   }

Рисунок 7. Пример извлечения Pub/Sub.

A.2. Пример «снимка» производительности VPN

Пример на рисунке 8 показывает тело сообщения VPN PM с запросом RESTCONF для извлечения данных производительности на канале и точке завершения TP, относящимся к VPN1.

   {
     "ietf-network:networks": {
       "network": {
         "network-id": "example:VPN1",
         "node": [
           {
             "node-id": "example:A",
             "ietf-network-vpn-pm:node-type": "pe",
             "termination-point": [
               {
                 "tp-id": "example:1-0-1",
                 "ietf-network-vpn-pm:pm-statistics": {
                   "inbound-octets": "100",
                   "outbound-octets": "150"
                 }
               }
             ]
           },
           {
             "node-id": "example:B",
             "ietf-network-vpn-pm:node-type": "pe",
             "termination-point": [
               {
                 "tp-id": "example:2-0-1",
                 "ietf-network-vpn-pm:pm-statistics": {
                   "inbound-octets": "150",
                   "outbound-octets": "100"
                 }
               }
             ]
           }
         ],
         "ietf-network-topology:link": [
           {
             "link-id": "example:A-B",
             "source": {
               "source-node": "example:A"
             },
             "destination": {
               "dest-node": "example:B"
             },
             "ietf-network-pm:perf-mon": {
               "pm": [
                 {
                   "pm-type": "pm-type-vpn-tunnel",
                   "pm-attributes": {
                     "one-way-pm-statistics": {
                       "loss-statistics": {
                         "packet-loss-count": "120"
                       }
                     }
                   }
                 }
               ],
               "vpn-pm-type": {
                 "vpn-tunnel": {
                   "vpn-tunnel-type": "ietf-vpn-common:gre"
                 }
               }
             }
           }
         ]
       }
     }
   }

Рисунок 8. Пример VPN PM.

A.3. Пример мониторинга процентилей

Это пример данных измерения в процентилях, которые могут быть возвращаны для канала example:A-B между example:A и example:B.

   {
     "ietf-network-topology:link": [
       {
         "link-id": "example:A-B",
         "source": {
           "source-node": "example:A"
         },
         "destination": {
           "dest-node": "example:B"
         },
         "ietf-network-vpn-pm:perf-mon": {
           "low-percentile": "20.000",
           "intermediate-percentile": "50.000",
           "high-percentile": "90.000",
           "pm": [
             {
               "pm-type": "pm-type-vpn-inter-access",
               "pm-attributes": {
                 "one-way-pm-statistics": {
                   "delay-statistics": {
                     "unit-value": "ietf-lime-time-types:milliseconds",
                     "min-delay-value": "43",
                     "max-delay-value": "99",
                     "low-delay-percentile": "64",
                     "intermediate-delay-percentile": "77",
                     "high-delay-percentile": "98"
                   }
                 }
               }
             }
           ],
           "vpn-pm-type": {
             "inter-vpn-access-interface": {
               "inter-vpn-access-interface": [null]
             }
           }
         }
       }
     ]
   }

Рисунок 9. Пример VPN PM со значениями процентилей.

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

Спасибо Joe Clarke, Adrian Farrel, Tom Petch, Greg Mirsky, Roque Gagliano, Erez Segev, Dhruv Dhody за рецензии и важный вклад в этот документ.

Эта работа частично поддерживалась Европейской комиссией в рамках проекта Horizon 2020 по обеспечения защищенного автономного управления трафиком для Tera-потоков SDN (Teraflow), грант № 101015857.

Участники работы

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

Michale Wang
Huawei
Email: wangzitao@huawei.com
 
Roni Even
Huawei
Email: ron.even.tlv@gmail.com
 
Change Liu
China Unicom
Email: liuc131@chinaunicom.cn
 
Honglei Xu
China Telecom
Email: xuhl6@chinatelecom.cn

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

Bo Wu (editor)
Huawei
Yuhua District
101 Software Avenue
Nanjing
Jiangsu, 210012
China
Email: lana.wubo@huawei.com
 
Qin Wu (editor)
Huawei
Yuhua District
101 Software Avenue
Nanjing
Jiangsu, 210012
China
Email: bill.wu@huawei.com
 
Mohamed Boucadair (editor)
Orange
Rennes 35000
France
Email: mohamed.boucadair@orange.com
 
Oscar Gonzalez de Dios
Telefonica
Madrid
Spain
Email: oscar.gonzalezdedios@telefonica.com
 
Bin Wen
Comcast
Email: bin_wen@comcast.com

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

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

nmalykh@protokols.ru


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

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

3VPN Routing and Forwarding — маршрутизация и пересылка VPN.

4Media Access Control — управление доступом к среде передачи.

5Autonomous System Border Router — граничный маршрутизатор автономной системы.

6Строка разделена символом \ в соответствии с RFC 8792.

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

RFC 9402 Concat Notation

Independent Submission                                       M. Basaglia
Request for Comments: 9402                                              
Category: Informational                                      J. Bernards
ISSN: 2070-1721                                                         
                                                                 J. Maas
                                                            1 April 2023

Concat Notation

Нотация Concat

PDF

Аннотация

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

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

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

Это независимый вклад в серию RFC, не связанный с каким-либо потоком RFC. Редактор RFC решил опубликовать документ по своему усмотрению и не делает заявлений о его ценности для реализации или внедрения. Документы, одобренные для публикации редактором RFC Editor не претендуют на статус Internet Standard (см. раздел 2 в RFC 7841).

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

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

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

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

1. Введение

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

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

Описанный в документе язык нотации основан на текстовом представлении и ограничивается кодировкой символов US-ASCII [RFC0020], что позволяет передавать связанные с котами материалы в средах с ограниченными возможностями.

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

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

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

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

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

Subject — субъект, предмет

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

Cat — кот1

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

Container

Термином «контейнер» в этом документе обозначаются неодушевлённые объекты, в которых может размешаться 1 или несколько котов. Чаще всего это картонные коробки, но возможны и иные варианты контейнеров.

2.2. Грамматика

Грамматика языка определена с использованием нотации ABNF [RFC5234].

   SEQUENCE  =  POSITION / POSITION "=>" SEQUENCE
   POSITION  =  ADJACENT
   ADJACENT  =  OVER / ADJACENT "+" OVER
   OVER      =  MULTIPLE / MULTIPLE "/" POSITION
   MULTIPLE  =  CONCAT / NUMBER [ "*" ] MULTIPLE / NUMBER "/" MULTIPLE
   CONCAT    =  SUBJECT [ NUMBER ] / [ PARTIAL ] CONTAINER [ PARTIAL ]
   CONTAINER =  "[" OPT-POS "]" / "(" OPT-POS ")"
   CONTAINER =/ "{" OPT-POS "}" / "<" OPT-POS ">"
   OPT-POS   =  [ POSITION ]
   SUBJECT   =  CAT / 1*ALPHA / "@"
   CAT       =  "cat" / PARTIAL
   PARTIAL   =  "c" / "a" / "t" / "ca" / "at"
   ALPHA     =   %x41-5A / %x61-7A
   NUMBER    =  1*DIGIT
   DIGIT     =  "0" / "1" / "2" / "3" / "4"
   DIGIT     =/ "5" / "6" / "7" / "8" / "9"

3. Элементы

3.1. Субъекты

3.1.1. Коты

Стандартным обозначением кота является слово «кот».

3.1.2. Частичные коты

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

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

Обозначения частичных котов приведены ниже.

   c - голова кота
   a - тело кота
   t - хвост кота
   ca - голова и тело кота
   at - тело и хвост кота.

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

3.1.3. Другие животные

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

3.1.4. Клубки ниток

Клубки ниток (yarn) следует обозначать символом @.

3.2. Контейнеры

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

  • Квадратные скобки [] представляют коробки и другие контейнеры с прямоугольным входным отверстием.

  • Круглые скобки () представляют контейнеры с круглым отверстием или формой.

  • Для представления контейнеров, не имеющих фиксированной формы, нужно применять фигурные скобки {}.

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

3.3. Позиционирование

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

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

3.3.1. Горизонтальная позиция

Для представления расположенных рядом субъектов или контейнеров применяется символ +.

3.3.2. Вертикальная позиция

Для представления субъекта, расположенного над или под другим должен применяться оператор /.

3.3.3. Множество повторяющихся объектов

При повторении нескольких объектов или конфигураций можно применять сокращённую нотацию.

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

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

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

3.4. Изменения с течением времени

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

3.4.1. Устранение неоднозначностей

За маркером субъекта может следовать целое число, чтобы различать конкретных котов, клубки ниток и другие субъекты. Аннотации с такими числовыми значениями должны включать идентификаторы для всех котов и клубков ниток.

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

4. Применение других языков

Слово кот (cat) является английским и предназначено для передачи нотации Concat лишь с использованием кодировки US-ASCII [RFC0020].

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

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

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

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

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

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

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

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

[RFC0020] Cerf, V., «ASCII format for network interchange», STD 80, RFC 20, DOI 10.17487/RFC0020, October 1969, <https://www.rfc-editor.org/info/rfc20>.

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

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

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

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

В этом приложении представлены некоторые примеры нотации Concat.

[cat]

Рисунок 1. Кот в коробке.

[cat] + cat

Рисунок 2. Кот в коробке рядом с котом не в коробке.

cat / [cat]

Рисунок 3. Кот поверх коробки с другим котом.

[c]at

Рисунок 4. Кот с головой в коробке.

3 * cat

Рисунок 5. 3 кота бок о бок.

3 / cat

Рисунок 6. 3 кота каждый поверх другого кота.

cat + cat / [cat]

Рисунок 7. Кот рядом с коробкой, на которой и внутри которой другие коты.

<cat + cat> / [cat]

Рисунок 8. 2 кота на коробке, в которой другой кот.

cat1 + [cat2] => cat2 + [cat1]

Рисунок 9. Коты внутри и вне коробки меняются местами (Swap)

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

Mattia Basaglia
Email: glax@dragon.best
URI: https://dragon.best/
 
Joep Bernards
Email: joep@duali.xyz
 
Joost Maas
Email: J.f.w.maas@tue.nl

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

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

nmalykh@protokols.ru

1Термин «кот» в этом документе можно заменить термином «кошка» на усмотрение читателя, хотя некоторые детали поведения упомянутых существ могут существенно различаться. Прим. перев.

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