ipfw dummynet: limiting packets per second (limit pps)?

Luigi Rizzo rizzo at icir.org
Tue Apr 22 02:55:26 PDT 2003


On Fri, Apr 18, 2003 at 02:17:10PM -0400, yossman wrote:
...
> good day, i've been searching for the last while for a way to use
> FreeBSD's ipfw and dummynet implementations to limit the number of packets
> per second destined for any matching network traffic pipe.  oddly, i can't
> find very much information on doing this at all, save for a patch written
...
> is there some reason limiting packets per second is not an option at the
> moment?  or does the capability already exist, and i'm just looking in the
> wrong places?  any hints would be appreciated, thanks!

the original motivation for dummynet was to work as a traffic
shaper, i.e. release data from the network interface at most
at the programmed rate. The natural way to express this type of
behaviour is in terms of bandwidth, and a queue to store the
input traffic that is to be released at the desired rate.

Limiting traffic to X pps generally means picking an interval
of T seconds and making sure that in each of those intervals
the first T*X packets are let out without delay, and the excess
is simply thrown away.

Besides the differences in terms of operations (shaping almost
always introduces some delay, whereas limiting never delays traffic),
the implementation of traffic shaping is also more expensive than
traffic limiting -- you need queues and timers for the former,
whereas the latter can be simply implemented with a counter and a
timestamp for each flow.

For a simple implementation of a "pps X" option i would suggest
simply defining a new "ipfw2" opcode O_PPS which would match only
up to X packets in each 1-second interval. The implementation would be
something like this:

	typedef struct _ipfw_insn_pps {
		ipfw_insn o;
		uint32_t	ts;	/* start of measuring period */
		uint32_t	limit;
		uint32_t	count;
	} ipfw_insn_pps;

and the action would be

	case O_PPS: {
		ipfw_insn_pps *x = (ipfw_insn_pps *)cmd;

		if (x->ts != time_second || x->count < x->limit) {
			match = 1;
			if (x->ts != time_second) {
				x->ts = time_second;
				x->count = 0;
			} else
				x->count++;
		}
		break;
		}

its use would be something like this:

	ipfw add 1000 accept ip from A to B pps 50
	ipfw add 1000 deny ip from A to B

A slightly more complex implementation that handles masks etc. is
probably best done by extending dummynet pipes to handle counts and
limits as shown above.

	cheers
	luigi
-----------------------------------+-------------------------------------
  Luigi RIZZO, luigi at iet.unipi.it  . Dip. di Ing. dell'Informazione
  http://www.iet.unipi.it/~luigi/  . Universita` di Pisa
  TEL/FAX: +39-050-568.533/522     . via Diotisalvi 2, 56122 PISA (Italy)
  Mobile   +39-347-0373137
-----------------------------------+-------------------------------------


More information about the freebsd-ipfw mailing list