From patchwork Tue Dec 16 12:30:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taras Kondratiuk X-Patchwork-Id: 42331 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ee0-f71.google.com (mail-ee0-f71.google.com [74.125.83.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id B67762456A for ; Tue, 16 Dec 2014 12:32:08 +0000 (UTC) Received: by mail-ee0-f71.google.com with SMTP id c13sf8871281eek.10 for ; Tue, 16 Dec 2014 04:32:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:subject:precedence:list-id:list-unsubscribe:list-archive :list-post:list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=G19vO4ueHWWJBbfxLcVuDt9SF5G3cyxMwzTR+s1mURI=; b=AyWLVpt5fQJ9axRqmAqwDg9Bc2zuwZPc1+Sx0UrcuQ9ltrAKC98ahPZbDySzLuQtqf ncOCSTKsfYb1dasAJNoD4DG2U6sH9AZDFWm1wjkgMmi0gwCDfP0l2+2gXqj3Vcq9GITI mkx/JE801MMPk6xibMS8j7DbZWkaohzk2YINnnNi9HU3bVbA6n/TtECWA7EhbOT6ivJQ aKUNTTRSuo5l7LiZjNg+u0LFR+wtYgS0ldkXWsDSOnl3lwZu/X9vJ/TwwANo6Mn2Y/+Y AALZGqgcxkQ/X3kvltBaTI8aU13xU/Wz9Luc2k5EyYjjQNtiCgZP4T4ZKXxia2KQfksX oJSA== X-Gm-Message-State: ALoCoQmZaLIJ8XOSiOTBxQAgyK6hBaIR/7GhM+gajaZftOl+aJ9HWXpVoY0wPBYQp9x5xVkRaSFi X-Received: by 10.194.178.163 with SMTP id cz3mr5592470wjc.1.1418733127907; Tue, 16 Dec 2014 04:32:07 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.44.194 with SMTP id g2ls969209lam.3.gmail; Tue, 16 Dec 2014 04:32:07 -0800 (PST) X-Received: by 10.152.23.38 with SMTP id j6mr27792099laf.81.1418733127636; Tue, 16 Dec 2014 04:32:07 -0800 (PST) Received: from mail-la0-f45.google.com (mail-la0-f45.google.com. [209.85.215.45]) by mx.google.com with ESMTPS id cq7si589371lad.125.2014.12.16.04.32.07 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 16 Dec 2014 04:32:07 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.45 as permitted sender) client-ip=209.85.215.45; Received: by mail-la0-f45.google.com with SMTP id gq15so11301592lab.18 for ; Tue, 16 Dec 2014 04:32:07 -0800 (PST) X-Received: by 10.152.87.100 with SMTP id w4mr35525771laz.71.1418733127529; Tue, 16 Dec 2014 04:32:07 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.142.69 with SMTP id ru5csp1020098lbb; Tue, 16 Dec 2014 04:32:06 -0800 (PST) X-Received: by 10.229.203.9 with SMTP id fg9mr64954589qcb.20.1418733126095; Tue, 16 Dec 2014 04:32:06 -0800 (PST) Received: from ip-10-35-177-41.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id z20si683149qax.23.2014.12.16.04.32.05 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 16 Dec 2014 04:32:06 -0800 (PST) Received-SPF: none (google.com: lng-odp-bounces@lists.linaro.org does not designate permitted sender hosts) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-35-177-41.ec2.internal) by ip-10-35-177-41.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1Y0rIJ-0006eU-8Z; Tue, 16 Dec 2014 12:32:03 +0000 Received: from mail-la0-f50.google.com ([209.85.215.50]) by ip-10-35-177-41.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1Y0rHQ-0006Uq-VK for lng-odp@lists.linaro.org; Tue, 16 Dec 2014 12:31:09 +0000 Received: by mail-la0-f50.google.com with SMTP id pn19so11033769lab.23 for ; Tue, 16 Dec 2014 04:31:03 -0800 (PST) X-Received: by 10.152.170.194 with SMTP id ao2mr36114330lac.12.1418733063398; Tue, 16 Dec 2014 04:31:03 -0800 (PST) Received: from uglx0153363.synapse.com ([195.238.92.128]) by mx.google.com with ESMTPSA id eg2sm169516lbb.29.2014.12.16.04.31.01 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 16 Dec 2014 04:31:02 -0800 (PST) From: Taras Kondratiuk To: lng-odp@lists.linaro.org Date: Tue, 16 Dec 2014 14:30:41 +0200 Message-Id: <1418733042-18047-9-git-send-email-taras.kondratiuk@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1418733042-18047-1-git-send-email-taras.kondratiuk@linaro.org> References: <1418733042-18047-1-git-send-email-taras.kondratiuk@linaro.org> X-Topics: patch Subject: [lng-odp] [PATCHv5 8/9] api: packet: add head/tail room manipulation X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: lng-odp-bounces@lists.linaro.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: taras.kondratiuk@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.45 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 From: Bill Fischofer Signed-off-by: Bill Fischofer Signed-off-by: Taras Kondratiuk --- example/ipsec/odp_ipsec.c | 4 +- example/ipsec/odp_ipsec_stream.c | 2 +- platform/linux-generic/include/api/odp_packet.h | 275 +++++++++++++++++---- .../linux-generic/include/odp_packet_internal.h | 33 +++ platform/linux-generic/odp_packet.c | 97 +++++++- 5 files changed, 349 insertions(+), 62 deletions(-) diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index ae04a4e..223ca61 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -807,10 +807,10 @@ pkt_disposition_e do_ipsec_in_finish(odp_packet_t pkt, odph_ipv4_csum_update(pkt); /* Correct the packet length and move payload into position */ - odp_packet_set_len(pkt, odp_packet_get_len(pkt) - (hdr_len + trl_len)); memmove(ipv4_data_p(ip), ipv4_data_p(ip) + hdr_len, odp_be_to_cpu_16(ip->tot_len)); + odp_packet_pull_tail(pkt, hdr_len + trl_len); /* Fall through to next state */ return PKT_CONTINUE; @@ -924,7 +924,7 @@ pkt_disposition_e do_ipsec_out_classify(odp_packet_t pkt, /* Set IPv4 length before authentication */ ipv4_adjust_len(ip, hdr_len + trl_len); - odp_packet_set_len(pkt, odp_packet_get_len(pkt) + (hdr_len + trl_len)); + odp_packet_push_tail(pkt, hdr_len + trl_len); /* Save remaining context */ ctx->ipsec.hdr_len = hdr_len; diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c index 93de198..1e932df 100644 --- a/example/ipsec/odp_ipsec_stream.c +++ b/example/ipsec/odp_ipsec_stream.c @@ -302,7 +302,7 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream, /* Since ESP can pad we can now fix IP length */ ip->tot_len = odp_cpu_to_be_16(data - (uint8_t *)ip); - odp_packet_set_len(pkt, data - base); + odp_packet_push_tail(pkt, data - base); /* Close AH if specified */ if (ah) { diff --git a/platform/linux-generic/include/api/odp_packet.h b/platform/linux-generic/include/api/odp_packet.h index cb5f177..853709d 100644 --- a/platform/linux-generic/include/api/odp_packet.h +++ b/platform/linux-generic/include/api/odp_packet.h @@ -113,6 +113,235 @@ odp_packet_t odp_packet_from_buffer(odp_buffer_t buf); */ odp_buffer_t odp_packet_to_buffer(odp_packet_t pkt); + +/* + * + * Pointers and lengths + * ******************************************************** + * + */ + +/** + * Packet head address + * + * Returns start address of the first segment. Packet level headroom starts + * from here. Use odp_packet_data() or odp_packet_l2_ptr() to return the + * packet data start address. + * + * @param pkt Packet handle + * + * @return Pointer to the start address of the first packet segment + * + * @see odp_packet_data(), odp_packet_l2_ptr(), odp_packet_headroom() + */ +void *odp_packet_head(odp_packet_t pkt); + +/** + * Total packet buffer length + * + * Returns sum of buffer lengths over all packet segments. + * + * @param pkt Packet handle + * + * @return Total packet buffer length in bytes + * + * @see odp_packet_reset() + */ +uint32_t odp_packet_buf_len(odp_packet_t pkt); + +/** + * Packet data pointer + * + * 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. + * + * User can adjust the data pointer with head_push/head_pull (does not modify + * segmentation) and add_data/rem_data calls (may modify segmentation). + * + * @param pkt Packet handle + * + * @return Pointer to the packet data + * + * @see odp_packet_l2_ptr(), odp_packet_seg_len() + */ +void *odp_packet_data(odp_packet_t pkt); + +/** + * Packet segment data length + * + * Returns number of data bytes following the current data pointer + * (odp_packet_data()) location in the segment. + * + * @param pkt Packet handle + * + * @return Segment data length in bytes (pointed by odp_packet_data()) + * + * @see odp_packet_data() + */ +uint32_t odp_packet_seg_len(odp_packet_t pkt); + +/** + * Packet data length + * + * Returns sum of data lengths over all packet segments. + * + * @param pkt Packet handle + * + * @return Packet data length + */ +uint32_t odp_packet_len(odp_packet_t pkt); + +/** + * Packet headroom length + * + * Returns the current packet level headroom length. + * + * @param pkt Packet handle + * + * @return Headroom length + */ +uint32_t odp_packet_headroom(odp_packet_t pkt); + +/** + * Packet tailroom length + * + * Returns the current packet level tailroom length. + * + * @param pkt Packet handle + * + * @return Tailroom length + */ +uint32_t odp_packet_tailroom(odp_packet_t pkt); + +/** + * Packet tailroom pointer + * + * Returns pointer to the start of the current packet level tailroom. + * + * User can adjust the tail pointer with tail_push/tail_pull (does not modify + * segmentation) and add_data/rem_data calls (may modify segmentation). + * + * @param pkt Packet handle + * + * @return Tailroom pointer + * + * @see odp_packet_tailroom() + */ +void *odp_packet_tail(odp_packet_t pkt); + +/** + * Push out packet head + * + * Increase packet data length by moving packet head into packet headroom. + * Packet headroom is decreased with the same amount. The packet head may be + * pushed out up to 'headroom' bytes. Packet is not modified if there's not + * enough headroom space. + * + * odp_packet_xxx: + * seg_len += len + * len += len + * headroom -= len + * data -= len + * + * Operation does not modify packet segmentation or move data. Handles and + * pointers remain valid. User is responsible to update packet meta-data + * offsets when needed. + * + * @param pkt Packet handle + * @param len Number of bytes to push the head (0 ... headroom) + * + * @return The new data pointer + * @retval NULL Requested offset exceeds available headroom + * + * @see odp_packet_headroom(), odp_packet_pull_head() + */ +void *odp_packet_push_head(odp_packet_t pkt, uint32_t len); + +/** + * Pull in packet head + * + * Decrease packet data length by removing data from the head of the packet. + * Packet headroom is increased with the same amount. Packet head may be pulled + * in up to seg_len - 1 bytes (i.e. packet data pointer must stay in the + * first segment). Packet is not modified if there's not enough data. + * + * odp_packet_xxx: + * seg_len -= len + * len -= len + * headroom += len + * data += len + * + * Operation does not modify packet segmentation or move data. Handles and + * pointers remain valid. User is responsible to update packet meta-data + * offsets when needed. + * + * @param pkt Packet handle + * @param len Number of bytes to pull the head (0 ... seg_len - 1) + * + * @return The new data pointer, or NULL in case of an error. + * @retval NULL Requested offset exceeds packet segment length + * + * @see odp_packet_seg_len(), odp_packet_push_head() + */ +void *odp_packet_pull_head(odp_packet_t pkt, uint32_t len); + +/** + * Push out packet tail + * + * Increase packet data length by moving packet tail into packet tailroom. + * Packet tailroom is decreased with the same amount. The packet tail may be + * pushed out up to 'tailroom' bytes. Packet is not modified if there's not + * enough tailroom. + * + * last_seg: + * data_len += len + * + * odp_packet_xxx: + * len += len + * tail += len + * tailroom -= len + * + * Operation does not modify packet segmentation or move data. Handles, + * pointers and offsets remain valid. + * + * @param pkt Packet handle + * @param len Number of bytes to push the tail (0 ... tailroom) + * + * @return The old tail pointer + * @retval NULL Requested offset exceeds available tailroom + * + * @see odp_packet_tailroom(), odp_packet_pull_tail() + */ +void *odp_packet_push_tail(odp_packet_t pkt, uint32_t len); + +/** + * Pull in packet tail + * + * Decrease packet data length by removing data from the tail of the packet. + * Packet tailroom is increased with the same amount. Packet tail may be pulled + * in up to last segment data_len - 1 bytes. (i.e. packet tail must stay in the + * last segment). Packet is not modified if there's not enough data. + * + * last_seg: + * data_len -= len + * + * odp_packet_xxx: + * len -= len + * tail -= len + * tailroom += len + * + * Operation does not modify packet segmentation or move data. Handles and + * pointers remain valid. User is responsible to update packet meta-data + * offsets when needed. + * + * @param pkt Packet handle + * @param len Number of bytes to pull the tail (0 ... last_seg:data_len - 1) + * + * @return The new tail pointer + * @retval NULL The specified offset exceeds allowable data length + */ +void *odp_packet_pull_tail(odp_packet_t pkt, uint32_t len); /** * Set the packet length * @@ -177,52 +406,6 @@ uint64_t odp_packet_user_u64(odp_packet_t pkt); void odp_packet_user_u64_set(odp_packet_t pkt, uint64_t ctx); /** - * Packet buffer start address - * - * Returns a pointer to the start of the packet buffer. The address is not - * necessarily the same as packet data address. E.g. on a received Ethernet - * frame, the protocol header may start 2 or 6 bytes within the buffer 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 frame - * or odp_packet_data(pkt) to get the current packet data address. - * - * @param pkt Packet handle - * - * @return Pointer to the start of the packet buffer - * - * @see odp_packet_l2(), odp_packet_data() - */ -uint8_t *odp_packet_addr(odp_packet_t pkt); - -/** - * Packet buffer maximum data size - * - * @note odp_packet_buf_size(pkt) != odp_packet_get_len(pkt), the former returns - * the max length of the buffer, the latter the size of a received packet. - * - * @param pkt Packet handle - * - * @return Packet buffer maximum data size - */ -size_t odp_packet_buf_size(odp_packet_t pkt); - -/** - * Packet data pointer - * - * 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 - * - * @return Pointer to the packet data - * - * @see odp_packet_l2(), odp_packet_addr() - */ -void *odp_packet_data(odp_packet_t pkt); - -/** * Layer 2 start pointer * * Returns pointer to the start of the layer 2 header. Optionally, outputs diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 0b24300..bd5daf0 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -188,6 +188,39 @@ static inline void *packet_map(odp_packet_hdr_t *pkt_hdr, pkt_hdr->headroom + pkt_hdr->frame_len); } +#define pull_offset(x, len) (x = x < len ? 0 : x - len) + +static inline void push_head(odp_packet_hdr_t *pkt_hdr, size_t len) +{ + pkt_hdr->headroom -= len; + pkt_hdr->frame_len += len; + pkt_hdr->l2_offset += len; + pkt_hdr->l3_offset += len; + pkt_hdr->l4_offset += len; +} + +static inline void pull_head(odp_packet_hdr_t *pkt_hdr, size_t len) +{ + pkt_hdr->headroom += len; + pkt_hdr->frame_len -= len; + pull_offset(pkt_hdr->l2_offset, len); + pull_offset(pkt_hdr->l3_offset, len); + pull_offset(pkt_hdr->l4_offset, len); +} + +static inline void push_tail(odp_packet_hdr_t *pkt_hdr, size_t len) +{ + pkt_hdr->tailroom -= len; + pkt_hdr->frame_len += len; +} + + +static inline void pull_tail(odp_packet_hdr_t *pkt_hdr, size_t len) +{ + pkt_hdr->tailroom += len; + pkt_hdr->frame_len -= len; +} + static inline void packet_set_len(odp_packet_t pkt, uint32_t len) { odp_packet_hdr(pkt)->frame_len = len; diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index ff05849..9f18540 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -78,28 +78,106 @@ odp_buffer_t odp_packet_to_buffer(odp_packet_t pkt) return (odp_buffer_t)pkt; } -void odp_packet_set_len(odp_packet_t pkt, size_t len) +/* + * + * Pointers and lengths + * ******************************************************** + * + */ + +void *odp_packet_head(odp_packet_t pkt) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + return buffer_map(&pkt_hdr->buf_hdr, 0, NULL, 0); +} + +uint32_t odp_packet_buf_len(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->buf_hdr.size; +} + +void *odp_packet_data(odp_packet_t pkt) { - odp_packet_hdr(pkt)->frame_len = len; + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + return packet_map(pkt_hdr, 0, NULL); +} + +uint32_t odp_packet_seg_len(odp_packet_t pkt) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + uint32_t seglen; + + /* Call returns length of 1st data segment */ + packet_map(pkt_hdr, 0, &seglen); + return seglen; } -size_t odp_packet_get_len(odp_packet_t pkt) +uint32_t odp_packet_len(odp_packet_t pkt) { return odp_packet_hdr(pkt)->frame_len; } -uint8_t *odp_packet_addr(odp_packet_t pkt) +uint32_t odp_packet_headroom(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->headroom; +} + +uint32_t odp_packet_tailroom(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->tailroom; +} + +void *odp_packet_tail(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - return buffer_map(&pkt_hdr->buf_hdr, 0, NULL, 0); + return packet_map(pkt_hdr, pkt_hdr->frame_len, NULL); } -void *odp_packet_data(odp_packet_t pkt) +void *odp_packet_push_head(odp_packet_t pkt, uint32_t len) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + if (len > pkt_hdr->headroom) + return NULL; + + push_head(pkt_hdr, len); + return packet_map(pkt_hdr, 0, NULL); +} + +void *odp_packet_pull_head(odp_packet_t pkt, uint32_t len) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + if (len > pkt_hdr->frame_len) + return NULL; + + pull_head(pkt_hdr, len); return packet_map(pkt_hdr, 0, NULL); } +void *odp_packet_push_tail(odp_packet_t pkt, uint32_t len) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + uint32_t origin = pkt_hdr->frame_len; + + if (len > pkt_hdr->tailroom) + return NULL; + + push_tail(pkt_hdr, len); + return packet_map(pkt_hdr, origin, NULL); +} + +void *odp_packet_pull_tail(odp_packet_t pkt, uint32_t len) +{ + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + if (len > pkt_hdr->frame_len) + return NULL; + + pull_tail(pkt_hdr, len); + return packet_map(pkt_hdr, pkt_hdr->frame_len, NULL); +} + void *odp_packet_user_ptr(odp_packet_t pkt) { return odp_packet_hdr(pkt)->buf_hdr.buf_ctx; @@ -265,13 +343,6 @@ int odp_packet_is_valid(odp_packet_t pkt) return odp_buffer_is_valid(buf); } -size_t odp_packet_buf_size(odp_packet_t pkt) -{ - odp_buffer_t buf = odp_packet_to_buffer(pkt); - - return odp_buffer_size(buf); -} - /* * * Internal Use Routines