Skip to content

Commit

Permalink
debloat: add some pie support
Browse files Browse the repository at this point in the history
Simple script for being able to look at pie harder
Also a mildly more robust and correct classifier
  • Loading branch information
Dave Taht committed May 18, 2013
1 parent 18fb3fd commit d147e81
Show file tree
Hide file tree
Showing 3 changed files with 293 additions and 44 deletions.
1 change: 1 addition & 0 deletions net/debloat/Makefile
Expand Up @@ -36,6 +36,7 @@ define Package/debloat/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/debloat.hotplug $(1)/etc/hotplug.d/iface/00-debloat
$(INSTALL_BIN) ./files/debloat $(1)/usr/sbin/debloat
$(INSTALL_BIN) ./files/pie.sh $(1)/usr/sbin/pie.sh
$(INSTALL_BIN) ./files/simple_qos.sh $(1)/usr/sbin/simple_qos.sh
$(INSTALL_DATA) ./files/debloat.config $(1)/etc/config/debloat
endef
Expand Down
255 changes: 255 additions & 0 deletions net/debloat/files/pie.sh
@@ -0,0 +1,255 @@
#!/bin/sh
# Cero3 Shaper
# A 3 bin tc_codel and ipv6 enabled shaping script for
# ethernet gateways, with an eye towards working well
# with wireless with uplinks in the 2Mbit to 25Mbit
# range. It ain't done yet, and is cerowrt specific
# in that it depends on clearly identifying the
# internal interfaces via a pattern match.

# Copyright (C) 2012 Michael D Taht
# GPLv2

# Compared to the complexity that debloat had become
# this cleanly shows a means of going from diffserv marking
# to prioritization using the current tools (ip(6)tables
# and tc. I note that the complexity of debloat exists for
# a reason, and it is expected that script is run first
# to setup various other parameters such as BQL and ethtool.
# (And that the debloat script has setup the other interfaces)

# You need to jiggle these parameters. Note limits are tuned towards a <10Mbit uplink <60Mbup down

UPLINK=2000
DOWNLINK=20000
DEV=ifb0
QDISC=pie # pie
IFACE=ge00
DEPTH=42
TC=~d/git/iproute2/tc/tc
FLOWS=8000
PERTURB="perturb 0" # Permutation is costly, disable
FLOWS=16000 #
BQL_MAX=3000 # it is important to factor this into the RED calc

CEIL=$UPLINK
MTU=1500
ADSLL=""
# PPOE=yes

#config interface ge00
# option classgroup "Default"
# option enabled 0
# option upload 128
# option download 1024

# uci get aqm.enable
#
# You shouldn't need to touch anything here

if [ -s "$PPOE" ]
then
OVERHEAD=40
LINKLAYER=adsl
ADSLL="linklayer ${LINKLAYER} overhead ${OVERHEAD}"
fi

ipt() {
iptables $*
ip6tables $*
}

do_modules() {

insmod sch_$QDISC
insmod sch_ingress
insmod act_mirred
insmod cls_fw
insmod sch_htb

}

fc() {
PARENT=$1
TOS=$2
CLASSID=$3
tc filter add dev $interface protocol ip parent $PARENT prio $prio u32 match ip tos $TOS 0xfc classid $CLASSID
prio=$(($prio + 1))
tc filter add dev $interface protocol ipv6 parent $PARENT prio $prio u32 match ip6 priority $TOS 0xfc classid $CLASSID
prio=$(($prio + 1))
}

# This could be a complete diffserv implementation

diffserv() {

interface=$1

prio=1

# Catchall

tc filter add dev $interface parent 1:0 protocol all prio 999 u32 \
match ip protocol 0 0x00 flowid 1:12

# Find the most common matches fast

fc 1:0 0x00 1:12 # BE
fc 1:0 0x20 1:13 # CS1
fc 1:0 0x10 1:11 # IMM
fc 1:0 0xb8 1:11 # EF
fc 1:0 0xc0 1:11 # CS3
fc 1:0 0xe0 1:11 # CS6
fc 1:0 0x90 1:11 # AF42 (mosh)

# Arp traffic
tc filter add dev $interface parent 1:0 protocol arp prio $prio handle 1 fw classid 1:11
prio=$(($prio + 1))
}


