diff mbox

[ODP/PATCHv3,REQUIRE,TESTING] rework packet io selection

Message ID 1396257768-4865-1-git-send-email-maxim.uvarov@linaro.org
State Superseded
Headers show

Commit Message

Maxim Uvarov March 31, 2014, 9:22 a.m. UTC
Dynamically select type of packet I/O
sock_params->type =
	ODP_PKTIO_TYPE_SOCKET_BASIC
	ODP_PKTIO_TYPE_SOCKET_MMSG
	ODP_PKTIO_TYPE_SOCKET_MMAP
	ODP_PKTIO_TYPE_NETMAP
sock_params->fanout = 1;
pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, &params);

v2:
 - remove NETMAP define in enum;
 - add command line parameters to odp_example_pktio for I/O selection.
v3:
 - add default cases for switch to fix compilation.

Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
---
 .../linux-generic/include/api/odp_pktio_socket.h   |   1 +
 .../linux-generic/include/api/odp_pktio_types.h    |   8 +-
 .../linux-generic/include/odp_packet_io_internal.h |   1 +
 platform/linux-generic/include/odp_packet_socket.h |  55 ++++-------
 platform/linux-generic/source/odp_packet_io.c      |  71 +++++++++++---
 platform/linux-generic/source/odp_packet_socket.c  | 103 +++++++++------------
 test/packet/odp_example_pktio.c                    |  30 +++++-
 7 files changed, 155 insertions(+), 114 deletions(-)

Comments

Anders Roxell March 31, 2014, 1:51 p.m. UTC | #1
On 31 March 2014 11:22, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:

> Dynamically select type of packet I/O
> sock_params->type =
>         ODP_PKTIO_TYPE_SOCKET_BASIC
>         ODP_PKTIO_TYPE_SOCKET_MMSG
>         ODP_PKTIO_TYPE_SOCKET_MMAP
>         ODP_PKTIO_TYPE_NETMAP
> sock_params->fanout = 1;
> pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, &params);
>
> v2:
>  - remove NETMAP define in enum;
>  - add command line parameters to odp_example_pktio for I/O selection.
> v3:
>  - add default cases for switch to fix compilation.
>

I think it would be better if the commit message just said what the patch
is.
If you need to describe what happened between different versions that
should go below the "---"

Cheers,
Anders


