Provided by: freebsd-manpages_9.2+1-1_all bug

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 systems.

       netmap requires explicit support in device drivers.  For a list of supported 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  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: visibility 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 */

                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 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_offset;      /* nifp offset in the shared region */
               uint32_t  nr_memsize;     /* size of the shared region */
               uint32_t  nr_numdescs;    /* descriptors per queue */
               uint16_t  nr_numqueues;
               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 */
       };

       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_numslots  indicates  how  many
             buffers are in a ring, nr_numrings indicates the number of 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  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 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 netmap_request nmr;

       fd = open("/dev/netmap", O_RDWR);
       bzero(&nmr, sizeof(nmr));
       strcpy(nmr.nm_name, "ix0");
       ioctl(fd, NIOCREG, &nmr);
       p = mmap(0, nmr.memsize, fd);
       nifp = NETMAP_IF(p, nmr.offset);
       ring = NETMAP_TXRING(nifp, 0);
       fds.fd = fd;
       fds.events = POLLOUT;
       for (;;) {
           poll(list, 1, -1);
           while (ring->avail-- > 0) {
               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), ixgbe(4), re(4),

AUTHORS

       The netmap framework has been designed and implemented by Luigi Rizzo and
       Matteo Landi in 2011 at the Universita` di Pisa.

Debian                                          November 16, 2011                                      NETMAP(4)