ipt_setup() {

ipt -t mangle -F
ipt -t mangle -N QOS_MARK

ipt -t mangle -A QOS_MARK -j MARK --set-mark 0x2
# You can go further with classification but...
ipt -t mangle -A QOS_MARK -m dscp --dscp-class CS1 -j MARK --set-mark 0x3
ipt -t mangle -A QOS_MARK -m dscp --dscp-class CS3 -j MARK --set-mark 0x1
ipt -t mangle -A QOS_MARK -m dscp --dscp-class CS6 -j MARK --set-mark 0x1
ipt -t mangle -A QOS_MARK -m dscp --dscp-class EF -j MARK --set-mark 0x1
ipt -t mangle -A QOS_MARK -m dscp --dscp-class AF42 -j MARK --set-mark 0x1
ipt -t mangle -A QOS_MARK -m tos --tos Minimize-Delay -j MARK --set-mark 0x1

# and it might be a good idea to do it for udp tunnels too

# Turn it on. Preserve classification if already performed

ipt -t mangle -A POSTROUTING -o $DEV -m mark --mark 0x00 -g QOS_MARK
ipt -t mangle -A POSTROUTING -o $IFACE -m mark --mark 0x00 -g QOS_MARK

# The Syn optimization was nice but fq_codel does it for us
# ipt -t mangle -A PREROUTING -i s+ -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 0x01
# Not sure if this will work. Encapsulation is a problem period
ipt -t mangle -A PREROUTING -i vtun+ -p tcp -j MARK --set-mark 0x2 # tcp tunnels need ordering

# Emanating from router, do a little more optimization
# but don't bother with it too much.

ipt -t mangle -A OUTPUT -p udp -m multiport --ports 123,53 -j DSCP --set-dscp-class AF42

#Not clear if the second line is needed
#ipt -t mangle -A OUTPUT -o $IFACE -g QOS_MARK

}


# TC rules

egress() {

CEIL=${UPLINK}
PRIO_RATE=`expr $CEIL / 3` # Ceiling for prioirty
BE_RATE=`expr $CEIL / 6` # Min for best effort
BK_RATE=`expr $CEIL / 9` # Min for background
BE_CEIL=`expr $CEIL - 64` # A little slop at the top

R2Q=""

if [ "$CEIL" -lt 1000 ]
then
R2Q="rtq 1"
fi

tc qdisc del dev $IFACE root
tc qdisc add dev $IFACE root handle 1: htb ${RTQ} default 12
tc class add dev $IFACE parent 1: classid 1:1 htb rate ${CEIL}kbit ceil ${CEIL}kbit $ADSLL
tc class add dev $IFACE parent 1:1 classid 1:10 htb rate ${CEIL}kbit ceil ${CEIL}kbit prio 0 $ADSLL
tc class add dev $IFACE parent 1:1 classid 1:11 htb rate 128kbit ceil ${PRIO_RATE}kbit prio 1 $ADSLL
tc class add dev $IFACE parent 1:1 classid 1:12 htb rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit prio 2 $ADSLL
tc class add dev $IFACE parent 1:1 classid 1:13 htb rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit prio 3 $ADSLL

$TC qdisc add dev $IFACE parent 1:11 handle 110: $QDISC limit 600 noecn
$TC qdisc add dev $IFACE parent 1:12 handle 120: $QDISC limit 600 noecn
$TC qdisc add dev $IFACE parent 1:13 handle 130: $QDISC limit 600 noecn

tc filter add dev $IFACE parent 1:0 protocol ip prio 1 handle 1 fw classid 1:11
tc filter add dev $IFACE parent 1:0 protocol ip prio 2 handle 2 fw classid 1:12
tc filter add dev $IFACE parent 1:0 protocol ip prio 3 handle 3 fw classid 1:13

# ipv6 support. Note that the handle indicates the fw mark bucket that is looked for

tc filter add dev $IFACE parent 1:0 protocol ipv6 prio 4 handle 1 fw classid 1:11
tc filter add dev $IFACE parent 1:0 protocol ipv6 prio 5 handle 2 fw classid 1:12
tc filter add dev $IFACE parent 1:0 protocol ipv6 prio 6 handle 3 fw classid 1:13

# Arp traffic

tc filter add dev $IFACE parent 1:0 protocol arp prio 7 handle 1 fw classid 1:11

}

