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.).
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
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:
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
options IPFIREWALL options DUMMYNET
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.001you 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 lo0the 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.
no significant bugs known, apart from some diagnostic code that i might have left enabled by mistake.
The code includes the following sysctl variables
Thanks to Philippe Regnauld who has been beating the code to find out bugs and mistakes.