diff mbox

[4/7] ODP Packet: L2,L3,L4-header access func retval change

Message ID 1392639281-2753-5-git-send-email-carl.wallen@linaro.org
State Accepted, archived
Commit a407fa2d23166d6d6b39922679728e75d9d92705
Headers show

Commit Message

Carl Wallen Feb. 17, 2014, 12:14 p.m. UTC
odp_packet_l2/l3/l4_offset() returns ODP_PACKET_OFFSET_INVALID
if no known header is found.
odp_packet_l2/l3/l4() returns NULL if no known header is found.

Signed-off-by: Carl Wallen <carl.wallen@linaro.org>
---
 include/odp_packet.h                       | 46 ++++++++++++++++++++++--------
 platform/linux-generic/source/odp_packet.c | 30 +++++++++++++++++--
 2 files changed, 61 insertions(+), 15 deletions(-)

Comments

Anders Roxell Feb. 17, 2014, 1:36 p.m. UTC | #1
On 2014-02-17 14:14, Carl Wallen wrote:
> odp_packet_l2/l3/l4_offset() returns ODP_PACKET_OFFSET_INVALID
> if no known header is found.
> odp_packet_l2/l3/l4() returns NULL if no known header is found.
> 
> Signed-off-by: Carl Wallen <carl.wallen@linaro.org>
> ---
>  include/odp_packet.h                       | 46 ++++++++++++++++++++++--------
>  platform/linux-generic/source/odp_packet.c | 30 +++++++++++++++++--
>  2 files changed, 61 insertions(+), 15 deletions(-)
> 
> diff --git a/include/odp_packet.h b/include/odp_packet.h
> index 4de4db2..0b693d9 100644
> --- a/include/odp_packet.h
> +++ b/include/odp_packet.h
> @@ -27,6 +27,8 @@ extern "C" {
>  typedef uint32_t odp_packet_t;
>  
>  #define ODP_PACKET_INVALID ODP_BUFFER_INVALID
> +#define ODP_PACKET_OFFSET_INVALID ((size_t)-1)
> +
>  
>  /**
>   * Initialize the packet
> @@ -74,21 +76,41 @@ void odp_packet_set_len(odp_packet_t pkt, size_t len);
>  size_t odp_packet_get_len(odp_packet_t pkt);
>  
>  /**
> - * Get pointer to the start of the packet buffer
> + * Get address to the start of the packet buffer
>   *
> - * The start address of the packet buffer is not necessarily the same as the
> - * start address of a received frame, e.g. an eth frame may be offset by 2 or 6
> + * The address of the packet buffer is not necessarily the same as the start
> + * address of the received frame, e.g. an eth frame may be offset by 2 or 6
>   * bytes to ensure 32 or 64-bit alignment of the IP header.
> - * Use odp_packet_l2(pkt) to get the start address of a received frame.
> + * Use odp_packet_l2(pkt) to get the start address of a received valid frame
> + * or odp_packet_start(pkt) to get the start address even if no valid L2 header
> + * could be found.
>   *
>   * @param pkt  Packet handle
>   *
>   * @return  Pointer to the start of the packet buffer
>   *
> - * @see odp_packet_l2()
> + * @see odp_packet_l2(), odp_packet_start()
>   */
>  uint8_t *odp_packet_buf_addr(odp_packet_t pkt);
>  
> +/**
> + * Get pointer to the start of the received frame
> + *
> + * The address of the packet buffer is not necessarily the same as the start
> + * address of the received frame, e.g. an eth frame may be offset by 2 or 6
> + * bytes to ensure 32 or 64-bit alignment of the IP header.
> + * Use odp_packet_l2(pkt) to get the start address of a received valid eth frame
> + *
> + * odp_packet_start() will always return a pointer to the start of the frame,
> + * even if the frame is unrecognized and no valid L2 header could be found.
> + *
> + * @param pkt  Packet handle
> + *
> + * @return  Pointer to the start of the received frame
> + *
> + * @see odp_packet_l2(), odp_packet_buf_addr()
> + */
> +uint8_t *odp_packet_start(odp_packet_t pkt);
>  
>  /**
>   * Get pointer to the start of the L2 frame
> @@ -98,9 +120,9 @@ uint8_t *odp_packet_buf_addr(odp_packet_t pkt);
>   *
>   * @param pkt  Packet handle
>   *
> - * @return  Pointer to L2 header
> + * @return  Pointer to L2 header or NULL if not found
>   *
> - * @see odp_packet_buf_addr()
> + * @see odp_packet_buf_addr(), odp_packet_start()
>   */
>  uint8_t *odp_packet_l2(odp_packet_t pkt);
>  
> @@ -109,7 +131,7 @@ uint8_t *odp_packet_l2(odp_packet_t pkt);
>   *
>   * @param pkt  Packet handle
>   *
> - * @return  L2 byte offset
> + * @return  L2 byte offset or ODP_PACKET_OFFSET_INVALID if not found
>   */
>  size_t odp_packet_l2_offset(odp_packet_t pkt);
>  
> @@ -127,7 +149,7 @@ void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset);
>   *
>   * @param pkt  Packet handle
>   *
> - * @return  Pointer to L3 packet
> + * @return  Pointer to L3 packet or NULL if not found
>   *
>   */
>  uint8_t *odp_packet_l3(odp_packet_t pkt);
> @@ -137,7 +159,7 @@ uint8_t *odp_packet_l3(odp_packet_t pkt);
>   *
>   * @param pkt  Packet handle
>   *
> - * @return  L3 byte offset
> + * @return  L3 byte offset or ODP_PACKET_OFFSET_INVALID if not found
>   */
>  size_t odp_packet_l3_offset(odp_packet_t pkt);
>  
> @@ -155,7 +177,7 @@ void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset);
>   *
>   * @param pkt  Packet handle
>   *
> - * @return  Pointer to L4 packet
> + * @return  Pointer to L4 packet or NULL if not found
>   *
>   */
>  uint8_t *odp_packet_l4(odp_packet_t pkt);
> @@ -165,7 +187,7 @@ uint8_t *odp_packet_l4(odp_packet_t pkt);
>   *
>   * @param pkt  Packet handle
>   *
> - * @return  L4 byte offset
> + * @return  L4 byte offset or ODP_PACKET_OFFSET_INVALID if not found
>   */
>  size_t odp_packet_l4_offset(odp_packet_t pkt);
>  
> diff --git a/platform/linux-generic/source/odp_packet.c b/platform/linux-generic/source/odp_packet.c
> index 6ee2c5b..060d82e 100644
> --- a/platform/linux-generic/source/odp_packet.c
> +++ b/platform/linux-generic/source/odp_packet.c
> @@ -25,6 +25,10 @@ void odp_packet_init(odp_packet_t pkt)
>  	start = (uint8_t *)pkt_hdr + start_offset;
>  	len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset;
>  	memset(start, 0, len);
> +
> +	pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
> +	pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
> +	pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
>  }
>  
>  odp_packet_t odp_packet_from_buffer(odp_buffer_t buf)
> @@ -52,10 +56,20 @@ uint8_t *odp_packet_buf_addr(odp_packet_t pkt)
>  	return odp_buffer_addr(odp_buffer_from_packet(pkt));
>  }
>  
> +uint8_t *odp_packet_start(odp_packet_t pkt)
> +{
> +	return odp_packet_buf_addr(pkt) + odp_packet_hdr(pkt)->frame_offset;
> +}
> +
>  
>  uint8_t *odp_packet_l2(odp_packet_t pkt)
>  {
> -	return odp_packet_buf_addr(pkt) + odp_packet_l2_offset(pkt);
> +	const size_t offset = odp_packet_l2_offset(pkt);
> +
> +	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
> +		return NULL;

Should we add ODP_ERR(...) before "return NULL;"?


> +
> +	return odp_packet_buf_addr(pkt) + offset;
>  }
>  
>  size_t odp_packet_l2_offset(odp_packet_t pkt)
> @@ -71,7 +85,12 @@ void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset)
>  
>  uint8_t *odp_packet_l3(odp_packet_t pkt)
>  {
> -	return odp_packet_buf_addr(pkt) + odp_packet_l3_offset(pkt);
> +	const size_t offset = odp_packet_l3_offset(pkt);
> +
> +	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
> +		return NULL;

and here.

> +
> +	return odp_packet_buf_addr(pkt) + offset;
>  }
>  
>  size_t odp_packet_l3_offset(odp_packet_t pkt)
> @@ -87,7 +106,12 @@ void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset)
>  
>  uint8_t *odp_packet_l4(odp_packet_t pkt)
>  {
> -	return odp_packet_buf_addr(pkt) + odp_packet_l4_offset(pkt);
> +	const size_t offset = odp_packet_l4_offset(pkt);
> +
> +	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
> +		return NULL;

and here.


Cheers,

> +
> +	return odp_packet_buf_addr(pkt) + offset;
>  }
>  
>  size_t odp_packet_l4_offset(odp_packet_t pkt)
> -- 
> 1.8.5.3
> 
> -- 
> You received this message because you are subscribed to the Google Groups "LNG ODP Sub-team - lng-odp@linaro.org" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lng-odp+unsubscribe@linaro.org.
> To post to this group, send email to lng-odp@linaro.org.
> Visit this group at http://groups.google.com/a/linaro.org/group/lng-odp/.
> To view this discussion on the web visit https://groups.google.com/a/linaro.org/d/msgid/lng-odp/1392639281-2753-5-git-send-email-carl.wallen%40linaro.org.
> For more options, visit https://groups.google.com/a/linaro.org/groups/opt_out.
Carl Wallen Feb. 18, 2014, 7:42 a.m. UTC | #2
On 17.2.2014 15:36, Anders Roxell wrote:
> On 2014-02-17 14:14, Carl Wallen wrote:
>> odp_packet_l2/l3/l4_offset() returns ODP_PACKET_OFFSET_INVALID
>> if no known header is found.
>> odp_packet_l2/l3/l4() returns NULL if no known header is found.
>>
>> Signed-off-by: Carl Wallen <carl.wallen@linaro.org>
>> ---
>>  include/odp_packet.h                       | 46 ++++++++++++++++++++++--------
>>  platform/linux-generic/source/odp_packet.c | 30 +++++++++++++++++--
>>  2 files changed, 61 insertions(+), 15 deletions(-)
>>
>> diff --git a/include/odp_packet.h b/include/odp_packet.h
>> index 4de4db2..0b693d9 100644
>> --- a/include/odp_packet.h
>> +++ b/include/odp_packet.h
>> @@ -27,6 +27,8 @@ extern "C" {
>>  typedef uint32_t odp_packet_t;
>>  
>>  #define ODP_PACKET_INVALID ODP_BUFFER_INVALID
>> +#define ODP_PACKET_OFFSET_INVALID ((size_t)-1)
>> +
>>  
>>  /**
>>   * Initialize the packet
>> @@ -74,21 +76,41 @@ void odp_packet_set_len(odp_packet_t pkt, size_t len);
>>  size_t odp_packet_get_len(odp_packet_t pkt);
>>  
>>  /**
>> - * Get pointer to the start of the packet buffer
>> + * Get address to the start of the packet buffer
>>   *
>> - * The start address of the packet buffer is not necessarily the same as the
>> - * start address of a received frame, e.g. an eth frame may be offset by 2 or 6
>> + * The address of the packet buffer is not necessarily the same as the start
>> + * address of the received frame, e.g. an eth frame may be offset by 2 or 6
>>   * bytes to ensure 32 or 64-bit alignment of the IP header.
>> - * Use odp_packet_l2(pkt) to get the start address of a received frame.
>> + * Use odp_packet_l2(pkt) to get the start address of a received valid frame
>> + * or odp_packet_start(pkt) to get the start address even if no valid L2 header
>> + * could be found.
>>   *
>>   * @param pkt  Packet handle
>>   *
>>   * @return  Pointer to the start of the packet buffer
>>   *
>> - * @see odp_packet_l2()
>> + * @see odp_packet_l2(), odp_packet_start()
>>   */
>>  uint8_t *odp_packet_buf_addr(odp_packet_t pkt);
>>  
>> +/**
>> + * Get pointer to the start of the received frame
>> + *
>> + * The address of the packet buffer is not necessarily the same as the start
>> + * address of the received frame, e.g. an eth frame may be offset by 2 or 6
>> + * bytes to ensure 32 or 64-bit alignment of the IP header.
>> + * Use odp_packet_l2(pkt) to get the start address of a received valid eth frame
>> + *
>> + * odp_packet_start() will always return a pointer to the start of the frame,
>> + * even if the frame is unrecognized and no valid L2 header could be found.
>> + *
>> + * @param pkt  Packet handle
>> + *
>> + * @return  Pointer to the start of the received frame
>> + *
>> + * @see odp_packet_l2(), odp_packet_buf_addr()
>> + */
>> +uint8_t *odp_packet_start(odp_packet_t pkt);
>>  
>>  /**
>>   * Get pointer to the start of the L2 frame
>> @@ -98,9 +120,9 @@ uint8_t *odp_packet_buf_addr(odp_packet_t pkt);
>>   *
>>   * @param pkt  Packet handle
>>   *
>> - * @return  Pointer to L2 header
>> + * @return  Pointer to L2 header or NULL if not found
>>   *
>> - * @see odp_packet_buf_addr()
>> + * @see odp_packet_buf_addr(), odp_packet_start()
>>   */
>>  uint8_t *odp_packet_l2(odp_packet_t pkt);
>>  
>> @@ -109,7 +131,7 @@ uint8_t *odp_packet_l2(odp_packet_t pkt);
>>   *
>>   * @param pkt  Packet handle
>>   *
>> - * @return  L2 byte offset
>> + * @return  L2 byte offset or ODP_PACKET_OFFSET_INVALID if not found
>>   */
>>  size_t odp_packet_l2_offset(odp_packet_t pkt);
>>  
>> @@ -127,7 +149,7 @@ void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset);
>>   *
>>   * @param pkt  Packet handle
>>   *
>> - * @return  Pointer to L3 packet
>> + * @return  Pointer to L3 packet or NULL if not found
>>   *
>>   */
>>  uint8_t *odp_packet_l3(odp_packet_t pkt);
>> @@ -137,7 +159,7 @@ uint8_t *odp_packet_l3(odp_packet_t pkt);
>>   *
>>   * @param pkt  Packet handle
>>   *
>> - * @return  L3 byte offset
>> + * @return  L3 byte offset or ODP_PACKET_OFFSET_INVALID if not found
>>   */
>>  size_t odp_packet_l3_offset(odp_packet_t pkt);
>>  
>> @@ -155,7 +177,7 @@ void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset);
>>   *
>>   * @param pkt  Packet handle
>>   *
>> - * @return  Pointer to L4 packet
>> + * @return  Pointer to L4 packet or NULL if not found
>>   *
>>   */
>>  uint8_t *odp_packet_l4(odp_packet_t pkt);
>> @@ -165,7 +187,7 @@ uint8_t *odp_packet_l4(odp_packet_t pkt);
>>   *
>>   * @param pkt  Packet handle
>>   *
>> - * @return  L4 byte offset
>> + * @return  L4 byte offset or ODP_PACKET_OFFSET_INVALID if not found
>>   */
>>  size_t odp_packet_l4_offset(odp_packet_t pkt);
>>  
>> diff --git a/platform/linux-generic/source/odp_packet.c b/platform/linux-generic/source/odp_packet.c
>> index 6ee2c5b..060d82e 100644
>> --- a/platform/linux-generic/source/odp_packet.c
>> +++ b/platform/linux-generic/source/odp_packet.c
>> @@ -25,6 +25,10 @@ void odp_packet_init(odp_packet_t pkt)
>>  	start = (uint8_t *)pkt_hdr + start_offset;
>>  	len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset;
>>  	memset(start, 0, len);
>> +
>> +	pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
>> +	pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
>> +	pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
>>  }
>>  
>>  odp_packet_t odp_packet_from_buffer(odp_buffer_t buf)
>> @@ -52,10 +56,20 @@ uint8_t *odp_packet_buf_addr(odp_packet_t pkt)
>>  	return odp_buffer_addr(odp_buffer_from_packet(pkt));
>>  }
>>  
>> +uint8_t *odp_packet_start(odp_packet_t pkt)
>> +{
>> +	return odp_packet_buf_addr(pkt) + odp_packet_hdr(pkt)->frame_offset;
>> +}
>> +
>>  
>>  uint8_t *odp_packet_l2(odp_packet_t pkt)
>>  {
>> -	return odp_packet_buf_addr(pkt) + odp_packet_l2_offset(pkt);
>> +	const size_t offset = odp_packet_l2_offset(pkt);
>> +
>> +	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
>> +		return NULL;
> 
> Should we add ODP_ERR(...) before "return NULL;"?

No. It's not an error that pre-classification did not recognize L2, L3
or L4 in the packet. It just means that the packet contains something else.
Currently if L2 is not ethernet its not set, if L3 is not IP it's not
set, if L4 is not TCP,UDP,SCTP (or ICMP) it's not set, but the packet
may still be valid.

E.g. a proprietary protocol on top of ethernet will have L2 set but L3
and L4 will not be set, thus the funcs should return NULL without an error.

> 
>> +
>> +	return odp_packet_buf_addr(pkt) + offset;
>>  }
>>  
>>  size_t odp_packet_l2_offset(odp_packet_t pkt)
>> @@ -71,7 +85,12 @@ void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset)
>>  
>>  uint8_t *odp_packet_l3(odp_packet_t pkt)
>>  {
>> -	return odp_packet_buf_addr(pkt) + odp_packet_l3_offset(pkt);
>> +	const size_t offset = odp_packet_l3_offset(pkt);
>> +
>> +	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
>> +		return NULL;
> 
> and here.
> 
>> +
>> +	return odp_packet_buf_addr(pkt) + offset;
>>  }
>>  
>>  size_t odp_packet_l3_offset(odp_packet_t pkt)
>> @@ -87,7 +106,12 @@ void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset)
>>  
>>  uint8_t *odp_packet_l4(odp_packet_t pkt)
>>  {
>> -	return odp_packet_buf_addr(pkt) + odp_packet_l4_offset(pkt);
>> +	const size_t offset = odp_packet_l4_offset(pkt);
>> +
>> +	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
>> +		return NULL;
> 
> and here.
> 
> 
> Cheers,
> 
>> +
>> +	return odp_packet_buf_addr(pkt) + offset;
>>  }
>>  
>>  size_t odp_packet_l4_offset(odp_packet_t pkt)
>> -- 
>> 1.8.5.3
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups "LNG ODP Sub-team - lng-odp@linaro.org" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to lng-odp+unsubscribe@linaro.org.
>> To post to this group, send email to lng-odp@linaro.org.
>> Visit this group at http://groups.google.com/a/linaro.org/group/lng-odp/.
>> To view this discussion on the web visit https://groups.google.com/a/linaro.org/d/msgid/lng-odp/1392639281-2753-5-git-send-email-carl.wallen%40linaro.org.
>> For more options, visit https://groups.google.com/a/linaro.org/groups/opt_out.
>
Anders Roxell Feb. 18, 2014, 9:24 a.m. UTC | #3
On 2014-02-18 09:42, Carl Wallen wrote:
> On 17.2.2014 15:36, Anders Roxell wrote:
> > On 2014-02-17 14:14, Carl Wallen wrote:
> >> odp_packet_l2/l3/l4_offset() returns ODP_PACKET_OFFSET_INVALID
> >> if no known header is found.
> >> odp_packet_l2/l3/l4() returns NULL if no known header is found.
> >>
> >> Signed-off-by: Carl Wallen <carl.wallen@linaro.org>
> >> ---
> >>  include/odp_packet.h                       | 46 ++++++++++++++++++++++--------
> >>  platform/linux-generic/source/odp_packet.c | 30 +++++++++++++++++--
> >>  2 files changed, 61 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/include/odp_packet.h b/include/odp_packet.h
> >> index 4de4db2..0b693d9 100644
> >> --- a/include/odp_packet.h
> >> +++ b/include/odp_packet.h
> >> @@ -27,6 +27,8 @@ extern "C" {
> >>  typedef uint32_t odp_packet_t;
> >>  
> >>  #define ODP_PACKET_INVALID ODP_BUFFER_INVALID
> >> +#define ODP_PACKET_OFFSET_INVALID ((size_t)-1)
> >> +
> >>  
> >>  /**
> >>   * Initialize the packet
> >> @@ -74,21 +76,41 @@ void odp_packet_set_len(odp_packet_t pkt, size_t len);
> >>  size_t odp_packet_get_len(odp_packet_t pkt);
> >>  
> >>  /**
> >> - * Get pointer to the start of the packet buffer
> >> + * Get address to the start of the packet buffer
> >>   *
> >> - * The start address of the packet buffer is not necessarily the same as the
> >> - * start address of a received frame, e.g. an eth frame may be offset by 2 or 6
> >> + * The address of the packet buffer is not necessarily the same as the start
> >> + * address of the received frame, e.g. an eth frame may be offset by 2 or 6
> >>   * bytes to ensure 32 or 64-bit alignment of the IP header.
> >> - * Use odp_packet_l2(pkt) to get the start address of a received frame.
> >> + * Use odp_packet_l2(pkt) to get the start address of a received valid frame
> >> + * or odp_packet_start(pkt) to get the start address even if no valid L2 header
> >> + * could be found.
> >>   *
> >>   * @param pkt  Packet handle
> >>   *
> >>   * @return  Pointer to the start of the packet buffer
> >>   *
> >> - * @see odp_packet_l2()
> >> + * @see odp_packet_l2(), odp_packet_start()
> >>   */
> >>  uint8_t *odp_packet_buf_addr(odp_packet_t pkt);
> >>  
> >> +/**
> >> + * Get pointer to the start of the received frame
> >> + *
> >> + * The address of the packet buffer is not necessarily the same as the start
> >> + * address of the received frame, e.g. an eth frame may be offset by 2 or 6
> >> + * bytes to ensure 32 or 64-bit alignment of the IP header.
> >> + * Use odp_packet_l2(pkt) to get the start address of a received valid eth frame
> >> + *
> >> + * odp_packet_start() will always return a pointer to the start of the frame,
> >> + * even if the frame is unrecognized and no valid L2 header could be found.
> >> + *
> >> + * @param pkt  Packet handle
> >> + *
> >> + * @return  Pointer to the start of the received frame
> >> + *
> >> + * @see odp_packet_l2(), odp_packet_buf_addr()
> >> + */
> >> +uint8_t *odp_packet_start(odp_packet_t pkt);
> >>  
> >>  /**
> >>   * Get pointer to the start of the L2 frame
> >> @@ -98,9 +120,9 @@ uint8_t *odp_packet_buf_addr(odp_packet_t pkt);
> >>   *
> >>   * @param pkt  Packet handle
> >>   *
> >> - * @return  Pointer to L2 header
> >> + * @return  Pointer to L2 header or NULL if not found
> >>   *
> >> - * @see odp_packet_buf_addr()
> >> + * @see odp_packet_buf_addr(), odp_packet_start()
> >>   */
> >>  uint8_t *odp_packet_l2(odp_packet_t pkt);
> >>  
> >> @@ -109,7 +131,7 @@ uint8_t *odp_packet_l2(odp_packet_t pkt);
> >>   *
> >>   * @param pkt  Packet handle
> >>   *
> >> - * @return  L2 byte offset
> >> + * @return  L2 byte offset or ODP_PACKET_OFFSET_INVALID if not found
> >>   */
> >>  size_t odp_packet_l2_offset(odp_packet_t pkt);
> >>  
> >> @@ -127,7 +149,7 @@ void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset);
> >>   *
> >>   * @param pkt  Packet handle
> >>   *
> >> - * @return  Pointer to L3 packet
> >> + * @return  Pointer to L3 packet or NULL if not found
> >>   *
> >>   */
> >>  uint8_t *odp_packet_l3(odp_packet_t pkt);
> >> @@ -137,7 +159,7 @@ uint8_t *odp_packet_l3(odp_packet_t pkt);
> >>   *
> >>   * @param pkt  Packet handle
> >>   *
> >> - * @return  L3 byte offset
> >> + * @return  L3 byte offset or ODP_PACKET_OFFSET_INVALID if not found
> >>   */
> >>  size_t odp_packet_l3_offset(odp_packet_t pkt);
> >>  
> >> @@ -155,7 +177,7 @@ void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset);
> >>   *
> >>   * @param pkt  Packet handle
> >>   *
> >> - * @return  Pointer to L4 packet
> >> + * @return  Pointer to L4 packet or NULL if not found
> >>   *
> >>   */
> >>  uint8_t *odp_packet_l4(odp_packet_t pkt);
> >> @@ -165,7 +187,7 @@ uint8_t *odp_packet_l4(odp_packet_t pkt);
> >>   *
> >>   * @param pkt  Packet handle
> >>   *
> >> - * @return  L4 byte offset
> >> + * @return  L4 byte offset or ODP_PACKET_OFFSET_INVALID if not found
> >>   */
> >>  size_t odp_packet_l4_offset(odp_packet_t pkt);
> >>  
> >> diff --git a/platform/linux-generic/source/odp_packet.c b/platform/linux-generic/source/odp_packet.c
> >> index 6ee2c5b..060d82e 100644
> >> --- a/platform/linux-generic/source/odp_packet.c
> >> +++ b/platform/linux-generic/source/odp_packet.c
> >> @@ -25,6 +25,10 @@ void odp_packet_init(odp_packet_t pkt)
> >>  	start = (uint8_t *)pkt_hdr + start_offset;
> >>  	len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset;
> >>  	memset(start, 0, len);
> >> +
> >> +	pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
> >> +	pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
> >> +	pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
> >>  }
> >>  
> >>  odp_packet_t odp_packet_from_buffer(odp_buffer_t buf)
> >> @@ -52,10 +56,20 @@ uint8_t *odp_packet_buf_addr(odp_packet_t pkt)
> >>  	return odp_buffer_addr(odp_buffer_from_packet(pkt));
> >>  }
> >>  
> >> +uint8_t *odp_packet_start(odp_packet_t pkt)
> >> +{
> >> +	return odp_packet_buf_addr(pkt) + odp_packet_hdr(pkt)->frame_offset;
> >> +}
> >> +
> >>  
> >>  uint8_t *odp_packet_l2(odp_packet_t pkt)
> >>  {
> >> -	return odp_packet_buf_addr(pkt) + odp_packet_l2_offset(pkt);
> >> +	const size_t offset = odp_packet_l2_offset(pkt);
> >> +
> >> +	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
> >> +		return NULL;
> > 
> > Should we add ODP_ERR(...) before "return NULL;"?
> 
> No. It's not an error that pre-classification did not recognize L2, L3
> or L4 in the packet. It just means that the packet contains something else.
> Currently if L2 is not ethernet its not set, if L3 is not IP it's not
> set, if L4 is not TCP,UDP,SCTP (or ICMP) it's not set, but the packet
> may still be valid.
> 
> E.g. a proprietary protocol on top of ethernet will have L2 set but L3
> and L4 will not be set, thus the funcs should return NULL without an error.

Aha, thank you!
Understood.

Cheers,

> 
> > 
> >> +
> >> +	return odp_packet_buf_addr(pkt) + offset;
> >>  }
> >>  
> >>  size_t odp_packet_l2_offset(odp_packet_t pkt)
> >> @@ -71,7 +85,12 @@ void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset)
> >>  
> >>  uint8_t *odp_packet_l3(odp_packet_t pkt)
> >>  {
> >> -	return odp_packet_buf_addr(pkt) + odp_packet_l3_offset(pkt);
> >> +	const size_t offset = odp_packet_l3_offset(pkt);
> >> +
> >> +	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
> >> +		return NULL;
> > 
> > and here.
> > 
> >> +
> >> +	return odp_packet_buf_addr(pkt) + offset;
> >>  }
> >>  
> >>  size_t odp_packet_l3_offset(odp_packet_t pkt)
> >> @@ -87,7 +106,12 @@ void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset)
> >>  
> >>  uint8_t *odp_packet_l4(odp_packet_t pkt)
> >>  {
> >> -	return odp_packet_buf_addr(pkt) + odp_packet_l4_offset(pkt);
> >> +	const size_t offset = odp_packet_l4_offset(pkt);
> >> +
> >> +	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
> >> +		return NULL;
> > 
> > and here.
> > 
> > 
> > Cheers,
> > 
> >> +
> >> +	return odp_packet_buf_addr(pkt) + offset;
> >>  }
> >>  
> >>  size_t odp_packet_l4_offset(odp_packet_t pkt)
> >> -- 
> >> 1.8.5.3
> >>
> >> -- 
> >> You received this message because you are subscribed to the Google Groups "LNG ODP Sub-team - lng-odp@linaro.org" group.
> >> To unsubscribe from this group and stop receiving emails from it, send an email to lng-odp+unsubscribe@linaro.org.
> >> To post to this group, send email to lng-odp@linaro.org.
> >> Visit this group at http://groups.google.com/a/linaro.org/group/lng-odp/.
> >> To view this discussion on the web visit https://groups.google.com/a/linaro.org/d/msgid/lng-odp/1392639281-2753-5-git-send-email-carl.wallen%40linaro.org.
> >> For more options, visit https://groups.google.com/a/linaro.org/groups/opt_out.
> > 
>
diff mbox