>
> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
> ---
>  .../linux-generic/include/api/odp_pktio_socket.h   |   1 +
>  .../linux-generic/include/api/odp_pktio_types.h    |   8 +-
>  .../linux-generic/include/odp_packet_io_internal.h |   1 +
>  platform/linux-generic/include/odp_packet_socket.h |  55 ++++-------
>  platform/linux-generic/source/odp_packet_io.c      |  71 +++++++++++---
>  platform/linux-generic/source/odp_packet_socket.c  | 103
> +++++++++------------
>  test/packet/odp_example_pktio.c                    |  30 +++++-
>  7 files changed, 155 insertions(+), 114 deletions(-)
>
> diff --git a/platform/linux-generic/include/api/odp_pktio_socket.h
> b/platform/linux-generic/include/api/odp_pktio_socket.h
> index e0211bf..deeeeed 100644
> --- a/platform/linux-generic/include/api/odp_pktio_socket.h
> +++ b/platform/linux-generic/include/api/odp_pktio_socket.h
> @@ -15,6 +15,7 @@ extern "C" {
>
>  typedef struct {
>         odp_pktio_type_t type;
> +       int fanout;
>  } socket_params_t;
>
>  #ifdef __cplusplus
> diff --git a/platform/linux-generic/include/api/odp_pktio_types.h
> b/platform/linux-generic/include/api/odp_pktio_types.h
> index e6b4cbf..8d195a5 100644
> --- a/platform/linux-generic/include/api/odp_pktio_types.h
> +++ b/platform/linux-generic/include/api/odp_pktio_types.h
> @@ -17,10 +17,10 @@ extern "C" {
>   */
>
>  typedef enum {
> -       ODP_PKTIO_TYPE_SOCKET = 0x01,
> -#ifdef ODP_HAVE_NETMAP
> -       ODP_PKTIO_TYPE_NETMAP = 0x02,
> -#endif
> +       ODP_PKTIO_TYPE_SOCKET_BASIC = 0x1,
> +       ODP_PKTIO_TYPE_SOCKET_MMSG,
> +       ODP_PKTIO_TYPE_SOCKET_MMAP,
> +       ODP_PKTIO_TYPE_NETMAP,
>  } odp_pktio_type_t;
>
>  #include <odp_pktio_socket.h>
> diff --git a/platform/linux-generic/include/odp_packet_io_internal.h
> b/platform/linux-generic/include/odp_packet_io_internal.h
> index ba1ee9b..3ab7fa0 100644
> --- a/platform/linux-generic/include/odp_packet_io_internal.h
> +++ b/platform/linux-generic/include/odp_packet_io_internal.h
> @@ -31,6 +31,7 @@ struct pktio_entry {
>         odp_queue_t outq_default;       /**< default out queue */
>         odp_pktio_params_t params;      /**< pktio parameters */
>         pkt_sock_t pkt_sock;            /**< using socket API for IO */
> +       pkt_sock_mmap_t pkt_sock_mmap;  /**< using socket mmap API for IO
> */
>  #ifdef ODP_HAVE_NETMAP
>         pkt_netmap_t pkt_nm;            /**< using netmap API for IO */
>  #endif
> diff --git a/platform/linux-generic/include/odp_packet_socket.h
> b/platform/linux-generic/include/odp_packet_socket.h
> index fe216bb..086de05 100644
> --- a/platform/linux-generic/include/odp_packet_socket.h
> +++ b/platform/linux-generic/include/odp_packet_socket.h
> @@ -20,37 +20,15 @@
>
>  #include <linux/version.h>
>
> -
>  /*
>   * Packet socket config:
>   */
> -#define ODP_PACKET_SOCKET_BASIC 0 /** use recv()/send() */
> -#define ODP_PACKET_SOCKET_MMSG  1 /** use recvmmsg()/sendmmsg() */
> -#define ODP_PACKET_SOCKET_MMAP  2 /** use PACKET_MMAP */
> -
> -
> -#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 1, 0)
> -/* PACKET_FANOUT feature not supported */
> -#define ODP_PACKET_SOCKET_FANOUT 0
> -#define ODP_PACKET_SOCKET_MODE (ODP_PACKET_SOCKET_BASIC)
> -#else
> -/** PACKET_FANOUT mode spreads incoming packets over multiple sockets*/
> -#define ODP_PACKET_SOCKET_FANOUT 1 /* 0=Off, 1=On */
> -/** Choose one from the alternatives above */
> -#define ODP_PACKET_SOCKET_MODE (ODP_PACKET_SOCKET_MMAP)
> -#endif
> -
>
>  /** Max receive (Rx) burst size*/
>  #define ODP_PACKET_SOCKET_MAX_BURST_RX 32
>  /** Max transmit (Tx) burst size*/
>  #define ODP_PACKET_SOCKET_MAX_BURST_TX 32
>
> -
> -
> -#if (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC) || \
> -       (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG)
> -
>  typedef struct {
>         int sockfd; /**< socket descriptor */
>         odp_buffer_pool_t pool; /**< buffer pool to alloc packets from */
> @@ -60,12 +38,6 @@ typedef struct {
>         unsigned char if_mac[ETH_ALEN]; /**< IF eth mac addr */
>  } pkt_sock_t;
>
> -#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMAP
> -
> -#if ODP_PACKET_SOCKET_FANOUT == 0
> -#error "ODP_PACKET_SOCKET_MMAP requires ODP_PACKET_SOCKET_FANOUT=1"
> -#endif
> -
>  /** packet mmap ring */
>  struct ring {
>         struct iovec *rd;
> @@ -99,31 +71,44 @@ typedef struct {
>         unsigned mmap_len;
>         unsigned char if_mac[ETH_ALEN];
>         struct sockaddr_ll ll;
> -} pkt_sock_t;
> -
> -#else
> -#error "Unsupported ODP_PACKET_SOCKET_MODE!"
> -#endif
> +} pkt_sock_mmap_t;
>
>  /**
>   * Open & configure a raw packet socket
>   */
>  int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev,
>                    odp_buffer_pool_t pool);
> +
> +int setup_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, char *netdev,
> +                  odp_buffer_pool_t pool, int fanout);
> +
>  /**
>   * Close a packet socket
>   */
>  int close_pkt_sock(pkt_sock_t * const pkt_sock);
>
> +int close_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock);
> +
>  /**
>   * Receive packets from the packet socket
>   */
> -int recv_pkt_sock(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[],
> +int recv_pkt_sock_basic(pkt_sock_t * const pkt_sock, odp_packet_t
> pkt_table[],
>                   unsigned len);
> +
> +int recv_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, odp_packet_t
> pkt_table[],
> +                 unsigned len);
> +
> +int recv_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock,
> +                 odp_packet_t pkt_table[], unsigned len);
>  /**
>   * Send packets through the packet socket
>   */
> -int send_pkt_sock(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[],
> +int send_pkt_sock_basic(pkt_sock_t * const pkt_sock, odp_packet_t
> pkt_table[],
> +                 unsigned len);
> +
> +int send_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, odp_packet_t
> pkt_table[],
>                   unsigned len);
>
> +int send_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock,
> +                 odp_packet_t pkt_table[], unsigned len);
>  #endif
> diff --git a/platform/linux-generic/source/odp_packet_io.c
> b/platform/linux-generic/source/odp_packet_io.c
> index 92aed34..6c6175d 100644
> --- a/platform/linux-generic/source/odp_packet_io.c
> +++ b/platform/linux-generic/source/odp_packet_io.c
> @@ -117,14 +117,21 @@ static void init_pktio_entry(pktio_entry_t *entry,
> odp_pktio_params_t *params)
>         set_taken(entry);
>         entry->s.inq_default = ODP_QUEUE_INVALID;
>         switch (params->type) {
> -       case ODP_PKTIO_TYPE_SOCKET:
> +       case ODP_PKTIO_TYPE_SOCKET_BASIC:
> +       case ODP_PKTIO_TYPE_SOCKET_MMSG:
> +       case ODP_PKTIO_TYPE_SOCKET_MMAP:
>                 memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock));
> +               memset(&entry->s.pkt_sock_mmap, 0,
> +                     sizeof(entry->s.pkt_sock_mmap));
>                 break;
>  #ifdef ODP_HAVE_NETMAP
>         case ODP_PKTIO_TYPE_NETMAP:
>                 memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm));
>                 break;
>  #endif
> +       default:
> +               ODP_ERR("Packet I/O type not supported. Please
> recompile\n");
> +               break;
>         }
>         /* Save pktio parameters, type is the most useful */
>         memcpy(&entry->s.params, params, sizeof(*params));
> @@ -177,7 +184,9 @@ odp_pktio_t odp_pktio_open(char *dev,
> odp_buffer_pool_t pool,
>         }
>
>         switch (params->type) {
> -       case ODP_PKTIO_TYPE_SOCKET:
> +       case ODP_PKTIO_TYPE_SOCKET_BASIC:
> +       case ODP_PKTIO_TYPE_SOCKET_MMSG:
> +       case ODP_PKTIO_TYPE_SOCKET_MMAP:
>                 ODP_DBG("Allocating socket pktio\n");
>                 break;
>  #ifdef ODP_HAVE_NETMAP
> @@ -200,7 +209,8 @@ odp_pktio_t odp_pktio_open(char *dev,
> odp_buffer_pool_t pool,
>         pktio_entry = get_entry(id);
>
>         switch (params->type) {
> -       case ODP_PKTIO_TYPE_SOCKET:
> +       case ODP_PKTIO_TYPE_SOCKET_BASIC:
> +       case ODP_PKTIO_TYPE_SOCKET_MMSG:
>                 res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool);
>                 if (res == -1) {
>                         close_pkt_sock(&pktio_entry->s.pkt_sock);
> @@ -208,17 +218,31 @@ odp_pktio_t odp_pktio_open(char *dev,
> odp_buffer_pool_t pool,
>                         id = ODP_PKTIO_INVALID;
>                 }
>                 break;
> +       case ODP_PKTIO_TYPE_SOCKET_MMAP:
> +               res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap,
> dev,
> +                               pool, params->sock_params.fanout);
> +               if (res == -1) {
> +                       close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap);
> +                       free_pktio_entry(id);
> +                       id = ODP_PKTIO_INVALID;
> +               }
> +               break;
>  #ifdef ODP_HAVE_NETMAP
>         case ODP_PKTIO_TYPE_NETMAP:
> +
>                 res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev,
> -                                      pool, &params->nm_params);
> +                               pool, &params->nm_params);
>                 if (res == -1) {
>                         close_pkt_netmap(&pktio_entry->s.pkt_nm);
>                         free_pktio_entry(id);
>                         id = ODP_PKTIO_INVALID;
>                 }
> -               break;
>  #endif
> +       default:
> +               free_pktio_entry(id);
> +               id = ODP_PKTIO_INVALID;
> +               ODP_ERR("This type of I/O is not supported. Please
> recompile.\n");
> +               break;
>         }
>
>         unlock_entry(pktio_entry);
> @@ -237,9 +261,13 @@ int odp_pktio_close(odp_pktio_t id)
>         lock_entry(entry);
>         if (!is_free(entry)) {
>                 switch (entry->s.params.type) {
> -               case ODP_PKTIO_TYPE_SOCKET:
> +               case ODP_PKTIO_TYPE_SOCKET_BASIC:
> +               case ODP_PKTIO_TYPE_SOCKET_MMSG:
>                         res  = close_pkt_sock(&entry->s.pkt_sock);
>                         break;
> +               case ODP_PKTIO_TYPE_SOCKET_MMAP:
> +                       res  =
> close_pkt_sock_mmap(&entry->s.pkt_sock_mmap);
> +                       break;
>  #ifdef ODP_HAVE_NETMAP
>                 case ODP_PKTIO_TYPE_NETMAP:
>                         res  = close_pkt_netmap(&entry->s.pkt_nm);
> @@ -247,7 +275,7 @@ int odp_pktio_close(odp_pktio_t id)
>  #endif
>                 default:
>                         break;
> -               res |= free_pktio_entry(id);
> +                       res |= free_pktio_entry(id);
>                 }
>         }
>         unlock_entry(entry);
> @@ -279,8 +307,17 @@ int odp_pktio_recv(odp_pktio_t id, odp_packet_t
> pkt_table[], unsigned len)
>
>         lock_entry(pktio_entry);
>         switch (pktio_entry->s.params.type) {
> -       case ODP_PKTIO_TYPE_SOCKET:
> -               pkts = recv_pkt_sock(&pktio_entry->s.pkt_sock, pkt_table,
> len);
> +       case ODP_PKTIO_TYPE_SOCKET_BASIC:
> +               pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock,
> +                               pkt_table, len);
> +               break;
> +       case ODP_PKTIO_TYPE_SOCKET_MMSG:
> +               pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock,
> +                               pkt_table, len);
> +               break;
> +       case ODP_PKTIO_TYPE_SOCKET_MMAP:
> +               pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap,
> +                               pkt_table, len);
>                 break;
>  #ifdef ODP_HAVE_NETMAP
>         case ODP_PKTIO_TYPE_NETMAP:
> @@ -312,12 +349,22 @@ int odp_pktio_send(odp_pktio_t id, odp_packet_t
> pkt_table[], unsigned len)
>
>         lock_entry(pktio_entry);
>         switch (pktio_entry->s.params.type) {
> -       case ODP_PKTIO_TYPE_SOCKET:
> -               pkts = send_pkt_sock(&pktio_entry->s.pkt_sock, pkt_table,
> len);
> +       case ODP_PKTIO_TYPE_SOCKET_BASIC:
> +               pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock,
> +                               pkt_table, len);
> +               break;
> +       case ODP_PKTIO_TYPE_SOCKET_MMSG:
> +               pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock,
> +                               pkt_table, len);
> +               break;
> +       case ODP_PKTIO_TYPE_SOCKET_MMAP:
> +               pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap,
> +                               pkt_table, len);
>                 break;
>  #ifdef ODP_HAVE_NETMAP
>         case ODP_PKTIO_TYPE_NETMAP:
> -               pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table,
> len);
> +               pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm,
> +                               pkt_table, len);
>                 break;
>  #endif
>         default:
> diff --git a/platform/linux-generic/source/odp_packet_socket.c
> b/platform/linux-generic/source/odp_packet_socket.c
> index aaf2605..4e5803f 100644
> --- a/platform/linux-generic/source/odp_packet_socket.c
> +++ b/platform/linux-generic/source/odp_packet_socket.c
> @@ -63,10 +63,9 @@ static inline int ethaddrs_equal(unsigned char mac_a[],
> unsigned char mac_b[])
>         return !memcmp(mac_a, mac_b, ETH_ALEN);
>  }
>
> -static int set_pkt_sock_fanout(pkt_sock_t * const pkt_sock, int
> sock_group_idx)
> +static int set_pkt_sock_fanout_mmap(pkt_sock_mmap_t * const pkt_sock,
> +               int sock_group_idx)
>  {
> -#if ODP_PACKET_SOCKET_FANOUT == 1
> -       /* Use FANOUT-mode for socket */
>         int sockfd = pkt_sock->sockfd;
>         int val;
>         int err;
> @@ -80,16 +79,9 @@ static int set_pkt_sock_fanout(pkt_sock_t * const
> pkt_sock, int sock_group_idx)
>                 perror("set_pkt_sock_fanout() -
> setsockopt(PACKET_FANOUT)");
>                 return -1;
>         }
> -#else
> -       (void)pkt_sock;
> -       (void)sock_group_idx;
> -#endif
> -
>         return 0;
>  }
>
> -#if (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC) || \
> -       (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG)
>  /*
>   * ODP_PACKET_SOCKET_BASIC:
>   * ODP_PACKET_SOCKET_MMSG:
> @@ -163,11 +155,6 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char
> *netdev,
>                 return -1;
>         }
>
> -       /* configure PACKET_FANOUT mode for socket (if mode enabled) */
> -       err = set_pkt_sock_fanout(pkt_sock, if_idx);
> -       if (err != 0)
> -               return -1;
> -
>         return sockfd;
>  }
>
> @@ -184,13 +171,11 @@ int close_pkt_sock(pkt_sock_t * const pkt_sock)
>
>         return 0;
>  }
> -#endif
>
> -#if ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC
>  /*
>   * ODP_PACKET_SOCKET_BASIC:
>   */
> -int recv_pkt_sock(pkt_sock_t *const pkt_sock,
> +int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock,
>                   odp_packet_t pkt_table[], unsigned len)
>  {
>         ssize_t recv_bytes;
> @@ -240,7 +225,7 @@ int recv_pkt_sock(pkt_sock_t *const pkt_sock,
>  /*
>   * ODP_PACKET_SOCKET_BASIC:
>   */
> -int send_pkt_sock(pkt_sock_t * const pkt_sock,
> +int send_pkt_sock_basic(pkt_sock_t * const pkt_sock,
>                   odp_packet_t pkt_table[], unsigned len)
>  {
>         odp_packet_t pkt;
> @@ -281,11 +266,10 @@ int send_pkt_sock(pkt_sock_t * const pkt_sock,
>         return nb_tx;
>  }
>
> -#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG
>  /*
>   * ODP_PACKET_SOCKET_MMSG:
>   */
> -int recv_pkt_sock(pkt_sock_t * const pkt_sock,
> +int recv_pkt_sock_mmsg(pkt_sock_t * const pkt_sock,
>                   odp_packet_t pkt_table[], unsigned len)
>  {
>         const int sockfd = pkt_sock->sockfd;
> @@ -348,7 +332,7 @@ int recv_pkt_sock(pkt_sock_t * const pkt_sock,
>  /*
>   * ODP_PACKET_SOCKET_MMSG:
>   */
> -int send_pkt_sock(pkt_sock_t * const pkt_sock,
> +int send_pkt_sock_mmsg(pkt_sock_t * const pkt_sock,
>                   odp_packet_t pkt_table[], unsigned len)
>  {
>         struct mmsghdr msgvec[ODP_PACKET_SOCKET_MAX_BURST_TX];
> @@ -387,7 +371,6 @@ int send_pkt_sock(pkt_sock_t * const pkt_sock,
>         return len;
>  }
>
> -#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMAP
>  /*
>   * ODP_PACKET_SOCKET_MMAP:
>   */
> @@ -402,7 +385,7 @@ union frame_map {
>         void *raw;
>  };
>
> -static int pkt_socket(void)
> +static int mmap_pkt_socket(void)
>  {
>         int ver = TPACKET_V2;
>
> @@ -421,23 +404,23 @@ static int pkt_socket(void)
>         return sock;
>  }
>
> -static inline int rx_kernel_ready(struct tpacket2_hdr *hdr)
> +static inline int mmap_rx_kernel_ready(struct tpacket2_hdr *hdr)
>  {
>         return ((hdr->tp_status & TP_STATUS_USER) == TP_STATUS_USER);
>  }
>
> -static inline void rx_user_ready(struct tpacket2_hdr *hdr)
> +static inline void mmap_rx_user_ready(struct tpacket2_hdr *hdr)
>  {
>         hdr->tp_status = TP_STATUS_KERNEL;
>         __sync_synchronize();
>  }
>
> -static inline int tx_kernel_ready(struct tpacket2_hdr *hdr)
> +static inline int mmap_tx_kernel_ready(struct tpacket2_hdr *hdr)
>  {
>         return !(hdr->tp_status & (TP_STATUS_SEND_REQUEST |
> TP_STATUS_SENDING));
>  }
>
> -static inline void tx_user_ready(struct tpacket2_hdr *hdr)
> +static inline void mmap_tx_user_ready(struct tpacket2_hdr *hdr)
>  {
>         hdr->tp_status = TP_STATUS_SEND_REQUEST;
>         __sync_synchronize();
> @@ -462,7 +445,7 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct
> ring *ring,
>         frame_num = ring->frame_num;
>
>         while (i < len) {
> -               if (rx_kernel_ready(ring->rd[frame_num].iov_base)) {
> +               if (mmap_rx_kernel_ready(ring->rd[frame_num].iov_base)) {
>                         ppd.raw = ring->rd[frame_num].iov_base;
>
>                         next_frame_num = (frame_num + 1) % ring->rd_num;
> @@ -474,7 +457,7 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct
> ring *ring,
>                         eth_hdr = (struct ethhdr *)pkt_buf;
>                         if (odp_unlikely(ethaddrs_equal(if_mac,
>
> eth_hdr->h_source))) {
> -                               rx_user_ready(ppd.raw); /* drop */
> +                               mmap_rx_user_ready(ppd.raw); /* drop */
>                                 continue;
>                         }
>
> @@ -486,7 +469,7 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct
> ring *ring,
>                                  + frame_offset;
>                         memcpy(l2_hdr, pkt_buf, pkt_len);
>
> -                       rx_user_ready(ppd.raw);
> +                       mmap_rx_user_ready(ppd.raw);
>
>                         /* Parse and set packet header data */
>                         odp_packet_parse(pkt_table[i], pkt_len,
> frame_offset);
> @@ -516,7 +499,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct
> ring *ring,
>         frame_num = ring->frame_num;
>
>         while (i < len) {
> -               if (tx_kernel_ready(ring->rd[frame_num].iov_base)) {
> +               if (mmap_tx_kernel_ready(ring->rd[frame_num].iov_base)) {
>                         ppd.raw = ring->rd[frame_num].iov_base;
>
>                         next_frame_num = (frame_num + 1) % ring->rd_num;
> @@ -530,7 +513,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct
> ring *ring,
>                         memcpy((uint8_t *)ppd.raw + TPACKET2_HDRLEN -
>                                sizeof(struct sockaddr_ll), pkt_buf,
> pkt_len);
>
> -                       tx_user_ready(ppd.raw);
> +                       mmap_tx_user_ready(ppd.raw);
>
>                         odp_packet_free(pkt_table[i]);
>                         frame_num = next_frame_num;
> @@ -553,7 +536,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct
> ring *ring,
>         return i;
>  }
>
> -static void fill_ring(struct ring *ring, unsigned blocks)
> +static void mmap_fill_ring(struct ring *ring, unsigned blocks)
>  {
>         ring->req.tp_block_size = getpagesize() << 2;
>         ring->req.tp_frame_size = TPACKET_ALIGNMENT << 7;
> @@ -567,7 +550,7 @@ static void fill_ring(struct ring *ring, unsigned
> blocks)
>         ring->flen = ring->req.tp_frame_size;
>  }
>
> -static int set_packet_loss_discard(int sock)
> +static int mmap_set_packet_loss_discard(int sock)
>  {
>         int ret, discard = 1;
>
> @@ -581,7 +564,7 @@ static int set_packet_loss_discard(int sock)
>         return 0;
>  }
>
> -static int setup_ring(int sock, struct ring *ring, int type)
> +static int mmap_setup_ring(int sock, struct ring *ring, int type)
>  {
>         int ret = 0;
>         unsigned blocks = 256;
> @@ -591,12 +574,12 @@ static int setup_ring(int sock, struct ring *ring,
> int type)
>         ring->version = TPACKET_V2;
>
>         if (type == PACKET_TX_RING) {
> -               ret = set_packet_loss_discard(sock);
> +               ret = mmap_set_packet_loss_discard(sock);
>                 if (ret != 0)
>                         return -1;
>         }
>
> -       fill_ring(ring, blocks);
> +       mmap_fill_ring(ring, blocks);
>
>         ret = setsockopt(sock, SOL_PACKET, type, &ring->req,
> sizeof(ring->req));
>         if (ret == -1) {
> @@ -614,7 +597,7 @@ static int setup_ring(int sock, struct ring *ring, int
> type)
>         return 0;
>  }
>
> -static int mmap_sock(pkt_sock_t *pkt_sock)
> +static int mmap_sock(pkt_sock_mmap_t *pkt_sock)
>  {
>         int i;
>         int sock = pkt_sock->sockfd;
> @@ -655,14 +638,14 @@ static int mmap_sock(pkt_sock_t *pkt_sock)
>         return 0;
>  }
>
> -static void unmap_sock(pkt_sock_t *pkt_sock)
> +static void mmap_unmap_sock(pkt_sock_mmap_t *pkt_sock)
>  {
>         munmap(pkt_sock->mmap_base, pkt_sock->mmap_len);
>         free(pkt_sock->rx_ring.rd);
>         free(pkt_sock->tx_ring.rd);
>  }
>
> -static int bind_sock(pkt_sock_t *pkt_sock, char *netdev)
> +static int mmap_bind_sock(pkt_sock_mmap_t *pkt_sock, char *netdev)
>  {
>         int ret;
>
> @@ -684,7 +667,7 @@ static int bind_sock(pkt_sock_t *pkt_sock, char
> *netdev)
>         return 0;
>  }
>
> -static int store_hw_addr(pkt_sock_t * const pkt_sock, char *netdev)
> +static int mmap_store_hw_addr(pkt_sock_mmap_t * const pkt_sock, char
> *netdev)
>  {
>         struct ifreq ethreq;
>         int ret;
> @@ -707,8 +690,8 @@ static int store_hw_addr(pkt_sock_t * const pkt_sock,
> char *netdev)
>  /*
>   * ODP_PACKET_SOCKET_MMAP:
>   */
> -int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev,
> -                  odp_buffer_pool_t pool)
> +int setup_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, char *netdev,
> +                  odp_buffer_pool_t pool, int fanout)
>  {
>         odp_packet_t pkt;
>         uint8_t *pkt_buf;
> @@ -733,17 +716,19 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char
> *netdev,
>         odp_packet_free(pkt);
>
>         pkt_sock->pool = pool;
> -       pkt_sock->sockfd = pkt_socket();
> +       pkt_sock->sockfd = mmap_pkt_socket();
>
> -       ret = bind_sock(pkt_sock, netdev);
> +       ret = mmap_bind_sock(pkt_sock, netdev);
>         if (ret != 0)
>                 return -1;
>
> -       ret = setup_ring(pkt_sock->sockfd, &pkt_sock->tx_ring,
> PACKET_TX_RING);
> +       ret = mmap_setup_ring(pkt_sock->sockfd, &pkt_sock->tx_ring,
> +                       PACKET_TX_RING);
>         if (ret != 0)
>                 return -1;
>
> -       ret = setup_ring(pkt_sock->sockfd, &pkt_sock->rx_ring,
> PACKET_RX_RING);
> +       ret = mmap_setup_ring(pkt_sock->sockfd, &pkt_sock->rx_ring,
> +                       PACKET_RX_RING);
>         if (ret != 0)
>                 return -1;
>
> @@ -751,7 +736,7 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char
> *netdev,
>         if (ret != 0)
>                 return -1;
>
> -       ret = store_hw_addr(pkt_sock, netdev);
> +       ret = mmap_store_hw_addr(pkt_sock, netdev);
>         if (ret != 0)
>                 return -1;
>
> @@ -761,9 +746,11 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char
> *netdev,
>                 return -1;
>         }
>
> -       ret = set_pkt_sock_fanout(pkt_sock, if_idx);
> -       if (ret != 0)
> -               return -1;
> +       if (fanout) {
> +               ret = set_pkt_sock_fanout_mmap(pkt_sock, if_idx);
> +               if (ret != 0)
> +                       return -1;
> +       }
>
>         return pkt_sock->sockfd;
>  }
> @@ -771,9 +758,9 @@ int setup_pkt_sock(pkt_sock_t * const pkt_sock, char
> *netdev,
>  /*
>   * ODP_PACKET_SOCKET_MMAP:
>   */
> -int close_pkt_sock(pkt_sock_t * const pkt_sock)
> +int close_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock)
>  {
> -       unmap_sock(pkt_sock);
> +       mmap_unmap_sock(pkt_sock);
>         if (close(pkt_sock->sockfd) != 0) {
>                 perror("close_pkt_sock() - close(sockfd)");
>                 return -1;
> @@ -785,7 +772,7 @@ int close_pkt_sock(pkt_sock_t * const pkt_sock)
>  /*
>   * ODP_PACKET_SOCKET_MMAP:
>   */
> -int recv_pkt_sock(pkt_sock_t * const pkt_sock,
> +int recv_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock,
>                   odp_packet_t pkt_table[], unsigned len)
>  {
>         return pkt_mmap_v2_rx(pkt_sock->rx_ring.sock, &pkt_sock->rx_ring,
> @@ -796,13 +783,9 @@ int recv_pkt_sock(pkt_sock_t * const pkt_sock,
>  /*
>   * ODP_PACKET_SOCKET_MMAP:
>   */
> -int send_pkt_sock(pkt_sock_t * const pkt_sock,
> +int send_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock,
>                   odp_packet_t pkt_table[], unsigned len)
>  {
>         return pkt_mmap_v2_tx(pkt_sock->tx_ring.sock, &pkt_sock->tx_ring,
>                               pkt_table, len);
>  }
> -
> -#else
> -#error "Unsupported ODP_PACKET_SOCKET_MODE!"
> -#endif
> diff --git a/test/packet/odp_example_pktio.c
> b/test/packet/odp_example_pktio.c
> index 85bbdd7..1d62123 100644
> --- a/test/packet/odp_example_pktio.c
> +++ b/test/packet/odp_example_pktio.c
> @@ -42,6 +42,8 @@ typedef struct {
>         int if_count;           /**< Number of interfaces to be used */
>         char **if_names;        /**< Array of pointers to interface names
> */
>         int mode;               /**< Packet IO mode */
> +       int type;               /**< Packet IO type */
> +       int fanout;             /**< Packet IO fanout */
>         odp_buffer_pool_t pool; /**< Buffer pool for packet IO */
>  } appl_args_t;
>
> @@ -52,6 +54,8 @@ typedef struct {
>         char *pktio_dev;        /**< Interface name to use */
>         odp_buffer_pool_t pool; /**< Buffer pool for packet IO */
>         int mode;               /**< Thread mode */
> +       int type;               /**< Thread i/o type */
> +       int fanout;             /**< Thread i/o fanout */
>  } thread_args_t;
>
>  /**
> @@ -111,7 +115,8 @@ static void *pktio_queue_thread(void *arg)
>         }
>
>         /* Open a packet IO instance for this thread */
> -       sock_params->type = ODP_PKTIO_TYPE_SOCKET;
> +       sock_params->type = thr_args->type;
> +       sock_params->fanout = thr_args->fanout;
>         pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool,
> &params);
>         if (pktio == ODP_PKTIO_INVALID) {
>                 ODP_ERR("  [%02i] Error: pktio create failed\n", thr);
> @@ -223,7 +228,8 @@ static void *pktio_ifburst_thread(void *arg)
>         }
>
>         /* Open a packet IO instance for this thread */
> -       sock_params->type = ODP_PKTIO_TYPE_SOCKET;
> +       sock_params->type = thr_args->type;
> +       sock_params->fanout = thr_args->fanout;
>         pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool,
> &params);
>         if (pktio == ODP_PKTIO_INVALID) {
>                 ODP_ERR("  [%02i] Error: pktio create failed.\n", thr);
> @@ -357,6 +363,8 @@ int main(int argc, char *argv[])
>                 args->thread[i].pktio_dev = args->appl.if_names[if_idx];
>                 args->thread[i].pool = pool;
>                 args->thread[i].mode = args->appl.mode;
> +               args->thread[i].type = args->appl.type;
> +               args->thread[i].fanout = args->appl.fanout;
>
>                 if (args->appl.mode == APPL_MODE_PKT_BURST)
>                         thr_run_func = pktio_ifburst_thread;
> @@ -470,9 +478,11 @@ static void parse_args(int argc, char *argv[],
> appl_args_t *appl_args)
>         };
>
>         appl_args->mode = -1; /* Invalid, must be changed by parsing */
> +       appl_args->type = 3;  /* 3: ODP_PKTIO_TYPE_SOCKET_MMAP */
> +       appl_args->fanout = 1; /* turn off fanout by default for mmap */
>
>         while (1) {
> -               opt = getopt_long(argc, argv, "+c:i:m:h",
> +               opt = getopt_long(argc, argv, "+c:i:m:t:f:h",
>                                   longopts, &long_index);
>
>                 if (opt == -1)
> @@ -533,6 +543,14 @@ static void parse_args(int argc, char *argv[],
> appl_args_t *appl_args)
>                                 appl_args->mode = APPL_MODE_PKT_QUEUE;
>                         break;
>
> +               case 't':
> +                       appl_args->type = atoi(optarg);
> +                       break;
> +
> +               case 'f':
> +                       appl_args->type = atoi(optarg);
> +                       break;
> +
>                 case 'h':
>                         usage(argv[0]);
>                         exit(EXIT_SUCCESS);
> @@ -602,6 +620,12 @@ static void usage(char *progname)
>                "  -i, --interface Eth interfaces (comma-separated, no
> spaces)\n"
>                "  -m, --mode      0: Burst send&receive packets (no
> queues)\n"
>                "                  1: Send&receive packets through ODP
> queues.\n"
> +              " -t, --type   1: ODP_PKTIO_TYPE_SOCKET_BASIC\n"
> +              "              2: ODP_PKTIO_TYPE_SOCKET_MMSG\n"
> +              "              3: ODP_PKTIO_TYPE_SOCKET_MMAP\n"
> +              "              4: ODP_PKTIO_TYPE_NETMAP\n"
> +              "         Default: 3: ODP_PKTIO_TYPE_SOCKET_MMAP\n"
> +              " -f, --fanout 0: off 1: on (Default 1: on)\n"
>                "\n"
>                "Optional OPTIONS\n"
>                "  -c, --count <number> Core count.\n"
> --
> 1.8.5.1.163.gd7aced9
>
> --
> You received this message because you are subscribed to the Google Groups
> "LNG ODP Sub-team - lng-odp@linaro.org" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to lng-odp+unsubscribe@linaro.org.
> To post to this group, send email to lng-odp@linaro.org.
> Visit this group at http://groups.google.com/a/linaro.org/group/lng-odp/.
> To view this discussion on the web visit
> https://groups.google.com/a/linaro.org/d/msgid/lng-odp/1396257768-4865-1-git-send-email-maxim.uvarov%40linaro.org
> .
> For more options, visit https://groups.google.com/a/linaro.org/d/optout.
>
diff mbox

Patch

diff --git a/platform/linux-generic/include/api/odp_pktio_socket.h b/platform/linux-generic/include/api/odp_pktio_socket.h
index e0211bf..deeeeed 100644
--- a/platform/linux-generic/include/api/odp_pktio_socket.h
+++ b/platform/linux-generic/include/api/odp_pktio_socket.h
@@ -15,6 +15,7 @@  extern "C" {
 
 typedef struct {
 	odp_pktio_type_t type;
+	int fanout;
 } socket_params_t;
 
 #ifdef __cplusplus
diff --git a/platform/linux-generic/include/api/odp_pktio_types.h b/platform/linux-generic/include/api/odp_pktio_types.h
index e6b4cbf..8d195a5 100644
--- a/platform/linux-generic/include/api/odp_pktio_types.h
+++ b/platform/linux-generic/include/api/odp_pktio_types.h
@@ -17,10 +17,10 @@  extern "C" {
  */
 
 typedef enum {
-	ODP_PKTIO_TYPE_SOCKET = 0x01,
-#ifdef ODP_HAVE_NETMAP
-	ODP_PKTIO_TYPE_NETMAP = 0x02,
-#endif
+	ODP_PKTIO_TYPE_SOCKET_BASIC = 0x1,
+	ODP_PKTIO_TYPE_SOCKET_MMSG,
+	ODP_PKTIO_TYPE_SOCKET_MMAP,
+	ODP_PKTIO_TYPE_NETMAP,
 } odp_pktio_type_t;
 
 #include <odp_pktio_socket.h>
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h
index ba1ee9b..3ab7fa0 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -31,6 +31,7 @@  struct pktio_entry {
 	odp_queue_t outq_default;	/**< default out queue */
 	odp_pktio_params_t params;	/**< pktio parameters */
 	pkt_sock_t pkt_sock;		/**< using socket API for IO */
+	pkt_sock_mmap_t pkt_sock_mmap;	/**< using socket mmap API for IO */
 #ifdef ODP_HAVE_NETMAP
 	pkt_netmap_t pkt_nm;		/**< using netmap API for IO */
 #endif
diff --git a/platform/linux-generic/include/odp_packet_socket.h b/platform/linux-generic/include/odp_packet_socket.h
index fe216bb..086de05 100644
--- a/platform/linux-generic/include/odp_packet_socket.h
+++ b/platform/linux-generic/include/odp_packet_socket.h
@@ -20,37 +20,15 @@ 
 
 #include <linux/version.h>
 
-
 /*
  * Packet socket config:
  */
-#define ODP_PACKET_SOCKET_BASIC 0 /** use recv()/send() */
-#define ODP_PACKET_SOCKET_MMSG  1 /** use recvmmsg()/sendmmsg() */
-#define ODP_PACKET_SOCKET_MMAP  2 /** use PACKET_MMAP */
-
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 1, 0)
-/* PACKET_FANOUT feature not supported */
-#define ODP_PACKET_SOCKET_FANOUT 0
-#define ODP_PACKET_SOCKET_MODE (ODP_PACKET_SOCKET_BASIC)
-#else
-/** PACKET_FANOUT mode spreads incoming packets over multiple sockets*/
-#define ODP_PACKET_SOCKET_FANOUT 1 /* 0=Off, 1=On */
-/** Choose one from the alternatives above */
-#define ODP_PACKET_SOCKET_MODE (ODP_PACKET_SOCKET_MMAP)
-#endif
-
 
 /** Max receive (Rx) burst size*/
 #define ODP_PACKET_SOCKET_MAX_BURST_RX 32
 /** Max transmit (Tx) burst size*/
 #define ODP_PACKET_SOCKET_MAX_BURST_TX 32
 
-
-
-#if (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC) || \
-	(ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG)
-
 typedef struct {
 	int sockfd; /**< socket descriptor */
 	odp_buffer_pool_t pool; /**< buffer pool to alloc packets from */
@@ -60,12 +38,6 @@  typedef struct {
 	unsigned char if_mac[ETH_ALEN];	/**< IF eth mac addr */
 } pkt_sock_t;
 
-#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMAP
-
-#if ODP_PACKET_SOCKET_FANOUT == 0
-#error "ODP_PACKET_SOCKET_MMAP requires ODP_PACKET_SOCKET_FANOUT=1"
-#endif
-
 /** packet mmap ring */
 struct ring {
 	struct iovec *rd;
@@ -99,31 +71,44 @@  typedef struct {
 	unsigned mmap_len;
 	unsigned char if_mac[ETH_ALEN];
 	struct sockaddr_ll ll;
-} pkt_sock_t;
-
-#else
-#error "Unsupported ODP_PACKET_SOCKET_MODE!"
-#endif
+} pkt_sock_mmap_t;
 
 /**
  * Open & configure a raw packet socket
  */
 int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev,
 		   odp_buffer_pool_t pool);
+
+int setup_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, char *netdev,
+		   odp_buffer_pool_t pool, int fanout);
+
 /**
  * Close a packet socket
  */
 int close_pkt_sock(pkt_sock_t * const pkt_sock);
 
+int close_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock);
+
 /**
  * Receive packets from the packet socket
  */
-int recv_pkt_sock(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[],
+int recv_pkt_sock_basic(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[],
 		  unsigned len);
+
+int recv_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[],
+		  unsigned len);
+
+int recv_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock,
+		  odp_packet_t pkt_table[], unsigned len);
 /**
  * Send packets through the packet socket
  */
-int send_pkt_sock(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[],
+int send_pkt_sock_basic(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[],
+		  unsigned len);
+
+int send_pkt_sock_mmsg(pkt_sock_t * const pkt_sock, odp_packet_t pkt_table[],
 		  unsigned len);
 
+int send_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock,
+		  odp_packet_t pkt_table[], unsigned len);
 #endif
diff --git a/platform/linux-generic/source/odp_packet_io.c b/platform/linux-generic/source/odp_packet_io.c
index 92aed34..6c6175d 100644
--- a/platform/linux-generic/source/odp_packet_io.c
+++ b/platform/linux-generic/source/odp_packet_io.c
@@ -117,14 +117,21 @@  static void init_pktio_entry(pktio_entry_t *entry, odp_pktio_params_t *params)
 	set_taken(entry);
 	entry->s.inq_default = ODP_QUEUE_INVALID;
 	switch (params->type) {
-	case ODP_PKTIO_TYPE_SOCKET:
+	case ODP_PKTIO_TYPE_SOCKET_BASIC:
+	case ODP_PKTIO_TYPE_SOCKET_MMSG:
+	case ODP_PKTIO_TYPE_SOCKET_MMAP:
 		memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock));
+		memset(&entry->s.pkt_sock_mmap, 0,
+		      sizeof(entry->s.pkt_sock_mmap));
 		break;
 #ifdef ODP_HAVE_NETMAP
 	case ODP_PKTIO_TYPE_NETMAP:
 		memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm));
 		break;
 #endif
+	default:
+		ODP_ERR("Packet I/O type not supported. Please recompile\n");
+		break;
 	}
 	/* Save pktio parameters, type is the most useful */
 	memcpy(&entry->s.params, params, sizeof(*params));
@@ -177,7 +184,9 @@  odp_pktio_t odp_pktio_open(char *dev, odp_buffer_pool_t pool,
 	}
 
 	switch (params->type) {
-	case ODP_PKTIO_TYPE_SOCKET:
+	case ODP_PKTIO_TYPE_SOCKET_BASIC:
+	case ODP_PKTIO_TYPE_SOCKET_MMSG:
+	case ODP_PKTIO_TYPE_SOCKET_MMAP:
 		ODP_DBG("Allocating socket pktio\n");
 		break;
 #ifdef ODP_HAVE_NETMAP
@@ -200,7 +209,8 @@  odp_pktio_t odp_pktio_open(char *dev, odp_buffer_pool_t pool,
 	pktio_entry = get_entry(id);
 
 	switch (params->type) {
-	case ODP_PKTIO_TYPE_SOCKET:
+	case ODP_PKTIO_TYPE_SOCKET_BASIC:
+	case ODP_PKTIO_TYPE_SOCKET_MMSG:
 		res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool);
 		if (res == -1) {
 			close_pkt_sock(&pktio_entry->s.pkt_sock);
@@ -208,17 +218,31 @@  odp_pktio_t odp_pktio_open(char *dev, odp_buffer_pool_t pool,
 			id = ODP_PKTIO_INVALID;
 		}
 		break;
+	case ODP_PKTIO_TYPE_SOCKET_MMAP:
+		res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, dev,
+				pool, params->sock_params.fanout);
+		if (res == -1) {
+			close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap);
+			free_pktio_entry(id);
+			id = ODP_PKTIO_INVALID;
+		}
+		break;
 #ifdef ODP_HAVE_NETMAP
 	case ODP_PKTIO_TYPE_NETMAP:
+
 		res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev,
-				       pool, &params->nm_params);
+				pool, &params->nm_params);
 		if (res == -1) {
 			close_pkt_netmap(&pktio_entry->s.pkt_nm);
 			free_pktio_entry(id);
 			id = ODP_PKTIO_INVALID;
 		}
-		break;
 #endif
+	default:
+		free_pktio_entry(id);
+		id = ODP_PKTIO_INVALID;
+		ODP_ERR("This type of I/O is not supported. Please recompile.\n");
+		break;
 	}
 
 	unlock_entry(pktio_entry);
@@ -237,9 +261,13 @@  int odp_pktio_close(odp_pktio_t id)
 	lock_entry(entry);
 	if (!is_free(entry)) {
 		switch (entry->s.params.type) {
-		case ODP_PKTIO_TYPE_SOCKET:
+		case ODP_PKTIO_TYPE_SOCKET_BASIC:
+		case ODP_PKTIO_TYPE_SOCKET_MMSG:
 			res  = close_pkt_sock(&entry->s.pkt_sock);
 			break;
+		case ODP_PKTIO_TYPE_SOCKET_MMAP:
+			res  = close_pkt_sock_mmap(&entry->s.pkt_sock_mmap);
+			break;
 #ifdef ODP_HAVE_NETMAP
 		case ODP_PKTIO_TYPE_NETMAP:
 			res  = close_pkt_netmap(&entry->s.pkt_nm);
@@ -247,7 +275,7 @@  int odp_pktio_close(odp_pktio_t id)
 #endif
 		default:
 			break;
-		res |= free_pktio_entry(id);
+			res |= free_pktio_entry(id);
 		}
 	}
 	unlock_entry(entry);
@@ -279,8 +307,17 @@  int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len)
 
 	lock_entry(pktio_entry);
 	switch (pktio_entry->s.params.type) {
-	case ODP_PKTIO_TYPE_SOCKET:
-		pkts = recv_pkt_sock(&pktio_entry->s.pkt_sock, pkt_table, len);
+	case ODP_PKTIO_TYPE_SOCKET_BASIC:
+		pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock,
+				pkt_table, len);
+		break;
+	case ODP_PKTIO_TYPE_SOCKET_MMSG:
+		pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock,
+				pkt_table, len);
+		break;
+	case ODP_PKTIO_TYPE_SOCKET_MMAP:
+		pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap,
+				pkt_table, len);
 		break;
 #ifdef ODP_HAVE_NETMAP
 	case ODP_PKTIO_TYPE_NETMAP:
@@ -312,12 +349,22 @@  int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len)
 
 	lock_entry(pktio_entry);
 	switch (pktio_entry->s.params.type) {
-	case ODP_PKTIO_TYPE_SOCKET:
-		pkts = send_pkt_sock(&pktio_entry->s.pkt_sock, pkt_table, len);
+	case ODP_PKTIO_TYPE_SOCKET_BASIC:
+		pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock,
+				pkt_table, len);
+		break;
+	case ODP_PKTIO_TYPE_SOCKET_MMSG:
+		pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock,
+				pkt_table, len);
+		break;
+	case ODP_PKTIO_TYPE_SOCKET_MMAP:
+		pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap,
+				pkt_table, len);
 		break;
 #ifdef ODP_HAVE_NETMAP
 	case ODP_PKTIO_TYPE_NETMAP:
-		pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, len);
+		pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm,
+				pkt_table, len);
 		break;
 #endif
 	default:
diff --git a/platform/linux-generic/source/odp_packet_socket.c b/platform/linux-generic/source/odp_packet_socket.c
index aaf2605..4e5803f 100644
--- a/platform/linux-generic/source/odp_packet_socket.c
+++ b/platform/linux-generic/source/odp_packet_socket.c
@@ -63,10 +63,9 @@  static inline int ethaddrs_equal(unsigned char mac_a[], unsigned char mac_b[])
 	return !memcmp(mac_a, mac_b, ETH_ALEN);
 }
 
-static int set_pkt_sock_fanout(pkt_sock_t * const pkt_sock, int sock_group_idx)
+static int set_pkt_sock_fanout_mmap(pkt_sock_mmap_t * const pkt_sock,
+		int sock_group_idx)
 {
-#if ODP_PACKET_SOCKET_FANOUT == 1
-	/* Use FANOUT-mode for socket */
 	int sockfd = pkt_sock->sockfd;
 	int val;
 	int err;
@@ -80,16 +79,9 @@  static int set_pkt_sock_fanout(pkt_sock_t * const pkt_sock, int sock_group_idx)
 		perror("set_pkt_sock_fanout() - setsockopt(PACKET_FANOUT)");
 		return -1;
 	}
-#else
-	(void)pkt_sock;
-	(void)sock_group_idx;
-#endif
-
 	return 0;
 }
 
