User Tools

Site Tools


fair_traffic_shaping_an_adsl_line_for_a_local_network_using_linux

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
fair_traffic_shaping_an_adsl_line_for_a_local_network_using_linux [2018/12/06 21:56]
abeverley
fair_traffic_shaping_an_adsl_line_for_a_local_network_using_linux [2018/12/06 22:02]
abeverley
Line 83: Line 83:
 Now we need to look out for all those P2P connections. We're going to find these out by looking for a client on the network making lots of connections to high port numbers, which is generally what P2P software does. This isn't foolproof of course: I have seen P2P software start to use port 80, and there could be false negatives, but on the whole it seems to work better than any other solutions out there that I have tried. Now we need to look out for all those P2P connections. We're going to find these out by looking for a client on the network making lots of connections to high port numbers, which is generally what P2P software does. This isn't foolproof of course: I have seen P2P software start to use port 80, and there could be false negatives, but on the whole it seems to work better than any other solutions out there that I have tried.
  
-''​%% #​ The next few lines pick out P2P packets%%''​\\ +<​code>​ 
-''​%% #​ These are characterised by lots of connections to high port numbers%%''​\\ +#​ The next few lines pick out P2P packets 
-''​%% #​ First look for the packets and log to IPSET p2p%%''​\\ +#​ These are characterised by lots of connections to high port numbers 
-''​%% #​ Detects traffic from users using >​8 ports above 1024%%''​\\ +#​ First look for the packets and log to IPSET p2p 
-''​%% #​ and adds the source address to the P2P list.%%''​\\ +#​ Detects traffic from users using >​8 ports above 1024 
-''​%% $IPTABLES -t mangle -A FORWARD -o ppp0 -p tcp --dport 1024:​ \%%''​\\ +#​ and adds the source address to the P2P list. 
-''​%%       -m connlimit --connlimit-above 8 -j SET --add-set p2p src%%''​\\ +$IPTABLES -t mangle -A FORWARD -o ppp0 -p tcp --dport 1024:​ \\ 
-''​%% %%''​\\ +       -m connlimit --connlimit-above 8 -j SET --add-set p2p src 
-''​%% #​ Detects traffic from users using >​4 UDP ports above 1024%%''​\\ + 
-''​%% #​ and adds the source address to the P2P list.%%''​\\ +#​ Detects traffic from users using >​4 UDP ports above 1024 
-''​%% $IPTABLES -t mangle -A FORWARD -o ppp0 -p udp --dport 1024:​ \%%''​\\ +#​ and adds the source address to the P2P list. 
-''​%%       -m connlimit --connlimit-above 4 -j SET --add-set p2p src%%''​\\ +$IPTABLES -t mangle -A FORWARD -o ppp0 -p udp --dport 1024:​ \\ 
-''​%% %%''​\\ +       -m connlimit --connlimit-above 4 -j SET --add-set p2p src 
-''​%% #​ Detects traffic to users using >​8 ports above 1024%%''​\\ + 
-''​%% #​ and adds the dst address (ie the user) to the P2P list.%%''​\\ +#​ Detects traffic to users using >​8 ports above 1024 
-''​%% $IPTABLES -t mangle -A FORWARD -i ppp0 -p tcp --sport 1024:​ \%%''​\\ +#​ and adds the dst address (ie the user) to the P2P list. 
-''​%%       -m connlimit --connlimit-above 8 -j SET --add-set p2p dst%%''​\\ +$IPTABLES -t mangle -A FORWARD -i ppp0 -p tcp --sport 1024:​ \\ 
-''​%% %%''​\\ +       -m connlimit --connlimit-above 8 -j SET --add-set p2p dst 
-''​%% #​ Detects traffic to users using >​4 UDP ports above 1024%%''​\\ + 
-''​%% #​ and adds the dst address (ie the user) to the P2P list.%%''​\\ +#​ Detects traffic to users using >​4 UDP ports above 1024 
-''​%% $IPTABLES -t mangle -A FORWARD -i ppp0 -p udp --sport 1024:​ \%%''​\\ +#​ and adds the dst address (ie the user) to the P2P list. 
-''​%%       -m connlimit --connlimit-above 4 -j SET --add-set p2p dst%%''​+$IPTABLES -t mangle -A FORWARD -i ppp0 -p udp --sport 1024:​ \\ 
 +       -m connlimit --connlimit-above 4 -j SET --add-set p2p dst 
 +</​code>​
  
 The above rules just add the client IP address to the ipset. We now need to mark the traffic, which the following rules do. On one network, traffic became so slow that I marked ALL traffic to and from those clients as '​60'​. This certainly sped the network up, but of course the entire internet connection for that client became really slow. If you want to do that just remove the destination port parameters. The above rules just add the client IP address to the ipset. We now need to mark the traffic, which the following rules do. On one network, traffic became so slow that I marked ALL traffic to and from those clients as '​60'​. This certainly sped the network up, but of course the entire internet connection for that client became really slow. If you want to do that just remove the destination port parameters.
  
