Linuxの帯域制御をする
目次
この記事はQiitaに投稿していたものです。 このブログに自身のアウトプットをまとめるための再投稿です。
tcとは?
tc(8) - Linux manual page Traffic Control(tc)と呼ばれるIPパケットの送信制御機構のこと。 特定のソフトウェア/セッションの帯域を制限したりできる。(その他にも色々できるらしい)
TCのコンセプト
- Traffic Controlは送信したいパケットをschedulerと呼ばれるものに通すことで行われる。
- schedulerはキューイング規則(Queueing discipline: qdisc)とも呼ばれる。
- パケットを一時的に格納して、以下のことができる。
- 順番を並べ替え
- 遅延させる
- 破棄する
- qdiscの操作は主に2つ
- enqueue
- 送信される予定のパケットをqdiscに格納しようとする処理
- dequeue
- 格納されたパケットを取り出し、デバイスドライバに渡す処理
- enqueue
- classful qdisc
- qdiscの操作は主に2つ
- schedulerはキューイング規則(Queueing discipline: qdisc)とも呼ばれる。
- パケットを一時的に格納して、以下のことができる。
- 順番を並べ替え
- 遅延させる
- 破棄する
class(階層を持った分類)構造を持ったqdisc
- classful qdiscは内部に複数のqdiscを持っている
- classful qdiscにおいては内部でのenqueue処理が2つに分かれる
- classify : 内部にあるqdiscのどこに振り分けるかの処理
- 内部qdisc: 決めたqdiscにパケットを格納する処理
- classify
- classifyはfilterからどの内部qdiscに格納するべきかを決定する処理
- 内部qdisc
- classfulなqdiscの内部で使用されるqdisc
- class構造の葉(leaf)となる要素にはかならずqdiscが1つ付属
- classfulなqdiscの内部で使用されるqdisc
Class構造
- クラスの作り方
- クラスはidを
majorid:minorid
という書式で割り当てる。
以下のようなコマンドを打つと図のような設定がされたclassが作成される
tc qdisc del dev eth0 root
# qdiscを作成し1:にハンドルするよう設定
tc qdisc add dev eth0 root handle 1: htb default 20 # qdisc A
# 最低1000Mbit/最高1000Mbitの帯域を持つクラスを1:の子として1というclassidをつけて作成
tc class add dev eth0 parent 1: classid 1:1 htb rate 1000Mbit ceil 1000Mbit burst 10Mb cburst 10Mb # class A
# 最低200Mbit/最高200Mbitの帯域を持つクラスを1:1の子として10というclassidをつけて作成
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 200Mbit ceil 200Mbit burst 10Mb cburst 10Mb # class B
# 最低200Mbit/最高200Mbitの帯域を持つクラスを1:1の子として20というclassidをつけて作成
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 800Mbit ceil 1000Mbit burst 10Mb cburst 10Mb # # class C
# qdiscを作成し1:10にハンドルするよう設定
tc qdisc add dev eth0 parent 1:10 handle 100: pfifo limit 1000 # inner qdisc B
# qdiscを作成し1:20にハンドルするよう設定
tc qdisc add dev eth0 parent 1:20 handle 200: pfifo limit 1000 # inner qdisc C
# IPパケットがTCP、UDPなどでsource portが6379である場合1:10(ClassB)に分類する
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip sport 6379 0xffff flowid 1:10
- classifyではこの中で最も小さな番号から分類に利用しようとする
- qdisc bなどで新たなmajorid 100:と200:を与えているが大きな意味はないので、他と被らなそうな値を入れておく
- burstとcburstはそれぞれrateとceilに対応するtoken bucketのsize→計算法は以下
- 上記設定のパケットが来た際の処理の流れ
- 1:0を確認する
- 1:0はフィルターなので、設定されたルールに従ってパケットを分類する. この場合は、IPパケットがTCP、UDPなどでsource portが6379である場合1:10(ClassB)に分類する なので、もし条件に合うパケットが来た場合は1:10(ClassB)のqdiscにパケットをスタックする
- フィルターに該当しなかった場合は他にフィルターがないため、defaultで設定された1:20に分類して終了