シニアエンジニアが教える!CAMテーブルの深層とエージングタイムの罠:L2スイッチの脳内を覗き見する
こんにちは。夜な夜なパケットキャプチャを開き、Wiresharkの画面に話しかけるのが日課のシニアネットワークエンジニアです。
Web APIの設計やモダンなクラウドインフラの構築に日々奔走している皆さん、ふと立ち止まってみてください。私たちが何気なく叩く curl や、アプリケーションが発火させる Fetch API のリクエストは、最終的にどのような物理世界(あるいは仮想物理世界)を通って相手に届いているでしょうか?
OSI参照モデルの第2層、データリンク層。ここで主役を演じるL2スイッチは、私たちが送るすべてのフレームの行き先をどうやって判断しているのか。その心臓部にあるのが MACアドレステーブル(一般的にはCAMテーブル) です。
今回は、このCAMテーブルの内部構造と、トラブルシューティングの現場で何度も私たちを救ってくれた(あるいは絶望の淵に落とした)「エージングタイム」の秘密について、現場の泥臭い知見を交えて徹底的に解説します。
—
1. CAMテーブルとは何か?なぜMACアドレス学習が必要なのか
L2スイッチの役割はシンプルです。「受信したフレームを、適切なポートにのみ転送する(フラッディングを避ける)」。これを実現するためにスイッチが保持しているのが、MACアドレステーブルです。
Hub(ハブ)のように受信したデータを全ポートにばらまく(フラッディング)のではなく、スイッチは賢く宛先を絞り込みます。その仕組みの根幹にあるのが、「送信元MACアドレスの動的学習(Source MAC Address Learning)」 です。
1. スイッチがポートAからフレームを受信する。
2. フレームの「送信元MACアドレス(SA)」と「受信したポート番号」のペアを確認する。
3. すでにテーブルに存在していなければ、CAMテーブルに新しくエントリとして書き込む。
4. フレームの「宛先MACアドレス(DA)」をCAMテーブルから引き、該当するポートがあればそこだけに転送する。テーブルになければ、受信ポート以外の全ポートへフラッディングする。
この一連の動作が、ハードウェアレベル(ASIC)で超高速に行われています。ここで使われているのが、通常のRAMとは一味違う「CAM(Content Addressable Memory)」という特殊なメモリです。
—
2. CAMテーブルの構造とASICの秘密
「テーブル」と呼ばれると、私たちはどうしてもデータベースのB-Treeインデックスや、連想配列(Hash Map)のようなソフトウェア的な構造を想像しがちです。しかし、CAMテーブルの正体は物理的なハードウェア回路です。
通常のRAM vs CAM
- 通常のRAM: 「アドレス(番地)」を指定して「データ」を取り出す。
- CAM(連想メモリ): 「データ(検索キー)」を入力すると、一瞬でそれが格納されている「アドレス」や「紐づく値(出力ポート)」を返す。
通常のRAMでMACアドレスを検索する場合、O(N) または O(log N) の検索コストがかかりますが、CAMは数クロック(ハードウェアの1サイクル)で全エントリをパラレル(並列)にスキャンし、一撃でマッチするポートを特定します。GbpsやTbpsといった現代のラインレートをL2スイッチが処理できるのは、このCAMのおかげなのです。
しかし、このCAMにも弱点があります。それは「容量の物理的な限界」です。
CatalystやNexusなどのスイッチモデルごとに、CAMテーブルが保持できるエントリ数(例: 8,000件、32,000件など)は厳密に決まっています。
—
3. エージングタイム(Aging Timer)の役割と「フラッディング地獄」
ここで重要になるのが、今回のテーマのもう一つの主役である 「エージングタイム(Aging Timer)」 です。
CAMテーブルのエントリは永遠に保持されるわけではありません。デフォルトでは多くのベンダー(Ciscoなど)で 300秒(5分) に設定されています。
なぜエージングタイムが必要なのか?
- MACアドレスの移動・撤去への追従: サーバが別のラックに移動したり、端末がシャットダウンされたりした際、古いルーティング情報が残り続けると通信不能(あるいは誤った転送)になります。
- CAMリソースの枯渇防止: ネットワーク内の機器が入れ替わる中で、使われなくなった古いエントリが残り続けると、貴重なCAMの容量が圧迫されます。
エージングのメカニズム
スイッチは、CAMテーブル内の特定のエントリ宛、あるいはそのエントリを送信元とするトラフィックを観測すると、そのエントリの「タイマー(エージングカウンタ)」をリセット(0に戻す)します。
もし、そのエントリに関連するトラフィックが一度も観測されないまま300秒が経過すると、スイッチは「この端末はもういなくなった、あるいは通信していない」と判断し、CAMテーブルからそのエントリを容赦なく削除(エージングアウト)します。
現場で起きた悲劇:エージングタイムにまつわるトラブル
以前、とある大規模オフィスのネットワークリプレイス案件で、「特定のクライアントPCから社内Web APIサーバーへの疎通が、数時間に1回、数秒間だけ途切れる」という不可解な現象に遭遇しました。
原因を辿ると、そのWeb APIサーバーの手前にあるL2スイッチのポートで、トラフィックの特性によりエージングタイム(300秒)の間に該当サーバーへのアクセスが途切れる時間帯がありました。サーバー側からの応答がないため、スイッチのCAMテーブルからサーバーのMACアドレスがエージングアウト。その直後にクライアントからリクエストが飛ぶと、スイッチは宛先を見失い、一時的にフラッディングが発生。ネットワーク機器の処理負荷や、スパニングツリー(STP)のトポロジによっては、この瞬間にパケットロスやレイマリオーダーが発生し、APIクライアント側でタイムアウトを引き起こしていたのです。
—
4. 実務で役立つ!スイッチのCAMテーブル確認とデバッグ手法
ネットワークの挙動がおかしいと感じたら、まずはスイッチのCLIにログインしてCAMテーブルの現状を確認するのがエンジニアの鉄則です。Cisco IOSを例に、実務で使うコマンドを見てみましょう。
カリカリの設定・確認コマンド例
! 現在のCAMテーブル(MACアドレステーブル)の全エントリを確認する
SW1# show mac address-table
! 特定のVLAN(例: VLAN 100)に絞って確認する
SW1# show mac address-table vlan 100
! 特定のMACアドレスがどのポートで学習されているかをピンポイントで探す
SW1# show mac address-table address 0011.2233.4455
! 動的学習されたエントリの総数や、現在のアロケーション状況を把握する
SW1# show mac address-table count
エージングタイムの確認と変更(Cisco IOS)
デフォルトの300秒から、環境に合わせてエージングタイムを調整したい場合のコンフィグレーションです。
! グローバルコンフィグレーションモードに入る
SW1# configure terminal
! MACアドレステーブルのエージングタイムを600秒(10分)に変更する
! (※極端に短くするとフラッディングが増え、長くしすぎると端末移動時の追従が遅れます)
SW1(config)# mac address-table aging-time 600
! 設定を保存する
SW1# write memory
—
5. アプリケーション開発者・インフラエンジニアへのメッセージ
「L2のMACアドレスやCAMテーブルなんて、ハードウェアが勝手にやってくれる黒魔術だろ?」と思っていませんでしたか?
しかし、コンテナ基盤(Dockerのbridgeネットワークなど)や仮想化環境(VMwareのvSwitchやOpen vSwitch)、さらにはパブリッククラウドのVPC内部に至るまで、ソフトウェアベースであっても「MACアドレスの学習と転送テーブル、そしてそのライフサイクル管理」という基本原理はまったく同じです。
Web APIのレスポンスがなぜか遅い、特定のマイクロサービス間でのみ通信が不安定になる――そんな時、レイヤー7やレイヤー4のログだけでなく、レイヤー2のハードウェア制限やエージングの挙動に思いを馳せることができるかどうかが、優れたフルスタックエンジニアと、単なる表面的な利用者との分かれ道になります。
パケットの旅路に思いを馳せながら、今日も爽やかにネットワークを組み上げていきましょう!
コメント