-''​%% #​ Once a user is in the p2p IPSET,​ these rules mark their packets%%''​\\ +<​code>​ 
-''​%% #​ Any packets above 1024 are marked as the lowest priority%%''​\\ +#​ Once a user is in the p2p IPSET,​ these rules mark their packets 
-''​%% $IPTABLES -t mangle -A FORWARD -o ppp0 -p tcp --dport 1024:​ \%%''​\\ +#​ Any packets above 1024 are marked as the lowest priority 
-''​%%       -m set --set p2p src -j MARK --set-mark 666%%''​\\ +$IPTABLES -t mangle -A FORWARD -o ppp0 -p tcp --dport 1024:​ \\ 
-''​%% $IPTABLES -t mangle -A FORWARD -i ppp0 -p tcp --sport 1024:​ \%%''​\\ +       -m set --set p2p src -j MARK --set-mark 666 
-''​%%       -m set --set p2p dst -j MARK --set-mark 666%%''​\\ +$IPTABLES -t mangle -A FORWARD -i ppp0 -p tcp --sport 1024:​ \\ 
-''​%% $IPTABLES -t mangle -A FORWARD -o ppp0 -p udp --dport 1024:​ \%%''​\\ +       -m set --set p2p dst -j MARK --set-mark 666 
-''​%%       -m set --set p2p src -j MARK --set-mark 666%%''​\\ +$IPTABLES -t mangle -A FORWARD -o ppp0 -p udp --dport 1024:​ \\ 
-''​%% $IPTABLES -t mangle -A FORWARD -i ppp0 -p udp --sport 1024:​ \%%''​\\ +       -m set --set p2p src -j MARK --set-mark 666 
-''​%%       -m set --set p2p dst -j MARK --set-mark 666%%''​+$IPTABLES -t mangle -A FORWARD -i ppp0 -p udp --sport 1024:​ \\ 
 +       -m set --set p2p dst -j MARK --set-mark 666 
 +</​code>​
  
 ===== Shaping the traffic using HTB ===== ===== Shaping the traffic using HTB =====
Line 135: Line 139:
 We don't set a default class; this is so that local eth0 traffic is not shaped. As already stated, we have to shape at eth0 and not ppp0 as we can only do egress shaping decently. We don't set a default class; this is so that local eth0 traffic is not shaped. As already stated, we have to shape at eth0 and not ppp0 as we can only do egress shaping decently.
  
-''​%% #​ Create the root qdisc on the interface%%''​\\ +<​code>​ 
-''​%% tc qdisc add dev eth0 root handle 1:​ htb r2q 1%%''​\\ +#​ Create the root qdisc on the interface 
-''​%% %%''​\\ +tc qdisc add dev eth0 root handle 1:​ htb r2q 1
-''​%% #​ Add some overall rate limits as defined above. Parent number 1:​%%''​\\ +
-''​%% #​ says to apply it to the root above. Call this child 1:​1%%''​\\ +
-''​%% tc class add dev eth0 parent 1:​ classid 1:​1 htb rate 3600kbit ceil 3600kbit%%''​+
  
