Skip site navigation (1)Skip section navigation (2)

FreeBSD Man Pages

Man Page or Keyword Search:
Man Architecture
Apropos Keyword Search (all sections) Output format
home | help
NETMAP(4)	       FreeBSD Kernel Interfaces Manual		     NETMAP(4)

NAME
     netmap -- a framework for fast packet I/O

SYNOPSIS
     device netmap

DESCRIPTION
     netmap is a framework for fast and	safe access to network devices (reach-
     ing 14.88 Mpps at less than 1 GHz).  netmap uses memory mapped buffers
     and metadata (buffer indexes and lengths) to communicate with the kernel,
     which is in charge	of validating information through ioctl() and
     select()/poll(). netmap can exploit the parallelism in multiqueue devices
     and multicore systems.

     netmap requires explicit support in device	drivers.  For a	list of	sup-
     ported devices, see the end of this manual	page.

OPERATION
     netmap clients must first open the	open("/dev/netmap"), and then issue an
     ioctl(...,NIOCREGIF,...) to bind the file descriptor to a network device.

     When a device is put in netmap mode, its data path	is disconnected	from
     the host stack.  The processes owning the file descriptor can exchange
     packets with the device, or with the host stack, through an mmapped mem-
     ory region	that contains pre-allocated buffers and	metadata.

     Non blocking I/O is done with special ioctl()'s, whereas the file
     descriptor	can be passed to select()/poll() to be notified	about incoming
     packet or available transmit buffers.

   Data	structures
     All data structures for all devices in netmap mode	are in a memory	region
     shared by the kernel and all processes who	open /dev/netmap (NOTE:	visi-
     bility may	be restricted in future	implementations).  All references
     between the shared	data structure are relative (offsets or	indexes). Some
     macros help converting them into actual pointers.

     The data structures in shared memory are the following:

     struct netmap_if (one per interface)
	  indicates the	number of rings	supported by an	interface, their
	  sizes, and the offsets of the	netmap_rings associated	to the inter-
	  face.	 The offset of a struct	netmap_if in the shared	memory region
	  is indicated by the nr_offset	field in the structure returned	by the
	  NIOCREGIF (see below).

	  struct netmap_if {
	      char ni_name[IFNAMSIZ]; /* name of the interface.	*/
	      const u_int ni_num_queues; /* number of hw ring pairs */
	      const ssize_t   ring_ofs[]; /* offset of tx and rx rings */
	  };

     struct netmap_ring	(one per ring)
	  contains the index of	the current read or write slot (cur), the num-
	  ber of slots available for reception or transmission (avail),	and an
	  array	of slots describing the	buffers.  There	is one ring pair for
	  each of the N	hardware ring pairs supported by the card (numbered
	  0..N-1), plus	one ring pair (numbered	N) for packets from/to the
	  host stack.

	  struct netmap_ring {
	      const ssize_t buf_ofs;
	      const uint32_t num_slots;	/* number of slots in the ring.	*/
	      uint32_t avail;		/* number of usable slots */
	      uint32_t cur;		/* 'current' index for the user	side */
	      uint32_t reserved;	/* not refilled	before current */

	      const uint16_t nr_buf_size;
	      uint16_t flags;
	      struct netmap_slot slot[0]; /* array of slots. */
	  }

     struct netmap_slot	(one per packet)
	  contains the metadata	for a packet: a	buffer index (buf_idx),	a
	  buffer length	(len), and some	flags.

	  struct netmap_slot {
	      uint32_t buf_idx;	/* buffer index	*/
	      uint16_t len;   /* packet	length */
	      uint16_t flags; /* buf changed, etc. */
	  #define NS_BUF_CHANGED  0x0001  /* must resync, buffer changed */
	  #define NS_REPORT	  0x0002  /* tell hw to	report results
					   * e.g. by generating	an interrupt
					   */
	  };

     packet buffers
	  are fixed size (approximately	2k) buffers allocated by the kernel
	  that contain packet data. Buffers addresses are computed through
	  macros.

     Some macros support the access to objects in the shared memory region. In
     particular:

     struct netmap_if *nifp;
     struct netmap_ring	*txring	= NETMAP_TXRING(nifp, i);
     struct netmap_ring	*rxring	= NETMAP_RXRING(nifp, i);
     int i = txring->slot[txring->cur].buf_idx;
     char *buf = NETMAP_BUF(txring, i);

