Thanks for the pointer to those guidelines, very helpful. I also found the
information at http://ace-host.stuart.id.au/russell/files/tc/doc/cls_u32.txt to
be very useful, although quite outdated.

For reference, the below is what I ended up with:

ETH="eth0"
EST="est 1sec 4sec"
BUCKETS=64
RATE="100Mbit"

tc qd del dev $ETH root 2>/dev/null

tc qdisc add dev $ETH root handle 8000: $EST htb r2q 1000 default 0
tc filter add dev $ETH parent 8000: protocol ip u32
tc filter add dev $ETH parent 8000: handle 2: protocol ip u32 divisor
${BUCKETS}

for i in $( seq 1 $BUCKETS ); do

   BUCKET=$( printf %x $((i)) )
   BUCKETM1=$( printf %x $((i-1)) )

   tc class add dev $ETH parent 8000: classid 8000:${BUCKET} ${EST} htb
rate ${RATE}
   tc qdisc add dev $ETH parent 8000:${BUCKET} handle ${BUCKET}: $EST
fq_codel
   tc filter add dev $ETH protocol ip parent 8000: u32 ht 2:${BUCKETM1}: \
      match u32 0 0 flowid 8000:${BUCKET}

done

tc filter add dev $ETH protocol ip parent 8000: u32 ht 800:: \
   match ip protocol 6 0xff \
   match ip sport 8081 0xffff \
   hashkey mask 0x0000ffff at 20 \
   link 2:


It seems to work pretty well in testing so far, but it certainly has some
flaws. The biggest is that hashing is now based solely on destination port
(ephemeral in our case, so not too bad), and it assumes that the IP header
has no options. Also, the filter lists inside the 2: hash table still have
to have a match run against them to direct them to a classid, which seems a
waste, but I can't imagine the always-match rule of "u32 0 0" adds much
overhead.

Thanks again,

Sam



On 10 July 2013 14:34, Eric Dumazet <eric.duma...@gmail.com> wrote:

> On Wed, 2013-07-10 at 11:53 +0100, Sam Crawford wrote:
> > Thanks Eric! I've adapted this to the following:
> >
> >
> > ETH="eth1"
> > EST="est 1sec 4sec"
> > BUCKETS=64
> > RATE="100Mbit"
> >
> >
> > tc qd del dev $ETH root 2>/dev/null
> >
> >
> > tc qdisc add dev $ETH root handle 8000: $EST htb r2q 1000 default 8000
> >
> >
> > for i in $( seq 1 $BUCKETS ); do
> >    BUCKET=$( printf %x $((i)) )
> >    tc class add dev $ETH parent 8000: classid 8000:${BUCKET} ${EST}
> > htb rate ${RATE}
> >    tc qdisc add dev $ETH parent 8000:${BUCKET} handle ${BUCKET}: $EST
> > fq_codel
> > done
> >
> >
> > tc filter add dev $ETH parent 8000: handle 7000 protocol ip flow hash
> > keys src,dst,proto-src,proto-dst baseclass 8000:1 divisor ${BUCKETS}
> >
> >
> If dst port is always 8081, you can omit proto-dst from the hash keys
>
>
>
> >
> > This seems to deliver the behaviour I'm looking for - each flow is
> > effectively rate limited to 100Mbit/s, and multiple flows between the
> > same src and dst can achieve this rate (unless they're unlucky and
> > fall into the same bucket, which is not too bad). Have I made any
> > silly mistakes in there?
> >
>
> > The final thing I'm struggling to work out is how to limit this rule
> > to a single service. Ideally the rate limiting should only apply to
> > TCP/8081. It seems you cannot combine different filter types (i.e. the
> > u32 match + the flow match). Any suggestions?
> >
> Please follow guidelines in
>
> http://www.tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.adv-filter.hashing.html
> >
> Because you need a more specialized setup than a single 'flow hash'
>
> > Apologies for going OT on the list... I hope this topic is useful to
> > others Googling for it in the future.
> >
> >
> No problem ;)
>
>
>
>
------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit 
http://communities.intel.com/community/wired

Reply via email to