Skip to content

Instantly share code, notes, and snippets.

@vpereira
Forked from thomasbhatia/qos-opendpi.sh
Created August 5, 2012 21:18
Show Gist options
  • Save vpereira/3267151 to your computer and use it in GitHub Desktop.
Save vpereira/3267151 to your computer and use it in GitHub Desktop.
Basic QoS with iproute2 and OpenDPI Netfilter wrapper
#!/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