Linuxカーネルに関する技術情報を集めていくプロジェクトです。現在、Linuxカーネル2.6解読室の第2章までを公開中。
以下の話は、仮にbaaという名前のイーサドライバであるとして説明を進める。
イーサコントローラがデータの受信を行うと、割り込みが発生する。(パケット到着毎に毎回割り込みを発生させるコントローラもあるが、 受信バッファに複数のパケットが溜った時点で 割り込みを 発生させるものが一般的である。)
割り込みハンドラ(baa_interrupt関数)では受信処理(baa_receiveとか、baa_rxとかいう別の関数になっていることが多い)を行う。パケット(sk_buff)を確保し(dev_alloc_skb関数)、受信バッファから確保したパケット(sk_buff)にデータを読み込む*1。その後パケット(sk_buff)内のポインタ(dataポインタ)をイーサヘッダ分進め、イーサヘッダの情報からプロトコルタイプ(上表参照)を求める(eth_type_trans関数)。イーサパケットの形式には、通常利用されるRFC894のタイプとRFC1042のタイプがあるため、少し面倒なことをして判定している。(イーサ以外の通信路の場合でも同様の手続きでネットワーク層のプロトコルタイプを求める。)
パケット(sk_buff)の用意ができたら、netif_rx関数を呼び出す。ドライバの受信処理は以上で完了である。あとは上位プロトコルスタックが自動的に処理を行ってくれる。
netif_rx関数はパケット(sk_buff)を遅延キュー(softnet_data[]のinput_pkt_queue)に繋ぎ、後の処理はネットワーク用ソフト割り込みハンドラ(net_rx_action関数)に委ねる。遅延して呼び出されたnet_rx_action関数は、先に求めたプロトコルタイプに応じて適する上位のプロトコルスタック(IP、X25、ARPなど)にパケットを上げる(packet_typeテーブルを検索し、上位のプロトコルスタックの受信関数を呼び出す)。
高負荷などにより、受信処理におけるパケット(sk_buff)確保で失敗した場合は、受信データを破棄してしまう。(プロトコル仕様上これで問題はない。ただし、再送処理等によりネットワークに負荷をかけることになる。)
SMP環境では softnet_data[]はCPU毎に複数用意されており、各CPU上で同時に受信処理(net_rx_action関数)を行うことも可能である。
(NIS)HirokazuTakahashi
2000年12月09日 (土) 23時55分06秒 JST1
[PageInfo]
LastUpdate: 2008-08-27 14:18:34, ModifiedBy: hiromichi-m
[Permissions]
view:all, edit:login users, delete/config:members