Back to my home page

What is dummynet

dummynet is a flexible tool for bandwidth management and for testing networking protocols. It is implemented in FreeBSD but is easily portable to other protocol stacks. There is also a one-floppy version of FreeBSD which includes dummynet and a lot of other goodies, see below. It works by intercepting packets in their way through the protocol stack, and passing them through one or more pipes which simulate the effects of bandwidth limitations, propagation delays, bounded-size queues, packet losses, etc.

Each pipe can be configured separately, and packets are forwarded to the appropriate pipe using the ipfw packet filter. Thus you can apply different limitations/delays to different traffic according to the ipfw rules (e.g. selecting on protocols, addresses and ports ranges, interfaces, etc.).

Download info

How to use it

There are several ways to run dummynet: You have the option to run dummynet on a full FreeBSD install, or (for the last two cases at least) to use a one-floppy version of FreeBSD, called PicoBSD.

PicoBSD install

I have prepared a PicoBSD image containing bridge, router and ipfw. All you need to do is to download the above image file (1.44MB), dump it to a formatted floppy using "dd" or equivalent command, and use that floppy to boot the machine acting as a bridge or router. You can then enable bridging and ipfw with commands like
   sysctl -w net.link.ether.bridge_ipfw=1

   ipfw add pipe 1 ip from hostA to hostB
   ipfw pipe 1 config bw 300kbit/s delay 232ms queue 30 plr 0.001

Full install

dummynet is kernel code plus a user-space configuration program, and it is made of modifications to a few kernel files, as listed in README.dummynet.

To the best of my knowledge this code works fine with natd and ipfw, and has never caused crashes to my system. To get dummynet working, you have to do the following:

  1. Apply the patches for your system, if necessary;
  2. Update the following files in /usr/include (unless they are already links to the same files in the kernel sources):
        cp -p /sys/sys/mbuf.h /usr/include/sys/mbuf.h
        cp -p /sys/netinet/in.h /usr/include/netinet/in.h
        cp -p /sys/netinet/ip_dummynet.h /usr/include/netinet/ip_dummynet.h
        cp -p /sys/netinet/ip_fw.h /usr/include/netinet/ip_fw.h
    
  3. Recompile and reinstall the ipfw program;
  4. Configure and build a kernel with the following options:
    	options IPFIREWALL
    	options DUMMYNET
    	

Use

Dummynet is heavily based on the ipfw package for packet selection. ipfw allows the selection of IP packets (and only them) based on a combination of source and destination addresses and ports, protocol types (e.g. UDP, TCP, ICMP, ...), interface, and direction (in or out). The packet filter can be programmed through a sequence of rules, which are applied in sequence to packets until a match is found. The rule specify the action to be taken, one of them being forward the packet to a dummynet pipe. Multiple rules can point to the same pipe.

A pipe simulates the presence of a communication path, with bandwidth limitations, propagation delays, and bounded-size queues. You can define all these parameters independently for each pipe, e.g.

   ipfw pipe 1 config bw 256Kbit/s delay 300ms queue 10
   ipfw pipe 2 config bw 128KByte/s
   ipfw pipe 3 config bw 80Kbit/s delay 100ms
   ipfw pipe 4 config plr 0.001
you define four pipes with different features (each pipe is identified by a unique, non-zero number). In particular the second one has no delay and unlimited buffers (virtually; in practice there is a configurable hard limit of 100 to avoid consuming all of your memory for packets queued on a pipe). The third one has no bandwidth and buffer limitations, but introduces a delay on packet forwarding. The fourth pipe simulates a lossy path with a packet loss rate (plr) of 0.1% This feature can be useful for testing purposes.

You can omit parameters that are not needed, and issue a command multiple time to reconfigure the features of a pipe on the fly. The usual suffixes of K (1000 bits/s), KB (1000 Bytes/s), M (1000000 bit/s), MB (1000000 Bytes/s) can be used to specify the bandwidth, whereas the "ms" after the delay is just ignored. Queue size is in buffers.

The routing of packets to pipes is done by specifying the action pipe NN to send the packet to a pipe. E.g.:

    ipfw add pipe 2 tcp from my_ip port 80 to any
    ipfw add pipe 3 icmp from any to any
    ipfw add pipe 1 ip from any to 224.0.0.0/4 out
    ipfw add pipe 4 ip from any to any via lo0
the first rule limits outgoing Web traffic, the second one acts on ICMP requests making your machine appear very badly connected, the third one acts on all outgoing multicast traffic, and the fourth one passes loopback traffic through the lossy pipe defined above. You can of course intermix these with other ipfw rules (including SKIPTO actions).

Once a packet has matched a rule with ``pipe'' action, it is forwarded to the appropriate pipe (where it can be just delayed, or even dropped if the queue is already full). On exit from the pipe, the packet is passed again to ip_input() or ip_output(), depending on its direction, and checked against ipfw rules starting from the next one after the matching rule. The presence of the SKIPTO rule makes it possible to construct arbitrary distribution graphs.


Status and known bugs

no significant bugs known, apart from some diagnostic code that i might have left enabled by mistake.

The code includes the following sysctl variables

net.inet.ip.fw.one_pass
allows each packet to pass through the firewall code only once (to construct strange pipe arrangements, you might need to do multiple passes).
net.inet.ip.dummynet.debug
guess what's for...
net.link.ether.bridge
controls bridge operations
net.link.ether.bridge_ipfw
enables bridged packets to be passed through the packet filter.

Thanks to Philippe Regnauld who has been beating the code to find out bugs and mistakes.


Luigi Rizzo
Dipartimento di Ingegneria dell'Informazione -- Univ. di Pisa
via Diotisalvi 2 -- 56126 PISA
tel. +39-050-568533 Fax +39-050-568522
email:
l.rizzo@iet.unipi.it