Patch

diff --git a/include/odp_packet.h b/include/odp_packet.h
index 4de4db2..0b693d9 100644
--- a/include/odp_packet.h
+++ b/include/odp_packet.h
@@ -27,6 +27,8 @@  extern "C" {
 typedef uint32_t odp_packet_t;
 
 #define ODP_PACKET_INVALID ODP_BUFFER_INVALID
+#define ODP_PACKET_OFFSET_INVALID ((size_t)-1)
+
 
 /**
  * Initialize the packet
@@ -74,21 +76,41 @@  void odp_packet_set_len(odp_packet_t pkt, size_t len);
 size_t odp_packet_get_len(odp_packet_t pkt);
 
 /**
- * Get pointer to the start of the packet buffer
+ * Get address to the start of the packet buffer
  *
- * The start address of the packet buffer is not necessarily the same as the
- * start address of a received frame, e.g. an eth frame may be offset by 2 or 6
+ * The address of the packet buffer is not necessarily the same as the start
+ * address of the received frame, e.g. an eth frame may be offset by 2 or 6
  * bytes to ensure 32 or 64-bit alignment of the IP header.
- * Use odp_packet_l2(pkt) to get the start address of a received frame.
+ * Use odp_packet_l2(pkt) to get the start address of a received valid frame
+ * or odp_packet_start(pkt) to get the start address even if no valid L2 header
+ * could be found.
  *
  * @param pkt  Packet handle
  *
  * @return  Pointer to the start of the packet buffer
  *
- * @see odp_packet_l2()
+ * @see odp_packet_l2(), odp_packet_start()
  */
 uint8_t *odp_packet_buf_addr(odp_packet_t pkt);
 
+/**
+ * Get pointer to the start of the received frame
+ *
+ * The address of the packet buffer is not necessarily the same as the start
+ * address of the received frame, e.g. an eth frame may be offset by 2 or 6
+ * bytes to ensure 32 or 64-bit alignment of the IP header.
+ * Use odp_packet_l2(pkt) to get the start address of a received valid eth frame
+ *
+ * odp_packet_start() will always return a pointer to the start of the frame,
+ * even if the frame is unrecognized and no valid L2 header could be found.
+ *
+ * @param pkt  Packet handle
+ *
+ * @return  Pointer to the start of the received frame
+ *
+ * @see odp_packet_l2(), odp_packet_buf_addr()
+ */
+uint8_t *odp_packet_start(odp_packet_t pkt);
 
 /**
  * Get pointer to the start of the L2 frame
@@ -98,9 +120,9 @@  uint8_t *odp_packet_buf_addr(odp_packet_t pkt);
  *
  * @param pkt  Packet handle
  *
- * @return  Pointer to L2 header
+ * @return  Pointer to L2 header or NULL if not found
  *
- * @see odp_packet_buf_addr()
+ * @see odp_packet_buf_addr(), odp_packet_start()
  */
 uint8_t *odp_packet_l2(odp_packet_t pkt);
 
@@ -109,7 +131,7 @@  uint8_t *odp_packet_l2(odp_packet_t pkt);
  *
  * @param pkt  Packet handle
  *
- * @return  L2 byte offset
+ * @return  L2 byte offset or ODP_PACKET_OFFSET_INVALID if not found
  */
 size_t odp_packet_l2_offset(odp_packet_t pkt);
 
@@ -127,7 +149,7 @@  void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset);
  *
  * @param pkt  Packet handle
  *
