diff options
author | Bill Fischofer <bill.fischofer@linaro.org> | 2014-12-16 14:30:36 +0200 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2014-12-16 19:03:39 +0300 |
commit | df8a28363d75dd27476cc89cb1fae60c167f444c (patch) | |
tree | 48ffe9c02630ecaf7140a9a352dba1b8e18a2b80 /platform/linux-generic | |
parent | a834a53925baa7196ed07ad8e0cd990979c33f19 (diff) |
api: packet: change layer offset/pointer API
Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>
Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org>
Reviewed-and-tested-by: Bill Fischofer <bill.fischofer@linaro.org>
Reviewed-by: Petri Savolainen <petri.savolainen@linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform/linux-generic')
-rw-r--r-- | platform/linux-generic/include/api/odp_packet.h | 130 | ||||
-rw-r--r-- | platform/linux-generic/include/odp_packet_internal.h | 11 | ||||
-rw-r--r-- | platform/linux-generic/odp_packet.c | 80 | ||||
-rw-r--r-- | platform/linux-generic/odp_packet_socket.c | 17 |
4 files changed, 152 insertions, 86 deletions
diff --git a/platform/linux-generic/include/api/odp_packet.h b/platform/linux-generic/include/api/odp_packet.h index 9a151146c..96e1474f4 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 eecdfd7a6..9338ec238 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -173,6 +173,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 a4ad3e858..783714bc8 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 76e437a8c..ead5d2f84 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; |