Monday, 24 September 2012

Bandwidth Throttling with NetEM Network Emulation..!!

Bandwidth Throttling with NetEM
NetEM (Network Emulation) provides functionality for testing protocols, by emulating the network properties of wide-area networks. This article describes the use of NetEM in benchmarking the performance of a Web application, simulating Internet-like speeds on a LAN.
On a recent project, I was busy doing a Web application performance benchmark test. For most such benchmarks, it is important to simulate the typical end-user’s average effective bandwidth. Since we used a fast network for our benchmarks, we had to find a way to somehow limit the bandwidth of our LAN so that it would resemble “real” Internet throughputs. It took some research and reading to find the best way to do this. We found that there were commercial shaping products like Allot’s Netenforcer and PacketShaper, but these were costly. So instead of these devices/appliances, we decided to use the NetEM tool.
In our environment (see Figure 1), the NetEM box also plays the role of a Linux router. Recent Linux kernels have built-in network traffic shaping capabilities. Those capabilities, in combination with the command-line tool tc (a part of the iproute2 package) can be used to set a bandwidth limit on one of your network interfaces, and even on incoming traffic on a specific port.
Current environment
Figure 1: Current environment

About traffic shaping

Traffic shaping is an attempt to control network traffic by prioritising network resources. It guarantees certain bandwidth, based on predefined policy rules. Traffic shaping uses traffic classification, policy rules, queue disciplines and quality of service (QoS).
The need for traffic shaping arises because network bandwidth is an expensive resource that is shared among many parties in an organisation, and some applications require guaranteed bandwidth and priority. Traffic shaping lets you: (1) control network services, (2) limit bandwidths, and (3) guarantee Quality of Service (QoS). Intelligently managed traffic shaping improves network latency, service availability and bandwidth utilisation.
NetEM capabilities include delay (it delays each packet); loss (it drops some packets); duplication (it duplicates some packets); and corruption (it introduces a single bit error at a random offset in a packet).

How NetEM works

NetEM consists of two components — a tiny kernel module for a queuing discipline, and a command-line utility to configure it. The kernel module has been integrated in 2.6.8 (and 2.4.28) or later, and the command is part of the iproute2 package. The command-line utility communicates with the kernel via the netlink socket interface. It encodes its requests into a standard message format, which the kernel decodes.
The queuing layer exists between the network device and the protocol output. The default queuing discipline is a simple FIFO packet queue. Queuing discipline consists of two key interfaces; one queues packets to be sent, and the other releases packets to the network device for transmission. The queuing discipline makes the policy decision of which packets to send, based on the current settings.

Terminology

  • qdisc — A queue discipline (qdisc) is a set of rules that determine the order in which arrivals are serviced. It is a packet queue with an algorithm that decides when to send each packet.
  • Classless qdisc — A qdisc with no configurable internal subdivision.
  • Classful qdisc — A qdisc that may contain classes; classful qdiscs allow packet classification (Class-Based Queueing and others)
  • Root qdisc — The root qdisc is attached to each network interface — either classful or classless.
  • egress qdisc — Works on outgoing traffic only.
  • ingress qdisc — Works on incoming traffic.
  • Filter — Classification can be performed using filters
Here are some examples that can be used for network throttling.

Network emulation examples

Note: I have used eth1 for the interface in the examples below; you should use the name of the specific Ethernet card where traffic needs to be throttled.
To add constant delay to every packet going out through a specific interface, use the following command:
# tc qdisc add dev eth1 root netem delay 80ms
Now a ping test to this host should show an increase of 80ms in the delay to replies.
To add random variance, use the command below:
# tc qdisc change dev eth1 root netem delay 80ms 10ms
We can also add variable delay (jitter)/Random Variance too. Most wide-area networks like the Internet have some jitter associated with them. The following command will add +/- 10 ms of jitter to the 80 ms of delay.
# tc qdisc add dev eth1 root netem delay 80ms 10ms
To see what queueing discipline (qdisc) has been applied to an interface, use:
# tc qdisc show dev eth1
To turn off/delete the qdisc from a specific interface (in this case, eth1), execute the command given below:
# tc qdisc del dev eth1 root
Typically, the delay in a network is not uniform. It is more common to use something like a normal distribution to describe the variation in delay. NetEM can accept a non-uniform distribution:
# tc qdisc change dev eth1 root netem delay 100ms 20ms distribution normal
Packet loss can be replicated:
# tc qdisc change dev eth1 root netem loss 0.1%
Packet duplication/corruption can also be configured:
# tc qdisc change dev eth1 root netem duplicate/corrupt 1%

Setting up the throttling

In the current environment (as seen in Figure 1), the Linux server plays the role of a router and a NetEM bandwidth throttling device. All the traffic goes through this server. Our requirement was to throttle the bandwidth by adding delay/packet loss/jitter, etc, and also to throttle incoming traffic on TCP port 7001 on eth1, down to 512 kbit/s.
To set up the throttling for incoming traffic, I ran the following commands:
# tc qdisc add dev eth1 root handle 1: cbq avpkt 1000 bandwidth 10Mbit
# tc class add dev eth1 parent 1: classid 1:1 cbq rate 512kbit allot 1500 prio 3 bounded isolated
# tc filter add dev eth1 parent 1: protocol ip u32 match ip protocol 6 0xff match ip dport 7001 0xffff flowid 1:1
The first command created a new root queuing discipline of type CBQ (class-based queuing, used to both shape and prioritise) on interface eth1, bandwidth set to 10 MBps, and the average size of the packet (avpkt) set to 1000.
The second command created a child class under the root qdisc, 1:, and named it 1:1, allocating 1500 bytes off the queue, and limiting the rate to 512 KBps. The prio 5 defines the priority of the queue. The smaller the number, the higher the priority when you have multiple queues with different priorities. Here I had only a single queue, so that didn’t matter. The bounded and isolated options are used to make sure the class will not borrow bandwidth from any unused/inactive sibling queues.
The last command is the filter, which will queue all packets going to TCP port 7001 [dport is destination port] to qdisc “1:1″ which is the throttle queue. Here u32 is the filter type.

No comments: