Linux 工具 | 第1篇:高級流控-TC+HTB+IFB+內核模塊

作者:isshe
日期:2018.09.19
郵箱:[email protected]
github: https://github.com/isshe

1. 前言

接觸了TC以後,感覺就是:別說入門了,根本連門都找不到。
網上資料一大堆,但是就是看得頭痛並且一臉懵逼。
但是這篇文章並不對TC相關基礎概念進行介紹。網絡上一搜基本都是關於概念介紹以及TC+iptables或者TC + 單ifb的。
這篇文章的關鍵詞:tcifbfwhtb。主要希望能更靈活地實現一些流控的功能。

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

  • 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範圍了…不過沒關係,還是可以指定。

  • 6.如何實現保障?

    • 用htb進行保障,同時還支持優先級。
    • 注意:要預留突發帶寬。例如10Mbps,要預留1-2M作爲突發帶寬。

4. 相關文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章