История изменений
Исправление Pinkbyte, (текущая версия) :
Тогда почему у меня по дефолту на физических интерфейсах fq_codel, а на бридже — noqueue? Это баг в инитскриптах OpenWRT?
Нет, это фича скриптов openwrt. Как я уже говорил - если не надо шейпить отдельные интерфейсы - лучше делать так. В OpenWRT видать считают что так нужно. Имеют полное право.
но для общего развития — можно на это посмотреть?
Примерно так:
iptables -t mangle -vn -L
Chain PREROUTING (policy ACCEPT 14M packets, 6620M bytes)
pkts bytes target prot opt in out source destination
12M 6333M FROM_INET all -- ppp999 * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 1389K packets, 1242M bytes)
pkts bytes target prot opt in out source destination
16075 843K TCPMSS tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:0x06/0x02 TCPMSS clamp to PMTU
881K 1212M FROM_INET all -- ppp999 * 0.0.0.0/0 0.0.0.0/0
506K 29M TO_INET all -- * ppp999 0.0.0.0/0 0.0.0.0/0
Chain POSTROUTING (policy ACCEPT 15M packets, 11G bytes)
pkts bytes target prot opt in out source destination
13M 8056M TO_INET all -- * ppp999 0.0.0.0/0 0.0.0.0/0
Chain FROM_INET (2 references)
pkts bytes target prot opt in out source destination
20055 2200K MARK icmp -- * * 0.0.0.0/0 0.0.0.0/0 MARK set 0xb
4835 670K MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 MARK set 0xb
0 0 MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:22 MARK set 0xb
Chain TO_INET (2 references)
pkts bytes target prot opt in out source destination
8394 918K MARK icmp -- * * 0.0.0.0/0 0.0.0.0/0 MARK set 0x15
0 0 MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 MARK set 0x15
6420 780K MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:22 MARK set 0x15
Приведены только основные записи, чтобы было примерно понятно о чём речь. Заметь, что маркировка делается дважды.
Идем дальше. В /etc/conf.d/net(гента же) есть следующий кусок:
postup() {
if [ "${IFACE}" = ppp999 ]; then
tc qdisc del dev ${IFACE} root &>/dev/null
tc qdisc add dev ${IFACE} root handle 1: prio
tc filter add dev ${IFACE} parent 1: prio 10 protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb1
tc qdisc del dev ${IFACE} ingress &>/dev/null
tc qdisc add dev ${IFACE} ingress handle ffff:
tc filter add dev ${IFACE} parent ffff: prio 10 protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0
fi
if [ "${IFACE}" = tunv6 ]; then
tc qdisc del dev ${IFACE} root &>/dev/null
tc qdisc add dev ${IFACE} root handle 1: prio
tc filter add dev ${IFACE} parent 1: prio 20 protocol ipv6 u32 match u32 0 0 action mirred egress redirect dev ifb1
# TODO: ingress qdisc may not work for some reason, remove it if problems occur
tc qdisc del dev ${IFACE} ingress &>/dev/null
tc qdisc add dev ${IFACE} ingress handle ffff:
tc filter add dev ${IFACE} parent ffff: prio 20 protocol ipv6 u32 match u32 0 0 action mirred egress redirect dev ifb0
fi
if [ "${IFACE}" = br0 -o "${IFACE}" = vlan2 ]; then
tc qdisc del dev ${IFACE} root &>/dev/null
tc qdisc add dev ${IFACE} root handle 1: prio
tc filter add dev ${IFACE} parent 1:0 prio 10 protocol ip handle 100 fw action mirred egress redirect dev ifb0
tc filter add dev ${IFACE} parent 1:0 prio 20 protocol ipv6 handle 100 fw action mirred egress redirect dev ifb0
fi
}
ifb0 отвечает за шейпинг входящего трафика, ifb1 - исходящего. Но так как я уже упомянул, что шейпить надо в том числе трафик, входящий на сам роутер, а от IMQ пришлось отказаться - имеем вот такой вот геморрой.
Дальше - веселее :-). Сам шейпер:
# Variables that control script parameters
MAIN_IFACE="ifb0"
OUT_IFACE="ifb1"
BAND="7Mbit"
HIGH_LIMIT="6Mbit"
# Simple shaper for outgoing traffic (device ${OUT_IFACE})
tc qdisc del dev ${OUT_IFACE} root &>/dev/null
tc qdisc add dev ${OUT_IFACE} root handle 1: prio
# add some qdisc to high priority traffic
tc qdisc add dev ${OUT_IFACE} parent 1:1 handle 10: sfq
# Properly marked traffic is high-priority
tc filter add dev ${OUT_IFACE} parent 1:0 prio 1 protocol ip \
handle 21 fw \
flowid 1:1
# Properly marked IPv6 traffic is high-priority
tc filter add dev ${OUT_IFACE} parent 1:0 prio 2 protocol ipv6 \
handle 21 fw \
flowid 1:1
# Other traffic is lowest-priority
tc filter add dev ${OUT_IFACE} parent 1:0 prio 100 protocol ip u32 match u32 0 0 flowid 1:3
# Other traffic(IPv6) is lowest-priority
tc filter add dev ${OUT_IFACE} parent 1:0 prio 200 protocol ipv6 u32 match u32 0 0 flowid 1:3
# Shaper for incoming traffic
tc qdisc del dev ${MAIN_IFACE} root handle 1: hfsc &>/dev/null
tc qdisc add dev ${MAIN_IFACE} root handle 1: hfsc
# Internet traffic (full MAXIMUM speed)
tc class add dev ${MAIN_IFACE} parent 1:0 classid 1:1 hfsc sc rate ${BAND} ul rate ${BAND}
# Dummy subclass for delayed shaping
tc class add dev ${MAIN_IFACE} parent 1:0 classid 1:100 hfsc sc rate 1Gbit ul rate 1Gbit
# Subclasses of Internet traffic
tc class add dev ${MAIN_IFACE} parent 1:1 classid 1:10 hfsc rt umax 1500 dmax 2ms rate 1Mbit ls rate ${HIGH_LIMIT}
tc class add dev ${MAIN_IFACE} parent 1:1 classid 1:11 hfsc ls rate 1Mbit
# SFQ Disciplines traffic with filter based on destination IP (fair use)
# for high-priority traffic
tc qdisc add dev ${MAIN_IFACE} parent 1:10 handle 10: sfq
tc filter add dev ${MAIN_IFACE} parent 10: protocol ip handle 1 flow hash keys nfct-dst divisor 256 baseclass 1:10
# for low-priority traffic
tc qdisc add dev ${MAIN_IFACE} parent 1:11 handle 11: sfq
tc filter add dev ${MAIN_IFACE} parent 11: protocol ip handle 1 flow hash keys nfct-dst divisor 256 baseclass 1:11
# end of SFQ Disciplines
# qdisc for dummy subclass
tc qdisc add dev ${MAIN_IFACE} parent 1:100 handle 100: pfifo limit 1000
# Properly marked traffic is high-priority
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 2 protocol ip \
handle 11 fw \
flowid 1:10
# Properly marked IPv6 traffic is high-priority
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 3 protocol ipv6 \
handle 11 fw \
flowid 1:10
# Not input traffic and not classified valid as FORWARD traffic - it should be low priority
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 90 protocol ip \
handle 100 fw \
flowid 1:11
# Not input IPv6 traffic and not classified valid as FORWARD traffic - it should be low priority
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 100 protocol ipv6 \
handle 200 fw \
flowid 1:11
# Not input traffic, shape it AGAIN later
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 2000 protocol ip u32 \
match u32 0 0 \
flowid 1:100 \
action xt -j MARK --set-mark 100 &>/dev/null
# Not input IPv6 traffic, shape it AGAIN later
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 1000 protocol ipv6 u32 \
match u32 0 0 \
flowid 1:100 \
action xt -j MARK --set-mark 200 &>/dev/null
Когда я это дописывал, я уже сам не верил, что эта сотона заработает
Кусок из ip6tables не привожу - там всё примерно аналогично.
Схема сети следующая:
2 VLAN-а(для проводной сети и wi-fi). vlan1(проводной) включен в мост(br0) - для виртуальных машин и контейнеров. Интернет поступает посредством PPPoE-соединения - ppp999. Поверх него - IPv6-туннель до Hurricane Electric. IPv6 в локалке поднят как на проводном VLAN-е, так и на беспроводном. Шейпить надо, как понимаешь и IPv4 и IPv6.
Исходная версия Pinkbyte, :
Тогда почему у меня по дефолту на физических интерфейсах fq_codel, а на бридже — noqueue? Это баг в инитскриптах OpenWRT?
Нет, это фича скриптов openwrt. Как я уже говорил - если не надо шейпить отдельные интерфейсы - лучше делать так. В OpenWRT видать считают что так нужно. Имеют полное право.
но для общего развития — можно на это посмотреть?
Примерно так:
iptables -t mangle -vn -L
Chain PREROUTING (policy ACCEPT 14M packets, 6620M bytes)
pkts bytes target prot opt in out source destination
12M 6333M FROM_INET all -- ppp999 * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 1389K packets, 1242M bytes)
pkts bytes target prot opt in out source destination
16075 843K TCPMSS tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:0x06/0x02 TCPMSS clamp to PMTU
881K 1212M FROM_INET all -- ppp999 * 0.0.0.0/0 0.0.0.0/0
506K 29M TO_INET all -- * ppp999 0.0.0.0/0 0.0.0.0/0
Chain POSTROUTING (policy ACCEPT 15M packets, 11G bytes)
pkts bytes target prot opt in out source destination
13M 8056M TO_INET all -- * ppp999 0.0.0.0/0 0.0.0.0/0
Chain FROM_INET (2 references)
pkts bytes target prot opt in out source destination
20055 2200K MARK icmp -- * * 0.0.0.0/0 0.0.0.0/0 MARK set 0xb
4835 670K MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 MARK set 0xb
0 0 MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:22 MARK set 0xb
Chain TO_INET (2 references)
pkts bytes target prot opt in out source destination
8394 918K MARK icmp -- * * 0.0.0.0/0 0.0.0.0/0 MARK set 0x15
0 0 MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 MARK set 0x15
6420 780K MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:22 MARK set 0x15
Приведены только основные записи, чтобы было примерно понятно о чём речь. Заметь, что маркировка делается дважды.
Идем дальше. В /etc/conf.d/net(гента же) есть следующий кусок:
postup() {
if [ "${IFACE}" = ppp999 ]; then
tc qdisc del dev ${IFACE} root &>/dev/null
tc qdisc add dev ${IFACE} root handle 1: prio
tc filter add dev ${IFACE} parent 1: prio 10 protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb1
tc qdisc del dev ${IFACE} ingress &>/dev/null
tc qdisc add dev ${IFACE} ingress handle ffff:
tc filter add dev ${IFACE} parent ffff: prio 10 protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0
fi
if [ "${IFACE}" = tunv6 ]; then
tc qdisc del dev ${IFACE} root &>/dev/null
tc qdisc add dev ${IFACE} root handle 1: prio
tc filter add dev ${IFACE} parent 1: prio 20 protocol ipv6 u32 match u32 0 0 action mirred egress redirect dev ifb1
# TODO: ingress qdisc may not work for some reason, remove it if problems occur
tc qdisc del dev ${IFACE} ingress &>/dev/null
tc qdisc add dev ${IFACE} ingress handle ffff:
tc filter add dev ${IFACE} parent ffff: prio 20 protocol ipv6 u32 match u32 0 0 action mirred egress redirect dev ifb0
fi
if [ "${IFACE}" = br0 -o "${IFACE}" = vlan2 ]; then
tc qdisc del dev ${IFACE} root &>/dev/null
tc qdisc add dev ${IFACE} root handle 1: prio
tc filter add dev ${IFACE} parent 1:0 prio 10 protocol ip handle 100 fw action mirred egress redirect dev ifb0
tc filter add dev ${IFACE} parent 1:0 prio 20 protocol ipv6 handle 100 fw action mirred egress redirect dev ifb0
fi
}
ifb0 отвечает за шейпинг входящего трафика, ifb1 - исходящего. Но так как я уже упомянул, что шейпить надо в том числе трафик, входящий на сам роутер, а от IMQ пришлось отказаться - имеем вот такой вот геморрой.
Дальше - веселее :-). Сам шейпер:
# Variables that control script parameters
MAIN_IFACE="ifb0"
OUT_IFACE="ifb1"
BAND="7Mbit"
HIGH_LIMIT="6Mbit"
# Simple shaper for outgoing traffic (device ${OUT_IFACE})
tc qdisc del dev ${OUT_IFACE} root &>/dev/null
tc qdisc add dev ${OUT_IFACE} root handle 1: prio
# add some qdisc to high priority traffic
tc qdisc add dev ${OUT_IFACE} parent 1:1 handle 10: sfq
# Properly marked traffic is high-priority
tc filter add dev ${OUT_IFACE} parent 1:0 prio 1 protocol ip \
handle 21 fw \
flowid 1:1
# Properly marked IPv6 traffic is high-priority
tc filter add dev ${OUT_IFACE} parent 1:0 prio 2 protocol ipv6 \
handle 21 fw \
flowid 1:1
# Other traffic is lowest-priority
tc filter add dev ${OUT_IFACE} parent 1:0 prio 100 protocol ip u32 match u32 0 0 flowid 1:3
# Other traffic(IPv6) is lowest-priority
tc filter add dev ${OUT_IFACE} parent 1:0 prio 200 protocol ipv6 u32 match u32 0 0 flowid 1:3
# Shaper for incoming traffic
tc qdisc del dev ${MAIN_IFACE} root handle 1: hfsc &>/dev/null
tc qdisc add dev ${MAIN_IFACE} root handle 1: hfsc
# Internet traffic (full MAXIMUM speed)
tc class add dev ${MAIN_IFACE} parent 1:0 classid 1:1 hfsc sc rate ${BAND} ul rate ${BAND}
# Dummy subclass for delayed shaping
tc class add dev ${MAIN_IFACE} parent 1:0 classid 1:100 hfsc sc rate 1Gbit ul rate 1Gbit
# Subclasses of Internet traffic
tc class add dev ${MAIN_IFACE} parent 1:1 classid 1:10 hfsc rt umax 1500 dmax 2ms rate 1Mbit ls rate ${HIGH_LIMIT}
tc class add dev ${MAIN_IFACE} parent 1:1 classid 1:11 hfsc ls rate 1Mbit
# SFQ Disciplines traffic with filter based on destination IP (fair use)
# for high-priority traffic
tc qdisc add dev ${MAIN_IFACE} parent 1:10 handle 10: sfq
tc filter add dev ${MAIN_IFACE} parent 10: protocol ip handle 1 flow hash keys nfct-dst divisor 256 baseclass 1:10
# for low-priority traffic
tc qdisc add dev ${MAIN_IFACE} parent 1:11 handle 11: sfq
tc filter add dev ${MAIN_IFACE} parent 11: protocol ip handle 1 flow hash keys nfct-dst divisor 256 baseclass 1:11
# end of SFQ Disciplines
# qdisc for dummy subclass
tc qdisc add dev ${MAIN_IFACE} parent 1:100 handle 100: pfifo limit 1000
# Properly marked traffic is high-priority
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 2 protocol ip \
handle 11 fw \
flowid 1:10
# Properly marked IPv6 traffic is high-priority
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 3 protocol ipv6 \
handle 11 fw \
flowid 1:10
# Not input traffic and not classified valid as FORWARD traffic - it should be low priority
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 90 protocol ip \
handle 100 fw \
flowid 1:11
# Not input IPv6 traffic and not classified valid as FORWARD traffic - it should be low priority
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 100 protocol ipv6 \
handle 200 fw \
flowid 1:11
# Not input traffic, shape it AGAIN later
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 2000 protocol ip u32 \
match u32 0 0 \
flowid 1:100 \
action xt -j MARK --set-mark 100 &>/dev/null
# Not input IPv6 traffic, shape it AGAIN later
tc filter add dev ${MAIN_IFACE} parent 1:0 prio 1000 protocol ipv6 u32 \
match u32 0 0 \
flowid 1:100 \
action xt -j MARK --set-mark 200 &>/dev/null
Когда я это дописывал, я уже сам не верил, что эта сотона заработает