diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
index ffa5e62..efa418f 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -19,7 +19,6 @@
 #include <odp.h>
 
 #include <odph_linux.h>
-#include <odph_packet.h>
 #include <odph_eth.h>
 #include <odph_ip.h>
 #include <odph_udp.h>
@@ -168,24 +167,24 @@ static int scan_mac(char *in, odph_ethaddr_t *des)
  *
  * @param obuf packet buffer
 */
-static void pack_udp_pkt(odp_buffer_t obuf)
+static void pack_udp_pkt(odp_packet_t pkt)
 {
 	char *buf;
-	int max;
-	odp_packet_t pkt;
+
 	odph_ethhdr_t *eth;
 	odph_ipv4hdr_t *ip;
 	odph_udphdr_t *udp;
 	unsigned short seq;
+	size_t seglen;
+
+	buf = odp_packet_push_tail_and_map(pkt, args->appl.payload +
+					   ODPH_UDPHDR_LEN +
+					   ODPH_IPV4HDR_LEN +
+					   ODPH_ETHHDR_LEN, &seglen);
 
-	buf = odp_buffer_addr(obuf);
 	if (buf == NULL)
 		return;
-	max = odp_buffer_size(obuf);
-	if (max <= 0)
-		return;
 
-	pkt = odp_packet_from_buffer(obuf);
 	/* ether */
 	odp_packet_set_l2_offset(pkt, 0);
 	eth = (odph_ethhdr_t *)buf;
@@ -213,8 +212,7 @@ static void pack_udp_pkt(odp_buffer_t obuf)
 	udp->length = odp_cpu_to_be_16(args->appl.payload + ODPH_UDPHDR_LEN);
 	udp->chksum = 0;
 	udp->chksum = odp_cpu_to_be_16(odph_ipv4_udp_chksum(pkt));
-	odp_packet_set_len(pkt, args->appl.payload + ODPH_UDPHDR_LEN +
-			   ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN);
+
 }
 
 /**
@@ -222,27 +220,27 @@ static void pack_udp_pkt(odp_buffer_t obuf)
  *
  * @param obuf packet buffer
 */
-static void pack_icmp_pkt(odp_buffer_t obuf)
+static void pack_icmp_pkt(odp_packet_t pkt)
 {
 	char *buf;
-	int max;
-	odp_packet_t pkt;
+
 	odph_ethhdr_t *eth;
 	odph_ipv4hdr_t *ip;
 	odph_icmphdr_t *icmp;
 	struct timeval tval;
 	uint8_t *tval_d;
 	unsigned short seq;
+	size_t seglen;
 
-	buf = odp_buffer_addr(obuf);
+	buf = odp_packet_push_tail_and_map(pkt, args->appl.payload +
+					   ODPH_ICMPHDR_LEN +
+					   ODPH_IPV4HDR_LEN +
+					   ODPH_ETHHDR_LEN, &seglen);
 	if (buf == NULL)
 		return;
-	max = odp_buffer_size(obuf);
-	if (max <= 0)
-		return;
 
 	args->appl.payload = 56;
-	pkt = odp_packet_from_buffer(obuf);
+
 	/* ether */
 	odp_packet_set_l2_offset(pkt, 0);
 	eth = (odph_ethhdr_t *)buf;
@@ -277,9 +275,6 @@ static void pack_icmp_pkt(odp_buffer_t obuf)
 	icmp->chksum = 0;
 	icmp->chksum = odp_chksum(icmp, args->appl.payload +
 				  ODPH_ICMPHDR_LEN);
-
-	odp_packet_set_len(pkt, args->appl.payload + ODPH_ICMPHDR_LEN +
-			   ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN);
 }
 
 /**
@@ -295,7 +290,7 @@ static void *gen_send_thread(void *arg)
 	thread_args_t *thr_args;
 	odp_queue_t outq_def;
 
-	odp_buffer_t buf;
+	odp_packet_t buf;
 
 	thr = odp_thread_id();
 	thr_args = arg;
@@ -316,8 +311,8 @@ static void *gen_send_thread(void *arg)
 	printf("  [%02i] created mode: SEND\n", thr);
 	for (;;) {
 		int err;
-		buf = odp_buffer_alloc(thr_args->pool);
-		if (!odp_buffer_is_valid(buf)) {
+		buf = odp_packet_alloc(thr_args->pool);
+		if (!odp_packet_is_valid(buf)) {
 			ODP_ERR("  [%2i] alloc_single failed\n", thr);
 			return NULL;
 		}
@@ -493,13 +488,13 @@ static void *gen_recv_thread(void *arg)
 		pkt = odp_packet_from_buffer(buf);
 		/* Drop packets with errors */
 		if (odp_unlikely(odp_packet_error(pkt))) {
-			odph_packet_free(pkt);
+			odp_packet_free(pkt);
 			continue;
 		}
 
 		print_pkts(thr, &pkt, 1);
 
-		odph_packet_free(pkt);
+		odp_packet_free(pkt);
 	}
 
 	return arg;
@@ -512,11 +507,11 @@ int main(int argc, char *argv[])
 	odph_linux_pthread_t thread_tbl[MAX_WORKERS];
 	odp_buffer_pool_t pool;
 	int num_workers;
-	void *pool_base;
 	int i;
 	int first_core;
 	int core_count;
 	odp_shm_t shm;
+	odp_buffer_pool_param_t params;
 
 	/* Init ODP before calling anything else */
 	if (odp_init_global(NULL, NULL)) {
@@ -579,20 +574,14 @@ int main(int argc, char *argv[])
 	printf("First core:         %i\n\n", first_core);
 
 	/* Create packet pool */
-	shm = odp_shm_reserve("shm_packet_pool",
-			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
-	pool_base = odp_shm_addr(shm);
 
-	if (pool_base == NULL) {
-		ODP_ERR("Error: packet pool mem alloc failed.\n");
-		exit(EXIT_FAILURE);
-	}
+	params.buf_size = SHM_PKT_POOL_BUF_SIZE;
+	params.buf_num  = SHM_PKT_POOL_SIZE/SHM_PKT_POOL_BUF_SIZE;
+	params.buf_type = ODP_BUFFER_TYPE_PACKET;
+	params.buf_opts = ODP_BUFFER_OPTS_UNSEGMENTED;
+
+	pool = odp_buffer_pool_create("packet_pool", &params, NULL);
 
-	pool = odp_buffer_pool_create("packet_pool", pool_base,
-				      SHM_PKT_POOL_SIZE,
-				      SHM_PKT_POOL_BUF_SIZE,
-				      ODP_CACHE_LINE_SIZE,
-				      ODP_BUFFER_TYPE_PACKET);
 	if (pool == ODP_BUFFER_POOL_INVALID) {
 		ODP_ERR("Error: packet pool create failed.\n");
 		exit(EXIT_FAILURE);
diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
index da6c48e..3b39be2 100644
--- a/example/ipsec/odp_ipsec.c
+++ b/example/ipsec/odp_ipsec.c
@@ -18,7 +18,6 @@
 #include <odp.h>
 
 #include <odph_linux.h>
-#include <odph_packet.h>
 #include <odph_eth.h>
 #include <odph_ip.h>
 #include <odph_icmp.h>
@@ -154,8 +153,6 @@ typedef struct {
 #define SHM_CTX_POOL_BUF_COUNT (SHM_PKT_POOL_BUF_COUNT + SHM_OUT_POOL_BUF_COUNT)
 #define SHM_CTX_POOL_SIZE      (SHM_CTX_POOL_BUF_COUNT * SHM_CTX_POOL_BUF_SIZE)
 
-static odp_buffer_pool_t ctx_pool = ODP_BUFFER_POOL_INVALID;
-
 /**
  * Get per packet processing context from packet buffer
  *
@@ -166,33 +163,7 @@ static odp_buffer_pool_t ctx_pool = ODP_BUFFER_POOL_INVALID;
 static
 pkt_ctx_t *get_pkt_ctx_from_pkt(odp_packet_t pkt)
 {
-	return (pkt_ctx_t *)odp_packet_get_ctx(pkt);
-}
-
-/**
- * Allocate per packet processing context and associate it with
- * packet buffer
- *
- * @param pkt  Packet
- *
- * @return pointer to context area
- */
-static
-pkt_ctx_t *alloc_pkt_ctx(odp_packet_t pkt)
-{
-	odp_buffer_t ctx_buf = odp_buffer_alloc(ctx_pool);
-	pkt_ctx_t *ctx;
-
-	/* There should always be enough contexts */
-	if (odp_unlikely(ODP_BUFFER_INVALID == ctx_buf))
-		abort();
-
-	ctx = odp_buffer_addr(ctx_buf);
-	memset(ctx, 0, sizeof(*ctx));
-	ctx->buffer = ctx_buf;
-	odp_packet_set_ctx(pkt, ctx);
-
-	return ctx;
+	return (pkt_ctx_t *)odp_packet_udata_addr(pkt);
 }
 
 /**
@@ -365,8 +336,7 @@ static
 void ipsec_init_pre(void)
 {
 	odp_queue_param_t qparam;
-	void *pool_base;
-	odp_shm_t shm;
+	odp_buffer_pool_param_t params;
 
 	/*
 	 * Create queues
@@ -399,16 +369,12 @@ void ipsec_init_pre(void)
 	}
 
 	/* Create output buffer pool */
-	shm = odp_shm_reserve("shm_out_pool",
-			      SHM_OUT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	params.buf_num  = SHM_OUT_POOL_BUF_COUNT;
+	params.buf_size = SHM_OUT_POOL_BUF_SIZE;
+	params.buf_type = ODP_BUFFER_TYPE_PACKET;
+	params.buf_opts = ODP_BUFFER_OPTS_UNSEGMENTED;
 
-	pool_base = odp_shm_addr(shm);
-
-	out_pool = odp_buffer_pool_create("out_pool", pool_base,
-					  SHM_OUT_POOL_SIZE,
-					  SHM_OUT_POOL_BUF_SIZE,
-					  ODP_CACHE_LINE_SIZE,
-					  ODP_BUFFER_TYPE_PACKET);
+	out_pool = odp_buffer_pool_create("out_pool", &params, NULL);
 
 	if (ODP_BUFFER_POOL_INVALID == out_pool) {
 		ODP_ERR("Error: message pool create failed.\n");
@@ -637,13 +603,15 @@ pkt_disposition_e do_input_verify(odp_packet_t pkt, pkt_ctx_t *ctx ODP_UNUSED)
 static
 pkt_disposition_e do_route_fwd_db(odp_packet_t pkt, pkt_ctx_t *ctx)
 {
-	odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
+	size_t seglen;
+	odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_map(pkt, &seglen);
 	fwd_db_entry_t *entry;
 
 	entry = find_fwd_db_entry(odp_be_to_cpu_32(ip->dst_addr));
 
 	if (entry) {
-		odph_ethhdr_t *eth = (odph_ethhdr_t *)odp_packet_l2(pkt);
+		odph_ethhdr_t *eth =
+			(odph_ethhdr_t *)odp_packet_l2_map(pkt, &seglen);
 
 		memcpy(&eth->dst, entry->dst_mac, ODPH_ETHADDR_LEN);
 		memcpy(&eth->src, entry->src_mac, ODPH_ETHADDR_LEN);
@@ -673,8 +641,9 @@ pkt_disposition_e do_ipsec_in_classify(odp_packet_t pkt,
 				       pkt_ctx_t *ctx,
 				       bool *skip)
 {
+	size_t seglen;
 	uint8_t *buf = odp_packet_addr(pkt);
-	odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
+	odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_map(pkt, &seglen);
 	int hdr_len;
 	odph_ahhdr_t *ah = NULL;
 	odph_esphdr_t *esp = NULL;
@@ -759,6 +728,7 @@ pkt_disposition_e do_ipsec_in_finish(odp_packet_t pkt,
 	odp_crypto_compl_status_t cipher_rc;
 	odp_crypto_compl_status_t auth_rc;
 	odph_ipv4hdr_t *ip;
+	size_t seglen;
 	int hdr_len = ctx->ipsec.hdr_len;
 	int trl_len = 0;
 
@@ -769,7 +739,7 @@ pkt_disposition_e do_ipsec_in_finish(odp_packet_t pkt,
 		return PKT_DROP;
 	if (!is_crypto_compl_status_ok(&auth_rc))
 		return PKT_DROP;
-	ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
+	ip = (odph_ipv4hdr_t *)odp_packet_l3_map(pkt, &seglen);
 
 	/*
 	 * Finish auth
@@ -803,11 +773,11 @@ pkt_disposition_e do_ipsec_in_finish(odp_packet_t pkt,
 	ip->chksum = 0;
 	odph_ipv4_csum_update(pkt);
 
-	/* Correct the packet length and move payload into position */
-	odp_packet_set_len(pkt, odp_packet_get_len(pkt) - (hdr_len + trl_len));
+	/* Move payload into position and correct the packet length */
 	memmove(ipv4_data_p(ip),
 		ipv4_data_p(ip) + hdr_len,
 		odp_be_to_cpu_16(ip->tot_len));
+	odp_packet_pull_tail(pkt, hdr_len + trl_len);
 
 	/* Fall through to next state */
 	return PKT_CONTINUE;
@@ -833,8 +803,9 @@ pkt_disposition_e do_ipsec_out_classify(odp_packet_t pkt,
 					pkt_ctx_t *ctx,
 					bool *skip)
 {
+	size_t seglen;
 	uint8_t *buf = odp_packet_addr(pkt);
-	odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
+	odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_map(pkt, &seglen);
 	uint16_t ip_data_len = ipv4_data_len(ip);
 	uint8_t *ip_data = ipv4_data_p(ip);
 	ipsec_cache_entry_t *entry;
@@ -921,7 +892,7 @@ pkt_disposition_e do_ipsec_out_classify(odp_packet_t pkt,
 
 	/* Set IPv4 length before authentication */
 	ipv4_adjust_len(ip, hdr_len + trl_len);
-	odp_packet_set_len(pkt, odp_packet_get_len(pkt) + (hdr_len + trl_len));
+	odp_packet_push_tail(pkt, hdr_len + trl_len);
 
 	/* Save remaining context */
 	ctx->ipsec.hdr_len = hdr_len;
@@ -995,6 +966,7 @@ pkt_disposition_e do_ipsec_out_finish(odp_packet_t pkt,
 	odp_crypto_compl_status_t cipher_rc;
 	odp_crypto_compl_status_t auth_rc;
 	odph_ipv4hdr_t *ip;
+	size_t seglen;
 
 	/* Check crypto result */
 	event = odp_packet_to_buffer(pkt);
@@ -1003,7 +975,7 @@ pkt_disposition_e do_ipsec_out_finish(odp_packet_t pkt,
 		return PKT_DROP;
 	if (!is_crypto_compl_status_ok(&auth_rc))
 		return PKT_DROP;
-	ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
+	ip = (odph_ipv4hdr_t *)odp_packet_l3_map(pkt, &seglen);
 
 	/* Finalize the IPv4 header */
 	ip->ttl = ctx->ipsec.ip_ttl;
@@ -1057,7 +1029,7 @@ void *pktio_thread(void *arg ODP_UNUSED)
 
 		/* Determine new work versus completion or sequence number */
 		if ((completionq != dispatchq) && (seqnumq != dispatchq)) {
-			ctx = alloc_pkt_ctx(pkt);
+			ctx = get_pkt_ctx_from_pkt(pkt);
 			ctx->state = PKT_STATE_INPUT_VERIFY;
 		} else {
 			ctx = get_pkt_ctx_from_pkt(pkt);
@@ -1144,7 +1116,7 @@ void *pktio_thread(void *arg ODP_UNUSED)
 
 		/* Check for drop */
 		if (PKT_DROP == rc)
-			odph_packet_free(pkt);
+			odp_packet_free(pkt);
 
 		/* Print packet counts every once in a while */
 		if (PKT_DONE == rc) {
@@ -1167,12 +1139,13 @@ main(int argc, char *argv[])
 {
 	odph_linux_pthread_t thread_tbl[MAX_WORKERS];
 	int num_workers;
-	void *pool_base;
 	int i;
 	int first_core;
 	int core_count;
 	int stream_count;
 	odp_shm_t shm;
+	odp_buffer_pool_param_t params;
+	odp_buffer_pool_init_t  init_params;
 
 	/* Init ODP before calling anything else */
 	if (odp_init_global(NULL, NULL)) {
@@ -1232,47 +1205,22 @@ main(int argc, char *argv[])
 	printf("First core:         %i\n\n", first_core);
 
 	/* Create packet buffer pool */
-	shm = odp_shm_reserve("shm_packet_pool",
-			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	params.buf_num  = SHM_PKT_POOL_BUF_COUNT;
+	params.buf_size = SHM_PKT_POOL_BUF_SIZE;
+	params.buf_type = ODP_BUFFER_TYPE_PACKET;
+	params.buf_opts = ODP_BUFFER_OPTS_UNSEGMENTED;
 
-	pool_base = odp_shm_addr(shm);
+	init_params.udata_size = sizeof(pkt_ctx_t);
+	init_params.buf_init   = NULL;
+	init_params.buf_init_arg = NULL;
 
-	if (NULL == pool_base) {
-		ODP_ERR("Error: packet pool mem alloc failed.\n");
-		exit(EXIT_FAILURE);
-	}
+	pkt_pool = odp_buffer_pool_create("packet_pool", &params, &init_params);
 
-	pkt_pool = odp_buffer_pool_create("packet_pool", pool_base,
-					  SHM_PKT_POOL_SIZE,
-					  SHM_PKT_POOL_BUF_SIZE,
-					  ODP_CACHE_LINE_SIZE,
-					  ODP_BUFFER_TYPE_PACKET);
 	if (ODP_BUFFER_POOL_INVALID == pkt_pool) {
 		ODP_ERR("Error: packet pool create failed.\n");
 		exit(EXIT_FAILURE);
 	}
 
-	/* Create context buffer pool */
-	shm = odp_shm_reserve("shm_ctx_pool",
-			      SHM_CTX_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
-
-	pool_base = odp_shm_addr(shm);
-
-	if (NULL == pool_base) {
-		ODP_ERR("Error: context pool mem alloc failed.\n");
-		exit(EXIT_FAILURE);
-	}
-
-	ctx_pool = odp_buffer_pool_create("ctx_pool", pool_base,
-					  SHM_CTX_POOL_SIZE,
-					  SHM_CTX_POOL_BUF_SIZE,
-					  ODP_CACHE_LINE_SIZE,
-					  ODP_BUFFER_TYPE_RAW);
-	if (ODP_BUFFER_POOL_INVALID == ctx_pool) {
-		ODP_ERR("Error: context pool create failed.\n");
-		exit(EXIT_FAILURE);
-	}
-
 	/* Populate our IPsec cache */
 	printf("Using %s mode for crypto API\n\n",
 	       (CRYPTO_API_SYNC == args->appl.mode) ? "SYNC" :
diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c
index fa9aba8..309cf70 100644
--- a/example/ipsec/odp_ipsec_stream.c
+++ b/example/ipsec/odp_ipsec_stream.c
@@ -14,7 +14,6 @@
 
 #include <odp.h>
 
-#include <odph_packet.h>
 #include <odph_eth.h>
 #include <odph_ip.h>
 #include <odph_icmp.h>
@@ -173,7 +172,6 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
 				odp_buffer_pool_t pkt_pool)
 {
 	ipsec_cache_entry_t *entry = stream->input.entry;
-	odp_buffer_t bfr;
 	odp_packet_t pkt;
 	uint8_t *base;
 	uint8_t *data;
@@ -184,18 +182,19 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
 	odph_icmphdr_t *icmp;
 	stream_pkt_hdr_t *test;
 	uint i;
+	size_t seglen;
 
-	/* Get buffer */
-	bfr = odp_buffer_alloc(pkt_pool);
-	if (ODP_BUFFER_INVALID == bfr)
+	/* Get packet */
+	pkt = odp_packet_alloc(pkt_pool);
+	if (ODP_PACKET_INVALID == pkt)
 		return ODP_PACKET_INVALID;
-	pkt = odp_packet_from_buffer(bfr);
-	odp_packet_init(pkt);
-	base = odp_packet_data(pkt);
-	data = odp_packet_data(pkt);
+
+	base = odp_packet_map(pkt, &seglen);
+	data = base;
 
 	/* Ethernet */
 	odp_packet_set_inflag_eth(pkt, 1);
+	odp_packet_set_inflag_l2(pkt, 1);
 	odp_packet_set_l2_offset(pkt, data - base);
 	eth = (odph_ethhdr_t *)data;
 	data += sizeof(*eth);
@@ -251,6 +250,7 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
 	/* ICMP header so we can see it on wireshark */
 	icmp = (odph_icmphdr_t *)data;
 	data += sizeof(*icmp);
+
 	icmp->type = ICMP_ECHO;
 	icmp->code = 0;
 	icmp->un.echo.id = odp_cpu_to_be_16(0x1234);
@@ -303,7 +303,7 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
 
 	/* Since ESP can pad we can now fix IP length */
 	ip->tot_len = odp_cpu_to_be_16(data - (uint8_t *)ip);
-	odp_packet_set_len(pkt, data - base);
+	odp_packet_push_tail(pkt, data - base);
 
 	/* Close AH if specified */
 	if (ah) {
@@ -344,9 +344,10 @@ bool verify_ipv4_packet(stream_db_entry_t *stream,
 	int hdr_len;
 	odph_icmphdr_t *icmp;
 	stream_pkt_hdr_t *test;
+	size_t seglen;
 
 	/* Basic IPv4 verify (add checksum verification) */
-	data = odp_packet_l3(pkt);
+	data = odp_packet_l3_map(pkt, &seglen);
 	ip = (odph_ipv4hdr_t *)data;
 	data += sizeof(*ip);
 	if (0x45 != ip->ver_ihl)
@@ -546,7 +547,7 @@ bool verify_stream_db_outputs(void)
 				good = verify_ipv4_packet(stream, pkt);
 				if (good)
 					stream->verified++;
-				odph_packet_free(pkt);
+				odp_packet_free(pkt);
 			}
 		}
 
diff --git a/example/l2fwd/odp_l2fwd.c b/example/l2fwd/odp_l2fwd.c
index 57037cd..c43ef86 100644
--- a/example/l2fwd/odp_l2fwd.c
+++ b/example/l2fwd/odp_l2fwd.c
@@ -17,7 +17,6 @@
 
 #include <odp.h>
 #include <odph_linux.h>
-#include <odph_packet.h>
 #include <odph_eth.h>
 #include <odph_ip.h>
 
@@ -311,12 +310,12 @@ int main(int argc, char *argv[])
 {
 	odph_linux_pthread_t thread_tbl[MAX_WORKERS];
 	odp_buffer_pool_t pool;
-	void *pool_base;
 	int i;
 	int first_core;
 	int core_count;
 	odp_pktio_t pktio;
 	odp_shm_t shm;
+	odp_buffer_pool_param_t params;
 
 	/* Init ODP before calling anything else */
 	if (odp_init_global(NULL, NULL)) {
@@ -380,20 +379,13 @@ int main(int argc, char *argv[])
 	printf("First core:         %i\n\n", first_core);
 
 	/* Create packet pool */
-	shm = odp_shm_reserve("shm_packet_pool",
-			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
-	pool_base = odp_shm_addr(shm);
+	params.buf_num  = SHM_PKT_POOL_SIZE/SHM_PKT_POOL_BUF_SIZE;
+	params.buf_size = SHM_PKT_POOL_BUF_SIZE;
+	params.buf_type = ODP_BUFFER_TYPE_PACKET;
+	params.buf_opts = ODP_BUFFER_OPTS_UNSEGMENTED;
 
-	if (pool_base == NULL) {
-		ODP_ERR("Error: packet pool mem alloc failed.\n");
-		exit(EXIT_FAILURE);
-	}
+	pool = odp_buffer_pool_create("packet_pool", &params, NULL);
 
-	pool = odp_buffer_pool_create("packet_pool", pool_base,
-				      SHM_PKT_POOL_SIZE,
-				      SHM_PKT_POOL_BUF_SIZE,
-				      ODP_CACHE_LINE_SIZE,
-				      ODP_BUFFER_TYPE_PACKET);
 	if (pool == ODP_BUFFER_POOL_INVALID) {
 		ODP_ERR("Error: packet pool create failed.\n");
 		exit(EXIT_FAILURE);
@@ -480,7 +472,7 @@ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len)
 		pkt = pkt_tbl[i];
 
 		if (odp_unlikely(odp_packet_error(pkt))) {
-			odph_packet_free(pkt); /* Drop */
+			odp_packet_free(pkt); /* Drop */
 			pkt_cnt--;
 		} else if (odp_unlikely(i != j++)) {
 			pkt_tbl[j-1] = pkt;
diff --git a/example/odp_example/odp_example.c b/example/odp_example/odp_example.c
index d0ec977..cdb78b6 100644
--- a/example/odp_example/odp_example.c
+++ b/example/odp_example/odp_example.c
@@ -317,7 +317,6 @@ static int test_poll_queue(int thr, odp_buffer_pool_t msg_pool)
  * @param thr      Thread
  * @param msg_pool Buffer pool
  * @param prio     Priority
- * @param barrier  Barrier
  *
  * @return 0 if successful
  */
@@ -375,7 +374,6 @@ static int test_schedule_one_single(const char *str, int thr,
  * @param thr      Thread
  * @param msg_pool Buffer pool
  * @param prio     Priority
- * @param barrier  Barrier
  *
  * @return 0 if successful
  */
@@ -436,7 +434,6 @@ static int test_schedule_one_many(const char *str, int thr,
  * @param thr      Thread
  * @param msg_pool Buffer pool
  * @param prio     Priority
- * @param barrier  Barrier
  *
  * @return 0 if successful
  */
@@ -512,7 +509,6 @@ static int test_schedule_single(const char *str, int thr,
  * @param thr      Thread
  * @param msg_pool Buffer pool
  * @param prio     Priority
- * @param barrier  Barrier
  *
  * @return 0 if successful
  */
@@ -587,7 +583,6 @@ static int test_schedule_many(const char *str, int thr,
  * @param thr      Thread
  * @param msg_pool Buffer pool
  * @param prio     Priority
- * @param barrier  Barrier
  *
  * @return 0 if successful
  */
@@ -949,13 +944,13 @@ int main(int argc, char *argv[])
 	test_args_t args;
 	int num_workers;
 	odp_buffer_pool_t pool;
-	void *pool_base;
 	odp_queue_t queue;
 	int i, j;
 	int prios;
 	int first_core;
 	odp_shm_t shm;
 	test_globals_t *globals;
+	odp_buffer_pool_param_t params;
 
 	printf("\nODP example starts\n\n");
 
@@ -1037,19 +1032,13 @@ int main(int argc, char *argv[])
 	/*
 	 * Create message pool
 	 */
-	shm = odp_shm_reserve("msg_pool",
-			      MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
 
-	pool_base = odp_shm_addr(shm);
+	params.buf_num  = MSG_POOL_SIZE/sizeof(test_message_t);
+	params.buf_size = sizeof(test_message_t);
+	params.buf_type = ODP_BUFFER_TYPE_RAW;
+	params.buf_opts = ODP_BUFFER_OPTS_NONE;
 
-	if (pool_base == NULL) {
-		ODP_ERR("Shared memory reserve failed.\n");
-		return -1;
-	}
-
-	pool = odp_buffer_pool_create("msg_pool", pool_base, MSG_POOL_SIZE,
-				      sizeof(test_message_t),
-				      ODP_CACHE_LINE_SIZE, ODP_BUFFER_TYPE_RAW);
+	pool = odp_buffer_pool_create("msg_pool", &params, NULL);
 
 	if (pool == ODP_BUFFER_POOL_INVALID) {
 		ODP_ERR("Pool create failed.\n");
diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c
index 2cf3f0d..64161f2 100644
--- a/example/packet/odp_pktio.c
+++ b/example/packet/odp_pktio.c
@@ -17,7 +17,6 @@
 
 #include <odp.h>
 #include <odph_linux.h>
-#include <odph_packet.h>
 #include <odph_eth.h>
 #include <odph_ip.h>
 
@@ -292,11 +291,11 @@ int main(int argc, char *argv[])
 	odph_linux_pthread_t thread_tbl[MAX_WORKERS];
 	odp_buffer_pool_t pool;
 	int num_workers;
-	void *pool_base;
 	int i;
 	int first_core;
 	int core_count;
 	odp_shm_t shm;
+	odp_buffer_pool_param_t params;
 
 	/* Init ODP before calling anything else */
 	if (odp_init_global(NULL, NULL)) {
@@ -350,20 +349,13 @@ int main(int argc, char *argv[])
 	printf("First core:         %i\n\n", first_core);
 
 	/* Create packet pool */
-	shm = odp_shm_reserve("shm_packet_pool",
-			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
-	pool_base = odp_shm_addr(shm);
+	params.buf_num  = SHM_PKT_POOL_SIZE/SHM_PKT_POOL_BUF_SIZE;
+	params.buf_size = SHM_PKT_POOL_BUF_SIZE;
+	params.buf_type = ODP_BUFFER_TYPE_PACKET;
+	params.buf_opts = ODP_BUFFER_OPTS_UNSEGMENTED;
 
-	if (pool_base == NULL) {
-		ODP_ERR("Error: packet pool mem alloc failed.\n");
-		exit(EXIT_FAILURE);
-	}
+	pool = odp_buffer_pool_create("packet_pool", &params, NULL);
 
-	pool = odp_buffer_pool_create("packet_pool", pool_base,
-				      SHM_PKT_POOL_SIZE,
-				      SHM_PKT_POOL_BUF_SIZE,
-				      ODP_CACHE_LINE_SIZE,
-				      ODP_BUFFER_TYPE_PACKET);
 	if (pool == ODP_BUFFER_POOL_INVALID) {
 		ODP_ERR("Error: packet pool create failed.\n");
 		exit(EXIT_FAILURE);
@@ -427,7 +419,7 @@ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len)
 		pkt = pkt_tbl[i];
 
 		if (odp_unlikely(odp_packet_error(pkt))) {
-			odph_packet_free(pkt); /* Drop */
+			odp_packet_free(pkt); /* Drop */
 			pkt_cnt--;
 		} else if (odp_unlikely(i != j++)) {
 			pkt_tbl[j-1] = pkt;
@@ -452,11 +444,12 @@ static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len)
 	odph_ipv4hdr_t *ip;
 	uint32be_t ip_tmp_addr; /* tmp ip addr */
 	unsigned i;
+	size_t seglen;
 
 	for (i = 0; i < len; ++i) {
 		pkt = pkt_tbl[i];
 		if (odp_packet_inflag_eth(pkt)) {
-			eth = (odph_ethhdr_t *)odp_packet_l2(pkt);
+			eth = (odph_ethhdr_t *)odp_packet_l2_map(pkt, &seglen);
 
 			tmp_addr = eth->dst;
 			eth->dst = eth->src;
@@ -464,7 +457,8 @@ static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len)
 
 			if (odp_packet_inflag_ipv4(pkt)) {
 				/* IPv4 */
-				ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
+				ip = (odph_ipv4hdr_t *)
+					odp_packet_l3_map(pkt, &seglen);
 
 				ip_tmp_addr  = ip->src_addr;
 				ip->src_addr = ip->dst_addr;
diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c
index 78b2ae2..c0fcf49 100644
--- a/example/timer/odp_timer_test.c
+++ b/example/timer/odp_timer_test.c
@@ -242,12 +242,11 @@ int main(int argc, char *argv[])
 	test_args_t args;
 	int num_workers;
 	odp_buffer_pool_t pool;
-	void *pool_base;
 	odp_queue_t queue;
 	int first_core;
 	uint64_t cycles, ns;
 	odp_queue_param_t param;
-	odp_shm_t shm;
+	odp_buffer_pool_param_t params;
 
 	printf("\nODP timer example starts\n");
 
@@ -306,17 +305,12 @@ int main(int argc, char *argv[])
 	printf("period:             %i usec\n", args.period_us);
 	printf("timeouts:           %i\n", args.tmo_count);
 
-	/*
-	 * Create message pool
-	 */
-	shm = odp_shm_reserve("msg_pool",
-			      MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
-	pool_base = odp_shm_addr(shm);
-
-	pool = odp_buffer_pool_create("msg_pool", pool_base, MSG_POOL_SIZE,
-				      0,
-				      ODP_CACHE_LINE_SIZE,
-				      ODP_BUFFER_TYPE_TIMEOUT);
+	params.buf_num  = 1024;
+	params.buf_size = 0;
+	params.buf_type = ODP_BUFFER_TYPE_TIMEOUT;
+	params.buf_opts = ODP_BUFFER_OPTS_NONE;
+
+	pool = odp_buffer_pool_create("msg_pool", &params, NULL);
 
 	if (pool == ODP_BUFFER_POOL_INVALID) {
 		ODP_ERR("Pool create failed.\n");
diff --git a/helper/include/odph_ip.h b/helper/include/odph_ip.h
index 2c83c0f..2dab164 100644
--- a/helper/include/odph_ip.h
+++ b/helper/include/odph_ip.h
@@ -79,10 +79,12 @@ static inline int odph_ipv4_csum_valid(odp_packet_t pkt)
 	odph_ipv4hdr_t ip;
 	uint16be_t chksum;
 
-	if (!odp_packet_l3_offset(pkt))
+	if (!odp_packet_inflag_ipv4(pkt))
 		return 0;
 
-	memcpy(&ip, odp_packet_l3(pkt), sizeof(odph_ipv4hdr_t));
+	odp_packet_copy_to_memory(&ip, pkt, odp_packet_l3_offset(pkt),
+				  sizeof(odph_ipv4hdr_t));
+
 	w = (uint16_t *)(void *)&ip;
 	chksum = ip.chksum;
 	ip.chksum = 0x0;
@@ -105,12 +107,13 @@ static inline uint16sum_t odph_ipv4_csum_update(odp_packet_t pkt)
 {
 	uint16_t *w;
 	odph_ipv4hdr_t *ip;
+	size_t seglen;
 	int nleft = sizeof(odph_ipv4hdr_t);
 
-	if (!odp_packet_l3_offset(pkt))
+	if (!odp_packet_inflag_ipv4(pkt))
 		return 0;
 
-	ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
+	ip = (odph_ipv4hdr_t *)odp_packet_l3_map(pkt, &seglen);
 	w = (uint16_t *)(void *)ip;
 	ip->chksum = odp_chksum(w, nleft);
 	return ip->chksum;
@@ -126,7 +129,14 @@ static inline uint16sum_t odph_ipv4_csum_update(odp_packet_t pkt)
  * IPv6 header
  */
 typedef struct ODP_PACKED {
-	uint32be_t ver_tc_flow;  /**< Version / Traffic class / Flow label */
+	union {
+		uint32be_t ver_tc_flow;  /**< Version / TC / Flow label */
+		struct {
+			uint32be_t ver:4;    /**< Version (must be 6) */
+			uint32be_t tc:8;     /**< Traffic class */
+			uint32be_t flow:20;  /**< Flow label */
+		};
+	};
 	uint16be_t payload_len;  /**< Payload length */
 	uint8_t    next_hdr;     /**< Next header */
 	uint8_t    hop_limit;    /**< Hop limit */
@@ -137,16 +147,29 @@ typedef struct ODP_PACKED {
 /** @internal Compile time assert */
 ODP_STATIC_ASSERT(sizeof(odph_ipv6hdr_t) == ODPH_IPV6HDR_LEN, "ODPH_IPV6HDR_T__SIZE_ERROR");
 
+/**
+ * IPv6 Header extensions
+ */
+typedef struct ODP_PACKED {
+	uint8_t    next_hdr;     /**< Protocol of next header */
+	uint8_t    ext_len;      /**< Length of this extention in 8 byte units,
+				    not counting first 8 bytes, so 0 = 8 bytes
+				    1 = 16 bytes, etc. */
+	uint8_t    filler[6];    /**< Fill out first 8 byte segment */
+} odph_ipv6hdr_ext_t;
+
 /** @name
  * IP protocol values (IPv4:'proto' or IPv6:'next_hdr')
  * @{*/
-#define ODPH_IPPROTO_ICMP 0x01 /**< Internet Control Message Protocol (1) */
-#define ODPH_IPPROTO_TCP  0x06 /**< Transmission Control Protocol (6) */
-#define ODPH_IPPROTO_UDP  0x11 /**< User Datagram Protocol (17) */
-#define ODPH_IPPROTO_SCTP 0x84 /**< Stream Control Transmission Protocol (132) */
-#define ODPH_IPPROTO_FRAG 0x2C /**< Fragment (44) */
-#define ODPH_IPPROTO_AH   0x33 /**< Authentication Header (51) */
-#define ODPH_IPPROTO_ESP  0x32 /**< Encapsulating Security Payload (50) */
+#define ODPH_IPPROTO_HOPOPTS 0x00 /**< IPv6 hop-by-hop options */
+#define ODPH_IPPROTO_ICMP    0x01 /**< Internet Control Message Protocol (1) */
+#define ODPH_IPPROTO_TCP     0x06 /**< Transmission Control Protocol (6) */
+#define ODPH_IPPROTO_UDP     0x11 /**< User Datagram Protocol (17) */
+#define ODPH_IPPROTO_ROUTE   0x2B /**< IPv6 Routing header (43) */
+#define ODPH_IPPROTO_FRAG    0x2C /**< IPv6 Fragment (44) */
+#define ODPH_IPPROTO_AH      0x33 /**< Authentication Header (51) */
+#define ODPH_IPPROTO_ESP     0x32 /**< Encapsulating Security Payload (50) */
+#define ODPH_IPPROTO_INVALID 0xFF /**< Reserved invalid by IANA */
 /**@}*/
 
 #ifdef __cplusplus
diff --git a/helper/include/odph_packet.h b/helper/include/odph_packet.h
deleted file mode 100644
index 3d53593..0000000
--- a/helper/include/odph_packet.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright (c) 2014, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier:     BSD-3-Clause
- */
-
-
-/**
- * @file
- *
- * Optional ODP packet helper functions
- */
-
-#ifndef ODPH_PACKET_HELPER_H_
-#define ODPH_PACKET_HELPER_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <odp.h>
-
-/**
- * Helper: Tests if packet is valid
- *
- * Allows for more thorough checking than "if (pkt == ODP_PACKET_INVALID)"
- *
- * @param pkt  Packet handle
- *
- * @return 1 if valid, otherwise 0
- */
-static inline int odph_packet_is_valid(odp_packet_t pkt)
-{
-	odp_buffer_t buf = odp_packet_to_buffer(pkt);
-
-	return odp_buffer_is_valid(buf);
-}
-
-/**
- * Helper: Allocate and initialize a packet buffer from a packet pool
- *
- * @param pool_id  Pool handle
- *
- * @note  The pool must have been created with 'buf_type=ODP_BUFFER_TYPE_PACKET'
- *
- * @return Packet handle or ODP_PACKET_INVALID
- */
-static inline odp_packet_t odph_packet_alloc(odp_buffer_pool_t pool_id)
-{
-	odp_packet_t pkt;
-	odp_buffer_t buf;
-
-	buf = odp_buffer_alloc(pool_id);
-	if (odp_unlikely(!odp_buffer_is_valid(buf)))
-		return ODP_PACKET_INVALID;
-
-	pkt = odp_packet_from_buffer(buf);
-	odp_packet_init(pkt);
-
-	return pkt;
-}
-
-/**
- * Helper: Free a packet buffer back into the packet pool
- *
- * @param pkt  Packet handle
- */
-static inline void odph_packet_free(odp_packet_t pkt)
-{
-	odp_buffer_t buf = odp_packet_to_buffer(pkt);
-
-	odp_buffer_free(buf);
-}
-
-/**
- * Helper: Packet buffer maximum data size
- *
- * @note odp_packet_buf_size(pkt) != odp_packet_get_len(pkt), the former returns
- *       the max length of the buffer, the latter the size of a received packet.
- *
- * @param pkt  Packet handle
- *
- * @return Packet buffer maximum data size
- */
-static inline size_t odph_packet_buf_size(odp_packet_t pkt)
-{
-	odp_buffer_t buf = odp_packet_to_buffer(pkt);
-
-	return odp_buffer_size(buf);
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/helper/include/odph_tcp.h b/helper/include/odph_tcp.h
new file mode 100644
index 0000000..4c5912b
--- /dev/null
+++ b/helper/include/odph_tcp.h
@@ -0,0 +1,61 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+
+/**
+ * @file
+ *
+ * ODP TCP header
+ */
+
+#ifndef ODPH_TCP_H_
+#define ODPH_TCP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp_align.h>
+#include <odp_debug.h>
+#include <odp_byteorder.h>
+
+/** UDP header length */
+#define ODPH_TCPHDR_LEN 8
+
+/** TCP header */
+typedef struct ODP_PACKED {
+	uint16be_t src_port; /**< Source port */
+	uint16be_t dst_port; /**< Destinatino port */
+	uint32be_t seq_no;   /**< Sequence number */
+	uint32be_t ack_no;   /**< Acknowledgment number */
+	union {
+		uint32be_t flags_and_window;
+		struct {
+			uint32be_t rsvd1:8;
+			uint32be_t flags:8; /**< TCP flags as a byte */
+			uint32be_t rsvd2:16;
+		};
+		struct {
+			uint32be_t hl:4;    /**< Hdr len, in words */
+			uint32be_t rsvd3:6; /**< Reserved */
+			uint32be_t urg:1;   /**< ACK */
+			uint32be_t ack:1;
+			uint32be_t psh:1;
+			uint32be_t rst:1;
+			uint32be_t syn:1;
+			uint32be_t fin:1;
+			uint32be_t window:16; /**< Window size */
+		};
+	};
+	uint16be_t cksm;   /**< Checksum */
+	uint16be_t urgptr; /**< Urgent pointer */
+} odph_tcphdr_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/helper/include/odph_udp.h b/helper/include/odph_udp.h
index b2eaf03..bd0fb68 100644
--- a/helper/include/odph_udp.h
+++ b/helper/include/odph_udp.h
@@ -57,15 +57,14 @@ static inline uint16_t odph_ipv4_udp_chksum(odp_packet_t pkt)
 	odph_udphdr_t *udph;
 	odph_ipv4hdr_t *iph;
 	uint16_t udplen;
+	size_t l3_seglen, l4_seglen;
 
-	if (!odp_packet_l3_offset(pkt))
+	if (odp_packet_l3_protocol(pkt) != 0x800 ||
+	    odp_packet_l4_protocol(pkt) != ODPH_IPPROTO_UDP)
 		return 0;
 
-	if (!odp_packet_l4_offset(pkt))
-		return 0;
-
-	iph = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
-	udph = (odph_udphdr_t *)odp_packet_l4(pkt);
+	iph = (odph_ipv4hdr_t *)odp_packet_l3_map(pkt, &l3_seglen);
+	udph = (odph_udphdr_t *)odp_packet_l4_map(pkt, &l4_seglen);
 	udplen = odp_be_to_cpu_16(udph->length);
 
 	/* the source ip */
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 0153a22..08c147c 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -21,7 +21,6 @@ include_HEADERS = \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_debug.h \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_hints.h \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_init.h \
-		  $(top_srcdir)/platform/linux-generic/include/api/odp_packet_flags.h \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_packet.h \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_packet_io.h \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_queue.h \
@@ -46,8 +45,8 @@ subdirheaders_HEADERS = \
 			$(top_srcdir)/helper/include/odph_ip.h \
 			$(top_srcdir)/helper/include/odph_ipsec.h \
 			$(top_srcdir)/helper/include/odph_linux.h \
-			$(top_srcdir)/helper/include/odph_packet.h \
 			$(top_srcdir)/helper/include/odph_ring.h \
+			$(top_srcdir)/helper/include/odph_tcp.h \
 			$(top_srcdir)/helper/include/odph_udp.h
 
 __LIB__libodp_la_SOURCES = \
@@ -60,7 +59,6 @@ __LIB__libodp_la_SOURCES = \
 			   odp_init.c \
 			   odp_linux.c \
 			   odp_packet.c \
-			   odp_packet_flags.c \
 			   odp_packet_io.c \
 			   odp_packet_socket.c \
 			   odp_queue.c \
diff --git a/platform/linux-generic/include/api/odp.h b/platform/linux-generic/include/api/odp.h
index 6e4f69e..ffdf1f3 100644
--- a/platform/linux-generic/include/api/odp.h
+++ b/platform/linux-generic/include/api/odp.h
@@ -44,7 +44,6 @@ extern "C" {
 #include <odp_schedule.h>
 #include <odp_sync.h>
 #include <odp_packet.h>
-#include <odp_packet_flags.h>
 #include <odp_packet_io.h>
 #include <odp_crypto.h>
 #include <odp_rwlock.h>
diff --git a/platform/linux-generic/include/api/odp_packet_flags.h b/platform/linux-generic/include/api/odp_packet_flags.h
deleted file mode 100644
index ccaa04f..0000000
--- a/platform/linux-generic/include/api/odp_packet_flags.h
+++ /dev/null
@@ -1,334 +0,0 @@
-/* Copyright (c) 2014, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier:     BSD-3-Clause
- */
-
-
-/**
- * @file
- *
- * ODP packet flags
- */
-
-#ifndef ODP_PACKET_FLAGS_H_
-#define ODP_PACKET_FLAGS_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <odp_std_types.h>
-#include <odp_packet.h>
-
-/** @addtogroup odp_packet
- *  Boolean operations on a packet.
- *  @{
- */
-
-/**
- * Check for packet errors
- *
- * Checks all error flags at once.
- *
- * @param pkt Packet handle
- * @return 1 if packet has errors, 0 otherwise
- */
-int odp_packet_error(odp_packet_t pkt);
-
-/**
- * Check if error was 'frame length' error
- *
- * @param pkt Packet handle
- * @return 1 if frame length error detected, 0 otherwise
- */
-int odp_packet_errflag_frame_len(odp_packet_t pkt);
-
-/**
- * Check for L2 header, e.g. ethernet
- *
- * @param pkt Packet handle
- * @return 1 if packet contains a valid & known L2 header, 0 otherwise
- */
-int odp_packet_inflag_l2(odp_packet_t pkt);
-
-/**
- * Check for L3 header, e.g. IPv4, IPv6
- *
- * @param pkt Packet handle
- * @return 1 if packet contains a valid & known L3 header, 0 otherwise
- */
-int odp_packet_inflag_l3(odp_packet_t pkt);
-
-/**
- * Check for L4 header, e.g. UDP, TCP, SCTP (also ICMP)
- *
- * @param pkt Packet handle
- * @return 1 if packet contains a valid & known L4 header, 0 otherwise
- */
-int odp_packet_inflag_l4(odp_packet_t pkt);
-
-/**
- * Check for Ethernet header
- *
- * @param pkt Packet handle
- * @return 1 if packet contains a valid eth header, 0 otherwise
- */
-int odp_packet_inflag_eth(odp_packet_t pkt);
-
-/**
- * Check for jumbo frame
- *
- * @param pkt Packet handle
- * @return 1 if packet contains jumbo frame, 0 otherwise
- */
-int odp_packet_inflag_jumbo(odp_packet_t pkt);
-
-/**
- * Check for VLAN
- *
- * @param pkt Packet handle
- * @return 1 if packet contains a VLAN header, 0 otherwise
- */
-int odp_packet_inflag_vlan(odp_packet_t pkt);
-
-/**
- * Check for VLAN QinQ (stacked VLAN)
- *
- * @param pkt Packet handle
- * @return 1 if packet contains a VLAN QinQ header, 0 otherwise
- */
-int odp_packet_inflag_vlan_qinq(odp_packet_t pkt);
-
-/**
- * Check for ARP
- *
- * @param pkt Packet handle
- * @return 1 if packet contains an ARP header, 0 otherwise
- */
-int odp_packet_inflag_arp(odp_packet_t pkt);
-
-/**
- * Check for IPv4
- *
- * @param pkt Packet handle
- * @return 1 if packet contains an IPv4 header, 0 otherwise
- */
-int odp_packet_inflag_ipv4(odp_packet_t pkt);
-
-/**
- * Check for IPv6
- *
- * @param pkt Packet handle
- * @return 1 if packet contains an IPv6 header, 0 otherwise
- */
-int odp_packet_inflag_ipv6(odp_packet_t pkt);
-
-/**
- * Check for IP fragment
- *
- * @param pkt Packet handle
- * @return 1 if packet is an IP fragment, 0 otherwise
- */
-int odp_packet_inflag_ipfrag(odp_packet_t pkt);
-
-/**
- * Check for IP options
- *
- * @param pkt Packet handle
- * @return 1 if packet contains IP options, 0 otherwise
- */
-int odp_packet_inflag_ipopt(odp_packet_t pkt);
-
-/**
- * Check for IPSec
- *
- * @param pkt Packet handle
- * @return 1 if packet requires IPSec processing, 0 otherwise
- */
-int odp_packet_inflag_ipsec(odp_packet_t pkt);
-
-/**
- * Check for UDP
- *
- * @param pkt Packet handle
- * @return 1 if packet contains a UDP header, 0 otherwise
- */
-int odp_packet_inflag_udp(odp_packet_t pkt);
-
-/**
- * Check for TCP
- *
- * @param pkt Packet handle
- * @return 1 if packet contains a TCP header, 0 otherwise
- */
-int odp_packet_inflag_tcp(odp_packet_t pkt);
-
-/**
- * Check for SCTP
- *
- * @param pkt Packet handle
- * @return 1 if packet contains an SCTP header, 0 otherwise
- */
-int odp_packet_inflag_sctp(odp_packet_t pkt);
-
-/**
- * Check for ICMP
- *
- * @param pkt Packet handle
- * @return 1 if packet contains an ICMP header, 0 otherwise
- */
-int odp_packet_inflag_icmp(odp_packet_t pkt);
-
-/**
- * Request L4 checksum calculation
- *
- * @param pkt Packet handle
- */
-void odp_packet_outflag_l4_chksum(odp_packet_t pkt);
-
-/**
- * Set flag for L2 header, e.g. ethernet
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_l2(odp_packet_t pkt, int val);
-
-/**
- * Set flag for L3 header, e.g. IPv4, IPv6
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_l3(odp_packet_t pkt, int val);
-
-/**
- * Set flag for L4 header, e.g. UDP, TCP, SCTP (also ICMP)
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_l4(odp_packet_t pkt, int val);
-
-/**
- * Set flag for Ethernet header
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_eth(odp_packet_t pkt, int val);
-
-/**
- * Set flag for jumbo frame
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_jumbo(odp_packet_t pkt, int val);
-
-/**
- * Set flag for VLAN
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_vlan(odp_packet_t pkt, int val);
-
-/**
- * Set flag for VLAN QinQ (stacked VLAN)
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_vlan_qinq(odp_packet_t pkt, int val);
-
-/**
- * Set flag for ARP
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_arp(odp_packet_t pkt, int val);
-
-/**
- * Set flag for IPv4
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_ipv4(odp_packet_t pkt, int val);
-
-/**
- * Set flag for IPv6
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_ipv6(odp_packet_t pkt, int val);
-
-/**
- * Set flag for IP fragment
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_ipfrag(odp_packet_t pkt, int val);
-
-/**
- * Set flag for IP options
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_ipopt(odp_packet_t pkt, int val);
-
-/**
- * Set flag for IPSec
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_ipsec(odp_packet_t pkt, int val);
-
-/**
- * Set flag for UDP
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_udp(odp_packet_t pkt, int val);
-
-/**
- * Set flag for TCP
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_tcp(odp_packet_t pkt, int val);
-
-/**
- * Set flag for SCTP
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_sctp(odp_packet_t pkt, int val);
-
-/**
- * Set flag for ICMP
- *
- * @param pkt Packet handle
- * @param val Value
- */
-void odp_packet_set_inflag_icmp(odp_packet_t pkt, int val);
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index 1475437..1e8d448 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -14,7 +14,6 @@
 #include <odp_shared_memory.h>
 #include <odp_crypto_internal.h>
 #include <odp_hints.h>
-#include <odph_packet.h>
 
 #include <string.h>
 
@@ -370,7 +369,7 @@ odp_crypto_operation(odp_crypto_op_params_t *params,
 		if (completion_event == odp_packet_to_buffer(params->pkt))
 			completion_event =
 				odp_packet_to_buffer(params->out_pkt);
-		odph_packet_free(params->pkt);
+		odp_packet_free(params->pkt);
 		params->pkt = ODP_PACKET_INVALID;
 	}
 
diff --git a/platform/linux-generic/odp_packet_flags.c b/platform/linux-generic/odp_packet_flags.c
deleted file mode 100644
index 06fdeed..0000000
--- a/platform/linux-generic/odp_packet_flags.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/* Copyright (c) 2014, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier:     BSD-3-Clause
- */
-
-#include <odp_packet_flags.h>
-#include <odp_packet_internal.h>
-
-
-int odp_packet_error(odp_packet_t pkt)
-{
-	return (odp_packet_hdr(pkt)->error_flags.all != 0);
-}
-
-/* Get Error Flags */
-
-int odp_packet_errflag_frame_len(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->error_flags.frame_len;
-}
-
-/* Get Input Flags */
-
-int odp_packet_inflag_l2(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.l2;
-}
-
-int odp_packet_inflag_l3(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.l3;
-}
-
-int odp_packet_inflag_l4(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.l4;
-}
-
-int odp_packet_inflag_eth(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.eth;
-}
-
-int odp_packet_inflag_jumbo(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.jumbo;
-}
-
-int odp_packet_inflag_vlan(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.vlan;
-}
-
-int odp_packet_inflag_vlan_qinq(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.vlan_qinq;
-}
-
-int odp_packet_inflag_arp(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.arp;
-}
-
-int odp_packet_inflag_ipv4(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.ipv4;
-}
-
-int odp_packet_inflag_ipv6(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.ipv6;
-}
-
-int odp_packet_inflag_ipfrag(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.ipfrag;
-}
-
-int odp_packet_inflag_ipopt(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.ipopt;
-}
-
-int odp_packet_inflag_ipsec(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.ipsec;
-}
-
-int odp_packet_inflag_udp(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.udp;
-}
-
-int odp_packet_inflag_tcp(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.tcp;
-}
-
-int odp_packet_inflag_sctp(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.sctp;
-}
-
-int odp_packet_inflag_icmp(odp_packet_t pkt)
-{
-	return odp_packet_hdr(pkt)->input_flags.icmp;
-}
-
-/* Set Output Flags */
-
-void odp_packet_outflag_l4_chksum(odp_packet_t pkt)
-{
-	odp_packet_hdr(pkt)->output_flags.l4_chksum = 1;
-}
-
-/* Set Input Flags */
-
-void odp_packet_set_inflag_l2(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.l2 = val;
-}
-
-void odp_packet_set_inflag_l3(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.l3 = val;
-}
-
-void odp_packet_set_inflag_l4(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.l4 = val;
-}
-
-void odp_packet_set_inflag_eth(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.eth = val;
-}
-
-void odp_packet_set_inflag_jumbo(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.jumbo = val;
-}
-
-void odp_packet_set_inflag_vlan(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.vlan = val;
-}
-
-void odp_packet_set_inflag_vlan_qinq(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.vlan_qinq = val;
-}
-
-void odp_packet_set_inflag_arp(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.arp = val;
-}
-
-void odp_packet_set_inflag_ipv4(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.ipv4 = val;
-}
-
-void odp_packet_set_inflag_ipv6(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.ipv6 = val;
-}
-
-void odp_packet_set_inflag_ipfrag(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.ipfrag = val;
-}
-
-void odp_packet_set_inflag_ipopt(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.ipopt = val;
-}
-
-void odp_packet_set_inflag_ipsec(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.ipsec = val;
-}
-
-void odp_packet_set_inflag_udp(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.udp = val;
-}
-
-void odp_packet_set_inflag_tcp(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.tcp = val;
-}
-
-void odp_packet_set_inflag_sctp(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.sctp = val;
-}
-
-void odp_packet_set_inflag_icmp(odp_packet_t pkt, int val)
-{
-	odp_packet_hdr(pkt)->input_flags.icmp = val;
-}
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index f35193f..5c6f628 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -369,7 +369,8 @@ odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id)
 
 int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr)
 {
-	odp_packet_t pkt = odp_packet_from_buffer(buf_hdr->handle.handle);
+	odp_packet_t pkt =
+		odp_packet_from_buf_internal(odp_hdr_to_buf(buf_hdr));
 	int len = 1;
 	int nbr;
 
@@ -391,7 +392,9 @@ int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[],
 	int i;
 
 	for (i = 0; i < num; ++i)
-		pkt_tbl[i] = odp_packet_from_buffer(buf_hdr[i]->handle.handle);
+		pkt_tbl[i] =
+			odp_packet_from_buf_internal(
+				odp_hdr_to_buf(buf_hdr[i]));
 
 	nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num);
 	return (nbr == num ? 0 : -1);
diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c
index 0492d1e..da66cf0 100644
--- a/platform/linux-generic/odp_packet_socket.c
+++ b/platform/linux-generic/odp_packet_socket.c
@@ -34,13 +34,13 @@
 #include <errno.h>
 #include <sys/syscall.h>
 
+#include <odp_spinlock.h>
 #include <odp_packet_socket.h>
 #include <odp_packet_internal.h>
 #include <odp_hints.h>
 
 #include <odph_eth.h>
 #include <odph_ip.h>
-#include <odph_packet.h>
 
 /** Provide a sendmmsg wrapper for systems with no libc or kernel support.
  *  As it is implemented as a weak symbol, it has zero effect on systems
@@ -178,28 +178,19 @@ int setup_pkt_sock(pkt_sock_t *const pkt_sock, const char *netdev,
 	unsigned int if_idx;
 	struct ifreq ethreq;
 	struct sockaddr_ll sa_ll;
-	odp_packet_t pkt;
-	uint8_t *pkt_buf;
-	uint8_t *l2_hdr;
 
 	if (pool == ODP_BUFFER_POOL_INVALID)
 		return -1;
 	pkt_sock->pool = pool;
 
-	pkt = odph_packet_alloc(pool);
-	if (!odph_packet_is_valid(pkt))
-		return -1;
-
-	pkt_buf = odp_packet_addr(pkt);
-	l2_hdr = ETHBUF_ALIGN(pkt_buf);
 	/* Store eth buffer offset for pkt buffers from this pool */
-	pkt_sock->frame_offset = (uintptr_t)l2_hdr - (uintptr_t)pkt_buf;
+	pkt_sock->frame_offset = 0;
 	/* pkt buffer size */
-	pkt_sock->buf_size = odph_packet_buf_size(pkt);
+	pkt_sock->buf_size = odp_buffer_pool_segment_size(pool);
 	/* max frame len taking into account the l2-offset */
-	pkt_sock->max_frame_len = pkt_sock->buf_size - pkt_sock->frame_offset;
-
-	odph_packet_free(pkt);
+	pkt_sock->max_frame_len = pkt_sock->buf_size -
+		odp_buffer_pool_headroom(pool) -
+		odp_buffer_pool_tailroom(pool);
 
 	odp_spinlock_lock(&raw_sockets_lock);
 
@@ -284,7 +275,6 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock,
 	int const sockfd = pkt_sock->sockfd;
 	odp_packet_t pkt = ODP_PACKET_INVALID;
 	uint8_t *pkt_buf;
-	uint8_t *l2_hdr;
 	int nb_rx = 0;
 
 	/*  recvfrom:
@@ -297,15 +287,14 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock,
 
 	for (i = 0; i < len; i++) {
 		if (odp_likely(pkt == ODP_PACKET_INVALID)) {
-			pkt = odph_packet_alloc(pkt_sock->pool);
+			pkt = odp_packet_alloc(pkt_sock->pool);
 			if (odp_unlikely(pkt == ODP_PACKET_INVALID))
 				break;
 		}
 
 		pkt_buf = odp_packet_addr(pkt);
-		l2_hdr = pkt_buf + pkt_sock->frame_offset;
 
-		recv_bytes = recvfrom(sockfd, l2_hdr,
+		recv_bytes = recvfrom(sockfd, pkt_buf,
 				      pkt_sock->max_frame_len, MSG_DONTWAIT,
 				      (struct sockaddr *)&sll, &addrlen);
 		/* no data or error: free recv buf and break out of loop */
@@ -316,7 +305,8 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock,
 			continue;
 
 		/* Parse and set packet header data */
-		odp_packet_parse(pkt, recv_bytes, pkt_sock->frame_offset);
+		odp_packet_set_len(pkt, recv_bytes);
+		odp_packet_parse(pkt);
 
 		pkt_table[nb_rx] = pkt;
 		pkt = ODP_PACKET_INVALID;
@@ -324,7 +314,7 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock,
 	} /* end for() */
 
 	if (odp_unlikely(pkt != ODP_PACKET_INVALID))
-		odph_packet_free(pkt);
+		odp_packet_free(pkt);
 
 	return nb_rx;
 }
@@ -350,8 +340,7 @@ int send_pkt_sock_basic(pkt_sock_t *const pkt_sock,
 	while (i < len) {
 		pkt = pkt_table[i];
 
-		frame = odp_packet_l2(pkt);
-		frame_len = odp_packet_get_len(pkt);
+		frame = odp_packet_map(pkt, &frame_len);
 
 		ret = send(sockfd, frame, frame_len, flags);
 		if (odp_unlikely(ret == -1)) {
@@ -367,8 +356,10 @@ int send_pkt_sock_basic(pkt_sock_t *const pkt_sock,
 	}			/* end while */
 	nb_tx = i;
 
-	for (i = 0; i < len; i++)
-		odph_packet_free(pkt_table[i]);
+	for (i = 0; i < len; i++) {
+		if (odp_packet_decr_refcount(pkt_table[i], 1) == 0)
+			odp_packet_free(pkt_table[i]);
+	}
 
 	return nb_tx;
 }
@@ -395,7 +386,7 @@ int recv_pkt_sock_mmsg(pkt_sock_t *const pkt_sock,
 	memset(msgvec, 0, sizeof(msgvec));
 
 	for (i = 0; i < (int)len; i++) {
-		pkt_table[i] = odph_packet_alloc(pkt_sock->pool);
+		pkt_table[i] = odp_packet_alloc(pkt_sock->pool);
 		if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID))
 			break;
 
@@ -417,13 +408,12 @@ int recv_pkt_sock_mmsg(pkt_sock_t *const pkt_sock,
 		/* Don't receive packets sent by ourselves */
 		if (odp_unlikely(ethaddrs_equal(pkt_sock->if_mac,
 						eth_hdr->h_source))) {
-			odph_packet_free(pkt_table[i]);
+			odp_packet_free(pkt_table[i]);
 			continue;
 		}
 
 		/* Parse and set packet header data */
-		odp_packet_parse(pkt_table[i], msgvec[i].msg_len,
-				 pkt_sock->frame_offset);
+		odp_packet_parse(pkt_table[i]);
 
 		pkt_table[nb_rx] = pkt_table[i];
 		nb_rx++;
@@ -431,7 +421,7 @@ int recv_pkt_sock_mmsg(pkt_sock_t *const pkt_sock,
 
 	/* Free unused pkt buffers */
 	for (; i < msgvec_len; i++)
-		odph_packet_free(pkt_table[i]);
+		odp_packet_free(pkt_table[i]);
 
 	return nb_rx;
 }
@@ -457,8 +447,8 @@ int send_pkt_sock_mmsg(pkt_sock_t *const pkt_sock,
 	memset(msgvec, 0, sizeof(msgvec));
 
 	for (i = 0; i < len; i++) {
-		uint8_t *const frame = odp_packet_l2(pkt_table[i]);
-		const size_t frame_len = odp_packet_get_len(pkt_table[i]);
+		size_t frame_len;
+		uint8_t *const frame = odp_packet_map(pkt_table[i], &frame_len);
 		iovecs[i].iov_base = frame;
 		iovecs[i].iov_len = frame_len;
 		msgvec[i].msg_hdr.msg_iov = &iovecs[i];
@@ -472,8 +462,10 @@ int send_pkt_sock_mmsg(pkt_sock_t *const pkt_sock,
 		flags = 0;	/* blocking for next rounds */
 	}
 
-	for (i = 0; i < len; i++)
-		odph_packet_free(pkt_table[i]);
+	for (i = 0; i < len; i++) {
+		if (odp_packet_decr_refcount(pkt_table[i], 1) == 0)
+			odp_packet_free(pkt_table[i]);
+	}
 
 	return len;
 }
@@ -537,7 +529,6 @@ static inline void mmap_tx_user_ready(struct tpacket2_hdr *hdr)
 static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring,
 				      odp_packet_t pkt_table[], unsigned len,
 				      odp_buffer_pool_t pool,
-				      size_t frame_offset,
 				      unsigned char if_mac[])
 {
 	union frame_map ppd;
@@ -570,18 +561,18 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring,
 				continue;
 			}
 
-			pkt_table[i] = odph_packet_alloc(pool);
+			pkt_table[i] = odp_packet_alloc(pool);
 			if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID))
 				break;
 
-			l2_hdr = odp_packet_addr(pkt_table[i])
-				 + frame_offset;
+			l2_hdr = odp_packet_addr(pkt_table[i]);
+			odp_packet_set_len(pkt_table[i], pkt_len);
 			memcpy(l2_hdr, pkt_buf, pkt_len);
 
 			mmap_rx_user_ready(ppd.raw);
 
 			/* Parse and set packet header data */
-			odp_packet_parse(pkt_table[i], pkt_len, frame_offset);
+			odp_packet_parse(pkt_table[i]);
 
 			frame_num = next_frame_num;
 			i++;
@@ -613,8 +604,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring,
 
 			next_frame_num = (frame_num + 1) % ring->rd_num;
 
-			pkt_buf = odp_packet_l2(pkt_table[i]);
-			pkt_len = odp_packet_get_len(pkt_table[i]);
+			pkt_buf = odp_packet_map(pkt_table[i], &pkt_len);
 
 			ppd.v2->tp_h.tp_snaplen = pkt_len;
 			ppd.v2->tp_h.tp_len = pkt_len;
@@ -624,7 +614,8 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring,
 
 			mmap_tx_user_ready(ppd.raw);
 
-			odph_packet_free(pkt_table[i]);
+			if (odp_packet_decr_refcount(pkt_table[i], 1) == 0)
+				odp_packet_free(pkt_table[i]);
 			frame_num = next_frame_num;
 			i++;
 		} else {
@@ -805,9 +796,6 @@ static int mmap_store_hw_addr(pkt_sock_mmap_t *const pkt_sock,
 int setup_pkt_sock_mmap(pkt_sock_mmap_t *const pkt_sock, const char *netdev,
 			odp_buffer_pool_t pool, int fanout)
 {
-	odp_packet_t pkt;
-	uint8_t *pkt_buf;
-	uint8_t *l2_hdr;
 	int if_idx;
 	int ret = 0;
 
@@ -816,16 +804,8 @@ int setup_pkt_sock_mmap(pkt_sock_mmap_t *const pkt_sock, const char *netdev,
 	if (pool == ODP_BUFFER_POOL_INVALID)
 		return -1;
 
-	pkt = odph_packet_alloc(pool);
-	if (!odph_packet_is_valid(pkt))
-		return -1;
-
-	pkt_buf = odp_packet_addr(pkt);
-	l2_hdr = ETHBUF_ALIGN(pkt_buf);
 	/* Store eth buffer offset for pkt buffers from this pool */
-	pkt_sock->frame_offset = (uintptr_t)l2_hdr - (uintptr_t)pkt_buf;
-
-	odph_packet_free(pkt);
+	pkt_sock->frame_offset = 0;
 
 	pkt_sock->pool = pool;
 	pkt_sock->sockfd = mmap_pkt_socket();
@@ -892,7 +872,7 @@ int recv_pkt_sock_mmap(pkt_sock_mmap_t *const pkt_sock,
 {
 	return pkt_mmap_v2_rx(pkt_sock->rx_ring.sock, &pkt_sock->rx_ring,
 			      pkt_table, len, pkt_sock->pool,
-			      pkt_sock->frame_offset, pkt_sock->if_mac);
+			      pkt_sock->if_mac);
 }
 
 /*
diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
index 1318bcd..af3a330 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -9,8 +9,9 @@
 #include <odp_std_types.h>
 #include <odp_align.h>
 #include <odp_buffer.h>
-#include <odp_buffer_internal.h>
 #include <odp_buffer_pool_internal.h>
+#include <odp_buffer_internal.h>
+#include <odp_buffer_inlines.h>
 #include <odp_internal.h>
 #include <odp_shared_memory.h>
 #include <odp_schedule_internal.h>
@@ -422,7 +423,7 @@ int odp_queue_deq_multi(odp_queue_t handle, odp_buffer_t buf[], int num)
 	ret = queue->s.dequeue_multi(queue, buf_hdr, num);
 
 	for (i = 0; i < ret; i++)
-		buf[i] = buf_hdr[i]->handle.handle;
+		buf[i] = odp_hdr_to_buf(buf_hdr[i]);
 
 	return ret;
 }
@@ -437,7 +438,7 @@ odp_buffer_t odp_queue_deq(odp_queue_t handle)
 	buf_hdr = queue->s.dequeue(queue);
 
 	if (buf_hdr)
-		return buf_hdr->handle.handle;
+		return odp_hdr_to_buf(buf_hdr);
 
 	return ODP_BUFFER_INVALID;
 }
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index 1bf819b..f30b877 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -83,8 +83,8 @@ int odp_schedule_init_global(void)
 {
 	odp_shm_t shm;
 	odp_buffer_pool_t pool;
-	void *pool_base;
 	int i, j;
+	odp_buffer_pool_param_t params;
 
 	ODP_DBG("Schedule init ... ");
 
@@ -99,20 +99,12 @@ int odp_schedule_init_global(void)
 		return -1;
 	}
 
-	shm = odp_shm_reserve("odp_sched_pool",
-			      SCHED_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	params.buf_num  = SCHED_POOL_SIZE/sizeof(queue_desc_t);
+	params.buf_size = sizeof(queue_desc_t);
+	params.buf_type = ODP_BUFFER_TYPE_RAW;
+	params.buf_opts = ODP_BUFFER_OPTS_UNSEGMENTED;
 
-	pool_base = odp_shm_addr(shm);
-
-	if (pool_base == NULL) {
-		ODP_ERR("Schedule init: Shm reserve failed.\n");
-		return -1;
-	}
-
-	pool = odp_buffer_pool_create("odp_sched_pool", pool_base,
-				      SCHED_POOL_SIZE, sizeof(queue_desc_t),
-				      ODP_CACHE_LINE_SIZE,
-				      ODP_BUFFER_TYPE_RAW);
+	pool = odp_buffer_pool_create("odp_sched_pool", &params, NULL);
 
 	if (pool == ODP_BUFFER_POOL_INVALID) {
 		ODP_ERR("Schedule init: Pool create failed.\n");
diff --git a/test/api_test/odp_timer_ping.c b/test/api_test/odp_timer_ping.c
index 65e3834..90c1ae6 100644
--- a/test/api_test/odp_timer_ping.c
+++ b/test/api_test/odp_timer_ping.c
@@ -318,9 +318,8 @@ int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
 	ping_arg_t pingarg;
 	odp_queue_t queue;
 	odp_buffer_pool_t pool;
-	void *pool_base;
 	int i;
-	odp_shm_t shm;
+	odp_buffer_pool_param_t params;
 
 	if (odp_test_global_init() != 0)
 		return -1;
@@ -333,14 +332,14 @@ int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
 	/*
 	 * Create message pool
 	 */
-	shm = odp_shm_reserve("msg_pool",
-			      MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
-	pool_base = odp_shm_addr(shm);
-
-	pool = odp_buffer_pool_create("msg_pool", pool_base, MSG_POOL_SIZE,
-				      BUF_SIZE,
-				      ODP_CACHE_LINE_SIZE,
-				      ODP_BUFFER_TYPE_RAW);
+
+	params.buf_num  = MSG_POOL_SIZE/BUF_SIZE;
+	params.buf_size = BUF_SIZE;
+	params.buf_type = ODP_BUFFER_TYPE_RAW;
+	params.buf_opts = ODP_BUFFER_OPTS_NONE;
+
+	pool = odp_buffer_pool_create("msg_pool", &params, NULL);
+
 	if (pool == ODP_BUFFER_POOL_INVALID) {
 		ODP_ERR("Pool create failed.\n");
 		return -1;
