diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
index 518c132..ae04a4e 100644
--- a/example/ipsec/odp_ipsec.c
+++ b/example/ipsec/odp_ipsec.c
@@ -167,7 +167,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);
+	return (pkt_ctx_t *)odp_packet_user_ptr(pkt);
 }
 
 /**
@@ -191,7 +191,7 @@ pkt_ctx_t *alloc_pkt_ctx(odp_packet_t pkt)
 	ctx = odp_buffer_addr(ctx_buf);
 	memset(ctx, 0, sizeof(*ctx));
 	ctx->buffer = ctx_buf;
-	odp_packet_set_ctx(pkt, ctx);
+	odp_packet_user_ptr_set(pkt, ctx);
 
 	return ctx;
 }
diff --git a/platform/linux-generic/include/api/odp_packet.h b/platform/linux-generic/include/api/odp_packet.h
index 96e1474..cb5f177 100644
--- a/platform/linux-generic/include/api/odp_packet.h
+++ b/platform/linux-generic/include/api/odp_packet.h
@@ -131,22 +131,50 @@ void odp_packet_set_len(odp_packet_t pkt, size_t len);
 size_t odp_packet_get_len(odp_packet_t pkt);
 
 /**
- * Set packet user context
+ * User context pointer
  *
- * @param buf      Packet handle
- * @param ctx      User context
+ * Return previously stored user context pointer.
  *
+ * @param pkt  Packet handle
+ *
+ * @return User context pointer
+ */
+void *odp_packet_user_ptr(odp_packet_t pkt);
+
+/**
+ * Set user context pointer
+ *
+ * Each packet has room for a user defined context. The context can be stored
+ * either as a pointer OR as a uint64_t value, but not both at the same time.
+ * The latest context set operation determines which one has been stored.
+ *
+ * @param pkt  Packet handle
+ * @param ctx  User context pointer
  */
-void odp_packet_set_ctx(odp_packet_t buf, const void *ctx);
+void odp_packet_user_ptr_set(odp_packet_t pkt, const void *ctx);
 
 /**
- * Get packet user context
+ * User context data (uint64_t)
  *
- * @param buf      Packet handle
+ * Return previously stored user context uint64_t value.
  *
- * @return User context
+ * @param pkt  Packet handle
+ *
+ * @return User context data
+ */
+uint64_t odp_packet_user_u64(odp_packet_t pkt);
+
+/**
+ * Set user context data (uint64_t)
+ *
+ * Each packet has room for a user defined context. The context can be stored
+ * either as a pointer OR as a uint64_t value, but not both at the same time.
+ * The latest context set operation determines which one has been stored.
+ *
+ * @param pkt  Packet handle
+ * @param ctx  User context data
  */
-void *odp_packet_get_ctx(odp_packet_t buf);
+void odp_packet_user_u64_set(odp_packet_t pkt, uint64_t ctx);
 
 /**
  * Packet buffer start address
diff --git a/platform/linux-generic/include/odp_buffer_internal.h b/platform/linux-generic/include/odp_buffer_internal.h
index 859633e..933097b 100644
--- a/platform/linux-generic/include/odp_buffer_internal.h
+++ b/platform/linux-generic/include/odp_buffer_internal.h
@@ -124,6 +124,7 @@ typedef struct odp_buffer_hdr_t {
 	union {
 		uint64_t         buf_u64;    /* user u64 */
 		void            *buf_ctx;    /* user context */
+		const void      *buf_cctx;   /* const alias for ctx */
 		void            *udata_addr; /* user metadata addr */
 	};
 	size_t                   udata_size; /* size of user metadata */
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index 783714b..e5899fd 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -103,6 +103,26 @@ void *odp_packet_data(odp_packet_t pkt)
 	return packet_map(pkt_hdr, 0, NULL);
 }
 
+void *odp_packet_user_ptr(odp_packet_t pkt)
+{
+	return odp_packet_hdr(pkt)->buf_hdr.buf_ctx;
+}
+
+void odp_packet_user_ptr_set(odp_packet_t pkt, const void *ctx)
+{
+	odp_packet_hdr(pkt)->buf_hdr.buf_cctx = ctx;
+}
+
+uint64_t odp_packet_user_u64(odp_packet_t pkt)
+{
+	return odp_packet_hdr(pkt)->buf_hdr.buf_u64;
+}
+
+void odp_packet_user_u64_set(odp_packet_t pkt, uint64_t ctx)
+{
+	odp_packet_hdr(pkt)->buf_hdr.buf_u64 = ctx;
+}
+
 void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
 {
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
@@ -407,16 +427,6 @@ int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src)
 	return 0;
 }
 
-void odp_packet_set_ctx(odp_packet_t pkt, const void *ctx)
-{
-	odp_packet_hdr(pkt)->user_ctx = (intptr_t)ctx;
-}
-
-void *odp_packet_get_ctx(odp_packet_t pkt)
-{
-	return (void *)(intptr_t)odp_packet_hdr(pkt)->user_ctx;
-}
-
 int odp_packet_is_valid(odp_packet_t pkt)
 {
 	odp_buffer_t buf = odp_packet_to_buffer(pkt);
