作者:isshe
日期:2018.09.19
郵箱:[email protected]
github: https://github.com/isshe
1. 前言
接觸了TC以後,感覺就是:別說入門了,根本連門都找不到。
網上資料一大堆,但是就是看得頭痛並且一臉懵逼。
但是這篇文章並不對TC相關基礎概念進行介紹。網絡上一搜基本都是關於概念介紹
以及TC+iptables
或者TC + 單ifb
的。
這篇文章的關鍵詞:tc
、ifb
、fw
、htb
。主要希望能更靈活地實現一些流控的功能。
2. 約定及環境
環境:
- openwrt路由器
一些約定:
-
出口/入口:站在用戶的角度,對用戶而言,也就是上傳=出口,下載=入口。
一些關鍵信息: -
TC的整形一般情況下,只能對出口流量(egress)進行。
- 對於
wan口
來說:下載是ingress,上傳是egress - 對於
lan口
來說:下載是egress,上傳是ingress - 因此,常規做法是,在lan口做下載流控,在wan口做上傳流控
- 對於
3. 需求、問題及解決方案
3.1 需求
探索一個工具,通常是因爲一些需求。
最本質的需求:對入口/下載
和出口/上傳
流量中重要的
流量進行保障,提升衝浪🏄體驗。
重要與否是根據個人需求。文章中指的重要的流量:遊戲、語音通話等(流量不大並對延時要求高的流量);不重要的流量:下載等(流量大並對延時要求低的)
3.2 最終實現圖
[wan1] \ / [lan1]
[wan2]-- ifb0 ----ifb1 -- [lan2]
[wan3] / \ [lan3]
-
優點:
- 支持多lan、多wan;
- 流控內容可定製性高,可實現複雜的流控。
- 配置簡單(相比使用TC+U32+iptables)
-
缺點:
- 需要編寫流量識別模塊(識別IP?識別協議?識別應用?)
- 需要編寫內核打標記模塊。
-
這兩個模塊可以合二爲一。
3.3 遇到的問題
-
1.如何只對外網流量(lan-wan)進行控制,不對內網流量(lan-lan)進行控制?
- 很簡單,不使用常規做法,不用lan口,不對lan口做任何流控。
-
剛開始的嘗試是,對lan-lan流量進行過濾。但是最後沒有這樣實現:1.不靈活,IP識別困難,外網IP也可以當做內網IP用;2.對不關注的流量進行操作,有性能損耗。
-
2.使用wan口的話,
egress/上傳
的流控如何識別lan口的IP?egress的流量,經過nat以後,源IP不再是lan段的IP,因此無法標識具體的IP/用戶。----> ingress ---> | ---> netfilter ---> | ---> egress -------------------------------------------------------- (打mark)nat轉換 TC流控
- 解決方法是使用
fw
分類器。在netfilter的forward上掛一個自定義的模塊(如:MyMark)
,根據需求打mark,這裏可以任意發揮想象,直覺可以實現任意你想到的功能。(牛13吹起來) fw
分類器,根據mark來分類:把打了1111
標記的分類到1:10
tc filter add dev ifbx parent 1: protocol ip prio 1 handle 1111 fw flowid 1:10
- 解決方法是使用
-
3.如何做到對
上傳
和下載
都進行流控,並且不使用lan口?- 這裏用的是
ifb
;還有其他方式,但是沒細看。 -
ifb
原理就是開一些接口,把實際接口的ingress流量轉到這些ifb接口的egress上;這樣看起來會有一定的性能損耗。但是記得文檔上說,對性能影響不大。(待查實)
- 這裏用的是
-
4.如果採用打mark的形式,會遇到問題:打mark是在
netfilter
那裏,但是ingress處流控在netfilter之前,將無法使用mark?----> ingress ---> | ---> netfilter(打mark) ---> | ---> egress
- 這個人家實現ifb的時候已經考慮到了:把eth0的所有IP協議流量轉到ifb0,並把鏈接跟蹤的mark恢復到skb->mark中。
tc filter add dev eth0 parent ffff: protocol ip prio 0 u32 match u32 0 0 action connmark action mirred egress redirect dev ifb0
- 這個人家實現ifb的時候已經考慮到了:把eth0的所有IP協議流量轉到ifb0,並把鏈接跟蹤的mark恢復到skb->mark中。
-
5.如果其他程序(如mwan3)也使用了skb->mark的話,怎麼辦?
- mark是按位操作的。例如:mwan3使用0x0000-0xff00,我們就可以用
0x01xxxx-0xffxxxx(16-23位)
- 問題2中的配置可以改爲: (注意
65536/ff0000
!)-
tc filter add dev ifbx parent 1: protocol ip prio 1 handle 65536/ff0000 fw flowid 1:10
-
-
mwan3新版本貌似可以自定義mark範圍了…不過沒關係,還是可以指定。
- mark是按位操作的。例如:mwan3使用0x0000-0xff00,我們就可以用
-
6.如何實現保障?
- 用htb進行保障,同時還支持優先級。
-
注意:要預留突發帶寬。例如10Mbps,要預留1-2M作爲突發帶寬。
4. 相關文檔
- LARTC-zh_CN.GB2312_流控高級應用
- Tc-man、Htb-man等man
- TC-HOWTO
- HTB手冊