-We now have one root HTB qdisc with a rate limit of 3600kbpsTo this we add 6 further children. Note the numbers. 1(or 1:0) is the root1:1 is the first child with the overall rate limit. Each child of this is 1:10, 1:20 and so on. To make things simpler, I have numbered the children below to align with the MARK numbers. <​html><​strong></​html>​Note that all the rates of the children should add up to the single rate limit of the parent.<​html></​strong>​</html>+#​ Add some overall rate limits as defined aboveParent number 1: 
 +#​ says to apply it to the root aboveCall this child 1:1 
 +tc class add dev eth0 parent 1classid 1:1 htb rate 3600kbit ceil 3600kbit 
 +</code>
  
-''​%% #​ Add a number of classes to the root qdisc.%%''​\\ +We now have one root HTB qdisc with a rate limit of 3600kbps. To this we add 6 further children. Note the numbers. 1: (or 1:0) is the root. 1:1 is the first child with the overall rate limit. Each child of this is 1:10, 1:20 and so on. To make things simpler, I have numbered the children below to align with the MARK numbers. Note that all the rates of the children should add up to the single rate limit of the parent. 
-''​%% #​ With some qdiscs the classes are automatically%%''​\\ + 
-''​%% #​ created. With HTB they are not so we add 4 in total%%''​\\ +<​code>​ 
-''​%% #​ with different rate limits for each%%''​\\ +#​ Add a number of classes to the root qdisc.%%''​\\ 
-''​%% %%''​\\ +#​ With some qdiscs the classes are automatically%%''​\\ 
-''​%% #​ interactive traffic%%''​\\ +#​ created. With HTB they are not so we add 4 in total%%''​\\ 
-''​%% tc class add dev eth0 parent 1:​1 classid 1:​10 htb rate 720kbit ceil 720kbit prio 0%%''​\\ +#​ with different rate limits for each%%''​\\ 
-''​%% %%''​\\ + 
-''​%% #​ Note:​ no class 20. This is only used in the upload for ack packets%%''​\\ +#​ interactive traffic 
-''​%% %%''​\\ +tc class add dev eth0 parent 1:​1 classid 1:​10 htb rate 720kbit ceil 720kbit prio 0 
-''​%% #​ web browsing%%''​\\ + 
-''​%% tc class add dev eth0 parent 1:​1 classid 1:​30 htb rate 1008kbit ceil 2880kbit prio 4%%''​\\ +#​ Note:​ no class 20. This is only used in the upload for ack packets 
-''​%% %%''​\\ + 
-''​%% #​ default traffic%%''​\\ +#​ web browsing 
-''​%% tc class add dev eth0 parent 1:​1 classid 1:​40 htb rate 792kbit ceil 2880kbit prio 4%%''​\\ +tc class add dev eth0 parent 1:​1 classid 1:​30 htb rate 1008kbit ceil 2880kbit prio 4 
-''​%% %%''​\\ + 
-''​%% # bulk%%''​\\ +#​ default traffic 
-''​%% tc class add dev eth0 parent 1:​1 classid 1:​50 htb rate 720kbit ceil 3420kbit prio 4%%''​\\ +tc class add dev eth0 parent 1:​1 classid 1:​40 htb rate 792kbit ceil 2880kbit prio 4 
-''​%% %%''​\\ + 
-''​%% #​ bad boys%%''​\\ +# bulk 
-''​%% tc class add dev eth0 parent 1:​1 classid 1:​666 htb rate 360kbit ceil 3600kbit prio 7%%''​+tc class add dev eth0 parent 1:​1 classid 1:​50 htb rate 720kbit ceil 3420kbit prio 4 
 + 
 +#​ bad boys 
 +tc class add dev eth0 parent 1:​1 classid 1:​666 htb rate 360kbit ceil 3600kbit prio 7 
 +</​code>​
  
 We now have the HTB qdisc fully set up. However, no traffic will be sent to it yet, and the traffic will not be shaped within each class. We now have the HTB qdisc fully set up. However, no traffic will be sent to it yet, and the traffic will not be shaped within each class.
Line 170: Line 178:
 The next set of rules shape traffic in each class. If we don't do this, then all the traffic for a particular class (such as all the webbrowsing traffic - 30) will be piled into the class on a fifo basis. We want to be more intelligent than this. SFQ does some nice fair shaping. The next set of rules shape traffic in each class. If we don't do this, then all the traffic for a particular class (such as all the webbrowsing traffic - 30) will be piled into the class on a fifo basis. We want to be more intelligent than this. SFQ does some nice fair shaping.
  
