Cecilia*1でQoS*2の設定

iproute2を使ってpppoe*1のところでQoSに従ったパケットキューイングをさせてみる。まずはお手本どおりに。

#!/bin/bash

# 次のパラメータを、実際のダウンロード・アップロード速度より
# 少々小さくしてください (キロバイト単位)
DOWNLINK=19000
UPLINK=1100
DEV=ppp0

# 既存の下り・上りの qdisc を削除。エラーは隠す。
tc qdisc del dev $DEV root    2> /dev/null > /dev/null
tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null

###### 上り

# root HTB をインストールし、デフォルトのトラフィックを 1:20 へ:

tc qdisc add dev $DEV root handle 1: htb default 20

# あらゆる物を $UPLINK 速度の内部に収める - これは DSL モデムの
# 巨大なキューを無効にし、遅延が出ないようにします:

tc class add dev $DEV parent 1: classid 1:1 htb rate ${UPLINK}kbit burst 6k

# 高優先度クラス 1:10

tc class add dev $DEV parent 1:1 classid 1:10 htb rate ${UPLINK}kbit \
   burst 6k prio 1

# バルクおよびデフォルトのクラス 1:20。ややトラフィックが少なく、
# 優先度が低くなります

tc class add dev $DEV parent 1:1 classid 1:20 htb rate $[9*$UPLINK/10]kbit \
   burst 6k prio 2

# 両者に確率的不偏キューをあてがいます
tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10

# TOS が Minimum Delay (scp 以外の ssh) のものを 1:10 へ:
tc filter add dev $DEV parent 1:0 protocol ip prio 10 u32 \
      match ip tos 0x10 0xff  flowid 1:10

# ICMP (ip プロトコル 1) を対話的クラス 1:10 へ。
# 測定と相手への通知ができるようになります:
tc filter add dev $DEV parent 1:0 protocol ip prio 10 u32 \
	match ip protocol 1 0xff flowid 1:10

# アップロード時のダウンロードを高速化するために、ACK パケットを
# 対話的クラスへ:

tc filter add dev $DEV parent 1: protocol ip prio 10 u32 \
   match ip protocol 6 0xff \
   match u8 0x05 0x0f at 0 \
   match u16 0x0000 0xffc0 at 2 \
   match u8 0x10 0xff at 33 \
   flowid 1:10

# 残りは「非対話的」つまり「バルク」なので 1:20 へ


###### 下り
# ダウンロードを実際の速度よりも少々遅くして、ISP でのキューを
# 無効にする。調整してできるだけ大きくしてください。
# ISP は大きなサイズのダウンロードを高速化するために「巨大」な
# キューを持つことが多い
#
# 入口監視制限を追加:

tc qdisc add dev $DEV handle ffff: ingress

# 「すべて」(0.0.0.0/0) をこちらへフィルタし、速すぎるものは
# 破棄する:

tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 match ip src \
   0.0.0.0/0 police rate ${DOWNLINK}kbit burst 10k drop flowid :1

次にやることはもうひとつクラスを追加して3段階のQoSの実現。iptablesと組み合わせればもっと柔軟な振り分けができるみたいだが、httpのリンクよりscpのリンクを優先するだとかはどうやって記述すればいいのやら。

*1:PPP over Ethernet