I couldn't make the question any clearer so here's an example scenario:

Given a Linux machine connected to an IP network through a physical interface of bandwidth 10Mbps (or a higher speed interface with a tc token bucket filter to limit the rate to 10Mbps).

On a remote machine (with an equal speed or faster link) start an iperf UDP server:

iperf -s -u -i 1

On the local machine start an iperf client with bw=20Mbps:

iperf -c <server ip> -u -i 1 -b 20M

Observation: The sender never exceeds the 10Mbps rate (defined in the link layer either in hardware or a tc qdisc).

I expected to see the sender push out 20Mbits worth of packets a second causing the local tx queue of the interface to build up and packet losses start to happen. But this is not the case. Why?

I have tried to look into the net/sched folder to the Linux kernel but I can't seem to find the source of this behavior.

Appreciate you help. Also feel free to suggest changes to the title to make it more relevant.


This is due to a procedure called Autonegotiation, which happens at the physical layer. As far as the kernel is concerned, that link (connection) can only handle a bandwidth of 10 Mbps, and iperf presumably respects that maximum connection speed.

The good folks over at https://networkengineering.stackexchange.com/ can probably go into more detail if you have more questions about that interaction.

| improve this answer | |
  • 1
    Autonegotiation applies only for interfaces. I have observed the same behavior for bandwidth limitations applied using the token bucket filter inside the Kernel. – Rango Feb 28 '15 at 0:07
  • Even in that case, the answer is still 'iperf respects the maximum connection speed reported by the kernel,' no? Sorry for misinterpreting. – rmelcer Feb 28 '15 at 0:18
  • I have tried with netcat and I can see the same behavior. I don't think netcat is doing any kind of throttling inside the application. I don't have the problem with the answer "the application respects the connection speed reported by the kernel", however I would like to find the kernel code responsible for this behavior - if that's the case. – Rango Mar 2 '15 at 17:24

The local machine is limited to the bandwidth of the NIC, which is passed up from the NIC to the stack. You will have throttling of the flow based on that value.

You can try parallel streams (-P) option to create multiple streams, each limited to the NIC speed, but all trying to push 10mb/s

| improve this answer | |
  • What stream? This is UDP, and expecting outbound packet drops seems reasonable. Even if it was TCP, iperf should be nonblocking and we'd expect to hit the EAGAIN/EWOULDBLOCK path rather than simply waiting. – Useless Jan 8 at 16:07
  • Stream as in the 5-tuple flow. A stream/flow is limited to the BW of the interface. The trick is to push multiple streams at the same time, with an aggregate larger then the nic BW – Kevin Jan 8 at 16:52
  • Here is the line from the help text -P, --parallel # number of parallel client streams to run – Kevin Jan 8 at 18:14

Roughly speaking, in general packets are held in what we call buckets, in a store-and-forward-like manner, and sent over time through the network, ensuring a predefined bandwidth. They're not always discarded. That's why depending which QoS method you're using, the amount of clients you're watching, and the general config, the CPU and memory costs can quickly escalate.

We can implement QoS (Quality of Service) in several OSI levels. We can do that in Squid Proxy Server, in a RouterOS interface, or privileging specific network protocols through their respective ports.

Best regards.

| improve this answer | |

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.