[LARTC] Shaping traffic over a linux bridge
Hugh Buchanan
isp-lists@userfriendly.com
Thu, 29 May 2003 10:31:26 -0700
I have since fixed my problem. I am not sure if it's useful to anyone,
but I'll briefly describe what I did to get it working.
In the end, I am not using the 'iptables' program at all. I am using
ebtables to mangle the packets on eth1 as they come in. What I was
doing before with ebtables was mostly right.. I have pretty simple
ebtable lines that mark the packets. Packet marks can be 32 bits.
And my shaping is very different now too.. I shape on the outside (eth0)
interface.. I can shape incoming traffic going over the eth1 interface
as well, although I don't need it.
I also find that cbq doesn't work too happily.. HTB works like a charm,
and really is more useful for my application. I ended up needing to use
the 'tc' binary supplied by the HTB people.
I am not completely done yet.. but at the very least it works.. it is
now just a matter of setting up all of the classes/rules for the 200+
MAC addresses I'll be shaping.
Hugh
Hugh Buchanan wrote:
> I should add some additional comments.
>
> I have gone through most of the LARTC archives dealing with tc.. it
> seems a lot of people have attempted this, but no one ever posts
> solutions to these things.
>
> There are a bunch of archive posts I found somewhat helpful.
> http://lists.netfilter.org/pipermail/netfilter/2002-May/034041.html
> http://mailman.ds9a.nl/pipermail/lartc/2003q1/007571.html
>
> Using those two posts, I decided to give u32 filtering a try to avoid
> the mangling confusion I have.. and it doesn't seem to change much.
>
> Shaping works perfectly using NAT/MASQUERADE and iptables mangling.
> When I throw bridging into the mix it stops working.
>
> I have yet to try a 2.5.x kernel.. I would prefer not to, but I
> suppose since I have no ideas right now on how to proceed, I better
> try 2.5.x.
>
> If anyone figures this out, send me your address.. i'll send you a box
> of cookies or something.
>
> Hugh
>
> Hugh Buchanan wrote:
>
>> Greetings,
>>
>> I am using tc/cbq to do some traffic shaping over a linux bridge. My
>> system is running the 2.4.20 kernel with the latest bridge-nf and
>> ebtables patches. I am also running ebtables 2.0.3 and iptables 1.2.8.
>>
>> Last week, since I had yet to discover ebtables/bridging I was testing
>> the shaping with a basic NAT setup using totally seperate networks on
>> each ethernet interface.
>>
>> I now have a fully functional bridge. I was amazed to see how easy it
>> is! I love it!
>>
>> But now I am trying to add tc back into the mix. I have looked at the
>> simple and real life examples, and a typical mark line would be
>> something like
>> ebtables -A FORWARD -p ipv4 -i eth0 -j mark --set-mark 2 --mark-target
>> CONTINUE
>>
>> So now I have two questions.
>>
>> How many bits are available for marking? On docum.org, I saw examples
>> for mark values up to '5', which leads me to assume that there are at
>> least 3 bits, meaning I can mark up to '7' (or is it '8'?). What is the
>> numeric range here?
>>
>> And what I am wanting to do is possible, right? I haven't found any
>> real life examples for traffic shaping over a bridge yet (links
>> appreciated). I have found this though:
>> "When you create a bridge with the bridge-utils, you get a new device :
>> br0. You can shape traffic on this device, but you can not use iptables
>> to mark packets and the fw filter to use that mark. But you can use the
>> u32 filter."
>>
>> Does this mean I need to use some other process besides normal mangling?
>>
>> What it comes down to are two issues (that are almost the same). I
>> don't know how to mark packets coming in from the LAN, and I don't know
>> which interface to bind tc to.
>>
>> Here is a diagram of my setup:
>>
>> 64.119.201.0/24 ---- eth1 [bridge, br0] eth0 ---- 64.119.201.1 (router)
>>
>> And here is the script I am playing with. I have tried binding tc and
>> ebtables and iptables to all three interfaces (eth0,eth1,br0) and it
>> doesn't seem to change anything.. but then again I don't know if my
>> packets are even being marked. Should I be using a 2.5.x kernel instead
>> of the patched 2.4.20? I need this for production use.. stability is
>> important.
>>
>> #!/bin/sh
>> OUTSIDE="eth0"
>> INSIDE="eth1"
>> BRIDGE="br0"
>> LAN="64.119.201.0/24"
>> OPTION="allot 1514 maxburst 20 avpkt 1000 prio 3"
>>
>> ebtables -P INPUT ACCEPT
>> ebtables -P OUTPUT ACCEPT
>> ebtables -P FORWARD ACCEPT
>> ebtables -F
>> ebtables -t nat -F
>>
>> iptables -P INPUT ACCEPT
>> iptables -P OUTPUT ACCEPT
>> iptables -P FORWARD ACCEPT
>> iptables -F
>> iptables -t nat -F
>>
>> echo "Loading ebtables rules"
>> ebtables -A FORWARD -p ipv4 -i eth1 --ip-source 64.119.201.114 -j mark
>> --set-mark 2 --mark-target CONTINUE
>> ebtables -A FORWARD -p ipv4 -j mark --set-mark 1 --mark-target CONTINUE
>>
>> echo "Loading iptables rules"
>> iptables -A PREROUTING -i eth1 -s $LAN -t mangle -j MARK --set-mark 1
>> iptables -A PREROUTING -i eth1 -t mangle -j MARK --set-mark 2
>>
>> ###############################################################################
>> # i have tried $INSIDE, $OUTSIDE, and $BRIDGE here
>> DEV="dev $INSIDE"
>> RATE_TOT=10kbit
>> SERVERS=500kbit
>> SERVERS_WEIGHT=50kbit
>> GEN=50kbit
>> GEN_WEIGHT=5kbit
>>
>> echo "Clearing qdiscs"
>> tc qdisc del dev br0 root
>> tc qdisc del dev eth0 root
>> tc qdisc del dev eth1 root
>>
>> echo "Inserting qdiscs"
>> tc qdisc add $DEV root handle 10: cbq bandwidth $RATE_TOT avpkt 1000
>> tc class add $DEV parent 10:0 classid 10:2 cbq bandwidth $RATE_TOT rate
>> $RATE_TOT $OPTION bounded
>>
>> tc qdisc add $DEV parent 10:2 handle 20: cbq bandwidth $RATE_TOT allot
>> 1514 avpkt 1000
>> tc class add $DEV parent 20: classid 20:2 cbq bandwidth $RATE_TOT rate
>> $RATE_TOT $OPTION prio 3
>> tc class add $DEV parent 20:2 classid 20:10 cbq bandwidth $RATE_TOT rate
>> $SERVERS $OPTION weight $SERVERS_WEIGHT bounded
>> tc class add $DEV parent 20:2 classid 20:20 cbq bandwidth $RATE_TOT rate
>> $GEN $OPTION weight $GEN_WEIGHT bounded
>>
>> echo "Adding tc filters"
>> tc filter add $DEV parent 10: protocol ip prio 3 handle 1 fw classid
>> 10:2
>> tc filter add $DEV parent 10: protocol ip prio 3 handle 2 fw classid
>> 10:2
>>
>> tc filter add $DEV parent 20: protocol ip prio 3 handle 1 fw classid
>> 20:20
>> tc filter add $DEV parent 20: protocol ip prio 3 handle 2 fw classid
>> 20:10
>>
>> echo "eth0:"
>> tc -s qdisc ls dev eth0
>> echo "eth1:"
>> tc -s qdisc ls dev eth1
>> echo "br0:"
>> tc -s qdisc ls dev br0
>>
>> Hugh Buchanan
>> Userfriendly.com
>