How can I create and use a Tap device

Robert Watson rwatson at freebsd.org
Thu Nov 18 16:50:01 GMT 2004


On Thu, 18 Nov 2004, Elton Machado wrote:

> I need a virtual ethernet device, can I use tap for that? 
> 
> How can I create it? 

Really quite easy, and fairly well documented in the man page.  Basically,
you need to:

- Load the module or compile it in.
- Open /dev/tapX where X is the interface number.  When the device is
  opened, the network interface will be instantiated.
- Read ethernet frames -- you'll get one per read, make sure to provide
  enough buffer room for a full frame at the MTU of choice.
- Write ethernet frames -- one per write.

Typically input from a tap device will look something like this:

	char packet[MAXPACKET];
	struct ether_header *h;
	ssize_t len, recvlen;

	len = MAXPACKET;
	recvlen = read(tap_fd, packet, len);
	if (recvlen == -1) {
		perror("read");
		return (-1);
	}
	if (len < sizeof(struct ether_header)) {
		fprintf(stderr, "short frame read");
		return (-1);
	}

	eh = (struct ether_header *)(packet);
	...

And a write will look something like this:

	sendlen = write(tap_fd, packet, recvlen);
	if (sendlen == -1) {
		perror("write");
		return (-1);
	}
	if (sendlen != recvlen) {
		fprintd(stderr, "short frame write");
		return (-1);
	}

Make sure to properly initialize the ethernet frame header with the
protocol type, source/destination ethernet addresses, and so on.

A couple of performance caveats:

- Every packet delivery requires going to user space, so possibly a
  context switch and certainly a system call.
- Every packet is copied to user space, and/or from user space, so you get
  a lot of memory copying.

For prototyping or light-weight stuff, tap is a great tool, but to improve
performance you want to run network code in the kernel, especially if
there are other applications running (and/or processing packets), which
will increase the number of context switches.  The cost as it stands isn't
bad -- I regularly use tap-derived tunnel software for remote network
access without a hitch.  There were recently some posts made with patches
to optimize the allocation of kernel memory for packets sent using a tap
device, which are in the mailing list archives (not sure if they were
merged yet).

Robert N M Watson             FreeBSD Core Team, TrustedBSD Projects
robert at fledge.watson.org      Principal Research Scientist, McAfee Research




More information about the freebsd-net mailing list