Теоретические основы и архитектура
RFC 3270 описывает три модели туннелирования QoS в MPLS: Uniform, Pipe и Short-Pipe. Выбор модели определяет, как DSCP и TC изменяются на входе, в транзите и на выходе. 1. Uniform: сквозная прозрачность. На входе DSCP клиента отображается в TC. Если узел ядра изменил TC (например, повысил drop precedence), на выходе изменённое значение копируется обратно в DSCP клиента, и клиент видит влияние ядра. 2. Pipe: изоляция клиента. DSCP отображается в TC на входе, а DSCP клиента на выходе остаётся без изменений; при этом выходной PE планирует очередь по TC метки, поэтому TC должен дойти до него (без PHP, например при explicit null). 3. Short-Pipe: наиболее частый выбор для VPN-сервисов. DSCP клиента сохраняется, а очередь на выходном интерфейсе выбирается по исходному DSCP клиента, поэтому он не зависит от обработки в ядре и работает с PHP.
Две иерархии PHB в одном пакете
Пакет клиента в L3VPN несёт два независимых приоритета: внутренний (tunneled PHB), которому соответствует клиентский DSCP, и внешний (LSP PHB), которому соответствует TC метки оператора. RFC 3270 (раздел 4) называет три модели туннелирования, то есть три способа ответить на вопросы: копируется ли внутренний приоритет во внешний при push; передаётся ли внешний обратно во внутренний при pop; и по какому из двух PHB egress PE ставит пакет в очередь на выходе к CE. Выбор - это не вопрос производительности, а условие договора: меняет ли оператор клиентский DSCP и считается ли клиентская маркировка частью SLA.
Uniform: один домен DiffServ от CE до CE
При push TC выводится из DSCP (копирование или таблица); транзитные P могут менять TC (re-marking, mark-down при перегрузке или нарушении профиля), и это изменение не локально: при снятии метки значение TC копируется в открывающийся заголовок, то есть в TC следующей метки или в DSCP IP-пакета (RFC 3270). Результат: IP-пакет, вышедший к CE, несёт DSCP, определённый ядром, а не клиентом. Модель подходит, когда оператор и клиент - один административный домен DiffServ: корпоративная сеть на MPLS, магистраль провайдера, где IP-трафик пользователей и так принадлежит провайдеру, или транзит между доменами с общей политикой. Для услуги VPN, проданной клиенту с собственной схемой QoS, Uniform вреден: клиент видит, что ядро переписало его маркировку.
Pipe: ядро невидимо, но egress ему подчиняется
Ingress PE назначает TC по политике оператора (по SLA услуги, не копированием) и не трогает внутренний DSCP; при pop ничего не копируется, клиентский DSCP на выходе остаётся прежним. Но по RFC 3270 egress LSR ставит пакет в очередь по внешнему PHB, то есть по TC, назначенному оператором (и возможно изменённому ядром), а не по DSCP клиента. Смысл: оператор может гарантировать класс услуги на всём пути, включая последний линк до CE, не завися от того, что клиент написал в DSCP. Цена: egress PE обязан видеть TC. Когда метка снимается при PHP на предпоследнем P, TC исчезает; в L3VPN выход есть, потому что VPN-метка остаётся в стеке и несёт собственный TC, а для однометочных LSP (IPv4 по LDP, 6PE без VPN-метки) нужно отключить PHP: egress объявляет explicit-null (метка 0 для IPv4, 2 для IPv6, RFC 3032), и последний хоп несёт метку с TC.
Short-Pipe: ядро невидимо и egress его игнорирует
Ingress и транзит те же, что в Pipe: TC назначается оператором, DSCP не копируется и не меняется. Разница только на egress PE: очередь на выходе к CE выбирается по внутреннему PHB, то есть по клиентскому DSCP, как обычный IP-трафик. Mark-down в ядре "прощается" на последнем линке: если P понизил EF с TC 5 до TC 0 из-за перегрузки, клиентский EF всё равно попадёт в приоритетную очередь выхода. PHP при этом не мешает: egress PE получает только VPN-метку (или чистый IP) и всё равно классифицирует по DSCP. Это самая распространённая модель у провайдеров: клиентская очередь на CE-интерфейсе - зона ответственности клиента, а профиль DSCP клиента PE уже знает по ingress-классификации.
| Модель | Ingress PE (push) | P и PHP | Egress PE: очередь на выходе | DSCP на выходе к CE | UHP нужен? |
|---|---|---|---|---|---|
| Uniform | TC из DSCP | TC меняется, при pop копируется вниз | По TC (после копирования это DSCP) | Переписан ядром | Нет |
| Pipe | TC по политике оператора | TC меняется, не копируется | По TC метки | Исходный клиентский | Да для LSP без VPN-метки |
| Short-Pipe | TC по политике оператора | TC меняется, не копируется | По клиентскому DSCP | Исходный клиентский | Нет |
Один и тот же пакет в трёх моделях
Клиент отправил EF (DSCP 46). Ingress PE поставил TC 5. На P1 нарушен профиль, и P1 переписал TC в 0. Дальше разница:
| Что видит пакет | Uniform | Pipe | Short-Pipe |
|---|---|---|---|
| TC в ядре после P1 | 0 | 0 | 0 |
| Очередь на последнем линке к CE | Best Effort | Best Effort (по TC 0) | Приоритетная (по DSCP EF) |
| DSCP на выходе к CE | 0 (потерян) | 46 (сохранён) | 46 (сохранён) |
| Видимость mark-down для клиента | Видна по DSCP | Скрыта, но задержка и потери видны | Скрыта, влияние минимально |
Что происходит в каждом узле
Ingress PE: классифицирует по клиентскому DSCP/ACL и ставит TC на все метки стека (транспортную и VPN). Транзитный P: меняет только внешнюю метку (swap), TC переносится, если не сработал policer или remark; P не видит ни DSCP, ни внутреннюю метку. Penultimate P при PHP снимает транспортную метку; в Uniform он (или egress PE) копирует TC в открывшуюся VPN-метку или IP; в Pipe и Short-Pipe копирования нет. Egress PE: находит VRF по VPN-метке, делает IP lookup и ставит пакет в выходную очередь по правилам выбранной модели. Если у PHP-сегмента стоит explicit-null, лишняя метка стоит 4 байта на последнем линке и дополнительный lookup на egress: часть ASIC делает его на второй проход, поэтому включают explicit-null осознанно и только для LSP без VPN-метки.