ネットワークの深淵を愛する皆さん、こんにちは。現場で数々の泥臭いパケットロスやL2ループ、QoSの不整合を殴り倒してきたシニアネットワークアーキテクトの私です。
Web APIの設計やモダンなクラウドインフラの構築に日々奔走しているエンジニアの皆さんにとって、OSI参照モデルの第1層や第2層、すなわち物理レイヤーやデータリンクレイヤーの挙動は「クラウドの向こう側のブラックボックス」に見えがちかもしれません。しかし、ひとたび本番環境で大規模なトラフィックバーストが発生し、APIのレイテンシーが跳ね上がったり、VoIPやリアルタイムストリーミングがパケット破棄の嵐に見舞われたりしたとき、最後に頼りになるのはL2スイッチの内部で何が起きているかという泥臭い知識です。
今回は、そのL2レイヤーにおけるQoS(Quality of Service)の要、IEEE 802.1Qタグ内にひっそりと存在する3ビットの巨人「PCP(Priority Code Point)」について、規格の背景から現場のトラブルシューティングまで徹底的に解説します。
—
1. なぜL2レイヤーで優先度制御が必要なのか?
私たちが普段何気なく使っているEthernet(イーサネット)は、もともと「ベストエフォート(最善努力)」が基本思想です。送ったパケットが届こうが途中でドロップされようが、ネットワークは原則として関知しません。
しかし、現代のネットワークは、ひとつの物理回線の上に、データベースの同期トラフィック、巨大なコンテナイメージの転送、監視用のSNMPトラフィック、そしてミリ秒単位の応答が求められるWeb APIや音声・映像トラフィックが同居しています。
もし、夜間のバッチ処理による大容量バックアップがスイッチのアップリンクを完全に飽和させたらどうなるでしょうか?当然、その背後で流れている重要度の高いAPIのリクエストやヘルスチェックも、同じFIFO(First-In, First-Out)のキューの列に並ばされている限り、容赦なく破棄(Tail Drop)されます。
ここで登場するのが、L2のスイッチングの段階でパケットを色分けし、重要度の高いものを優先的に転送・処理するIEEE 802.1QのQoSメカニズムです。
—
2. IEEE 802.1Qフレーム構造とTCI内部のPCP
VLAN(Virtual LAN)を流れるイーサネットフレームには、宛先MACアドレスと送信元MACアドレスの間に、おなじみの4バイトの「802.1Qタグ」が挿入されます。このタグの内部構造を分解してみましょう。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| TPID (0x8100) | TCI (Tag Control Information) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| TCI (続き) | Length / EtherType |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
このうち、後半の2バイト(16ビット)が TCI(Tag Control Information) と呼ばれる領域です。TCIは、さらに以下の3つのフィールドに細分化されます。
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PCP |C| VLAN ID (12ビット)|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- PCP (Priority Code Point) : 上位3ビット(0〜2ビット目)
- CFI / DEI (Canonical Format Indicator / Drop Eligible Indicator) : 1ビット(3ビット目)
- VLAN ID (VID) : 下位12ビット(4〜15ビット目)
今回フォーカスする PCP は、この先頭の3ビットです。3ビットで表現できる組み合わせは $2^3 = 8$ 通り。つまり、8段階のトラフィック優先度をL2のヘッダーレベルで直接表現できるのです。
—
3. PCPの8段階(CoS)とIEEE 802.1pの思想
IEEE 802.1Q(現在はIEEE 802.1-2014などの統合規格に移行)の一部として規定されているこの優先度マッピングは、もともとはIEEE 802.1pというワーキンググループで策定されたため、現場では今でも「CoS(Class of Service)ペティ」や「802.1pプライオリティ」と呼ばれることがよくあります。
IEEE 802.1Q/802.1pが推奨する標準的なPCPの値とトラフィッククラスの割り当ては以下の通りです。
| PCP値 | 優先度 (低〜高) | トラフィックの種類 | 具体例・ユースケース |
| :—: | :—: | :— | :— |
| 0 | 最低 (Background) | バックグラウンド | 大規模ファイル転送、バックアップ、ログ転送 |
| 1 | (デフォルト) | ベストエフォート | 一般的なWebブラウジング、通常のAPIトラフィック |
| 2 | 中低 (Excellent Effort) | 優れたベストエフォート | 重要度の低いデータ、VLAN管理トラフィック |
| 3 | 中 (Critical Applications) | クリティカル・アプリケーション | データベースのトランザクション、重要なAPIレスポンス |
| 4 | 中高 (Video) | ビデオ (< 100ms ジッター) | ライブ動画ストリーミング、監視カメラ映像 |
| 5 | 高 (Voice) | 音声 (< 10ms ジッター) | VoIP、IP電話、リアルタイム音声通話 |
| 6 | 制御 (Internetwork Control) | インターネットワーク制御 | OSPF、BGPなどのルーティングプロトコルパケット |
| 7 | 最高 (Network Control) | ネットワーク制御 | スイッチ間のL2制御(STP、LACPなど) |
現場のエンジニアとして非常に重要なのは、「PCP 1 がデフォルトのベストエフォートであり、PCP 0 よりも優先度が低い」という歴史的かつ直感に反する仕様です。(※多くの機器の実装では 0 と 1 が同じベストエフォートキューにまとめられることも多いですが、厳密な規格上は 1 がデフォルトです)。
—
4. ネットワーク機器(Cisco/Linux)でのPCP設定とマッピング実例
では、実際にこのPCPがネットワーク機器やサーバのOS(Linux)上でどのように扱われるのか、具体的な設定を見ていきましょう。
実環境では、L2のPCP(3ビット)だけでエンドツーエンドのQoSが完結することは稀です。通常は、L3のIPヘッダーにある DSCP(Differentiated Services Code Point / 6ビット) と相互にマッピング(Trust設定)されながら、ルーターやスイッチの複数の出力キュー(通常は4〜8キュー)へと振り分けられます。
Cisco IOSスイッチでの設定例
エッジスイッチのポートで、受信したパケットのL2 PCP値を信頼(Trust)し、内部のQoSキューイングに反映させる典型的なCisco IOSの設定です。
! 1. インターフェイスで802.1p(PCP)の信頼を設定
interface GigabitEthernet0/1
description Connected to Application Server
switchport access vlan 100
switchport mode access
mls qos trust cos
! 2. CoS(PCP)値から内部のドロップ/スケジューリングキューへのマッピング定義
! PCP 5 (Voice) を最も優先度の高いqueue 4に割り当てる例
mls qos map cos-dst 5 5
mls qos map queue-cos 1 0 1
mls qos map queue-cos 2 2 3
mls qos map queue-cos 3 4
mls qos map queue-cos 4 5 6 7
Linux (iproute2 / tc) でのPCPタギング例
KubernetesのノードやベアメタルのLinuxサーバーから送出するパケットに、特定のソケットやマークを基にしてL2のPCP(skb->priority)を付与し、VLANインターフェイス経由で送出する際の設定(tc コマンド)です。
#!/bin/bash
# ネットワークインターフェイス eth0 上にVLAN 100を作成
ip link add link eth0 name eth0.100 type vlan id 100
# egress(送信方向)のトラフィックマップを設定
# Linuxのパケットプライオリティ(SO_PRIORITY)を、VLANヘッダーのPCPにマッピングする
# 例: 優先度 6 のパケットに PCP = 5 (Voice) を付与する
ip link set dev eth0.100 type vlan egress-qos-map 6:5
# ネットワークインターフェイスを有効化
ip link set dev eth0.100 up
開発者がアプリケーションコード(PythonやNode.js)から直接PCPを叩くことは稀ですが、Linuxソケットオプションの SO_PRIORITY を適切に設定することで、カーネル経由でこのPCP値を制御することが可能です。
—
5. Web API開発者・インフラエンジニアがハマる「QoSの落とし穴」
ここで、現場で幾度となく目撃してきた「PCPにまつわる悲劇」をいくつか共有しておきましょう。
落とし穴1:L2トランク越しのVLAN再マーキング問題
サーバーとデータベースの間に、複数のL2スイッチやプロバイダ網が挟まっている場合、途中の機器が勝手にPCP値を 0 に書き換えてしまう(Trustしない)現象が起きます。
- 対策: エッジ(最初に入るスイッチ)で必ず
mls qos trustを有効にし、L2のPCP値だけでなく、L3のDSCP値へと昇格(Maps to DSCP)させてトンネリングさせる設計が鉄則です。
落とし穴2:クラウド環境(AWS/GCP/Azure)におけるPCPの無力化
パブリッククラウドの仮想インスタンス(EC2等)からAPIリクエストを飛ばす際、OS上でいくら ip link や tc を使ってVLANのPCPやDSCPをいじっても、ハイパーバイザーやクラウドの物理NWのトランスポート層で完全にマスク(ストリップまたは初期化)されることがほとんどです。
- 対策: クラウドネイティブな環境でAPIのQoSを担保したい場合は、L2のPCPに頼るのではなく、AWSならVPCのトラフィックミラーリングや、アプリケーション層(HTTP/gRPCのタイムアウト設計、サーキットブレーカー、プライオリティキューイング)での制御に注力すべきです。PCPが真価を発揮するのは、依然として「オンプレミスのデータセンター内ネットワーク」や「キャリア回線網」です。
—
6. まとめ
IEEE 802.1QのTCI内にひそむたった3ビットのPCP。しかしこの小さな3ビットこそが、膨大なトラフィックの濁流の中で「どのパケットを先に行かせるか」を決める、L2世界のエスプリです。
- PCPはTCIの先頭3ビットに位置し、8段階の優先度を表現する。
- デフォルトのベストエフォートは
1であり、0(バックグラウンド)よりも優先度が低いという仕様上のトラップがある。 - クラウド環境では意識されにくいが、オンプレミスやキャリア網におけるL2 QoS設計の根幹をなす。
インフラの基礎知識は、一見モダンな開発から遠く離れているように思えて、実はアプリのパフォーマンスチューニングや障害切り分けの土台を支える強力な武器になります。パケットの旅路に思いを馳せながら、ぜひ皆さんのネットワーク設計にもこの視点を取り入れてみてください。
コメント