-
Notifications
You must be signed in to change notification settings - Fork 2
/
QoS.sh
executable file
·367 lines (304 loc) · 10.9 KB
/
QoS.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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
#!/bin/bash
#load configurations
. qos.cfg
IPTMAN="iptables -t mangle"
function check_label(){
if [ ! -e $LABEL_CONF ]
then
mkdir -p /etc/xtables/
echo "$1" > $LABEL_CONF
else
is_present=`grep -c "$1" $LABEL_CONF`
if [ $is_present -eq 0 ]
then
echo "$1" >> $LABEL_CONF
fi
fi
}
function add_system_configurations(){
#https://bugzilla.redhat.com/show_bug.cgi?id=1011281
#echo 1 >/sys/module/sch_htb/parameters/htb_rate_est
#load ifb module
modprobe ifb
#load act_mirred module
modprobe act_mirred
#set ifb device as UP
ip link set dev $IFB up
if [ $ENABLE_NAT == "on" ]
#Enable ip forwarding,otherwise device behind this GW won't reach Internet
then
sysctl -w net.ipv4.ip_forward=1
fi
check_label "100 $APP_LABEL"
}
function del_system_configurations(){
if [ $ENABLE_NAT == "on" ]
then
#disable forwarding
sysctl -w net.ipv4.ip_forward=0
fi
#remove Qos modules
rmmod ifb
rmmod act_mirred
}
function app_log(){
if [ $APP_LOG = "on" ]
then
$IPTMAN -A QOS_DPI -m ndpi --$app -m limit --limit 10/min -j LOG --log-prefix "nDPI-$app: "
fi
}
function l7_classification(){
$IPTMAN -N QOS_DPI
#Send everything to nDPI to applications detection
$IPTMAN -A PREROUTING -j QOS_DPI
#DPI for applications
$IPTMAN -A QOS_DPI -m connlabel --label $APP_LABEL -j RETURN
$IPTMAN -A QOS_DPI -m connbytes --connbytes-mode packets --connbytes-dir both --connbytes 20 -j RETURN
if [ ${#LOW_PRIO_APP[@]} -gt 0 ]
then
for app in ${LOW_PRIO_APP[@]}
do
app_log
$IPTMAN -A QOS_DPI -m ndpi --$app -m connlabel --set --label $APP_LABEL -j CONNMARK --set-mark $DOWN_LOW_PRIO_MARK
done
fi
if [ ${#BULK_PRIO_APP[@]} -gt 0 ]
then
for app in ${BULK_PRIO_APP[@]}
do
app_log
$IPTMAN -A QOS_DPI -m ndpi --$app -m connlabel --set --label $APP_LABEL -j CONNMARK --set-mark $DOWN_BULK_MARK
done
fi
if [ ${#HIGH_PRIO_APP[@]} -gt 0 ]
then
for app in ${HIGH_PRIO_APP[@]}
do
app_log
$IPTMAN -A QOS_DPI -m ndpi --$app -m connlabel --set --label $APP_LABEL -j CONNMARK --set-mark $DOWN_HIGH_PRIO_MARK
done
fi
$IPTMAN -A QOS_UPLOAD -m mark --mark $APP_HIGH_PRIO_MARK -j CLASSIFY --set-class 1:$UP_HIGH_PRIO_MARK
$IPTMAN -A QOS_UPLOAD -m mark --mark $APP_HIGH_PRIO_MARK -j RETURN
$IPTMAN -A QOS_UPLOAD -m mark --mark $APP_LOW_PRIO_MARK -j CLASSIFY --set-class 1:$UP_LOW_PRIO_MARK
$IPTMAN -A QOS_UPLOAD -m mark --mark $APP_LOW_PRIO_MARK -j RETURN
$IPTMAN -A QOS_UPLOAD -m mark --mark $APP_BULK_MARK -j CLASSIFY --set-class 1:$UP_BULK_MARK
$IPTMAN -A QOS_UPLOAD -m mark --mark $APP_BULK_MARK -j RETURN
}
function slowdown(){
$IPTMAN -N QOS_SLOWDOWN
$IPTMAN -I FORWARD -j QOS_SLOWDOWN
if [ ! -z ${TCP_SLOWDOWN_PORTS} ]
then
$IPTMAN -A QOS_SLOWDOWN \
-p tcp -m multiport --dports $TCP_SLOWDOWN_PORTS -m connbytes --connbytes $SLOWDOWN_QUOTA: \
--connbytes-dir both --connbytes-mode bytes -j CONNMARK --set-mark $DOWN_LOW_PRIO_MARK
$IPTMAN -A QOS_SLOWDOWN \
-p tcp -m multiport --dports $TCP_SLOWDOWN_PORTS -m connbytes --connbytes $SLOWDOWN_QUOTA: \
--connbytes-dir both --connbytes-mode bytes -j RETURN
fi
if [ ! -z ${UDP_SLOWDOWN_PORTS} ]
then
$IPTMAN -A QOS_SLOWDOWN \
-p udp -m multiport --dports $UDP_SLOWDOWN_PORTS -m connbytes --connbytes $SLOWDOWN_QUOTA: \
--connbytes-dir both --connbytes-mode bytes -j CONNMARK --set-mark $DOWN_LOW_PRIO_MARK
$IPTMAN -A QOS_SLOWDOWN \
-p udp -m multiport --dports $UDP_SLOWDOWN_PORTS -m connbytes --connbytes $SLOWDOWN_QUOTA: \
--connbytes-dir both --connbytes-mode bytes -j RETURN
fi
}
function add_iptables_rules(){
if [ $ENABLE_NAT == "on" ]
then
#Outgoing NAT
iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE
fi
#Qos chains
$IPTMAN -N QOS_UPLOAD
$IPTMAN -N QOS_DOWNLOAD
$IPTMAN -N RESTORE-MARK
$IPTMAN -N SAVE-MARK
$IPTMAN -A FORWARD -m mark --mark 0 -o $WAN -j QOS_DOWNLOAD
$IPTMAN -A FORWARD -o $WAN -m mark ! --mark 0 -j QOS_UPLOAD
$IPTMAN -A PREROUTING -m connmark ! --mark 0 -j RESTORE-MARK
$IPTMAN -A POSTROUTING -m mark ! --mark 0 -j SAVE-MARK
#restore mark for previously marked connection
$IPTMAN -A RESTORE-MARK -m conntrack ! --ctstate NEW -j CONNMARK --restore-mark
if [ $ENABLE_L7 == "on" ]
then
l7_classification
fi
if [ $ENABLE_SLOWDOWN == "on" ]
then
slowdown
fi
#high prio traffic
#http(s),ssh
$IPTMAN -A QOS_DOWNLOAD -p tcp -m multiport --dports $TCP_HIGH_PRIO_PORTS \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $DOWN_HIGH_PRIO_MARK
$IPTMAN -A QOS_DOWNLOAD -p tcp -m multiport --dports $TCP_HIGH_PRIO_PORTS \
-m conntrack --ctstate NEW -j RETURN
#voip,dns,ipsec,openvpn,NTP
$IPTMAN -A QOS_DOWNLOAD -p udp -m multiport --dports $UDP_HIGH_PRIO_PORTS \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $DOWN_HIGH_PRIO_MARK
$IPTMAN -A QOS_DOWNLOAD -p udp -m multiport --dports $UDP_HIGH_PRIO_PORTS \
-m conntrack --ctstate NEW -j RETURN
#bulk traffic
$IPTMAN -A QOS_DOWNLOAD -p tcp -m multiport --dports $TCP_BULK_PORTS \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $DOWN_BULK_MARK
$IPTMAN -A QOS_DOWNLOAD -p tcp -m multiport --dports $TCP_BULK_PORTS \
-m conntrack --ctstate NEW -j RETURN
$IPTMAN -A QOS_DOWNLOAD -p udp -m multiport --dports $UDP_BULK_PORTS \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $DOWN_BULK_MARK
$IPTMAN -A QOS_DOWNLOAD -p udp -m multiport --dports $UDP_BULK_PORTS \
-m conntrack --ctstate NEW -j RETURN
#low prio traffic
$IPTMAN -A QOS_DOWNLOAD -p tcp -m multiport --dports $TCP_LOW_PRIO_PORTS \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $DOWN_LOW_PRIO_MARK
$IPTMAN -A QOS_DOWNLOAD -p tcp -m multiport --dports $TCP_LOW_PRIO_PORTS \
-m conntrack --ctstate NEW -j RETURN
$IPTMAN -A QOS_DOWNLOAD -p udp -m multiport --dports $UDP_LOW_PRIO_PORTS \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $DOWN_LOW_PRIO_MARK
$IPTMAN -A QOS_DOWNLOAD -p udp -m multiport --dports $UDP_LOW_PRIO_PORTS \
-m conntrack --ctstate NEW -j RETURN
#In this way i should not need to mark connection for upload,and the mark for download traffic shuold be maintained
$IPTMAN -A QOS_UPLOAD -m mark --mark $DOWN_HIGH_PRIO_MARK -j CLASSIFY --set-class 1:$UP_HIGH_PRIO_MARK
$IPTMAN -A QOS_UPLOAD -m mark --mark $DOWN_HIGH_PRIO_MARK -j RETURN
$IPTMAN -A QOS_UPLOAD -m mark --mark $DOWN_LOW_PRIO_MARK -j CLASSIFY --set-class 1:$UP_LOW_PRIO_MARK
$IPTMAN -A QOS_UPLOAD -m mark --mark $DOWN_LOW_PRIO_MARK -j RETURN
$IPTMAN -A QOS_UPLOAD -m mark --mark $DOWN_BULK_MARK -j CLASSIFY --set-class 1:$UP_BULK_MARK
$IPTMAN -A QOS_UPLOAD -m mark --mark $DOWN_BULK_MARK -j RETURN
# #save mark of the previously marked connections
$IPTMAN -A SAVE-MARK -m conntrack --ctstate NEW -j CONNMARK --save-mark
}
function add_qos_devs_and_classes(){
#######################DOWNLOAD#############################################
if [ $BULK_DEFAULT == "on" ]
then
#Defult class is bulk traffic class
tc qdisc add dev $IFB root handle 1: htb default $DOWN_BULK_MARK
else
tc qdisc add dev $IFB root handle 1: htb
fi
#set global download value
tc class add dev $IFB parent 1: classid 1:1 htb rate $WAN_DOWNLOAD burst $BURST
#high priority class
tc class add dev $IFB parent 1:1 classid 1:$DOWN_HIGH_PRIO_MARK htb rate $HIGH_PRIO_DOWN_GUARANTEED \
ceil $HIGH_PRIO_DOWN_MAX quantum $QUANTUM burst $BURST prio 0
#low priority class
tc class add dev $IFB parent 1:1 classid 1:$DOWN_LOW_PRIO_MARK htb rate $LOW_PRIO_DOWN_GUARANTEED \
ceil $LOW_PRIO_DOWN_MAX quantum $QUANTUM burst $BURST prio 7
#bulk traffic class
tc class add dev $IFB parent 1:1 classid 1:$DOWN_BULK_MARK htb rate $DOWNLOAD_GUARANTEED_DEFAULT \
ceil $DOWNLOAD_MAX_DEFAULT quantum $QUANTUM burst $BURST prio 5
#use class [high prio]
tc filter add dev $IFB parent 1:0 protocol ip handle $DOWN_HIGH_PRIO_MARK fw flowid 1:$DOWN_HIGH_PRIO_MARK
#use class [low prio]
tc filter add dev $IFB parent 1:0 protocol ip handle $DOWN_LOW_PRIO_MARK fw flowid 1:$DOWN_LOW_PRIO_MARK
#use class [bulk traffic]
tc filter add dev $IFB parent 1:0 protocol ip handle $DOWN_BULK_MARK fw flowid 1:$DOWN_BULK_MARK
# Tell which algorithm the classes use
tc qdisc add dev $IFB parent 1:$DOWN_HIGH_PRIO_MARK sfq perturb 10
tc qdisc add dev $IFB parent 1:$DOWN_LOW_PRIO_MARK sfq perturb 10
tc qdisc add dev $IFB parent 1:$DOWN_BULK_MARK sfq perturb 10
#redirect everything to ifb interface,needed for ingress (traffic coming from WAN)
tc qdisc add dev $WAN handle ffff: ingress
tc filter add dev $WAN parent ffff: protocol ip u32 match u32 0 0 action \
connmark action mirred egress redirect dev $IFB
#######################UPLOAD################################################
if [ $BULK_DEFAULT == "on" ]
then
#default class is bulk traffic class
tc qdisc add dev $WAN root handle 1:0 htb default $UP_BULK_MARK
else
tc qdisc add dev $WAN root handle 1:0 htb
fi
#set the global upload value
tc class add dev $WAN parent 1: classid 1:1 htb rate $WAN_UPLOAD burst $BURST
#high priority class
tc class add dev $WAN parent 1:1 classid 1:$UP_HIGH_PRIO_MARK htb rate $HIGH_PRIO_UP_GUARANTEED \
ceil $HIGH_PRIO_UP_MAX quantum $QUANTUM burst $BURST prio 0
#low priority class
tc class add dev $WAN parent 1:1 classid 1:$UP_LOW_PRIO_MARK htb rate $LOW_PRIO_UP_GUARANTEED \
ceil $LOW_PRIO_UP_MAX quantum $QUANTUM burst $BURST prio 7
#bulk traffic class
tc class add dev $WAN parent 1:1 classid 1:$UP_BULK_MARK htb rate $UPLOAD_GUARANTEED_DEFAULT \
ceil $UPLOAD_MAX_DEFAULT quantum $QUANTUM burst $BURST prio 5
#Tell which algorithm the classes use
tc qdisc add dev $WAN parent 1:$UP_HIGH_PRIO_MARK sfq perturb 10
tc qdisc add dev $WAN parent 1:$UP_LOW_PRIO_MARK sfq perturb 10
tc qdisc add dev $WAN parent 1:$UP_BULK_MARK sfq perturb 10
}
function del_qos_dev_and_classes(){
#remove tc devices
tc qdisc del dev $WAN ingress
tc qdisc del dev $WAN root
tc qdisc del dev $IFB root
}
function del_iptables_rules(){
#flush iptables rules
$IPTMAN -F SAVE-MARK
$IPTMAN -D POSTROUTING -m mark ! --mark 0 -j SAVE-MARK
$IPTMAN -X SAVE-MARK
$IPTMAN -F RESTORE-MARK
$IPTMAN -D PREROUTING -m connmark ! --mark 0 -j RESTORE-MARK
$IPTMAN -X RESTORE-MARK
if [ $ENABLE_SLOWDOWN == "on" ]
then
$IPTMAN -F QOS_SLOWDOWN
$IPTMAN -D FORWARD -j QOS_SLOWDOWN
$IPTMAN -X QOS_SLOWDOWN
fi
$IPTMAN -F QOS_DOWNLOAD
$IPTMAN -D FORWARD -m mark --mark 0 -o $WAN -j QOS_DOWNLOAD
$IPTMAN -X QOS_DOWNLOAD
$IPTMAN -F QOS_UPLOAD
$IPTMAN -D FORWARD -o $WAN -m mark ! --mark 0 -j QOS_UPLOAD
$IPTMAN -X QOS_UPLOAD
if [ $ENABLE_L7 == "on" ]
then
$IPTMAN -F QOS_DPI
$IPTMAN -D PREROUTING -j QOS_DPI
$IPTMAN -X QOS_DPI
fi
if [ $ENABLE_NAT == "on" ]
then
iptables -t nat -D POSTROUTING -o $WAN -j MASQUERADE
fi
}
function start(){
add_system_configurations
add_qos_devs_and_classes
add_iptables_rules
}
function stop(){
del_qos_dev_and_classes
del_iptables_rules
del_system_configurations
}
function show(){
clear
echo "## Download QoS classes ##"
tc -g -s -nm -cf qos_class_mapping.cfg class show dev $IFB
echo " "
echo "## Upload QoS classes ##"
tc -g -s -nm -cf qos_class_mapping.cfg class show dev $WAN
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
stats)
show
;;
*)
echo "usage $0 start|stop|restart|stats"
;;
esac