LoginSignup
8
7

More than 5 years have passed since last update.

sk_buff transport_header の変遷

Last updated at Posted at 2016-04-22

struct skbuff は Linux Kernel networking code で最も利用される構造体の1つで、include/linux/skbuff.h に定義されています。

「最も利用される」ため、コピー時のオーバーヘッド削減など様々な改良が継続的に加えられているため、メンバー変数の型や名前も大いに変遷しています。

そのうちの各レイヤのヘッダの場所を示す変数の変遷を調べたのでメモ。

v2.6.0 ~ v2.6.21

    union {
        struct tcphdr   *th;
        struct udphdr   *uh;
        struct icmphdr  *icmph;
        struct igmphdr  *igmph;
        struct iphdr    *ipiph;
        struct ipv6hdr  *ipv6h;
        unsigned char   *raw;
    } h;

    union {
        struct iphdr    *iph;
        struct ipv6hdr  *ipv6h;
        struct arphdr   *arph;
        unsigned char   *raw;
    } nh;

    union {
        unsigned char   *raw;
    } mac;

この時代は各レイヤ事にヘッダへのポインタが union されていました。
実は v2.6.21 ~ v2.6.22 の間はいきなり変更されたのではなく、いくつもの commit により少しずつunion内のメンバーが減っていき、最終的に *raw だけになり、v2.6.22 以降の sk_buff_data_t になるという変遷をたどっています。
全てを列挙するのはあきらめましたので一部だけご紹介します。

ここまでで union { ... } hn; のメンバーは *raw 1つになります。

    union {
 -      struct ipv6hdr  *ipv6h;
        unsigned char   *raw;
    } nh;
  • [SK_BUFF]: unions of just one member don't get anything done, kill them
    • b0e380b1d8a8e0aca215df97702f99815f05c094
    • Renaming skb->h to skb->transport_header, skb->nh to skb->network_header and skb->mac to skb->mac_header, to match the names of the associated helpers (skb[[re]set]{transport,network,mac}_header)

ここで union から unsigned char となり、名前も変更されます。

 -  union {
 -      unsigned char   *raw;
 -  } h;
 -
 -  union {
 -      unsigned char   *raw;
 -  } nh;
 -
 -  union {
 -      unsigned char   *raw;
 -  } mac;
 -
 +  unsigned char       *transport_header;
 +  unsigned char       *network_header;
 +  unsigned char       *mac_header;

v2.6.22 ~ v2.6.39 (last v2.6.x), v3.0 ~ v3.10

#ifdef NET_SKBUFF_DATA_USES_OFFSET
typedef unsigned int sk_buff_data_t;
#else
typedef unsigned char *sk_buff_data_t;
#endif

    sk_buff_data_t      transport_header;
    sk_buff_data_t      network_header;
    sk_buff_data_t      mac_header;

このバージョンではポインタではなくオフセットを使うようになります。
NET_SKBUFF_DATA_USES_OFFSET が定義されていない場合は従来通り char ポインタになります。)

 -  unsigned char       *transport_header;
 -  unsigned char       *network_header;
 -  unsigned char       *mac_header;
 +  sk_buff_data_t      transport_header;
 +  sk_buff_data_t      network_header;
 +  sk_buff_data_t      mac_header;

v3.11 ~ v3.19, v4.0 ~ v4.5 (last v4.x as of 2016/04/22)

    __u16           transport_header;
    __u16           network_header;
    __u16           mac_header;

現在は sk_buff構造体のサイズを小さくするために、sk_buff_data_t ではなく、__u16 を使用しています。

  • net: Use 16bits for *_headers fields of struct skbuff
 -  sk_buff_data_t      inner_transport_header;
 -  sk_buff_data_t      inner_network_header;
 -  sk_buff_data_t      inner_mac_header;
 -  sk_buff_data_t      transport_header;
 -  sk_buff_data_t      network_header;
 -  sk_buff_data_t      mac_header;
 +  __u16           inner_transport_header;
 +  __u16           inner_network_header;
 +  __u16           inner_mac_header;
 +  __u16           transport_header;
 +  __u16           network_header;
 +  __u16           mac_header;

参考リンク

変更が行われたコミットを発見するために以下手順で進めました。

$ git log v2.6.21 | head -1
commit de46c33745f5e2ad594c72f2cf5f490861b16ce1
$ git log v2.6.22 | head -1
commit 7dcca30a32aadb0520417521b0c44f42d09fe05c
$ git log 94a05509a9e11806acd797153d03019706e466f1 7dcca30a32aadb0520417521b0c44f42d09fe05c > ../tools/git-log-v2.6.21-22.log

2016/04/22 追記
コミット番号だけでなく、以下例のようにv2.6.11, v3.14等のTag名でもファイルを確認する事が可能です。

https://github.com/torvalds/linux/blame/<tag>/include/linux/skbuff.h
https://github.com/torvalds/linux/blame/v3.14/include/linux/skbuff.h

また、Twitter: @hiroysato さんにご紹介頂いた以下リンクを参考にしました。ありがとうございました。

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7