NIC(ネットワークインターフェースカード)— データを信号に変える

上級の解説は準備中のため、上級の内容を表示しています。

概要 — まず全体をつかむ

中級では、NICを「L2の住所付け(MACアドレス)とフレーム化」まで見ました。上級では視点を一段下げ、一枚のフレームが物理信号として届いてから、CPUのメモリに載り、上位ソフトへ渡るまでの内部の受け渡しを端から端まで掘ります。読み終える頃には、「なぜ高速回線ほど割り込みが敵になるのか」「なぜNICに計算を肩代わりさせるのか」「なぜ調査ツールがチェックサム不正と嘘をつくのか」が、すべて同じ1本の受け渡しの話として読めるはずです。

信号がどの層でビットになるのかは ネットワーク層、有線・無線それぞれの物理は 有線無線 を参照。

アニメーション『NIC(デジタル↔信号の変換)』を開く
NIC=データと信号の変換器PC内のデータ0と1のビット列(デジタル)0101NIC変換器0/1 ⇄ 信号回線を流れる信号電気/光/電波(連続した波)送信→信号へ受信→0/1へ戻すPCの外は連続した信号、中は0と1。その橋渡しがNIC

詳細 — 1段階ずつ追う

① MACアドレスとイーサネットフレーム

中級の「宛先MAC・送信元MAC+データ」を、上級ではフレームの構造末尾の誤り検出まで下ろします。

  1. 送信するデータの前にヘッダ(宛先MAC※1・送信元MAC・種別)を、後ろにFCS※2 を付けてフレームの形にする
  2. 宛先MACには、その回線に1台へ届けるユニキャストのほか、全員宛のブロードキャスト、特定グループ宛のマルチキャストがある
  3. 受信側NICは、まず宛先MACが自分宛(またはブロードキャスト等)かを見て、無関係なフレームはMAC層で捨てる
  4. 自分宛ならFCSを再計算して照合し、壊れていれば黙って破棄する。訂正はせず、再送は上位(TCP)に委ねる

登場人物メモ(※の説明):

  • ※1 宛先MAC — 48ビットの機器固有番号。先頭側にベンダー識別子(OUI)を含み、同じ回線内で「どれに渡すか」を一意に指す
  • ※2 FCS — Frame Check Sequence。フレーム全体から計算したCRC値。受信側で再計算して一致を見る、誤り検出専用の番人(訂正はしない)

⚠️ イレギュラー(正常系との違いが学びどころ):

  • 無差別モード(プロミスキャス) — 通常は自分宛以外を捨てるが、この設定にすると全フレームを取り込む。パケットキャプチャはこれを使う
  • 壊れたフレーム — FCS不一致は破棄されるだけで、送信元は「届かなかった」ことをここでは知らない。気づくのは上位の再送タイマ

② 割り込み・DMA・リングバッファ

届いたフレームをどうやってCPUのメモリに載せ、CPUへ知らせるか。ここが受信性能の心臓部です。

  1. NICは受信フレームを、DMA※1 でCPUを介さず直接メインメモリへ書き込む。書き込む先はあらかじめOSが用意したリングバッファ※2 の空きスロット
  2. 置き終えたらNICは割り込み※3 でCPUに「届いた」と知らせる
  3. CPUは割り込みハンドラで、リングバッファに溜まったフレームを取り出し、上位(IPスタック)へ渡す
  4. 取り出して空いたスロットは、次の受信のためにNICへ返却(補充)する。リングは使い回される輪

登場人物メモ(※の説明):

  • ※1 DMA — Direct Memory Access。周辺機器がCPUを介さずメモリを読み書きする仕組み。CPUはコピー作業から解放される
  • ※2 リングバッファ — 受信用スロットを環状に並べた領域(ディスクリプタの列)。先頭と末尾を追いかけっこさせて、コピーなしで受け渡す
  • ※3 割り込み — 機器がCPUの今の処理に割り込んで通知するハードの仕組み。応答は速いが、出入りに段取りコストがかかる

⚠️ イレギュラー(速さが仇になる):

  • 割り込みライブロック — 高速回線で毎パケット割り込むと、割り込み処理の段取りだけでCPUが埋まり、実処理が進まない
  • ポーリングへの切替(NAPI) — 最初の1回を割り込みのきっかけにし、以降は割り込みを止めてまとめて刈り取る折衷。低負荷では割り込みの速さ、高負荷ではポーリングの効率を取る
  • リング溢れ — 取り出しが追いつかないとスロットが尽き、以降のフレームはNICで取りこぼす(ドロップカウンタが増える)

③ オフロードと受信側スケーリング

CPUの負担を下げるため、定型作業をNIC側の回路に肩代わりさせます。これがオフロードです。

  • チェックサムオフロード — IP/TCPのチェックサム計算・検証をNICが行う。CPUは全バイトを舐めずに済む
  • TSO/LRO — 送信時、大きな塊をNICがMTU※1 サイズのフレーム群へ分割するのがTSO。受信時、細切れフレームをNICが1つの大きな塊へ束ねて渡すのがLRO。どちらも1パケットあたりのCPU手間を減らす
  • 受信側スケーリング(RSS) — 複数のリングバッファを用意し、フローごとに別々のCPUコアへ割り当てて並列に処理する。1コアが受信で飽和するのを防ぐ

