成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

【博文推薦】Linux TC(Traffic Control)框架原理解析

開源 Linux
Linux內核內置了一個Traffic Control框架,可以實現流量限速,流量整形,策略應用(丟棄,NAT等)。從這個框架你能想到別的什么嗎?或許現在不能,但是我會先簡單說一下,和 TC框架比較相似的是Netfilter框架,但是二者卻又有很大的不同。

本博文出自51CTO博客 dog250博主,有任何問題請進入博主頁面互動討論!
博文地址:http://dog250.blog.51cto.com/2466061/1568267

近日的工作多多少少和Linux的流控有點關系,自打幾年前知道有TC這么一個玩意兒并且多多少少理解了它的原理之后,我就沒有再動過它,因為我不喜歡 TC命令行,實在是太繁瑣了,iptables命令行也比較繁瑣,但是比TC命令行直觀,而TC命令行則太過于技術化。也許是我對TC框架沒有對 Netfilter框架理解深刻吧,也許是的。iptables/Netfilter對應的就是tc/TC。

Linux內核內置了一個Traffic Control框架,可以實現流量限速,流量整形,策略應用(丟棄,NAT等)。從這個框架你能想到別的什么嗎?或許現在不能,但是我會先簡單說一下,和 TC框架比較相似的是Netfilter框架,但是二者卻又有很大的不同。

在精通了Netfilter框架之后,再來體會TC框架會簡單得多,特別是,當你覺得Netfilter具有這樣那樣的局限時,帶著這些問題去體會TC框架的設計,你可能會發現,TC在某些方面彌補了Netfilter的不足。在具體深入到細節前,我先來介紹一下二者的相同點以及因其初衷不同而導致設計的大相徑庭。

先說Netfilter,無疑這個框架被設計用來在網絡協議棧的內核路徑上過濾數據包,就像在一條路上的關卡一樣,Netfilter在協議棧處理網絡數據包的路徑上的5個位置設置了這樣的關卡,一個數據包在被處理的路徑上經過這些關卡被檢查,結果就是若干個動作:接受,丟棄,排隊,導入其它路徑等,框架只需針對一個數據包得出一個結果即可,關卡內部提供什么服務在Netfilter框架中并沒有任何規定。

現在我們看TC,它旨在對數據包或者數據流提供一種服務,比如限速,整形等,而這并不是一個類似Netfilter的結果可以表達的,提供這些服務需要執行一系列的動作,因此如何來“規劃和組織這些動作的執行”是TC框架設計的關鍵!也就是說,TC框架關注的是如何執行而不是僅僅想要得到一個要執行的動作。換句話說,Netfilter框架關鍵做什么,而TC框架關注怎么做。(關于Netfilter我已經寫了大量的代碼和文章,不再贅述了...)

有關限速,流量整形方面的理論已經很多了,比較常見的比如使用令牌桶,但是本文關注的是Linux對TC框架的實現而不是令牌桶算法相關的內容,然而在一篇短文中又不可能詳細描述從流量控制理論到各種操作系統版本實現的歷史,但是我們知道,使用隊列是大多數實現中實際的選擇,那么現在問題來了,Linux 的TC框架是如何組織隊列的。在詳細深入討論隊列組織之前,我最后一次比較一下Netfilter和TC。

如果你知道UNIX的字符設備和塊設備之間的區別,那么理解Netfilter框架和TC框架之間的區別就比較容易了。Netfilter的一個HOOK 點類似一個管道字符設備,而skb就是這個設備中的單向字符流,一般都是按照從一端流入,然后按照進入的順序從另一端流出,附帶一個結果,比如 ACCEPT,DROP等。而TC框架比較類似一個塊設備,對內容進行隨機存儲和隨機訪問,即skb進入的順序并不一定是skb出來的順序,而這正是流量整形需要做的。也就是說,TC框架必須實現一個隨機訪問的數據包存儲緩沖區,在這個緩沖區中進行流量控制,當然,我們已經知道,這是由隊列實現的。

當然,任何事情都不是絕對的,Netfilter的一個HOOK點也可以有存儲緩沖區或者執行一系列的動作,典型的就是conntrack中的分片重組以及NAT功能,對于PREROUTING這個HOOK點的分片重組,無疑對于分片而言,只是進入HOOK,暫時保存在里面,直到所有分片都來了切重組成功后才一次性流出這個HOOK點,而對于NAT而言,Netfilter的處理結果無疑是“執行了一系列的動作”而不僅僅是ACCEPT。此外,我也寫過一些模塊,用Netfilter來實現流量控制,反過來,TC框架也可以實現Netfilter的功能,總之,當你理解了這些框架的設計原則以及其本質后,在使用和擴展上,你就可以庖丁解牛,游刃有余了。