-''​%% tc qdisc add dev eth0 parent 1:​10 handle 4210:​ sfq perturb 10 limit 50%%''​\\ +<​code>​ 
-''​%% tc qdisc add dev eth0 parent 1:​30 handle 4230:​ sfq perturb 10 limit 64%%''​\\ +tc qdisc add dev eth0 parent 1:​10 handle 4210:​ sfq perturb 10 limit 50 
-''​%% tc qdisc add dev eth0 parent 1:​40 handle 4240:​ sfq perturb 10 limit 128%%''​\\ +tc qdisc add dev eth0 parent 1:​30 handle 4230:​ sfq perturb 10 limit 64 
-''​%% tc qdisc add dev eth0 parent 1:​50 handle 4250:​ sfq perturb 10 limit 64%%''​\\ +tc qdisc add dev eth0 parent 1:​40 handle 4240:​ sfq perturb 10 limit 128 
-''​%% tc qdisc add dev eth0 parent 1:​666 handle 666:​ sfq perturb 10 limit 128%%''​+tc qdisc add dev eth0 parent 1:​50 handle 4250:​ sfq perturb 10 limit 64 
 +tc qdisc add dev eth0 parent 1:​666 handle 666:​ sfq perturb 10 limit 128 
 +</​code>​
  
 So, everything is set up and ready to go. We just need to divert some traffic into each of the classes. We do this by attaching a filter to the class. A filter looks for traffic of a particular type and sucks it into the class. In this example, we use the MARK of the traffic (called flowid here). So, everything is set up and ready to go. We just need to divert some traffic into each of the classes. We do this by attaching a filter to the class. A filter looks for traffic of a particular type and sucks it into the class. In this example, we use the MARK of the traffic (called flowid here).
  
-''​%% tc filter add dev eth0 parent 1:​0 protocol ip handle 10 fw flowid 1:​10%%''​\\ +<​code>​ 
-''​%% tc filter add dev eth0 parent 1:​0 protocol ip handle 30 fw flowid 1:​30%%''​\\ +tc filter add dev eth0 parent 1:​0 protocol ip handle 10 fw flowid 1:​10 
-''​%% tc filter add dev eth0 parent 1:​0 protocol ip handle 40 fw flowid 1:​40%%''​\\ +tc filter add dev eth0 parent 1:​0 protocol ip handle 30 fw flowid 1:​30 
-''​%% tc filter add dev eth0 parent 1:​0 protocol ip handle 50 fw flowid 1:​50%%''​\\ +tc filter add dev eth0 parent 1:​0 protocol ip handle 40 fw flowid 1:​40 
-''​%% tc filter add dev eth0 parent 1:​0 protocol ip handle 666 fw flowid 1:​666%%''​+tc filter add dev eth0 parent 1:​0 protocol ip handle 50 fw flowid 1:​50 
 +tc filter add dev eth0 parent 1:​0 protocol ip handle 666 fw flowid 1:​666 
 +</​code>​
  
 Everything will be working nicely at this point. However, we have one more tweak to do. We want to share traffic between clients (by IP address) not by connection. This means that if one client has 4 downloads on the go, and another has only one, that traffic will be split 50/50, as opposed to the first client getting 80%. We do this by applying more filters to the existing ones. Everything will be working nicely at this point. However, we have one more tweak to do. We want to share traffic between clients (by IP address) not by connection. This means that if one client has 4 downloads on the go, and another has only one, that traffic will be split 50/50, as opposed to the first client getting 80%. We do this by applying more filters to the existing ones.
  
