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 multiqueue devices and multicore sys-
     tems.

     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	descrip-
     tor  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: visibil-
     ity  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 interface.   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 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 between
     the kernel and the user processes, plus some to query and configure the in-
     terface.  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  sup-
	   ported 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 number
	   of slots available for transmission.

     NIOCRXSYNC
	   tells the hardware of consumed packets, and asks for newly  available
	   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, Communica-
     tions 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 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