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年12月09日 (土) 23時55分06秒 JST1