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

FreeBSD Manual Pages

  
 
  

home | help
NETMAP(4)		    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
       (reaching 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 mul-
       tiqueue 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
       memory region that contains pre-allocated buffers and metadata.

       Non  blocking  I/O is done with special ioctl()'s, whereas the file de-
       scriptor	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  re-
       gion shared by the kernel and all processes who open /dev/netmap	(NOTE:
       visibility  may	be  restricted in future implementations).  All	refer-
       ences between the shared	data structure are relative  (offsets  or  in-
       dexes). 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  in-
	    terface.   The  offset  of a struct	netmap_if in the shared	memory
	    region is indicated	by the nr_offset field in  the	structure  re-
	    turned 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
	    number 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  be-
       tween 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 re-
	     turn,  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, disconnect-
	     ing  it  from the host stack, and/or defines which	rings are con-
	     trolled through this file descriptor.  On return,	it  gives  the
	     same  info	 as NIOCGINFO, and nr_ringid indicates the identity of
	     the rings controlled 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
	     feature 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
	     number 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,	Commu-
       nications 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 Univer-
       sita` 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	10.0		      September	23, 2013		     NETMAP(4)

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

home | help