-
Notifications
You must be signed in to change notification settings - Fork 2
/
lnw_gateway_tc.sh
174 lines (133 loc) · 6.85 KB
/
lnw_gateway_tc.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#! /usr/bin/env bash
#
### BEGIN INIT INFO
# Provides: lnw_gateway_qos.sh
# Required-Start: $syslog
# Required-Stop: $syslog
# Should-Start: $local_fs
# Should-Stop: $local_fs
# Default-Start: 2
# Default-Stop: 0 1 6
# Short-Description: starts/stops lnw_gateway_qos.sh
# Description: load or stop the Traffic Control rules on the network interface
### END INIT INFO
NETCARD=eth0 # network card to apply the QoS to
UPLINK=1600 # upload in kbits/s
DOWNLINK=16000 # download in kbits/s
TC=/sbin/tc
IPT=/sbin/iptables
case "$1" in
start)
echo "~~~~ LOADING $NETCARD TRAFFIC CONTROL RULES FOR `uname -n` ~~~~"
echo
echo "#-cleanup"
$TC qdisc del dev $NETCARD root
$IPT -t mangle -F
# the r2q value is calculated to let ~3 full packets pass before
# rescheduling, so r2q = (UPLINK / (3 * MTU * 8))
echo "#-define a HTB root qdisc"
$TC qdisc add dev $NETCARD root handle 1: htb default 999 r2q 40
# this is the main branch that sets the total bandwidth available to the leaves
echo "#--uplink - rate $UPLINK kbit ceil $UPLINK kbit"
$TC class add dev $NETCARD parent 1:0 classid 1:1 htb \
rate $(($UPLINK))kbit ceil $(($UPLINK))kbit
# INTERACTIVE CLASS: for low latency, high priority packets such as VoIP and DNS
# it has little bandwidth assigned to it, but pass before everything else
echo "#---interactive - id 100 - rate $(( $UPLINK / 10 )) kbit ceil $(( $UPLINK / 10 * 8 )) kbit"
$TC class add dev $NETCARD parent 1:1 classid 1:100 htb \
rate $(( $UPLINK / 10 ))kbit ceil $(( $UPLINK / 10 * 8 ))kbit \
burst 5k prio 1
# this class transmits uses a pfifo before exiting
echo "#--- ~ sub interactive: pfifo"
$TC qdisc add dev $NETCARD parent 1:100 handle 1100: pfifo limit 10
# filter definition, that will catch all the packets carrying the mark 100
echo "#--- ~ interactive filter"
$TC filter add dev $NETCARD parent 1:0 protocol ip prio 1 \
handle 100 fw flowid 1:100
# netfilter/iptables rules, will mark all UDP packets
echo "#--- ~ netfilter rule - all UDP traffic at 100"
$IPT -t mangle -A POSTROUTING -o $NETCARD -p udp -j CONNMARK --set-mark 100
# TCP ACKs class: it's important to let the ACKs leave the network as fast as possible
# when a host of the network is downloading.
echo "#---tcp acks - id 200 - rate $(( $UPLINK / 5 )) kbit ceil $(( $UPLINK )) kbit"
$TC class add dev $NETCARD parent 1:1 classid 1:200 htb \
rate $(( $UPLINK / 5 ))kbit ceil $(( $UPLINK / 10 ))kbit burst 15k prio 2
echo "#--- ~ sub tcp acks: sfq"
$TC qdisc add dev $NETCARD parent 1:200 handle 1200: sfq perturb 10 limit 32
echo "#--- ~ filtre tcp acks"
$TC filter add dev $NETCARD parent 1:0 protocol ip prio 2 handle 200 fw flowid 1:200
echo "#--- ~ netfilter rule for TCP ACKs will be loaded at the end"
# SSH class: for outgoing connections to avoid lag when somebody else is downloading
# however, an SSH connection cannot fill up the connection to more than 70%
echo "#---ssh - id 300 - rate $(( $UPLINK / 10 )) kbit ceil $(( $UPLINK / 10 * 7 )) kbit"
$TC class add dev $NETCARD parent 1:1 classid 1:300 htb \
rate $(( $UPLINK / 10 ))kbit ceil $(( $UPLINK / 10 * 7 ))kbit burst 15k prio 3
# SFQ will mix the packets if there are several SSH connections in parallel
# and ensure that none has the priority
echo "#--- ~ sub ssh: sfq"
$TC qdisc add dev $NETCARD parent 1:300 handle 1300: sfq perturb 10 limit 32
echo "#--- ~ ssh filter"
$TC filter add dev $NETCARD parent 1:0 protocol ip prio 3 handle 300 fw flowid 1:300
echo "#--- ~ netfilter rule - SSH at 300"
$IPT -t mangle -A POSTROUTING -o $NETCARD -p tcp --tcp-flags SYN SYN \
--dport 22 -j CONNMARK --set-mark 300
# HTTP class: All web browsing (80/443) gets half the bandwidth and can borrow full
echo "#---http branch - id 400 - rate $(( $UPLINK / 2 )) kbit ceil $UPLINK kbit"
$TC class add dev $NETCARD parent 1:1 classid 1:400 htb \
rate $(( $UPLINK / 2 ))kbit ceil $(( $UPLINK ))kbit burst 30k prio 4
echo "#--- ~ sub http branch: sfq"
$TC qdisc add dev $NETCARD parent 1:400 handle 1400: sfq perturb 10 limit 32
echo "#--- ~ http branch filter"
$TC filter add dev $NETCARD parent 1:0 protocol ip prio 4 handle 400 fw flowid 1:400
echo "#--- ~ netfilter rule - http/s"
$IPT -t mangle -A POSTROUTING -o $NETCARD -p tcp --tcp-flags SYN SYN \
--dport 80 -j CONNMARK --set-mark 400
$IPT -t mangle -A POSTROUTING -o $NETCARD -p tcp --tcp-flags SYN SYN \
--dport 443 -j CONNMARK --set-mark 400
# DEFAULT Class: the root qdisc will send all non filtered traffic to this one
# we also set a netfilter rule to send large file transfert to this queue
# and avoid impacting the HTTP queue
echo "#---default - id 999 - rate $(( $UPLINK / 10 ))kbit ceil $(( $UPLINK ))kbit"
$TC class add dev $NETCARD parent 1:1 classid 1:999 htb \
rate $(( $UPLINK / 10 ))kbit ceil $(( $UPLINK ))kbit burst 2k prio 9
echo "#--- ~ sub default: sfq"
$TC qdisc add dev $NETCARD parent 1:999 handle 1999: sfq perturb 10 limit 32
echo "#--- ~ filtre default"
$TC filter add dev $NETCARD parent 1:0 protocol ip prio 99 handle 999 fw flowid 1:999
$IPT -t mangle -A POSTROUTING -o $NETCARD -p tcp -m connbytes --connbytes 10000000: \
--connbytes-mode bytes --connbytes-dir both -j CONNMARK --set-mark 999
echo "#--- ~ propagating marks on connections"
$IPT -t mangle -A POSTROUTING -j CONNMARK --restore-mark
echo "#--- ~ Mark TCP ACKs flags at 200"
$IPT -t mangle -A POSTROUTING -p tcp --tcp-flags URG,ACK,PSH,RST,SYN,FIN ACK \
-m length --length 40:64 -j MARK --set-mark 200
echo
echo "Traffic Control is up and running"
echo
;;
stop)
$IPT -t mangle -F
$IPT -t mangle -X
echo "iptables rules removed"
$TC qdisc del dev $NETCARD root handle 1
echo "traffic control rules removed"
exit 0
;;
restart)
$0 stop
$0 start
exit 0
;;
show)
echo;echo " ---- qdiscs details -----"
$TC -d qdisc show dev $NETCARD
echo;echo " ---- qdiscs statistics --"
$TC -s qdisc show dev $NETCARD
exit 0
;;
*)
echo;echo "usage:$0 {start|stop|restart|show}"
echo "load or stop the Traffic Control rules on the network interface"
echo;echo "julien vehent - 2011 - julien@linuxwall.info"
;;
esac