previous up index search

Previous: 4.1.1.6 Пассивные оптические сети (PON/EPON/GEPON)    UP: 4.1.1 Ethernet (IEEE 802.3)

4.1.1.7 Сетевая технология OpenFlow (SDN)
Семенов Ю.А. (ГНЦ ИТЭФ)

Протокол конфигурации и управления OpenFlow
Базовая терминология
Общие требования
Логические переключатели OpenFlow
Инструкции
Разрыв соединения
Шифрование
Очереди
Порты
Выявление возможностей
Идентификатор обмена данных (Datapath ID)
Требования, предъявляемые к протоколу управления переключателем
Модель данных
Схема XML
Модификация таблиц переадресации
Удаление потока
Групповая таблица
Операционные требования
Нормативные ограничения
Точка конфигурации OpenFlow
Заголовок сообщения OpenFlow
Структуры портов
Структуры очередей
Структуры параметров сверки
Туннель
Приложение
Классы OXM
Сверка потока
Маскирование полей сверки потока
Поля сверки потока
Структуры инструкций
Структура действий
Сообщения контроллер-переключатель
Конфигурирование переключателя
Конфигурация таблицы переадресации
Сообщения изменения состояния
Сообщение модификации порта
Описание порта
Сообщения конфигурирования очереди
Сообщение вывода
Асинхронные сообщения
Cообщения ошибки
Cимметричные сообщения
SDN для WAN
Библиография

Современные сетевые технологии эволюционируют уже около 40 лет. Существовала 7-уровневая модель построения сетей ISO. Из семи уровней этой модели на практике никогда не было реализовано более четырех. Задачи же все эти годы быстро усложнялись. Это связано со все более глубоким проникновением информационных процессов во все сферы человеческой жизни. Особые требования предъявляет необходимость обеспечения безопасности сети и данных, которые там хранятся. Появляется необходимость в Firewall, не только защищающих периметр сети, но и выделяющих особые зоны безопасности внутри локальной или корпоративной сети. Особые требования возникают при необходимости обеспечить требуемый уровень QoS не только со стороны провайдера услуг, но и в локальной сети. Мало-по-малу все чаще ставятся задачи динамического перераспределения ресурсов сети (пропускная способность, задержки и т.д.). Решить все эти проблемы в рамках традиционных сетевых технологий уже невозможно. Ответить на эти вызовы призвана техника OpenFlow (или SDN - Software Defined Network).

OpenFlow представляет собой открытый стандарт, который позволяет разработчикам работать в локальной сети с экспериментальными протоколами. OpenFlow добавлен в качестве новой возможности в коммерческие переключатели Ethernet, маршрутизаторы и беспроводные узлы доступа, чтобы позволить эксперименты с сетью, не требуя раскрытия внутреннего устройства сетевых устройств. Стандарт OpenFlow в настоящее время принят большинством производителей сетевого оборудования. Сегодня переключатели с поддержкой OpenFlow доступны на рынке сетевого оборудования. Протокол OpenFlow базируется на технологии SDN (Software Defined Networking) и может использоваться в проводных и беспроводных сетях. В настоящий момент протокол имеет версию 1.3. Смотри OpenFlow Management and Configuration Protocol (OF-Config 1.1), Version 1.1, June 25, 2012 (117 стр), а также OpenFlow Switch Specification v1.3.0 104 стр. Далее предлагается сокращенный конспект этих двух публикаций.

В классическом маршрутизаторе или переключателе, быстрая переадресация пакетов (пересылка данных) и решения маршрутизации высокого уровня (операции управления) осуществляются в одном и том же устройстве. Переключатель OpenFlow разделяет эти две функции. Пересылка данных выполняется самим переключателем, в то время как решения маршрутизации поручены отдельному контроллеру, обычно стандартному серверу. Канал связи с контроллером должен быть криптографически защищен. Переключатель OpenFlow и контроллер взаимодействуют друг с другом посредством протокола OpenFlow, который определяет сообщения, такие как packet-received (пакет получен), send-packet-out (отослать пакет), modify-forwarding-table (модифицировать таблицу переадресации), и get-stats (получить статистику).