-''​%% tc filter add dev eth0 parent 4210:​ protocol ip handle 10 flow hash keys nfct-dst divisor 1024%%''​\\ +<​code>​ 
-''​%% tc filter add dev eth0 parent 4230:​ protocol ip handle 30 flow hash keys nfct-dst divisor 1024%%''​\\ +tc filter add dev eth0 parent 4210:​ protocol ip handle 10 flow hash keys nfct-dst divisor 1024 
-''​%% tc filter add dev eth0 parent 4240:​ protocol ip handle 40 flow hash keys nfct-dst divisor 1024%%''​\\ +tc filter add dev eth0 parent 4230:​ protocol ip handle 30 flow hash keys nfct-dst divisor 1024 
-''​%% tc filter add dev eth0 parent 4250:​ protocol ip handle 50 flow hash keys nfct-dst divisor 1024%%''​\\ +tc filter add dev eth0 parent 4240:​ protocol ip handle 40 flow hash keys nfct-dst divisor 1024 
-''​%% tc filter add dev eth0 parent 666:​ protocol ip handle 666 flow hash keys nfct-dst divisor 1024%%''​+tc filter add dev eth0 parent 4250:​ protocol ip handle 50 flow hash keys nfct-dst divisor 1024 
 +tc filter add dev eth0 parent 666:​ protocol ip handle 666 flow hash keys nfct-dst divisor 1024 
 +</​code>​
  
 ==== Uplink ==== ==== Uplink ====
Line 196: Line 210:
 The uplink is almost identical, except that it puts ACK packets into a separate class. This is so that when the upload link is saturated, download speeds are not affected. The uplink is almost identical, except that it puts ACK packets into a separate class. This is so that when the upload link is saturated, download speeds are not affected.
  
