Following situation:

  • Network A is connected to network B over an slow connection.
  • Different hosts in network A would like to send traffic to hosts in network B.
  • Hosts in network B sending commands to network A.

What to do:

  • Allow hosts in network A to send data with an average of 0.3 MBit/s and an maximum 0.5MBit/s. i would like to use token bucket for that.
  • Send TCP acknowledgements with priority from A to B. The commands from network B will be send with TCP. I don't want to block the command-transmission then the clients using the hole brandwith for data-transmission from A->B.

The gateway router are linux systems with two interfaces. I figured out that i can use tc to configure traffic shaping.

My Commands:

sudo tc qdisc add dev eth0 handle 1: root tbf rate 300000  burst 500000  latency 1ms

A speedtest with iperf gave me 265 Kbits/sec as result.

Question: How can i set the correct tc rules for limiting traffic per client and prioritisation TCP ACK?


There would be so much to ask to properly answer, and so many possible implmentations, I'll just make some asumptions and propose one solution you could modify later.

You could use TCP flags and conntrack, the connection machine in the linux kernel, to find which connections are B to A tcp ones. Then, you could mark them in the connection machine with CONNMARK target. This way, and with -j CONNMARK --restore-mark target, when a packet in this connection is going in the A to B direction, it will be marked 100.

TC side, I'm using htb as a classful QDISC. HTB class will drop packets if there is too much traffic. fq_codel is used as a queue. fq_codel does organize queues in each class.

The root htb qdisc send packet which are not marked in class 1:1000. Marked packets will go in 1:100. tc filter is used to recognize marked 100 packets and send them into class 1:100.

tc class is used to set the limit bandwidth.

The following code is assuming your max bandwidth is 1Mb/s, your network B interface is eth0, your A network is eth1, and your layer to is ethernet.

# Spread connmark to mark
iptables -t mangle -A POSTROUTING -o eth0 -j CONNMARK --restore-mark

# New TCP connections from B to A : connmark 100
iptables -t mangle -A POSTROUTING -o eth1 -p tcp --syn -m state --state NEW -j CONNMARK --set-mark 100

# Interface : eth0, qdisc : htb, default leaf : 1000
tc qdisc add dev eth0 root handle 1:0 htb default 1000

# Interface eth0, parent branch node : 1:0, branch id : 1:10
tc class add dev eth0 parent 1:0 classid 1:10 htb rate 1000kbit ceil 1000kbit

# CLASS - B to A TCP branch
tc class add dev eth0 parent 1:10 classid 1:100 htb rate 700kbit ceil 1000kbit burst 5k prio 0 linklayer ethernet
# QDISC - Queue
tc qdisc add dev eth0 parent 1:100 handle 110: fq_codel
# FILTER - Filter
tc filter add dev eth0 parent 1:0 protocol ip prio 0 handle 100 fw flowid 1:100

# CLASS - Default branch
tc class add dev eth0 parent 1:10 classid 1:200 htb rate 300kbit ceil 500kbit burst 5k prio 7 linklayer ethernet
# QDISC - default branch queue
tc qdisc add dev eth0 parent 1:1000 handle 1010: fq_codel

I might not be as clear as I would want to B, ask me anything you don't understand.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.