Передача данных переключателем OpenFlow использует абстракцию таблицы; каждая запись в этой таблице содержит набор полей пакета, которые следует сверять, и действия (такие как send-out-port (порт, куда послать), modify-field (модифицировать поле), или drop (отбросить). Когда переключатель OpenFlow получает пакет, который ему не встречался ранее, для которого нет записи в таблице переадресации, он посылает этот пакет контроллеру. Контроллер затем принимает решение, как обрабатывать пакет. Он может отбросить пакет, или добавить запись маршрутизации, чтобы переадресовать аналогичные пакеты в будущем.

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

Протокол конфигурации и управления OpenFlow

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

Рис.1. Точка конфигурации OpenFlow взаимодействует с операционным контекстом, который может поддерживать работу переключателя OpenFlow, используя конфигурацию и протокол управления (OF-CONFIG)

Протокол OpenFlow предполагает, что OpenFlow обмен данными (напр. переключатель Ethernet, который поддерживает протокол OpenFlow) был сконфигурирован с учетом необходимых данных, таких как IP-адреса контроллеров. Целью протокола конфигурации OpenFlow (OF-CONFIG) является предоставление возможности удаленного конфигурирования обмена данными. Примером работы протокола OF-CONFIG является формирование таблицы переадресации и решений относительно действий, которые протокол Openflow должен выполнять.

OF-CONFIG определяет схему взаимодействия с логическим переключателем OpenFlow (абстракция переключателя). Протокол OF-CONFIG допускает задание характеристик логического переключателя, так чтобы контроллер мог взаимодействовать с переключателем и управлять им посредством протокола OpenFlow.

Версия OF-CONFIG 1.1 определяет операционный контекст одного или более обменов OpenFlow. Переключатель, совместимый с OpenFlow, является эквивалентом реального физического или виртуального сетевого переключателя (напр. переключателя Ethernet), через который осуществляется один или более обменов путем разделения набора ресурсов OpenFlow, таких как порты и очереди данных. Протокол OF-CONFIG позволяет динамическое ассоциирование ресурсов переключателя, совместимого с OpenFlow, с определенными логическими переключателями, которые имеются в переключателе, совместимом с OpenFlow. OFCONFIG не специфицирует того, как получаются ресурсы переключателя, совместимого с OpenFlow. OF-CONFIG предполагает, что такие ресурсы как порты и очереди используются совместно несколькими логическими переключателями (OpenFlow Logical Switches), так что каждый такой переключатель может иметь полный контроль над ресурсами, ему предоставленными.

Задания, которые несут в себе сообщения OF-CONFIG для OpenFlow Capable Switch называются конфигурационными точками OpenFlow. Никаких предположений относительно природы конфигурационной точки OpenFlow не делается. Например, это может быть сервис, предоставляемый программой, выполняющей функцию контроллера OpenFlow или это может быть сервис, предоставляемый традиционной системой сетевого управления. Любое взаимодействие между конфигурационной точкой OpenFlow и контроллерами OpenFlow находятся за пределами стандарта OF-CONFIG 1.1.

На рис. 2 показано взаимодействие различных компонентов протоколов OF-CONFIG 1.1, а линии связи показывают, что точки конфигурации и переключатели, совместимые с OpenFlow, взаимодействуют через OFCONFIG. Установки конфигурации воздействуют на соответствующие контроллеры логических переключателей и сами логические переключатели.

Рис.2. Взаимодействия между компонентами спецификации протоколов OF-CONFIG и OpenFlow

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

Базовая терминология

ТерминЗначение
OpenFlow Capable SwitchПереключатель, совместимый с OpenFlow представляет собой физический или виртуальный переключатель, который может действовать в операционном контексте, как логический переключатель OpenFlow. Такие переключатели содержат и поддерживают ресурсы OpenFlow, которые могут быть ассоциированы с контекстом логического ключа OpenFlow.
OpenFlow Configuration PointТочка конфигурации OpenFlow конфигурирует один или более переключателей OpenFlow посредством протокола конфигурирования и управления OpenFlow (OF-CONFIG).
OpenFlow Logical SwitchЛогический переключатель OpenFlow представляет собой набор ресурсов (напр. портов) переключателя, совместимого с OpenFlow, который может быть ассоциирован с определенным контроллером OpenFlow. Логический переключатель OpenFlow представляет собой средство для переадресации данных.
OpenFlow ResourceРесурс OpenFlow представляет собой порт или очередь, которые ассоциированы с переключателем, поддерживающим OpenFlow и способным быть ассоциированным с логическим переключателем.
OpenFlow QueueОчередь OpenFlow Queue представляет собой ресурс логического переключателя OpenFlow.
OpenFlow PortПорт OpenFlow представляет собой интерфейс, через который производится переадресация данных лочическим переключателем OpenFlow. Порт Openflow может соответствовать физическому порту физического или виртуального переключателя.
OpenFlow ControllerКонтроллер OpenFlow является программой, которая управляет логическими ключами OpenFlow посредством протокола OpenFlow.

Общие требования

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

OF-CONFIG 1.1 должен обеспечить средства для конфигурирования этих параметров.

Логические переключатели OpenFlow

Протокол OpenFlow 1.3 специфицирует различные виды ресурсов OpenFlow, ассоциированных с логическим переключателем. Протокол OF-CONFIG должен поддерживать конфигурирование этих ресурсов, ассоциированных с логическим переключателем OpenFlow. Образцы ресурсов включают в себя очереди и порты, которые сопряжены с логическим переключателем.

Рис. 3. Внутренние устройства переключателя OpenFlow

На рис. 3 видно, что в переключателе может использоваться несколько таблиц переадресации. Таблицы пронумерованы, начиная с 0. Пакет будет передан для анализа следующей таблице, если он прошел фильтрацию предыдущей. Если пакет соответствует критериям отбора, выполняется определенный набор команд. При этом пакет может быть и просто переадресован следующей таблице с помощью команды goto. Каждая запись в таблице переадресации (Flow Table) содержит:

Поля соответствияСчетчикиИнструкции

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

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

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

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

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

Очевидно, что последняя таблица конвейера не должна содержать команд Goto.

Рис. 4. Диаграмма модели данных таблицы переадресаций

Переключатели, совместимые с требованиями OpenFlow, бывают двух типов: только OpenFlow и гибридные OpenFlow. Только OpenFlow переключатели поддерживают исключительно OpenFlow-операции, в этих переключателях все пакеты обрабатываются конвейером, и не могут анализироваться как-то иначе. Гибридные переключатели могут поддерживать также традиционный L2-режим (Ethernet), VLAN, L3-маршрутизацию, ACL и гарантированное QoS.

Модификация таблиц переадресации

Сообщения модификации таблицы переадресации могут иметь следующие типы:

enum ofp_flow_mod_command {
OFPFC_ADD, /* Новый поток. */
OFPFC_MODIFY, /* Модифицировать все подходящие потоки. */
OFPFC_MODIFY_STRICT, /* Модифицировать записи, строго соответствующие эталону и приоритету. */
OFPFC_DELETE, /* Удалить все подходящие потоки. */
OFPFC_DELETE_STRICT /* Удалить записи, строго соответствующие эталону и приоритету. */
};

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

Для корректных запросов добавления (не перекрывающихся), или запросов без проверки перекрытия, переключатель должен вставить запись в оговоренную таблицу переадресации. Если запись переадресации с идентичными полями соответствия (match fields) и приоритетами уже существует в оговоренной таблице, тогда эта запись, включая ее счетчики и длительность, должна быть удалена из таблицы, а новая запись вставлена. При этом не генерируется никакого уведомления, если контроллер хочет получить сообщение удаления, он должен послать DELETE STRICT для старой записи до занесения новой.

Для запросов модификации (OFPFC_MODIFY или OFPFC_MODIFY_STRICT), если соответствующая запись в таблице имеется, поле инструкции этой записи обновляется значением из запроса, в то время как его поля cookie, idle_timeout, hard_timeout, флаги, счетчики и длительность остаются неизменными. Если флаг FPFF_RESET_COUNTS установлен, счетчики записи переадресации должны быть обнулены. Для запросов модификации, если в таблице нет подходящей для запроса записи, ошибка не фиксируется и никакой модификации не происходит.

Для запросов удаления (OFPFC_DELETE или OFPFC_DELETE_STRICT), если соответствующая запись в таблице имеется, она должна быть удалена, и, если запись имеет флаг OFPFF_SEND_FLOW_REM=1, должно быть сформировано сообщение об удалении записи переадресации. Для запросов удаления, если соответствующая запись отсутствует, ошибки не возникает, и никакой модификации записей не происходит.

Команды удаления и модификации не имеют строго определенных версий (OFPFC_MODIFY и OFPFC_DELETE) и (OFPFC_MODIFY_STRICT или OFPFC_DELETE_STRICT). В нечетко определенных версиях могут использоваться эталонные подмены (wildcards) и все записи переадресации, которые соответствуют этим эталонам модифицируются или удаляются. В четких версиях все поля, включая wildcards, и приоритет сравниваются с эталоном и только при полном соответствии производится удаление или модификация. Например, если послано сообщение об удалении записи со всеми установленными wildcard-флагами, команда OFPFC_DELETE удалит все записи из всех таблиц, в то время как команда OFPFC_DELETE_STRICT удалит только правило, которое применяется ко всем пакетам специфицированного приоритета.

Для нечетких команд модификации и удаления, которые содержат wildcards, соответствие происходит, когда запись переадресации строго соответствует параметрам команды. Например, если команда OFPFC_DELETE указывает удалить все записи переадресации с портом назначения 80, тогда запись переадресации, которая накрывает все поля с помощью wildcards, не будет удалена. Однако, команда OFPFC_DELETE, которая накрывает все поля посредством wildcards, удалит запись, которая соответствует трафику через порт 80.

Команды удаления могут опционно фильтроваться по группе назначения или выходному порту. Если поле out_port содержит значение отличное от OFPP_ANY, в случае выявления соответствия вводится ограничение. Это ограничение заключается в том, что каждое правило сверки должно содержать выходную инструкцию, относящуюся к определенному порту. Это ограничение лимитируется только действиями, относящимися к данному правилу. Другими словами, переключатель должен отслеживать весь набор инструкций, относящийся к группе, которая может иметь подходящие выходные команды. Если out_group отличается от OFPG_ANY, она вводит аналогичные ограничения на групповые действия. Эти поля игнорируются сообщениями OFPFC_ADD, OFPFC_MODIFY и OFPFC_MODIFY_STRICT.

Команды удаления и модификации могут также фильтроваться с помощью cookie, если поле cookie_mask содержит значение отличное от 0. Это ограничение заключается в том, что биты, специфицированные cookie_mask в полях cookie команды модификации и записи переадресации должны совпадать. Другими словами, (flow.cookie & flow mod.cookie mask) == (flow mod.cookie & flow mod.cookie mask).

Если сообщение модификации записи переадресации специфицирует таблицу неверно или использует 0xFF, переключатель посылает сообщение ofp_error_msg с типом OFPET_FLOW_MOD_FAILED и кодом OFPFMFC_BAD_TABLE_ID.

Удаление потока

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

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

Групповая таблица

Группа - это список перечней операций и некоторые средства выбора одного или более перечней (buckets) для обработки отдельных пакетов.

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

Каждая запись группы (смотри таблицу ниже) содержит:

Идентификатор группыТип группыСчетчикиПеречни команд

Определены следующие типы групп:

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

/* Group commands */
enum ofp_group_mod_command {
OFPGC_ADD, /* Новая группа. */
OFPGC_MODIFY, /* Модифицировать все подходящие группы. */
OFPGC_DELETE, /* Удалить все подходящие группы. */
};

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

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

Например, группа быстрого рерутинга может иметь два перечня инструкций, где каждый указывает на группу выбора. Если переключатель не поддерживает группы групп, он должен послать сообщение ofp_error_msg с типом OFPET_GROUP_MOD_FAILED и кодом OFPGMFC_CHAINING_UNSUPPORTED. Если послан групповой модификатор (group mod), такой что может возникнуть зацикливание пакетов, переключатель должен послать сообщение ofp_error_msg с типом OFPET_GROUP_MOD_FAILED и кодом OFPGMFC_LOOP. Если переключатель не поддерживает такие проверки, поведение переадресации неопределенно.

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

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

Если специфицированный тип группы не корректен (т.e: включает в себя поля, такие как вес, который не специфицирован для заданного типа группы), тогда переключатель отказывается добавить групповую запись и должен послать сообщение ofp_error_msg с типом OFPET_GROUP_MOD_FAILED и кодом OFPGMFC_INVALID_GROUP.

Если переключатель не поддерживает веса перечня, отличные от 1, он должен отказаться добавлять групповую запись и должен послать сообщение ofp_error_msg с типом OFPET_GROUP_MOD_FAILED и кодом OFPGMFC_WEIGHT_UNSUPPORTED.

Если переключатель не может добавить входную запись группы из-за недостатка места, он должен послать сообщение ofp_error_msg с типом OFPET_GROUP_MOD_FAILED и кодом OFPGMFC_OUT_OF_GROUPS.

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

Если переключатель не может добавить входную запись группы, из-за отсутствия поддержки конфигурации живучести, он должен послать сообщение ofp_error_msg с типом OFPET_GROUP_MOD_FAILED и кодом OFPGMFC_WATCH_UNSUPPORTED. Это включает в себя спецификацию watch_port или watch_group для группы, которая не поддерживает живучести, или спецификацию порта, который не поддерживает живучести в watch_port, или спецификации группы, которая не поддерживает живучести в watch_group.

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

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

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

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

Таблица 1. Список счетчиков

СчетчикЧисло бит
На таблицу
Число ссылок (активных записей)32
Полное число пришедших пакетов64
Число прошедших пакетов64
На поток
Число пришедших пакетов64
Число полученных байт64
Продолжительность (сек.)32
Продолжительность (нсек)32
На порт
Число полученных пакетов64
Число переданных пакетов64
Полученных байт64
Переданных байт64
Число отбросов на входе64
Число отбросов на выходе64
Число ошибок на входе64
Число ошибок на выходе64
Число ошибок выравнивания на входе64
Число переполнений на входе64
Число CRC-ошибок64
Число столкновений64
На очередь
Число переданных пакетов64
Число переданных байт64
Число ошибок переполнения при передаче64
На группу
Эталонный счет (поток)32
Число пакетов64
Число байт64
На перечень инструкций
Число пакетов64
Число байт64

Инструкции

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

Набор инструкций, ассоциированных с записью переадресации, содержит максимум одну инструкцию каждого типа. Инструкции этого набора исполняются в порядке, специфицированном в списке. На практике, единственными исключением является то, что команда Clear-Actions выполняется до команды Write-Actions и что инструкция Goto-Table исполняется последней.

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

Набор инструкций, ассоциированный с каждым пакетом, по умолчанию не содержит команд. Запись переадресации может модифицировать набор инструкций, используя команду Write-Action или Clear-Action, ассоциированную с конкретной сверкой.

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

Рис. 5. Схема прохождения пакета через переключатель OpenFlow

Разрыв соединения

В протоколе предусматривается два режима, в которые должен перейти переключатель сразу после потери контакта с контроллерами. Это:


Протокол OF-CONFIG должен обеспечить в такой ситуации средства для конфигурирования режима.

Шифрование

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

Очереди

Очередь имеет три параметра, которые могут конфигурироваться:


OF-CONFIG 1.1 должен обеспечить средства для конфигурирования этих параметров.

Порты

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


OF-CONFIG 1.1 должен обеспечить средства для конфигурирования этих параметров.

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

OF-CONFIG 1.1 должен обеспечивать средства для конфигурирования этих анонсированных характеристик.

В спецификации определены логические порты, которые имеют высокий уровень абстракции. Кроме того, логические порты поддерживают передачу метаданных контроллеру. OFCONFIG 1.1 должен поддерживать конфигурирование этих логических портов. Однако, конфигурирование логических портов в OF-Config 1.1 ограничено небольшим числом туннелей (в частности сюда включены IPinGRE, VxLAN и NVGRE), которые могут использоваться в сценариях информационного центра типа виртуализации сети.

Туннель (логический порт)

Оконечная точка туннеля соответствует логическому порту OpenFlow, который поддерживает специфический метод инкапсуляции. Общим случаем использования туннелей является создание виртуальных сетей путем инкапсуляции, например, трафика уровня 2 (Ethernet) в пакетах уровня 3 (IP). OF-CONFIG делает возможным ассоциацию логических портов OpenFlow с определенным типом туннеля и соответствующими параметрами туннеля.

Элемент <tunnel> существует, если порт является логическим портом, который представляет собой конец туннеля. Он содержит в себе тип туннеля. В настоящее время определены следующие типы туннелей: IPinGRE, VxLAN и NVGRE. Все типы туннелей имеют общий набор элементов: адреса начальной (local) и конечной точки туннеля (<local-XXX-address> и <remote-XXX-address>) для типов адресов IPv4, IPv6 и MAC.

Выявление возможностей

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

Идентификатор обмена данных (Datapath ID)

Канал обмена данными (datapath - маршрут) переключателя должен иметь идентификатор ID. Это 64-битное поле с младшими 48 битами, соответствующими МАС-адресу, а оставшиеся 16 бит оставлены для оператора переключателя. OF-CONFIG должен обеспечить средства для конфигурирования идентификатора канала (ID).

Операционные требования

The OF-CONFIG 1.1 должен отвечать требованиям следующих сценариев:

  1. OF-CONFIG 1.1 должен поддерживать конфигурирование переключателя, совместимого с OpenFlow, со стороны нескольких точек конфигурации.
  2. OF-CONFIG 1.1 должен поддерживать конфигурационную точку, управляющую несколькими переключателями, совместимыми с OpenFlow.
  3. OF-CONFIG 1.1 должен поддерживать логический переключатель OpenFlow, управляемый несколькими контроллерами.
  4. OF-CONFIG 1.1 должен поддерживать конфигурирование портов и очередей переключателя, совместимого с OpenFlow.
  5. OF-CONFIG 1.1 должен поддерживать выявление возможностей логического переключателя OpenFlow.
  6. OF-CONFIG 1.1 должен поддерживать конфигурирование туннелей, таких как IP-in-GRE, NVGRE и VxLan, которые представляют собой логические порты логического переключателя OpenFlow.

Требования, предъявляемые к протоколу управления переключателем

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

  1. Протокол должен обеспечивать безопасность, целостность, конфиденциальность и аутентификацию. Должна поддерживаться аутентификация переключателя и конфигурационной точки.
  2. Протокол должен поддерживать надежный транспорт для конфигурационных запросов и откликов.
  3. Протокол должен поддерживать установление соединение со стороны точки конфигурирования.
  4. Протокол должен поддерживать установление соединением со стороны переключателя.
  5. Протокол должен быть способен выполнять конфигурирование переключателя.
  6. Протокол должен быть способен конфигурировать переключатель.
  7. Протокол должен поддерживать занесение конфигурационных данных из точки конфигурации в переключатель.
  8. Протокол должен поддерживать извлечение конфигурационных данных точкой конфигурации из переключателя.
  9. Протокол должен поддерживать получение точкой конфигурации статусных данных переключателя.
  10. Протокол должен поддерживать создание, модификацию и удаление конфигурационной информации из/в переключателя.
  11. Протокол должен поддерживать уведомление о выполнении запроса конфигурации.
  12. Протокол должен сообщать коды ошибки в случае не выполнения запроса конфигурации.
  13. Протокол должен поддерживать посылку конфигурационных запросов до завершения реализации предыдущих.
  14. Протокол должен поддерживать транзакционные возможности, включая откат операции.
  15. Протокол должен обеспечивать средства для асинхронного уведомления переключателем конфигурационной точки.
  16. Протокол должен быть расширяемым.
  17. Протокол должен поддерживать объявление своих возможностей.

Модель данных

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

  1. UML-диаграммы, описывающей класс (UML - Universal Modeling Language).
  2. Частью схемы XML, извлеченной из нормативной схемы XML,
  3. Пример кодирования XML-текста является частным случаем класса,
  4. Нормативные ограничения для требований класса расширяют XML-схему с помощью семантических спецификаций,
  5. Части модуля YANG, извлеченной из модуля YANG

Одной из целей модели является эффективное четкое кодирование конфигурации переключателя в XML. Простота восприятия человеком является сильной стороной XML. Но так как XML-схема создавалась для формирования и анализа протокольных объектов, простота кодирования и разбора здесь имеют предпочтение перед простотой чтения.

Рис. 6. UML-диаграмма класса для модели данных OF-CONFIG

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

Переключатель содержит набор ресурсов различных типов. Для OF-CONFIG 1.1 в модель включено несколько типов ресурсов: Порты OpenFlow, очереди OpenFlow, внешний сертификат, собственный сертификат и таблица переадресации (Flow Table). Ряд дополнительных типов ресурсов могут быть добавлены в будущем. Ресурсы OpenFlow могут быть сделаны доступными для использования логическими переключателями OpenFlow.

Модель данных содержит несколько идентификаторов, большинство из них кодируются как XML-элементы <id>. В настоящее время эти ID определены как строки, которые являются в определенном контексте уникальными. Помимо требований уникальности никаких других требований к этим строкам не предъявляется. В дальнейшем предполагается использование URN (Universal Resource Names).

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

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


Опционное действие: Output. Переключатель может опционно поддерживать переадресацию на следующие виртуальные порты:

Опционное действие: Set-Queue. Операция set-queue устанавливает идентификатор очереди для пакета. Когда пакет переадресуется в порт, с использованием операции output, идентификатор очереди определяет, какая очередь соответствует порту, через который следует переадресовать пакет. Реализация переадресации диктуется конфигурацией очереди и используется для обеспечения базового уровня QoS (Quality-of-Service).

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

Необходимое действие: Group. Обрабатывает пакет для специфицированной группы. Точная интерпретация зависит от типа группы.

Опционное действие: Push-Tag/Pop-Tag. Переключатели могут поддерживать возможность меток push/pop, как это показано в таблице 2. Чтобы упростить интеграцию с существующими сетями, мы предлагаем обеспечить поддержку push/pop операций для VLAN меток.

Таблица 2. Операции push/pop c метками

ДействиеСопряженные данныеОписание
Push VLAN-заголовокEthertypePush новый VLAN-заголовок в пакет. Ethertype используется в качестве Ethertype для метки. Следует использовать только Ethertype равные 0x8100 и 0x88a8.
Pop VLAN-заголовок-Pop самый верхний VLAN-заголовок из пакета.
Push MPLS-заголовокEthertypePush новый промежуточный MPLS-заголовок в пакет. Ethertype используется как Ethertype для метки. Следует использовать только значения Ethertype 0x8847 и 0x8848.
Pop MPLS-заголовокEthertypePop самую верхнюю MPLS-метку, если промежуточный заголовок из пакета. Ethertype используется как Ethertype для результирующего пакета (Ethertype для поля данных MPLS).

Опционное действие: Set-Field. Различные операции Set-Field модифицируют соответствующее значения поля заголовка пакета. Даже когда это не требуется обязательно, операции, представленные в таблице 3, существенно увеличивают полезность реализаций OpenFlow. Чтобы улучшить интеграцию с существующими сетями, мы предлагаем поддержку операций модификации VLAN. Действие операций Set-Field должны всегда относиться к самому внешнему заголовку (напр. операция "Set VLAN ID" всегда задает значение ID самой внешней метки VLAN).

Таблица 3. Действия поля SET

ДействиеСопряженные данныеОписание
Set VLAN priority3 бита: нового значения приоритета VLANЗамещается существующее значение VLAN-приоритета. Применимо только для пакетов, которые имеют VLAN-метку.
Set MPLS label20 бит: новой метки MPLSЗамещает существующую MPLS-метку. Относится только к пакетам, которые имеют промежуточный MPLS-заголовок.
Set MPLS trafic class3 бита: нового класса трафика MPLSЗамещается существующий класс MPLS-трафика. Применимо только для пакетов с промежуточным MPLS-заголовком.
Set MPLS TTL8 бит: нового значения MPLS TTLЗамещает существующее значение MPLS TTL. Эта операция применима только для пакетов с существующим промежуточным MPLS-заголовком.
Decrement MPLS TTL-Декрементирует значение MPLS TTL. OЭта операция применима только для пакетов с существующим промежуточным MPLS-заголовком.
Set IPv4 source address32 бита: нового IPv4-адреса отправителяЗамещает существующее значение IP-адреса отправителя на новое значение и new value и обновляет контрольную сумму IP (а также контрольную сумму TCP/UDP/SCTP, если это необходимо). Эта операция применима только для IPv4 пакетов.
Set IPv4 destination address32 бита: нового IPv4-адреса получателяЗамещает существующий IP-адрес места назначения на новое значение и обновляет контрольную сумму (и контрольные суммы TCP/UDP/SCTP, если это требуется). Эта операция применима только для IPv4 пакетов.
Set IPv4 ToS bits6 бит: нового значения IPv4 ToSЗамещает существующее значение IP ToS, обновляет контрольную сумму IP. Применимо только для пакетов IPv4.
Set IPv4 ECN bits2 бита: нового значения IPv4 ECNЗамещает существующее значение IP ECN и обновляет контрольную сумму IP. Применимо только для пакетов IPv4.
Set IPv4 TTL8 бит: нового IPv4 TTLЗамещает существующее значение IP TTL и обновляет контрольную сумму IP. Применимо только для пакетов IPv4.
Decrement IPv4 TTL-Декрементирует значение поля IP TTL и обновляет контрольную сумму IP. Применимо только для пакетов IPv4.
Установка значения порта отправителя16 бит: нового TCP, UDP или SCTP порта отправителяЗамещает существующее значение TCP/UDP/SCTP порта отправителя на новое значение и обновляет контрольную сумму TCP/UDP/SCTP. Эта операция применима только для TCP, UDP и SCTP-пакетов.
Установка значения порта назначенияt16 бит: нового TCP, UDP или SCTP порта назначенияЗамещает существующее значение TCP/UDP/SCTP порта назначения на новое значение и обновляет контрольную сумму TCP/UDP/SCTP. Эта операция применима только для TCP, UDP и SCTP-пакетов.
Copy TTL outwards-Копирует значение TTL из заголовка, следующего за самым внешним, во внешний заголовок. Копирование возможно для IP-to-IP, MPLS-to-MPLS или IPto-MPLS.
Copy TTL inwards-Копирует значение TTL из заголовка, следующего за самым внешним, во внешний заголовок. Копирование возможно для IP-to-IP, MPLS-to-MPLS или MPLS-to-IP.

Порядок следования полей заголовка:

EthernetVLANMPLSARP/IPTCP/UDP/SCTP

Вновь заносимые метки должны быть самыми верхними. Когда заносится новая метка VLAN, она должна следовать непосредственно после Ethernet-заголовка. Аналогично, когда заносится новая MPLS-метка, она должна быть самой верхней MPLS-меткой, вставленной как промежуточный заголовок после всех VLAN-меток.

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

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

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

На рис. 7 представлена UML-диаграмма переключателя OpenFlow.

Рис. 7. UML-диаграмма переключателя, совместимого с OpenFlow

Схема XML

<xs:complexType name="OFCapableSwitchType">
<xs:sequence>
<xs:element name="id"
type="OFConfigID"/>
<xs:element name="configuration-points"
type="OFConfigurationPointListType"/>
<xs:element name="resources"
type="OFCapableSwitchResourceListType"/>
<xs:element name="logical-switches"
type="OFLogicalSwitchListType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="OFConfigurationPointListType">
<xs:sequence>
<xs:element name=“configuration-point”
type="OFConfigurationPointType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="OFCapableSwitchResourceListType">
<xs:sequence>
<xs:element name="port"
type="OFPortType" maxOccurs="unbounded"/>
<xs:element name="queue"
type="OFQueueType" maxOccurs="unbounded"/>
<xs:element name="owned-certificate"
type="OFOwnedCertificateType" maxOccurs="unbounded"/>
<xs:element name="external-certificate"
type="OFExternalCertificateType"
maxOccurs="unbounded"/>
<xs:element name="flow-table"
type="OFFlowTableType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="OFLogicalSwitchListType">
<xs:sequence>
<xs:element name="logical-switch"
type="OFLogicalSwitchType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>

Нормативные ограничения

Переключатель, совместимый с OpenFlow, идентифицируется конфигурационной точкой OpenFlow по идентификатору <id>. Идентификатор должен быть уникальным в пределах контекста потенциальных точек конфигурации.

Элемент <capabilities> содержит элементы возможностей, которые может реализовать логический переключатель. Предполагается, что эти возможности конфигурируются в процессе инсталляции переключателя. Эти элементы возможностей могут быть выявлены конфигуратором с помощью запроса NETCONF get-config.

Элемент <max-buffered-packets> определяет максимальное число пакетов, которое логический переключатель может буферизовать при посылке пакетов контроллеру, используя сообщения packet-in.

Элемент <max-tables> указывает максимальное число таблиц переадресации, поддерживаемых логическим переключателем OpenFlow.

Элемент <max-ports> указывает максимальное число портов, поддерживаемых логическим переключателем OpenFlow.

Элемент <flow-statistics> указывает, поддерживает ли логический переключатель статистику потоков.

Элемент <table-statistics> указывает, поддерживает ли логический переключатель статистику для таблиц.

Элемент <port-statistics> указывает, поддерживает ли логический переключатель статистику для портов.

Элемент <group-statistics> указывает, поддерживает ли логический переключатель групповую статистику.

Элемент <queue-statistics> указывает, поддерживает ли переключатель статистику очередей.

Элемент <reassemble-ip-fragments> указывает, поддерживает ли логический переключатель сборку IP-фрагментов.

Элемент <block-looping-ports> указывает, является ли протоколом переключателя OpenFlow, например, 802.1D Spanning Tree, будет ли детектировать петли маршрутов и блокировать порты для предотвращения зацикливания пакетов.

Элемент <reserved-port-types> указывает на общие операции переадресации, такие как посылка пакета контроллеру, отправка на все порты или переадресация, использующая методы non-OpenFlow, такие как в традиционном переключателе.

Элемент <group-types> определяет типы групп, поддерживаемых логическим переключателем OpenFlow.

Элемент <group-capabilities> указывает групповые возможности, поддерживаемых логическим переключателем OpenFlow.

Элемент <action-types> указывает типы действий, поддерживаемых логическим переключателем OpenFlow.

Элемент <instruction-types> указывает типы инструкций, поддерживаемых логическим переключателем OpenFlow.

Элемент <configuration-points> содержит список всех точек конфигурации, известных переключателю.

Элемент <resources> содержит списки всех ресурсов переключателя OpenFlow, которые могут использоваться логическими переключателями. Ресурсы, перечисленные здесь, независят от их действительного присвоения.

Элемент <logical-switches> содержит список всех доступных логических переключателей OpenFlow.

Точка конфигурации OpenFlow

Точка конфигурации является объектом, который управляет переключателем, используя протокол OF-CONFIG. Атрибуты точки конфигурации позволяют переключателям, совместимым с OpenFlow идентифицировать точку конфигурации и специфицировать, протокол, который используется для взаимодействия переключателя и точки конфигурации. Переключатель запоминает список конфигурационных точек, которые им управляют. Конфигуратор (OpenFlow Configuration Point) является для переключателя, совместимого с OpenFlow, тем же, что и контроллер для логического переключателя OpenFlow.

В настоящее время единственной транспортной конфигурацией, которая поддерживает формирование соединения переключателем, является схема, обеспечиваемая протоколом BEEP (Blocks Extensible Exchange Protocol).

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

В последнее время технология OpenFlow чаще называется SDN (Software Defined Network). Широкая адаптивность технологии позволяет ее использовать в том числе и для мониторирования сетей (Рис. 8). См. "Open SDN for Network Visibility. Simplifying large scale network monitoring systems with Big Tap", Big Switch Networks.

Рис. 8. Использование SDN для мониторирования сети

Приложение

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

Структуры, определения и нумерация, представленные ниже, взяты из файла include/openflow/openflow.h, который является частью спецификации стандарта OpenFlow. Все структуры выравниваются по 8-байтовым границам. Все сообщения OpenFlow посылаются в формате big-endian (от старшего к младшему).

Заголовок сообщения OpenFlow

Каждое сообщение OpenFlow начинается с заголовка:

/* Заголовок всех пакетов OpenFlow. */
struct ofp_header {
uint8_t version; /* OFP_VERSION. */
uint8_t type; /* одна из констант OFPT. */
uint16_t length; /* Длина, включая этот ofp_заголовок. */
uint32_t xid; /* Идентификатор транзакции, сопряженной с данным пакетом. Отклики используют те же идентификаторы, что и запросы. */
};
OFP_ASSERT(sizeof(struct ofp_header) == 8);

Версия определяет код версии используемого протокола OpenFlow. Текущее значение версии равно 0x02 . Длина поля указывает полную длину сообщения, так что никаких других средств для разделения кадров не требуется. Коды типа могут иметь следующие значения:

enum ofp_type {
/* Immutable messages. */
OFPT_HELLO, /* симметричное сообщение */
OFPT_ERROR, /* симметричное сообщение */
OFPT_ECHO_REQUEST, /* симметричное сообщение */
OFPT_ECHO_REPLY, /* симметричное сообщение */
OFPT_EXPERIMENTER, /* симметричное сообщение */
/* Сообщение конфигурации переключателя. */
OFPT_FEATURES_REQUEST, /* Сообщение контроллер/переключатель */
OFPT_FEATURES_REPLY, /* Сообщение контроллер/переключатель */
OFPT_GET_CONFIG_REQUEST, /* Сообщение контроллер/переключатель */
OFPT_GET_CONFIG_REPLY, /* Сообщение контроллер/переключатель */
OFPT_SET_CONFIG, /* Сообщение контроллер/переключатель */
/* Асинхронные сообщения. */
OFPT_PACKET_IN, /* асинх. сообщение */
OFPT_FLOW_REMOVED, /* асинх. сообщение */
OFPT_PORT_STATUS, /* асинх. сообщение */
/* Командное сообщение контроллера. */
OFPT_PACKET_OUT, /* Сообщение контроллер/переключатель */
OFPT_FLOW_MOD, /* Сообщение контроллер/переключатель */
OFPT_GROUP_MOD, /* Сообщение контроллер/переключатель */
OFPT_PORT_MOD, /* Сообщение контроллер/переключатель */
OFPT_TABLE_MOD, /* Сообщение контроллер/переключатель */
/* Сообщения статистики. */
OFPT_STATS_REQUEST, /* Сообщение контроллер/переключатель */
OFPT_STATS_REPLY, /* Сообщение контроллер/переключатель */
/* Барьерные сообщения. */
OFPT_BARRIER_REQUEST, /* Сообщение контроллер/переключатель */
OFPT_BARRIER_REPLY, /* Сообщение контроллер/переключатель */
/* Сообщения конфигурирования очередей. */
OFPT_QUEUE_GET_CONFIG_REQUEST, /* Сообщение контроллер/переключатель */
OFPT_QUEUE_GET_CONFIG_REPLY, /* Сообщение контроллер/переключатель */
/* Сообщения изменения роли контроллера. */
OFPT_ROLE_REQUEST = 24, /* Сообщение контроллер/переключатель */
OFPT_ROLE_REPLY = 25, /* Сообщение контроллер/переключатель */
/* Асинхронное сообщение конфигурации. */
OFPT_GET_ASYNC_REQUEST = 26, /* Сообщение контроллер/переключатель */
OFPT_GET_ASYNC_REPLY = 27, /* Сообщение контроллер/переключатель */
OFPT_SET_ASYNC = 28, /* Сообщение контроллер/переключатель */
/* Сообщения конфигурации измерителей и ограничителей скорости. */
OFPT_METER_MOD = 29, /* Сообщение контроллер/переключатель */
};

Структуры портов

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

Физические порты, определенные переключателем виртуальные порты и порт OFPP_LOCAL описываются с помощью следующих структур:

/* Описание порта */
struct ofp_port {
uint32_t port_no;
uint8_t pad[4];
uint8_t hw_addr[OFP_ETH_ALEN];
uint8_t pad2[2]; /* Выравнивается по границе 64 бит. */
char name[OFP_MAX_PORT_NAME_LEN]; /* Завершается нулем */
uint32_t config; /* Бит карта OFPPC_* флагов. */
uint32_t state; /* Бит карта OFPPS_* флагов. */
/* Карта бит OFPPF_*, которая описывает характеристики. Все биты равны нулю для неподдерживаемых или недоступных объектов. */
uint32_t curr; /* Имеющиеся возможности. */
uint32_t advertised; /* Возможности, анонсированные портом. */
uint32_t supported; /* Возможности, поддерживаемые портом. */
uint32_t peer; /* Характеристики, анонсируемые партнером. */
uint32_t curr_speed; /* Текущая скорость передачи порта в кбит/c. */
uint32_t max_speed; /* Максимальная скорость передачи порта в кбит/c */
};
OFP_ASSERT(sizeof(struct ofp_port) == 64);

Поле hw_addr обычно содержит MAC-адрес порта; OFP_MAX_ETH_ALEN равно 6. Поле name является строкой, завершающейся нулем, и содержащей читаемое имя интерфейса. Значение OFP_MAX_PORT_NAME_LEN равно 16.

Поле config описывает администрантивные установки порта, и имеет следующую структуру:

/* Флаги для индикации поведения физического порта. Эти флаги используются в ofp_port для описания текущей конфигурации. Они
* используются в сообщениях ofp_port_mod для конфигурации поведения порта.*/
enum ofp_port_config {
OFPPC_PORT_DOWN = 1 << 0, /* Порт отключен администратором. */
OFPPC_NO_RECV = 1  << 2, /* Отбрасывать все пакеты, полученные портом. */
OFPPC_NO_FWD = 1  <<  5, /* Отбрасывать пакеты, адресованные порту. */
OFPPC_NO_PACKET_IN = 1  <<  6 /* Не посылать сообщения для данного порта. */
};

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

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

Поле состояния описывает внутреннее состояние порта и имеет следующую структуру:

/* Текущее состояние физического порта. Контроллер здесь не осуществляет конфигурации.*/
enum ofp_port_state {
OFPPS_LINK_DOWN = 1  <<  0, /* Нет физического канала. */
OFPPS_BLOCKED = 1  << 1, /* Порт блокирован */
OFPPS_LIVE = 1  <<  2, /* Live for Fast Failover Group. */
};

Биты состояния порта характеризуют состояние физического канала или протоколов переключателя за пределами OpenFlow. Бит OFPPS_LINK_DOWN указывает, что физический канал отсутствует. Бит OFPPS_BLOCKED индицирует, что протокол переключателя не соответствует OpenFlow, например является STP 802.1D, и предотвращает использование этого порта с OFPP_FLOOD.

Все биты состояния порта являются read-only и не могут быть изменены контроллером. Когда флаги порта изменены, переключатель посылает сообщение OFPT_PORT_STATUS, чтобы оповестить контроллер об этих изменениях.

Номера портов должны следовать определенным ограничениям:

/* Нумерация портов. Порты нумеруются, начиная с 1. */
enum ofp_port_no {
/* Максимальное число физических портов переключателя. */
OFPP_MAX = 0xffffff00,
/* Fake output "ports". */
OFPP_IN_PORT = 0xfffffff8, /* Послать пакет через порт. Этот виртуальный порт должен использоваться явно, для того чтобы исключать посылку пакета на порт, откуда он пришел. */
OFPP_TABLE = 0xfffffff9, /* Предъявить пакет первой таблице переадресации. NB: Этот порт назначения может использоваться только в исходящих пакетах. */
OFPP_NORMAL = 0xfffffffa, /* Обрабатывать пакет в соответствии со стандартом L2/L3. */
OFPP_FLOOD = 0xfffffffb, /* Все физические порты VLAN, кроме входного и те, что блокированы или отключены. */
OFPP_ALL = 0xfffffffc, /* Все физические порты кроме входного. */
OFPP_CONTROLLER = 0xfffffffd, /* Послать контроллеру. */
OFPP_LOCAL = 0xfffffffe, /* Локальный openflow "порт". */
OFPP_ANY = 0xffffffff /* Коды подмены (Wildcard) номера порта используются только для запросов модификации
(удаления) статистики. Выбирает все потоки вне зависимости от выходного порта (включая потоки с отсутствующим выходным портом). */
};

Поля curr (текущий), advertised (анонсированный), supported (поддерживаемый) и peer (партнера) указывают на режим канала (скорость и дуплексность), тип канала (медь/волокно) и характеристики канала (автосогласование и пауза). Характеристики порта определяются следующими структурами:

/* Характеристики портов, доступные при передаче. */
enum ofp_port_features {
OFPPF_10MB_HD = 1  <<  0, /* 10 МБ поддержка полудуплекса. */
OFPPF_10MB_FD = 1  <<  1, /* 10 МБ поддержка полного дуплекса. */
OFPPF_100MB_HD = 1  <<  2, /* 100 МБ поддержка полного дуплекса. */
OFPPF_100MB_FD = 1  << 3, /* 100 МБ поддержка полного дуплекса. */
OFPPF_1GB_HD = 1  <<  4, /* 1 ГБ поддержка полного дуплекса. */
OFPPF_1GB_FD = 1  <<  5, /* 1 ГБ поддержка полного дуплекса. */
OFPPF_10GB_FD = 1  <<  6, /* 10 ГБ поддержка полного дуплекса. */
OFPPF_40GB_FD = 1  <<  7, /* 40 ГБ поддержка полного дуплекса. */
OFPPF_100GB_FD = 1  <<  8, /* 100 ГБ поддержка полного дуплекса. */
OFPPF_1TB_FD = 1  <<  9, /* 1 ТБ поддержка полного дуплекса. */
OFPPF_OTHER = 1  <<  10, /* Другая скорость, не из списка. */
OFPPF_COPPER = 1  <<  11, /* Проводная среда. */
OFPPF_FIBER = 1  <<  12, /* Оптоволоконная среда. */
OFPPF_AUTONEG = 1  <<  13, /* Auto-negotiation. */
OFPPF_PAUSE = 1  << 14, /* Пауза. */
OFPPF_PAUSE_ASYM = 1 << 15 /* Асимметричная пауза. */
};

Можно устанавливать сразу несколько флагов. Если не установлен ни один из флагов быстродействия порта, используются значения из max_speed или curr_speed.

Поля curr_speed и max_speed fields указывают текущую и максимальную скорость передачи канала в кбитах в сек. Число должно быть округлено. Например, оптический 10Гб-Ethernet порт должен иметь поле с кодом 10000000 (вместо 10312500), а порт OC-192 должен иметь в этом поле код 10000000 (вместо 9953280).

Поля max_speed указывают на максимально возможное быстродействие канала, в то время как curr_speed указывает текущую скорость. Если порт является LAG (Link Aggregation) с 3 каналами 1Гб/с, с одним отключенным портом, один порт с автосогласованием на 1Гб/с и 1 порт с автосогласованием на 100Мбит/с, тогда max_speed равна 3 Гб/с, а curr_speed равна 1.1 Гб/с.

Структура очередей

Переключатель OpenFlow предлагает ограниченную поддержку QoS (Quality-of-Service) через посредство простого механизма управления очередями. Одна (или более) очередей может быть подключены к порту и использоваться потоками данных. Потоки, направленные на определенную очередь будут обрабатываться в соответствии с конфигурацией очереди (напр. с минимальной скоростью).

Очередь описывается структурой ofp_packet_queue:

/* Полное описание очереди. */
struct ofp_packet_queue {
uint32_t queue_id; /* id для определенной очереди. */
uint16_t len; /* Длина в байтах для данного контроллера очереди. */
uint8_t pad[2]; /* Выравнивание на границе 64-бит. */
struct ofp_queue_prop_header properties[0]; /* Список характеристик. */
};
OFP_ASSERT(sizeof(struct ofp_packet_queue) == 8);

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

enum ofp_queue_properties {
OFPQT_NONE = 0, /* Нет четкого определения для очереди (по-умолчанию). */
OFPQT_MIN_RATE, /* Минимальная гарантированная скорость передачи данных. */
/* Другие типы должны быть добавлены здесь (т.e. максимальная скорость, приоритет, и т.д.). */
};

Каждое описание характеристик очереди начинается с общего заголовка:

/* Общее описание для очереди. */
struct ofp_queue_prop_header {
uint16_t property; /* Один из OFPQT_. */
uint16_t len; /* Длина характеристики, включая заголовок. */
uint8_t pad[4]; /* 64-битовое выравнивание. */
};
OFP_ASSERT(sizeof(struct ofp_queue_prop_header) == 8);

Характеристика очереди minimum-rate использует следующую структуру полей:

/* Описание характеристики очереди Min-Rate. */
struct ofp_queue_prop_min_rate {
struct ofp_queue_prop_header prop_header; /* prop: OFPQT_MIN, len: 16. */
uint16_t rate; /* В 1/10 процента; >1000 -> disabled. */
uint8_t pad[6]; /* 64-битовое выравнивание */
};
OFP_ASSERT(sizeof(struct ofp_queue_prop_min_rate) == 16);

Характеристика очереди maximum-rate использует следующую структуру полей:

/* Описание характеристики очереди Max-Rate. */
struct ofp_queue_prop_max_rate {
struct ofp_queue_prop_header prop_header; /* prop: OFPQT_MAX, len: 16. */
uint16_t rate; /* В 1/10 процента; >1000 -> disabled. */
uint8_t pad[6]; /* 64-битовое выравнивание */
};
OFP_ASSERT(sizeof(struct ofp_queue_prop_max_rate) == 16);

Характеристика очереди experimenter использует следующую структуру полей:

/* Описание характеристики очереди Experimenter. */
struct ofp_queue_prop_experimenter {
struct ofp_queue_prop_header prop_header; /* prop: OFPQT_EXPERIMENTER, len: 16. */
uint32_t experimenter; /* ID экспериментатора, который имеет ту же форму, как в структуре ofp_experimenter_header. */
uint8_t pad[4]; /* 64-битовое выравнивание */
uint8_t data[0]; /* Данные, определенные экспериментатором. */
};
OFP_ASSERT(sizeof(struct ofp_queue_prop_experimenter) == 16);

Структура параметров сверки (в табицах переадресации)

Структура данных сверки OpenFlow содержит заголовок и последовательность из нуля или более полей сверки (match fields).

Заголовок сверки описывается структурой ofp_match:

/* Поля сверки */
struct ofp_match {
uint16_t type; /* Один изf OFPMT_* */
uint16_t length; /* Длина ofp_match (исключая заполнитель) */
/* За которой следует:  - ровно (длина - 4) (возможно 0) байт, содержащих OXM TLVs, затем
* - ровно ((длина + 7)/8*8 - длина) (между 0 и 7) байт, заполненных нулями,
* ofp_match при необходимости дополняется заполнителем, чтобы сделать полный размер кратным 8.
*/
uint8_t oxm_fields[4]; /* OXMs начинаются здесь - Make compiler happy */
};
OFP_ASSERT(sizeof(struct ofp_match) == 8);

Тип поля устанавливается равным OFPMT_OXM, а длина поля равна действительной длине структуры ofp_match, включая все поля сверки.

/* Тип сверки указывает на используемую структуру сверки (набор полей, которые определяют результат сравнения). Тип сверки помещается в поле типа перед началом всех структур сверки.
* Тип "OpenFlow Extensible Match" соответствует формату
* OXM TLV, описанному ниже, и должен поддерживаться всеми переключателями OpenFlow.
*/
enum ofp_match_type {
OFPMT_STANDARD = 0, /* Устарело. */
OFPMT_OXM = 1, /* Расширенная сверка OpenFlow */
};

Единственно допустимым типом сверки в данной спецификации является OFPMT_OXM, тип сверки OpenFlow 1.1 OFPMT_STANDARD считается устаревшим.

Поля сверки описываются с использованием расширенного формата OpenFlow (OXM), который представляет собой компактный формат типа TLV (type-length-value). Каждый OXM TLV имеет длину от 5 до 259 байт. OXM TLVs не выравниваются и не используют заполнителей. Первые 4 байта OXM TLV представляют его заголовок, за которым следует тело.

Заголовок OXM TLV's интерпретируется как 32-битовое слово в сетевом байтовом порядке.

31 16 15 987 0
Класс oxmПоле oxmHMДлина oxm

oxm_class является классом OXM-сверки, который содержит в себе сопряженные классы сверки. oxm_field является значением, зависящим от класса, и идентифицирующим типы сверки внутри класса. Комбинация oxm_class и oxm_field (старшие 23 бита заголовка) определяют oxm_type. oxm_type определяет протокольное поле заголовка, такое как тип Ethernet, но оно может также относиться к метаданным пакета, таким как порт переключателя, на корорый прибыл пакет.

ИмяШиринаПрименение
oxm typeoxm_class16Класс сверки: член класса или зарезервированный класс
oxm_field7Поле сверки в пределах класса
 oxm_hasmask1Установлен, если OXM содержит в поле данных битовую маску
 oxm_length8Длина поля OXM

oxm_length является положительным целым числом, характеризующим длину поля OXM TLV в байтах. Длина OXM TLV, включая заголовок, равна 4 + oxm_length байт.

Для данных значений oxm_class, oxm_field и oxm_hasmask, oxm_length является константой. Она включена только для того чтобы позволить программе анализировать неизвестные типы OXM TLVs. (Аналогично, для заданных oxm_class, oxm_field и oxm_length, oxm_hasmask является константой.)

Классы OXM

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

Определены следующие классы OXM:

/* OXM Class IDs.
* Старший бит отличает зарезервированные классы от членов классов.
* Классы 0x0000 до 0x7FFF являются членами классов, назначенными ONF.
* Классы 0x8000 до 0xFFFE являются зарезервированными классами, выделенными для стандартизации.
*/
enum ofp_oxm_class {
OFPXMC_NXM_0 = 0x0000, /* Обратная совместимость с NXM */
OFPXMC_NXM_1 = 0x0001, /* Обратная совместимость с NXM */
OFPXMC_OPENFLOW_BASIC = 0x8000, /* Базовый класс для OpenFlow */
OFPXMC_EXPERIMENTER = 0xFFFF, /* Экспериментальный класс */
};

Класс OFPXMC_OPENFLOW_BASIC содержит базовый набор полей сверки OpenFlow. Опционный класс OFPXMC_EXPERIMENTER используется для экспериментальных сверок. Другие зарезервированные классы ONF оставлены для будущего использования, такого как модуляризация спецификации. Первые два члена класса ONF OFPXMC_NXM_0 и OFPXMC_NXM_1 зарезервированы для обратной совместимости со спецификацией сверки Nicira Extensible (NXM).

Сверка потока

Совпадение OpenFlow с нулевой длиной (с отсутствующим OXM TLVs) соответствует любому пакету. Поля сверки, которые должны соответствовать эталонам wildcarded в сверку OpenFlow не входят.

OXM TLV накладывает ограничение на пакеты соответствующие сверке OpenFlow:

Когда имеется несколько OXM TLV, все ограничения должны быть удовлетворены: поля пакета должны соответствовать всем частям OXM TLV сверки OpenFlow. Поля для которых OXM TLV отсутствуют воспринимаются как wildcarded, пропущенные OXM TLV оказываются замаскированными.

Маскирование полей сверки потока

Когда oxm_hasmask равно 1, OXM TLV содержит битмаску, ее длина эффективно удваивается, таким образом oxm_length всегда четна. Битмаска следует за значением поля и кодируется точно также. Маски определяются так, что 0 в данном бите указывает "don't care" (безразлично) для аналогичного бита в соответствующем поле, в то время как 1 означает точное соответствие бит.

Маска all-zero-bits oxm_mask эквивалентна полному игнорированию OXM TLV. Маска all-one-bits oxm_mask эквивалентна спецификации 0 для oxm_hasmask и игнорированию oxm_mask.

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

Некоторые типы oxm_types, которые поддерживают маскирование с помощью wildcards, могут поддерживать только определенные образцы oxm_mask. Например, некоторые поля, которые имеют значения IPv4-адреса, могут быть запрещены для CIDR-масок (маски субсети).

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

Поля сверки потока

Спецификация определяет набор по умолчанию полей сверки с oxm_class=OFPXMC_OPENFLOW_BASIC, которые могут иметь следующие значения:

/* Типы полей сверки потока OXM для базового класса OpenFlow. */
enum oxm_ofb_match_fields {
OFPXMT_OFB_IN_PORT = 0, /* Входной порт переключателя. */
OFPXMT_OFB_IN_PHY_PORT = 1, /* Физический входной порт переключателя. */
OFPXMT_OFB_METADATA = 2, /* Метаданные передаваемые от таблицы к таблице. */
OFPXMT_OFB_ETH_DST = 3, /* Ethernet адрес назначения. */
OFPXMT_OFB_ETH_SRC = 4, /* Ethernet адрес отправителя. */
OFPXMT_OFB_ETH_TYPE = 5, /* Тип кадра Ethernet. */
OFPXMT_OFB_VLAN_VID = 6, /* VLAN id. */
OFPXMT_OFB_VLAN_PCP = 7, /* VLAN приоритет. */
OFPXMT_OFB_IP_DSCP = 8, /* IP DSCP (6 бит в поле ToS). */
OFPXMT_OFB_IP_ECN = 9, /* IP ECN (2 бита в поле ToS). */
OFPXMT_OFB_IP_PROTO = 10, /* IP-протокол. */
OFPXMT_OFB_IPV4_SRC = 11, /* IPv4 sадрес отправителя. */
OFPXMT_OFB_IPV4_DST = 12, /* IPv4 адрес назначения. */
OFPXMT_OFB_TCP_SRC = 13, /* TCP порт отправителя. */
OFPXMT_OFB_TCP_DST = 14, /* TCP порт назначения. */
OFPXMT_OFB_UDP_SRC = 15, /* UDP порт отправителя. */
OFPXMT_OFB_UDP_DST = 16, /* UDP порт назначения. */
OFPXMT_OFB_SCTP_SRC = 17, /* SCTP порт отправителя. */
OFPXMT_OFB_SCTP_DST = 18, /* SCTP порт назначения. */
OFPXMT_OFB_ICMPV4_TYPE = 19, /* ICMP тип. */
OFPXMT_OFB_ICMPV4_CODE = 20, /* ICMP код. */
OFPXMT_OFB_ARP_OP = 21, /* ARP opcode. */
OFPXMT_OFB_ARP_SPA = 22, /* ARP адрес отправителя IPv4. */
OFPXMT_OFB_ARP_TPA = 23, /* ARP адрес получателя IPv4. */
OFPXMT_OFB_ARP_SHA = 24, /* ARP аппаратный адрес отправителя. */
OFPXMT_OFB_ARP_THA = 25, /* ARP аппаратный адрес получателя. */
OFPXMT_OFB_IPV6_SRC = 26, /* IPv6 адрес отправителя. */
OFPXMT_OFB_IPV6_DST = 27, /* IPv6 адрес назначения. */
OFPXMT_OFB_IPV6_FLABEL = 28, /* IPv6 метка потока */
OFPXMT_OFB_ICMPV6_TYPE = 29, /* ICMPv6 тип. */
OFPXMT_OFB_ICMPV6_CODE = 30, /* ICMPv6 код. */
OFPXMT_OFB_IPV6_ND_TARGET = 31, /* Адрес назначения для ND. */
OFPXMT_OFB_IPV6_ND_SLL = 32, /* слой канала отправителя для ND. */
OFPXMT_OFB_IPV6_ND_TLL = 33, /* слой канала получателя для ND. */
OFPXMT_OFB_MPLS_LABEL = 34, /* MPLS метка. */
OFPXMT_OFB_MPLS_TC = 35, /* MPLS TC. */
OFPXMT_OFP_MPLS_BOS = 36, /* MPLS BoS бит. */
OFPXMT_OFB_PBB_ISID = 37, /* PBB I-SID. */
OFPXMT_OFB_TUNNEL_ID = 38, /* Метаданные логического порта. */
OFPXMT_OFB_IPV6_EXTHDR = 39, /* Псевдо поле расширения заголовка IPv6 */
};

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

Таблица 4. Обязательные поля сверки

ПолеОписание
OXM_OF_IN_PORTВходной порт. Это может быть физический или определенный переключателем логический порт.
OXM_OF_ETH_DSTEthernet адрес отправителя. Может использоваться произвольная бит-маска
OXM_OF_ETH_SRCEthernet адрес назначения. Может использоваться произвольная бит-маска
OXM_OF_ETH_TYPEТип Ethernet поля данных пакета OpenFlow, после VLAN-меток.
OXM_OF_IP_PROTOIPv4 или IPv6 код протокола
OXM_OF_IPV4_SRCIPv4 адрес отправителя. Может использоваться маска субсети или произвольная бит-маска
OXM_OF_IPV4_DSTIPv4 адрес назначения. Может использоваться маска субсети или произвольная бит-маска
OXM_OF_IPV6_SRCIPv6 адрес отправителя. Может использоваться маска субсети или произвольная бит-маска
OXM_OF_IPV6_DSTIPv6 адрес получателя. Может использоваться маска субсети или произвольная бит-маска
OXM_OF_TCP_SRCПорт отправителя TCP
OXM_OF_TCP_DSTПорт назначения TCP
OXM_OF_UDP_SRCПорт отправителя UDP
OXM_OF_UDP_DSTПорт назначения UDP

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

Таблица 5. Особенности полей сверки

ПолеБитыМаскаПредварительное условиеОписание
OXM_OF_IN_PORT32НетНетВходной порт. Числовая нумерация портов начинается с 1. Это может быть физический или определенный переключателем логический порт.
OXM_OF_IN_PHY_PORT32НетIN PORT присутствуетФизический порт. В сообщениях ofp_packet_in, уникальный физический порт, когда пакет получен через логический порт.
OXM_OF_METADATA64ДаНетТаблица метаданных. Используется для передачи информации между таблицами.
OXM_OF_ETH_DST48ДаНетМАС-адрес места назначения Ethernet.
OXM_OF_ETH_SRC48ДаНетМАС-адрес отправителя Ethernet
OXM_OF_ETH_TYPE16НетНетПоле типа поля данных Ethernet пакета OpenFlow, после меток VLAN.
OXM_OF_VLAN_VID12+1ДаНетЗаголовок VLAN-ID из 802.1Q. Бит CFI индицирует присутствие корректного VLAN-ID.
OXM_OF_VLAN_PCP3НетVLAN VID!=NONEVLAN-PCP из заголока 802.1Q.
OXM_OF_IP_DSCP6НетETH TYPE=0x0800 или ETH TYPE=0x86ddКод дифференциальной услуги (DSCP). Часть поля IPv4 ToS или класса трафика IPv6.
OXM_OF_IP_ECN2НетETH TYPE=0x0800 или ETH TYPE=0x86ddБиты ECN IP-заголовка. Часть поля IPv4 ToS или поля класса трафика IPv6.
OXM_OF_IP_PROTO8НетETH TYPE=0x0800 или ETH TYPE=0x86ddКод протокола IPv4 или IPv6
OXM_OF_IPV4_SRC32ДаETH TYPE=0x0800IPv4 адрес отправителя. Может использовать маску субсети или произвольную битмаску
OXM_OF_IPV4_DST32ДаETH TYPE=0x0800IPv4 адрес места назначения. Может использовать маску субсети или произвольную битмаску
OXM_OF_TCP_SRC16НетIP PROTO=6Порт отправителя TCP
OXM_OF_TCP_DST16НетIP PROTO=6Порт назначения ТСР
OXM_OF_UDP_SRC16НетIP PROTO=17Порт отправителя UDP
OXM_OF_UDP_DST16НетIP PROTO=17Порт назначения UDP
OXM_OF_SCTP_SRC16НетIP PROTO=132Порт отправителя SCTP
OXM_OF_SCTP_DST16НетIP PROTO=132Порт назначения SCTP
OXM_OF_ICMPV4_TYPE8НетIP PROTO=1Тип ICMP
OXM_OF_ICMPV4_CODE8НетIP PROTO=1Код ICMP
OXM_OF_ARP_OP16НетETH TYPE=0x0806Код операции ARP
OXM_OF_ARP_SPA32ДаETH TYPE=0x0806Адрес отправителя IPv4 в поле данных ARP. Может использовать маску субсети или произвольную битмаску
OXM_OF_ARP_TPA32ДаETH TYPE=0x0806Адрес получателя IPv4 в поле данных ARP. Может использовать маску субсети или произвольную битмаску
OXM_OF_ARP_SHA48ДаETH TYPE=0x0806Адрес отправителя Ethernet в поле данных ARP.
OXM_OF_ARP_THA48ДаETH TYPE=0x0806Адрес получателя Ethernet в поле данных ARP.
OXM_OF_IPV6_SRC128ДаETH TYPE=0x86ddАдрес отправителя IPv6. Может использовать маску субсети или произвольную битмаску
OXM_OF_IPV6_DST128ДаETH TYPE=0x86ddАдрес получателя IPv6. Может использовать маску субсети или произвольную битмаску
OXM_OF_IPV6_FLABEL29ДаETH TYPE=0x86ddМетка потока IPv6
OXM_OF_ICMPV6_TYPE8НетIP PROTO=58Тип ICMPv6
OXM_OF_ICMPV6_CODE8НетIP PROTO=58Код ICMPv6
OXM_OF_IPV6_ND_TARGET128НетICMPV6 TYPE=135 или ICMPV6 TYPE=136Адрес получателя в сообщении выявления соседа IPv6.
OXM_OF_IPV6_ND_SLL48НетICMPV6 TYPE=135Адрес отправителя канального уровня в сообщении выявления соседа IPv6.
OXM_OF_IPV6_ND_TLL48НетICMPV6 TYPE=136Адрес получателя канального уровня опции сообщения выявления соседа IPv6.
OXM_OF_MPLS_LABEL20НетETH TYPE=0x8847 или ETH TYPE=0x8848Метка в первом промежуточном MPLS-заголовке.
OXM_OF_MPLS_TC3НетETH TYPE=0x8847 или ETH TYPE=0x8848TC в первом промежуточном заголовке MPLS.
OXM_OF_MPLS_BOS1НетETH TYPE=0x8847 или ETH TYPE=0x8848Бит BoS в первом промежуточном заголовке MPLS.
OXM_OF_PBB_ISID24ДаETH TYPE=0x88E7I-SID в первой метке сервиса PBB.
OXM_OF_TUNNEL_ID64ДаНетМетаданные, ассоциированные с логическим портом.
OXM_OF_IPV6_EXTHDR9ДаETH TYPE=0x86ddПсевдо поле расширения заголовка IPv6.

Входной порт OXM_OF_IN_PORT является корректным стандартным портом, физическим или логическим, зарезервированным портом OFPP_LOCAL или резервным портом OFPP_CONTROLLER. Физический порт OXM_OF_IN_PHY_PORT используется в сообщениях Packet-in, чтобы идентифицировать физический порт, скрывающийся под логическим.

Поле метаданных OXM_OF_METADATA используется для передачи информации между большим числом таблиц. Поле идентификатор туннеля OXM_OF_TUNNEL_ID несет в себе опционные метаданные, сопряженные с логическим портом. Привязка этих метаданных определяется реализацией логического порта, например, если логический порт выполняет инкапсуляцию (такую как GRE), это будет поле демультеплексирования из заголовка инкапсуляции (для GRE 32-битовый ключ). Если логический порт не предоставляет таких данных, или если пакет был получен через физический порт, его значение равно нулю.

Отсутствие поля OFPXMT_OFB_VLAN_VID уведомляет, что запись переадресации должна соответствовать пакетам вне зависимости от того, содержат ли они соответствующую метку. Определены специальные значения для метки VLAN, чтобы обеспечить соответствие для пакетов с любыми метками, независимо от значения метки, и поддерживать сверку пакетов без VLAN-метки. Специальные значения, определенные для OFPXMT_OFB_VLAN_VID представлены ниже:

/* VLAN id имеет 12-бит, так что мы можем использовать 16 бит для индикации специальных условий. */
enum ofp_vlan_id {
OFPVID_PRESENT = 0x1000, /* Бит, который индицирует, что VLAN id установлен */
OFPVID_NONE = 0x0000, /* Никакого VLAN id не установлено. */
};

Поле OFPXMT_OFB_VLAN_PCP должно быть отвергнуто, когда поле OFPXMT_OFB_VLAN_VID соответствует wildcard (отсутствует) или когда значение OFPXMT_OFB_VLAN_VID равно OFPVID_NONE. В таблице 6 рассмотрены комбинации битов wildcard и значения поля для сверки в случае конкретных меток VLAN.

Таблица 6. Комбинации сверки для меток VLAN

Поле OXMoxm valueoxm maskСоответствующие пакеты
Отсутствует--Пакеты с и без VLAN-метки
ПрисутствуетOFPVID_NONEОтсутствуетТолько пакеты без VLAN-метки
ПрисутствуетOFPVID_PRESENTOFPVID_PRESENTТолько пакеты с VLAN-меткой, вне зависимости от ее значения
Присутствуетvalue | OFPVID_PRESENTОтсутствуетТолько пакеты с VLAN-меткой и VID равным value

Поле OXM_OF_IPV6_EXTHDR является псевдополем, которое указывает на присутствие в заголовке пакета различных заголовков расширения IPv6. Биты заголовка расширения заголовка IPv6 объединяются вместе в полях OXM_OF_IPV6_EXTHDR, и эти биты могут иметь следующие значения:

/* Определения битов псевдополя заголовка расширения IPv6. */
enum ofp_ipv6exthdr_flags {
OFPIEH_NONEXT = 1 << 0, /* Не встретилось никакого следующего заголовка. */
OFPIEH_ESP = 1 << 1, /* Присутствует поле данных  шифрованного заголовка. */
OFPIEH_AUTH = 1 << 2, /* Присутствует заголовок аутентификации. */
OFPIEH_DEST = 1 << 3, /* Присутствует 1 или 2 заголовков места назначения. */
OFPIEH_FRAG = 1 << 4, /* Присутствует заголовок фрагмента. */
OFPIEH_ROUTER = 1 << 5, /* Присутствует заголовок маршрутизатора. */
OFPIEH_HOP = 1 << 6, /* Присутствует заголовок Hop-by-hop. */
OFPIEH_UNREP = 1 << 7, /* Встретились неожиданные повторения. */
OFPIEH_UNSEQ = 1 << 8, /* Встретилось неожиданная последовательность. */
};

Структуры инструкций

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

enum ofp_instruction_type {
OFPIT_GOTO_TABLE = 1, /* Установить следующую таблицу в конвейер просмотра */
OFPIT_WRITE_METADATA = 2, /* Установить поле метаданных для использования позднее в конвейере */
OFPIT_WRITE_ACTIONS = 3, /* Записать операцию в набор инструкций */
OFPIT_APPLY_ACTIONS = 4, /* Применить операцию немедленно */
OFPIT_CLEAR_ACTIONS = 5, /* Очистить список операций */
OFPIT_METER = 6, /* Применить измеритель (ограничитель скорости) */
OFPIT_EXPERIMENTER = 0xFFFF /* Инструкция экспериментатора */
};

Таблицы переадресации могут поддерживать субнабор типов инструкций.

Инструкция OFPIT_GOTO_TABLE использует следующую структуру и поля:

/* Структура инструкции для OFPIT_GOTO_TABLE */
struct ofp_instruction_goto_table {
uint16_t type; /* OFPIT_GOTO_TABLE */
uint16_t len; /* Длина этой структуры в байтах. */
uint8_t table_id; /* Установить следующую таблицу в конвейер сверки */
uint8_t pad[3]; /* дополнить до 64 бит. */
};
OFP_ASSERT(sizeof(struct ofp_instruction_goto_table) == 8);

table_id указывает на следующую таблицу конвейера обработки пакета.

Инструкция OFPIT_WRITE_METADATA использует следующую структуру и поля:

/* Структура инструкций для IOFPIT_WRITE_METADATA */
struct ofp_instruction_write_metadata {
uint16_t type; /* OFPIT_WRITE_METADATA */
uint16_t len; /* Длина этой структуры в байтах. */
uint8_t table_id; /* Установить следующую табл. */
uint8_t pad[4]; /* Выровнять по границе 64-бит */
uint64_t metadata; /* Значение метаданных для записи */
uint64_t metadata_mask; /* Битовая маска для записи метаданных */
};
OFP_ASSERT(sizeof(struct ofp_instruction_write_metadata) == 24);

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

Инструкции OFPIT_WRITE_ACTIONS, OFPIT_APPLY_ACTIONS и OFPIT_CLEAR_ACTIONS используют следующие структуры и поля:

/* Структура инструкции для OFPIT_WRITE/APPLY/CLEAR_ACTIONS */
struct ofp_instruction_actions {
uint16_t type; /* Одна из OFPIT_*_ACTIONS */
uint16_t len; /* Длина этой структуры в байтах. */
uint8_t pad[4]; /* Выровнять по границе 64-бит */
struct ofp_action_header actions[0]; /* Операции, ассоциированные с OFPIT_WRITE_ACTIONS и OFPIT_APPLY_ACTIONS */
};
OFP_ASSERT(sizeof(struct ofp_instruction_actions) == 8);

Для инструкции Apply-Actions поле операций воспринимается как список и операции, последовательно обрабатывающие пакет. Для инструкции Write-Actions поле операций воспринимается, как перечень, который добавляется к текущему набору операций.

Для инструкции Clear-Actions, структура не содержит никаких операций.

Инструкция OFPIT_METER использует следующие структуру и поля:

/* Структура инструкций для OFPIT_METER */
struct ofp_instruction_meter {
uint16_t type; /* OFPIT_METER */
uint16_t len; /* Длина равна 8. */
uint32_t meter_id; /* Meter instance. */
};
OFP_ASSERT(sizeof(struct ofp_instruction_meter) == 8);

Структура действий

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

enum ofp_action_type {
OFPAT_OUTPUT = 0, /* Вывод на порт переключателя. */
OFPAT_COPY_TTL_OUT = 11, /* Копировать TTL "outwards" -- from next-to-outermost
to outermost */
OFPAT_COPY_TTL_IN = 12, /* Копировать TTL "inwards" -- from outermost to
next-to-outermost */
OFPAT_SET_MPLS_TTL = 15, /* MPLS TTL */
OFPAT_DEC_MPLS_TTL = 16, /* Декрементировать MPLS TTL */
OFPAT_PUSH_VLAN = 17, /* Занести в стек новую метку VLAN */
OFPAT_POP_VLAN = 18, /* Извлечь из стека внешнюю метку VLAN */
OFPAT_PUSH_MPLS = 19, /* Занести в стек новую метку MPLS */
OFPAT_POP_MPLS = 20, /* Извлечь внешнюю метку стека MPLS */
OFPAT_SET_QUEUE = 21, /* Установить идентификатор очереди, при выводе через порт */
OFPAT_GROUP = 22, /* Применить группу. */
OFPAT_SET_NW_TTL = 23, /* IP TTL. */
OFPAT_DEC_NW_TTL = 24, /* Декремент IP TTL. */
OFPAT_SET_FIELD = 25, /* Установить поле заголовка, используя формат OXM TLV. */
OFPAT_PUSH_PBB = 26, /* Занести в стек новую сервисную метку PBB (I-TAG) */
OFPAT_POP_PBB = 27, /* Извлечь из стека внешнюю сервисную метку PBB  (I-TAG) */
OFPAT_EXPERIMENTER = 0xffff
};

Описание инструкции содержит тип операции, длину и некоторые ассоциированные данные:

/* Заголовок действий, который является общим для всех операций. Длина включает заголовок и любые заполнители, для 64-битового выравнивания.
* NB: Длина операции должна быть всегда кратна 8. */
struct ofp_action_header {
uint16_t type; /* Один из OFPAT_*. */
uint16_t len; /* Длина операции, включая этот заголовок. Это длина операции любые заполнители, примененные для выравнивания на границе 64-бита. */
uint8_t pad[4];
};
OFP_ASSERT(sizeof(struct ofp_action_header) == 8);

Операция вывод использует следующую структуры и поля:

/* Структура инструкции для OFPAT_OUTPUT, которая посылает пакеты из порта.
* Когда портом является OFPP_CONTROLLER, 'max_len' указывает максимальное число байт, которое посылается. 'max_len' равное нулю означает, что не следует посылать ни одного байта.
* 'max_len' OFPCML_NO_BUFFER означает, что пакет не буферизован и весь пакет следует послать контроллеру. */
struct ofp_action_output {
uint16_t type; /* OFPAT_OUTPUT. */
uint16_t len; /* Длина равна 16. */
uint32_t port; /* Выходной порт. */
uint16_t max_len; /* Максимальная длина при посылке контроллеру. */
uint8_t pad[6]; /* Заполнение до границы 64 бит. */
};
OFP_ASSERT(sizeof(struct ofp_action_output) == 16);

Порт специфицирует номер порта, через который должен быть послан пакет. max_len индицирует максимальный объем данных из пакета, который должен быть послан, когда код порта равен OFPP_CONTROLLER. Если max_len равно нулю, переключатель должен послать нуль байт. max_len OFPCML_NO_BUFFER означает, что следует послать весь пакет и его не следует буферизовать.

enum ofp_controller_max_len {
OFPCML_MAX = 0xffe5, /* Максимальное значение max_len, которое может быть использовано при запросе специфической длины. */
OFPCML_NO_BUFFER = 0xffff /* индицирует, что не следует использовать буферизацию и весь пакет должен быть послан контроллеру. */
};

Сообщения контроллер-переключатель

При установлении сессии контроллер посылает сообщение OFPT_FEATURES_REQUEST. Это сообщение не содержит тела после заголовка OpenFlow. Переключатель откликается сообщением OFPT_FEATURES_REPLY:

/* Характеристики переключателя. */
struct ofp_switch_features {
struct ofp_header header;
uint64_t datapath_id; /* Уникальный ID маршрута. Младшие 48-бит предназначены для MAC-адреса, в то время как назначение старших 16-бит определяет разработчик. */
uint32_t n_buffers; /* Максимальное число пакетов, буферизуемых одновременно. */
uint8_t n_tables; /* Число таблиц, поддерживаемых маршрутом (datapath). */
uint8_t auxiliary_id; /* Идентифицирует дополнительные соединения */
uint8_t pad[2]; /* выравнивание на 64-бита. */
/* Features. */
uint32_t capabilities; /* Карта бит соответствия поддержки "ofp_capabilities". */
uint32_t reserved;
};
OFP_ASSERT(sizeof(struct ofp_switch_features) == 32);

Поле datapath_id однозначно идентифицирует маршрут. Младшие 48-бит предназначены для MAC-адреса переключателя, в то время как назначение старших 16-бит определяет разработчик. Примером использования старших 16 бит может быть VLAN ID, чтобы различать разные виртуальные переключатели, реализованные в физическом переключателе. Это поле следует рассматриваться контроллером как непрозрачная строка бит.

Поле n_buffers специфицирует максимальное число пакетов, которые переключатель может буферизовать, при отправке контроллеру, используя сообщения packet-in.

Поле n_tables характеризует число таблиц, поддерживаемых переключателем, каждая из которых может иметь разный набор полей сверки, операций и число записей. Когда контроллер и переключатель взаимодействуют впервые, контроллер из сообщения Features Reply определяет, сколько таблиц поддерживает переключатель. Если он хочет узнать размер, типы и порядок в котором используются таблицы, контроллер посылает многосекционный запрос OFPMP_TABLE_FEATURES. Переключатель должен прислать данные о порядке использования таблиц при прохождении пакета.

Поле auxiliary_id идентифицирует тип соединения переключателя и контроллера, главное соединение имеет в этом поле код=0, дополнительное соединение должно иметь в этом поле значение не равное нулю.

Поле возможностей использует следующие флаги:

enum ofp_capabilities {
OFPC_FLOW_STATS = 1 << 0, /* Статистика потока. */
OFPC_TABLE_STATS = 1 << 1, /* Статистика таблицы. */
OFPC_PORT_STATS = 1 << 2, /* Статистика порта. */
OFPC_GROUP_STATS = 1 << 3, /* Групповая статистика. */
OFPC_IP_REASM = 1 << 5, /* Можно реассемблировать IP-фрагменты. */
OFPC_QUEUE_STATS = 1 << 6, /* Статистика очереди. */
OFPC_PORT_BLOCKED = 1 << 8 /* Переключатель блокирует порты, реализующие зацикливание. */
};

Бит OFPC_PORT_BLOCKED указывает, что протокол переключателя не соответствует стеку OpenFlow, например, 802.1D Spanning Tree, детектирует топологические петли и блокирует определенные порты, чтобы предотвратить зацикливание пакетов. Если этот бит не установлен, в большинстве случаев контроллер должен сам реализовать механизм для предотвращения зацикливания пакетов.

Конфигурирование переключателя

Контроллер способен установить конфигурацию и параметры очереди в переключателе с помощью сообщений OFPT_SET_CONFIG и OFPT_GET_CONFIG_REQUEST, соответственно. Переключатель реагирует на запрос конфигурации сообщением OFPT_GET_CONFIG_REPLY; на запрос конфигурации отклика не посылается.

Запрос OFPT_GET_CONFIG_REQUEST не содержит тела после заголовка OpenFlow. OFPT_SET_CONFIG и OFPT_GET_CONFIG_REPLY используют следующее:

/* Конфигурация переключателя. */
struct ofp_switch_config {
struct ofp_header header;
uint16_t flags; /* OFPC_* флаги. */
uint16_t miss_send_len; /* Максимальное число байт пакета, которые должны быть посланы контроллеру. Корректные значения смотри в ofp_controller_max_len.
*/
};
OFP_ASSERT(sizeof(struct ofp_switch_config) == 12);

Флаги конфигурации включают следующее:

enum ofp_config_flags {
/* Обработка IP-фрагментов. */
OFPC_FRAG_NORMAL = 0, /* Никакой специальной обработки фрагментов. */
OFPC_FRAG_DROP = 1 << 0, /* Отбросить фрагменты. */
OFPC_FRAG_REASM = 1 << 1, /* Дезассемблировать (только если установлен OFPC_IP_REASM). */
OFPC_FRAG_MASK = 3,
};

Флаги OFPC_FRAG_* указывают, следует ли обрабатывать IP-фрагменты обычным образом, отбросить или реассемблировать. "Стандартная" обработка фрагментов означает, что следует предпринять попытку передать фрагменты через таблицы OpenFlow. Если любое из полей отсутствует (напр., порты TCP/UDP не подходят), тогда пакет не будет подходить ни одной из записей таблиц, которые содержат такой флаг.

Полe miss_send_len обозначает число байт в каждом пакете, посланном контроллеру конвейером OpenFlow, когда не используется выводная операция локального порта OFPP_CONTROLLER, например, при посылке пакетов с неверным TTL. Если это поле содержит 0, переключатель должен послать пакет с нулем байт в сообщении ofp_packet_in. Если значение установлено равным OFPCML_NO_BUFFER, весь пакет должен быть включен в сообщение, и не должен буферизоваться.

Конфигурация таблицы переадресации

Таблицы переадресации (Flow tables) пронумерованы, начиная с нуля и могут иметь любой номер вплоть до OFPTT_MAX. OFPTT_ALL является зарезервированным значением.

/* Нумерация таблиц. Таблица может использовать любой номер вплоть до OFPT_MAX. */
enum ofp_table {
/* Последний используемый номер таблицы. */
OFPTT_MAX = 0xfe,
/* Ложные таблицы. */
OFPTT_ALL = 0xff /* Wildcard таблицы используются для конфигурации таблиц, статистики потоков и ликвидации потоков. */
};

Контроллер может конфигурировать и задавать параметры таблиц в переключателе с помощью запросов OFP_TABLE_MOD и OFPMP_TABLE_STATS. Переключатель откликается на многосекционный табличный запрос посредством сообщения OFPT_MULTIPART_REPLY. OFP_TABLE_MOD использует следующие структуры и поля:

/* Поведение таблиц переадресации при конфигурировании/модификации */
struct ofp_table_mod {
struct ofp_header header;
uint8_t table_id; /* Идентификатор таблицы, OFPTT_ALL указывает на все таблицы */
uint8_t pad[3]; /* Заполнитель размером до 32 бит */
uint32_t config; /* бит карта флагов OFPTC_* */
};
OFP_ASSERT(sizeof(struct ofp_table_mod) == 16);

table_id выбирает таблицу, к которой относится конфигурационное изменение. Если table_id является OFPTT_ALL, конфигурирование применяется ко всем таблицам переключателя.

Сообщения изменения состояния

Модификации таблицы переадресации со стороны контроллера осуществляется с помощью сообщений OFPT_FLOW_MOD:

/* Установление и прерывание потоков (controller -> datapath). */
struct ofp_flow_mod {
struct ofp_header header;
uint64_t cookie; /* Идентификатор, выработанный контроллером. */
uint64_t cookie_mask; /* Маска используется, чтобы ограничить биты cookie, которые должны согласовываться,
когда командой является OFPFC_MODIFY* или OFPFC_DELETE*. Значение 0 указывает на отсутствие ограничений. */
/* Операции с потоком. */
uint8_t table_id; /* ID таблицы, куда посылается поток. Для команд OFPFC_DELETE_*, можно использовать OFPTT_ALL, чтобы убрать определенные потоки из всех таблиц. */
uint8_t command; /* Один из OFPFC_*. */
uint16_t idle_timeout; /* Время ожидания до удаления (секунд). */
uint16_t hard_timeout; /* Максимальное время до удаления (секунд). */
uint16_t priority; /* Уровень приоритета записи переадресации. */
uint32_t buffer_id; /* Буферизованный пакет, к которому это относится, или OFP_NO_BUFFER. Не имеет смысла для OFPFC_DELETE*. */
uint32_t out_port; /* Для команд OFPFC_DELETE* требует соответствия записей и включения этого значения в качестве номера выходного порта. Значение OFPP_ANY указывает на отсутствие ограничений. */
uint32_t out_group; /* Для команд OFPFC_DELETE*, требует соответствия записям, чтобы включить в выходную группу. Значение OFPG_ANY указывает на отсутствие ограничений. */
uint16_t flags; /* Один из OFPFF_*. */
uint8_t pad[2];
struct ofp_match match; /* Поля для сверки. Длина переменная. */
//struct ofp_instruction instructions[0]; /* Набор инструкций set */
};
OFP_ASSERT(sizeof(struct ofp_flow_mod) == 56);

Поле cookie представляет непрозрачные данные, выбранные контроллером. Это значение проявляется в сообщениях удаления сообщений и статистики потоков, и может также использоваться для фильтрации статистики потоков, модификации и удаления потоков. Значение -1 (0xFFFFFFFFFFFFFFFF) зарезервировано и не должно использоваться. Когда запись переадресации вносится в таблицу с помощью сообщений OFPFC_ADD, его поле cookie равно представленной величине. Когда запись переадресации модифицирована сообщениями (OFPFC_MODIFY или OFPFC_MODIFY_STRICT), его поле cookie не изменяется.

Поле table_id специфицирует таблицу, в которую должна быть внесена, модифицирована или удалена запись переадресации. Таблица 0 обозначает первую таблицу конвейера. Использование OFPTT_ALL приемлемо только для запросов удаления.

Поле command может содержать одно из:

enum ofp_flow_mod_command {
OFPFC_ADD = 0, /* Новый поток. */
OFPFC_MODIFY = 1, /* Модифицировать все потоки, отвечающие критериям отбора. */
OFPFC_MODIFY_STRICT = 2, /* Модифицировать запись, соответствующую wildcards и значению приоритета. */
OFPFC_DELETE = 3, /* Удалить все потоки, отвечающие критериям отбора. */
OFPFC_DELETE_STRICT = 4, /* Удалить запись, точно соответствующую  wildcards и значению приоритета. */
};

Поля idle_timeout и hard_timeout управляют тем, как быстро истечет время пригодности записи. Когда запись переадресации внесена в таблицу, ее значения поля idle_timeout и hard_timeout берутся из сообщения. Когда запись переадресации модифицирована (сообщения OFPFC_MODIFY или OFPFC_MODIFY_STRICT), поля idle_timeout и hard_timeout игнорируются.

Сообщение модификации порта

Контроллер для модификации поведения порта использует сообщение OFPT_PORT_MOD:

/* Модификационное поведение физического порта */
struct ofp_port_mod {
struct ofp_header header;
uint32_t port_no;
uint8_t pad[4];
uint8_t hw_addr[OFP_ETH_ALEN]; /* Аппаратный адрес не конфигурируем. Это используется при проверке корректности запросов, так что он должен быть тем же, что возвращен в структуре ofp_port. */
uint8_t pad2[2]; /* Заполнитель до границы в 64 бит. */
uint32_t config; /* Карта бит OFPPC_* флагов. */
uint32_t mask; /* Карта бит OFPPC_* флагов, которую нужно изменить. */
uint32_t advertise; /* Карта бит OFPPF_*. Все биты обнуляются, если нужно предотвратить любые операции. */
uint8_t pad3[4]; /* Заполнитель до 64 бит. */
};
OFP_ASSERT(sizeof(struct ofp_port_mod) == 40);

Поле маски используется, чтобы выбрать биты в поле config, которые нужно изменить. Поле анонсирования (advertise) не имеет маски; Все характеристики порта меняются вместе.

Описание порта

Запрос описания порта OFPMP_PORT_DESCRIPTION позволяет контроллеру получить описание всех портов в системе, которые поддерживают OpenFlow. Тело запроса пусто. Тело отклика состоит из следующего массива:

/* Описание порта */
struct ofp_port {
uint32_t port_no;
uint8_t pad[4];
uint8_t hw_addr[OFP_ETH_ALEN];
uint8_t pad2[2]; /* Выровнять по границе 64 бита. */
char name[OFP_MAX_PORT_NAME_LEN]; /* Завершается нулем */
uint32_t config; /* Бит карта OFPPC_* флагов. */
uint32_t state; /* Бит карта OFPPS_* флагов. */
/* Бит карта OFPPF_*, которая описывает характеристики. Все биты обнуляются, если это не поддерживается или недоступно. */
uint32_t curr; /* Текущие характеристики. */
uint32_t advertised; /* Характеристики анонсированные портом. */
uint32_t supported; /* Характеристики поддерживаемые портом. */
uint32_t peer; /* Характеристики анонсированные партнером. */
uint32_t curr_speed; /* Текущая скорость работы порта в кбит/с. */
uint32_t max_speed; /* Максимальная скорость работы порта в кбит/c */
};
OFP_ASSERT(sizeof(struct ofp_port) == 64);

Сообщения конфигурирования очереди

Конфигурирование очередей осуществляется помимо протокола OpenFlow, или из командной строки или с привлечением какого-то внешнего протокола.

Контроллер может запрашивать переключатель на предмет конфигурирования очередей для порта, используя следующую структуру:

/* Запрос конфигурирования очереди для порта. */
struct ofp_queue_get_config_request {
struct ofp_header header;
uint32_t port; /* Порт, подлежащий конфигурированию. Привязывается к определенному физическому порту (т.e. < OFPP_MAX),
или OFPP_ANY, чтобы запросить обо всех сконфигурированных очередях. */
uint8_t pad[4];
};
OFP_ASSERT(sizeof(struct ofp_queue_get_config_request) == 16);

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

/* Конфигурация очереди для заданного порта. */
struct ofp_queue_get_config_reply {
struct ofp_header header;
uint32_t port;
uint8_t pad[4];
struct ofp_packet_queue queues[0]; /* Список сконфигурированных очередей. */
};
OFP_ASSERT(sizeof(struct ofp_queue_get_config_reply) == 16);

Сообщение вывода

Когда контроллер хочет послать пакет по маршруту, он использует сообщение OFPT_PACKET_OUT:

/* Послать пакет (controller -> datapath). */
struct ofp_packet_out {
struct ofp_header header;
uint32_t buffer_id; /* Идентификатор, присвоенный маршруту (OFP_NO_BUFFER если его нет). */
uint32_t in_port; /* Входной порт пакета или OFPP_CONTROLLER. */
uint16_t actions_len; /* Размер массива инструкций в байтах. */
uint8_t pad[6];
struct ofp_action_header actions[0]; /* Список операций. */
/* uint8_t data[0]; */ /* Данные пакета. Длина получена из поля длины в заголовке.
(Имеет смысл, только если buffer_id == -1.) */
};
OFP_ASSERT(sizeof(struct ofp_packet_out) == 24);

buffer_id тот же, что и в сообщении ofp_packet_in. Если buffer_id равен OFP_NO_BUFFER, тогда данные пакета включены в массив данных.

Асинхронные сообщения

Сообщение packet-In

Когда пакет получен маршрутом (datapath) и послан контроллеру, используется сообщение OFPT_PACKET_IN:

/* Пакет получен на порт (datapath -> controller). */
struct ofp_packet_in {
struct ofp_header header;
uint32_t buffer_id; /* ID присваивается маршрутом. */
uint16_t total_len; /* Кадр полной длины. */
uint8_t reason; /* Пакет причины послан (один из OFPR_*) */
uint8_t table_id; /* ID таблицы, которая просматривалась */
uint64_t cookie; /* Cookie записи таблицы переадресации, которая использовалась. */
struct ofp_match match; /* Метаданные пакета. Размер переменный. */
/* Далее следуют:
* - Ровно 2 байта заполнителя, содержащие нули, затем
* - Кадр Ethernet, чья длина получена из header.length.
* Байты заполнителя, предшествующие Ethernet-кадру, гарантируют то, что IP-заголовок
* (если имеется), следующий далее выровнен на границе 32-бита.
*/
//uint8_t pad[2]; /* Выравнивается на границу 64 бит + 16 бит */
//uint8_t data[0]; /* Кадр Ethernet */
};
OFP_ASSERT(sizeof(struct ofp_packet_in) == 32);

buffer_id представляет собой значение, используемое маршрутом (datapath), чтобы идентифицировать буферизованный пакет. Когда пакет буферизуется, некоторое число байт из сообщения будет включено в информационную часть сообщения. Если пакет послан в результате операции "send to controller" (послать контроллеру), тогда посылаются max_len байт из ofp_action_output из запроса установления потока. Если пакет послан по другим причинам, таким как некорректное значение TTL, тогда посылаются, по крайней мере, miss_send_len байт из сообщения OFPT_SET_CONFIG. По умолчанию miss_send_len равно 128 байтам. Если пакет не буферизован - либо по причине отсутствия места в буфере, либо из-за явного запроса OFPCML_NO_BUFFER - весь пакет включается в информационную часть, а buffer_id соответствует OFP_NO_BUFFER.

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

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

Поле причины может принимать одно из следующих значений:

/* Почему пакет посылается контроллеру? */
enum ofp_packet_in_reason {
OFPR_NO_MATCH = 0, /* Никакого совпадения с потоком (table-miss flow entry). */
OFPR_ACTION = 1, /* Непосредственный вывод в контроллер. */
OFPR_INVALID_TTL = 2, /* У пакета неверное значение TTL */
};

OFPR_INVALID_TTL указывает, что пакеты с неверным значением IP TTL или MPLS TTL было отвергнуто конвейером и передано контроллеру. Проверка корректности TTL не требуется для каждого пакета, но это может быть сделано каждый раз, когда для пакета выполняется операция OFPAT_DEC_MPLS_TTL или OFPAT_DEC_NW_TTL.

Сообщение ошибки

Бывают моменты, когда переключатель вынужден оповестить контроллер о проблеме. Это делается с помощью сообщения OFPT_ERROR_MSG:

/* OFPT_ERROR: Сообщение об ошибке (datapath -> controller). */
struct ofp_error_msg {
struct ofp_header header;
uint16_t type;
uint16_t code;
uint8_t data[0]; /* Данные переменной длины. Интерпретируются на основе типа и кода. Никаких заполнителей. */
};
OFP_ASSERT(sizeof(struct ofp_error_msg) == 12);

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

Если сообщение ошибки является результатом определенного сообщения контроллера, напр., OFPET_BAD_REQUEST, OFPET_BAD_ACTION, OFPET_BAD_INSTRUCTION, OFPET_BAD_MATCH или OFPET_FLOW_MOD_FAILED, тогда поле xid заголовка должно соответствовать сообщению, вызвавшему ошибку.

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

В настоящее время определены следующие типы ошибок:

/* Значения для 'type' в сообщении ofp_error_message. Эти значения остаются неизменными: они
* не будут изменены в будущих версиях протокола (хотя новые значения могут быть добавлены). */
enum ofp_error_type {
OFPET_HELLO_FAILED = 0, /* Протокол Hello потерпел неудачу. */
OFPET_BAD_REQUEST = 1, /* Запрос был не понят. */
OFPET_BAD_ACTION = 2, /* Ошибка в описании операции. */
OFPET_BAD_INSTRUCTION = 3, /* Ошибка в списке инструкций. */
OFPET_BAD_MATCH = 4, /* Ошибка сверки . */
OFPET_FLOW_MOD_FAILED = 5, /* Проблема при модификации записи таблицы переадресации. */
OFPET_GROUP_MOD_FAILED = 6, /* Проблема при модификации групповой таблицы. */
OFPET_PORT_MOD_FAILED = 7, /* Запрос модификации порта не прошел. */
OFPET_TABLE_MOD_FAILED = 8, /* Запрос модификации записи таблицы не прошел. */
OFPET_QUEUE_OP_FAILED = 9, /* Операция с очередью не прошла. */
OFPET_SWITCH_CONFIG_FAILED = 10, /* Запрос конфигурации переключателя не прошел. */
OFPET_ROLE_REQUEST_FAILED = 11, /* Запрос роли контроллера не прошел. */
OFPET_METER_MOD_FAILED = 12, /* Ошибка измерителя. */
OFPET_TABLE_FEATURES_FAILED = 13, /* Установка характеристик таблицы на прошла. */
OFPET_EXPERIMENTER = 0xffff /* Ошибка сообщения экспериментатора. */
};

Для типа ошибки OFPET_HELLO_FAILED, в настоящее время определены следующие коды:

/* Значения ofp_error_msg 'code' для OFPET_HELLO_FAILED. 'data' содержат ASCII-текстовую строку, которая может предоставить подробности проблемы. */
enum ofp_hello_failed_code {
OFPHFC_INCOMPATIBLE = 0, /* Нет совместимой версии. */
OFPHFC_EPERM = 1, /* Ошибка разрешений. */
};

Поле данных содержит ASCII-текстовую строку, которая добавляет подробности о причинах произошедшей ошибки.

Для типа ошибки OFPET_BAD_REQUEST определены следующие коды:

/* Значения ofp_error_msg 'code' для OFPET_BAD_REQUEST. 'data' содержат по крайней мере первые 64 байта неудачного запроса. */
enum ofp_bad_request_code {
OFPBRC_BAD_VERSION = 0, /* ofp_header.version не поддерживается. */
OFPBRC_BAD_TYPE = 1, /* ofp_header.type не поддерживается. */
OFPBRC_BAD_MULTIPART = 2, /* ofp_multipart_request.type не поддерживается. */
OFPBRC_BAD_EXPERIMENTER = 3, /* Идентификатор экспериментатора не поддерживается
* (in ofp_experimenter_header или
* ofp_multipart_request или
* ofp_multipart_reply). */
OFPBRC_BAD_EXP_TYPE = 4, /* Тип экспериментатора не поддерживается. */
OFPBRC_EPERM = 5, /* Ошибка разрешений. */
OFPBRC_BAD_LEN = 6, /* Неверная длина запроса для данного типа. */
OFPBRC_BUFFER_EMPTY = 7, /* Специфицированный буфер уже используется. */
OFPBRC_BUFFER_UNKNOWN = 8, /* Специфицированный буфер не существует. */
OFPBRC_BAD_TABLE_ID = 9, /* Специфицированный table-id неверен или не существует. */
OFPBRC_IS_SLAVE = 10, /* Отвергается, так как контроллер является slave. */
OFPBRC_BAD_PORT = 11, /* Неверный порт. */
OFPBRC_BAD_PACKET = 12, /* Неправильный пакет в packet-out. */
OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13, /* ofp_multipart_request переполнил указанный буфер. */
};

Для типа ошибки OFPET_BAD_ACTION определены следующие коды:

/* Значения ofp_error_msg 'code' для OFPET_BAD_ACTION. 'data' содержит, по крайней мере, первые 64 байта неудачного запроса. */
enum ofp_bad_action_code {
OFPBAC_BAD_TYPE = 0, /* Не известный тип операции. */
OFPBAC_BAD_LEN = 1, /* Проблема длины в операции. */
OFPBAC_BAD_EXPERIMENTER = 2, /* Специфицирован неизвестный идентификатор экспериментатора. */
OFPBAC_BAD_EXP_TYPE = 3, /* Неизвестная операция для идентификатора экспериментатора. */
OFPBAC_BAD_OUT_PORT = 4, /* Проблема с валидацией выходного порта. */
OFPBAC_BAD_ARGUMENT = 5, /* Не корректный аргумент операции. */
OFPBAC_EPERM = 6, /* Ошибка разрешений. */
OFPBAC_TOO_MANY = 7, /* Не может обработать так много операций. */
OFPBAC_BAD_QUEUE = 8, /* Проблема с валидацией выходной очереди. */
OFPBAC_BAD_OUT_GROUP = 9, /* Некорректный идентификатор группы для операции переадресации. */
OFPBAC_MATCH_INCONSISTENT = 10, /* Операция не применима для данной сверки, или отсутствуют предварительные условия для Set-Field. */
OFPBAC_UNSUPPORTED_ORDER = 11, /* Порядок операций не поддерживается для списка операций в инструкции Apply-Actions */
OFPBAC_BAD_TAG = 12, /* Операции используют неподдерживаемые tag/encap. */
OFPBAC_BAD_SET_TYPE = 13, /* Неподдерживаемый тип в операции SET_FIELD. */
OFPBAC_BAD_SET_LEN = 14, /* Проблема с длиной в операции SET_FIELD. */
OFPBAC_BAD_SET_ARGUMENT = 15, /* Плохой аргумент операции SET_FIELD. */
};

Для типа ошибки OFPET_BAD_INSTRUCTION определены следующие коды:

/* Значения ofp_error_msg 'code' для OFPET_BAD_INSTRUCTION. 'data' содержит, по крайней мере, первые 64 байта неудачного запроса. */
enum ofp_bad_instruction_code {
OFPBIC_UNKNOWN_INST = 0, /* Неизвестная инструкция. */
OFPBIC_UNSUP_INST = 1, /* Переключатель или таблица не поддерживают инструкцию. */
OFPBIC_BAD_TABLE_ID = 2, /* Специфицирован неверный Table-ID. */
OFPBIC_UNSUP_METADATA = 3, /* Значение метаданных не поддерживается маршрутом (datapath). */
OFPBIC_UNSUP_METADATA_MASK = 4, /* Значение маски метаданных не поддерживается маршрутом. */
OFPBIC_BAD_EXPERIMENTER = 5, /* Специфицирован неизвестный идентификатор экспериментатора. */
OFPBIC_BAD_EXP_TYPE = 6, /* Неизвестная операция для идентификатора экспериментатора. */
OFPBIC_BAD_LEN = 7, /* В инструкции проблема с длиной. */
OFPBIC_EPERM = 8, /* Ошибка разрешений. */
};

Для типа ошибки OFPET_BAD_MATCH определены следующие коды:

/* Значения ofp_error_msg 'code' для OFPET_BAD_MATCH. 'data' содержит, по крайней мере, первые 64 байта неудачного запроса. */
enum ofp_bad_match_code {
OFPBMC_BAD_TYPE = 0, /* Специфицирован неподдерживаемый тип сверки */
OFPBMC_BAD_LEN = 1, /* Проблемы длины при сверке. */
OFPBMC_BAD_TAG = 2, /* Сверка использует неподдерживаемый tag/encap. */
OFPBMC_BAD_DL_ADDR_MASK = 3, /* Неподдерживаемая адресная маска канала - переключатель не поддерживает произвольные адресные маски канала. */
OFPBMC_BAD_NW_ADDR_MASK = 4, /* Неподдерживаемая сетевая маска канала - переключатель не поддерживает произвольные адресные маски сети. */
OFPBMC_BAD_WILDCARDS = 5, /* Неподдерживаемая комбинация полей маскированных или опущенных при сверке. */
OFPBMC_BAD_FIELD = 6, /* Неподдерживаемое поле тип при сверке. */
OFPBMC_BAD_VALUE = 7, /* Неподдерживаемое значение в поле сверки. */
OFPBMC_BAD_MASK = 8, /* Неподдерживаемая маска, специфицированная при сверке, поле не является сетевым или канальным адресом. */
OFPBMC_BAD_PREREQ = 9, /* Предварительные условия не выполнены. */
OFPBMC_DUP_FIELD = 10, /* Поле типа было задублировано. */
OFPBMC_EPERM = 11, /* Ошибка разрешений. */
};

Для типа ошибки OFPET_FLOW_MOD_FAILED определены следующие коды:

/* Значения ofp_error_msg 'code' для OFPET_FLOW_MOD_FAILED. 'data' содержит, по крайней мере, первые 64 байта неудачного запроса. */
enum ofp_flow_mod_failed_code {
OFPFMFC_UNKNOWN = 0, /* Неспецифицированная ошибка. */
OFPFMFC_TABLE_FULL = 1, /* Поток не добавлен, так как таблица переполнена. */
OFPFMFC_BAD_TABLE_ID = 2, /* Таблица не существует */
OFPFMFC_OVERLAP = 3, /* Попытка добавить перекрывающиеся потоки с установленным флагом CHECK_OVERLAP. */
OFPFMFC_EPERM = 4, /* Ошибка разрешений. */
OFPFMFC_BAD_TIMEOUT = 5, /* Поток не добавлен, из-за неподдерживаемого idle/hard таймаута. */
OFPFMFC_BAD_COMMAND = 6, /* Неподдерживаемая или неизвестная команда. */
OFPFMFC_BAD_FLAGS = 7, /* Неподдерживаемые или неизвестные флаги. */
};

Для типа ошибки OFPET_GROUP_MOD_FAILED определены следующие коды:

/* Значение ofp_error_msg 'code' для OFPET_GROUP_MOD_FAILED. 'data' содержит, по крайней мере, первые 64 байта неудачного запроса. */
enum ofp_group_mod_failed_code {
OFPGMFC_GROUP_EXISTS = 0, /* Группа не добавлена, так как совершена попытка замещения уже существующей группы. */
OFPGMFC_INVALID_GROUP = 1, /* Группа не добавлена, так как специфицирована некорректно. */
OFPGMFC_WEIGHT_UNSUPPORTED = 2, /* Переключатель не поддерживает неравное распределение нагрузки. */
OFPGMFC_OUT_OF_GROUPS = 3, /* Групповая таблица заполнена. */
OFPGMFC_OUT_OF_BUCKETS = 4, /* Превышено максимальное число операций перечня для группы. */
OFPGMFC_CHAINING_UNSUPPORTED = 5, /* Переключатель не поддерживает группы, которые осуществляют переадресацию группам. */
OFPGMFC_WATCH_UNSUPPORTED = 6, /* Эта группа не может отслеживать watch_port или специфицированную watch_group. */
OFPGMFC_LOOP = 7, /* Групповая запись приведет к зацикливанию. */
OFPGMFC_UNKNOWN_GROUP = 8, /* Группа не модифицирована, так как предпринята попытка модифицировать несуществующую группу. */
OFPGMFC_CHAINED_GROUP = 9, /* Группа не удалена, так как другая группа осуществляет ей переадресацию. */
OFPGMFC_BAD_TYPE = 10, /* Неподдерживаемый или неизвестный тип группы. */
OFPGMFC_BAD_COMMAND = 11, /* Неподдерживаемая или неизвестная команда. */
OFPGMFC_BAD_BUCKET = 12, /* Ошибка в перечне. */
OFPGMFC_BAD_WATCH = 13, /* Ошибка в отслеживание порта/группы. */
OFPGMFC_EPERM = 14, /* Ошибка разрешений. */
};

Для ошибок типа OFPET_PORT_MOD_FAILED определены следующие коды:

/* Значения кода ofp_error_msg для OFPET_PORT_MOD_FAILED (не корректны). 'data' содержит, по крайней мере, первые 64 байта неудачного запроса. */
enum ofp_port_mod_failed_code {
OFPPMFC_BAD_PORT = 0, /* Специфицированный номер порта не существует. */
OFPPMFC_BAD_HW_ADDR = 1, /* Специфицированный аппаратный адрес не соответствует номеру порта. */
OFPPMFC_BAD_CONFIG = 2, /* Специфицированная конфигурация не корректна. */
OFPPMFC_BAD_ADVERTISE = 3, /* Специфицированные анонсирования не корректны. */
OFPPMFC_EPERM = 4, /* Ошибка разрешений (Permissions). */
};

Для ошибок типа OFPET_TABLE_MOD_FAILED определены следующие значения:

/* ofp_error_msg 'code' values for OFPET_TABLE_MOD_FAILED. 'data' содержит, по крайней мере, первые 64 байта неудачного запроса. */
enum ofp_table_mod_failed_code {
OFPTMFC_BAD_TABLE = 0, /* Специфицированная таблица не существует. */
OFPTMFC_BAD_CONFIG = 1, /* Специфицированная конфигурация некорректна. */
OFPTMFC_EPERM = 2, /* Ошибка разрешений. */
};

Для ошибок типа OFPET_QUEUE_OP_FAILED определены следующие значения:

/* Значение ofp_error msg 'code' для OFPET_QUEUE_OP_FAILED. 'data' содержит по крайней мере первые 64 байта
* неудачного запроса */
enum ofp_queue_op_failed_code {
OFPQOFC_BAD_PORT = 0, /* Некорректный порт (или порт не существует). */
OFPQOFC_BAD_QUEUE = 1, /* Очередь не существует. */
OFPQOFC_EPERM = 2, /* Ошибка разрешений. */
};

Для типа ошибки OFPET_SWITCH_CONFIG_FAILED определены следующие коды:

/* ofp_error_msg 'code' values for OFPET_SWITCH_CONFIG_FAILED. 'data' содержит по крайней мере первые 64 байта неудачного запроса. */
enum ofp_switch_config_failed_code {
OFPSCFC_BAD_FLAGS = 0, /* Специфицированные некорректные флаги. */
OFPSCFC_BAD_LEN = 1, /* Специфицированная длина некорректна. */
OFPQCFC_EPERM = 2, /* Ошибка разрешений. */
};

Для типа ошибки OFPET_ROLE_REQUEST_FAILED определены следующие коды:

/* Значение ofp_error_msg 'code' для OFPET_ROLE_REQUEST_FAILED. 'data' содержит по крайней мере первые 64 байта неудачного запроса. */
enum ofp_role_request_failed_code {
OFPRRFC_STALE = 0, /* Устаревшее сообщение: старый generation_id. */
OFPRRFC_UNSUP = 1, /* Изменение роли контроллера не поддерживается. */
OFPRRFC_BAD_ROLE = 2, /* Некорректная роль. */
};

Для типа ошибки OFPET_METER_MOD_FAILED определены следующие коды:

/* Значения ofp_error_msg 'code' для OFPET_METER_MOD_FAILED. 'data' содержит по крайней мере первые 64 байта неудачного запроса. */
enum ofp_meter_mod_failed_code {
OFPMMFC_UNKNOWN = 0, /* Неспецифицированная ошибка. */
OFPMMFC_METER_EXISTS = 1, /* Измеритель не добавлен, так как сделана попытка заменить существующий измеритель. */
OFPMMFC_INVALID_METER = 2, /* Измеритель не добавлен, так как специфицирован некорректный измеритель. */
OFPMMFC_UNKNOWN_METER = 3, /* Измеритель не модифицирован, так как Meter MODIFY пыталась модифицировать несуществующий измеритель. */
OFPMMFC_BAD_COMMAND = 4, /* Неподдерживаемая или неизвестная команда. */
OFPMMFC_BAD_FLAGS = 5, /* Конфигурация флага не поддерживается. */
OFPMMFC_BAD_RATE = 6, /* Скорость не поддерживается. */
OFPMMFC_BAD_BURST = 7, /* Размер всплеска не поддерживается. */
OFPMMFC_BAD_BAND = 8, /* Диапазон не поддерживается. */
OFPMMFC_BAD_BAND_VALUE = 9, /* Не поддерживается значение диапазона. */
OFPMMFC_OUT_OF_METERS = 10, /* Нет больше измерителей. */
OFPMMFC_OUT_OF_BANDS = 11, /* Превышено максимальное число свойств для измерителя. */
};

Для типа ошибки OFPET_TABLE_FEATURES_FAILED определены следующие коды:

/* ofp_error_msg 'code' values for OFPET_TABLE_FEATURES_FAILED. 'data' содержит по крайней мере первые 64 байта неудачного запроса. */
enum ofp_table_features_failed_code {
OFPTFFC_BAD_TABLE = 0, /* Специфицированная таблица не существует. */
OFPTFFC_BAD_METADATA = 1, /* Некорректная маска метаданных. */
OFPTFFC_BAD_TYPE = 2, /* Неизвестный тип свойства. */
OFPTFFC_BAD_LEN = 3, /* Проблема длины в свойствах. */
OFPTFFC_BAD_ARGUMENT = 4, /* Неподдерживаемое значение свойства. */
OFPTFFC_EPERM = 5, /* Ошибка разрешений. */
};

Для типа ошибки OFPET_EXPERIMENTER сообщение ошибки определяется следующей структурой и полями, за которыми следуют данные, заданные экспериментатором:

/* OFPET_EXPERIMENTER: Сообщение об ошибке (маршрут -> контроллер). */
struct ofp_error_experimenter_msg {
struct ofp_header header;
uint16_t type; /* OFPET_EXPERIMENTER. */
uint16_t exp_type; /* Определяется экспериментатором. */
uint32_t experimenter; /* Идентификатор экспериментатора, который имеет ту же форму, что и структура ofp_experimenter_header. */
 uint8_t data[0]; /* Данные переменной длины. Интерпретируются на основе типа и кода. Никаких заполнителей. */
 };
 OFP_ASSERT(sizeof(struct ofp_error_experimenter_msg) == 16);

Симметричные сообщения

Hello

Сообщение OFPT_HELLO не имеет тела; то есть, оно состоит только из заголовка OpenFlow. Должны быть подготовлены реализации, воспринимающие сообщения hello, которые имеют тело.

Запрос эхо

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

Эхо отклик

Сообщение эхо отклик (Echo Reply) состоит из заголовка OpenFlow и немодифицированного поля данных эхо-запроса.

Техника SDN имеет хорошую перспективу в системах со значительными вариациями трафика (например, узлы сетевой торговли). Здесь возможна простая балансировка нагрузки серверов. Есть примеры построения WAN на основе технологии SDN (см. рис. 9). Смотри также Программируемый Интернет, Андрей Робачевский.

Рис. 9. Международная сеть компании Google на основе технологии SDN

Компания Juniper является одним из лидеров в этой области (см. Juniper’s SDN Approach Created a Rift in Engineering, Craig Matsumoto, January 7, 2014 ).

Библиография

  1. OpenFlow Specification 1.3. Open Networking Foundation. 2011.
  2. OpenFlow: enabling innovation in campus networks. McKeown, Nick, et al., et al. 2008, ACM SIGCOMM Computer Communication Review, pp. 69-74.
  3. Bradner, S. RFC 2119. IETF. [Online] March 1997. http://www.ietf.org/rfc/rfc2119.txt.
  4. Enns, et al., et al. RFC 6241. IETF. [Online] June 2011. http://tools.ietf.org/rfc/rfc6241.txt.

Previous: 4.1.1.6 Пассивные оптические сети (PON/EPON/GEPON)    UP: 4.1.1 Ethernet (IEEE 802.3)