Created
December 8, 2010 11:47
-
-
Save nacx/733177 to your computer and use it in GitHub Desktop.
Basic QoS with iproute2 and OpenDPI Netfilter wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Basic QoS script that uses OpenDPI (http://www.opendpi.org/) | |
# Netfilter wrapper to identify packets by the protocol. | |
# | |
# This script enqueues packets in three queues, each one | |
# with a different priority: | |
# | |
# The first queue has the higher priority and gets the TCP SYN | |
# packets, ACKs, ICMPs and packets with Minimize-Delay TOS. | |
# The second one has a normal priority and gets all unmarked | |
# packets. | |
# The third queue has the lower priority and gets all traffic | |
# which delivering can be delayed (p2p traffic, etc) in order | |
# to guarantee that the rest of packets will be delivered as | |
# soon as possible. | |
############################ | |
### Script configuration ### | |
############################ | |
DEV=wlan0 # The gateway device | |
UPLOAD_KPBS=150 # The line upload capacity in kbps | |
################################ | |
### End script configuration ### | |
################################ | |
# We will set the maximum bandwith to use to the 90% of the upload capacity. | |
# This will guarantee that the traffic will be enqueues in our operating system | |
# and not in the router. | |
# We also set the maximum bandwith for the queues with lower priority to 10kbps | |
# less than the queue with higher priority. | |
MAX=$[$UPLOAD_KPBS*90/100] | |
MIN=$[$MAX-10] | |
case "$1" in | |
start) | |
### 1. Initialization ### | |
modprobe ip_conntrack # Required to mark packets in the connection | |
modprobe xt_opendpi # Required to match packets by protocol | |
tc qdisc del dev ${DEV} root 2>/dev/null # Delete existing queues and classes | |
iptables -t mangle -F # Delete packet marking rules | |
### 2. Queue definition ### | |
echo "Creating queues and classes..." | |
# Create an HTB parent queue | |
tc qdisc add dev ${DEV} root handle 1: htb default 20 | |
# Create a parent class to distribute the unused bandwith to the rest of queues | |
tc class add dev ${DEV} parent 1: classid 1:1 htb rate ${MAX}kbit ceil ${MAX}kbit | |
# Create the classes in which the packets will be classified, with the appropiate | |
# bandwith assigned | |
tc class add dev ${DEV} parent 1:1 classid 1:10 htb rate ${MAX}kbit ceil ${MAX}kbit prio 1 | |
tc class add dev ${DEV} parent 1:1 classid 1:20 htb rate ${MIN}kbit ceil ${MAX}kbit prio 2 | |
tc class add dev ${DEV} parent 1:1 classid 1:30 htb rate ${MIN}kbit ceil ${MAX}kbit prio 3 | |
# Add the SQF policy to the leaf classes | |
tc qdisc add dev ${DEV} parent 1:10 handle 10: sfq perturb 10 | |
tc qdisc add dev ${DEV} parent 1:20 handle 20: sfq perturb 10 | |
tc qdisc add dev ${DEV} parent 1:30 handle 30: sfq perturb 10 | |
### 3. Create classifier filters ### | |
echo "Creating classifier filters..." | |
# Classify the marked pakets in the corresponding classes | |
# Unmarked packets will be classified in the default class (1:20) | |
tc filter add dev ${DEV} parent 1: protocol ip prio 1 handle 1 fw classid 1:10 | |
tc filter add dev ${DEV} parent 1: protocol ip prio 2 handle 3 fw classid 1:30 | |
### 4. Packet marking ### | |
echo "Creating packet marking rules..." | |
# Mark high priority packets | |
iptables -t mangle -A OUTPUT -p tcp --tcp-flags ACK ACK -m length --length 0:64 \ | |
-j MARK --set-mark 1 | |
iptables -t mangle -A OUTPUT -m tos --tos Minimize-Delay -j MARK --set-mark 1 | |
iptables -t mangle -A OUTPUT -p icmp -j MARK --set-mark 1 | |
iptables -t mangle -A OUTPUT -p tcp --syn -j MARK --set-mark 1 | |
# Mark low priority packets. Since this packets will be identified by | |
# protocol, we can put a mark in the connection to make a more accurate | |
# packet identification | |
# If the connection is already marked, just continue and do not mark it again | |
iptables -t mangle -A OUTPUT -p tcp -j CONNMARK --restore-mark | |
iptables -t mangle -A OUTPUT -p tcp -m mark ! --mark 0 -j ACCEPT | |
# Filter the packets by protocol, and mark them if necessary | |
iptables -t mangle -A OUTPUT -p tcp -m opendpi --bittorrent -j MARK --set-mark 3 | |
iptables -t mangle -A OUTPUT -p tcp -m opendpi --gnutella -j MARK --set-mark 3 | |
iptables -t mangle -A OUTPUT -p tcp -m opendpi --edonkey -j MARK --set-mark 3 | |
# Save mark in the connection | |
iptables -t mangle -A OUTPUT -p tcp -m mark --mark 3 -j CONNMARK --save-mark | |
;; | |
stop) | |
echo "Removing existing queues and classes..." | |
tc qdisc del dev ${DEV} root 2>/dev/null | |
echo "Removing packet marking rules..." | |
iptables -t mangle -F | |
;; | |
restart) | |
${0} stop | |
${0} start | |
;; | |
status) | |
tc -s qdisc show dev ${DEV} | |
;; | |
monitor) | |
watch -n 1 "tc -s qdisc show dev ${DEV}" | |
;; | |
*) | |
echo "Usage: ${0} {start|stop|restart|status|monitor}" | |
exit 1 | |
;; | |
esac | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment