diff mbox

[PATCHv5,3/9] api: packet: change layer offset/pointer API

Message ID 1418733042-18047-4-git-send-email-taras.kondratiuk@linaro.org
State Accepted
Commit df8a28363d75dd27476cc89cb1fae60c167f444c
Headers show

Commit Message

Taras Kondratiuk Dec. 16, 2014, 12:30 p.m. UTC
From: Bill Fischofer <bill.fischofer@linaro.org>

Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>
Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org>
---
 example/generator/odp_generator.c                  |  10 +-
 example/ipsec/odp_ipsec.c                          |  13 ++-
 example/ipsec/odp_ipsec_stream.c                   |   8 +-
 example/packet/odp_pktio.c                         |   5 +-
 helper/include/odph_ip.h                           |   4 +-
 helper/include/odph_udp.h                          |   4 +-
 platform/linux-generic/include/api/odp_packet.h    | 130 ++++++++++++++-------
 .../linux-generic/include/odp_packet_internal.h    |  11 ++
 platform/linux-generic/odp_packet.c                |  80 +++++++------
 platform/linux-generic/odp_packet_socket.c         |  17 ++-
 10 files changed, 175 insertions(+), 107 deletions(-)

Comments

Anders Roxell Dec. 16, 2014, 1:48 p.m. UTC | #1
On 2014-12-16 14:30, Taras Kondratiuk wrote:
> From: Bill Fischofer <bill.fischofer@linaro.org>
> 
> Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>
> Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org>
> ---
>  example/generator/odp_generator.c                  |  10 +-
>  example/ipsec/odp_ipsec.c                          |  13 ++-
>  example/ipsec/odp_ipsec_stream.c                   |   8 +-
>  example/packet/odp_pktio.c                         |   5 +-
>  helper/include/odph_ip.h                           |   4 +-
>  helper/include/odph_udp.h                          |   4 +-
>  platform/linux-generic/include/api/odp_packet.h    | 130 ++++++++++++++-------
>  .../linux-generic/include/odp_packet_internal.h    |  11 ++
>  platform/linux-generic/odp_packet.c                |  80 +++++++------
>  platform/linux-generic/odp_packet_socket.c         |  17 ++-
>  10 files changed, 175 insertions(+), 107 deletions(-)
> 
> diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
> index 5ded85c..aec2275 100644
> --- a/example/generator/odp_generator.c
> +++ b/example/generator/odp_generator.c
> @@ -189,13 +189,13 @@ static void pack_udp_pkt(odp_buffer_t obuf)
>  
>  	pkt = odp_packet_from_buffer(obuf);
>  	/* ether */
> -	odp_packet_set_l2_offset(pkt, 0);
> +	odp_packet_l2_offset_set(pkt, 0);
>  	eth = (odph_ethhdr_t *)buf;
>  	memcpy((char *)eth->src.addr, args->appl.srcmac.addr, ODPH_ETHADDR_LEN);
>  	memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, ODPH_ETHADDR_LEN);
>  	eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>  	/* ip */
> -	odp_packet_set_l3_offset(pkt, ODPH_ETHHDR_LEN);
> +	odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
>  	ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
>  	ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip);
>  	ip->src_addr = odp_cpu_to_be_32(args->appl.srcip);
> @@ -208,7 +208,7 @@ static void pack_udp_pkt(odp_buffer_t obuf)
>  	ip->chksum = 0;
>  	odph_ipv4_csum_update(pkt);
>  	/* udp */
> -	odp_packet_set_l4_offset(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
> +	odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
>  	udp = (odph_udphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
>  	udp->src_port = 0;
>  	udp->dst_port = 0;
> @@ -246,13 +246,13 @@ static void pack_icmp_pkt(odp_buffer_t obuf)
>  	args->appl.payload = 56;
>  	pkt = odp_packet_from_buffer(obuf);
>  	/* ether */
> -	odp_packet_set_l2_offset(pkt, 0);
> +	odp_packet_l2_offset_set(pkt, 0);
>  	eth = (odph_ethhdr_t *)buf;
>  	memcpy((char *)eth->src.addr, args->appl.srcmac.addr, ODPH_ETHADDR_LEN);
>  	memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, ODPH_ETHADDR_LEN);
>  	eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>  	/* ip */
> -	odp_packet_set_l3_offset(pkt, ODPH_ETHHDR_LEN);
> +	odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
>  	ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
>  	ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip);
>  	ip->src_addr = odp_cpu_to_be_32(args->appl.srcip);
> diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
> index cd73682..c6f7471 100644
> --- a/example/ipsec/odp_ipsec.c
> +++ b/example/ipsec/odp_ipsec.c
> @@ -639,13 +639,14 @@ pkt_disposition_e do_input_verify(odp_packet_t pkt,
>  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);
> +	odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>  	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_ptr(pkt, NULL);
>  
>  		memcpy(&eth->dst, entry->dst_mac, ODPH_ETHADDR_LEN);
>  		memcpy(&eth->src, entry->src_mac, ODPH_ETHADDR_LEN);
> @@ -676,7 +677,7 @@ pkt_disposition_e do_ipsec_in_classify(odp_packet_t pkt,
>  				       bool *skip)
>  {
>  	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_ptr(pkt, NULL);
>  	int hdr_len;
>  	odph_ahhdr_t *ah = NULL;
>  	odph_esphdr_t *esp = NULL;
> @@ -771,7 +772,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_ptr(pkt, NULL);
>  
>  	/*
>  	 * Finish auth
> @@ -836,7 +837,7 @@ pkt_disposition_e do_ipsec_out_classify(odp_packet_t pkt,
>  					bool *skip)
>  {
>  	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_ptr(pkt, NULL);
>  	uint16_t ip_data_len = ipv4_data_len(ip);
>  	uint8_t *ip_data = ipv4_data_p(ip);
>  	ipsec_cache_entry_t *entry;
> @@ -1003,7 +1004,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_ptr(pkt, NULL);
>  
>  	/* Finalize the IPv4 header */
>  	ip->ttl = ctx->ipsec.ip_ttl;
> diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c
> index 15cdb3d..93de198 100644
> --- a/example/ipsec/odp_ipsec_stream.c
> +++ b/example/ipsec/odp_ipsec_stream.c
> @@ -195,7 +195,7 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
>  
>  	/* Ethernet */
>  	odp_packet_has_eth_set(pkt, 1);
> -	odp_packet_set_l2_offset(pkt, data - base);
> +	odp_packet_l2_offset_set(pkt, data - base);
>  	eth = (odph_ethhdr_t *)data;
>  	data += sizeof(*eth);
>  
> @@ -205,10 +205,10 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
>  
>  	/* IPv4 */
>  	odp_packet_has_ipv4_set(pkt, 1);
> -	odp_packet_set_l3_offset(pkt, data - base);
> +	odp_packet_l3_offset_set(pkt, data - base);
>  	ip = (odph_ipv4hdr_t *)data;
>  	data += sizeof(*ip);
> -	odp_packet_set_l4_offset(pkt, data - base);
> +	odp_packet_l4_offset_set(pkt, data - base);
>  
>  	/* Wait until almost finished to fill in mutable fields */
>  	memset((char *)ip, 0, sizeof(*ip));
> @@ -345,7 +345,7 @@ bool verify_ipv4_packet(stream_db_entry_t *stream,
>  	stream_pkt_hdr_t *test;
>  
>  	/* Basic IPv4 verify (add checksum verification) */
> -	data = odp_packet_l3(pkt);
> +	data = odp_packet_l3_ptr(pkt, NULL);
>  	ip = (odph_ipv4hdr_t *)data;
>  	data += sizeof(*ip);
>  	if (0x45 != ip->ver_ihl)
> diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c
> index 10b79d7..463042c 100644
> --- a/example/packet/odp_pktio.c
> +++ b/example/packet/odp_pktio.c
> @@ -483,7 +483,7 @@ static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len)
>  	for (i = 0; i < len; ++i) {
>  		pkt = pkt_tbl[i];
>  		if (odp_packet_has_eth(pkt)) {
> -			eth = (odph_ethhdr_t *)odp_packet_l2(pkt);
> +			eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
>  
>  			tmp_addr = eth->dst;
>  			eth->dst = eth->src;
> @@ -491,7 +491,8 @@ static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len)
>  
>  			if (odp_packet_has_ipv4(pkt)) {
>  				/* IPv4 */
> -				ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
> +				ip = (odph_ipv4hdr_t *)
> +					odp_packet_l3_ptr(pkt, NULL);
>  
>  				ip_tmp_addr  = ip->src_addr;
>  				ip->src_addr = ip->dst_addr;
> diff --git a/helper/include/odph_ip.h b/helper/include/odph_ip.h
> index f78724e..16c8266 100644
> --- a/helper/include/odph_ip.h
> +++ b/helper/include/odph_ip.h
> @@ -88,7 +88,7 @@ static inline int odph_ipv4_csum_valid(odp_packet_t pkt)
>  	if (!odp_packet_l3_offset(pkt))
>  		return 0;
>  
> -	memcpy(&ip, odp_packet_l3(pkt), sizeof(odph_ipv4hdr_t));
> +	memcpy(&ip, odp_packet_l3_ptr(pkt, NULL), sizeof(odph_ipv4hdr_t));
>  	w = (uint16_t *)(void *)&ip;
>  	chksum = ip.chksum;
>  	ip.chksum = 0x0;
> @@ -116,7 +116,7 @@ static inline uint16sum_t odph_ipv4_csum_update(odp_packet_t pkt)
>  	if (!odp_packet_l3_offset(pkt))
>  		return 0;
>  
> -	ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
> +	ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>  	w = (uint16_t *)(void *)ip;
>  	ip->chksum = odp_chksum(w, nleft);
>  	return ip->chksum;
> diff --git a/helper/include/odph_udp.h b/helper/include/odph_udp.h
> index b2eaf03..ef0cd4c 100644
> --- a/helper/include/odph_udp.h
> +++ b/helper/include/odph_udp.h
> @@ -64,8 +64,8 @@ static inline uint16_t odph_ipv4_udp_chksum(odp_packet_t pkt)
>  	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_ptr(pkt, NULL);
> +	udph = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>  	udplen = odp_be_to_cpu_16(udph->length);
>  
>  	/* the source ip */
> diff --git a/platform/linux-generic/include/api/odp_packet.h b/platform/linux-generic/include/api/odp_packet.h
> index 9a15114..96e1474 100644
> --- a/platform/linux-generic/include/api/odp_packet.h
> +++ b/platform/linux-generic/include/api/odp_packet.h
> @@ -180,10 +180,11 @@ uint8_t *odp_packet_addr(odp_packet_t pkt);
>  size_t odp_packet_buf_size(odp_packet_t pkt);
>  
>  /**
> - * Packet data address
> + * Packet data pointer
>   *
> - * Returns the current packet data address. When a packet is received from
> - * packet input, the data address points to the first byte of the packet.
> + * Returns the current packet data pointer. When a packet is received
> + * from packet input, this points to the first byte of the received
> + * packet. Packet level offsets are calculated relative to this position.
>   *
>   * @param pkt  Packet handle
>   *
> @@ -191,94 +192,145 @@ size_t odp_packet_buf_size(odp_packet_t pkt);
>   *
>   * @see odp_packet_l2(), odp_packet_addr()
>   */
> -uint8_t *odp_packet_data(odp_packet_t pkt);
> +void *odp_packet_data(odp_packet_t pkt);
>  
>  /**
> - * Get pointer to the start of the L2 frame
> + * Layer 2 start pointer
>   *
> - * The L2 frame header address is not necessarily the same as the address of the
> - * packet buffer, see odp_packet_addr()
> + * Returns pointer to the start of the layer 2 header. Optionally, outputs
> + * number of data bytes in the segment following the pointer.
>   *
> - * @param pkt  Packet handle
> + * @param      pkt      Packet handle
> + * @param[out] len      Number of data bytes remaining in the segment (output).
> + *                      Ignored when NULL.
>   *
> - * @return  Pointer to L2 header or NULL if not found
> + * @return  Layer 2 start pointer, or offset 0 by default
>   *
> - * @see odp_packet_addr(), odp_packet_data()
> + * @see odp_packet_l2_offset(), odp_packet_l2_offset_set()
>   */
> -uint8_t *odp_packet_l2(odp_packet_t pkt);
> +void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len);
>  
>  /**
> - * Return the byte offset from the packet buffer to the L2 frame
> + * Layer 2 start offset
> + *
> + * Returns offset to the start of the layer 2 header. The offset is calculated
> + * from the current odp_packet_data() position in bytes.
> + *
> + * User is responsible to update the offset when modifying the packet data
> + * pointer position.
>   *
>   * @param pkt  Packet handle
>   *
> - * @return  L2 byte offset or ODP_PACKET_OFFSET_INVALID if not found
> + * @return  Layer 2 start offset
>   */
> -size_t odp_packet_l2_offset(odp_packet_t pkt);
> +uint32_t odp_packet_l2_offset(odp_packet_t pkt);
>  
>  /**
> - * Set the byte offset to the L2 frame
> + * Set layer 2 start offset
> + *
> + * Set offset to the start of the layer 2 header. The offset is calculated from
> + * the current odp_packet_data() position in bytes. Offset must not exceed
> + * packet data length. Packet is not modified on an error.
>   *
>   * @param pkt     Packet handle
> - * @param offset  L2 byte offset
> + * @param offset  Layer 2 start offset (0 ... odp_packet_len()-1)
> + *
> + * @retval 0 Success
> + * @retval Non-zero Failure
>   */
> -void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset);
> -
> +int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset);
>  
>  /**
> - * Get pointer to the start of the L3 packet
> + * Layer 3 start pointer
>   *
> - * @param pkt  Packet handle
> + * Returns pointer to the start of the layer 3 header. Optionally, outputs
> + * number of data bytes in the segment following the pointer.
> + *
> + * @param      pkt      Packet handle
> + * @param[out] len      Number of data bytes remaining in the segment (output).
> + *                      Ignored when NULL.
>   *
> - * @return  Pointer to L3 packet or NULL if not found
> + * @return  Layer 3 start pointer, or NULL
>   *
> + * @see odp_packet_l3_offset(), odp_packet_l3_offset_set()
>   */
> -uint8_t *odp_packet_l3(odp_packet_t pkt);
> +void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len);
>  
>  /**
> - * Return the byte offset from the packet buffer to the L3 packet
> + * Layer 3 start offset
> + *
> + * Returns offset to the start of the layer 3 header. The offset is calculated
> + * from the current odp_packet_data() position in bytes.
> + *
> + * User is responsible to update the offset when modifying the packet data
> + * pointer position.
>   *
>   * @param pkt  Packet handle
>   *
> - * @return  L3 byte offset or ODP_PACKET_OFFSET_INVALID if not found
> + * @return  Layer 3 start offset or ODP_PACKET_OFFSET_INVALID if not found

In the implementation we don't return ODP_PACKET_OFFSET_INVALID if it's not found?
Shouldn't we do that?

Cheers,
Anders
Bill Fischofer Dec. 16, 2014, 5:34 p.m. UTC | #2
This is an omission (bug).  Fix in preparation and will be posted shortly.
Thanks.

Bill

On Tue, Dec 16, 2014 at 7:48 AM, Anders Roxell <anders.roxell@linaro.org>
wrote:
>
> On 2014-12-16 14:30, Taras Kondratiuk wrote:
> > From: Bill Fischofer <bill.fischofer@linaro.org>
> >
> > Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>
> > Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org>
> > ---
> >  example/generator/odp_generator.c                  |  10 +-
> >  example/ipsec/odp_ipsec.c                          |  13 ++-
> >  example/ipsec/odp_ipsec_stream.c                   |   8 +-
> >  example/packet/odp_pktio.c                         |   5 +-
> >  helper/include/odph_ip.h                           |   4 +-
> >  helper/include/odph_udp.h                          |   4 +-
> >  platform/linux-generic/include/api/odp_packet.h    | 130
> ++++++++++++++-------
> >  .../linux-generic/include/odp_packet_internal.h    |  11 ++
> >  platform/linux-generic/odp_packet.c                |  80 +++++++------
> >  platform/linux-generic/odp_packet_socket.c         |  17 ++-
> >  10 files changed, 175 insertions(+), 107 deletions(-)
> >
> > diff --git a/example/generator/odp_generator.c
> b/example/generator/odp_generator.c
> > index 5ded85c..aec2275 100644
> > --- a/example/generator/odp_generator.c
> > +++ b/example/generator/odp_generator.c
> > @@ -189,13 +189,13 @@ static void pack_udp_pkt(odp_buffer_t obuf)
> >
> >       pkt = odp_packet_from_buffer(obuf);
> >       /* ether */
> > -     odp_packet_set_l2_offset(pkt, 0);
> > +     odp_packet_l2_offset_set(pkt, 0);
> >       eth = (odph_ethhdr_t *)buf;
> >       memcpy((char *)eth->src.addr, args->appl.srcmac.addr,
> ODPH_ETHADDR_LEN);
> >       memcpy((char *)eth->dst.addr, args->appl.dstmac.addr,
> ODPH_ETHADDR_LEN);
> >       eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
> >       /* ip */
> > -     odp_packet_set_l3_offset(pkt, ODPH_ETHHDR_LEN);
> > +     odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
> >       ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
> >       ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip);
> >       ip->src_addr = odp_cpu_to_be_32(args->appl.srcip);
> > @@ -208,7 +208,7 @@ static void pack_udp_pkt(odp_buffer_t obuf)
> >       ip->chksum = 0;
> >       odph_ipv4_csum_update(pkt);
> >       /* udp */
> > -     odp_packet_set_l4_offset(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
> > +     odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
> >       udp = (odph_udphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
> >       udp->src_port = 0;
> >       udp->dst_port = 0;
> > @@ -246,13 +246,13 @@ static void pack_icmp_pkt(odp_buffer_t obuf)
> >       args->appl.payload = 56;
> >       pkt = odp_packet_from_buffer(obuf);
> >       /* ether */
> > -     odp_packet_set_l2_offset(pkt, 0);
> > +     odp_packet_l2_offset_set(pkt, 0);
> >       eth = (odph_ethhdr_t *)buf;
> >       memcpy((char *)eth->src.addr, args->appl.srcmac.addr,
> ODPH_ETHADDR_LEN);
> >       memcpy((char *)eth->dst.addr, args->appl.dstmac.addr,
> ODPH_ETHADDR_LEN);
> >       eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
> >       /* ip */
> > -     odp_packet_set_l3_offset(pkt, ODPH_ETHHDR_LEN);
> > +     odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
> >       ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
> >       ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip);
> >       ip->src_addr = odp_cpu_to_be_32(args->appl.srcip);
> > diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
> > index cd73682..c6f7471 100644
> > --- a/example/ipsec/odp_ipsec.c
> > +++ b/example/ipsec/odp_ipsec.c
> > @@ -639,13 +639,14 @@ pkt_disposition_e do_input_verify(odp_packet_t pkt,
> >  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);
> > +     odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt,
> NULL);
> >       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_ptr(pkt, NULL);
> >
> >               memcpy(&eth->dst, entry->dst_mac, ODPH_ETHADDR_LEN);
> >               memcpy(&eth->src, entry->src_mac, ODPH_ETHADDR_LEN);
> > @@ -676,7 +677,7 @@ pkt_disposition_e do_ipsec_in_classify(odp_packet_t
> pkt,
> >                                      bool *skip)
> >  {
> >       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_ptr(pkt,
> NULL);
> >       int hdr_len;
> >       odph_ahhdr_t *ah = NULL;
> >       odph_esphdr_t *esp = NULL;
> > @@ -771,7 +772,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_ptr(pkt, NULL);
> >
> >       /*
> >        * Finish auth
> > @@ -836,7 +837,7 @@ pkt_disposition_e do_ipsec_out_classify(odp_packet_t
> pkt,
> >                                       bool *skip)
> >  {
> >       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_ptr(pkt,
> NULL);
> >       uint16_t ip_data_len = ipv4_data_len(ip);
> >       uint8_t *ip_data = ipv4_data_p(ip);
> >       ipsec_cache_entry_t *entry;
> > @@ -1003,7 +1004,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_ptr(pkt, NULL);
> >
> >       /* Finalize the IPv4 header */
> >       ip->ttl = ctx->ipsec.ip_ttl;
> > diff --git a/example/ipsec/odp_ipsec_stream.c
> b/example/ipsec/odp_ipsec_stream.c
> > index 15cdb3d..93de198 100644
> > --- a/example/ipsec/odp_ipsec_stream.c
> > +++ b/example/ipsec/odp_ipsec_stream.c
> > @@ -195,7 +195,7 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t
> *stream,
> >
> >       /* Ethernet */
> >       odp_packet_has_eth_set(pkt, 1);
> > -     odp_packet_set_l2_offset(pkt, data - base);
> > +     odp_packet_l2_offset_set(pkt, data - base);
> >       eth = (odph_ethhdr_t *)data;
> >       data += sizeof(*eth);
> >
> > @@ -205,10 +205,10 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t
> *stream,
> >
> >       /* IPv4 */
> >       odp_packet_has_ipv4_set(pkt, 1);
> > -     odp_packet_set_l3_offset(pkt, data - base);
> > +     odp_packet_l3_offset_set(pkt, data - base);
> >       ip = (odph_ipv4hdr_t *)data;
> >       data += sizeof(*ip);
> > -     odp_packet_set_l4_offset(pkt, data - base);
> > +     odp_packet_l4_offset_set(pkt, data - base);
> >
> >       /* Wait until almost finished to fill in mutable fields */
> >       memset((char *)ip, 0, sizeof(*ip));
> > @@ -345,7 +345,7 @@ bool verify_ipv4_packet(stream_db_entry_t *stream,
> >       stream_pkt_hdr_t *test;
> >
> >       /* Basic IPv4 verify (add checksum verification) */
> > -     data = odp_packet_l3(pkt);
> > +     data = odp_packet_l3_ptr(pkt, NULL);
> >       ip = (odph_ipv4hdr_t *)data;
> >       data += sizeof(*ip);
> >       if (0x45 != ip->ver_ihl)
> > diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c
> > index 10b79d7..463042c 100644
> > --- a/example/packet/odp_pktio.c
> > +++ b/example/packet/odp_pktio.c
> > @@ -483,7 +483,7 @@ static void swap_pkt_addrs(odp_packet_t pkt_tbl[],
> unsigned len)
> >       for (i = 0; i < len; ++i) {
> >               pkt = pkt_tbl[i];
> >               if (odp_packet_has_eth(pkt)) {
> > -                     eth = (odph_ethhdr_t *)odp_packet_l2(pkt);
> > +                     eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt,
> NULL);
> >
> >                       tmp_addr = eth->dst;
> >                       eth->dst = eth->src;
> > @@ -491,7 +491,8 @@ static void swap_pkt_addrs(odp_packet_t pkt_tbl[],
> unsigned len)
> >
> >                       if (odp_packet_has_ipv4(pkt)) {
> >                               /* IPv4 */
> > -                             ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
> > +                             ip = (odph_ipv4hdr_t *)
> > +                                     odp_packet_l3_ptr(pkt, NULL);
> >
> >                               ip_tmp_addr  = ip->src_addr;
> >                               ip->src_addr = ip->dst_addr;
> > diff --git a/helper/include/odph_ip.h b/helper/include/odph_ip.h
> > index f78724e..16c8266 100644
> > --- a/helper/include/odph_ip.h
> > +++ b/helper/include/odph_ip.h
> > @@ -88,7 +88,7 @@ static inline int odph_ipv4_csum_valid(odp_packet_t
> pkt)
> >       if (!odp_packet_l3_offset(pkt))
> >               return 0;
> >
> > -     memcpy(&ip, odp_packet_l3(pkt), sizeof(odph_ipv4hdr_t));
> > +     memcpy(&ip, odp_packet_l3_ptr(pkt, NULL), sizeof(odph_ipv4hdr_t));
> >       w = (uint16_t *)(void *)&ip;
> >       chksum = ip.chksum;
> >       ip.chksum = 0x0;
> > @@ -116,7 +116,7 @@ static inline uint16sum_t
> odph_ipv4_csum_update(odp_packet_t pkt)
> >       if (!odp_packet_l3_offset(pkt))
> >               return 0;
> >
> > -     ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
> > +     ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
> >       w = (uint16_t *)(void *)ip;
> >       ip->chksum = odp_chksum(w, nleft);
> >       return ip->chksum;
> > diff --git a/helper/include/odph_udp.h b/helper/include/odph_udp.h
> > index b2eaf03..ef0cd4c 100644
> > --- a/helper/include/odph_udp.h
> > +++ b/helper/include/odph_udp.h
> > @@ -64,8 +64,8 @@ static inline uint16_t
> odph_ipv4_udp_chksum(odp_packet_t pkt)
> >       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_ptr(pkt, NULL);
> > +     udph = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> >       udplen = odp_be_to_cpu_16(udph->length);
> >
> >       /* the source ip */
> > diff --git a/platform/linux-generic/include/api/odp_packet.h
> b/platform/linux-generic/include/api/odp_packet.h
> > index 9a15114..96e1474 100644
> > --- a/platform/linux-generic/include/api/odp_packet.h
> > +++ b/platform/linux-generic/include/api/odp_packet.h
> > @@ -180,10 +180,11 @@ uint8_t *odp_packet_addr(odp_packet_t pkt);
> >  size_t odp_packet_buf_size(odp_packet_t pkt);
> >
> >  /**
> > - * Packet data address
> > + * Packet data pointer
> >   *
> > - * Returns the current packet data address. When a packet is received
> from
> > - * packet input, the data address points to the first byte of the
> packet.
> > + * Returns the current packet data pointer. When a packet is received
> > + * from packet input, this points to the first byte of the received
> > + * packet. Packet level offsets are calculated relative to this
> position.
> >   *
> >   * @param pkt  Packet handle
> >   *
> > @@ -191,94 +192,145 @@ size_t odp_packet_buf_size(odp_packet_t pkt);
> >   *
> >   * @see odp_packet_l2(), odp_packet_addr()
> >   */
> > -uint8_t *odp_packet_data(odp_packet_t pkt);
> > +void *odp_packet_data(odp_packet_t pkt);
> >
> >  /**
> > - * Get pointer to the start of the L2 frame
> > + * Layer 2 start pointer
> >   *
> > - * The L2 frame header address is not necessarily the same as the
> address of the
> > - * packet buffer, see odp_packet_addr()
> > + * Returns pointer to the start of the layer 2 header. Optionally,
> outputs
> > + * number of data bytes in the segment following the pointer.
> >   *
> > - * @param pkt  Packet handle
> > + * @param      pkt      Packet handle
> > + * @param[out] len      Number of data bytes remaining in the segment
> (output).
> > + *                      Ignored when NULL.
> >   *
> > - * @return  Pointer to L2 header or NULL if not found
> > + * @return  Layer 2 start pointer, or offset 0 by default
> >   *
> > - * @see odp_packet_addr(), odp_packet_data()
> > + * @see odp_packet_l2_offset(), odp_packet_l2_offset_set()
> >   */
> > -uint8_t *odp_packet_l2(odp_packet_t pkt);
> > +void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len);
> >
> >  /**
> > - * Return the byte offset from the packet buffer to the L2 frame
> > + * Layer 2 start offset
> > + *
> > + * Returns offset to the start of the layer 2 header. The offset is
> calculated
> > + * from the current odp_packet_data() position in bytes.
> > + *
> > + * User is responsible to update the offset when modifying the packet
> data
> > + * pointer position.
> >   *
> >   * @param pkt  Packet handle
> >   *
> > - * @return  L2 byte offset or ODP_PACKET_OFFSET_INVALID if not found
> > + * @return  Layer 2 start offset
> >   */
> > -size_t odp_packet_l2_offset(odp_packet_t pkt);
> > +uint32_t odp_packet_l2_offset(odp_packet_t pkt);
> >
> >  /**
> > - * Set the byte offset to the L2 frame
> > + * Set layer 2 start offset
> > + *
> > + * Set offset to the start of the layer 2 header. The offset is
> calculated from
> > + * the current odp_packet_data() position in bytes. Offset must not
> exceed
> > + * packet data length. Packet is not modified on an error.
> >   *
> >   * @param pkt     Packet handle
> > - * @param offset  L2 byte offset
> > + * @param offset  Layer 2 start offset (0 ... odp_packet_len()-1)
> > + *
> > + * @retval 0 Success
> > + * @retval Non-zero Failure
> >   */
> > -void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset);
> > -
> > +int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset);
> >
> >  /**
> > - * Get pointer to the start of the L3 packet
> > + * Layer 3 start pointer
> >   *
> > - * @param pkt  Packet handle
> > + * Returns pointer to the start of the layer 3 header. Optionally,
> outputs
> > + * number of data bytes in the segment following the pointer.
> > + *
> > + * @param      pkt      Packet handle
> > + * @param[out] len      Number of data bytes remaining in the segment
> (output).
> > + *                      Ignored when NULL.
> >   *
> > - * @return  Pointer to L3 packet or NULL if not found
> > + * @return  Layer 3 start pointer, or NULL
> >   *
> > + * @see odp_packet_l3_offset(), odp_packet_l3_offset_set()
> >   */
> > -uint8_t *odp_packet_l3(odp_packet_t pkt);
> > +void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len);
> >
> >  /**
> > - * Return the byte offset from the packet buffer to the L3 packet
> > + * Layer 3 start offset
> > + *
> > + * Returns offset to the start of the layer 3 header. The offset is
> calculated
> > + * from the current odp_packet_data() position in bytes.
> > + *
> > + * User is responsible to update the offset when modifying the packet
> data
> > + * pointer position.
> >   *
> >   * @param pkt  Packet handle
> >   *
> > - * @return  L3 byte offset or ODP_PACKET_OFFSET_INVALID if not found
> > + * @return  Layer 3 start offset or ODP_PACKET_OFFSET_INVALID if not
> found
>
> In the implementation we don't return ODP_PACKET_OFFSET_INVALID if it's
> not found?
> Shouldn't we do that?
>
> Cheers,
> Anders
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
diff mbox

Patch

diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
index 5ded85c..aec2275 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -189,13 +189,13 @@  static void pack_udp_pkt(odp_buffer_t obuf)
 
 	pkt = odp_packet_from_buffer(obuf);
 	/* ether */
-	odp_packet_set_l2_offset(pkt, 0);
+	odp_packet_l2_offset_set(pkt, 0);
 	eth = (odph_ethhdr_t *)buf;
 	memcpy((char *)eth->src.addr, args->appl.srcmac.addr, ODPH_ETHADDR_LEN);
 	memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, ODPH_ETHADDR_LEN);
 	eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
 	/* ip */
-	odp_packet_set_l3_offset(pkt, ODPH_ETHHDR_LEN);
+	odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
 	ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
 	ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip);
 	ip->src_addr = odp_cpu_to_be_32(args->appl.srcip);
@@ -208,7 +208,7 @@  static void pack_udp_pkt(odp_buffer_t obuf)
 	ip->chksum = 0;
 	odph_ipv4_csum_update(pkt);
 	/* udp */
-	odp_packet_set_l4_offset(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
+	odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
 	udp = (odph_udphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
 	udp->src_port = 0;
 	udp->dst_port = 0;
@@ -246,13 +246,13 @@  static void pack_icmp_pkt(odp_buffer_t obuf)
 	args->appl.payload = 56;
 	pkt = odp_packet_from_buffer(obuf);
 	/* ether */
-	odp_packet_set_l2_offset(pkt, 0);
+	odp_packet_l2_offset_set(pkt, 0);
 	eth = (odph_ethhdr_t *)buf;
 	memcpy((char *)eth->src.addr, args->appl.srcmac.addr, ODPH_ETHADDR_LEN);
 	memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, ODPH_ETHADDR_LEN);
 	eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
 	/* ip */
-	odp_packet_set_l3_offset(pkt, ODPH_ETHHDR_LEN);
+	odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
 	ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
 	ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip);
 	ip->src_addr = odp_cpu_to_be_32(args->appl.srcip);
diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
index cd73682..c6f7471 100644
--- a/example/ipsec/odp_ipsec.c
+++ b/example/ipsec/odp_ipsec.c
@@ -639,13 +639,14 @@  pkt_disposition_e do_input_verify(odp_packet_t pkt,
 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);
+	odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
 	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_ptr(pkt, NULL);
 
 		memcpy(&eth->dst, entry->dst_mac, ODPH_ETHADDR_LEN);
 		memcpy(&eth->src, entry->src_mac, ODPH_ETHADDR_LEN);
@@ -676,7 +677,7 @@  pkt_disposition_e do_ipsec_in_classify(odp_packet_t pkt,
 				       bool *skip)
 {
 	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_ptr(pkt, NULL);
 	int hdr_len;
 	odph_ahhdr_t *ah = NULL;
 	odph_esphdr_t *esp = NULL;
@@ -771,7 +772,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_ptr(pkt, NULL);
 
 	/*
 	 * Finish auth
@@ -836,7 +837,7 @@  pkt_disposition_e do_ipsec_out_classify(odp_packet_t pkt,
 					bool *skip)
 {
 	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_ptr(pkt, NULL);
 	uint16_t ip_data_len = ipv4_data_len(ip);
 	uint8_t *ip_data = ipv4_data_p(ip);
 	ipsec_cache_entry_t *entry;
@@ -1003,7 +1004,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_ptr(pkt, NULL);
 
 	/* Finalize the IPv4 header */
 	ip->ttl = ctx->ipsec.ip_ttl;
diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c
index 15cdb3d..93de198 100644
--- a/example/ipsec/odp_ipsec_stream.c
+++ b/example/ipsec/odp_ipsec_stream.c
@@ -195,7 +195,7 @@  odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
 
 	/* Ethernet */
 	odp_packet_has_eth_set(pkt, 1);
-	odp_packet_set_l2_offset(pkt, data - base);
+	odp_packet_l2_offset_set(pkt, data - base);
 	eth = (odph_ethhdr_t *)data;
 	data += sizeof(*eth);
 
@@ -205,10 +205,10 @@  odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
 
 	/* IPv4 */
 	odp_packet_has_ipv4_set(pkt, 1);
-	odp_packet_set_l3_offset(pkt, data - base);
+	odp_packet_l3_offset_set(pkt, data - base);
 	ip = (odph_ipv4hdr_t *)data;
 	data += sizeof(*ip);
-	odp_packet_set_l4_offset(pkt, data - base);
+	odp_packet_l4_offset_set(pkt, data - base);
 
 	/* Wait until almost finished to fill in mutable fields */
 	memset((char *)ip, 0, sizeof(*ip));
@@ -345,7 +345,7 @@  bool verify_ipv4_packet(stream_db_entry_t *stream,
 	stream_pkt_hdr_t *test;
 
 	/* Basic IPv4 verify (add checksum verification) */
-	data = odp_packet_l3(pkt);
+	data = odp_packet_l3_ptr(pkt, NULL);
 	ip = (odph_ipv4hdr_t *)data;
 	data += sizeof(*ip);
 	if (0x45 != ip->ver_ihl)
diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c
index 10b79d7..463042c 100644
--- a/example/packet/odp_pktio.c
+++ b/example/packet/odp_pktio.c
@@ -483,7 +483,7 @@  static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len)
 	for (i = 0; i < len; ++i) {
 		pkt = pkt_tbl[i];
 		if (odp_packet_has_eth(pkt)) {
-			eth = (odph_ethhdr_t *)odp_packet_l2(pkt);
+			eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
 
 			tmp_addr = eth->dst;
 			eth->dst = eth->src;
@@ -491,7 +491,8 @@  static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len)
 
 			if (odp_packet_has_ipv4(pkt)) {
 				/* IPv4 */
-				ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
+				ip = (odph_ipv4hdr_t *)
+					odp_packet_l3_ptr(pkt, NULL);
 
 				ip_tmp_addr  = ip->src_addr;
 				ip->src_addr = ip->dst_addr;
diff --git a/helper/include/odph_ip.h b/helper/include/odph_ip.h
index f78724e..16c8266 100644
--- a/helper/include/odph_ip.h
+++ b/helper/include/odph_ip.h
@@ -88,7 +88,7 @@  static inline int odph_ipv4_csum_valid(odp_packet_t pkt)
 	if (!odp_packet_l3_offset(pkt))
 		return 0;
 
-	memcpy(&ip, odp_packet_l3(pkt), sizeof(odph_ipv4hdr_t));
+	memcpy(&ip, odp_packet_l3_ptr(pkt, NULL), sizeof(odph_ipv4hdr_t));
 	w = (uint16_t *)(void *)&ip;
 	chksum = ip.chksum;
 	ip.chksum = 0x0;
@@ -116,7 +116,7 @@  static inline uint16sum_t odph_ipv4_csum_update(odp_packet_t pkt)
 	if (!odp_packet_l3_offset(pkt))
 		return 0;
 
-	ip = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
+	ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
 	w = (uint16_t *)(void *)ip;
 	ip->chksum = odp_chksum(w, nleft);
 	return ip->chksum;
diff --git a/helper/include/odph_udp.h b/helper/include/odph_udp.h
index b2eaf03..ef0cd4c 100644
--- a/helper/include/odph_udp.h
+++ b/helper/include/odph_udp.h
@@ -64,8 +64,8 @@  static inline uint16_t odph_ipv4_udp_chksum(odp_packet_t pkt)
 	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_ptr(pkt, NULL);
+	udph = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
 	udplen = odp_be_to_cpu_16(udph->length);
 
 	/* the source ip */
diff --git a/platform/linux-generic/include/api/odp_packet.h b/platform/linux-generic/include/api/odp_packet.h
index 9a15114..96e1474 100644
--- a/platform/linux-generic/include/api/odp_packet.h
+++ b/platform/linux-generic/include/api/odp_packet.h
@@ -180,10 +180,11 @@  uint8_t *odp_packet_addr(odp_packet_t pkt);
 size_t odp_packet_buf_size(odp_packet_t pkt);
 
 /**
- * Packet data address
+ * Packet data pointer
  *
- * Returns the current packet data address. When a packet is received from
- * packet input, the data address points to the first byte of the packet.
+ * Returns the current packet data pointer. When a packet is received
+ * from packet input, this points to the first byte of the received
+ * packet. Packet level offsets are calculated relative to this position.
  *
  * @param pkt  Packet handle
  *
@@ -191,94 +192,145 @@  size_t odp_packet_buf_size(odp_packet_t pkt);
  *
  * @see odp_packet_l2(), odp_packet_addr()
  */
-uint8_t *odp_packet_data(odp_packet_t pkt);
+void *odp_packet_data(odp_packet_t pkt);
 
 /**
- * Get pointer to the start of the L2 frame
+ * Layer 2 start pointer
  *
- * The L2 frame header address is not necessarily the same as the address of the
- * packet buffer, see odp_packet_addr()
+ * Returns pointer to the start of the layer 2 header. Optionally, outputs
+ * number of data bytes in the segment following the pointer.
  *
- * @param pkt  Packet handle
+ * @param      pkt      Packet handle
+ * @param[out] len      Number of data bytes remaining in the segment (output).
+ *                      Ignored when NULL.
  *
- * @return  Pointer to L2 header or NULL if not found
+ * @return  Layer 2 start pointer, or offset 0 by default
  *
- * @see odp_packet_addr(), odp_packet_data()
+ * @see odp_packet_l2_offset(), odp_packet_l2_offset_set()
  */
-uint8_t *odp_packet_l2(odp_packet_t pkt);
+void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len);
 
 /**
- * Return the byte offset from the packet buffer to the L2 frame
+ * Layer 2 start offset
+ *
+ * Returns offset to the start of the layer 2 header. The offset is calculated
+ * from the current odp_packet_data() position in bytes.
+ *
+ * User is responsible to update the offset when modifying the packet data
+ * pointer position.
  *
  * @param pkt  Packet handle
  *
- * @return  L2 byte offset or ODP_PACKET_OFFSET_INVALID if not found
+ * @return  Layer 2 start offset
  */
-size_t odp_packet_l2_offset(odp_packet_t pkt);
+uint32_t odp_packet_l2_offset(odp_packet_t pkt);
 
 /**
- * Set the byte offset to the L2 frame
+ * Set layer 2 start offset
+ *
+ * Set offset to the start of the layer 2 header. The offset is calculated from
+ * the current odp_packet_data() position in bytes. Offset must not exceed
+ * packet data length. Packet is not modified on an error.
  *
  * @param pkt     Packet handle
- * @param offset  L2 byte offset
+ * @param offset  Layer 2 start offset (0 ... odp_packet_len()-1)
+ *
+ * @retval 0 Success
+ * @retval Non-zero Failure
  */
-void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset);
-
+int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset);
 
 /**
- * Get pointer to the start of the L3 packet
+ * Layer 3 start pointer
  *
- * @param pkt  Packet handle
+ * Returns pointer to the start of the layer 3 header. Optionally, outputs
+ * number of data bytes in the segment following the pointer.
+ *
+ * @param      pkt      Packet handle
+ * @param[out] len      Number of data bytes remaining in the segment (output).
+ *                      Ignored when NULL.
  *
- * @return  Pointer to L3 packet or NULL if not found
+ * @return  Layer 3 start pointer, or NULL
  *
+ * @see odp_packet_l3_offset(), odp_packet_l3_offset_set()
  */
-uint8_t *odp_packet_l3(odp_packet_t pkt);
+void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len);
 
 /**
- * Return the byte offset from the packet buffer to the L3 packet
+ * Layer 3 start offset
+ *
+ * Returns offset to the start of the layer 3 header. The offset is calculated
+ * from the current odp_packet_data() position in bytes.
+ *
+ * User is responsible to update the offset when modifying the packet data
+ * pointer position.
  *
  * @param pkt  Packet handle
  *
- * @return  L3 byte offset or ODP_PACKET_OFFSET_INVALID if not found
+ * @return  Layer 3 start offset or ODP_PACKET_OFFSET_INVALID if not found
  */
-size_t odp_packet_l3_offset(odp_packet_t pkt);
+uint32_t odp_packet_l3_offset(odp_packet_t pkt);
 
 /**
- * Set the byte offset to the L3 packet
+ * Set layer 3 start offset
+ *
+ * Set offset to the start of the layer 3 header. The offset is calculated from
+ * the current odp_packet_data() position in bytes. Offset must not exceed
+ * packet data length. Packet is not modified on an error.
  *
  * @param pkt     Packet handle
- * @param offset  L3 byte offset
+ * @param offset  Layer 3 start offset (0 ... odp_packet_len()-1)
+ *
+ * @retval 0 Success
+ * @retval Non-zero Failure
  */
-void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset);
-
+int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset);
 
 /**
- * Get pointer to the start of the L4 packet
+ * Layer 4 start pointer
  *
- * @param pkt  Packet handle
+ * Returns pointer to the start of the layer 4 header. Optionally, outputs
+ * number of data bytes in the segment following the pointer.
+ *
+ * @param      pkt      Packet handle
+ * @param[out] len      Number of data bytes remaining in the segment (output).
+ *                      Ignored when NULL.
  *
- * @return  Pointer to L4 packet or NULL if not found
+ * @return  Layer 4 start pointer, or NULL
  *
+ * @see odp_packet_l4_offset(), odp_packet_l4_offset_set()
  */
-uint8_t *odp_packet_l4(odp_packet_t pkt);
+void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len);
 
 /**
- * Return the byte offset from the packet buffer to the L4 packet
+ * Layer 4 start offset
+ *
+ * Returns offset to the start of the layer 4 header. The offset is calculated
+ * from the current odp_packet_data() position in bytes.
+ *
+ * User is responsible to update the offset when modifying the packet data
+ * pointer position.
  *
  * @param pkt  Packet handle
  *
- * @return  L4 byte offset or ODP_PACKET_OFFSET_INVALID if not found
+ * @return  Layer 4 start offset or ODP_PACKET_OFFSET_INVALID if not found
  */