個人覺得,對于單獨的一個Netfilter HOOK點,TC框架是其超集,實現上更加靈活,當然也就更加復雜。Netfilter所擁有的TC不具備的魅力在于其HOOK點位置的定義。

好了,現在開始正式介紹TC框架的設計。

很多網上搜到的資料在介紹TC的時候,無一例外地介紹了TC是由“隊列規程,類別,過濾器”三者組成的,大多數含糊不清,我敢說這些都是出自一篇文檔或者一本書。很少有人從另外一個角度去理解TC框架的設計,而這本身就是一個比較有挑戰性的事,我個人比較喜歡這種事情。在介紹TC的隊列組織之前,我先來介紹一下什么叫作遞歸控制,所謂的遞歸控制就是分層次地控制,而對于每個層次,控制方式都是一致的。熟悉CFS調度的都知道,對于組調度和task調度都采用了完全相同的調度方式,然而顯然組和task是屬于不同層次的,我畫了下面一張圖來簡單描述這種情況:

不光是控制邏輯的組織,就連Linux在實現UNIX進程模型時,也采用了這種樹形的遞歸控制邏輯,每一個層次都是一個兩層的樹,下圖展示了這個模型:

wKiom1RNDBuiCM5hAAFp6zJIm3c574.jpg

可以看出,遞歸控制是分形的,如果能用立體的圖展示會更好些,對于上圖而言,除了葉子節點之外的每一個節點都是一顆獨立的小樹,不管是大樹還是小樹,對于控制邏輯或者組織邏輯而言,其性質是完全一樣的。

遞歸的控制便于控制邏輯的任意疊加,這個我們在協議棧的設計中看到過,比如X over Y,簡稱XoY,比如PPPoE,IP over UDP(tun模式的OpenVPN),TCP over IP(原生的TCP/IP棧)...對于TC而言,考慮下面一個需求:

1.將整個帶寬按照2:3的比例分給TCP和UDP;

2.在TCP流量中,按照源IP地址段將其劃分為不同的優先級;

3.在相同的優先級隊列中,按照2:8的比例將帶寬分給HTTP應用和其它;

4....

從以上需求可以看出,這是一個遞歸控制的需求,其中1和3均使用了帶寬比例分配,但是顯而易見,這是屬于不同層次的。整個架構看起來應該是下面這個樣子:

wKioL1RNDFiCUiHlAANeTGKgt4A809.jpg

但是事情遠非想象的那個單純,雖然上面的圖已經讓你看出了TC框架的端倪,然而對于實現它卻沒有一點幫助。幾個典型的問題擺在那里,你怎么甄別數據包到不同的隊列,圖中的非葉子節點要呈現成什么數據結構,既然不是真正的隊列卻又要有隊列的行為,那么如何表達它們?...

Linux在實現TC的時候,對“隊列”進行了抽象,基本上它維護了兩個回調函數指針,一個是enqueue入隊操作,一個是dequeue出隊操作。不管是enqueue還是dequeue,都并不一定真正將數據包排入隊列,而僅僅是“執行一系列的操作”。這個“執行一系列的操作”可以是:

1.對于葉子節點,真正排入一個真實的隊列或者從真正的隊列拉出一個數據包;

2.遞歸調用其它抽象隊列的enqueue/dequeue。

注意上面的第2點,提到了“其它抽象隊列”,那么如何來定位這個抽象隊列呢?這就需要一個抉擇,也就是一個選擇器,根據數據包的特征來將數據包歸入一個抽象隊列,這個時候,TC的設計框圖可以用下圖來表達:

wKiom1RNC_aQyP2VAAWvbHAakTQ531.jpg 

可以看到,我并沒有用那個經典的“隊列規程,類別,過濾器”三元組來定義TC框架,而是用一種遞歸控制的意義來解釋。如果用經典三元組來套在這幅圖上,就會是下面這個樣子,注意,我刪去了不必要的文字,這樣圖不至于太過混亂,需要文字的請參考上圖

wKioL1RNDDWT6o5NAAT0OWwNOYo271.jpg 

可見,萬變不離其衷或者說英雄所見略同。

好了,現在說點題外話,還是和Netfilter有關的,當然不是它和TC的比較,而是我個人的一點想法。曾幾何時,我十分推崇Cisco的ACL,應為它們是應用于網卡接口的,而Netfilter則是攔截在處理路徑上而不是處理設備上,對于Netfilter而言,處理設備只是一個毫無特殊之處的 match,不管有無關系,所有的數據包均要經過Netfilter HOOK點的抉擇,起碼你要判斷它是否匹配-i ethX...我想在net_device上掛一個filter_list,也寫過一些代碼,發現效果比較好,準備采用。我是一個經常重復造輪子的人,當我后來看了TC的實現后,發現TC框架正是我想要找的,于是我放言,能用Netfilter實現的,用TC也一樣能實現。并且,TC基于隊列規程(數據結構字段正是這么寫,Qdisc-queue discipline,這并非受經典三元組表達法的影響)的,抽象的入隊/出隊并沒有規定如何實現,且隊列規程和網卡綁定(更精確地說是網卡的隊列-如果網卡支持多隊列的話)而不是攔截在處理路徑上。于是我有兩種選擇:

