I have a Linux box being used as a router. It has 2x interfaces, one which connects to the internet (it uses NAT) and one which connects to a local network serving multiple computers.

I would like to use 'tc' to be able to shape traffic going out to the internet from the local computers (upload), and police the traffic coming in (download) for each computer based on its IP address. Normally I would add an egress shaper and an ingress policer to the external interface, the trouble is that I have a squid proxy sitting on the server which the local computers connect to in order to access the web.

If I mark packets with iptables as they leave the local network interface it makes no difference to web traffic because the marks get lost when squid intercepts and creates its own connection to the web on a different port. Likewise policing the incoming traffic doesn't work because the web traffic is always destined for squid so I can't match on IP address.

So far I've managed a 90% successful work around by adding an egress shaper to the internal interface which limits download speed to each local computer based on their IP. This doesn't save line speed of course, it just creates a queue so that each computer only sees a certain download speed. For the upload I mark packets as they leave the local network and use a shaper on the egress of the external interface to shape them, but this won't work with web traffic from squid.

Has anyone else come across a similar issue, or know how I could shape upload traffic that has a destination port 80 when squid is intercepting it?

  • How are you setting the mark? Per IP address, per service? – Diego Woitasen Apr 19 '12 at 11:40
  • Hi, I'm setting the marks with iptables with a class based on the ip address as follows: iptables -t mangle -A PREROUTING -i eth0 -j MARK --set-mark 100 – Jak Apr 19 '12 at 12:27

I managed to create a work-around for this by using an Ingress policer on the internal interface which drops excess packets from the local computers to Squid. I could only get it working with a variable buffer size though. Strange.


You have to mark you packets again inside Squid with TOS with tcp_outgoing_tos. Is the only way to match IPs before and after Squid.

acl tosX src x.x.x.1 x.x.x.2 x.x.x.3
tcp_outgoing_tos 0x20 toxX

Then you have to use the TOS filter in tc.

  • Thanks for this, the only trouble is that I never know what the IP address is before an internal computer makes a connection (its on DHCP), so I guess I'd need a preset list of IP addresses and marks for every possible scenario, which would be thousands of lines :-( – Jak Apr 23 '12 at 8:35

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.