- * @return  Pointer to L3 packet
+ * @return  Pointer to L3 packet or NULL if not found
  *
  */
 uint8_t *odp_packet_l3(odp_packet_t pkt);
@@ -137,7 +159,7 @@  uint8_t *odp_packet_l3(odp_packet_t pkt);
  *
  * @param pkt  Packet handle
  *
- * @return  L3 byte offset
+ * @return  L3 byte offset or ODP_PACKET_OFFSET_INVALID if not found
  */
 size_t odp_packet_l3_offset(odp_packet_t pkt);
 
@@ -155,7 +177,7 @@  void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset);
  *
  * @param pkt  Packet handle
  *
- * @return  Pointer to L4 packet
+ * @return  Pointer to L4 packet or NULL if not found
  *
  */
 uint8_t *odp_packet_l4(odp_packet_t pkt);
@@ -165,7 +187,7 @@  uint8_t *odp_packet_l4(odp_packet_t pkt);
  *
  * @param pkt  Packet handle
  *
- * @return  L4 byte offset
+ * @return  L4 byte offset or ODP_PACKET_OFFSET_INVALID if not found
  */
 size_t odp_packet_l4_offset(odp_packet_t pkt);
 
diff --git a/platform/linux-generic/source/odp_packet.c b/platform/linux-generic/source/odp_packet.c
index 6ee2c5b..060d82e 100644
--- a/platform/linux-generic/source/odp_packet.c
+++ b/platform/linux-generic/source/odp_packet.c
@@ -25,6 +25,10 @@  void odp_packet_init(odp_packet_t pkt)
 	start = (uint8_t *)pkt_hdr + start_offset;
 	len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset;
 	memset(start, 0, len);
