diff mbox series

[CLOUD-DEV,RFCv1] Add generic ops_data support

Message ID 1504007274-32201-2-git-send-email-bogdan.pricope@linaro.org
State New
Headers show
Series [CLOUD-DEV,RFCv1] Add generic ops_data support | expand

Commit Message

Bogdan Pricope Aug. 29, 2017, 11:47 a.m. UTC
Signed-off-by: Bogdan Pricope <bogdan.pricope@linaro.org>

---
 .../linux-generic/include/odp_config_internal.h    |   2 +
 .../linux-generic/include/odp_packet_io_internal.h |  25 ++-
 .../linux-generic/include/odp_pktio_ops_socket.h   |  20 ---
 .../include/odp_pktio_ops_subsystem.h              |  25 ---
 platform/linux-generic/odp_packet_io.c             |   1 +
 platform/linux-generic/pktio/common.c              |  85 +++++++++
 platform/linux-generic/pktio/dpdk.c                | 103 +++++------
 platform/linux-generic/pktio/ipc.c                 | 190 +++++++++++----------
 platform/linux-generic/pktio/loopback.c            |  27 ++-
 platform/linux-generic/pktio/netmap.c              |  94 +++++-----
 platform/linux-generic/pktio/pcap.c                |  20 +--
 platform/linux-generic/pktio/socket.c              | 117 +++----------
 platform/linux-generic/pktio/socket_mmap.c         |  46 +++--
 platform/linux-generic/pktio/tap.c                 |  33 ++--
 14 files changed, 415 insertions(+), 373 deletions(-)

-- 
2.1.4
diff mbox series

Patch

diff --git a/platform/linux-generic/include/odp_config_internal.h b/platform/linux-generic/include/odp_config_internal.h
index e8d0acb..f037fc6 100644
--- a/platform/linux-generic/include/odp_config_internal.h
+++ b/platform/linux-generic/include/odp_config_internal.h
@@ -34,6 +34,8 @@ 
  */
 #define ODP_CONFIG_PKTIO_ENTRIES 64
 
+#define ODP_CONFIG_PKTIO_ODPS_DATA_MAX_SIZE 5500
+
 /*
  * Minimum buffer alignment
  *
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h
index 7359b58..585f784 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -46,9 +46,11 @@  typedef union pktio_entry_u pktio_entry_t;
  *  requested number of packets were not handled. */
 #define SOCK_ERR_REPORT(e) (e != EAGAIN && e != EWOULDBLOCK && e != EINTR)
 