ingress() {

CEIL=$DOWNLINK
PRIO_RATE=`expr $CEIL / 3` # Ceiling for prioirty
BE_RATE=`expr $CEIL / 3` # Min for best effort
BK_RATE=`expr $CEIL / 6` # Min for background
BE_CEIL=`expr $CEIL - 64` # A little slop at the top

R2Q=""

tc qdisc del dev $IFACE handle ffff: ingress
tc qdisc add dev $IFACE handle ffff: ingress

tc qdisc del dev $DEV root
tc qdisc add dev $DEV root handle 1: htb ${RTQ} default 12
tc class add dev $DEV parent 1: classid 1:1 htb rate ${CEIL}kbit ceil ${CEIL}kibit $ADSLL
tc class add dev $DEV parent 1:1 classid 1:10 htb rate ${CEIL}kbit ceil ${CEIL}kibit prio 0 $ADSLL
tc class add dev $DEV parent 1:1 classid 1:11 htb rate 32kbit ceil ${PRIO_RATE}kibit prio 1 $ADSLL
tc class add dev $DEV parent 1:1 classid 1:12 htb rate ${BE_RATE}kbit ceil ${BE_CEIL}kibit prio 2 $ADSLL
tc class add dev $DEV parent 1:1 classid 1:13 htb rate ${BK_RATE}kbit ceil ${BE_CEIL}kibit prio 3 $ADSLL

# I'd prefer to use a pre-nat filter but that causes permutation...

$TC qdisc add dev $DEV parent 1:11 handle 110: $QDISC limit 1000 ecn
$TC qdisc add dev $DEV parent 1:12 handle 120: $QDISC limit 1000 ecn
$TC qdisc add dev $DEV parent 1:13 handle 130: $QDISC limit 1000 ecn

diffserv ifb0

ifconfig ifb0 up

# redirect all IP packets arriving in $IFACE to ifb0

$TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \
match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV

}

do_modules
ipt_setup
egress
ingress

# References:
# This alternate shaper attempts to go for 1/u performance in a clever way
# http://git.coverfire.com/?p=linux-qos-scripts.git;a=blob;f=src-3tos.sh;hb=HEAD

# Comments
# This does the right thing with ipv6 traffic.
# It also does not rehash with sfq skewing streams
# It also tries to leverage diffserv to some sane extent. In particular,
# the 'priority' queue is limited to 33% of the total, so EF, and IMM traffic
# cannot starve other types. The rfc suggested 30%. 30% is probably
# a lot in today's world.

# Flaws
# Many!

# Why 42?
# Lucky number.
# the sum of the number of packets here + htb + the ar71xx device driver
# ~= 50 the core number used by theorists everywhere.

81 changes: 37 additions & 44 deletions net/debloat/files/simple_qos.sh
Expand Up @@ -23,7 +23,7 @@
UPLINK=2000
DOWNLINK=20000
DEV=ifb0
QDISC=nfq_codel # nfq_codel is higher over head than fq_codel but does better on quantums. I hope.
QDISC=fq_codel # fq_codel is winning universally
IFACE=ge00
DEPTH=42
TC=/usr/sbin/tc
Expand Down Expand Up @@ -69,50 +69,42 @@ insmod sch_htb

}

fc() {
PARENT=$1
TOS=$2
CLASSID=$3
tc filter add dev $interface protocol ip parent $PARENT prio $prio u32 match ip tos $TOS 0xfc classid $CLASSID
prio=$(($prio + 1))
tc filter add dev $interface protocol ipv6 parent $PARENT prio $prio u32 match ip6 priority $TOS 0xfc classid $CLASSID
prio=$(($prio + 1))
}

# This could be a complete diffserv implementation

diffserv() {

# While it would be simpler to do this in a loop, we try to find our first matches
# fast which takes the following

#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 1 u32 match ip tos 0x00 0xfc classid 1:12 # CS0
tc filter add dev $DEV protocol ip parent 1:0 prio 2 u32 match ip tos 0x00 0xfc classid 1:12 # CS0
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 3 u32 match ip6 flowlabel 12345 0xfc classid 1:11 # Low Delay
tc filter add dev $DEV protocol ip parent 1:0 prio 4 u32 match ip tos 0x10 0xfc classid 1:11 # Low Delay
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 5 u32 match ip tos 0x20 0xfc classid 1:13 # CS1 Bulk
tc filter add dev $DEV protocol ip parent 1:0 prio 6 u32 match ip tos 0x20 0xfc classid 1:13 # CS1 Bulk

#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 4 u32 match ip tos 0x88 0xfc classid 1:11 # AF41
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 5 u32 match ip tos 0x90 0xfc classid 1:11 # AF42
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 21 u32 match ip tos 0x98 0xfc classid 1:13 # AF43
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 7 u32 match ip tos 0x28 0xfc classid 1:12 # AF11
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 8 u32 match ip tos 0x30 0xfc classid 1:12 # AF12
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 9 u32 match ip tos 0x38 0xfc classid 1:13 # AF13
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 10 u32 match ip tos 0x48 0xfc classid 1:12 # AF21
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 11 u32 match ip tos 0x58 0xfc classid 1:12 # AF22
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 12 u32 match ip tos 0x58 0xfc classid 1:13 # AF23
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 13 u32 match ip tos 0x68 0xfc classid 1:12 # AF31
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 14 u32 match ip tos 0x70 0xfc classid 1:12 # AF32
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 15 u32 match ip tos 0x78 0xfc classid 1:13 # AF33

#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 16 u32 match ip tos 0x40 0xfc classid 1:12 # CS2
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 17 u32 match ip tos 0x60 0xfc classid 1:12 # CS3
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 18 u32 match ip tos 0x80 0xfc classid 1:12 # CS4
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 19 u32 match ip tos 0xa0 0xfc classid 1:12 # CS5
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 9 u32 match ip tos 0xc0 0xfc classid 1:11 # CS6
#tc filter add dev $DEV protocol ipv6 parent 1:0 prio 6 u32 match ip tos 0xe0 0xfc classid 1:11 # CS7

# We can't use these on ifb
#tc filter add dev $DEV parent 1:0 protocol ip prio 3 handle 1 fw classid 1:12
#tc filter add dev $DEV parent 1:0 protocol ip prio 4 handle 2 fw classid 1:13
# ipv6 support. Note that the handle indicates the fw mark bucket that is looked for
#tc filter add dev $DEV parent 1:0 protocol ipv6 prio 8 handle 1 fw classid 1:11
#tc filter add dev $DEV parent 1:0 protocol ipv6 prio 9 handle 2 fw classid 1:12
#tc filter add dev $DEV parent 1:0 protocol ipv6 prio 10 handle 3 fw classid 1:13
interface=$1

prio=1

# Catchall

tc filter add dev $interface parent 1:0 protocol all prio 999 u32 \
match ip protocol 0 0x00 flowid 1:12

# Find the most common matches fast

fc 1:0 0x00 1:12 # BE
fc 1:0 0x20 1:13 # CS1
fc 1:0 0x10 1:11 # IMM
fc 1:0 0xb8 1:11 # EF
fc 1:0 0xc0 1:11 # CS3
fc 1:0 0xe0 1:11 # CS6
fc 1:0 0x90 1:11 # AF42 (mosh)

# Arp traffic
tc filter add dev $DEV parent 1:0 protocol arp prio 7 handle 1 fw classid 1:11
tc filter add dev $interface parent 1:0 protocol arp prio $prio handle 1 fw classid 1:11
prio=$(($prio + 1))
}


