STPの心臓部を暴く:ブリッジIDの構造とルートブリッジ選出の全貌
こんにちは。ネットワークの現場で幾度となくレイヤ2ループによる全館通信断の阿鼻叫喚を鎮めてきた、シニアネットワークエンジニアの私だ。
モダンなWebアプリケーション開発やAPI設計に携わるエンジニアからすれば、「L2のループ防止? STPなんてスイッチが勝手にやってくれる黒魔術だろ?」と思うかもしれない。しかし、クラウドネイティブな環境であっても、オンプレミスとのハイブリッド接続、あるいはコンテナ基盤を支える物理・仮想ネットワークの足回りでは、このSpanning Tree Protocol(STP)の挙動がシステムの生死を分ける。
今回は、STPの根幹をなす「ブリッジID(Bridge ID)」の構造と、それがネットワーク全体の命運を握る「ルートブリッジ選出アルゴリズム」について、パケットの挙動から現場のトラブルシューティングまで徹底的に解説しよう。
—
1. なぜSTPが必要なのか、そして誰が王を決めるのか
レイヤ2スイッチングの基本は「フラッディングと学習」だ。しかし、冗長性を確保するためにスイッチ同士を複数本のケーブルで物理的に接続(ループを形成)すると、ブロードキャストフレームが無限ループを描き、わずか数秒でネットワーク帯域を食い尽くし、CPU使用率が100%に張り付いてスイッチが沈黙する。この悪夢を防ぐのがSTP(IEEE 802.1D)だ。
STPは、冗長パスの中から「論理的な木構造(スパンニング・ツリー)」を計算し、一部のポートをブロックすることでループを断つ。そのすべての計算の起点、すなわち「ネットワーク全体の中心(根=ルート)」となるのがルートブリッジ(Root Bridge)である。
このルートブリッジを自動的、かつ一意に決定するために使われるのが、各スイッチが持つブリッジID(Bridge ID: BID)なのだ。
—
2. ブリッジID(BID)の解剖学:8バイトの身分証明書
ブリッジIDは合計8バイト(64ビット)で構成されるデータ構造であり、IEEE 802.1Dの世界におけるスイッチの「戸籍謄本」のようなものだ。
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ブリッジ・プライオリティ (16 bits) | 拡張システムID (12 bits ※PVST+の場合) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ ベースMACアドレス (48 bits) +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
この8バイトは、大きく2つのフィールドに分かれている。
1. ブリッジ・プライオリティ(Bridge Priority:16ビット)
- スイッチの「偉さ」を示す値。デフォルトは通常
32768(0x8000)。 - 4096の倍数で変更可能(
0,4096,8192…61440)。 - 値が小さいほど優先度が高い(=偉い)。
2. ベースMACアドレス(Base MAC Address:48ビット)
- スイッチが持つ固有のMACアドレス(バックプレーンや特定のマネジメントポートのMAC)。
拡張システムID(Extended System ID)の罠
Cisco等のモダンなスイッチでVLANごとのSTPインスタンス(PVST+やRapid-PVST+)を動かす場合、16ビットのプライオリティ領域は次のように分割される。
- プライオリティ(4ビット): 上位4ビット。4096刻みで指定する値がここに入る。
- 拡張システムID(12ビット): 下位12ビット。ここにVLAN番号(VLAN ID)が自動的に付算される。
例えば、VLAN 10でプライオリティをデフォルト(32768)のままにしていると、実際のBIDのプライオリティフィールドは 32768 + 10 = 32778 として扱われる。この仕様を知らないと、「設定したはずのプライオリティと実際のBIDが微妙に違うぞ?」と現場で首を傾げることになるので注意が必要だ。
—
3. ルートブリッジ選出アルゴリズム:勝者は誰だ?
ネットワーク上のすべてのスイッチは、起動直後、自分がルートブリッジであると信じ込み、自分自身のBIDを送信元とするConfiguration BPDU(Bridge Protocol Data Unit)をすべてのポートから送出する。
BPDUが行き交う中で、スイッチは以下の比較ルール(STPパスコストとBIDの比較プロセス)に従って「より優れた情報」を受け入れる。
比較の優先順位(最重要)
1. 最小のルートBID(Lowest Root BID):
自分が知っている中で、最もプライオリティが高く(値が小さく)、MACアドレスが若いスイッチを「ルート」として認める。
2. 最小のパスコスト(Lowest Root Path Cost):
そのルートブリッジに至るまでのトータルのコスト(リンク速度に基づく。1Gbpsなら4、10Gbpsなら2など)が最も小さいパスを選ぶ。
3. 最小の送信元BID(Lowest Sender BID):
同一セグメント上に複数のスイッチがいる場合、隣接する中で最もBIDが小さいスイッチからのBPDUを優先する。
4. 最小の送信元ポートID(Lowest Sender Port ID):
同一スイッチ間に複数本のケーブルがある場合など。
このアルゴリズムの結果、「ネットワーク全体で最もBID(プライオリティ + MACアドレス)が小さいスイッチ」が、絶対的な王であるルートブリッジとして君臨することになる。
—
4. 現場の落とし穴:なぜ「デフォルト放置」が地獄を生むのか?
新人エンジニアがやりがちな最大のミスが、スイッチを箱から出して初期設定(プライオリティ変更なし=32768)のままネットワークに組み込むことだ。
もし、あなたが中古の安価なスイッチや、たまたまMACアドレスが非常に若い(例: 00:11:22:33:44:55)古びたアクセススイッチをコアレイヤに接続したとしよう。すべてのスイッチのプライオリティが 32768 で並んでいるため、アルゴリズムの判定は最後の砦、「MACアドレスの若さ」に委ねられる。
結果として、「一番性能が低く、古くて安価なスイッチ」がルートブリッジに選出されるという大惨事が起きる。トラフィックがその貧弱なスイッチに集中し、ネットワーク全体がスローダウン、あるいはダウンする。これが、実務において「意図したデバイスを確実にルートブリッジにする」ためのプライオリティ手動チューニングが必須である理由だ。
—
5. 実践:Cisco IOSでのルートブリッジ固定設定
運命を運任せにせず、ネットワーク設計者の意図通りにプライマリのルートブリッジとセカンダリ(冗長用)のルートブリッジを明示的に指定する設定例だ。
! =====================================================================
! プライマリ・ルートブリッジの設定 (VLAN 10および20)
! プライオリティを強制的に「24096」に下げ、他のどの機器よりも優位にする
! =====================================================================
SW-CORE-01# configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
SW-CORE-01(config)# spanning-tree vlan 10,20 root primary
! ※内部的には priority 24096 が自動計算されて割り当てられる
! =====================================================================
! セカンダリ・ルートブリッジの設定 (万が一の障害時に備える)
! プライオリティを「28672」に設定し、プライマリの次に偉い位置づけにする
! =====================================================================
SW-CORE-02# configure terminal
SW-CORE-02(config)# spanning-tree vlan 10,20 root secondary
! ※内部的には priority 28672 が割り当てられる
状態確認のCLIコマンド
現在のスイッチがルートブリッジとして機能しているか、あるいは誰をルートと仰いでいるのかを確認するには、以下のコマンドを叩く。
SW-ACCESS-01# show spanning-tree vlan 10
VLAN0010
Spanning tree enabled protocol ieee
Root ID Priority 24106 (24096 + SysID 10)
Address aabb.cc00.1000
Cost 4
Port 1 (GigabitEthernet0/1)
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Bridge ID Priority 32778 (32768 + SysID 10)
Address aabb.cc00.3000
PeerCost 4
----------------(略)----------------
この出力結果から、次のような状況が瞬時に読み取れる。
- Root IDのAddress (
aabb.cc00.1000): 我々のネットワークの王様(ルートブリッジ)のMACアドレス。 - Bridge IDのAddress (
aabb.cc00.3000): 今自分がログインしてコマンドを叩いているこのスイッチのMACアドレス。 - Root IDとBridge IDのAddressが異なるため、「このスイッチはルートブリッジではなく、ルートポート(GigabitEthernet0/1)経由でルートにぶら下がっている下位スイッチである」と判断できる。
—
6. PythonでシミュレートするBID比較ロジック
プログラマブルなネットワーク運用や、自製オーケストレーションツール・検証スクリプトを書く際に役立つ、BIDの比較アルゴリズムのPython実装例を示す。ネットワークのパケット処理が裏でどうロジックを回しているのか、直感的に理解できるはずだ。
#!/usr/bin/env python3
"""
Bridge ID (BID) 比較シミュレーションスクリプト
STPのルート選出におけるプライオリティとMACアドレスの優劣判定ロジックを模倣します。
"""
from dataclasses import dataclass
@dataclass
class Bridge:
name: str
priority: int
mac_address: str
def get_bid(self) -> int:
"""BIDを数値表現に変換する (プライオリティ << 48 + MACの整数値)"""
mac_int = int(self.mac_address.replace(":", ""), 16)
return (self.priority << 48) + mac_int
def compare_bridges(bridge_a: Bridge, bridge_b: Bridge) -> Bridge:
"""
2つのブリッジを比較し、STPのルールに従ってより優れた(BIDが小さい)方を返す。
"""
bid_a = bridge_a.get_bid()
bid_b = bridge_b.get_bid()
if bid_a < bid_b:
return bridge_a
elif bid_b < bid_a:
return bridge_b
else:
# 理論上あり得ないが完全に同一の場合
return bridge_a
if __name__ == "__main__":
# 現場のスイッチに見立てたインスタンス群
sw_old_cheap = Bridge(name="SW-OLD-ACCESS", priority=32768, mac_address="00:11:22:33:44:55")
sw_core_1 = Bridge(name="SW-CORE-01", priority=24096, mac_address="cc:dd:ee:ff:00:11")
sw_core_2 = Bridge(name="SW-CORE-02", priority=28672, mac_address="cc:dd:ee:ff:00:22")
switches = [sw_old_cheap, sw_core_1, sw_core_2]
# ネットワーク全体で最優秀のブリッジ(ルートブリッジ)を決定する
current_best = switches[0]
for sw in switches[1:]:
current_best = compare_bridges(current_best, sw)
print(f"=== STP ルートブリッジ選出結果 ===")
print(フローおよび勝者: f"選出されたルートブリッジ: {current_best.name}")
print(f"プライオリティ: {current_best.priority}")
print(f"MACアドレス: {current_best.mac_address}")
このコードを実行すればわかる通り、設定によってプライオリティを 24096 に引き下げた SW-CORE-01 が、MACアドレスの若さ(00:11... vs cc:dd...)を軽々と超越して見事にルートブリッジの座を勝ち取る。
—
7. まとめ
L2ネットワークの平穏は、たった8バイトのブリッジIDと、泥臭い大小比較の積み重ねによって保たれている。
- BIDはプライオリティ(16bit)とMACアドレス(48bit)の結合体。
- 数値が小さいほうが「偉い」。
- デフォルト放置は「最弱のスイッチが王様になる」という恐怖のディザスターを引き起こす。
- 現場では必ず
spanning-tree vlan X root primary/secondaryで意図した設計を流し込むこと。
クラウド全盛の時代であっても、パケットを物理的に運ぶレイヤ2の基本原則が変わることはない。この仕組みを腹に落としておけば、万が一のループ障害に直面した際も、冷静に show spanning-tree を叩いて秒速で原因を特定できるはずだ。
インフラの深淵へようこそ。次のパケット解析の旅も楽しんでいこう。
コメント