+#define _ops_data(_p, _mod) ((pktio_ops_ ## _mod ## _data_t *)_p->s.ops_data)
+
 struct pktio_entry {
 	const pktio_ops_module_t *ops;	/**< Implementation specific methods */
-	pktio_ops_data_t ops_data;	/**< IO operation specific data */
+	uint8_t ops_data[ODP_CONFIG_PKTIO_ODPS_DATA_MAX_SIZE];
 	/* These two locks together lock the whole pktio device */
 	odp_ticketlock_t rxl;		/**< RX ticketlock */
 	odp_ticketlock_t txl;		/**< TX ticketlock */
@@ -151,6 +153,27 @@  int sock_stats_fd(pktio_entry_t *pktio_entry,
 		  int fd);
 int sock_stats_reset_fd(pktio_entry_t *pktio_entry, int fd);
 
+/**
+ * Read the MTU from a packet socket
+ */
+uint32_t mtu_get_fd(int fd, const char *name);
+
+/**
+ * Enable/Disable promisc mode for a packet socket
+ */
+int promisc_mode_set_fd(int fd, const char *name, int enable);
+
+/**
+ * Return promisc mode of a packet socket
+ */
+int promisc_mode_get_fd(int fd, const char *name);
+
+
+/**
+ * Get ethtool statistics of a packet socket
+ */
+int ethtool_stats_get_fd(int fd, const char *name, odp_pktio_stats_t *stats);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/linux-generic/include/odp_pktio_ops_socket.h b/platform/linux-generic/include/odp_pktio_ops_socket.h
index 32c49c0..179741e 100644
--- a/platform/linux-generic/include/odp_pktio_ops_socket.h
+++ b/platform/linux-generic/include/odp_pktio_ops_socket.h
@@ -99,21 +99,6 @@  ethaddrs_equal(unsigned char mac_a[], unsigned char mac_b[])
 int mac_addr_get_fd(int fd, const char *name, unsigned char mac_dst[]);
 
 /**
- * Read the MTU from a packet socket
- */
-uint32_t mtu_get_fd(int fd, const char *name);
-
-/**
- * Enable/Disable promisc mode for a packet socket
- */
-int promisc_mode_set_fd(int fd, const char *name, int enable);
-
-/**
- * Return promisc mode of a packet socket
- */
-int promisc_mode_get_fd(int fd, const char *name);
-
-/**
  * Return link status of a packet socket (up/down)
  */
 int link_status_fd(int fd, const char *name);
@@ -164,9 +149,4 @@  int rss_conf_set_fd(int fd, const char *name,
  */
 void rss_conf_print(const odp_pktin_hash_proto_t *hash_proto);
 
-/**
- * Get ethtool statistics of a packet socket
- */
-int ethtool_stats_get_fd(int fd, const char *name, odp_pktio_stats_t *stats);
-
 #endif
diff --git a/platform/linux-generic/include/odp_pktio_ops_subsystem.h b/platform/linux-generic/include/odp_pktio_ops_subsystem.h
index 7a915b8..ff497a2 100644
--- a/platform/linux-generic/include/odp_pktio_ops_subsystem.h
+++ b/platform/linux-generic/include/odp_pktio_ops_subsystem.h
@@ -78,29 +78,4 @@  typedef ODP_MODULE_CLASS(pktio_ops) {
 	odp_api_proto(pktio_ops, print) print;
 } pktio_ops_module_t;
 
-/* All implementations of this subsystem */
-#include <odp_pktio_ops_ipc.h>
-#include <odp_pktio_ops_loopback.h>
-#include <odp_pktio_ops_netmap.h>
-#include <odp_pktio_ops_pcap.h>
-#include <odp_pktio_ops_socket.h>
-#include <odp_pktio_ops_tap.h>
-
-/* Per implementation private data
- * TODO: refactory each implementation to hide it internally
- */
-typedef union {
-	void *dpdk;
-	pktio_ops_ipc_data_t ipc;
-	pktio_ops_loopback_data_t loopback;
-	pktio_ops_netmap_data_t netmap;
-	pktio_ops_pcap_data_t pcap;
-	pktio_ops_socket_data_t socket;
-	pktio_ops_socket_mmap_data_t mmap;
-	pktio_ops_tap_data_t tap;
-} pktio_ops_data_t;
-
-/* Extract pktio ops data from pktio entry structure */
-#define ops_data(mod) s.ops_data.mod
-
 #endif
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index aa6187d..12513cb 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -26,6 +26,7 @@ 
 #include <ifaddrs.h>
 #include <errno.h>
 #include <time.h>
+#include <linux/if_ether.h>
 
 /* Sleep this many nanoseconds between pktin receive calls */
 #define SLEEP_NSEC  1000
diff --git a/platform/linux-generic/pktio/common.c b/platform/linux-generic/pktio/common.c
index 611bb45..0303cee 100644
--- a/platform/linux-generic/pktio/common.c
+++ b/platform/linux-generic/pktio/common.c
@@ -9,6 +9,13 @@ 
 #include <odp_classification_internal.h>
 #include <errno.h>
 
+#include <sys/ioctl.h>
+#include <sys/types.h>          /* See NOTES */
+#include <sys/socket.h>
+#include <net/if.h>
+#include <linux/if.h>
+
+
 int sock_stats_reset_fd(pktio_entry_t *pktio_entry, int fd)
 {
 	int err = 0;
@@ -80,3 +87,81 @@  int sock_stats_fd(pktio_entry_t *pktio_entry,
 
 	return ret;
 }
+
+/*
+ * ODP_PACKET_SOCKET_MMSG:
+ * ODP_PACKET_SOCKET_MMAP:
+ * ODP_PACKET_NETMAP:
+ */
+uint32_t mtu_get_fd(int fd, const char *name)
+{
+	struct ifreq ifr;
+	int ret;
+
+	snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", name);
+	ret = ioctl(fd, SIOCGIFMTU, &ifr);
+	if (ret < 0) {
+		__odp_errno = errno;
+		ODP_DBG("ioctl(SIOCGIFMTU): %s: \"%s\".\n", strerror(errno),
+			ifr.ifr_name);
+		return 0;
+	}
+	return ifr.ifr_mtu;
+}
+
+/*
+ * ODP_PACKET_SOCKET_MMSG:
+ * ODP_PACKET_SOCKET_MMAP:
+ * ODP_PACKET_NETMAP:
+ */
+int promisc_mode_set_fd(int fd, const char *name, int enable)
+{
+	struct ifreq ifr;
+	int ret;
+
+	snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", name);
+	ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
+	if (ret < 0) {
+		__odp_errno = errno;
+		ODP_DBG("ioctl(SIOCGIFFLAGS): %s: \"%s\".\n", strerror(errno),
+			ifr.ifr_name);
+		return -1;
+	}
+
+	if (enable)
+		ifr.ifr_flags |= IFF_PROMISC;
+	else
+		ifr.ifr_flags &= ~(IFF_PROMISC);
+
+	ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
+	if (ret < 0) {
+		__odp_errno = errno;
+		ODP_DBG("ioctl(SIOCSIFFLAGS): %s: \"%s\".\n", strerror(errno),
+			ifr.ifr_name);
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * ODP_PACKET_SOCKET_MMSG:
+ * ODP_PACKET_SOCKET_MMAP:
+ * ODP_PACKET_NETMAP:
+ */
+int promisc_mode_get_fd(int fd, const char *name)
+{
+	struct ifreq ifr;
+	int ret;
+
+	snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", name);
+	ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
+	if (ret < 0) {
+		__odp_errno = errno;
+		ODP_DBG("ioctl(SIOCGIFFLAGS): %s: \"%s\".\n", strerror(errno),
+			ifr.ifr_name);
+		return -1;
+	}
+
+	return !!(ifr.ifr_flags & IFF_PROMISC);
+}
+
diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c
index 511c777..4ba8996 100644
--- a/platform/linux-generic/pktio/dpdk.c
+++ b/platform/linux-generic/pktio/dpdk.c
@@ -12,6 +12,7 @@ 
 #include <ctype.h>
 #include <unistd.h>
 #include <math.h>
+#include <linux/ethtool.h>
 
 #include <odp/api/cpumask.h>
 
@@ -32,18 +33,6 @@ 
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
 
-static inline pktio_ops_dpdk_data_t *
-	__retrieve_op_data(pktio_entry_t *pktio)
-{
-	return (pktio_ops_dpdk_data_t *)(pktio->ops_data(dpdk));
-}
-
-static inline void __release_op_data(pktio_entry_t *pktio)
-{
-	free(pktio->ops_data(dpdk));
-	pktio->ops_data(dpdk) = NULL;
-}
-
 #if ODP_DPDK_ZERO_COPY
 ODP_STATIC_ASSERT(CONFIG_PACKET_HEADROOM == RTE_PKTMBUF_HEADROOM,
 		  "ODP and DPDK headroom sizes not matching!");
@@ -322,10 +311,11 @@  static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
 	int i, j;
 	int nb_pkts = 0;
 	int alloc_len, num;
-	odp_pool_t pool = __retrieve_op_data(pktio_entry)->pool;
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
+	odp_pool_t pool = pkt_dpdk->pool;
 
 	/* Allocate maximum sized packets */
-	alloc_len = __retrieve_op_data(pktio_entry)->data_room;
+	alloc_len = pkt_dpdk->data_room;
 
 	num = packet_alloc_multi(pool, alloc_len, pkt_table, mbuf_num);
 	if (num != mbuf_num) {
@@ -397,8 +387,7 @@  static inline int pkt_to_mbuf(pktio_entry_t *pktio_entry,
 			      struct rte_mbuf *mbuf_table[],
 			      const odp_packet_t pkt_table[], uint16_t num)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		__retrieve_op_data(pktio_entry);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 	int i, j;
 	char *data;
 	uint16_t pkt_len;
@@ -443,7 +432,8 @@  static inline int mbuf_to_pkt_zero(pktio_entry_t *pktio_entry,
 	void *data;
 	int i;
 	int nb_pkts = 0;
-	odp_pool_t pool = __retrieve_op_data(pktio_entry)->pool;
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
+	odp_pool_t pool = pkt_dpdk->pool;
 
 	for (i = 0; i < mbuf_num; i++) {
 		odp_packet_hdr_t parsed_hdr;
@@ -500,8 +490,8 @@  static inline int pkt_to_mbuf_zero(pktio_entry_t *pktio_entry,
 				   const odp_packet_t pkt_table[], uint16_t num,
 				   uint16_t *seg_count)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		__retrieve_op_data(pktio_entry);
+
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 	int i;
 
 	*seg_count = 0;
@@ -576,8 +566,7 @@  static uint32_t dpdk_vdev_mtu_get(uint8_t port_id)
 
 static uint32_t dpdk_mtu_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		__retrieve_op_data(pktio_entry);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 	uint32_t mtu = 0;
 
 	if (rte_eth_dev_get_mtu(pkt_dpdk->port_id, (uint16_t *)&mtu))
@@ -670,8 +659,7 @@  static void rss_conf_to_hash_proto(struct rte_eth_rss_conf *rss_conf,
 static int dpdk_setup_port(pktio_entry_t *pktio_entry)
 {
 	int ret;
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		__retrieve_op_data(pktio_entry);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 	struct rte_eth_rss_conf rss_conf;
 
 	/* Always set some hash functions to enable DPDK RSS hash calculation */
@@ -713,8 +701,7 @@  static int dpdk_setup_port(pktio_entry_t *pktio_entry)
 
 static int dpdk_close(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		__retrieve_op_data(pktio_entry);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 	unsigned idx;
 	unsigned i, j;
 
@@ -732,7 +719,6 @@  static int dpdk_close(pktio_entry_t *pktio_entry)
 	if (!ODP_DPDK_ZERO_COPY)
 		rte_mempool_free(pkt_dpdk->pkt_pool);
 
-	__release_op_data(pktio_entry);
 	return 0;
 }
 
@@ -866,6 +852,7 @@  static int dpdk_input_queues_config(pktio_entry_t *pktio_entry,
 				    const odp_pktin_queue_param_t *p)
 {
 	odp_pktin_mode_t mode = pktio_entry->s.param.in_mode;
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 	odp_bool_t lockless;
 
 	/**
@@ -878,9 +865,9 @@  static int dpdk_input_queues_config(pktio_entry_t *pktio_entry,
 		lockless = 0;
 
 	if (p->hash_enable && p->num_queues > 1)
-		__retrieve_op_data(pktio_entry)->hash = p->hash_proto;
+		pkt_dpdk->hash = p->hash_proto;
 
-	__retrieve_op_data(pktio_entry)->lockless_rx = lockless;
+	pkt_dpdk->lockless_rx = lockless;
 
 	return 0;
 }
@@ -888,8 +875,7 @@  static int dpdk_input_queues_config(pktio_entry_t *pktio_entry,
 static int dpdk_output_queues_config(pktio_entry_t *pktio_entry,
 				     const odp_pktout_queue_param_t *p)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		__retrieve_op_data(pktio_entry);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 	odp_bool_t lockless;
 
 	if (p->op_mode == ODP_PKTIO_OP_MT_UNSAFE)
@@ -905,8 +891,7 @@  static int dpdk_output_queues_config(pktio_entry_t *pktio_entry,
 static void dpdk_init_capability(pktio_entry_t *pktio_entry,
 				 struct rte_eth_dev_info *dev_info)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		__retrieve_op_data(pktio_entry);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 	odp_pktio_capability_t *capa = &pkt_dpdk->capa;
 
 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
@@ -938,6 +923,7 @@  static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 	int i;
 	pool_t *pool_entry;
 
+	printf("Size of dpdk op_data = %ld\n", sizeof(pktio_ops_dpdk_data_t));
 	if (disable_pktio)
 		return -1;
 
@@ -957,8 +943,8 @@  static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 		dpdk_initialized = 1;
 	}
 
-	pktio_entry->ops_data(dpdk) = malloc(sizeof(pktio_ops_dpdk_data_t));
-	pkt_dpdk = __retrieve_op_data(pktio_entry);
+	/*pktio_entry->ops_data(dpdk) = malloc(sizeof(pktio_ops_dpdk_data_t));*/
+	pkt_dpdk = _ops_data(pktio_entry, dpdk);
 
 	if (odp_unlikely(pkt_dpdk == NULL)) {
 		ODP_ERR("Failed to allocate pktio_ops_dpdk_data_t struct");
@@ -973,7 +959,6 @@  static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 
 	if (rte_eth_dev_count() == 0) {
 		ODP_ERR("No DPDK ports found\n");
-		__release_op_data(pktio_entry);
 		return -1;
 	}
 
@@ -982,7 +967,6 @@  static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 	mtu = dpdk_mtu_get(pktio_entry);
 	if (mtu == 0) {
 		ODP_ERR("Failed to read interface MTU\n");
-		__release_op_data(pktio_entry);
 		return -1;
 	}
 	pkt_dpdk->mtu = mtu + _ODP_ETHHDR_LEN;
@@ -1019,7 +1003,6 @@  static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 	}
 	if (pkt_pool == NULL) {
 		ODP_ERR("Cannot init mbuf packet pool\n");
-		__release_op_data(pktio_entry);
 		return -1;
 	}
 
@@ -1044,8 +1027,7 @@  static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 
 static int dpdk_start(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		__retrieve_op_data(pktio_entry);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 	uint8_t port_id = pkt_dpdk->port_id;
 	int ret;
 	unsigned i;
@@ -1096,7 +1078,9 @@  static int dpdk_start(pktio_entry_t *pktio_entry)
 
 static int dpdk_stop(pktio_entry_t *pktio_entry)
 {
-	rte_eth_dev_stop(__retrieve_op_data(pktio_entry)->port_id);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
+
+	rte_eth_dev_stop(pkt_dpdk->port_id);
 
 	return 0;
 }
@@ -1104,8 +1088,7 @@  static int dpdk_stop(pktio_entry_t *pktio_entry)
 static int dpdk_recv(pktio_entry_t *pktio_entry, int index,
 		     odp_packet_t pkt_table[], int num)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		__retrieve_op_data(pktio_entry);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 	pkt_cache_t *rx_cache = &pkt_dpdk->rx_cache[index];
 	odp_time_t ts_val;
 	odp_time_t *ts = NULL;
@@ -1180,8 +1163,7 @@  static int dpdk_send(pktio_entry_t *pktio_entry, int index,
 		     const odp_packet_t pkt_table[], int num)
 {
 	struct rte_mbuf *tx_mbufs[num];
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		__retrieve_op_data(pktio_entry);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 	uint16_t seg_count = 0;
 	int tx_pkts;
 	int i;
@@ -1244,16 +1226,19 @@  static int dpdk_send(pktio_entry_t *pktio_entry, int index,
 
 static int dpdk_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 {
-	rte_eth_macaddr_get(__retrieve_op_data(pktio_entry)->port_id,
-			    (struct ether_addr *)mac_addr);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
+
+	rte_eth_macaddr_get(pkt_dpdk->port_id, (struct ether_addr *)mac_addr);
+
 	return ETH_ALEN;
 }
 
 static int dpdk_promisc_mode_set(pktio_entry_t *pktio_entry, odp_bool_t enable)
 {
-	uint8_t port_id = __retrieve_op_data(pktio_entry)->port_id;
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
+	uint8_t port_id = pkt_dpdk->port_id;
 
-	if (__retrieve_op_data(pktio_entry)->vdev_sysc_promisc)
+	if (pkt_dpdk->vdev_sysc_promisc)
 		return dpdk_vdev_promisc_mode_set(port_id, enable);
 
 	if (enable)
@@ -1266,9 +1251,10 @@  static int dpdk_promisc_mode_set(pktio_entry_t *pktio_entry, odp_bool_t enable)
 
 static int dpdk_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	uint8_t port_id = __retrieve_op_data(pktio_entry)->port_id;
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
+	uint8_t port_id = pkt_dpdk->port_id;
 
-	if (__retrieve_op_data(pktio_entry)->vdev_sysc_promisc)
+	if (pkt_dpdk->vdev_sysc_promisc)
 		return dpdk_vdev_promisc_mode_get(port_id);
 	else
 		return rte_eth_promiscuous_get(port_id);
@@ -1277,18 +1263,20 @@  static int dpdk_promisc_mode_get(pktio_entry_t *pktio_entry)
 static int dpdk_capability(pktio_entry_t *pktio_entry,
 			   odp_pktio_capability_t *capa)
 {
-	*capa = __retrieve_op_data(pktio_entry)->capa;
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
+
+	*capa = pkt_dpdk->capa;
 	return 0;
 }
 
 static int dpdk_link_status(pktio_entry_t *pktio_entry)
 {
 	struct rte_eth_link link;
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 
 	memset(&link, 0, sizeof(struct rte_eth_link));
 
-	rte_eth_link_get_nowait(
-		__retrieve_op_data(pktio_entry)->port_id, &link);
+	rte_eth_link_get_nowait(pkt_dpdk->port_id, &link);
 
 	return link.link_status;
 }
@@ -1309,9 +1297,9 @@  static int dpdk_stats(pktio_entry_t *pktio_entry, odp_pktio_stats_t *stats)
 {
 	int ret;
 	struct rte_eth_stats rte_stats;
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
 
-	ret = rte_eth_stats_get(
-		__retrieve_op_data(pktio_entry)->port_id, &rte_stats);
+	ret = rte_eth_stats_get(pkt_dpdk->port_id, &rte_stats);
 
 	if (ret == 0) {
 		stats_convert(&rte_stats, stats);
@@ -1322,7 +1310,10 @@  static int dpdk_stats(pktio_entry_t *pktio_entry, odp_pktio_stats_t *stats)
 
 static int dpdk_stats_reset(pktio_entry_t *pktio_entry)
 {
-	rte_eth_stats_reset(__retrieve_op_data(pktio_entry)->port_id);
+	pktio_ops_dpdk_data_t *pkt_dpdk = _ops_data(pktio_entry, dpdk);
+
+	rte_eth_stats_reset(pkt_dpdk->port_id);
+
 	return 0;
 }
 
diff --git a/platform/linux-generic/pktio/ipc.c b/platform/linux-generic/pktio/ipc.c
index 14cd86e..7f388b2 100644
--- a/platform/linux-generic/pktio/ipc.c
+++ b/platform/linux-generic/pktio/ipc.c
@@ -8,10 +8,12 @@ 
 #include <odp/api/system_info.h>
 #include <odp_shm_internal.h>
 #include <_ishm_internal.h>
+#include <odp_pktio_ops_ipc.h>
 
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <linux/if_ether.h>
 
 #define IPC_ODP_DEBUG_PRINT 0
 
@@ -42,7 +44,8 @@  static const char *_ipc_odp_buffer_pool_shm_name(odp_pool_t pool_hdl)
 
 static int _ipc_master_start(pktio_entry_t *pktio_entry)
 {
-	struct pktio_info *pinfo = pktio_entry->ops_data(ipc).pinfo;
+	pktio_ops_ipc_data_t *pkt_ipc = _ops_data(pktio_entry, ipc);
+	struct pktio_info *pinfo = pkt_ipc->pinfo;
 	odp_shm_t shm;
 
 	if (pinfo->slave.init_done == 0)
@@ -56,11 +59,11 @@  static int _ipc_master_start(pktio_entry_t *pktio_entry)
 		return -1;
 	}
 
-	pktio_entry->ops_data(ipc).remote_pool_shm = shm;
-	pktio_entry->ops_data(ipc).pool_base = odp_shm_addr(shm);
-	pktio_entry->ops_data(ipc).pool_mdata_base = (char *)odp_shm_addr(shm);
+	pkt_ipc->remote_pool_shm = shm;
+	pkt_ipc->pool_base = odp_shm_addr(shm);
+	pkt_ipc->pool_mdata_base = (char *)odp_shm_addr(shm);
 
-	odp_atomic_store_u32(&pktio_entry->ops_data(ipc).ready, 1);
+	odp_atomic_store_u32(&pkt_ipc->ready, 1);
 
 	IPC_ODP_DBG("%s started.\n",  pktio_entry->s.name);
 	return 0;
@@ -71,6 +74,7 @@  static int _ipc_init_master(pktio_entry_t *pktio_entry,
 			    odp_pool_t pool_hdl)
 {
 	char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_m_prod")];
+	pktio_ops_ipc_data_t *pkt_ipc = _ops_data(pktio_entry, ipc);
 	pool_t *pool;
 	struct pktio_info *pinfo;
 	const char *pool_name;
@@ -87,62 +91,62 @@  static int _ipc_init_master(pktio_entry_t *pktio_entry,
 	 * to be processed packets ring.
 	 */
 	snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_prod", dev);
-	pktio_entry->ops_data(ipc).tx.send = _ring_create(ipc_shm_name,
+	pkt_ipc->tx.send = _ring_create(ipc_shm_name,
 			PKTIO_IPC_ENTRIES,
 			_RING_SHM_PROC | _RING_NO_LIST);
-	if (!pktio_entry->ops_data(ipc).tx.send) {
+	if (!pkt_ipc->tx.send) {
 		ODP_ERR("pid %d unable to create ipc ring %s name\n",
 			getpid(), ipc_shm_name);
 		return -1;
 	}
 	ODP_DBG("Created IPC ring: %s, count %d, free %d\n",
-		ipc_shm_name, _ring_count(pktio_entry->ops_data(ipc).tx.send),
-		_ring_free_count(pktio_entry->ops_data(ipc).tx.send));
+		ipc_shm_name, _ring_count(pkt_ipc->tx.send),
+		_ring_free_count(pkt_ipc->tx.send));
 
 	/* generate name in shm like ipc_pktio_p for
 	 * already processed packets
 	 */
 	snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_cons", dev);
-	pktio_entry->ops_data(ipc).tx.free = _ring_create(ipc_shm_name,
+	pkt_ipc->tx.free = _ring_create(ipc_shm_name,
 			PKTIO_IPC_ENTRIES,
 			_RING_SHM_PROC | _RING_NO_LIST);
-	if (!pktio_entry->ops_data(ipc).tx.free) {
+	if (!pkt_ipc->tx.free) {
 		ODP_ERR("pid %d unable to create ipc ring %s name\n",
 			getpid(), ipc_shm_name);
 		goto free_m_prod;
 	}
 	ODP_DBG("Created IPC ring: %s, count %d, free %d\n",
-		ipc_shm_name, _ring_count(pktio_entry->ops_data(ipc).tx.free),
-		_ring_free_count(pktio_entry->ops_data(ipc).tx.free));
+		ipc_shm_name, _ring_count(pkt_ipc->tx.free),
+		_ring_free_count(pkt_ipc->tx.free));
 
 	snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_prod", dev);
-	pktio_entry->ops_data(ipc).rx.recv = _ring_create(ipc_shm_name,
+	pkt_ipc->rx.recv = _ring_create(ipc_shm_name,
 			PKTIO_IPC_ENTRIES,
 			_RING_SHM_PROC | _RING_NO_LIST);
-	if (!pktio_entry->ops_data(ipc).rx.recv) {
+	if (!pkt_ipc->rx.recv) {
 		ODP_ERR("pid %d unable to create ipc ring %s name\n",
 			getpid(), ipc_shm_name);
 		goto free_m_cons;
 	}
 	ODP_DBG("Created IPC ring: %s, count %d, free %d\n",
-		ipc_shm_name, _ring_count(pktio_entry->ops_data(ipc).rx.recv),
-		_ring_free_count(pktio_entry->ops_data(ipc).rx.recv));
+		ipc_shm_name, _ring_count(pkt_ipc->rx.recv),
+		_ring_free_count(pkt_ipc->rx.recv));
 
 	snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_cons", dev);
-	pktio_entry->ops_data(ipc).rx.free = _ring_create(ipc_shm_name,
+	pkt_ipc->rx.free = _ring_create(ipc_shm_name,
 			PKTIO_IPC_ENTRIES,
 			_RING_SHM_PROC | _RING_NO_LIST);
-	if (!pktio_entry->ops_data(ipc).rx.free) {
+	if (!pkt_ipc->rx.free) {
 		ODP_ERR("pid %d unable to create ipc ring %s name\n",
 			getpid(), ipc_shm_name);
 		goto free_s_prod;
 	}
 	ODP_DBG("Created IPC ring: %s, count %d, free %d\n",
-		ipc_shm_name, _ring_count(pktio_entry->ops_data(ipc).rx.free),
-		_ring_free_count(pktio_entry->ops_data(ipc).rx.free));
+		ipc_shm_name, _ring_count(pkt_ipc->rx.free),
+		_ring_free_count(pkt_ipc->rx.free));
 
 	/* Set up pool name for remote info */
-	pinfo = pktio_entry->ops_data(ipc).pinfo;
+	pinfo = pkt_ipc->pinfo;
 	pool_name = _ipc_odp_buffer_pool_shm_name(pool_hdl);
 	if (strlen(pool_name) > ODP_POOL_NAME_LEN) {
 		ODP_ERR("pid %d ipc pool name %s is too big %d\n",
@@ -155,7 +159,7 @@  static int _ipc_init_master(pktio_entry_t *pktio_entry,
 	pinfo->slave.pid = 0;
 	pinfo->slave.init_done = 0;
 
-	pktio_entry->ops_data(ipc).pool = pool_hdl;
+	pkt_ipc->pool = pool_hdl;
 
 	ODP_DBG("Pre init... DONE.\n");
 	pinfo->master.init_done = 1;
@@ -221,15 +225,18 @@  static int _ipc_init_slave(const char *dev,
 			   pktio_entry_t *pktio_entry,
 			   odp_pool_t pool)
 {
+	pktio_ops_ipc_data_t *pkt_ipc = _ops_data(pktio_entry, ipc);
+
 	if (strlen(dev) > (ODP_POOL_NAME_LEN - sizeof("_slave_r")))
 		ODP_ABORT("too big ipc name\n");
 
-	pktio_entry->ops_data(ipc).pool = pool;
+	pkt_ipc->pool = pool;
 	return 0;
 }
 
 static int _ipc_slave_start(pktio_entry_t *pktio_entry)
 {
+	pktio_ops_ipc_data_t *pkt_ipc = _ops_data(pktio_entry, ipc);
 	char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_slave_r")];
 	struct pktio_info *pinfo;
 	odp_shm_t shm;
@@ -245,61 +252,61 @@  static int _ipc_slave_start(pktio_entry_t *pktio_entry)
 	sprintf(dev, "ipc:%s", tail);
 
 	snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_prod", dev);
-	pktio_entry->ops_data(ipc).rx.recv  = _ipc_shm_map(ipc_shm_name, pid);
-	if (!pktio_entry->ops_data(ipc).rx.recv) {
+	pkt_ipc->rx.recv  = _ipc_shm_map(ipc_shm_name, pid);
+	if (!pkt_ipc->rx.recv) {
 		ODP_DBG("pid %d unable to find ipc ring %s name\n",
 			getpid(), dev);
 		sleep(1);
 		return -1;
 	}
 	ODP_DBG("Connected IPC ring: %s, count %d, free %d\n",
-		ipc_shm_name, _ring_count(pktio_entry->ops_data(ipc).rx.recv),
-		_ring_free_count(pktio_entry->ops_data(ipc).rx.recv));
+		ipc_shm_name, _ring_count(pkt_ipc->rx.recv),
+		_ring_free_count(pkt_ipc->rx.recv));
 
 	snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_cons", dev);
-	pktio_entry->ops_data(ipc).rx.free = _ipc_shm_map(ipc_shm_name, pid);
-	if (!pktio_entry->ops_data(ipc).rx.free) {
+	pkt_ipc->rx.free = _ipc_shm_map(ipc_shm_name, pid);
+	if (!pkt_ipc->rx.free) {
 		ODP_ERR("pid %d unable to find ipc ring %s name\n",
 			getpid(), dev);
 		goto free_m_prod;
 	}
 	ODP_DBG("Connected IPC ring: %s, count %d, free %d\n",
-		ipc_shm_name, _ring_count(pktio_entry->ops_data(ipc).rx.free),
-		_ring_free_count(pktio_entry->ops_data(ipc).rx.free));
+		ipc_shm_name, _ring_count(pkt_ipc->rx.free),
+		_ring_free_count(pkt_ipc->rx.free));
 
 	snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_prod", dev);
-	pktio_entry->ops_data(ipc).tx.send = _ipc_shm_map(ipc_shm_name, pid);
-	if (!pktio_entry->ops_data(ipc).tx.send) {
+	pkt_ipc->tx.send = _ipc_shm_map(ipc_shm_name, pid);
+	if (!pkt_ipc->tx.send) {
 		ODP_ERR("pid %d unable to find ipc ring %s name\n",
 			getpid(), dev);
 		goto free_m_cons;
 	}
 	ODP_DBG("Connected IPC ring: %s, count %d, free %d\n",
-		ipc_shm_name, _ring_count(pktio_entry->ops_data(ipc).tx.send),
-		_ring_free_count(pktio_entry->ops_data(ipc).tx.send));
+		ipc_shm_name, _ring_count(pkt_ipc->tx.send),
+		_ring_free_count(pkt_ipc->tx.send));
 
 	snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_cons", dev);
-	pktio_entry->ops_data(ipc).tx.free = _ipc_shm_map(ipc_shm_name, pid);
-	if (!pktio_entry->ops_data(ipc).tx.free) {
+	pkt_ipc->tx.free = _ipc_shm_map(ipc_shm_name, pid);
+	if (!pkt_ipc->tx.free) {
 		ODP_ERR("pid %d unable to find ipc ring %s name\n",
 			getpid(), dev);
 		goto free_s_prod;
 	}
 	ODP_DBG("Connected IPC ring: %s, count %d, free %d\n",
-		ipc_shm_name, _ring_count(pktio_entry->ops_data(ipc).tx.free),
-		_ring_free_count(pktio_entry->ops_data(ipc).tx.free));
+		ipc_shm_name, _ring_count(pkt_ipc->tx.free),
+		_ring_free_count(pkt_ipc->tx.free));
 
 	/* Get info about remote pool */
-	pinfo = pktio_entry->ops_data(ipc).pinfo;
+	pinfo = pkt_ipc->pinfo;
 	shm = _ipc_map_remote_pool(pinfo->master.pool_name,
 				   pid);
-	pktio_entry->ops_data(ipc).remote_pool_shm = shm;
-	pktio_entry->ops_data(ipc).pool_mdata_base = (char *)odp_shm_addr(shm);
-	pktio_entry->ops_data(ipc).pkt_size = pinfo->master.block_size;
+	pkt_ipc->remote_pool_shm = shm;
+	pkt_ipc->pool_mdata_base = (char *)odp_shm_addr(shm);
+	pkt_ipc->pkt_size = pinfo->master.block_size;
 
-	_ipc_export_pool(pinfo, pktio_entry->ops_data(ipc).pool);
+	_ipc_export_pool(pinfo, pkt_ipc->pool);
 
-	odp_atomic_store_u32(&pktio_entry->ops_data(ipc).ready, 1);
+	odp_atomic_store_u32(&pkt_ipc->ready, 1);
 	pinfo->slave.init_done = 1;
 
 	ODP_DBG("%s started.\n",  pktio_entry->s.name);
@@ -325,6 +332,7 @@  static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 			  const char *dev,
 			  odp_pool_t pool)
 {
+	pktio_ops_ipc_data_t *pkt_ipc = _ops_data(pktio_entry, ipc);
 	int ret = -1;
 	int pid ODP_UNUSED;
 	struct pktio_info *pinfo;
@@ -338,15 +346,15 @@  static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 	if (strncmp(dev, "ipc", 3))
 		return -1;
 
-	odp_atomic_init_u32(&pktio_entry->ops_data(ipc).ready, 0);
+	odp_atomic_init_u32(&pkt_ipc->ready, 0);
 
-	pktio_entry->ops_data(ipc).rx.cache = _ring_create("ipc_rx_cache",
+	pkt_ipc->rx.cache = _ring_create("ipc_rx_cache",
 						   PKTIO_IPC_ENTRIES,
 						   _RING_NO_LIST);
 
 	/* Shared info about remote pktio */
 	if (sscanf(dev, "ipc:%d:%s", &pid, tail) == 2) {
-		pktio_entry->ops_data(ipc).type = PKTIO_TYPE_IPC_SLAVE;
+		pkt_ipc->type = PKTIO_TYPE_IPC_SLAVE;
 
 		snprintf(name, sizeof(name), "ipc:%s_info", tail);
 		IPC_ODP_DBG("lookup for name %s for pid %d\n", name, pid);
@@ -359,12 +367,12 @@  static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 			odp_shm_free(shm);
 			return -1;
 		}
-		pktio_entry->ops_data(ipc).pinfo = pinfo;
-		pktio_entry->ops_data(ipc).pinfo_shm = shm;
+		pkt_ipc->pinfo = pinfo;
+		pkt_ipc->pinfo_shm = shm;
 		ODP_DBG("process %d is slave\n", getpid());
 		ret = _ipc_init_slave(name, pktio_entry, pool);
 	} else {
-		pktio_entry->ops_data(ipc).type = PKTIO_TYPE_IPC_MASTER;
+		pkt_ipc->type = PKTIO_TYPE_IPC_MASTER;
 		snprintf(name, sizeof(name), "%s_info", dev);
 		shm = odp_shm_reserve(name, sizeof(struct pktio_info),
 				      ODP_CACHE_LINE_SIZE,
@@ -377,8 +385,8 @@  static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 		pinfo = odp_shm_addr(shm);
 		pinfo->master.init_done = 0;
 		pinfo->master.pool_name[0] = 0;
-		pktio_entry->ops_data(ipc).pinfo = pinfo;
-		pktio_entry->ops_data(ipc).pinfo_shm = shm;
+		pkt_ipc->pinfo = pinfo;
+		pkt_ipc->pinfo_shm = shm;
 		ODP_DBG("process %d is master\n", getpid());
 		ret = _ipc_init_master(pktio_entry, dev, pool);
 	}
@@ -388,6 +396,7 @@  static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 
 static void _ipc_free_ring_packets(pktio_entry_t *pktio_entry, _ring_t *r)
 {
+	pktio_ops_ipc_data_t *pkt_ipc = _ops_data(pktio_entry, ipc);
 	uintptr_t offsets[PKTIO_IPC_ENTRIES];
 	int ret;
 	void **rbuf_p;
@@ -398,7 +407,7 @@  static void _ipc_free_ring_packets(pktio_entry_t *pktio_entry, _ring_t *r)
 	if (!r)
 		return;
 
-	pool = pool_entry_from_hdl(pktio_entry->ops_data(ipc).pool);
+	pool = pool_entry_from_hdl(pkt_ipc->pool);
 	addr = odp_shm_addr(pool->shm);
 
 	rbuf_p = (void *)&offsets;
@@ -423,6 +432,7 @@  static void _ipc_free_ring_packets(pktio_entry_t *pktio_entry, _ring_t *r)
 static int ipc_pktio_recv_lockless(pktio_entry_t *pktio_entry,
 				   odp_packet_t pkt_table[], int len)
 {
+	pktio_ops_ipc_data_t *pkt_ipc = _ops_data(pktio_entry, ipc);
 	int pkts = 0;
 	int i;
 	_ring_t *r;
@@ -432,16 +442,16 @@  static int ipc_pktio_recv_lockless(pktio_entry_t *pktio_entry,
 	uint32_t ready;
 	int pkts_ring;
 
-	ready = odp_atomic_load_u32(&pktio_entry->ops_data(ipc).ready);
+	ready = odp_atomic_load_u32(&pkt_ipc->ready);
 	if (odp_unlikely(!ready)) {
 		IPC_ODP_DBG("start pktio is missing before usage?\n");
 		return 0;
 	}
 
-	_ipc_free_ring_packets(pktio_entry, pktio_entry->ops_data(ipc).tx.free);
+	_ipc_free_ring_packets(pktio_entry, pkt_ipc->tx.free);
 
 	/* rx from cache */
-	r = pktio_entry->ops_data(ipc).rx.cache;
+	r = pkt_ipc->rx.cache;
 	pkts = _ring_mc_dequeue_burst(r, ipcbufs_p, len);
 	if (odp_unlikely(pkts < 0))
 		ODP_ABORT("internal error dequeue\n");
@@ -449,7 +459,7 @@  static int ipc_pktio_recv_lockless(pktio_entry_t *pktio_entry,
 	/* rx from other app */
 	if (pkts == 0) {
 		ipcbufs_p = (void *)&offsets[0];
-		r = pktio_entry->ops_data(ipc).rx.recv;
+		r = pkt_ipc->rx.recv;
 		pkts = _ring_mc_dequeue_burst(r, ipcbufs_p, len);
 		if (odp_unlikely(pkts < 0))
 			ODP_ABORT("internal error dequeue\n");
@@ -467,10 +477,9 @@  static int ipc_pktio_recv_lockless(pktio_entry_t *pktio_entry,
 		uint64_t data_pool_off;
 		void *rmt_data_ptr;
 
-		phdr = (void *)((uint8_t *)pktio_entry->
-			ops_data(ipc).pool_mdata_base + offsets[i]);
+		phdr = (void *)((uint8_t *)pkt_ipc->pool_mdata_base + offsets[i]);
 
-		pool = pktio_entry->ops_data(ipc).pool;
+		pool = pkt_ipc->pool;
 		if (odp_unlikely(pool == ODP_POOL_INVALID))
 			ODP_ABORT("invalid pool");
 
@@ -494,12 +503,10 @@  static int ipc_pktio_recv_lockless(pktio_entry_t *pktio_entry,
 		pkt_data = odp_packet_data(pkt);
 		if (odp_unlikely(!pkt_data))
 			ODP_ABORT("unable to map pkt_data ipc_slave %d\n",
-				  (PKTIO_TYPE_IPC_SLAVE ==
-					pktio_entry->ops_data(ipc).type));
+				  (PKTIO_TYPE_IPC_SLAVE == pkt_ipc->type));
 
 		/* Copy packet data from shared pool to local pool. */
-		rmt_data_ptr = (uint8_t *)pktio_entry->
-			ops_data(ipc).pool_mdata_base + data_pool_off;
+		rmt_data_ptr = (uint8_t *)pkt_ipc->pool_mdata_base + data_pool_off;
 		memcpy(pkt_data, rmt_data_ptr, phdr->frame_len);
 
 		/* Copy packets L2, L3 parsed offsets and size */
@@ -518,7 +525,7 @@  static int ipc_pktio_recv_lockless(pktio_entry_t *pktio_entry,
 	/* put back to rx ring dequed but not processed packets*/
 	if (pkts != i) {
 		ipcbufs_p = (void *)&offsets[i];
-		r_p = pktio_entry->ops_data(ipc).rx.cache;
+		r_p = pkt_ipc->rx.cache;
 		pkts_ring = _ring_mp_enqueue_burst(r_p, ipcbufs_p, pkts - i);
 
 		if (pkts_ring != (pkts - i))
@@ -533,7 +540,7 @@  static int ipc_pktio_recv_lockless(pktio_entry_t *pktio_entry,
 	pkts = i;
 
 	/* Now tell other process that we no longer need that buffers.*/
-	r_p = pktio_entry->ops_data(ipc).rx.free;
+	r_p = pkt_ipc->rx.free;
 
 repeat:
 
@@ -577,11 +584,12 @@  static int ipc_pktio_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 static int ipc_pktio_send_lockless(pktio_entry_t *pktio_entry,
 				   const odp_packet_t pkt_table[], int len)
 {
+	pktio_ops_ipc_data_t *pkt_ipc = _ops_data(pktio_entry, ipc);
 	_ring_t *r;
 	void **rbuf_p;
 	int ret;
 	int i;
-	uint32_t ready = odp_atomic_load_u32(&pktio_entry->ops_data(ipc).ready);
+	uint32_t ready = odp_atomic_load_u32(&pkt_ipc->ready);
 	odp_packet_t pkt_table_mapped[len]; /**< Ready to send packet has to be
 					      * in memory mapped pool. */
 	uintptr_t offsets[len];
@@ -589,15 +597,14 @@  static int ipc_pktio_send_lockless(pktio_entry_t *pktio_entry,
 	if (odp_unlikely(!ready))
 		return 0;
 
-	_ipc_free_ring_packets(pktio_entry, pktio_entry->ops_data(ipc).tx.free);
+	_ipc_free_ring_packets(pktio_entry, pkt_ipc->tx.free);
 
 	/* Copy packets to shm shared pool if they are in different
 	 * pool, or if they are references (we can't share across IPC).
 	 */
 	for (i = 0; i < len; i++) {
 		odp_packet_t pkt =  pkt_table[i];
-		pool_t *ipc_pool = pool_entry_from_hdl(
-			pktio_entry->ops_data(ipc).pool);
+		pool_t *ipc_pool = pool_entry_from_hdl(pkt_ipc->pool);
 		odp_packet_hdr_t *pkt_hdr;
 		pool_t *pool;
 
@@ -609,7 +616,7 @@  static int ipc_pktio_send_lockless(pktio_entry_t *pktio_entry,
 			odp_packet_t newpkt;
 
 			newpkt = odp_packet_copy(
-				pkt, pktio_entry->ops_data(ipc).pool);
+				pkt, pkt_ipc->pool);
 			if (newpkt == ODP_PACKET_INVALID)
 				ODP_ABORT("Unable to copy packet\n");
 
@@ -641,19 +648,17 @@  static int ipc_pktio_send_lockless(pktio_entry_t *pktio_entry,
 			    odp_packet_to_u64(pkt), odp_pool_to_u64(pool_hdl),
 			    pkt_hdr, pkt_hdr->buf_hdr.ipc_data_offset,
 			    offsets[i], odp_shm_addr(pool->shm),
-			    odp_shm_addr(pool_entry_from_hdl(pktio_entry->
-					 ops_data(ipc).pool)->shm));
+			    odp_shm_addr(pool_entry_from_hdl(pkt_ipc->pool)->shm));
 	}
 
 	/* Put packets to ring to be processed by other process. */
 	rbuf_p = (void *)&offsets[0];
-	r = pktio_entry->ops_data(ipc).tx.send;
+	r = pkt_ipc->tx.send;
 	ret = _ring_mp_enqueue_burst(r, rbuf_p, len);
 	if (odp_unlikely(ret < 0)) {
 		ODP_ERR("pid %d odp_ring_mp_enqueue_bulk fail, ipc_slave %d, ret %d\n",
 			getpid(),
-			(PKTIO_TYPE_IPC_SLAVE ==
-			 pktio_entry->ops_data(ipc).type),
+			(PKTIO_TYPE_IPC_SLAVE == pkt_ipc->type),
 			ret);
 		ODP_ERR("odp_ring_full: %d, odp_ring_count %d, _ring_free_count %d\n",
 			_ring_full(r), _ring_count(r),
@@ -693,15 +698,16 @@  static int ipc_mac_addr_get(pktio_entry_t *pktio_entry ODP_UNUSED,
 
 static int ipc_start(pktio_entry_t *pktio_entry)
 {
+	pktio_ops_ipc_data_t *pkt_ipc = _ops_data(pktio_entry, ipc);
 	uint32_t ready = odp_atomic_load_u32(
-		&pktio_entry->ops_data(ipc).ready);
+		&pkt_ipc->ready);
 
 	if (ready) {
 		ODP_ABORT("%s Already started\n", pktio_entry->s.name);
 		return -1;
 	}
 
-	if (pktio_entry->ops_data(ipc).type == PKTIO_TYPE_IPC_MASTER)
+	if (pkt_ipc->type == PKTIO_TYPE_IPC_MASTER)
 		return _ipc_master_start(pktio_entry);
 	else
 		return _ipc_slave_start(pktio_entry);
@@ -710,23 +716,24 @@  static int ipc_start(pktio_entry_t *pktio_entry)
 static int ipc_stop(pktio_entry_t *pktio_entry)
 {
 	unsigned tx_send = 0, tx_free = 0;
+	pktio_ops_ipc_data_t *pkt_ipc = _ops_data(pktio_entry, ipc);
 
-	odp_atomic_store_u32(&pktio_entry->ops_data(ipc).ready, 0);
+	odp_atomic_store_u32(&pkt_ipc->ready, 0);
 
-	if (pktio_entry->ops_data(ipc).tx.send)
+	if (pkt_ipc->tx.send)
 		_ipc_free_ring_packets(pktio_entry,
-				       pktio_entry->ops_data(ipc).tx.send);
+				       pkt_ipc->tx.send);
 	/* other process can transfer packets from one ring to
 	 * other, use delay here to free that packets. */
 	sleep(1);
-	if (pktio_entry->ops_data(ipc).tx.free)
+	if (pkt_ipc->tx.free)
 		_ipc_free_ring_packets(pktio_entry,
-				       pktio_entry->ops_data(ipc).tx.free);
+				       pkt_ipc->tx.free);
 
-	if (pktio_entry->ops_data(ipc).tx.send)
-		tx_send = _ring_count(pktio_entry->ops_data(ipc).tx.send);
-	if (pktio_entry->ops_data(ipc).tx.free)
-		tx_free = _ring_count(pktio_entry->ops_data(ipc).tx.free);
+	if (pkt_ipc->tx.send)
+		tx_send = _ring_count(pkt_ipc->tx.send);
+	if (pkt_ipc->tx.free)
+		tx_free = _ring_count(pkt_ipc->tx.free);
 	if (tx_send | tx_free) {
 		ODP_DBG("IPC rings: tx send %d tx free %d\n",
 			tx_send, tx_free);
@@ -737,6 +744,7 @@  static int ipc_stop(pktio_entry_t *pktio_entry)
 
 static int ipc_close(pktio_entry_t *pktio_entry)
 {
+	pktio_ops_ipc_data_t *pkt_ipc = _ops_data(pktio_entry, ipc);
 	char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_m_prod")];
 	char *dev = pktio_entry->s.name;
 	char name[ODP_POOL_NAME_LEN];
@@ -745,7 +753,7 @@  static int ipc_close(pktio_entry_t *pktio_entry)
 
 	ipc_stop(pktio_entry);
 
-	odp_shm_free(pktio_entry->ops_data(ipc).remote_pool_shm);
+	odp_shm_free(pkt_ipc->remote_pool_shm);
 
 	if (sscanf(dev, "ipc:%d:%s", &pid, tail) == 2)
 		snprintf(name, sizeof(name), "ipc:%s", tail);
@@ -753,7 +761,7 @@  static int ipc_close(pktio_entry_t *pktio_entry)
 		snprintf(name, sizeof(name), "%s", dev);
 
 	/* unlink this pktio info for both master and slave */
-	odp_shm_free(pktio_entry->ops_data(ipc).pinfo_shm);
+	odp_shm_free(pkt_ipc->pinfo_shm);
 
 	/* destroy rings */
 	snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_cons", name);
diff --git a/platform/linux-generic/pktio/loopback.c b/platform/linux-generic/pktio/loopback.c
index 0c57233..126b7d2 100644
--- a/platform/linux-generic/pktio/loopback.c
+++ b/platform/linux-generic/pktio/loopback.c
@@ -12,6 +12,7 @@ 
 #include <odp_debug_internal.h>
 #include <odp/api/hints.h>
 #include <odp_queue_if.h>
+#include <odp_pktio_ops_loopback.h>
 
 #include <protocols/eth.h>
 #include <protocols/ip.h>
@@ -19,6 +20,7 @@ 
 #include <errno.h>
 #include <inttypes.h>
 #include <limits.h>
+#include <linux/if_ether.h>
 
 /* MAC address for the "loop" interface */
 static const char pktio_loop_mac[] = {0x02, 0xe9, 0x34, 0x80, 0x73, 0x01};
@@ -28,6 +30,8 @@  static int loopback_stats_reset(pktio_entry_t *pktio_entry);
 static int loopback_open(odp_pktio_t id, pktio_entry_t *pktio_entry,
 			 const char *devname, odp_pool_t pool ODP_UNUSED)
 {
+	pktio_ops_loopback_data_t *pkt_lbk = _ops_data(pktio_entry, loopback);
+
 	if (strcmp(devname, "loop"))
 		return -1;
 
@@ -35,10 +39,9 @@  static int loopback_open(odp_pktio_t id, pktio_entry_t *pktio_entry,
 
 	snprintf(loopq_name, sizeof(loopq_name), "%" PRIu64 "-pktio_loopq",
 		 odp_pktio_to_u64(id));
-	pktio_entry->ops_data(loopback).loopq =
-		odp_queue_create(loopq_name, NULL);
+	pkt_lbk->loopq = odp_queue_create(loopq_name, NULL);
 
-	if (pktio_entry->ops_data(loopback).loopq == ODP_QUEUE_INVALID)
+	if (pkt_lbk->loopq == ODP_QUEUE_INVALID)
 		return -1;
 
 	loopback_stats_reset(pktio_entry);
@@ -48,12 +51,15 @@  static int loopback_open(odp_pktio_t id, pktio_entry_t *pktio_entry,
 
 static int loopback_close(pktio_entry_t *pktio_entry)
 {
-	return odp_queue_destroy(pktio_entry->ops_data(loopback).loopq);
+	pktio_ops_loopback_data_t *pkt_lbk = _ops_data(pktio_entry, loopback);
+
+	return odp_queue_destroy(pkt_lbk->loopq);
 }
 
 static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			 odp_packet_t pkts[], int len)
 {
+	pktio_ops_loopback_data_t *pkt_lbk = _ops_data(pktio_entry, loopback);
 	int nbr, i;
 	odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
 	queue_t queue;
@@ -70,7 +76,7 @@  static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 
 	odp_ticketlock_lock(&pktio_entry->s.rxl);
 
-	queue = queue_fn->from_ext(pktio_entry->ops_data(loopback).loopq);
+	queue = queue_fn->from_ext(pkt_lbk->loopq);
 	nbr = queue_fn->deq_multi(queue, hdr_tbl, len);
 
 	if (pktio_entry->s.config.pktin.bit.ts_all ||
@@ -154,6 +160,7 @@  static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 static int loopback_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			 const odp_packet_t pkt_tbl[], int len)
 {
+	pktio_ops_loopback_data_t *pkt_lbk = _ops_data(pktio_entry, loopback);
 	odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
 	queue_t queue;
 	int i;
@@ -170,7 +177,7 @@  static int loopback_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 
 	odp_ticketlock_lock(&pktio_entry->s.txl);
 
-	queue = queue_fn->from_ext(pktio_entry->ops_data(loopback).loopq);
+	queue = queue_fn->from_ext(pkt_lbk->loopq);
 	ret = queue_fn->enq_multi(queue, hdr_tbl, len);
 
 	if (ret > 0) {
@@ -223,13 +230,17 @@  static int loopback_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
 static int loopback_promisc_mode_set(pktio_entry_t *pktio_entry,
 				     odp_bool_t enable)
 {
-	pktio_entry->ops_data(loopback).promisc = enable;
+	pktio_ops_loopback_data_t *pkt_lbk = _ops_data(pktio_entry, loopback);
+
+	pkt_lbk->promisc = enable;
 	return 0;
 }
 
 static int loopback_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	return pktio_entry->ops_data(loopback).promisc ? 1 : 0;
+	pktio_ops_loopback_data_t *pkt_lbk = _ops_data(pktio_entry, loopback);
+
+	return pkt_lbk->promisc ? 1 : 0;
 }
 
 static int loopback_stats(pktio_entry_t *pktio_entry,
diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c
index 07d6d9e..e105245 100644
--- a/platform/linux-generic/pktio/netmap.c
+++ b/platform/linux-generic/pktio/netmap.c
@@ -22,6 +22,7 @@ 
 #include <odp_classification_datamodel.h>
 #include <odp_classification_inlines.h>
 #include <odp_classification_internal.h>
+#include <odp_pktio_ops_netmap.h>
 
 #include <inttypes.h>
 
@@ -44,8 +45,7 @@  static int netmap_stats_reset(pktio_entry_t *pktio_entry);
 static int netmap_do_ioctl(pktio_entry_t *pktio_entry, unsigned long cmd,
 			   int subcmd)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		&pktio_entry->ops_data(netmap);
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 	struct ethtool_value eval;
 	struct ifreq ifr;
 	int err;
@@ -132,8 +132,7 @@  static inline void map_netmap_rings(netmap_ring_t *rings,
 static int netmap_input_queues_config(pktio_entry_t *pktio_entry,
 				      const odp_pktin_queue_param_t *p)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		&pktio_entry->ops_data(netmap);
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 	odp_pktin_mode_t mode = pktio_entry->s.param.in_mode;
 	unsigned num_queues = p->num_queues;
 	odp_bool_t lockless;
@@ -161,8 +160,7 @@  static int netmap_input_queues_config(pktio_entry_t *pktio_entry,
 static int netmap_output_queues_config(pktio_entry_t *pktio_entry,
 				       const odp_pktout_queue_param_t *p)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		&pktio_entry->ops_data(netmap);
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 
 	pkt_nm->lockless_tx = (p->op_mode == ODP_PKTIO_OP_MT_UNSAFE);
 
@@ -179,8 +177,7 @@  static int netmap_output_queues_config(pktio_entry_t *pktio_entry,
 static inline void netmap_close_descriptors(pktio_entry_t *pktio_entry)
 {
 	int i, j;
-	pktio_ops_netmap_data_t *pkt_nm =
-		&pktio_entry->ops_data(netmap);
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 
 	for (i = 0; i < PKTIO_MAX_QUEUES; i++) {
 		for (j = 0; j < NM_MAX_DESC; j++) {
@@ -203,8 +200,7 @@  static inline void netmap_close_descriptors(pktio_entry_t *pktio_entry)
 
 static int netmap_close(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		&pktio_entry->ops_data(netmap);
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 
 	netmap_close_descriptors(pktio_entry);
 
@@ -218,11 +214,12 @@  static int netmap_close(pktio_entry_t *pktio_entry)
 
 static int netmap_link_status(pktio_entry_t *pktio_entry)
 {
-	if (pktio_entry->ops_data(netmap).is_virtual)
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
+
+	if (pkt_nm->is_virtual)
 		return 1;
 
-	return link_status_fd(pktio_entry->ops_data(netmap).sockfd,
-			      pktio_entry->ops_data(netmap).if_name);
+	return link_status_fd(pkt_nm->sockfd, pkt_nm->if_name);
 }
 
 /**
@@ -236,6 +233,7 @@  static int netmap_link_status(pktio_entry_t *pktio_entry)
  */
 static inline int netmap_wait_for_link(pktio_entry_t *pktio_entry)
 {
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 	int i;
 	int ret;
 
@@ -249,12 +247,12 @@  static inline int netmap_wait_for_link(pktio_entry_t *pktio_entry)
 		 * until the opposing end's interface comes back up again. In
 		 * this case without the additional sleep pktio validation
 		 * tests fail. */
-		if (!pktio_entry->ops_data(netmap).is_virtual)
+		if (!pkt_nm->is_virtual)
 			sleep(1);
 		if (ret == 1)
 			return 1;
 	}
-	ODP_DBG("%s link is down\n", pktio_entry->ops_data(netmap).if_name);
+	ODP_DBG("%s link is down\n", pkt_nm->if_name);
 	return 0;
 }
 
@@ -265,8 +263,7 @@  static inline int netmap_wait_for_link(pktio_entry_t *pktio_entry)
  */
 static void netmap_init_capability(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		&pktio_entry->ops_data(netmap);
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 	odp_pktio_capability_t *capa = &pkt_nm->capa;
 
 	memset(&pkt_nm->capa, 0, sizeof(odp_pktio_capability_t));
@@ -333,8 +330,7 @@  static int netmap_open(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry,
 	const char *prefix;
 	uint32_t mtu;
 	uint32_t buf_size;
-	pktio_ops_netmap_data_t *pkt_nm =
-		&pktio_entry->ops_data(netmap);
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 	struct nm_desc *desc;
 	struct netmap_ring *ring;
 	odp_pktin_hash_proto_t hash_proto;
@@ -457,8 +453,7 @@  error:
 
 static int netmap_start(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		&pktio_entry->ops_data(netmap);
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 	netmap_ring_t *desc_ring;
 	struct nm_desc *desc_ptr;
 	unsigned i;
@@ -614,8 +609,9 @@  static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry,
 				    netmap_slot_t slot_tbl[], int16_t slot_num,
 				    odp_time_t *ts)
 {
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 	odp_packet_t pkt;
-	odp_pool_t pool = pktio_entry->ops_data(netmap).pool;
+	odp_pool_t pool = pkt_nm->pool;
 	odp_packet_hdr_t *pkt_hdr;
 	odp_packet_hdr_t parsed_hdr;
 	int i;
@@ -623,7 +619,7 @@  static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry,
 	int alloc_len;
 
 	/* Allocate maximum sized packets */
-	alloc_len = pktio_entry->ops_data(netmap).mtu;
+	alloc_len = pkt_nm->mtu;
 
 	num = packet_alloc_multi(pool, alloc_len, pkt_tbl, slot_num);
 
@@ -637,9 +633,9 @@  static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry,
 		odp_prefetch(slot.buf);
 
 		if (odp_unlikely(len > pktio_entry->
-				 ops_data(netmap).max_frame_len)) {
+				 pkt_nm->max_frame_len)) {
 			ODP_ERR("RX: frame too big %" PRIu16 " %zu!\n", len,
-				pktio_entry->ops_data(netmap).max_frame_len);
+				pkt_nm->max_frame_len);
 			goto fail;
 		}
 
@@ -735,8 +731,7 @@  static int netmap_recv(pktio_entry_t *pktio_entry, int index,
 		       odp_packet_t pkt_table[], int num)
 {
 	struct nm_desc *desc;
-	pktio_ops_netmap_data_t *pkt_nm =
-		&pktio_entry->ops_data(netmap);
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 	unsigned first_desc_id = pkt_nm->rx_desc_ring[index].s.first;
 	unsigned last_desc_id = pkt_nm->rx_desc_ring[index].s.last;
 	unsigned desc_id;
@@ -789,8 +784,7 @@  static int netmap_recv(pktio_entry_t *pktio_entry, int index,
 static int netmap_send(pktio_entry_t *pktio_entry, int index,
 		       const odp_packet_t pkt_table[], int num)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		&pktio_entry->ops_data(netmap);
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 	struct pollfd polld;
 	struct nm_desc *desc;
 	struct netmap_ring *ring;
@@ -865,48 +859,57 @@  static int netmap_send(pktio_entry_t *pktio_entry, int index,
 
 static int netmap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 {
-	memcpy(mac_addr, pktio_entry->ops_data(netmap).if_mac, ETH_ALEN);
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
+
+	memcpy(mac_addr, pkt_nm->if_mac, ETH_ALEN);
 	return ETH_ALEN;
 }
 
 static uint32_t netmap_mtu_get(pktio_entry_t *pktio_entry)
 {
-	return pktio_entry->ops_data(netmap).mtu;
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
+
+	return pkt_nm->mtu;
 }
 
 static int netmap_promisc_mode_set(pktio_entry_t *pktio_entry,
 				   odp_bool_t enable)
 {
-	if (pktio_entry->ops_data(netmap).is_virtual) {
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
+
+	if (pkt_nm->is_virtual) {
 		__odp_errno = ENOTSUP;
 		return -1;
 	}
 
-	return promisc_mode_set_fd(
-		pktio_entry->ops_data(netmap).sockfd,
-		pktio_entry->ops_data(netmap).if_name, enable);
+	return promisc_mode_set_fd(pkt_nm->sockfd,
+		pkt_nm->if_name, enable);
 }
 
 static int netmap_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	if (pktio_entry->ops_data(netmap).is_virtual)
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
+
+	if (pkt_nm->is_virtual)
 		return 0;
 
-	return promisc_mode_get_fd(
-		pktio_entry->ops_data(netmap).sockfd,
-		pktio_entry->ops_data(netmap).if_name);
+	return promisc_mode_get_fd(pkt_nm->sockfd, pkt_nm->if_name);
 }
 
 static int netmap_capability(pktio_entry_t *pktio_entry,
 			     odp_pktio_capability_t *capa)
 {
-	*capa = pktio_entry->ops_data(netmap).capa;
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
+
+	*capa = pkt_nm->capa;
 	return 0;
 }
 
 static int netmap_stats(pktio_entry_t *pktio_entry,
 			odp_pktio_stats_t *stats)
 {
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
+
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(stats, 0, sizeof(*stats));
 		return 0;
@@ -914,11 +917,13 @@  static int netmap_stats(pktio_entry_t *pktio_entry,
 
 	return sock_stats_fd(pktio_entry,
 			     stats,
-			     pktio_entry->ops_data(netmap).sockfd);
+			     pkt_nm->sockfd);
 }
 
 static int netmap_stats_reset(pktio_entry_t *pktio_entry)
 {
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
+
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(&pktio_entry->s.stats, 0,
 		       sizeof(odp_pktio_stats_t));
@@ -926,15 +931,16 @@  static int netmap_stats_reset(pktio_entry_t *pktio_entry)
 	}
 
 	return sock_stats_reset_fd(pktio_entry,
-				   pktio_entry->ops_data(netmap).sockfd);
+				   pkt_nm->sockfd);
 }
 
 static void netmap_print(pktio_entry_t *pktio_entry)
 {
+	pktio_ops_netmap_data_t *pkt_nm = _ops_data(pktio_entry, netmap);
 	odp_pktin_hash_proto_t hash_proto;
 
-	if (rss_conf_get_fd(pktio_entry->ops_data(netmap).sockfd,
-			    pktio_entry->ops_data(netmap).if_name, &hash_proto))
+	if (rss_conf_get_fd(pkt_nm->sockfd,
+			    pkt_nm->if_name, &hash_proto))
 		rss_conf_print(&hash_proto);
 }
 
diff --git a/platform/linux-generic/pktio/pcap.c b/platform/linux-generic/pktio/pcap.c
index b54501e..360908a 100644
--- a/platform/linux-generic/pktio/pcap.c
+++ b/platform/linux-generic/pktio/pcap.c
@@ -39,6 +39,7 @@ 
 #include <odp_api.h>
 #include <odp_packet_internal.h>
 #include <odp_packet_io_internal.h>
+#include <odp_pktio_ops_pcap.h>
 
 #include <protocols/eth.h>
 
@@ -137,8 +138,7 @@  static int _pcapif_init_tx(pktio_ops_pcap_data_t *pcap)
 static int pcapif_init(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry,
 		       const char *devname, odp_pool_t pool)
 {
-	pktio_ops_pcap_data_t *pcap =
-		&pktio_entry->ops_data(pcap);
+	pktio_ops_pcap_data_t *pcap = _ops_data(pktio_entry, pcap);
 	int ret;
 
 	memset(pcap, 0, sizeof(pktio_ops_pcap_data_t));
@@ -165,8 +165,7 @@  static int pcapif_init(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry,
 
 static int pcapif_close(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_pcap_data_t *pcap =
-		&pktio_entry->ops_data(pcap);
+	pktio_ops_pcap_data_t *pcap = _ops_data(pktio_entry, pcap);
 
 	if (pcap->tx_dump)
 		pcap_dump_close(pcap->tx_dump);
@@ -213,8 +212,7 @@  static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 	odp_packet_t pkt;
 	odp_packet_hdr_t *pkt_hdr;
 	uint32_t pkt_len;
-	pktio_ops_pcap_data_t *pcap =
-		&pktio_entry->ops_data(pcap);
+	pktio_ops_pcap_data_t *pcap = _ops_data(pktio_entry, pcap);
 	odp_time_t ts_val;
 	odp_time_t *ts = NULL;
 
@@ -297,8 +295,7 @@  static int _pcapif_dump_pkt(pktio_ops_pcap_data_t *pcap, odp_packet_t pkt)
 static int pcapif_send_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			   const odp_packet_t pkts[], int len)
 {
-	pktio_ops_pcap_data_t *pcap =
-		&pktio_entry->ops_data(pcap);
+	pktio_ops_pcap_data_t *pcap = _ops_data(pktio_entry, pcap);
 	int i;
 
 	odp_ticketlock_lock(&pktio_entry->s.txl);
@@ -366,8 +363,7 @@  static int pcapif_promisc_mode_set(pktio_entry_t *pktio_entry,
 {
 	char filter_exp[64] = {0};
 	struct bpf_program bpf;
-	pktio_ops_pcap_data_t *pcap =
-		&pktio_entry->ops_data(pcap);
+	pktio_ops_pcap_data_t *pcap = _ops_data(pktio_entry, pcap);
 
 	if (!pcap->rx) {
 		pcap->promisc = enable;
@@ -407,7 +403,9 @@  static int pcapif_promisc_mode_set(pktio_entry_t *pktio_entry,
 
 static int pcapif_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	return pktio_entry->ops_data(pcap).promisc;
+	pktio_ops_pcap_data_t *pcap = _ops_data(pktio_entry, pcap);
+
+	return pcap->promisc;
 }
 
 static int pcapif_stats_reset(pktio_entry_t *pktio_entry)
diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c
index c7c3c5a..cf5f8ff 100644
--- a/platform/linux-generic/pktio/socket.c
+++ b/platform/linux-generic/pktio/socket.c
@@ -35,6 +35,7 @@ 
 #include <odp_api.h>
 #include <odp_packet_internal.h>
 #include <odp_packet_io_internal.h>
+#include <odp_pktio_ops_socket.h>
 #include <odp_align_internal.h>
 #include <odp_debug_internal.h>
 #include <odp_classification_datamodel.h>
@@ -122,82 +123,6 @@  int mac_addr_get_fd(int fd, const char *name, unsigned char mac_dst[])
 	return 0;
 }
 
-/*
- * ODP_PACKET_SOCKET_MMSG:
- * ODP_PACKET_SOCKET_MMAP:
- * ODP_PACKET_NETMAP:
- */
-uint32_t mtu_get_fd(int fd, const char *name)
-{
-	struct ifreq ifr;
-	int ret;
-
-	snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", name);
-	ret = ioctl(fd, SIOCGIFMTU, &ifr);
-	if (ret < 0) {
-		__odp_errno = errno;
-		ODP_DBG("ioctl(SIOCGIFMTU): %s: \"%s\".\n", strerror(errno),
-			ifr.ifr_name);
-		return 0;
-	}
-	return ifr.ifr_mtu;
-}
-
-/*
- * ODP_PACKET_SOCKET_MMSG:
- * ODP_PACKET_SOCKET_MMAP:
- * ODP_PACKET_NETMAP:
- */
-int promisc_mode_set_fd(int fd, const char *name, int enable)
-{
-	struct ifreq ifr;
-	int ret;
-
-	snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", name);
-	ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
-	if (ret < 0) {
-		__odp_errno = errno;
-		ODP_DBG("ioctl(SIOCGIFFLAGS): %s: \"%s\".\n", strerror(errno),
-			ifr.ifr_name);
-		return -1;
-	}
-
-	if (enable)
-		ifr.ifr_flags |= IFF_PROMISC;
-	else
-		ifr.ifr_flags &= ~(IFF_PROMISC);
-
-	ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
-	if (ret < 0) {
-		__odp_errno = errno;
-		ODP_DBG("ioctl(SIOCSIFFLAGS): %s: \"%s\".\n", strerror(errno),
-			ifr.ifr_name);
-		return -1;
-	}
-	return 0;
-}
-
-/*
- * ODP_PACKET_SOCKET_MMSG:
- * ODP_PACKET_SOCKET_MMAP:
- * ODP_PACKET_NETMAP:
- */
-int promisc_mode_get_fd(int fd, const char *name)
-{
-	struct ifreq ifr;
-	int ret;
-
-	snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", name);
-	ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
-	if (ret < 0) {
-		__odp_errno = errno;
-		ODP_DBG("ioctl(SIOCGIFFLAGS): %s: \"%s\".\n", strerror(errno),
-			ifr.ifr_name);
-		return -1;
-	}
-
-	return !!(ifr.ifr_flags & IFF_PROMISC);
-}
 
 int link_status_fd(int fd, const char *name)
 {
@@ -454,8 +379,7 @@  void rss_conf_print(const odp_pktin_hash_proto_t *hash_proto)
  */
 static int sock_close(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		&pktio_entry->ops_data(socket);
+	pktio_ops_socket_data_t *pkt_sock = _ops_data(pktio_entry, socket);
 
 	if (pkt_sock->sockfd != -1 && close(pkt_sock->sockfd) != 0) {
 		__odp_errno = errno;
@@ -478,8 +402,7 @@  static int sock_setup_pkt(pktio_entry_t *pktio_entry, const char *netdev,
 	struct ifreq ethreq;
 	struct sockaddr_ll sa_ll;
 	char shm_name[ODP_SHM_NAME_LEN];
-	pktio_ops_socket_data_t *pkt_sock =
-		&pktio_entry->ops_data(socket);
+	pktio_ops_socket_data_t *pkt_sock = _ops_data(pktio_entry, socket);
 	odp_pktio_stats_t cur_stats;
 
 	/* Init pktio entry */
@@ -603,8 +526,7 @@  static uint32_t _rx_pkt_to_iovec(odp_packet_t pkt,
 static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			  odp_packet_t pkt_table[], int len)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		&pktio_entry->ops_data(socket);
+	pktio_ops_socket_data_t *pkt_sock = _ops_data(pktio_entry, socket);
 	odp_pool_t pool = pkt_sock->pool;
 	odp_time_t ts_val;
 	odp_time_t *ts = NULL;
@@ -719,8 +641,7 @@  static uint32_t _tx_pkt_to_iovec(odp_packet_t pkt,
 static int sock_mmsg_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			  const odp_packet_t pkt_table[], int len)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		&pktio_entry->ops_data(socket);
+	pktio_ops_socket_data_t *pkt_sock = _ops_data(pktio_entry, socket);
 	struct mmsghdr msgvec[len];
 	struct iovec iovecs[len][MAX_SEGS];
 	int ret;
@@ -766,7 +687,9 @@  static int sock_mmsg_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
  */
 static uint32_t sock_mtu_get(pktio_entry_t *pktio_entry)
 {
-	return pktio_entry->ops_data(socket).mtu;
+	pktio_ops_socket_data_t *pkt_sock = _ops_data(pktio_entry, socket);
+
+	return pkt_sock->mtu;
 }
 
 /*
@@ -775,7 +698,9 @@  static uint32_t sock_mtu_get(pktio_entry_t *pktio_entry)
 static int sock_mac_addr_get(pktio_entry_t *pktio_entry,
 			     void *mac_addr)
 {
-	memcpy(mac_addr, pktio_entry->ops_data(socket).if_mac, ETH_ALEN);
+	pktio_ops_socket_data_t *pkt_sock = _ops_data(pktio_entry, socket);
+
+	memcpy(mac_addr, pkt_sock->if_mac, ETH_ALEN);
 	return ETH_ALEN;
 }
 
@@ -785,7 +710,9 @@  static int sock_mac_addr_get(pktio_entry_t *pktio_entry,
 static int sock_promisc_mode_set(pktio_entry_t *pktio_entry,
 				 odp_bool_t enable)
 {
-	return promisc_mode_set_fd(pktio_entry->ops_data(socket).sockfd,
+	pktio_ops_socket_data_t *pkt_sock = _ops_data(pktio_entry, socket);
+
+	return promisc_mode_set_fd(pkt_sock->sockfd,
 				   pktio_entry->s.name, enable);
 }
 
@@ -794,13 +721,17 @@  static int sock_promisc_mode_set(pktio_entry_t *pktio_entry,
  */
 static int sock_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	return promisc_mode_get_fd(pktio_entry->ops_data(socket).sockfd,
+	pktio_ops_socket_data_t *pkt_sock = _ops_data(pktio_entry, socket);
+
+	return promisc_mode_get_fd(pkt_sock->sockfd,
 				   pktio_entry->s.name);
 }
 
 static int sock_link_status(pktio_entry_t *pktio_entry)
 {
-	return link_status_fd(pktio_entry->ops_data(socket).sockfd,
+	pktio_ops_socket_data_t *pkt_sock = _ops_data(pktio_entry, socket);
+
+	return link_status_fd(pkt_sock->sockfd,
 			      pktio_entry->s.name);
 }
 
@@ -822,6 +753,8 @@  static int sock_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
 static int sock_stats(pktio_entry_t *pktio_entry,
 		      odp_pktio_stats_t *stats)
 {
+	pktio_ops_socket_data_t *pkt_sock = _ops_data(pktio_entry, socket);
+
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(stats, 0, sizeof(*stats));
 		return 0;
@@ -829,11 +762,13 @@  static int sock_stats(pktio_entry_t *pktio_entry,
 
 	return sock_stats_fd(pktio_entry,
 			     stats,
-			     pktio_entry->ops_data(socket).sockfd);
+			     pkt_sock->sockfd);
 }
 
 static int sock_stats_reset(pktio_entry_t *pktio_entry)
 {
+	pktio_ops_socket_data_t *pkt_sock = _ops_data(pktio_entry, socket);
+
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(&pktio_entry->s.stats, 0,
 		       sizeof(odp_pktio_stats_t));
@@ -841,7 +776,7 @@  static int sock_stats_reset(pktio_entry_t *pktio_entry)
 	}
 
 	return sock_stats_reset_fd(pktio_entry,
-				   pktio_entry->ops_data(socket).sockfd);
+				   pkt_sock->sockfd);
 }
 
 static int sock_init_global(void)
diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c
index 9054a83..2ab6b57 100644
--- a/platform/linux-generic/pktio/socket_mmap.c
+++ b/platform/linux-generic/pktio/socket_mmap.c
@@ -25,6 +25,7 @@ 
 #include <odp_api.h>
 #include <odp_packet_internal.h>
 #include <odp_packet_io_internal.h>
+#include <odp_pktio_ops_socket.h>
 #include <odp_debug_internal.h>
 #include <odp_classification_datamodel.h>
 #include <odp_classification_inlines.h>
@@ -487,7 +488,7 @@  static int mmap_bind_sock(pktio_ops_socket_mmap_data_t *pkt_sock,
 static int sock_mmap_close(pktio_entry_t *entry)
 {
 	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = &entry->ops_data(mmap);
+		*const pkt_sock = _ops_data(entry, socket_mmap);
 	int ret;
 
 	ret = mmap_unmap_sock(pkt_sock);
@@ -517,7 +518,7 @@  static int sock_mmap_open(odp_pktio_t id ODP_UNUSED,
 		return -1;
 
 	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = &pktio_entry->ops_data(mmap);
+		*const pkt_sock = _ops_data(pktio_entry, socket_mmap);
 	int fanout = 1;
 
 	/* Init pktio entry */
@@ -603,7 +604,7 @@  static int sock_mmap_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			  odp_packet_t pkt_table[], int len)
 {
 	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = &pktio_entry->ops_data(mmap);
+		*const pkt_sock = _ops_data(pktio_entry, socket_mmap);
 	int ret;
 
 	odp_ticketlock_lock(&pktio_entry->s.rxl);
@@ -619,7 +620,7 @@  static int sock_mmap_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 {
 	int ret;
 	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = &pktio_entry->ops_data(mmap);
+		*const pkt_sock = _ops_data(pktio_entry, socket_mmap);
 
 	odp_ticketlock_lock(&pktio_entry->s.txl);
 	ret = pkt_mmap_v2_tx(pkt_sock->tx_ring.sock, &pkt_sock->tx_ring,
@@ -631,32 +632,47 @@  static int sock_mmap_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 
 static uint32_t sock_mmap_mtu_get(pktio_entry_t *pktio_entry)
 {
-	return mtu_get_fd(pktio_entry->ops_data(mmap).sockfd,
+	pktio_ops_socket_mmap_data_t
+		*const pkt_sock = _ops_data(pktio_entry, socket_mmap);
+
+	return mtu_get_fd(pkt_sock->sockfd,
 			  pktio_entry->s.name);
 }
 
 static int sock_mmap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 {
-	memcpy(mac_addr, pktio_entry->ops_data(mmap).if_mac, ETH_ALEN);
+	pktio_ops_socket_mmap_data_t
+		*const pkt_sock = _ops_data(pktio_entry, socket_mmap);
+
+	memcpy(mac_addr, pkt_sock->if_mac, ETH_ALEN);
 	return ETH_ALEN;
 }
 
 static int sock_mmap_promisc_mode_set(pktio_entry_t *pktio_entry,
 				      odp_bool_t enable)
 {
-	return promisc_mode_set_fd(pktio_entry->ops_data(mmap).sockfd,
+	pktio_ops_socket_mmap_data_t
+		*const pkt_sock = _ops_data(pktio_entry, socket_mmap);
+
+	return promisc_mode_set_fd(pkt_sock->sockfd,
 				   pktio_entry->s.name, enable);
 }
 
 static int sock_mmap_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	return promisc_mode_get_fd(pktio_entry->ops_data(mmap).sockfd,
+	pktio_ops_socket_mmap_data_t
+		*const pkt_sock = _ops_data(pktio_entry, socket_mmap);
+
+	return promisc_mode_get_fd(pkt_sock->sockfd,
 				   pktio_entry->s.name);
 }
 
 static int sock_mmap_link_status(pktio_entry_t *pktio_entry)
 {
-	return link_status_fd(pktio_entry->ops_data(mmap).sockfd,
+	pktio_ops_socket_mmap_data_t
+		*const pkt_sock = _ops_data(pktio_entry, socket_mmap);
+
+	return link_status_fd(pkt_sock->sockfd,
 			      pktio_entry->s.name);
 }
 
@@ -678,26 +694,30 @@  static int sock_mmap_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
 static int sock_mmap_stats(pktio_entry_t *pktio_entry,
 			   odp_pktio_stats_t *stats)
 {
+	pktio_ops_socket_mmap_data_t
+		*const pkt_sock = _ops_data(pktio_entry, socket_mmap);
+
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(stats, 0, sizeof(*stats));
 		return 0;
 	}
 
 	return sock_stats_fd(pktio_entry,
-			     stats,
-			     pktio_entry->ops_data(mmap).sockfd);
+			     stats, pkt_sock->sockfd);
 }
 
 static int sock_mmap_stats_reset(pktio_entry_t *pktio_entry)
 {
+	pktio_ops_socket_mmap_data_t
+		*const pkt_sock = _ops_data(pktio_entry, socket_mmap);
+
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(&pktio_entry->s.stats, 0,
 		       sizeof(odp_pktio_stats_t));
 		return 0;
 	}
 
-	return sock_stats_reset_fd(pktio_entry,
-				   pktio_entry->ops_data(mmap).sockfd);
+	return sock_stats_reset_fd(pktio_entry, pkt_sock->sockfd);
 }
 
 static int sock_mmap_init_global(void)
diff --git a/platform/linux-generic/pktio/tap.c b/platform/linux-generic/pktio/tap.c
index 090e51b..f0d5831 100644
--- a/platform/linux-generic/pktio/tap.c
+++ b/platform/linux-generic/pktio/tap.c
@@ -43,6 +43,7 @@ 
 #include <odp_packet_internal.h>
 #include <odp_packet_io_internal.h>
 #include <odp_classification_internal.h>
+#include <odp_pktio_ops_tap.h>
 
 #define BUF_SIZE 65536
 
@@ -63,7 +64,7 @@  static int tap_pktio_open(odp_pktio_t id ODP_UNUSED,
 	int fd, skfd, flags;
 	uint32_t mtu;
 	struct ifreq ifr;
-	pktio_ops_tap_data_t *tap = &pktio_entry->ops_data(tap);
+	pktio_ops_tap_data_t *tap = _ops_data(pktio_entry, tap);
 
 	if (strncmp(devname, "tap:", 4) != 0)
 		return -1;
@@ -163,7 +164,7 @@  tap_err:
 static int tap_pktio_close(pktio_entry_t *pktio_entry)
 {
 	int ret = 0;
-	pktio_ops_tap_data_t *tap = &pktio_entry->ops_data(tap);
+	pktio_ops_tap_data_t *tap = _ops_data(pktio_entry, tap);
 
 	if (tap->fd != -1 && close(tap->fd) != 0) {
 		__odp_errno = errno;
@@ -183,6 +184,7 @@  static int tap_pktio_close(pktio_entry_t *pktio_entry)
 static odp_packet_t pack_odp_pkt(pktio_entry_t *pktio_entry, const void *data,
 				 unsigned int len, odp_time_t *ts)
 {
+	pktio_ops_tap_data_t *tap = _ops_data(pktio_entry, tap);
 	odp_packet_t pkt;
 	odp_packet_hdr_t *pkt_hdr;
 	odp_packet_hdr_t parsed_hdr;
@@ -190,13 +192,12 @@  static odp_packet_t pack_odp_pkt(pktio_entry_t *pktio_entry, const void *data,
 
 	if (pktio_cls_enabled(pktio_entry)) {
 		if (cls_classify_packet(pktio_entry, data, len, len,
-					&pktio_entry->ops_data(tap).pool,
-					&parsed_hdr)) {
+					&tap->pool, &parsed_hdr)) {
 			return ODP_PACKET_INVALID;
 		}
 	}
 
-	num = packet_alloc_multi(pktio_entry->ops_data(tap).pool, len, &pkt, 1);
+	num = packet_alloc_multi(tap->pool, len, &pkt, 1);
 
 	if (num != 1)
 		return ODP_PACKET_INVALID;
@@ -227,7 +228,7 @@  static int tap_pktio_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 	ssize_t retval;
 	int i;
 	uint8_t buf[BUF_SIZE];
-	pktio_ops_tap_data_t *tap = &pktio_entry->ops_data(tap);
+	pktio_ops_tap_data_t *tap = _ops_data(pktio_entry, tap);
 	odp_time_t ts_val;
 	odp_time_t *ts = NULL;
 
@@ -267,7 +268,7 @@  static int tap_pktio_send_lockless(pktio_entry_t *pktio_entry,
 	int i, n;
 	uint32_t pkt_len;
 	uint8_t buf[BUF_SIZE];
-	pktio_ops_tap_data_t *tap = &pktio_entry->ops_data(tap);
+	pktio_ops_tap_data_t *tap = _ops_data(pktio_entry, tap);
 
 	for (i = 0; i < len; i++) {
 		pkt_len = odp_packet_len(pkts[i]);
@@ -329,11 +330,11 @@  static int tap_pktio_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 static uint32_t tap_mtu_get(pktio_entry_t *pktio_entry)
 {
 	uint32_t ret;
+	pktio_ops_tap_data_t *tap = _ops_data(pktio_entry, tap);
 
-	ret =  mtu_get_fd(pktio_entry->ops_data(tap).skfd,
-			  pktio_entry->s.name + 4);
+	ret =  mtu_get_fd(tap->skfd, pktio_entry->s.name + 4);
 	if (ret > 0)
-		pktio_entry->ops_data(tap).mtu = ret;
+		tap->mtu = ret;
 
 	return ret;
 }
@@ -341,19 +342,25 @@  static uint32_t tap_mtu_get(pktio_entry_t *pktio_entry)
 static int tap_promisc_mode_set(pktio_entry_t *pktio_entry,
 				odp_bool_t enable)
 {
-	return promisc_mode_set_fd(pktio_entry->ops_data(tap).skfd,
+	pktio_ops_tap_data_t *tap = _ops_data(pktio_entry, tap);
+
+	return promisc_mode_set_fd(tap->skfd,
 				   pktio_entry->s.name + 4, enable);
 }
 
 static int tap_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	return promisc_mode_get_fd(pktio_entry->ops_data(tap).skfd,
+	pktio_ops_tap_data_t *tap = _ops_data(pktio_entry, tap);
+
+	return promisc_mode_get_fd(tap->skfd,
 				   pktio_entry->s.name + 4);
 }
 
 static int tap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 {
-	memcpy(mac_addr, pktio_entry->ops_data(tap).if_mac, ETH_ALEN);
+	pktio_ops_tap_data_t *tap = _ops_data(pktio_entry, tap);
+
+	memcpy(mac_addr, tap->if_mac, ETH_ALEN);
 	return ETH_ALEN;
 }