-''​%% tc qdisc add dev ppp0 root handle 1:​ htb r2q 1%%''​\\ +<​code>​ 
-''​%% tc class add dev ppp0 parent 1:​ classid 1:​1 htb rate 550kbit ceil 550kbit%%''​\\ +tc qdisc add dev ppp0 root handle 1:​ htb r2q 1 
-''​%% %%''​\\ +tc class add dev ppp0 parent 1:​ classid 1:​1 htb rate 550kbit ceil 550kbit 
-''​%% tc class add dev ppp0 parent 1:​1 classid 1:​10 htb rate 76kbit ceil 110kbit prio 0%%''​\\ + 
-''​%% tc class add dev ppp0 parent 1:​1 classid 1:​20 htb rate 170kbit ceil 495kbit prio 1%%''​\\ +tc class add dev ppp0 parent 1:​1 classid 1:​10 htb rate 76kbit ceil 110kbit prio 0 
-''​%% tc class add dev ppp0 parent 1:​1 classid 1:​30 htb rate 106kbit ceil 440kbit prio 4%%''​\\ +tc class add dev ppp0 parent 1:​1 classid 1:​20 htb rate 170kbit ceil 495kbit prio 1 
-''​%% tc class add dev ppp0 parent 1:​1 classid 1:​40 htb rate 84kbit ceil 440kbit prio 4%%''​\\ +tc class add dev ppp0 parent 1:​1 classid 1:​30 htb rate 106kbit ceil 440kbit prio 4 
-''​%% tc class add dev ppp0 parent 1:​1 classid 1:​50 htb rate 76kbit ceil 522kbit prio 4%%''​\\ +tc class add dev ppp0 parent 1:​1 classid 1:​40 htb rate 84kbit ceil 440kbit prio 4 
-''​%% tc class add dev ppp0 parent 1:​1 classid 1:​666 htb rate 38kbit ceil 550kbit prio 7%%''​\\ +tc class add dev ppp0 parent 1:​1 classid 1:​50 htb rate 76kbit ceil 522kbit prio 4 
-''​%% %%''​\\ +tc class add dev ppp0 parent 1:​1 classid 1:​666 htb rate 38kbit ceil 550kbit prio 7 
-''​%% tc qdisc add dev ppp0 parent 1:​10 handle 4210:​ sfq perturb 10 limit 50%%''​\\ + 
-''​%% tc qdisc add dev ppp0 parent 1:​20 handle 4220:​ sfq perturb 10 limit 50%%''​\\ +tc qdisc add dev ppp0 parent 1:​10 handle 4210:​ sfq perturb 10 limit 50 
-''​%% tc qdisc add dev ppp0 parent 1:​30 handle 4230:​ sfq perturb 10 limit 64%%''​\\ +tc qdisc add dev ppp0 parent 1:​20 handle 4220:​ sfq perturb 10 limit 50 
-''​%% tc qdisc add dev ppp0 parent 1:​40 handle 4240:​ sfq perturb 10 limit 128%%''​\\ +tc qdisc add dev ppp0 parent 1:​30 handle 4230:​ sfq perturb 10 limit 64 
-''​%% tc qdisc add dev ppp0 parent 1:​50 handle 4250:​ sfq perturb 10 limit 64%%''​\\ +tc qdisc add dev ppp0 parent 1:​40 handle 4240:​ sfq perturb 10 limit 128 
-''​%% tc qdisc add dev ppp0 parent 1:​666 handle 666:​ sfq perturb 10 limit 128%%''​\\ +tc qdisc add dev ppp0 parent 1:​50 handle 4250:​ sfq perturb 10 limit 64 
-''​%% %%''​\\ +tc qdisc add dev ppp0 parent 1:​666 handle 666:​ sfq perturb 10 limit 128 
-''​%% tc filter add dev ppp0 parent 1:​0 protocol ip prio 20 handle 20 fw flowid 1:​20%%''​\\ + 
-''​%% tc filter add dev ppp0 parent 1:​0 protocol ip prio 10 handle 10 fw flowid 1:​10%%''​\\ +tc filter add dev ppp0 parent 1:​0 protocol ip prio 20 handle 20 fw flowid 1:​20 
-''​%% tc filter add dev ppp0 parent 1:​0 protocol ip prio 30 handle 30 fw flowid 1:​30%%''​\\ +tc filter add dev ppp0 parent 1:​0 protocol ip prio 10 handle 10 fw flowid 1:​10 
-''​%% tc filter add dev ppp0 parent 1:​0 protocol ip prio 40 handle 40 fw flowid 1:​40%%''​\\ +tc filter add dev ppp0 parent 1:​0 protocol ip prio 30 handle 30 fw flowid 1:​30 
-''​%% tc filter add dev ppp0 parent 1:​0 protocol ip prio 50 handle 50 fw flowid 1:​50%%''​\\ +tc filter add dev ppp0 parent 1:​0 protocol ip prio 40 handle 40 fw flowid 1:​40 
-''​%% %%''​\\ +tc filter add dev ppp0 parent 1:​0 protocol ip prio 50 handle 50 fw flowid 1:​50 
-''​%% tc filter add dev ppp0 parent 1:​0 protocol ip prio 666 handle 666 fw flowid 1:​666%%''​\\ + 
-''​%% tc filter add dev ppp0 parent 4210:​ protocol ip handle 10 flow hash keys nfct-src divisor 1024%%''​\\ +tc filter add dev ppp0 parent 1:​0 protocol ip prio 666 handle 666 fw flowid 1:​666 
-''​%% tc filter add dev ppp0 parent 4220:​ protocol ip handle 20 flow hash keys nfct-src divisor 1024%%''​\\ +tc filter add dev ppp0 parent 4210:​ protocol ip handle 10 flow hash keys nfct-src divisor 1024 
-''​%% tc filter add dev ppp0 parent 4230:​ protocol ip handle 30 flow hash keys nfct-src divisor 1024%%''​\\ +tc filter add dev ppp0 parent 4220:​ protocol ip handle 20 flow hash keys nfct-src divisor 1024 
-''​%% tc filter add dev ppp0 parent 4240:​ protocol ip handle 40 flow hash keys nfct-src divisor 1024%%''​\\ +tc filter add dev ppp0 parent 4230:​ protocol ip handle 30 flow hash keys nfct-src divisor 1024 
-''​%% tc filter add dev ppp0 parent 4250:​ protocol ip handle 50 flow hash keys nfct-src divisor 1024%%''​\\ +tc filter add dev ppp0 parent 4240:​ protocol ip handle 40 flow hash keys nfct-src divisor 1024 
-''​%% tc filter add dev ppp0 parent 666:​ protocol ip handle 666 flow hash keys nfct-src divisor 1024%%''​+tc filter add dev ppp0 parent 4250:​ protocol ip handle 50 flow hash keys nfct-src divisor 1024 
 +tc filter add dev ppp0 parent 666:​ protocol ip handle 666 flow hash keys nfct-src divisor 1024 
 +</​code>​
  
 ===== The full script ===== ===== The full script =====
fair_traffic_shaping_an_adsl_line_for_a_local_network_using_linux.txt · Last modified: 2018/12/06 22:02 by abeverley