-size_t odp_packet_l4_offset(odp_packet_t pkt);
+uint32_t odp_packet_l4_offset(odp_packet_t pkt);
 
 /**
- * Set the byte offset to the L4 packet
+ * Set layer 4 start offset
+ *
+ * Set offset to the start of the layer 4 header. The offset is calculated from
+ * the current odp_packet_data() position in bytes. Offset must not exceed
+ * packet data length. Packet is not modified on an error.
  *
  * @param pkt     Packet handle
- * @param offset  L4 byte offset
+ * @param offset  Layer 4 start offset (0 ... odp_packet_len()-1)
+ *
+ * @retval 0 Success
+ * @retval Non-zero Failure
  */
-void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset);
+int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset);
 
 /**
  * Print (debug) information about the packet
diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h
index 9553f13..fbaaa5f 100644
--- a/platform/linux-generic/include/odp_packet_internal.h
+++ b/platform/linux-generic/include/odp_packet_internal.h
@@ -169,6 +169,17 @@  static inline void packet_init(pool_entry_t *pool,
 		(pool->s.headroom + size);
 }
 
+static inline void *packet_map(odp_packet_hdr_t *pkt_hdr,
+			       uint32_t offset, uint32_t *seglen)
+{
+	if (offset > pkt_hdr->frame_len)
+		return NULL;
+
+	return buffer_map(&pkt_hdr->buf_hdr,
+			  pkt_hdr->headroom + offset, seglen,
+			  pkt_hdr->headroom + pkt_hdr->frame_len);
+}
+
 odp_packet_t _odp_packet_alloc(odp_buffer_pool_t pool_hdl);
 
 #ifdef __cplusplus
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index a4ad3e8..783714b 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -93,75 +93,81 @@  size_t odp_packet_get_len(odp_packet_t pkt)
 
 uint8_t *odp_packet_addr(odp_packet_t pkt)
 {
-	return odp_buffer_addr(odp_packet_to_buffer(pkt));
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+	return buffer_map(&pkt_hdr->buf_hdr, 0, NULL, 0);
 }
 
-uint8_t *odp_packet_data(odp_packet_t pkt)
+void *odp_packet_data(odp_packet_t pkt)
 {
-	return odp_packet_addr(pkt) + odp_packet_hdr(pkt)->headroom;
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+	return packet_map(pkt_hdr, 0, NULL);
 }
 
-
-uint8_t *odp_packet_l2(odp_packet_t pkt)
+void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
 {
-	const size_t offset = odp_packet_l2_offset(pkt);
-
-	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
-		return NULL;
-
-	return odp_packet_addr(pkt) + offset;
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+	return packet_map(pkt_hdr, pkt_hdr->l2_offset, len);
 }
 
-size_t odp_packet_l2_offset(odp_packet_t pkt)
+uint32_t odp_packet_l2_offset(odp_packet_t pkt)
 {
 	return odp_packet_hdr(pkt)->l2_offset;
 }
 
-void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset)
-{
-	odp_packet_hdr(pkt)->l2_offset = offset;
-}
-
-uint8_t *odp_packet_l3(odp_packet_t pkt)
+int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset)
 {
-	const size_t offset = odp_packet_l3_offset(pkt);
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 
-	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
-		return NULL;
+	if (offset >= pkt_hdr->frame_len)
+		return -1;
 
-	return odp_packet_addr(pkt) + offset;
+	pkt_hdr->l2_offset = offset;
+	return 0;
 }
 
-size_t odp_packet_l3_offset(odp_packet_t pkt)
+void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
 {
-	return odp_packet_hdr(pkt)->l3_offset;
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+	return packet_map(pkt_hdr, pkt_hdr->l3_offset, len);
 }
 
-void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset)
+uint32_t odp_packet_l3_offset(odp_packet_t pkt)
 {
-	odp_packet_hdr(pkt)->l3_offset = offset;
+	return odp_packet_hdr(pkt)->l3_offset;
 }
 
-uint8_t *odp_packet_l4(odp_packet_t pkt)
+int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset)
 {
-	const size_t offset = odp_packet_l4_offset(pkt);
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 
-	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
-		return NULL;
+	if (offset >= pkt_hdr->frame_len)
+		return -1;
 
-	return odp_packet_addr(pkt) + offset;
+	pkt_hdr->l3_offset = offset;
+	return 0;
 }
 
-size_t odp_packet_l4_offset(odp_packet_t pkt)
+void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len)
 {
-	return odp_packet_hdr(pkt)->l4_offset;
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+	return packet_map(pkt_hdr, pkt_hdr->l4_offset, len);
 }
 
-void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset)
+uint32_t odp_packet_l4_offset(odp_packet_t pkt)
 {
-	odp_packet_hdr(pkt)->l4_offset = offset;
+	return odp_packet_hdr(pkt)->l4_offset;
 }
 
+int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset)
+{
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+
+	if (offset >= pkt_hdr->frame_len)
+		return -1;
+
+	pkt_hdr->l4_offset = offset;
+	return 0;
+}
 
 int odp_packet_is_segmented(odp_packet_t pkt)
 {
@@ -230,14 +236,14 @@  void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset)
 		pkt_hdr->input_flags.ipv4 = 1;
 		pkt_hdr->input_flags.l3 = 1;
 		pkt_hdr->l3_offset = frame_offset + ODPH_ETHHDR_LEN + offset;
-		ipv4 = (odph_ipv4hdr_t *)odp_packet_l3(pkt);
+		ipv4 = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
 		ip_proto = parse_ipv4(pkt_hdr, ipv4, &offset);
 		break;
 	case ODPH_ETHTYPE_IPV6:
 		pkt_hdr->input_flags.ipv6 = 1;
 		pkt_hdr->input_flags.l3 = 1;
 		pkt_hdr->l3_offset = frame_offset + ODPH_ETHHDR_LEN + offset;
-		ipv6 = (odph_ipv6hdr_t *)odp_packet_l3(pkt);
+		ipv6 = (odph_ipv6hdr_t *)odp_packet_l3_ptr(pkt, NULL);
 		ip_proto = parse_ipv6(pkt_hdr, ipv6, &offset);
 		break;
 	case ODPH_ETHTYPE_ARP:
diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c
index 76e437a..ead5d2f 100644
--- a/platform/linux-generic/odp_packet_socket.c
+++ b/platform/linux-generic/odp_packet_socket.c
@@ -372,7 +372,7 @@  int send_pkt_sock_basic(pkt_sock_t *const pkt_sock,
 {
 	odp_packet_t pkt;
 	uint8_t *frame;
-	size_t frame_len;
+	uint32_t frame_len;
 	unsigned i;
 	unsigned flags;
 	int sockfd;
@@ -385,8 +385,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_l2_ptr(pkt, &frame_len);
 
 		ret = send(sockfd, frame, frame_len, flags);
 		if (odp_unlikely(ret == -1)) {
@@ -492,10 +491,9 @@  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]);
-		iovecs[i].iov_base = frame;
-		iovecs[i].iov_len = frame_len;
+		uint32_t seglen;
+		iovecs[i].iov_base = odp_packet_l2_ptr(pkt_table[i], &seglen);
+		iovecs[i].iov_len = seglen;
 		msgvec[i].msg_hdr.msg_iov = &iovecs[i];
 		msgvec[i].msg_hdr.msg_iovlen = 1;
 	}
@@ -635,7 +633,7 @@  static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring,
 {
 	union frame_map ppd;
 	uint8_t *pkt_buf;
-	size_t pkt_len;
+	uint32_t pkt_len;
 	unsigned frame_num, next_frame_num;
 	int ret;
 	unsigned i = 0;
@@ -648,8 +646,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_l2_ptr(pkt_table[i], &pkt_len);
 
 			ppd.v2->tp_h.tp_snaplen = pkt_len;
 			ppd.v2->tp_h.tp_len = pkt_len;