-#if (ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC) || \
-	(ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG)
 /*
  * ODP_PACKET_SOCKET_BASIC:
  * ODP_PACKET_SOCKET_MMSG:
@@ -163,11 +155,6 @@  int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev,
 		return -1;
 	}
 
-	/* configure PACKET_FANOUT mode for socket (if mode enabled) */
-	err = set_pkt_sock_fanout(pkt_sock, if_idx);
-	if (err != 0)
-		return -1;
-
 	return sockfd;
 }
 
@@ -184,13 +171,11 @@  int close_pkt_sock(pkt_sock_t * const pkt_sock)
 
 	return 0;
 }
-#endif
 
-#if ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_BASIC
 /*
  * ODP_PACKET_SOCKET_BASIC:
  */
-int recv_pkt_sock(pkt_sock_t *const pkt_sock,
+int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock,
 		  odp_packet_t pkt_table[], unsigned len)
 {
 	ssize_t recv_bytes;
@@ -240,7 +225,7 @@  int recv_pkt_sock(pkt_sock_t *const pkt_sock,
 /*
  * ODP_PACKET_SOCKET_BASIC:
  */
-int send_pkt_sock(pkt_sock_t * const pkt_sock,
+int send_pkt_sock_basic(pkt_sock_t * const pkt_sock,
 		  odp_packet_t pkt_table[], unsigned len)
 {
 	odp_packet_t pkt;
@@ -281,11 +266,10 @@  int send_pkt_sock(pkt_sock_t * const pkt_sock,
 	return nb_tx;
 }
 
-#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMSG
 /*
  * ODP_PACKET_SOCKET_MMSG:
  */
-int recv_pkt_sock(pkt_sock_t * const pkt_sock,
+int recv_pkt_sock_mmsg(pkt_sock_t * const pkt_sock,
 		  odp_packet_t pkt_table[], unsigned len)
 {
 	const int sockfd = pkt_sock->sockfd;
@@ -348,7 +332,7 @@  int recv_pkt_sock(pkt_sock_t * const pkt_sock,
 /*
  * ODP_PACKET_SOCKET_MMSG:
  */
-int send_pkt_sock(pkt_sock_t * const pkt_sock,
+int send_pkt_sock_mmsg(pkt_sock_t * const pkt_sock,
 		  odp_packet_t pkt_table[], unsigned len)
 {
 	struct mmsghdr msgvec[ODP_PACKET_SOCKET_MAX_BURST_TX];
@@ -387,7 +371,6 @@  int send_pkt_sock(pkt_sock_t * const pkt_sock,
 	return len;
 }
 
-#elif ODP_PACKET_SOCKET_MODE == ODP_PACKET_SOCKET_MMAP
 /*
  * ODP_PACKET_SOCKET_MMAP:
  */
@@ -402,7 +385,7 @@  union frame_map {
 	void *raw;
 };
 
-static int pkt_socket(void)
+static int mmap_pkt_socket(void)
 {
 	int ver = TPACKET_V2;
 
@@ -421,23 +404,23 @@  static int pkt_socket(void)
 	return sock;
 }
 
-static inline int rx_kernel_ready(struct tpacket2_hdr *hdr)
+static inline int mmap_rx_kernel_ready(struct tpacket2_hdr *hdr)
 {
 	return ((hdr->tp_status & TP_STATUS_USER) == TP_STATUS_USER);
 }
 
-static inline void rx_user_ready(struct tpacket2_hdr *hdr)
+static inline void mmap_rx_user_ready(struct tpacket2_hdr *hdr)
 {
 	hdr->tp_status = TP_STATUS_KERNEL;
 	__sync_synchronize();
 }
 
-static inline int tx_kernel_ready(struct tpacket2_hdr *hdr)
+static inline int mmap_tx_kernel_ready(struct tpacket2_hdr *hdr)
 {
 	return !(hdr->tp_status & (TP_STATUS_SEND_REQUEST | TP_STATUS_SENDING));
 }
 
-static inline void tx_user_ready(struct tpacket2_hdr *hdr)
+static inline void mmap_tx_user_ready(struct tpacket2_hdr *hdr)
 {
 	hdr->tp_status = TP_STATUS_SEND_REQUEST;
 	__sync_synchronize();
@@ -462,7 +445,7 @@  static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring,
 	frame_num = ring->frame_num;
 
 	while (i < len) {
-		if (rx_kernel_ready(ring->rd[frame_num].iov_base)) {
+		if (mmap_rx_kernel_ready(ring->rd[frame_num].iov_base)) {
 			ppd.raw = ring->rd[frame_num].iov_base;
 
 			next_frame_num = (frame_num + 1) % ring->rd_num;
@@ -474,7 +457,7 @@  static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring,
 			eth_hdr = (struct ethhdr *)pkt_buf;
 			if (odp_unlikely(ethaddrs_equal(if_mac,
 							eth_hdr->h_source))) {
-				rx_user_ready(ppd.raw); /* drop */
+				mmap_rx_user_ready(ppd.raw); /* drop */
 				continue;
 			}
 
@@ -486,7 +469,7 @@  static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring,
 				 + frame_offset;
 			memcpy(l2_hdr, pkt_buf, pkt_len);
 
-			rx_user_ready(ppd.raw);
+			mmap_rx_user_ready(ppd.raw);
 
 			/* Parse and set packet header data */
 			odp_packet_parse(pkt_table[i], pkt_len, frame_offset);
@@ -516,7 +499,7 @@  static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring,
 	frame_num = ring->frame_num;
 
 	while (i < len) {
-		if (tx_kernel_ready(ring->rd[frame_num].iov_base)) {
+		if (mmap_tx_kernel_ready(ring->rd[frame_num].iov_base)) {
 			ppd.raw = ring->rd[frame_num].iov_base;
 
 			next_frame_num = (frame_num + 1) % ring->rd_num;
@@ -530,7 +513,7 @@  static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring,
 			memcpy((uint8_t *)ppd.raw + TPACKET2_HDRLEN -
 			       sizeof(struct sockaddr_ll), pkt_buf, pkt_len);
 
-			tx_user_ready(ppd.raw);
+			mmap_tx_user_ready(ppd.raw);
 
 			odp_packet_free(pkt_table[i]);
 			frame_num = next_frame_num;
@@ -553,7 +536,7 @@  static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring,
 	return i;
 }
 
-static void fill_ring(struct ring *ring, unsigned blocks)
+static void mmap_fill_ring(struct ring *ring, unsigned blocks)
 {
 	ring->req.tp_block_size = getpagesize() << 2;
 	ring->req.tp_frame_size = TPACKET_ALIGNMENT << 7;
@@ -567,7 +550,7 @@  static void fill_ring(struct ring *ring, unsigned blocks)
 	ring->flen = ring->req.tp_frame_size;
 }
 
-static int set_packet_loss_discard(int sock)
+static int mmap_set_packet_loss_discard(int sock)
 {
 	int ret, discard = 1;
 
@@ -581,7 +564,7 @@  static int set_packet_loss_discard(int sock)
 	return 0;
 }
 
-static int setup_ring(int sock, struct ring *ring, int type)
+static int mmap_setup_ring(int sock, struct ring *ring, int type)
 {
 	int ret = 0;
 	unsigned blocks = 256;
@@ -591,12 +574,12 @@  static int setup_ring(int sock, struct ring *ring, int type)
 	ring->version = TPACKET_V2;
 
 	if (type == PACKET_TX_RING) {
-		ret = set_packet_loss_discard(sock);
+		ret = mmap_set_packet_loss_discard(sock);
 		if (ret != 0)
 			return -1;
 	}
 
-	fill_ring(ring, blocks);
+	mmap_fill_ring(ring, blocks);
 
 	ret = setsockopt(sock, SOL_PACKET, type, &ring->req, sizeof(ring->req));
 	if (ret == -1) {
@@ -614,7 +597,7 @@  static int setup_ring(int sock, struct ring *ring, int type)
 	return 0;
 }
 
-static int mmap_sock(pkt_sock_t *pkt_sock)
+static int mmap_sock(pkt_sock_mmap_t *pkt_sock)
 {
 	int i;
 	int sock = pkt_sock->sockfd;
@@ -655,14 +638,14 @@  static int mmap_sock(pkt_sock_t *pkt_sock)
 	return 0;
 }
 
-static void unmap_sock(pkt_sock_t *pkt_sock)
+static void mmap_unmap_sock(pkt_sock_mmap_t *pkt_sock)
 {
 	munmap(pkt_sock->mmap_base, pkt_sock->mmap_len);
 	free(pkt_sock->rx_ring.rd);
 	free(pkt_sock->tx_ring.rd);
 }
 
-static int bind_sock(pkt_sock_t *pkt_sock, char *netdev)
+static int mmap_bind_sock(pkt_sock_mmap_t *pkt_sock, char *netdev)
 {
 	int ret;
 
@@ -684,7 +667,7 @@  static int bind_sock(pkt_sock_t *pkt_sock, char *netdev)
 	return 0;
 }
 
-static int store_hw_addr(pkt_sock_t * const pkt_sock, char *netdev)
+static int mmap_store_hw_addr(pkt_sock_mmap_t * const pkt_sock, char *netdev)
 {
 	struct ifreq ethreq;
 	int ret;
@@ -707,8 +690,8 @@  static int store_hw_addr(pkt_sock_t * const pkt_sock, char *netdev)
 /*
  * ODP_PACKET_SOCKET_MMAP:
  */
-int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev,
-		   odp_buffer_pool_t pool)
+int setup_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock, char *netdev,
+		   odp_buffer_pool_t pool, int fanout)
 {
 	odp_packet_t pkt;
 	uint8_t *pkt_buf;
@@ -733,17 +716,19 @@  int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev,
 	odp_packet_free(pkt);
 
 	pkt_sock->pool = pool;
-	pkt_sock->sockfd = pkt_socket();
+	pkt_sock->sockfd = mmap_pkt_socket();
 
-	ret = bind_sock(pkt_sock, netdev);
+	ret = mmap_bind_sock(pkt_sock, netdev);
 	if (ret != 0)
 		return -1;
 
-	ret = setup_ring(pkt_sock->sockfd, &pkt_sock->tx_ring, PACKET_TX_RING);
+	ret = mmap_setup_ring(pkt_sock->sockfd, &pkt_sock->tx_ring,
+			PACKET_TX_RING);
 	if (ret != 0)
 		return -1;
 
-	ret = setup_ring(pkt_sock->sockfd, &pkt_sock->rx_ring, PACKET_RX_RING);
+	ret = mmap_setup_ring(pkt_sock->sockfd, &pkt_sock->rx_ring,
+			PACKET_RX_RING);
 	if (ret != 0)
 		return -1;
 
@@ -751,7 +736,7 @@  int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev,
 	if (ret != 0)
 		return -1;
 
-	ret = store_hw_addr(pkt_sock, netdev);
+	ret = mmap_store_hw_addr(pkt_sock, netdev);
 	if (ret != 0)
 		return -1;
 
@@ -761,9 +746,11 @@  int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev,
 		return -1;
 	}
 
-	ret = set_pkt_sock_fanout(pkt_sock, if_idx);
-	if (ret != 0)
-		return -1;
+	if (fanout) {
+		ret = set_pkt_sock_fanout_mmap(pkt_sock, if_idx);
+		if (ret != 0)
+			return -1;
+	}
 
 	return pkt_sock->sockfd;
 }
@@ -771,9 +758,9 @@  int setup_pkt_sock(pkt_sock_t * const pkt_sock, char *netdev,
 /*
  * ODP_PACKET_SOCKET_MMAP:
  */
-int close_pkt_sock(pkt_sock_t * const pkt_sock)
+int close_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock)
 {
-	unmap_sock(pkt_sock);
+	mmap_unmap_sock(pkt_sock);
 	if (close(pkt_sock->sockfd) != 0) {
 		perror("close_pkt_sock() - close(sockfd)");
 		return -1;
@@ -785,7 +772,7 @@  int close_pkt_sock(pkt_sock_t * const pkt_sock)
 /*
  * ODP_PACKET_SOCKET_MMAP:
  */
-int recv_pkt_sock(pkt_sock_t * const pkt_sock,
+int recv_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock,
 		  odp_packet_t pkt_table[], unsigned len)
 {
 	return pkt_mmap_v2_rx(pkt_sock->rx_ring.sock, &pkt_sock->rx_ring,
@@ -796,13 +783,9 @@  int recv_pkt_sock(pkt_sock_t * const pkt_sock,
 /*
  * ODP_PACKET_SOCKET_MMAP:
  */
-int send_pkt_sock(pkt_sock_t * const pkt_sock,
+int send_pkt_sock_mmap(pkt_sock_mmap_t * const pkt_sock,
 		  odp_packet_t pkt_table[], unsigned len)
 {
 	return pkt_mmap_v2_tx(pkt_sock->tx_ring.sock, &pkt_sock->tx_ring,
 			      pkt_table, len);
 }
-
-#else
-#error "Unsupported ODP_PACKET_SOCKET_MODE!"
-#endif
diff --git a/test/packet/odp_example_pktio.c b/test/packet/odp_example_pktio.c
index 85bbdd7..1d62123 100644
--- a/test/packet/odp_example_pktio.c
+++ b/test/packet/odp_example_pktio.c
@@ -42,6 +42,8 @@  typedef struct {
 	int if_count;		/**< Number of interfaces to be used */
 	char **if_names;	/**< Array of pointers to interface names */
 	int mode;		/**< Packet IO mode */
+	int type;		/**< Packet IO type */
+	int fanout;		/**< Packet IO fanout */
 	odp_buffer_pool_t pool;	/**< Buffer pool for packet IO */
 } appl_args_t;
 
@@ -52,6 +54,8 @@  typedef struct {
 	char *pktio_dev;	/**< Interface name to use */
 	odp_buffer_pool_t pool;	/**< Buffer pool for packet IO */
 	int mode;		/**< Thread mode */
+	int type;		/**< Thread i/o type */
+	int fanout;		/**< Thread i/o fanout */
 } thread_args_t;
 
 /**
@@ -111,7 +115,8 @@  static void *pktio_queue_thread(void *arg)
 	}
 
 	/* Open a packet IO instance for this thread */
-	sock_params->type = ODP_PKTIO_TYPE_SOCKET;
+	sock_params->type = thr_args->type;
+	sock_params->fanout = thr_args->fanout;
 	pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, &params);
 	if (pktio == ODP_PKTIO_INVALID) {
 		ODP_ERR("  [%02i] Error: pktio create failed\n", thr);
@@ -223,7 +228,8 @@  static void *pktio_ifburst_thread(void *arg)
 	}
 
 	/* Open a packet IO instance for this thread */
-	sock_params->type = ODP_PKTIO_TYPE_SOCKET;
+	sock_params->type = thr_args->type;
+	sock_params->fanout = thr_args->fanout;
 	pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, &params);
 	if (pktio == ODP_PKTIO_INVALID) {
 		ODP_ERR("  [%02i] Error: pktio create failed.\n", thr);
@@ -357,6 +363,8 @@  int main(int argc, char *argv[])
 		args->thread[i].pktio_dev = args->appl.if_names[if_idx];
 		args->thread[i].pool = pool;
 		args->thread[i].mode = args->appl.mode;
+		args->thread[i].type = args->appl.type;
+		args->thread[i].fanout = args->appl.fanout;
 
 		if (args->appl.mode == APPL_MODE_PKT_BURST)
 			thr_run_func = pktio_ifburst_thread;
@@ -470,9 +478,11 @@  static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
 	};
 
 	appl_args->mode = -1; /* Invalid, must be changed by parsing */
+	appl_args->type = 3;  /* 3: ODP_PKTIO_TYPE_SOCKET_MMAP */
+	appl_args->fanout = 1; /* turn off fanout by default for mmap */
 
 	while (1) {
-		opt = getopt_long(argc, argv, "+c:i:m:h",
+		opt = getopt_long(argc, argv, "+c:i:m:t:f:h",
 				  longopts, &long_index);
 
 		if (opt == -1)
@@ -533,6 +543,14 @@  static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
 				appl_args->mode = APPL_MODE_PKT_QUEUE;
 			break;
 
+		case 't':
+			appl_args->type = atoi(optarg);
+			break;
+
+		case 'f':
+			appl_args->type = atoi(optarg);
+			break;
+
 		case 'h':
 			usage(argv[0]);
 			exit(EXIT_SUCCESS);
@@ -602,6 +620,12 @@  static void usage(char *progname)
 	       "  -i, --interface Eth interfaces (comma-separated, no spaces)\n"
 	       "  -m, --mode      0: Burst send&receive packets (no queues)\n"
 	       "                  1: Send&receive packets through ODP queues.\n"
+	       " -t, --type   1: ODP_PKTIO_TYPE_SOCKET_BASIC\n"
+	       "	      2: ODP_PKTIO_TYPE_SOCKET_MMSG\n"
+	       "	      3: ODP_PKTIO_TYPE_SOCKET_MMAP\n"
+	       "	      4: ODP_PKTIO_TYPE_NETMAP\n"
+	       "	 Default: 3: ODP_PKTIO_TYPE_SOCKET_MMAP\n"
+	       " -f, --fanout 0: off 1: on (Default 1: on)\n"
 	       "\n"
 	       "Optional OPTIONS\n"
 	       "  -c, --count <number> Core count.\n"