它表明,tc_index只有在編譯時定義了CONFIG_NET_SCHED符號才有效。這個符號可以通過選擇特定的編譯選項來定義(例如:"Device Drivers Networking supportNetworking options QoS and/or fair queueing")。這些編譯選項可以由管理員通過make config來選擇,或者通過壹些自動安裝工具來選擇。前面的例子有兩個嵌套的選項:CONFIG_NET_CLS_ACT(包分類器)只有在選擇支持“QoS and/or fair queueing”時才能生效。順便提壹下,QoS選項不能被編譯成內核模塊。原因就是,內核編譯之後,由某個選項所控制的數據結構是不能動態變化的。壹般來說,如果某個選項會修改內核數據結構(比如說,在sk_buff
裏面增加壹個項tc_index),那麽,包含這個選項的組件就不能被編譯成內核模塊。妳可能經常需要查找是哪個make config編譯選項或者變種定義了某個#ifdef標記,以便理解內核中包含的某段代碼。在2.6內核中,最快的,查找它們之間關聯關系的方法,就是查找分布在內核源代碼樹中的kconfig文件中是否定義了相應的符號(每個目錄都有壹個這樣的文件)。在
2.4內核中,妳需要查看Documentation/Configure.help文件。2. Layout Fields有些sk_buff成員變量的作用是方便查找或者是連接數據結構本身。內核可以把sk_buff組織成壹個雙向鏈表。當然,這個鏈表的結構要比常見的雙向鏈表的結構復雜壹點。就像任何壹個雙向鏈表壹樣,sk_buff中有兩個指針next和prev,其中,next指向下壹個節點,而
prev指向上壹個節點。但是,這個鏈表還有另壹個需求:每個sk_buff結構都必須能夠很快找到鏈表頭節點。為了滿足這個需求,在第壹個節點前面會插入另壹個結構sk_buff_head,這是壹個輔助節點,它的定義如下:struct sk_buff_head { struct sk_buff * next; struct sk_buff * prev; _ _u32 qlen; spinlock_t lock; }; qlen代表鏈表元素的個數。lock用於防止對鏈表的並發訪問。sk_buff和sk_buff_head的前兩個元素是壹樣的:next和prev指針。這使得它們可以放到同壹個鏈表中,盡管sk_buff_head要比sk_buff小得多。另外,相同的函數可以同樣應用於sk_buff和sk_buff_head。為了使這個數據結構更靈活,每個sk_buff結構都包含壹個指向sk_buff_head的指針。這個指針的名字是list。圖1會幫助妳理解它們之間的關系。Figure 1. List of sk_buff elements