粗略阅读TCP/IP说明书或者内核配置可知,网络代码提供了大量的选项,虽然有用,但是不一定总是需要,如防火墙,多播一集其他功能,这些选项大多数要求在内核数据结构中附加其他字段,因此sk_buff 是被C预处理程序的#ifdef 指示附加的字段,例如,在sk_buff 定义底端附近可以发现
struct sk_buff
{
#ifdef CONFIG_NET_SCHED
__u32 tc_index;
#ifdef CONFIG_NET_CLS_ACT
__u32 tc_verd;
__u32 tc_classid;
#endif
#endif
}
这表示只有在编译期间定义了CONFIG_NET_SCHED 符号,也就是管理员或自动安装工具已经是能了某种版本的make config 的正确选项。字段tc_index 才会是此数据结构的一部分。
前述的例子实际上是两个嵌套选择,只有Qos and/or fair queueing的支持存在,CONFIG_NET_CLS_ACT 所用的的那些字段才会被引入。
顺便提一下,应该注意到Qos选项不能编译成一个模块,其原因在于内核编译后,开启该选项所得的多数结果为不可逆的,一般而言,任何引起内核数据结构改变的选项(如把tc_index字段添加到sk_buff结构),都不适合编译成一个模块。
通常会想知道make config 或者其变量的哪个编译选项和特定的#ifdef 符号相配,以了解一个代码区块什么时候会包含到内核中,在2.6 版本内核中,找出这种关联性的最快方式,就是在那些分散的代码树中的kconfig文件中寻找该符号。对2.4 版本内核而言,可以参考Decumentation/Configure.help 文件。