【テクニカル・上級編】 IEEE 802.1Qタグフレーム構造とTPID(Tag Protocol Identifier) – インフラ・物理&L2/L3ネットワーク基礎実践ガイド

ネットワークエンジニアの多くは、日々の業務で何気なく vlan 10 や dot1q といった設定を投入し、L2スイッチのポートにトランクモードを流し込んでいる。しかし、その足元を支えるイーサネットフレームの内部構造、特に IEEE 802.1Q がいかにしてレイヤー2の世界を拡張し、パケットの運命を決定づけているかについて、パケットキャプチャのバイト列レベルまで降りて考えたことはあるだろうか。

今回は、VLANタグの心臓部である TPID(Tag Protocol Identifier) に焦点を当て、単なる「VLANの分け方」という教科書的な説明を遥かに超越した、カーネル内部の処理、MTU問題、Q-in-Qの闇、そして極限のパフォーマンスチューニングの世界へと読者を誘いたい。

—

1. 802.1Qタグフレーム構造とTPIDの正体

レガシーなイーサネット(Ethernet II)フレームにおいて、宛先MACアドレス(6オクテット)、送信元MACアドレス(6オクテット)の次にやってくるのは、長らく EtherType(2オクテット)だった。ここに 0x0800(IPv4)や 0x0806(ARP)が入り、上位プロトコルを指し示していた。

しかし、ネットワークの巨大化に伴い、物理的な境界にとらわれずにブロードキャストドメインを論理分割する必要性から生み出されたのが IEEE 802.1Q である。

フレーム構造の再定義

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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Destination MAC                          |
|                        (6 Octets)                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Source MAC (6 Octets)                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          TPID (0x8100)        |      TCI (PCP + DEI + VID)    |  <-- 802.1Q Tag (4 Octets)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          EtherType            |                               |
|          (2 Octets)           |      Payload (Data)           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
|                           ...                                 |

ここで注目すべきが、送信元MACアドレスの直後に割り込んだ 4オクテット(32ビット)のタグヘッダーだ。前半の16ビットが TPID であり、標準では 0x8100 が格納される。

受信側のNICやスイッチのASIC(またはLinuxカーネルのソフトウェアルータ)は、送信元MACアドレスの直後に 0x8100 を検知した瞬間、「あ、これは通常のEtherTypeではなく802.1Qタグだ」と即座に認識し、続く16ビットを TCI(Tag Control Information:PCP 3ビット、DEI 1ビット、VID 12ビット)としてパースする。

—

2. MTUの罠:1500バイトの壁とJumbo Frameの必然

ここでインフラエンジニアが必ず直面する「泥臭い現実」に触れておこう。
標準的なイーサネットの最大ペイロード(MTU)は 1500バイトである。ここに 802.1Qタグの 4オクテット(TPID + TCI)が挿入されると、フレーム全体は 1518バイトに膨れ上がる。さらにQ-in-Q(IEEE 802.1ad)などで多重タギングを行えば、フレームサイズはさらに増加する。

もしネットワーク機器やNICがこの「1518バイト以上のフレーム」を許容していなかった場合、何が起きるか?
スイッチのカウンターには Giant Frames や Runt/Oversize エラーがカウントされ、パケットは無慈悲にドロップされる。TCPの3wayハンドシェイクはSYNで成功したかに見えても、TLSハンドシェイクのClient Helloや証明書チェーンが含まれる巨大なパケット(MSS 1460バイト+IP/TCPヘッダー+VLANタグ)が流れた瞬間に通信が沈黙するという、原因究明に数時間を要する悪夢のようなパケットロスが発生する。

この問題を根本から回避するため、現代のデータセンターインフラでは、トランクポートを経由するパスにおいて、物理インターフェースのMTUを最低でも 1504バイト(できればJumbo Frameとして9000バイト) に設定することが鉄則となっている。