IOCTLS
     netmap supports some ioctl() to synchronize the state of the rings
     between the kernel	and the	user processes,	plus some to query and config-
     ure the interface.	 The former do not require any argument, whereas the
     latter use	a struct netmap_req defined as follows:

     struct nmreq {
	     char      nr_name[IFNAMSIZ];
	     uint32_t  nr_version;     /* API version */
     #define NETMAP_API	     3	       /* current version */
	     uint32_t  nr_offset;      /* nifp offset in the shared region */
	     uint32_t  nr_memsize;     /* size of the shared region */
	     uint32_t  nr_tx_slots;    /* slots	in tx rings */
	     uint32_t  nr_rx_slots;    /* slots	in rx rings */
	     uint16_t  nr_tx_rings;    /* number of tx rings */
	     uint16_t  nr_rx_rings;    /* number of tx rings */
	     uint16_t  nr_ringid;      /* ring(s) we care about	*/
     #define NETMAP_HW_RING  0x4000    /* low bits indicate one	hw ring	*/
     #define NETMAP_SW_RING  0x2000    /* we process the sw ring */
     #define NETMAP_NO_TX_POLL 0x1000  /* no gratuitous	txsync on poll */
     #define NETMAP_RING_MASK 0xfff    /* the actual ring number */
	     uint16_t	     spare1;
	     uint32_t	     spare2[4];
     };

     A device descriptor obtained through /dev/netmap also supports the	ioctl
     supported by network devices.

     The netmap-specific ioctl(2) command codes	below are defined in
     <net/netmap.h> and	are:

     NIOCGINFO
	   returns information about the interface named in nr_name.  On
	   return, nr_memsize indicates	the size of the	shared netmap memory
	   region (this	is device-independent),	nr_tx_slots and	nr_rx_slots
	   indicates how many buffers are in a transmit	and receive ring,
	   nr_tx_rings and nr_rx_rings indicates the number of transmit	and
	   receive rings supported by the hardware.

	   If the device does not support netmap, the ioctl returns EINVAL.

     NIOCREGIF
	   puts	the interface named in nr_name into netmap mode, disconnecting
	   it from the host stack, and/or defines which	rings are controlled
	   through this	file descriptor.  On return, it	gives the same info as
	   NIOCGINFO, and nr_ringid indicates the identity of the rings	con-
	   trolled through the file descriptor.

	   Possible values for nr_ringid are

	   0	  default, all hardware	rings

	   NETMAP_SW_RING
		  the ``host rings'' connecting	to the host stack

	   NETMAP_HW_RING + i
		  the i-th hardware ring
	   By default, a poll or select	call pushes out	any pending packets on
	   the transmit	ring, even if no write events are specified.  The fea-
	   ture	can be disabled	by or-ing NETMAP_NO_TX_SYNC to nr_ringid.  But
	   normally you	should keep this feature unless	you are	using separate
	   file	descriptors for	the send and receive rings, because otherwise
	   packets are pushed out only if NETMAP_TXSYNC	is called, or the send
	   queue is full.

	   NIOCREGIF can be used multiple times	to change the association of a
	   file	descriptor to a	ring pair, always within the same device.

     NIOCUNREGIF
	   brings an interface back to normal mode.

     NIOCTXSYNC
	   tells the hardware of new packets to	transmit, and updates the num-
	   ber of slots	available for transmission.

     NIOCRXSYNC
	   tells the hardware of consumed packets, and asks for	newly avail-
	   able	packets.

SYSTEM CALLS
     netmap uses select	and poll to wake up processes when significant events
     occur.

EXAMPLES
     The following code	implements a traffic generator

     #include <net/netmap.h>
     #include <net/netmap_user.h>
     struct netmap_if *nifp;
     struct netmap_ring	*ring;
     struct nmreq nmr;

     fd	= open("/dev/netmap", O_RDWR);
     bzero(&nmr, sizeof(nmr));
     strcpy(nmr.nr_name, "ix0");
     nmr.nr_version = NETMAP_API;
     ioctl(fd, NIOCREG,	&nmr);
     p = mmap(0, nmr.nr_memsize, fd);
     nifp = NETMAP_IF(p, nmr.offset);
     ring = NETMAP_TXRING(nifp,	0);
     fds.fd = fd;
     fds.events	= POLLOUT;
     for (;;) {
	 poll(list, 1, -1);
	 for ( ; ring->avail > 0 ; ring->avail--) {
	     i = ring->cur;
	     buf = NETMAP_BUF(ring, ring->slot[i].buf_index);
	     ... prepare packet	in buf ...
	     ring->slot[i].len = ... packet length ...
	     ring->cur = NETMAP_RING_NEXT(ring,	i);
	 }
     }

SUPPORTED INTERFACES
     netmap supports the following interfaces: em(4), igb(4), ixgbe(4),
     lem(4), re(4)

SEE ALSO
     vale(4)

     http://info.iet.unipi.it/~luigi/netmap/

     Luigi Rizzo, Revisiting network I/O APIs: the netmap framework, Communi-
     cations of	the ACM, 55 (3), pp.45-51, March 2012

     Luigi Rizzo, netmap: a novel framework for	fast packet I/O, Usenix
     ATC'12, June 2012,	Boston

AUTHORS
     The netmap	framework has been designed and	implemented at the Universita`
     di	Pisa in	2011 by	Luigi Rizzo, with help from Matteo Landi, Gaetano
     Catalli, Giuseppe Lettieri.

     netmap has	been funded by the European Commission within FP7 Project
     CHANGE (257422).

FreeBSD	9.3		      September	23, 2013		   FreeBSD 9.3

NAME | SYNOPSIS | DESCRIPTION | OPERATION | IOCTLS | SYSTEM CALLS | EXAMPLES | SUPPORTED INTERFACES | SEE ALSO | AUTHORS

Want to link to this manual page? Use this URL:
<http://www.freebsd.org/cgi/man.cgi?query=netmap&manpath=FreeBSD+10.0-RELEASE>

home | help