+
+	pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
+	pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
+	pkt_hdr->l4_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
 }
 
 odp_packet_t odp_packet_from_buffer(odp_buffer_t buf)
@@ -52,10 +56,20 @@  uint8_t *odp_packet_buf_addr(odp_packet_t pkt)
 	return odp_buffer_addr(odp_buffer_from_packet(pkt));
 }
 
+uint8_t *odp_packet_start(odp_packet_t pkt)
+{
+	return odp_packet_buf_addr(pkt) + odp_packet_hdr(pkt)->frame_offset;
+}
+
 
 uint8_t *odp_packet_l2(odp_packet_t pkt)
 {
-	return odp_packet_buf_addr(pkt) + odp_packet_l2_offset(pkt);
+	const size_t offset = odp_packet_l2_offset(pkt);
+
+	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
+		return NULL;
+
+	return odp_packet_buf_addr(pkt) + offset;
 }
 
 size_t odp_packet_l2_offset(odp_packet_t pkt)
@@ -71,7 +85,12 @@  void odp_packet_set_l2_offset(odp_packet_t pkt, size_t offset)
 
 uint8_t *odp_packet_l3(odp_packet_t pkt)
 {
-	return odp_packet_buf_addr(pkt) + odp_packet_l3_offset(pkt);
+	const size_t offset = odp_packet_l3_offset(pkt);
+
+	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
+		return NULL;
+
+	return odp_packet_buf_addr(pkt) + offset;
 }
 
 size_t odp_packet_l3_offset(odp_packet_t pkt)
@@ -87,7 +106,12 @@  void odp_packet_set_l3_offset(odp_packet_t pkt, size_t offset)
 
 uint8_t *odp_packet_l4(odp_packet_t pkt)
 {
-	return odp_packet_buf_addr(pkt) + odp_packet_l4_offset(pkt);
+	const size_t offset = odp_packet_l4_offset(pkt);
+
+	if (odp_unlikely(offset == ODP_PACKET_OFFSET_INVALID))
+		return NULL;
+
+	return odp_packet_buf_addr(pkt) + offset;
 }
 
 size_t odp_packet_l4_offset(odp_packet_t pkt)