Linux環境におけるインターフェースのMTU拡張と、VLANサブインターフェースの作成は、以下のようにカーネルに明示的に指示する必要がある。

# 1. 物理インターフェース (eth0) のMTUをJumbo Frame (9000バイト) に拡張し、VLANヘッダー分のオーバヘッドを完全に吸収する
sudo ip link set dev eth0 mtu 9000
sudo ip link set dev eth0 up

# 2. 802.1Q VLAN 100のサブインターフェースを作成する
sudo ip link add link eth0 name eth0.100 type vlan id 100

# 3. 仮想インターフェース側にも適切なIPアドレスとMTUを付与
sudo ip addr add 192.168.100.10/24 dev eth0.100
sudo ip link set dev eth0.100 up

—

3. カーネル内部の挙動とオフロード機構(NIC Offloading)

Linuxカーネルのネットワークスタック(net/8021q/)は、パケットの送受信においてこのTPIDとVLANタグのハンドリングを極めて効率的に行っている。

受信時(RX)、NICがパケットをキャプチャすると、最新のNICドライバはハードウェアレベル(ASIC)で 0x8100 を検知し、VIDをパケットのメタデータ(sk_buff 構造体の skb->vlan_tci)に格納した上で、EtherTypeを元の値に書き戻してOSに渡す(これを HW VLAN stripping と呼ぶ)。これにより、上位のネットワークスタックはVLANタグの存在を意識することなく、通常のL3処理を行うことができる。

逆に送信時(TX)には、カーネルは skb 内のVLAN情報を元に、NICのハードウェア支援機能(VLAN Acceleration / TX VLAN Insertion)を利用して、送信パケットのDMA転送時にNIC自身にTPIDとTCIを挿入させる。

このオフロードが有効か無効かで、CPU使用率は劇的に変化する。以下のコマンドで現在の設定を確認・調整することができる。

# ネットワークインターフェースのVLANオフロード機能(vlan-hw-insert, vlan-hw-strip)の状態を確認
ethtool -k eth0 | grep vlan

# もしハードウェアアクセラレーションを強制的に有効化・無効化する場合
sudo ethtool -K eth0 vlan-hw-insert on
sudo ethtool -K eth0 vlan-hw-strip on

高スループットを要求されるKubernetesノードやNFV(Network Functions Virtualization)基盤において、この設定の不備は直ちにCPUボトルネックを引き起こす。スペシャリストたる者、ethtool の出力結果を片時も忘れてはならない。

—

4. セキュリティの急所:VLANホッピング攻撃とTPIDの偽装

セキュリティ専門家の視点から見逃せないのが、TPIDの処理の不備を突いた VLANホッピング攻撃(VLAN Hopping) である。

最も古典的な手法である「二重タギング(Double Tagging)」は、攻撃者が自身の端末から発信するパケットにあらかじめ2枚のVLANタグを仕込むというものだ。
1. 外側のタグ:ネイティブVLAN(スイッチ側でタグなしとして処理されるVLAN)のID
2. 内側のタグ:本来アクセスしたい標的の秘密VLANのID

不正なパケットがアクセスポート(単一VLAN所属)に入ると、スイッチは1枚目のタグ(ネイティブVLAN)を剥ぎ取り、ポートの所属VLANと一致していると判断してパケットをトランク方向へ送り出す。その際、スイッチは「すでにタグは処理した」と勘違いしているため、攻撃者が仕込んだ 2枚目のタグ(TPID 0x8100 + 標的のVID) がそのまま温存された状態でトランクリンクへ流出してしまう。結果として、パケットは本来到達不可能な別のVLANへルーティング・ブリッジされてしまうのだ。

対策:厳格なトランク規約とネイティブVLANの分離

この脆弱性を完全に封殺するためには、以下のベストプラクティスをハードウェアレベルで徹底する必要がある。