1.實現一個新的Qdisc,其內置一個簡單的FIFO隊列,enqueue操作進行從Netfilter移植過來的matches/target,所有ACCEPT的數據包排入FIFO;

2.在分類器上做文章,是否將數據包歸于一個類別不光要看數據包的特征,還要額外執行一個action回調函數,只有該函數返回0才代表成功,而既然作為回調,你便可以在其中進行任何action(drop,nat等),關起門來lualu。

以上1和2中,第2點已經實現了,第一點很容易實現,你只需要實現一個隊列規程即可,或者說為每一個隊列規程都加一個action,看上去如下圖所示:

對于第2點,比較簡單,其本質就是在那個菱形中做文章,放大后的菱形如下圖所示:

 

這樣就用TC框架實現了防火墻的功能以及NAT的功能,這是我一直以來的愿望。其實我早就知道這件事,只是我不太喜歡TC的命令,因為它配置起來太技術化了,維護起來極其困難,甚至比iptables規則維護起來都困難,而維護是超級重要的,它甚至比你想到如何書寫這個規則更重要,因為如何書寫是一瞬間的事,如果你有足夠的積累,那么一瞬間你就能搞定,如果你碰到了難題,敢說靈感的顯現也是一瞬間的,比如酒后,但是維護卻是長久的事,且維護的人不一定是你自己,你必須要為別人考慮,因為技術社會是利他的社會。

好了,到此為止,相信我已經把該說的都說了,都是框架性的,沒有任何細節在里面,雖然不太喜歡TC命令行,但是我還是希望最后用一幅圖展示一下每一條TC命令和內核數據結構的關系,依然是沒有細節,命令也不全,省略了match,因為我知道那些不重要:

 

看我的文章,你可能很難得到那種復制了之后直接粘貼上就能用的東西,代碼省略了,命令省略了,就算是我自己,在看到自己多年前寫的東西時,十分想快速運行點什么,但是沒有這樣的東西。可是我覺得,思想大于實現,如果你理解了實現背后或者現實背后的本質,那么你就會得心應手,游刃有余。

責任編輯:林師授 來源: 51CTO
相關推薦

2015-06-04 11:17:12

2015-05-15 10:04:28

localhost

2015-04-17 11:15:01

Windows Azu虛擬機SCVMM

2018-11-01 09:46:02

推薦系統架構

2009-10-27 11:16:20

VB.NET應用框架

2015-06-17 09:34:09

軟件定義存儲 云存儲

2015-07-01 10:25:07

Docker開源項目容器

2015-04-22 10:28:40

2014-12-12 10:46:55

Azure地緣組affinitygro

2023-02-28 09:07:18

ChatGPTAI

2015-06-15 13:06:23

項目項目經驗

2015-09-29 10:26:51

pythonlogging模塊

2015-05-05 15:32:59

linux遠程訪問windows

2015-05-13 11:12:19

Linux企業運維技巧

2023-12-26 08:08:02

Spring事務MySQL

2015-03-16 10:26:59

2015-04-28 17:16:12

Linux遠程登錄詳細配置

2014-12-01 10:33:51

Python

2015-04-21 09:28:58

ockerdocker監控平臺監控

2015-07-29 13:46:27

OpenStackIcehouse私有云實戰部署
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91热爆在线观看 | 综合久久色 | 男人的天堂久久 | 一级在线免费观看 | 欧美日韩久久 | 国产在线第一页 | 亚洲经典一区 | 日韩不卡一区二区三区 | xx视频在线 | 天天夜干 | 在线成人www免费观看视频 | 久久久精品综合 | 91深夜福利视频 | 91精品国产综合久久精品 | 国产成人精品视频在线观看 | 日韩精品在线视频免费观看 | 尤物视频在线免费观看 | 亚洲成人精品视频 | 中文在线一区二区 | 午夜影院黄 | 91久久精品一区二区二区 | 成人不卡| 国产视频精品区 | 国产精品区二区三区日本 | 久久久久久99 | 日本精品一区 | 中文字幕日本一区二区 | 狠狠狠干 | 亚洲午夜精品视频 | 91在线视频播放 | 男女免费观看在线爽爽爽视频 | 欧美极品少妇xxxxⅹ免费视频 | 久久精品日产第一区二区三区 | 免费看a| 91精品国产乱码久久蜜臀 | 一区在线观看 | 国产视频一区二区 | 亚洲国产一区在线 | 久久人人网 | 蜜臀网| 蜜桃在线播放 |