登場人物メモ(※の説明):

  • ※1 MTU — Maximum Transmission Unit。1フレームに載せられる最大サイズ。イーサネットは標準1500バイト。これを超えるデータは複数フレームに刻む必要がある

⚠️ イレギュラー(肩代わりの副作用):

  • キャプチャが嘘をつく — チェックサムはNICが送出直前に埋めるため、手前で覗くツールには「未計算=不正」に見える。実回線上は正しい
  • LROとルーティングの相性 — 受信で束ねてしまうと、そのまま転送する機器では都合が悪いことがある(束ねた塊をまた刻み直す羽目になる)
  • オフロードのバグ — 特定のNIC・ドライバでオフロードが誤動作すると、原因が上位ソフトに見えて切り分けが難しい。疑うときは一時的に無効化して比較する

④ PHYとMACの役割分担

NICは1枚に見えて、内部は信号を扱う層フレームを扱う層に分かれています。

  • PHY(物理層) — ビット列を電気・光・電波の信号へ変調して載せ、受信では信号からビットを復調する。ケーブルや電波との境目そのもの
  • MAC(データリンク層) — フレームの組立・宛先MAC判定・送受信のアクセス制御(いつ送ってよいか)を担う。①②で見た仕事はここ
  • 両者のつなぎ目 — PHYとMACはMII系のインターフェースで結ばれ、速度規格(100M/1G/10G…)は主にPHYと相手との取り決め(中級で見たオートネゴシエーション)で決まる

登場人物メモ(※の説明):

  • ※1 変調/復調 — デジタルのビットを、送れる形の物理信号に変える/戻す操作。何をどう変調するかが速度規格の中身

⚠️ イレギュラー(層をまたぐ切り分け):

  • リンクは上がるのに通信できない — PHY同士はつながった(リンクアップ)が、MAC以上(速度・全二重の食い違いなど)で不整合、という切り分けが要る場面
  • 速度が出ない — ケーブル品質やPHYの劣化で、規格上の最高速へ上がりきらずに落ちることがある(オートネゴシエーションが安全側へ倒れる)

⚠️ 上級の落とし穴

受信の内部が見えると、次のような詰まりどころが同じ絵の上で読めます。

  • 割り込み過多を見落とす — 高速回線ほど毎パケット割り込みが害になる。NAPI/割り込み合体(interrupt coalescing)で通知をまとめるのが定石
  • コピーコストの軽視 — DMAでメモリには載っても、そこから上位へ何度もコピーするとCPUを食う。ゼロコピー系の工夫はこの重複コピーを削る
  • オフロード副作用の誤診 — チェックサム不正表示やLROの束ねを「異常」と早合点しない。切り分けは一時無効化して比較する
  • リングサイズの当てずっぽう — 溢れて取りこぼすなら増やす、というだけでなく、大きすぎれば遅延(バッファ膨張)を招く。捨てている数(ドロップ)を見て釣り合わせる
  • 「NICは速いから大丈夫」という過信 — 物理速度が出ても、割り込み・コピー・1コア集中がボトルネックになれば実効速度は伸びない。速さは回線だけでなく受け渡しの設計で決まる

まとめ——NICの中では、フレーム(宛先判定とFCS)/DMAとリングバッファ(どうメモリへ載せCPUへ渡すか)/割り込みとポーリング(いつ知らせるか)/オフロード(何を肩代わりさせるか)/PHYとMAC(信号とフレームの分業)という何段もの受け渡しが連なっています。速さも、CPU負荷も、そして調査時の勘違いも、すべてこの受け渡しの上で起きている——ここまで見えれば、スイッチ・ルータ・高速サーバの通信設計は、同じ受け渡しをどこで束ね、どこへ分散するかの応用として読めるようになります。

関連する知識

理解度チェック

そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。

1. 受信時に、細切れで届いた複数のフレームをNICが1つの大きな塊へ束ねてからCPUへ渡す機能はどれ?

2. NICが受信フレームを、CPUを介さず直接メインメモリへ書き込む仕組みを英字3文字で答えてください。

3. 複数のリングバッファを用意し、フローごとに別々のCPUコアへ割り当てて受信処理を並列化する仕組みはどれ?

4. 受信のたびにNICがCPUへ割り込みをかける素朴な方式が、高負荷時にかえって性能を落とす(割り込みライブロック)根本原因はどれ?

5. TSO(TCPセグメンテーションオフロード)が肩代わりしているのは、次のどれか?

6. チェックサムオフロードを有効にしたのに、キャプチャツールで自機の送信パケットを見ると「チェックサム不正」と表示された。最も妥当な解釈はどれ?

7. イーサネットフレームの末尾に付くFCS(フレームチェックシーケンス)を、受信側NICはどう扱うか?

8. 「PHYとMACの役割分担」の説明として最も正確なのはどれ?