Anyone has a good tutorial on how to implement fair nat?
Basicly I want my children to have to share the use of the internet.
Topic: Fair nat
The content of this topic has been archived on 4 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.
anyone,
Do you mean you want your children to get a fair share of the bandwidth?
In that case, QoS (Quality of Service) is what you're looking for:
QoSHowto
Do you mean you want your children to get a fair share of the bandwidth?
In that case, QoS (Quality of Service) is what you're looking for:
QoSHowto
No the problem is that my oldest son is using 10 sites at the same time.
Or he is on msn, downloading etc.
And my other kids just open 1 page.
Then my oldest son will have 10/11 bandwith and my other kid just 1/11 of the available bandwith.
With fair nat both will have 50/50 bandwith.
Without fair nat it is connection based. The more connections the more bandwith.
I'm using Fair NAT on OpenWRT, you can get the script from my page http://www.metamorpher.de/fairnat/ - see the OpenWRT version there.
You will however need some knowledge about Linux and QoS in order to customize it to your needs. Fair NAT is something I made for my personal use, I don't have the time to maintain it for general purpose use anymore.
I'm using Fair NAT on OpenWRT, you can get the script from my page http://www.metamorpher.de/fairnat/ - see the OpenWRT version there.
You will however need some knowledge about Linux and QoS in order to customize it to your needs. Fair NAT is something I made for my personal use, I don't have the time to maintain it for general purpose use anymore.
I understand but trying to implement it on my work too now and you must define the users for the script. I am looking for a script that would do it dynamicly.
So if 3 users are connected all gets 33%
10 users then they get 10%
and that without changing the configs.
Willing to pay a programmer for it. So if anyone is interested u may pm me.
Well, HTB does it dynamically. Even though there are two users in my config, if only one is online he will get 100% because that's the way the scheduler works. So if you have 10 users max you can configure it for 10 users, and it will still work if only 3 are using it with 33% for each. That's the whole idea. Dynamically adding users on the fly would require some means of authentication or some other way that allows the router to detect when there is a new user, or old user no longer there. Plus you would have to re-create the shaping and iptables rules every time a user is added / removed. Such a feature was requested for Fair NAT once but I never got around to implementing it, and now I'm not planning to do so either. For 10 users it shouldn't be necessary anyway, and if it's just for the kids / your home network, it's simply the wrong approach, as it adds too much complexity for very little profit.
Well, HTB does it dynamically. Even though there are two users in my config, if only one is online he will get 100% because that's the way the scheduler works. So if you have 10 users max you can configure it for 10 users, and it will still work if only 3 are using it with 33% for each. That's the whole idea. Dynamically adding users on the fly would require some means of authentication or some other way that allows the router to detect when there is a new user, or old user no longer there. Plus you would have to re-create the shaping and iptables rules every time a user is added / removed. Such a feature was requested for Fair NAT once but I never got around to implementing it, and now I'm not planning to do so either. For 10 users it shouldn't be necessary anyway, and if it's just for the kids / your home network, it's simply the wrong approach, as it adds too much complexity for very little profit.
Ok it is ok for my kids but I want to implement the same thing for my chillispot.
Hi Belrpr, not sure if the above is still an issue for you but you should be able to implement what you want using the esfq queing discipline. Basicly its sfq with the ability added to schedule fairly on a client basis (i.s.o a connection basis). Its provided by the package kmod_sched . I have not used it but intent to give it a try, for the same purpose as you mentioned (fair bandwidth sharing on a hotspot ). First however i'll try frostschutz fairnat (for two users) to get sort of a benchmark of what to expect.
Btw esfq is not yet part of the latest linux kernel (2.6.25) and it is not supported by shorewall. Whether it ever will or if the functionality will be integrated into sfq is still an open issue as far as I can tell.
PS: If it matters I'm using kamikaze 7.09
The following is guesswork as I never used esfq:
esfq should be able to handle many more clients than my fair nat HTB approach (since you don't have to create a class for every client), but you can't add traffic prioritization (because you can't create a class with subclasses for every client that does this in the HTB approach). You could do the traffic prioritization first but then it already won't be fair anymore, whoever uses more different kinds of bandwidth gets more bandwidth. I have only four static ip clients so I prefer the class based approach, as it gives you finer control over things. Of course that's only good if you know what to do when you have to control something. esfq on the other hand should be pretty much a zero config approach...
I'd love to hear what worked out best for you in the end
Frostschutz, belrpr,
I did some test using a setup with two clients (read:laptops) :
Client A has 20 download sessions running, implemented with netcat, simulating a p2p user.
Client B has an ftp download in progress. Here is the summary of my testresults and the settings used.:
----------------------------------------------------------------------------------
Trafficshaping:None
Client B gets about 5% of the total bandwdith. This what I would expect as about 5% of the connects belong to B.
Settings:
tc qdisc add dev $DEVICE root handle 1: htb default 1
tc class add dev $DEVICE parent 1: classid 1:1 htb rate $TOTRATE"kbit" \
ceil $TOTRATE"kbit" mpu 96 overhead 50 quantum 1600
----------------------------------------------------------------------------------
Trafficshaping:FairNat (my implementation of it)
Client B gets about 30% of the total bandwdith. Not sure why its not at 50% here. I would expect any bandwidth over USRRATE(x2) would be distributed fairly over A and B. .
Settings:
# Create the qdisc
tc qdisc add dev $DEVICE root handle 1: htb default 30
# Create the root class
tc class add dev $DEVICE parent 1: classid 1:1 htb rate $TOTRATE"kbit" \
ceil $TOTRATE"kbit" mpu 96 overhead 50 quantum 1600
# 'local' qdisc
tc class add dev $DEVICE parent 1:1 classid 1:30 htb rate $LOCRATE"kbit" \
ceil $TOTRATE"kbit" mpu 96 overhead 50 quantum 1600
tc qdisc add dev $DEVICE parent 1:30 handle 300: prio
# Create class for clientA @ 243
tc class add dev $DEVICE parent 1:1 classid 1:10 htb rate $USRRATE"kbit" \
ceil $TOTRATE"kbit" mpu 96 overhead 50 quantum 1600
tc qdisc add dev $DEVICE parent 1:10 handle 100: prio
tc filter add dev $DEVICE parent 1: prio 1 protocol ip handle 0x10 fw flowid 1:10
# Create class for ClientB @ 245
tc class add dev $DEVICE parent 1:1 classid 1:20 htb rate $USRRATE"kbit" \
ceil $TOTRATE"kbit" mpu 96 overhead 50 quantum 1600
tc qdisc add dev $DEVICE parent 1:20 handle 200: prio
tc filter add dev $DEVICE parent 1: prio 1 protocol ip handle 0x20 fw flowid 1:20
# Now to mark the packets appropriately:
iptables -t mangle -A POSTROUTING -p tcp -d 192.168.163.243 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p tcp -d 192.168.163.245 -j MARK --set-mark 0x20
----------------------------------------------------------------------------------
Trafficshaping:ESFQ
Client B gets about 50% of the total bandwdith. What I would expect
Settings:
# create the qdisc
tc qdisc add dev $DEVICE root handle 1: htb default 1
# create the root class
tc class add dev $DEVICE parent 1: classid 1:1 htb rate $TOTRATE"kbit" \
ceil $TOTRATE"kbit" mpu 96 overhead 50 quantum 1600
tc qdisc add dev $DEVICE parent 1:1 handle 100: esfq hash dst perturb 20
----------------------------------------------------------------------------------
Prelimanary concusion is that esfq is quite fair indeed and like frostschutz said 'pretty much a zero config approach'
. Next step is to add traffic prioritization for ssh,acks, dns etc. I think I would indeed loose a bit of fairness that I would have using fairnat (as frostschutz points out above) but thats ok; Primarily I want my hotspot to be hogproof.
The marking rules confuse me just a little; did you shape download traffic only, since you're using -d $LOCALIP and not -s? (and tcp only?). Download control is inaccurate because you can't really influence what other people send to you. If it's upload, then it should be fair (if USRRATE*2+LOCRATE == TOTRATE in this case). If it's not, then TOTRATE may be too large (HTB believes it can send more than it actually can) or some packets may end up in the wrong class.
To be clear the $DEVICE above is the lan-side device (br-lan on openwrt). I suspect this is a bad decision primarily because other examples I find on the internet sofar are always shaping on the wan device (and/or like yourself on imq). I am sure youre right in saying so but sofar I do not understand how "Download control is inaccurate because you can't really influence what other people send to you" ; Is it not the case that when I shape on the lan-side device using 'Trafficshaping:ESFQ' above any traffic over the alloted share will be dropped and thus slows the download (i.e. the data comming in on the wan por ) by not sending an ack) ?
The "-p tcp" was indeed a mistake as I was also using udp (ftp) in my tests. All in all my measerument of 30% above using the fair nat approach can be safly disregarded as being unreliable:).
Another remarkable difference btw between Trafficshaping:None and Trafficshaping:ESFQ. If I start a download from one client (the other is inactive) then with the latter I get a very very stable download rate. With the first the rate is very erratic.
After (quite) some experimenting I think below script is my final implementation of 'fair nat'
-----------------------------------------------------------------
#!/bin/sh -x
LANDEV=br-lan
WANDEV=eth0.1
DOWNLINK=4000
UPLINK=600
HALFUPLINK=300
LOWLATENCY="1:10"
SMALLACKS="1:20"
BULK="1:30"
#UPLINK
tc qdisc add dev $WANDEV root handle 1: htb default 30
tc class add dev $WANDEV parent 1: classid 1:1 htb rate ${UPLINK}kbit burst 6k
tc class add dev $WANDEV parent 1:1 classid ${LOWLATENCY} htb rate 100kbit ceil ${HALFUPLINK}kbit burst 6k prio 1
tc class add dev $WANDEV parent 1:1 classid ${SMALLACKS} htb rate 100kbit ceil ${HALFUPLINK}kbit burst 6k prio 2
tc class add dev $WANDEV parent 1:1 classid ${BULK} htb rate 100kbit ceil ${UPLINK}kbit burst 6k prio 3
tc qdisc add dev $WANDEV parent ${LOWLATENCY} handle 10: pfifo limit 10
tc qdisc add dev $WANDEV parent ${SMALLACKS} handle 20: pfifo limit 10
tc qdisc add dev $WANDEV parent ${BULK} handle 30: esfq hash ctorigsrc perturb 10
tc filter add dev $WANDEV protocol ip parent 1:0 prio 102 handle 0x10 fw classid ${LOWLATENCY}
tc filter add dev $WANDEV protocol ip parent 1:0 prio 102 handle 0x30 fw classid ${BULK}
tc filter add dev $WANDEV protocol ip parent 1:0 prio 101 u32 \
match ip protocol 6 0xff \
match u8 0x05 0x0f at 0 \
match u16 0x0000 0xffc0 at 2 \
match u8 0x10 0xff at 33 \
flowid ${SMALLACKS}
iptables -t mangle -A POSTROUTING -p tcp --dport 5900 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p udp --dport 5900 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p tcp --dport 21 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p udp --dport 21 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p tcp --sport 22 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p tcp --dport 22 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p udp --dport 22 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p tcp --dport 23 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p udp --dport 23 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p tcp --dport 53 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p udp --dport 53 -j MARK --set-mark 0x10
iptables -t mangle -A POSTROUTING -p icmp -j MARK --set-mark 0x10
#DOWNLINK
tc qdisc add dev $LANDEV root handle 1: htb default 1
tc class add dev $LANDEV parent 1: classid 1:1 htb rate $DOWNLINK"kbit"
tc qdisc add dev $LANDEV parent 1:1 handle 100: esfq hash dst perturb 10
-----------------------------------------------------------------
Feel free to comment and point out where theres room for improvement or /corrections still.
The discussion might have continued from here.
