IPパケットのフラグメント

下位のデバイスの種類により、一度に送信可能なパケットの大きさ(フレーム長)は限界がある(MTUと呼ばれている)。

代表的なMTUの大きさを、を下表に示す。

ハードウェア MTU
イーサネット 1492 byte
FDDI 4352 byte
X.25 576 byte

上記サイズを越えるIPパケットは、IPレイヤの送信処理(ip_output関数)中で複数のパケットに分割(フラグメント化)され(ip_fragment関数)、送信される。

複数のパケットに分割(フラグメント化)されたIPパケットは、IPレイヤの受信処理(ip_local_deliver関数)中で一つのIPパケットに復元(リアセンブル)される(ip_defrag関数)。(設定によっては受信の瞬間に行うことも可能(ip_rcv関数)。ルータとしてforwarding処理を行う前に復元することにより、ネットワーク負荷を下げるという意味で効果がある場合もある)

  • ip_fragment()
    • パケット送信時、パケット長がMTUより大きい時に呼び出される。 設定されている時に呼び出される。ただしパケットの分割を 禁止されている場合(ip_dont_fragment関数)は、自分自身に ICMPメッセージを上げる(icmp_send(ICMP_DEST_UNREACH)関数)。
    • パケット長がMTU以下になるように、複数のパケットに分割する。 必要なだけ新しいパケットを確保(alloc_skb関数)し、 ヘッダとデータのコピーを行う。
    • IPヘッダfrag_offの上位フィールドにフラグメントされているか いなかの情報(IP_MF)を格納、下位フィールドに元のIPパケットに おける内部オフセットを格納。
  • ip_defrag()
    • パケット受信時、イーサヘッダfrag_off にIP_DFかoffsetが 設定されている時に呼び出される。
    • フラグメントは、復元される(はずの)IPパケット毎のキュー(ipq構造体) 毎にリンクされる。完全に復元されまで、この関数は上記キューに フラグメントをリンクし続ける。
      • タイマ(ip_expire)の起動要求。新しいフラグメントが到着する度に リセットされ再起動要求を行う。(標準では不完全なフラグメントを破棄する 時間は30秒だが、/proc/sys/net/ipfrag_timeで変更可能)
      • タイマ(ip_expire)が起動されると、不完全なフラグメントを 全て破棄する。送信元にはicmpメッセージを送り返し そのことを通知する。(icmp_send(ICMP_TIME_EXCEEDED)関数)
    • 完全なIPパケットを復元するためのフラグメントが全て揃ったら、 新しいパケット(sk_buff)を確保し、そこにフラグメントからデータを 全てコピーする(ip_glue関数)。 ipq構造体のキューおよびそこに継っているフラグメントは全て 破棄してしまう。

(NIS)HirokazuTakahashi
2000年06月11日 (日) 22時29分57秒 JST
1