祝順民
2003 年 6 月 15 日
本文描述了linux 2.4.x內核中對QoS支持的設計與實現,并且對缺省的數據包調度機制PFIFO進行了具體的分析。
在傳統的TCP/ip網絡的路由器中,所有的IP數據包的傳輸都是采用FIFO(先進先出),盡最大努力傳輸的處理機制。在早期網絡數據量和要害業務數據不多的時候,并沒有體現出非常大的缺點,路由器簡單的把數據報丟棄來處理擁塞。但是隨著計算機網絡的發展, 數據量的急劇增長,以及多媒體,VOIP數據等對延時要求高的應用的增加。路由器簡單丟棄數據包的處理方法已經不再適合當前的網絡。單純的增加網絡帶寬也不能從根本上解決問題。所以網絡的開發者們提出了服務質量的概念。概括的說:就是針對各種不同需求,提供不同服務質量的網絡服務功能。提供QoS能力將是對未來IP網絡的基本要求。
1.Linux內核對QoS的支持
Linux內核網絡協議棧從2.2.x開始,就實現了對服務質量的支持模塊。具體的代碼位于net/sched/目錄。在Linux里面,對這個功能模塊的稱呼是Traffic Control ,簡稱TC。
首先我們了解一下Linux網絡協議棧在沒有TC模塊時發送數據包的大致流程。如圖1。注:上圖的分層是按照Linux實現來畫,并沒有嚴格遵守OSI分層
從上圖可以看出,沒有TC的情況下,每個數據包的發送都會調用dev_queue_xmit,然后判定是否需要向AF_PACKET協議支持體傳遞數據包內容,最后直接調用網卡驅動注冊的發送函數把數據包發送出去。發送數據包的機制就是本文開始講到的FIFO機制。一旦出現擁塞,協議棧只是盡自己最大的努力去調用網卡發送函數。所以這種傳統的處理方法存在著很大的弊端。
為了支持QoS,Linux的設計者在發送數據包的代碼中加入了TC模塊。從而可以對數據包進行分類,治理,檢測擁塞和處理擁塞。為了避免和以前的代碼沖突,并且讓用戶可以選擇是否使用TC。內核開發者在上圖中的兩個紅色圓圈之間添加了TC模塊。(實際上在TC模塊中,發送數據包也實現對AF_PACKET協議的支持,本文為了描述方便,把兩個地方的AF_PACKET協議處理分開來了)。
下面從具體的代碼中分析一下對TC模塊的支持。
net/core/dev.c: dev_queue_xmit函數中略了部分代碼:
int dev_queue_xmit(strUCt sk_buff *skb){………………. q = dev->qdisc; if (q->enqueue) { /*假如這個設備啟動了TC,那么把數據包壓入隊列*/ int ret = q->enqueue(skb, q); /*啟動這個設備發送*/ qdisc_run(dev); return; } if (dev->flags&IFF_UP) {…………. if (netdev_nit) dev_queue_xmit_nit(skb,dev); /*對AF_PACKET協議的支持*/ if (dev->hard_start_xmit(skb, dev) == 0) { /*調用網卡驅動發送函數發送數據包*/ return 0; } }………………}
從上面的代碼中可以看出,當q->enqueue為假的時候,就不采用TC處理,而是直接發送這個數據包。假如為真,則對這個數據包進行QoS處理。
新聞熱點
疑難解答