ア | イ | ウ | エ | オ |
カ | キ | ク | ケ | コ |
サ | シ | ス | セ | ソ |
タ | チ | ツ | テ | ト |
ナ | ニ | ヌ | ネ | ノ |
ハ | ヒ | フ | ヘ | ホ |
マ | ミ | ム | メ | モ |
ヤ | ユ | ヨ | ||
ラ | リ | ル | レ | ロ |
ワ | ヰ | ヴ | ヱ | ヲ |
ン |
A | B | C | D | E |
F | G | H | I | J |
K | L | M | N | O |
P | Q | R | S | T |
U | V | W | X | Y |
Z | 数字 | 記号 |
BSDがカーネル内で用いるデータ構造。主としてネットワークパケットの処理に用いられる。
mbufは、簡潔に述べればネットワークのデータを格納するバッファーのことである。
TCP/IPを例にすれば、ネットワークからパケットを受信した場合、Ethernet→IP→TCPの順に、処理を遷移する。上位の層に到達するまでに、ヘッダーの除去や、断片化されたパケットの再構築、あるいはパケット順序の入れ替えなどの作業が必要となる。逆に送信する場合は、下の層に移る度に、ヘッダーの付加や、データの分割などが必要になる。
通常の方法であれば、こういった作業は効率面で問題がある。何度もバッファーを確保してデータを複写したり、不要になったバッファーを解放したりせねばならない。
しかしmbufは連結リストなので、バッファの再確保やデータのコピーをすることなく、データの前、中、後、好きな場所に、ヘッダーや断片化されたパケットの一部を付加ないし挿入することが可能である。
ネットワーク処理を効率的に行なう方法として、BSDではmbufが使われている。
sys/mbuf.hで、mbuf構造体が定義されている。
mbuf構造体はヘッダー部分とデータ部分に分かれているが、その合計サイズは固定長である。CではMSIZEとして定義され、MSIZEはFreeBSDならsys/param.hで定義があり、FreeBSD 8.0なら256バイトである。環境によって変わり、128バイトなどの環境もあるようである。
mbufの機構がややこしいため、BSDスタックのソース解読は最初はとっつきにくいが、使っていないLinuxのそれと比べて大幅に簡潔かつ読みやすいものになっている。
TCP/IPに依存したLinuxの実装と更に比較すると、TCP/IPの速度などの性能は当然Linuxの方が上ということになるが代わりに汎用性がなく、一方のmbufは効率を若干犠牲にする代わりに汎用性が高く、このためTCP/IPとは無関係の通信処理(例えばBluetoothの処理など)にも使われている。
具体的な内容については後で説明されるが、ヘッダーにおける構造体の定義は次の通りである。
struct mbuf { struct m_hdr m_hdr; union { struct { struct pkthdr MH_pkthdr; /* M_PKTHDR set */ union { struct m_ext MH_ext; /* M_EXT set */ char MH_databuf[MHLEN]; } MH_dat; } MH; char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */ } M_dat; };
上述のように、ヘッダー部分とデータ部分に分かれ、データ部分は何重かのunionで同じ領域を共用化している。
プリプロセッサーシンボルは、次のように定義されている。
#define MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */ #define MHLEN (MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */
以上はsys/mbuf.h内、次がsys/param.h内。
#ifndef MSIZE #define MSIZE 256 /* size of an mbuf */ #endif /* MSIZE */
かくして、一つのstruct mbufは256バイトの固定長となっている。
struct m_hdr構造体には、二つのmbuf構造体へのポインターがある。
この他、次の変数を含む。
mbufは単なるバッファーとしてだけでなく、経路制御表などの構成にも使われるため、mbufの使われ方をmh_typeとmh_flagsで表わす。
padは8バイト(64ビット)アラインメントのためのパディングであり、データ型モデルによってサイズが変わる。
#if defined(__LP64__) #define M_HDR_PAD 6 #else #define M_HDR_PAD 2 #endif
__LP64__が定義されるLP64時は構造体のサイズを40バイトに、それ以外(ILP32を想定)時は構造体のサイズを24バイトにすることで、これに続くデータ部は64ビット境界に配置される。
mbufデータ部は、MSIZEバイトからヘッダーの長さを引いた分となり、共用体となっているため、次の三種類の使い方ができる。
mbufでは、多様な関数とマクロが定義されている。関数は/usr/src/sys/kern/uipc_mbuf.cに実体があり、マクロはsys/mbuf.hで定義される。
よく使われるものを以下に説明する(順不同)。
コメントなどを投稿するフォームは、日本語対応時のみ表示されます