Expand All @@ -124,6 +116,7 @@ ipt -t mangle -N QOS_MARK
ipt -t mangle -A QOS_MARK -j MARK --set-mark 0x2
# You can go further with classification but...
ipt -t mangle -A QOS_MARK -m dscp --dscp-class CS1 -j MARK --set-mark 0x3
ipt -t mangle -A QOS_MARK -m dscp --dscp-class CS3 -j MARK --set-mark 0x1
ipt -t mangle -A QOS_MARK -m dscp --dscp-class CS6 -j MARK --set-mark 0x1
ipt -t mangle -A QOS_MARK -m dscp --dscp-class EF -j MARK --set-mark 0x1
ipt -t mangle -A QOS_MARK -m dscp --dscp-class AF42 -j MARK --set-mark 0x1
Expand Down Expand Up @@ -177,8 +170,8 @@ tc class add dev $IFACE parent 1:1 classid 1:11 htb rate 128kbit ceil ${PRIO_RAT
tc class add dev $IFACE parent 1:1 classid 1:12 htb rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit prio 2 $ADSLL
tc class add dev $IFACE parent 1:1 classid 1:13 htb rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit prio 3 $ADSLL

tc qdisc add dev $IFACE parent 1:11 handle 110: $QDISC limit 600 noecn
tc qdisc add dev $IFACE parent 1:12 handle 120: $QDISC limit 600 noecn
tc qdisc add dev $IFACE parent 1:11 handle 110: $QDISC limit 600 quantum 300 noecn
tc qdisc add dev $IFACE parent 1:12 handle 120: $QDISC limit 600 quantum 300 noecn
tc qdisc add dev $IFACE parent 1:13 handle 130: $QDISC limit 600 noecn

tc filter add dev $IFACE parent 1:0 protocol ip prio 1 handle 1 fw classid 1:11
Expand All @@ -201,8 +194,8 @@ ingress() {

CEIL=$DOWNLINK
PRIO_RATE=`expr $CEIL / 3` # Ceiling for prioirty
BE_RATE=`expr $CEIL / 6` # Min for best effort
BK_RATE=`expr $CEIL / 9` # Min for background
BE_RATE=`expr $CEIL / 3` # Min for best effort
BK_RATE=`expr $CEIL / 6` # Min for background
BE_CEIL=`expr $CEIL - 64` # A little slop at the top

R2Q=""
Expand All @@ -224,7 +217,7 @@ tc qdisc add dev $DEV parent 1:11 handle 110: $QDISC limit 1000 ecn
tc qdisc add dev $DEV parent 1:12 handle 120: $QDISC limit 1000 ecn
tc qdisc add dev $DEV parent 1:13 handle 130: $QDISC limit 1000 ecn

diffserv
diffserv ifb0

ifconfig ifb0 up

Expand Down

0 comments on commit d147e81

Please sign in to comment.