Dynamic QoS How-TO (FwGuardian steps)
Dynamic QoS HOW-TO By Humberto L Jucá (betolj@gmail.com) The purpose of this how-to is to demonstrate a technique for dynamic QoS, similar to Squid delay_pools, just using the firewall features and traffic control native on the Linux kernel (2.6 series). The idea is basically to divide the total bandwidth into smaller slices (virtual links). The TCP/UDP sessions will be distributed in round-robin to each of these slices. We will do a load-balance between classes using the extension of netfilter "statistic" (nth mode) and load-balance will be made per session (using CONNMARK) or hash IP address (using recent). The QoS will be defined as follows: - We will setup a 1.5Mbits Internet link - The algorithm chosen will be the HTB (qdisc). - The bandwidth is sliced into three (three HTB classes) - Each class will have 500Kbits guaranteed bandwidth, but with permission to use up 1.3Mbits - The leaf node will be the SFQ The goal is to make each "session" limited by HTB class in round-robin. A single session can consume up 1.3Mbits if not competing bandwidth with other sessions. However three concurrent sessions consume up to maximum 500Kbits each. The next sessions will compete bandwidth of their "slice" (class). For this reason, we say it is similar to delay_pools. - Making HTB Qdisc and classes ## HTB qdisc and class /sbin/tc qdisc add dev eth0 root handle 101:0 htb default 1 /sbin/tc class add dev eth0 parent 101:0 classid 101:1 htb rate 1500Kbit burst 10k cburst 10k /sbin/tc class add dev eth0 parent 101:1 classid 101:2 htb rate 500Kbit ceil 1300Kbit /sbin/tc class add dev eth0 parent 101:1 classid 101:3 htb rate 500Kbit ceil 1300Kbit /sbin/tc class add dev eth0 parent 101:1 classid 101:4 htb rate 500Kbit ceil 1300Kbit /sbin/tc qdisc add dev eth0 parent 101:2 sfq perturb 10 /sbin/tc qdisc add dev eth0 parent 101:3 sfq perturb 10 /sbin/tc qdisc add dev eth0 parent 101:4 sfq perturb 10 "Remember this: 101:1 is a default class for unclassified packets (defined in root qdisc)." The QoS will be made by "connection" (CONNMARK) or "hash ip" (recent): - 1. QoS by connection ## TC filter for netfilter MARK /sbin/tc filter add dev eth0 parent 101: protocol ip handle 0x1012 fw flowid 101:2 /sbin/tc filter add dev eth0 parent 101: protocol ip handle 0x1013 fw flowid 101:3 /sbin/tc filter add dev eth0 parent 101: protocol ip handle 0x1014 fw flowid 101:4 ## LB_QOS1 to nf MARK 0x1012 (101:2 class) /sbin/iptables -t mangle -N LB_QOS1 /sbin/iptables -t mangle -A LB_QOS1 -m mark --mark 0x0 -j MARK --set-mark 0x1012 ## LB_QOS2 to nf MARK 0x1013 (101:3 class) /sbin/iptables -t mangle -N LB_QOS2 /sbin/iptables -t mangle -A LB_QOS2 -m mark --mark 0x0 -j MARK --set-mark 0x1013 ## LB_QOS3 to nf MARK 0x1014 (101:4 class) /sbin/iptables -t mangle -N LB_QOS3 /sbin/iptables -t mangle -A LB_QOS3 -m mark --mark 0x0 -j MARK --set-mark 0x1014 ## Netfilter MARKs and NTH load-balance /sbin/iptables -t mangle -A POSTROUTING -j CONNMARK --restore-mark /sbin/iptables -t mangle -A POSTROUTING -m mark --mark 0x1012 -j LB_QOS1 /sbin/iptables -t mangle -A POSTROUTING -m mark --mark 0x1013 -j LB_QOS2 /sbin/iptables -t mangle -A POSTROUTING -m mark --mark 0x1014 -j LB_QOS3 /sbin/iptables -t mangle -A POSTROUTING -m mark ! --mark 0x0 -j CONNMARK --save /sbin/iptables -t mangle -A POSTROUTING -m mark ! --mark 0x0 -j RETURN /sbin/iptables -t mangle -A POSTROUTING -m statistic --mode nth --every 3 --packet 0 -j LB_QOS1 /sbin/iptables -t mangle -A POSTROUTING -m statistic --mode nth --every 3 --packet 1 -j LB_QOS2 /sbin/iptables -t mangle -A POSTROUTING -m statistic --mode nth --every 3 --packet 2 -j LB_QOS3 ## Netfilter CONNMARK (keepalive netfilter MARKs) /sbin/iptables -t mangle -I PREROUTING -m mark --mark 0x0 -j CONNMARK --restore-mark - 2. QoS by hash IP ## LB_QOS1 to nf MARK 0x1012 (101:2 class) /sbin/iptables -t mangle -N LB_QOS1 /sbin/iptables -t mangle -A LB_QOS1 -j CLASSIFY --set-class 101:2 /sbin/iptables -t mangle -A LB_QOS1 -m recent --name LBQOS0 --set /sbin/iptables -t mangle -A LB_QOS1 -m recent --name LBQOS1 --remove -p tcp --tcp-flags ALL RST -j RETURN /sbin/iptables -t mangle -A LB_QOS1 -m recent --name LBQOS1 --remove -p tcp --tcp-flags ALL FIN -j RETURN /sbin/iptables -t mangle -A LB_QOS1 -m recent --name LBQOS1 --set -j RETURN ## LB_QOS2 to nf MARK 0x1013 (101:3 class) /sbin/iptables -t mangle -N LB_QOS2 /sbin/iptables -t mangle -A LB_QOS2 -j CLASSIFY --set-class 101:3 /sbin/iptables -t mangle -A LB_QOS2 -m recent --name LBQOS0 --set /sbin/iptables -t mangle -A LB_QOS2 -m recent --name LBQOS2 --remove -p tcp --tcp-flags ALL RST -j RETURN /sbin/iptables -t mangle -A LB_QOS2 -m recent --name LBQOS2 --remove -p tcp --tcp-flags ALL FIN -j RETURN /sbin/iptables -t mangle -A LB_QOS2 -m recent --name LBQOS2 --set -j RETURN ## LB_QOS3 to nf MARK 0x1014 (101:4 class) /sbin/iptables -t mangle -N LB_QOS3 /sbin/iptables -t mangle -A LB_QOS3 -j CLASSIFY --set-class 101:4 /sbin/iptables -t mangle -A LB_QOS3 -m recent --name LBQOS0 --set /sbin/iptables -t mangle -A LB_QOS3 -m recent --name LBQOS3 --remove -p tcp --tcp-flags ALL RST -j RETURN /sbin/iptables -t mangle -A LB_QOS3 -m recent --name LBQOS3 --remove -p tcp --tcp-flags ALL FIN -j RETURN /sbin/iptables -t mangle -A LB_QOS3 -m recent --name LBQOS3 --set -j RETURN /sbin/iptables -t mangle -A POSTROUTING -m recent --rcheck --name LBQOS1 -j LB_QOS1 /sbin/iptables -t mangle -A POSTROUTING -m recent --rcheck --name LBQOS2 -j LB_QOS2 /sbin/iptables -t mangle -A POSTROUTING -m recent --rcheck --name LBQOS3 -j LB_QOS3 /sbin/iptables -t mangle -A POSTROUTING -m recent --rcheck --name LBQOS0 -j RETURN /sbin/iptables -t mangle -A POSTROUTING -m statistic --mode nth --every 3 --packet 0 -j LB_QOS1 /sbin/iptables -t mangle -A POSTROUTING -m statistic --mode nth --every 3 --packet 1 -j LB_QOS2 /sbin/iptables -t mangle -A POSTROUTING -m statistic --mode nth --every 3 --packet 2 -j LB_QOS3 /sbin/iptables -t mangle -A POSTROUTING -m recent --name LBQOS0 --remove -j RETURN CONSIDERATIONS: 1. It would be interesting to use the "state" module in addition to the "statistic", but this will make processing the rule doesnt work in oldest kernel (with "-m state --state NEW"). 2. I'm still a little undecided about the technique for hash table delets (--remove -p tcp --tcp-flags). 3. The recent extension track by source IP address - include --rdest to track destination address (-m recent --name LBQOSn --rdest). Suggestions? betolj@gmail.com
about
With FwGuardian
Current version:
4.2.5 (Pre 4.3)
Developed
by
Humberto L Jucá
betolj@gmail.com
FWGuardian Authenticated Area Access
Web server based in Horatio Project