From patchwork Mon Feb 17 12:14:37 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carl Wallen X-Patchwork-Id: 24762 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pa0-f70.google.com (mail-pa0-f70.google.com [209.85.220.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1A543202B2 for ; Mon, 17 Feb 2014 12:15:44 +0000 (UTC) Received: by mail-pa0-f70.google.com with SMTP id kq14sf37186349pab.5 for ; Mon, 17 Feb 2014 04:15:44 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:to:cc:subject:date:message-id :in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe:content-type; bh=cOeQlVrrcl5xUqeCHaNsRJKLwaCV5IGW4xtl3f9H/Hw=; b=RGIqctcSVwFOEK7hoUFf+uUC+2NwwTO7we4C5k7UniPGtf9t1ELwZ5gSvA2NW0XhS5 lUH57zaWi9H48WSNgcjeqNxVXwYUtTA5n4cGxmAvXUt0mR5ewop/Mz/CSzZNXCIfu3Ha KK7Y6trxNmshVCYp2un6XpXJDshgXRJVOEXqGv6ii+PFwFV6P/9sfnXUI9oGSq4HV2Ml g+8tgPJGtsgB9CFmgGoGi39fV00vFdKgyyce2jxKKL+P+SbHXM9jZAMGyyWYynT9MKHP KuXpcnJmMFpAuHvno4Qi4N53nkeuZq6ceteL6mxaMLfK1+eLRzOS6hKpYzYVavOK/5a5 fTSg== X-Gm-Message-State: ALoCoQnAjsoQCaZ5TKeCFLvfmIs69nJojSnYTxCjIiftJqO2NYpMz4HHALgibKz0zDZjBl+E2VmC X-Received: by 10.66.157.35 with SMTP id wj3mr10338135pab.11.1392639344046; Mon, 17 Feb 2014 04:15:44 -0800 (PST) MIME-Version: 1.0 X-BeenThere: lng-odp@linaro.org Received: by 10.140.35.208 with SMTP id n74ls869228qgn.65.gmail; Mon, 17 Feb 2014 04:15:43 -0800 (PST) X-Received: by 10.224.98.212 with SMTP id r20mr34241310qan.0.1392639343053; Mon, 17 Feb 2014 04:15:43 -0800 (PST) Received: from mail-qc0-f181.google.com (mail-qc0-f181.google.com [209.85.216.181]) by mx.google.com with ESMTPS id y3si8008594qas.188.2014.02.17.04.15.43 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 17 Feb 2014 04:15:43 -0800 (PST) Received-SPF: neutral (google.com: 209.85.216.181 is neither permitted nor denied by best guess record for domain of carl.wallen@linaro.org) client-ip=209.85.216.181; Received: by mail-qc0-f181.google.com with SMTP id e9so23775413qcy.12 for ; Mon, 17 Feb 2014 04:15:43 -0800 (PST) X-Received: by 10.140.93.111 with SMTP id c102mr31653196qge.53.1392639342858; Mon, 17 Feb 2014 04:15:42 -0800 (PST) Received: from mcint01.emea.nsn-net.net (ec2-23-23-178-99.compute-1.amazonaws.com. [23.23.178.99]) by mx.google.com with ESMTPSA id 3sm44637049qan.15.2014.02.17.04.15.41 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 17 Feb 2014 04:15:42 -0800 (PST) From: Carl Wallen To: lng-odp@linaro.org Cc: Carl Wallen Subject: [lng-odp] [PATCH 3/7] ODP Packet Flags API Date: Mon, 17 Feb 2014 14:14:37 +0200 Message-Id: <1392639281-2753-4-git-send-email-carl.wallen@linaro.org> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1392639281-2753-1-git-send-email-carl.wallen@linaro.org> References: <1392639281-2753-1-git-send-email-carl.wallen@linaro.org> X-Original-Sender: carl.wallen@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.216.181 is neither permitted nor denied by best guess record for domain of carl.wallen@linaro.org) smtp.mail=carl.wallen@linaro.org Precedence: list Mailing-list: list lng-odp@linaro.org; contact lng-odp+owners@linaro.org List-ID: X-Google-Group-Id: 474323889996 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add ODP Packet Flags API funcs to access the error, input and output flags set by packet IO. Signed-off-by: Carl Wallen --- include/odp.h | 1 + include/odp_packet_flags.h | 189 +++++++++++++++++++++ platform/linux-generic/Makefile | 1 + .../linux-generic/include/odp_packet_internal.h | 95 ++++++++--- platform/linux-generic/source/odp_packet.c | 18 +- platform/linux-generic/source/odp_packet_flags.c | 116 +++++++++++++ 6 files changed, 383 insertions(+), 37 deletions(-) create mode 100644 include/odp_packet_flags.h create mode 100644 platform/linux-generic/source/odp_packet_flags.c diff --git a/include/odp.h b/include/odp.h index 08c7c31..6a52346 100644 --- a/include/odp.h +++ b/include/odp.h @@ -295,6 +295,7 @@ extern "C" { #include #include #include +#include #include #ifdef __cplusplus diff --git a/include/odp_packet_flags.h b/include/odp_packet_flags.h new file mode 100644 index 0000000..eb9315b --- /dev/null +++ b/include/odp_packet_flags.h @@ -0,0 +1,189 @@ +/* Copyright (c) 2014, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +/** + * @file + * + * ODP packet flags + */ + +#ifndef ODP_PACKET_FLAGS_H_ +#define ODP_PACKET_FLAGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * Check for packet errors + * + * Checks all error flags at once. + * + * @param pkt Packet handle + * @return 1 if packet has errors, 0 otherwise + */ +int odp_packet_error(odp_packet_t pkt); + +/** + * Check if error was 'frame length' error + * + * @param pkt Packet handle + * @return 1 if frame length error detected, 0 otherwise + */ +int odp_packet_errflag_frame_len(odp_packet_t pkt); + +/** + * Check for L2 header, e.g. ethernet + * + * @param pkt Packet handle + * @return 1 if packet contains a valid & known L2 header, 0 otherwise + */ +int odp_packet_inflag_l2(odp_packet_t pkt); + +/** + * Check for L3 header, e.g. IPv4, IPv6 + * + * @param pkt Packet handle + * @return 1 if packet contains a valid & known L3 header, 0 otherwise + */ +int odp_packet_inflag_l3(odp_packet_t pkt); + +/** + * Check for L4 header, e.g. UDP, TCP, SCTP (also ICMP) + * + * @param pkt Packet handle + * @return 1 if packet contains a valid & known L4 header, 0 otherwise + */ +int odp_packet_inflag_l4(odp_packet_t pkt); + +/** + * Check for Ethernet header + * + * @param pkt Packet handle + * @return 1 if packet contains a valid eth header, 0 otherwise + */ +int odp_packet_inflag_eth(odp_packet_t pkt); + +/** + * Check for jumbo frame + * + * @param pkt Packet handle + * @return 1 if packet contains jumbo frame, 0 otherwise + */ +int odp_packet_inflag_jumbo(odp_packet_t pkt); + +/** + * Check for VLAN + * + * @param pkt Packet handle + * @return 1 if packet contains a VLAN header, 0 otherwise + */ +int odp_packet_inflag_vlan(odp_packet_t pkt); + +/** + * Check for VLAN QinQ (stacked VLAN) + * + * @param pkt Packet handle + * @return 1 if packet contains a VLAN QinQ header, 0 otherwise + */ +int odp_packet_inflag_vlan_qinq(odp_packet_t pkt); + +/** + * Check for ARP + * + * @param pkt Packet handle + * @return 1 if packet contains an ARP header, 0 otherwise + */ +int odp_packet_inflag_arp(odp_packet_t pkt); + +/** + * Check for IPv4 + * + * @param pkt Packet handle + * @return 1 if packet contains an IPv4 header, 0 otherwise + */ +int odp_packet_inflag_ipv4(odp_packet_t pkt); + +/** + * Check for IPv6 + * + * @param pkt Packet handle + * @return 1 if packet contains an IPv6 header, 0 otherwise + */ +int odp_packet_inflag_ipv6(odp_packet_t pkt); + +/** + * Check for IP fragment + * + * @param pkt Packet handle + * @return 1 if packet is an IP fragment, 0 otherwise + */ +int odp_packet_inflag_ipfrag(odp_packet_t pkt); + +/** + * Check for IP options + * + * @param pkt Packet handle + * @return 1 if packet contains IP options, 0 otherwise + */ +int odp_packet_inflag_ipopt(odp_packet_t pkt); + +/** + * Check for IPSec + * + * @param pkt Packet handle + * @return 1 if packet requires IPSec processing, 0 otherwise + */ +int odp_packet_inflag_ipsec(odp_packet_t pkt); + +/** + * Check for UDP + * + * @param pkt Packet handle + * @return 1 if packet contains a UDP header, 0 otherwise + */ +int odp_packet_inflag_udp(odp_packet_t pkt); + +/** + * Check for TCP + * + * @param pkt Packet handle + * @return 1 if packet contains a TCP header, 0 otherwise + */ +int odp_packet_inflag_tcp(odp_packet_t pkt); + +/** + * Check for SCTP + * + * @param pkt Packet handle + * @return 1 if packet contains an SCTP header, 0 otherwise + */ +int odp_packet_inflag_sctp(odp_packet_t pkt); + +/** + * Check for ICMP + * + * @param pkt Packet handle + * @return 1 if packet contains an ICMP header, 0 otherwise + */ +int odp_packet_inflag_icmp(odp_packet_t pkt); + +/** + * Request L4 checksum calculation + * + * @param pkt Packet handle + */ +void odp_packet_outflag_l4_chksum(odp_packet_t pkt); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/Makefile b/platform/linux-generic/Makefile index f665683..b640928 100644 --- a/platform/linux-generic/Makefile +++ b/platform/linux-generic/Makefile @@ -54,6 +54,7 @@ OBJS += $(OBJ_DIR)/odp_coremask.o OBJS += $(OBJ_DIR)/odp_init.o OBJS += $(OBJ_DIR)/odp_linux.o OBJS += $(OBJ_DIR)/odp_packet.o +OBJS += $(OBJ_DIR)/odp_packet_flags.o OBJS += $(OBJ_DIR)/odp_packet_io.o OBJS += $(OBJ_DIR)/odp_packet_socket.o OBJS += $(OBJ_DIR)/odp_queue.o diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index afef976..f0dda95 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -25,59 +25,98 @@ extern "C" { #include #include -typedef struct { - uint32_t l2:1; - uint32_t l3:1; - uint32_t l4:1; - - uint32_t macsec:1; - uint32_t vlan:1; - uint32_t vlan_double:1; - uint32_t ipv4:1; - uint32_t ipv6:1; - uint32_t ip_frag:1; - uint32_t udp:1; - uint32_t tcp:1; - uint32_t icmp:1; -} proto_flags_t; +/** + * Packet input & protocol flags + */ +typedef union { + /* All input flags */ + uint32_t all; -typedef struct { - uint32_t frame_len:1; - uint32_t l2_chksum:1; - uint32_t ip_err:1; - uint32_t tcp_err:1; - uint32_t udp_err:1; + /* Bitfield flags for each protocol */ + uint32_t l2:1; /**< known L2 protocol present */ + uint32_t l3:1; /**< known L3 protocol present */ + uint32_t l4:1; /**< known L4 protocol present */ + + uint32_t eth:1; /**< Ethernet */ + uint32_t jumbo:1; /**< Jumbo frame */ + uint32_t vlan:1; /**< VLAN hdr found */ + uint32_t vlan_qinq:1; /**< Stacked VLAN found, QinQ */ + + uint32_t arp:1; /**< ARP */ + + uint32_t ipv4:1; /**< IPv4 */ + uint32_t ipv6:1; /**< IPv6 */ + uint32_t ipfrag:1; /**< IP fragment */ + uint32_t ipopt:1; /**< IP optional headers */ + uint32_t ipsec; /**< IPSec decryption may be needed */ + + uint32_t udp:1; /**< UDP */ + uint32_t tcp:1; /**< TCP */ + uint32_t sctp:1; /**< SCTP */ + uint32_t icmp:1; /**< ICMP */ +} input_flags_t; + +ODP_ASSERT(sizeof(input_flags_t) == sizeof(uint32_t), INPUT_FLAGS_SIZE_ERROR); + +/** + * Packet error flags + */ +typedef union { + /* All error flags */ + uint32_t all; + + /* Bitfield flags for each detected error */ + uint32_t frame_len:1; /**< Frame length error */ + uint32_t l2_chksum:1; /**< L2 checksum error, checks TBD */ + uint32_t ip_err:1; /**< IP error, checks TBD */ + uint32_t tcp_err:1; /**< TCP error, checks TBD */ + uint32_t udp_err:1; /**< UDP error, checks TBD */ } error_flags_t; -typedef struct { - uint32_t calc_l4_chksum:1; +ODP_ASSERT(sizeof(error_flags_t) == sizeof(uint32_t), ERROR_FLAGS_SIZE_ERROR); + +/** + * Packet output flags + */ +typedef union { + /* All output flags */ + uint32_t all; + + /* Bitfield flags for each output option */ + uint32_t l4_chksum:1; /**< Request L4 checksum calculation */ } output_flags_t; +ODP_ASSERT(sizeof(output_flags_t) == sizeof(uint32_t), OUTPUT_FLAGS_SIZE_ERROR); + /** * Internal Packet header */ -typedef struct odp_packet_hdr_t { +typedef struct { /* common buffer header */ odp_buffer_hdr_t buf_hdr; - proto_flags_t proto_flags; + input_flags_t input_flags; error_flags_t error_flags; output_flags_t output_flags; - uint32_t l2_offset; - uint32_t l3_offset; - uint32_t l4_offset; + uint32_t frame_offset; /**< offset to start of frame, even on error */ + uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */ + uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */ + uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also ICMP) */ uint32_t frame_len; odp_pktio_t input; + uint32_t pad; uint8_t payload[]; } odp_packet_hdr_t; ODP_ASSERT(sizeof(odp_packet_hdr_t) == ODP_OFFSETOF(odp_packet_hdr_t, payload), ODP_PACKET_HDR_T__SIZE_ERR); +ODP_ASSERT(sizeof(odp_packet_hdr_t) % sizeof(uint64_t) == 0, + ODP_PACKET_HDR_T__SIZE_ERR2); /** * Return the packet header diff --git a/platform/linux-generic/source/odp_packet.c b/platform/linux-generic/source/odp_packet.c index 6b06f76..6ee2c5b 100644 --- a/platform/linux-generic/source/odp_packet.c +++ b/platform/linux-generic/source/odp_packet.c @@ -124,7 +124,7 @@ void odp_packet_parse(odp_packet_t pkt, size_t len, size_t l2_offset) if (odp_unlikely(len < ODP_ETH_LEN_MIN)) pkt_hdr->error_flags.frame_len = 1; - pkt_hdr->proto_flags.l2 = 1; + pkt_hdr->input_flags.l2 = 1; pkt_hdr->l2_offset = l2_offset; eth = (odp_ethhdr_t *)odp_packet_l2(pkt); @@ -132,25 +132,25 @@ void odp_packet_parse(odp_packet_t pkt, size_t len, size_t l2_offset) vlan = (odp_vlanhdr_t *)ð->type; if (ethtype == ODP_ETHTYPE_VLAN_OUTER) { - pkt_hdr->proto_flags.vlan_double = 1; + pkt_hdr->input_flags.vlan_qinq = 1; ethtype = odp_be_to_cpu_16(vlan->tpid); offset += sizeof(odp_vlanhdr_t); vlan = &vlan[1]; } if (ethtype == ODP_ETHTYPE_VLAN) { - pkt_hdr->proto_flags.vlan = 1; + pkt_hdr->input_flags.vlan = 1; ethtype = odp_be_to_cpu_16(vlan->tpid); offset += sizeof(odp_vlanhdr_t); } - pkt_hdr->proto_flags.l3 = 1; + pkt_hdr->input_flags.l3 = 1; pkt_hdr->l3_offset = l2_offset + ODP_ETHHDR_LEN + offset; if (ethtype == ODP_ETHTYPE_IPV4) { uint8_t ihl; - pkt_hdr->proto_flags.ipv4 = 1; + pkt_hdr->input_flags.ipv4 = 1; ip = (odp_ipv4hdr_t *)odp_packet_l3(pkt); ihl = ODP_IPV4HDR_IHL(ip->ver_ihl); @@ -159,19 +159,19 @@ void odp_packet_parse(odp_packet_t pkt, size_t len, size_t l2_offset) return; } - pkt_hdr->proto_flags.l4 = 1; + pkt_hdr->input_flags.l4 = 1; pkt_hdr->l4_offset = pkt_hdr->l3_offset + sizeof(uint32_t) * ihl; switch (ip->proto) { case ODP_IPPROTO_UDP: - pkt_hdr->proto_flags.udp = 1; + pkt_hdr->input_flags.udp = 1; break; case ODP_IPPROTO_TCP: - pkt_hdr->proto_flags.tcp = 1; + pkt_hdr->input_flags.tcp = 1; break; case ODP_IPPROTO_ICMP: - pkt_hdr->proto_flags.icmp = 1; + pkt_hdr->input_flags.icmp = 1; break; } } diff --git a/platform/linux-generic/source/odp_packet_flags.c b/platform/linux-generic/source/odp_packet_flags.c new file mode 100644 index 0000000..0fd0aa9 --- /dev/null +++ b/platform/linux-generic/source/odp_packet_flags.c @@ -0,0 +1,116 @@ +/* Copyright (c) 2014, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + #include + #include + + +int odp_packet_error(odp_packet_t pkt) +{ + return (odp_packet_hdr(pkt)->error_flags.all != 0); +} + +/* Get Error Flags */ + +int odp_packet_errflag_frame_len(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->error_flags.frame_len; +} + +/* Get Input Flags */ + +int odp_packet_inflag_l2(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.l2; +} + +int odp_packet_inflag_l3(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.l3; +} + +int odp_packet_inflag_l4(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.l4; +} + +int odp_packet_inflag_eth(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.eth; +} + +int odp_packet_inflag_jumbo(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.jumbo; +} + +int odp_packet_inflag_vlan(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.vlan; +} + +int odp_packet_inflag_vlan_qinq(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.vlan_qinq; +} + +int odp_packet_inflag_arp(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.arp; +} + +int odp_packet_inflag_ipv4(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.ipv4; +} + +int odp_packet_inflag_ipv6(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.ipv6; +} + +int odp_packet_inflag_ipfrag(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.ipfrag; +} + +int odp_packet_inflag_ipopt(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.ipopt; +} + +int odp_packet_inflag_ipsec(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.ipsec; +} + +int odp_packet_inflag_udp(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.udp; +} + +int odp_packet_inflag_tcp(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.tcp; +} + +int odp_packet_inflag_sctp(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.sctp; +} + +int odp_packet_inflag_icmp(odp_packet_t pkt) +{ + return odp_packet_hdr(pkt)->input_flags.icmp; +} + +/* Set Output Flags */ + +void odp_packet_outflag_l4_chksum(odp_packet_t pkt) +{ + odp_packet_hdr(pkt)->output_flags.l4_chksum = 1; +} +