1. アクセスポートでのDTP(Dynamic Trunking Protocol)の無効化:
Cisco環境では必ず switchport nonegotiate を指定し、勝手にトランク交渉が行われる余地を断つ。
2. ネイティブVLANの未使用IDへの変更:
デフォルトの VLAN 1 をネイティブVLANとして放置せず、誰も使用していないダミーのVLAN(例:VLAN 999)に追いやり、データトラフィックが流れないようにする。
3. トランクポートにおけるネイティブVLANタギングの強制:
近年のモダンなスイッチOSでは、ネイティブVLANであってもフレームにタグを強制する機能(vlan dot1q tag native)が実装されている。これを有効にすることで、タグなしフレームの侵入を一切拒絶できる。

—

5. 高度な応用:Q-in-Q (IEEE 802.1ad) と Service Provider の世界

データセンターやキャリアネットワークの領域に踏み込むと、通常の 0x8100 だけでは足りなくなる。ユーザー企業が独自のVLAN(VID 1〜4094)を自由に構築したいと要求してきたとき、通信事業者(SP)側がそのVLAN IDをそのまま自網のコアスイッチに流し込むと、他社のVLANとIDが衝突する。

そこで登場するのが、IEEE 802.1ad(Q-in-Q / Provider Bridging) である。

Q-in-Qでは、ユーザーから送られてきた通常の 802.1Qフレーム(TPID: 0x8100)の上から、通信事業者側が「サービスプロバイダー用網内識別子」となる外側タグを強制的にラップする。この外側タグのTPIDには、標準の 0x8100 ではなく、拡張用の 0x88a8 や、レガシー環境向けの 0x9100 などが使用される。

+-------------------+-------------------+-------------------+-------------------+
| S-TPID (0x88a8)   | S-TCI (SP-VID)    | C-TPID (0x8100)   | C-TCI (Cust-VID)  |
| (Service Tag)     | (Outer Tag)       | (Customer Tag)    | (Inner Tag)       |
+-------------------+-------------------+-------------------+-------------------+

Linuxの iproute2 を用いて、このような多重タギング(QinQ)インターフェースを構築する際の設定例を以下に示す。

# 1. 物理インターフェースにサービスプロバイダー用の外側タグ (TPID 0x88a8, VID 3000) を作成
sudo ip link add link eth0 name eth0.3000 type vlan id 3000 proto 802.1ad

# 2. その上層に、顧客側の内側タグ (TPID 0x8100, VID 100) をさらにネストさせる
sudo ip link add link eth0.3000 name eth0.3000.100 type vlan id 100 proto 802.1Q

# 3. インターフェースを有効化し、二重タグパケットの送受信準備を完了する
sudo ip link set dev eth0.3000 up
sudo ip link set dev eth0.3000.100 up
sudo ip addr add 10.200.100.1/24 dev eth0.3000.100

このパケットがワイヤー上を流れるとき、ワイヤークラフト(Wireshark等)で覗くと、0x88a8 と 0x8100 が美しくネストしている様子が確認できるはずだ。この挙動を完全に理解していれば、通信事業者のレイヤー2VPN(VPLSやEVPN)のトラブルシューティングにおいて、パケットの剥離ミスやTPIDミスマッチを一撃で特定できるようになる。

—

結びにかえて

たった16ビットの 0x8100 というTPID。
しかし、その小さな数値の解釈を誤ればネットワークは沈黙し、設計の妙を知れば何万台もの仮想マシンを安全かつ効率的に収容する巨大なクラウドインフラの礎となる。

パケットのヘッダーは、単なるデータの運び屋ではない。そこには設計者の意図、OSカーネルの執念、そしてセキュリティの攻防の歴史が凝縮されている。日々の運用において、画面上のステータスランプに一喜一憂するのではなく、ぜひ tcpdump や wireshark を開き、バイト列の深淵を覗き込んでみてほしい。そこには、ネットワークプロトコルを愛する者だけが味わえる、確かな真実が流れている。

コメント

タイトルとURLをコピーしました