L2の深淵に潜む「優先順位」の正体:802.1QのPCPでトラフィックを制御する
ネットワークエンジニアとして現場に立っていると、「Web APIのレスポンスがなぜかバースト的に遅延する」という相談をよく受けます。アプリケーション層でリトライ処理を書いても解決しない。L7のボトルネックを探し尽くした後に、ふとL2スイッチの統計情報を見ると、特定のポートで転送待ちが発生している……。
そんな時、我々が最後に頼るのが IEEE 802.1p、すなわち 802.1Qタグ内のPCP(Priority Code Point) です。今日は、イーサネットフレームの隅っこに隠れたこの「3ビットの魔法」が、いかにして現代のシビアなネットワーク品質を支えているのか、その深淵を覗いてみましょう。
—
1. PCP(Priority Code Point)とは何か
802.1Qタグ(VLANタグ)は、ご存知の通りイーサネットフレームに挿入される4バイトの識別子です。その中のTCI(Tag Control Information)フィールド、具体的には先頭16ビットのうちの末尾3ビットが PCP です。
- PCP (3 bits): 0〜7の8段階の優先度(CoS: Class of Service)を定義。
- DEI (1 bit): Drop Eligible Indicator。輻輳時にドロップされても良いフレームかを示す。
この「たった3ビット」が、スイッチのキューイングアルゴリズムに対して「このフレームはVoIPだから最優先で送れ」や「これはバックグラウンド同期だから後回しでいい」という強烈なヒントを与えます。
8段階のCoS値と一般的な用途
| PCP (CoS) | 優先度 | 用途の目安 |
| :— | :— | :— |
| 7 | 最高 | ネットワーク制御 (OSPF/BGP等のルーティングプロトコル) |
| 6 | 高 | インターネットワーク制御 |
| 5 | 高 | 音声 (VoIP) |
| 4 | 中 | 動画 (Video Streaming) |
| 3 | 中 | ミッションクリティカルなデータ |
| 2 | 低 | 通常のトラフィック |
| 1 | 低 | 最小優先度 (バックグラウンド) |
| 0 | デフォルト | ベストエフォート |
—
2. 現場での実務:スイッチ設定の勘所
理論はわかっても、設定を間違えればネットワーク全体を停止させかねません。特に重要なのは「信頼境界(Trust Boundary)」の概念です。
例えば、Cisco Catalystスイッチで特定のポートに到着したフレームのCoS値を信頼し、内部キューにマッピングする場合の設定例を見てみましょう。
# インターフェース単位で「受信したタグのCoS値を信頼する」設定
interface GigabitEthernet1/0/1
description API-SERVER-UPLINK
switchport mode trunk
# 受信したフレームのCoS値をそのまま内部のDSCP値へマッピング(信頼する)
mls qos trust cos
# コアスイッチでのキューマッピング(CoS 5を優先キューへ)
# 8段階のCoSを、スイッチ内のどのハードウェアキューに割り当てるか定義する
priority-queue out
wrr-queue cos-map 1 0 1 # キュー1にCoS 0, 1を割り当て
wrr-queue cos-map 4 5 # 最優先のキュー4にCoS 5を割り当て
エンジニアの泥臭いTip:
現場で最も多いトラブルは「タグが付与されていない」または「アップストリームのスイッチでQoS設定がリセットされている」ことです。show interfaces gigabitEthernet 1/0/1 statistics で、期待通りのキューにパケットが振り分けられているか、必ずカウンターを確認してください。
—
3. アプリケーション層との接点:パケットに細工はできるか?
開発者が「APIのパケットに優先度を付けたい」と考えるのは自然なことですが、残念ながらOSの標準的なソケットAPIから直接「PCPビットを操作する」ことはできません。NICのドライバやOSのカーネルがタグを書き換えることはセキュリティ上制限されているからです。
しかし、Linuxであれば iproute2 (tcコマンド) を使って、特定のポート番号や送信元IPを持つトラフィックにマークを付け、それがブリッジを通る際にタグとして反映されるよう構成可能です。
# 特定のAPI通信(ポート8080)にマークを付与する例
# 1. iptablesでパケットにマークを付ける
iptables -t mangle -A POSTROUTING -p tcp --dport 8080 -j MARK --set-mark 1
# 2. tc (Traffic Control) でマークに基づき優先度を割り当てる
tc qdisc add dev eth0 root handle 1: prio
tc filter add dev eth0 parent 1: protocol 802.1Q prio 1 handle 1 fw flowid 1:1
※ただし、このマークはあくまでOS内部の話であり、スイッチのトランクポートでタグが付与されるタイミングで、カーネルが skb->priority を見てPCP値を設定する仕組みが必要です。
—
4. 最後に:なぜ「3ビット」にこだわるのか
私が新人だった頃、ネットワークの遅延を「アプリのコードが悪い」と決めつけ、深夜までログを追ったことがあります。結局の原因は、社内のバックアップ通信がネットワークの帯域を食いつぶし、APIのレスポンスが遅延していたことでした。
PCPによる優先度制御は、いわば「混雑した高速道路に救急車専用レーンを作る」ようなものです。すべての車を速く走らせることは物理的に不可能ですが、「本当に届けるべきデータ」の道筋を確保することは、エンジニアの技量でコントロール可能です。
Web APIの設計においても、インフラのトポロジーを理解し、トラフィックの重要度を把握しておくことは必須のスキルです。次回のインフラ設計時には、ぜひこの「3ビットの優先度」がパケットに刻まれている様子を脳内でシミュレーションしてみてください。
現場からは以上です。また次の技術深掘りでお会いしましょう。
コメント