スキップしてメイン コンテンツに移動

tc コマンドを用いて上りと下りの両方向で帯域制限を行う

tc コマンドをつかって帯域制限をかけたつもりだったのですが、シンプルな設定だと片方向(上り)しか帯域制限がかかっていませんでした。そこで調べたところ "下りに対する帯域制御は不可能" という検索結果もあったのですが、もう少ししらべたところ、ifbにリダイレクトすることで下りに対する帯域制御を適用する例と図解付きの説明がみつかりました。(ありがとうございます。)またさらに調べたところ、こちらのスクリプトをベースにしたものが最も期待に近い動作ができました。(ありがとうございます。)
早速ですが、スクリプトは以下のようにしてみました。
#!/bin/bash
SWITCH=$1        # "on" or "off"
DEVICE=$2        # "eth0", "br0", etc.
RATE=$3          # for example "1000m"

rate=`echo $RATE | sed -s 's/m//g'`000
CONFIG_HZ=250
burst=$(($rate/$CONFIG_HZ))
#limit=$(($burst*10))

#echo burst: $burst

if [ "$SWITCH" = "off" ]; then
   echo "--- Initialize $DEVICE and ifb0 ---"
   tc qdisc del dev $DEVICE ingress handle ffff:
   tc qdisc del dev ifb0 root handle 1: htb
   rmmod ifb
   rmmod act_mirred
   tc qdisc del dev $DEVICE root
fi

if [ "$SWITCH" = "on" ]; then
   echo "--- Load ifb module ---"
   modprobe ifb
   sleep 1
   ip link add dev ifb0 type ifb
   ip link set dev ifb0 up

   echo "--- Traffic Shape ${DEVICE} ---"
   tc qdisc add dev $DEVICE root handle 1: htb default 1
   tc class add dev $DEVICE parent 1: classid 1:1 htb rate ${RATE}bit ceil ${RATE}bit burst ${burst}kbit cburst ${burst}kbit

   echo "--- Mirror $DEVICE to ifb0 ---"
   modprobe act_mirred
   sleep 1
   tc qdisc add dev $DEVICE ingress handle ffff:
   tc filter add dev $DEVICE parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0
   tc filter add dev $DEVICE parent ffff: protocol ipv6 u32 match u32 0 0 flowid 1:2 action mirred egress redirect dev ifb0

   echo "--- Traffic Shape ifb0 ---"
   tc qdisc add dev ifb0 root handle 1: htb default 1
   tc class add dev ifb0 parent 1: classid 1:1 htb rate ${RATE}bit ceil ${RATE}bit burst ${burst}kbit cburst ${burst}kbit

fi

exit
スクリプト名はたとえば、/usr/local/sbin/tcap.sh (chmod +x) とすると、制限は以下のようにするとかかります。
tcap.sh off enp1s0f0	#初期化
tcap.sh on enp1s0f0 150m
制限解除(初期化)は以下のようにします。
tcap.sh off enp1s0f0
転送制限のあるサーバに対して事前に転送容量から上限のスピードをはじき出してあらかじめ制限をかけたい場合などに有効だと思います。今回は以上です。それでは。

コメント