From patchwork Tue Sep 13 14:30:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Elo, Matias \(Nokia - FI/Espoo\)" X-Patchwork-Id: 76075 Delivered-To: patch@linaro.org Received: by 10.140.106.72 with SMTP id d66csp1392492qgf; Tue, 13 Sep 2016 07:33:08 -0700 (PDT) X-Received: by 10.200.47.165 with SMTP id l34mr1412203qta.78.1473777188378; Tue, 13 Sep 2016 07:33:08 -0700 (PDT) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id d20si4463503qta.156.2016.09.13.07.33.07; Tue, 13 Sep 2016 07:33:08 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE dis=NONE) header.from=nokia.com Received: by lists.linaro.org (Postfix, from userid 109) id C21CF60965; Tue, 13 Sep 2016 14:33:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAD_ENC_HEADER,BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 2C58160F21; Tue, 13 Sep 2016 14:31:46 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id E50A260F45; Tue, 13 Sep 2016 14:31:30 +0000 (UTC) Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on0132.outbound.protection.outlook.com [104.47.2.132]) by lists.linaro.org (Postfix) with ESMTPS id 2008F60F21 for ; Tue, 13 Sep 2016 14:30:47 +0000 (UTC) Received: from DB4PR07CA004.eurprd07.prod.outlook.com (2a01:111:e400:9828::14) by AM3PR07MB1073.eurprd07.prod.outlook.com (2a01:111:e400:536e::15) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.619.10; Tue, 13 Sep 2016 14:30:36 +0000 Received: from DB3FFO11FD050.protection.gbl (2a01:111:f400:7e04::121) by DB4PR07CA004.outlook.office365.com (2a01:111:e400:9828::14) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.619.10 via Frontend Transport; Tue, 13 Sep 2016 14:30:35 +0000 Received-SPF: Pass (protection.outlook.com: domain of nokia.com designates 131.228.2.240 as permitted sender) receiver=protection.outlook.com; client-ip=131.228.2.240; helo=fihe3nok0734.emea.nsn-net.net; Received: from fihe3nok0734.emea.nsn-net.net (131.228.2.240) by DB3FFO11FD050.mail.protection.outlook.com (10.47.217.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.619.6 via Frontend Transport; Tue, 13 Sep 2016 14:30:35 +0000 Received: from fihe3nok0734.emea.nsn-net.net (localhost [127.0.0.1]) by fihe3nok0734.emea.nsn-net.net (8.14.9/8.14.5) with ESMTP id u8DEUCZs003560 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 13 Sep 2016 17:30:12 +0300 Received: from 10.144.19.15 ([10.144.104.92]) by fihe3nok0734.emea.nsn-net.net (8.14.9/8.14.5) with ESMTP id u8DEUCG3003526 (version=TLSv1/SSLv3 cipher=AES128-SHA256 bits=128 verify=NOT) for ; Tue, 13 Sep 2016 17:30:12 +0300 X-HPESVCS-Source-Ip: 10.144.104.92 From: Matias Elo To: Date: Tue, 13 Sep 2016 17:30:10 +0300 Message-ID: <1473777012-21850-1-git-send-email-matias.elo@nokia.com> X-Mailer: git-send-email 2.7.4 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:131.228.2.240; IPV:NLI; CTRY:FI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(7916002)(2980300002)(438002)(199003)(189002)(51234002)(50986999)(7846002)(305945005)(356003)(450100001)(5660300001)(11100500001)(16796002)(626004)(68736007)(77096005)(33646002)(97736004)(19580395003)(2351001)(229853001)(19580405001)(92566002)(5003940100001)(47776003)(107886002)(81166006)(586003)(48376002)(8676002)(50466002)(2906002)(87936001)(8936002)(106466001)(50226002)(81156014)(189998001)(110136003)(36756003)(42882005); DIR:OUT; SFP:1102; SCL:1; SRVR:AM3PR07MB1073; H:fihe3nok0734.emea.nsn-net.net; FPR:; SPF:Pass; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; DB3FFO11FD050; 1:RKdUnDoIg8PubQqLCTeIA6rIfVNkKWYGdICG9wUeyBQzOE3Ckjw+fr+WTP8xb8fuKMVGtN/N2yesBIjDccbMMSsjgNRa0DwDi7H55OcJS7jRqMIOM0rm7iK5nkFAKCjTUigpgWspFQrEIEfaowYEF1GOOu/72+56QYbwgObq1ltlxYUSdlC+XHCY1eEGzZQNdkbYSX6JGQL/eVkUSDpZZxFbib04TjixDQr7FczCXILztQqrAh5ynvR1gMsymOiQ1CxBXECjS9rKDIV7lmXXyMT9ay/7t9IFwymY8t7nW4lYqgI4RSpuKJeMpv+rOv0/UC75biWTRFBZko/U4UkthyCIf28i+LBe2lOSijyMU7v8JdkbtQvSY38fJewhmtAr+Z6U2ansWwZMBoZ8IK5n9lQ/TDzZ3/c+z2AF/a0O/n6pTARGm368msiDv2HetW+fwkFor6xVZAvdjEX+/x6rx+6Qq2tCzbDm/nVA/Tzq3ik= MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: c1fc8038-9b17-492a-6948-08d3dbe286a0 X-Microsoft-Exchange-Diagnostics: 1; AM3PR07MB1073; 2:mmlDCLmWyHzkThcpgO3pHNxur2cDGjklvg8oYCd6e5C/9l2BgJT3Z+SZ7owOofB5dmSlexM+fx1/UA+4TaiUqP3X57R9ko4d2EeAgM6ye0u4YpDhmczofhEakPdZJYBY4Kp8YkS3MfF0bZKgLl6ZRnfSrLqjo2yJRRamrugeZageB7U9QKbpiaVvGg+QmjvZ; 3:4ceOEgd+W/FM3UgzFzgMlVQE0/mM21j56uWKK+NVZnj0DANMP4wLiF/wSlkvJrRsUQgFShwtkqTqh6nEHHuo7bOOwUsyIsOA4XEpQi5vmMv9JNDWhDVnNTujYE9TolaXMa4S9I6g0kNXwGYVp/eEGjvaPv5kxZBZgaWtMxRAqGLbQGUT/V3LdkPqveXmCMja6x9ZJFplCW9hJDY3Vm8vw/VmLSVH9+q/H/OTdTH+wflCwo3ryosG097UrzmDGI22aaKksGyARu1EMX5EXcrD3w==; 25:nLFSmidOad0GXyAQMbRcGQzIIWLCOMAgexHSGBu3zc+9ntpOC/mHsocGwQVjKMVNTpKGGcBCnYK0LQCHd2XtQoIBq5p8SZvwQv7vpMTFAHwcmlcbmgwaUjfSm+5P962DNKw3h7UsudLNr2allFwXnXdYjFsdv5Xjz9gWZoq9ouHDhPyHmvqy1799O+r48oZgbKSMiH5ePUJO9HASzemfGddxzB5SNVwhRItt1ZQWr11RQa9zQaS7Yjsujdfd0Qsa3hnTqf+zxD62gSYzl9q2UrSLEiuh2/D0aaCFuC15Iqi4CGforkBvp4kZOc6RFFGyAEyGtpybiqH3caYiaRgbJ/Fh0RkB35J3N+zDzCJkcwNmAdv5Qnt8qPJUYHzo/3GX3Qum7O/SEueQIaiGM2ShsV0eXu0l94IlmMPLTBPimO8= X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(8251501002); SRVR:AM3PR07MB1073; X-Microsoft-Exchange-Diagnostics: 1; AM3PR07MB1073; 31:k/0mNLaySZjHFIoM5JpHrBKeosninzDky+ZXk+gIMoskZz3rEE5285IycenkDAFyDL2hTKMb2Ruv7291oIMZJbJs0ZsAJ6Nn00G5KJSuZ/KZPtpVDheFEyW1QhLK0UrurBCiwqnx1z/XaPOYiVGbACFz3rB2SPB6wZ/UGhU5XcaElb3M99xftxOwLj9b3WlAEsp5KfJgBYd2mOaBAhvTzaOQo0aDFuO0PViJzvJSfY8=; 20:MSZm9pdnhe1BzDBtCjghXJMh23PUvo8CaU2020kcWjf7stt63y6LtK0/8OCcvB/gn3LX6KaxMjqic0Q4fYYtQYysTGn5cj1ttNYB8x0JWvVw7AhWDZ9PARsOy6TFLLGKKV8l4H3Lk/Y4OHY9+DhBfS7Pv9bJM3WbY6mAL58WEZIhF4dENVGek34bqu8Xy8aGcshIOw4+Fc2o+aAAPuBQJJc4AQg+EocXq48UUa64qtLyuBl+ea981gfRF3FO6VgSnQxkyPREhvphQafn7iMmZpm3M0yINnSRLPmDZL8c2C/OSZllxpyrGRgH4EbDeKbwmSPDQ1UDhQS5DcbNs9XV8jdssAnkse6VzAJHxmj546IIhv5hCKXzbHSV3MJ30Ta8z+Yc5FaA94O1wBddWNnAHoPYvXB9ZgO8nI7qqTReRKiU7TqVQxOKwkIJa07WjFU+PsrIjlzcIN4z2YNVin6QDXP0Cyt5qCqIOTQttoZKw6eYL8sz8cznnmkx9SttzoHYQ/28hF8sGMpI0PUECG4I642wwV/At4Bu2W2O+HhBrWjts67jY7YBir+bSGVz1dUxe6v+uyEgEjPIt+hOoQPvVs1Dwf3ZnQpKqDSzZ7Cj5uY= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(82608151540597); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(13016025)(13018025)(8121501046)(5005006)(3002001)(10201501046)(6055026); SRVR:AM3PR07MB1073; BCL:0; PCL:0; RULEID:; SRVR:AM3PR07MB1073; X-Microsoft-Exchange-Diagnostics: 1; AM3PR07MB1073; 4:+YK6J8h/df4QOlkDZcUFElljszp1Q1rDOQddRdX04gUAWBSIRleazAZl6Gjc+tB6s3Wio7WXKhk/GeCoXGmwqhMhdRhxi+1orhnerOkkKg9Oa7iduBvaZ5JNOIRuhDVNg2xANIP99/SVaLTI6lLq/KM7i5lidzoMy2/oAf6wmlcus2ApBbF4eO3kpA3pJE26L1Iie9Ek28aAbyFjgk884FBXSxL6NLZpzaBYIcm9Z9gbk52fsKgECQc9u5qpasU77hQIWMH0ALfpCkh0nNnIDkP4C5gZgpmW2stfE37W6XFwOazaBRw8e+4ovYgY8P9z/tZ/CnOdAuoep163ZvU+bmeC96HUlolsQKs6d8jzRIu1czwaDLy58Eva1BGIjwX2FD/KtdxqIE1Dt2RrWcAgaANPm/jyHkx6huGtc2EmehTtgrNDrlWhZZ4wXYpFB1HMfmOcD+Lmf8tQrJHEnZQ4rk4L85wbqD+CCh60gyD1qzE= X-Forefront-PRVS: 0064B3273C X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM3PR07MB1073; 23:pGdqA8MijFE67/RF1UJW3R4ozrMYnz30BXoXbibXP?= =?us-ascii?Q?QwTROeMcdIPmef2ufIJtLrfGFFs03pi7CUHUdSM9XvIWIKBwxoycjC1fwBAu?= =?us-ascii?Q?jRtGjb1IuD8y11tiaj+hoaTyEM9v1VumK8lVPwtQG37N6jw1+uslbxMBobcm?= =?us-ascii?Q?xI0MhP1GVHr1ZfjwYbIF4sNKFQwKGK+6BVBr3g+F2iL9qHZ5tKrln48zqITM?= =?us-ascii?Q?KHb53gOVSk6QC+L6CLRk6gKMpj4RqZiWwhtXZLkAPfcxrYZ60D+ZRYMhiN9v?= =?us-ascii?Q?DUgAwied9MbqxmMIHmGk8qM7csr8knf6L6iikmrtm0keVUzoa0hbZbc6abFi?= =?us-ascii?Q?Y0jjWbh12S1yJt7RgOhoVODUSWmNh5iTrFfaS3AVpgAfDN2ipGN4wHt2G4cN?= =?us-ascii?Q?ugLZi3T3oDIpbnQfwuzKeYQP/Q4gQdiD7bwwbG+FfdFA9KbRGwnZySCC6ne9?= =?us-ascii?Q?5/JWSYA5Sd4eRzVBHcy+HzWAtXhdbUOm4fDuRgcnxB9ziSRPiqZEWNdJCKOj?= =?us-ascii?Q?7YoZQO3TuwRiVk+He2VJQl5psuIWFUfenp/BbDzfVUUPyFEl8uuA/NHgMlf9?= =?us-ascii?Q?S4qVXr/0qWGyMraOiY9Jd3tuX6GDIcARJQ1NJavgPGWxLfKXsY85egTkhzsq?= =?us-ascii?Q?bZ2XWBVPjetFuykEfKgOvMO/aEdxkaztd+9nWxtGTph/kgm4D/mj2Gfcdcdd?= =?us-ascii?Q?Bs8SX60Sl7TKWwPFzt4KNgi0ORA6qkkkBkZf5GJvHI7jTiAErJvaT+tP8qeO?= =?us-ascii?Q?97IjPL9OQaYdTrRw020aQ8Ts7FSdQvaWWX1OPLjX705QFVoRieSjbdMseHIe?= =?us-ascii?Q?98SoFV4J7yTs8wSJhQLJbrYaFnaSI2QjXV5Bx+LGJ+u59Foc9jGmp9aHabOJ?= =?us-ascii?Q?0kiNEOt2Wi6CW9tZFA6lhaR+glqZqzGRFWNDpeCVo0Qp/xlz26AH3+BI7XeW?= =?us-ascii?Q?F5cjhlDmgf/TpwKEqEbeqmU1bLYav7lizD4EMwsAtnSKhctatbkJXarVvgKC?= =?us-ascii?Q?fMDkle3B4LROmMqzIYDbcIx98QMLwoR46i7JT734djvN9lAFpC9WW6iZCp4v?= =?us-ascii?Q?VDIg9eJ6Hsl9PiJFIOjJg1aCZkp+G+YYWJazj0S1x/atI1/7w=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; AM3PR07MB1073; 6:mneyiPDbcJ6vGEVId9Nk7agoJ1omuTZAueax3cVRxIalrbyMcYwtxI+fZ2HB0VK8kzLAlvh2DsO67nWlLNm2c7cR/qfzJPQL8+C3Xgq4hsKAGjqshqkYRecFPD9Fpj8qLZlQc8U+jS3XYFib06vExnJdRAZAmkDwPcEScZ27uuqUl16RUwJ+r6FJEFH5semoddQWaVGOg1Clak05uOk2tiMelqrK9tZ6J3McXbrBnaRDIs0TxyHGrUmKojW25SxRgoRU12MzMEavQZqHkEm+q53ZQJVjS6G3tbUzwQlZjtsJnprnnWUZmo/nPzS3qVHFcdktS+BoSTBPE7NkjazFEg==; 5:fS57Ut/y5fjKAI15i135obO1FPmKOdtUEYQztlaNhZpM+zws5QYIflc/Zzen7ySG4nhTqU5wAa9QCqDKaa8UOp37aThUrK3QWulemZvwNRvKQSKtE27ny2JY2Z2hPZxPzm5mWynRmm/KLMMqXnNvxg==; 24:aL1vlCKlQM13Xr50ycim2AjFD9NDSqJZqY4cmYC36KLogAVSMCAia/N2fgT+cJmhcQMAV5RF3CUEHcXBjLLPOgz1IALfj13U5q+ofoAkLso=; 7:BeYAIiOMPSo8zg1qCwG6m9/KB/7vhNyKiGfPdTBYkMDSLFedf9xxzWPINJOjgXQ+2TiHYPkigtWyu9XNyuDU+8szo6phj2qBbJvlWgJprPEMja2x9bfQddLmcADdrS1npIfs8S8yV+E5aJb6QiczpLEFqQPtHxi7GsMg/t4RvWgzE1YUq0NrgeL/B1JFCcFgZZM9ASFt7MBOaNbqASUQm/O2wZXdk9lizC8kX5M3HVQyrU4SZEJOEYPKGAlWE3fW SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: nokia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Sep 2016 14:30:35.5251 (UTC) X-MS-Exchange-CrossTenant-Id: 5d471751-9675-428d-917b-70f44f9630b0 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5d471751-9675-428d-917b-70f44f9630b0; Ip=[131.228.2.240]; Helo=[fihe3nok0734.emea.nsn-net.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR07MB1073 X-Topics: patch Subject: [lng-odp] [PATCH 1/3] linux-gen: packet: enable parsing only selected packet header layers X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" Enable parsing packet headers up to a given protocol layer. Signed-off-by: Matias Elo --- .../linux-generic/include/odp_packet_internal.h | 24 +- platform/linux-generic/odp_classification.c | 2 +- platform/linux-generic/odp_packet.c | 293 ++++++++++++--------- 3 files changed, 193 insertions(+), 126 deletions(-) -- 2.7.4 diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 392d670..9b4f59e 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -41,7 +41,6 @@ typedef union { struct { uint64_t parsed_l2:1; /**< L2 parsed */ - uint64_t parsed_all:1;/**< Parsing complete */ uint64_t dst_queue:1; /**< Dst queue present */ uint64_t flow_hash:1; /**< Flow hash present */ @@ -131,6 +130,18 @@ ODP_STATIC_ASSERT(sizeof(output_flags_t) == sizeof(uint32_t), "OUTPUT_FLAGS_SIZE_ERROR"); /** + * Protocol stack layers + */ +typedef enum { + LAYER_NONE = 0, + LAYER_L1, + LAYER_L2, + LAYER_L3, + LAYER_L4, + LAYER_ALL +} layer_t; + +/** * Packet parser metadata */ typedef struct { @@ -145,6 +156,10 @@ typedef struct { uint32_t l3_len; /**< Layer 3 length */ uint32_t l4_len; /**< Layer 4 length */ + layer_t parsed_layers; /**< Highest parsed protocol stack layer */ + uint16_t ethtype; /**< EtherType */ + uint8_t ip_proto; /**< IP protocol */ + } packet_parser_t; /** @@ -300,7 +315,7 @@ static inline int packet_parse_l2_not_done(packet_parser_t *prs) static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr) { - return !pkt_hdr->p.input_flags.parsed_all; + return pkt_hdr->p.parsed_layers != LAYER_ALL; } /* Forward declarations */ @@ -316,6 +331,9 @@ void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len); /* Perform full packet parse */ int packet_parse_full(odp_packet_hdr_t *pkt_hdr); +/* Perform packet parse up to a given protocol layer */ +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer); + /* Reset parser metadata for a new parse */ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr); @@ -349,7 +367,7 @@ static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t *ts) } int packet_parse_common(packet_parser_t *pkt_hdr, const uint8_t *ptr, - uint32_t pkt_len, uint32_t seg_len); + uint32_t pkt_len, uint32_t seg_len, layer_t layer); int _odp_cls_parse(odp_packet_hdr_t *pkt_hdr, const uint8_t *parseptr); diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index ea223bf..868058d 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -821,7 +821,7 @@ int cls_classify_packet(pktio_entry_t *entry, const uint8_t *base, packet_parse_reset(pkt_hdr); packet_set_len(pkt_hdr, pkt_len); - packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len); + packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len, LAYER_ALL); cos = cls_select_cos(entry, base, pkt_hdr); if (cos == NULL) diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index c4cf324..5f84869 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -30,12 +30,13 @@ static inline void packet_parse_disable(odp_packet_hdr_t *pkt_hdr) { pkt_hdr->p.input_flags.parsed_l2 = 1; - pkt_hdr->p.input_flags.parsed_all = 1; + pkt_hdr->p.parsed_layers = LAYER_ALL; } void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) { /* Reset parser metadata before new parse */ + pkt_hdr->p.parsed_layers = LAYER_NONE; pkt_hdr->p.error_flags.all = 0; pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; @@ -50,6 +51,8 @@ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) static void packet_init(pool_entry_t *pool, odp_packet_hdr_t *pkt_hdr, size_t size, int parse) { + pkt_hdr->p.parsed_layers = LAYER_NONE; + pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; pkt_hdr->p.error_flags.all = 0; @@ -1166,151 +1169,185 @@ void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len) } /** - * Parse common packet headers + * Parse common packet headers up to given layer * * The function expects at least PACKET_PARSE_SEG_LEN bytes of data to be * available from the ptr. */ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, - uint32_t frame_len, uint32_t seg_len) + uint32_t frame_len, uint32_t seg_len, layer_t layer) { - const _odp_ethhdr_t *eth; - const _odp_vlanhdr_t *vlan; - uint16_t ethtype; uint32_t offset; - uint8_t ip_proto = 0; const uint8_t *parseptr; - uint16_t macaddr0, macaddr2, macaddr4; - - offset = sizeof(_odp_ethhdr_t); - if (packet_parse_l2_not_done(prs)) - packet_parse_l2(prs, frame_len); - - eth = (const _odp_ethhdr_t *)ptr; - - /* Handle Ethernet broadcast/multicast addresses */ - macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth)); - prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; - - if (macaddr0 == 0xffff) { - macaddr2 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 1)); - macaddr4 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 2)); - prs->input_flags.eth_bcast = - (macaddr2 == 0xffff) && (macaddr4 == 0xffff); - } else { - prs->input_flags.eth_bcast = 0; - } - - /* Get Ethertype */ - ethtype = odp_be_to_cpu_16(eth->type); - parseptr = (const uint8_t *)(eth + 1); - /* Check for SNAP vs. DIX */ - if (ethtype < _ODP_ETH_LEN_MAX) { - prs->input_flags.snap = 1; - if (ethtype > frame_len - offset) { - prs->error_flags.snap_len = 1; - goto parse_exit; + switch (prs->parsed_layers) { + case LAYER_NONE: + case LAYER_L2: + { + const _odp_ethhdr_t *eth; + uint16_t macaddr0, macaddr2, macaddr4; + const _odp_vlanhdr_t *vlan; + + offset = sizeof(_odp_ethhdr_t); + if (packet_parse_l2_not_done(prs)) + packet_parse_l2(prs, frame_len); + + eth = (const _odp_ethhdr_t *)ptr; + + /* Handle Ethernet broadcast/multicast addresses */ + macaddr0 = odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth)); + prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; + + if (macaddr0 == 0xffff) { + macaddr2 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 1)); + macaddr4 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 2)); + prs->input_flags.eth_bcast = + (macaddr2 == 0xffff) && (macaddr4 == 0xffff); + } else { + prs->input_flags.eth_bcast = 0; } - ethtype = odp_be_to_cpu_16(*((const uint16_t *) - (uintptr_t)(parseptr + 6))); - offset += 8; - parseptr += 8; - } - - /* Parse the VLAN header(s), if present */ - if (ethtype == _ODP_ETHTYPE_VLAN_OUTER) { - prs->input_flags.vlan_qinq = 1; - prs->input_flags.vlan = 1; - - vlan = (const _odp_vlanhdr_t *)parseptr; - ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); - } - - if (ethtype == _ODP_ETHTYPE_VLAN) { - prs->input_flags.vlan = 1; - vlan = (const _odp_vlanhdr_t *)parseptr; - ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); - } - /* Set l3_offset+flag only for known ethtypes */ - prs->input_flags.l3 = 1; - prs->l3_offset = offset; + /* Get Ethertype */ + prs->ethtype = odp_be_to_cpu_16(eth->type); + parseptr = (const uint8_t *)(eth + 1); + + /* Check for SNAP vs. DIX */ + if (prs->ethtype < _ODP_ETH_LEN_MAX) { + prs->input_flags.snap = 1; + if (prs->ethtype > frame_len - offset) { + prs->error_flags.snap_len = 1; + goto parse_exit; + } + prs->ethtype = odp_be_to_cpu_16(*((const uint16_t *) + (uintptr_t) + (parseptr + 6))); + offset += 8; + parseptr += 8; + } - /* Parse Layer 3 headers */ - switch (ethtype) { - case _ODP_ETHTYPE_IPV4: - prs->input_flags.ipv4 = 1; - ip_proto = parse_ipv4(prs, &parseptr, &offset, frame_len); - break; + /* Parse the VLAN header(s), if present */ + if (prs->ethtype == _ODP_ETHTYPE_VLAN_OUTER) { + prs->input_flags.vlan_qinq = 1; + prs->input_flags.vlan = 1; - case _ODP_ETHTYPE_IPV6: - prs->input_flags.ipv6 = 1; - ip_proto = parse_ipv6(prs, &parseptr, &offset, frame_len, - seg_len); - break; + vlan = (const _odp_vlanhdr_t *)parseptr; + prs->ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); + } - case _ODP_ETHTYPE_ARP: - prs->input_flags.arp = 1; - ip_proto = 255; /* Reserved invalid by IANA */ - break; + if (prs->ethtype == _ODP_ETHTYPE_VLAN) { + prs->input_flags.vlan = 1; + vlan = (const _odp_vlanhdr_t *)parseptr; + prs->ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); + } - default: - prs->input_flags.l3 = 0; - prs->l3_offset = ODP_PACKET_OFFSET_INVALID; - ip_proto = 255; /* Reserved invalid by IANA */ + prs->l3_offset = offset; + prs->parsed_layers = LAYER_L2; + if (layer == LAYER_L2) + return prs->error_flags.all != 0; } + case LAYER_L3: + { + offset = prs->l3_offset; + parseptr = (const uint8_t *)(ptr + offset); + /* Set l3_offset+flag only for known ethtypes */ + prs->input_flags.l3 = 1; + + /* Parse Layer 3 headers */ + switch (prs->ethtype) { + case _ODP_ETHTYPE_IPV4: + prs->input_flags.ipv4 = 1; + prs->ip_proto = parse_ipv4(prs, &parseptr, &offset, + frame_len); + break; + + case _ODP_ETHTYPE_IPV6: + prs->input_flags.ipv6 = 1; + prs->ip_proto = parse_ipv6(prs, &parseptr, &offset, + frame_len, seg_len); + break; + + case _ODP_ETHTYPE_ARP: + prs->input_flags.arp = 1; + prs->ip_proto = 255; /* Reserved invalid by IANA */ + break; + + default: + prs->input_flags.l3 = 0; + prs->l3_offset = ODP_PACKET_OFFSET_INVALID; + prs->ip_proto = 255; /* Reserved invalid by IANA */ + } - /* Set l4_offset+flag only for known ip_proto */ - prs->input_flags.l4 = 1; - prs->l4_offset = offset; - - /* Parse Layer 4 headers */ - switch (ip_proto) { - case _ODP_IPPROTO_ICMP: - prs->input_flags.icmp = 1; - break; - - case _ODP_IPPROTO_TCP: - if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) - return -1; - prs->input_flags.tcp = 1; - parse_tcp(prs, &parseptr, NULL); - break; - - case _ODP_IPPROTO_UDP: - if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) - return -1; - prs->input_flags.udp = 1; - parse_udp(prs, &parseptr, NULL); - break; + /* Set l4_offset+flag only for known ip_proto */ + prs->l4_offset = offset; + prs->parsed_layers = LAYER_L3; + if (layer == LAYER_L3) + return prs->error_flags.all != 0; + } + case LAYER_L4: + { + offset = prs->l4_offset; + parseptr = (const uint8_t *)(ptr + offset); + prs->input_flags.l4 = 1; + + /* Parse Layer 4 headers */ + switch (prs->ip_proto) { + case _ODP_IPPROTO_ICMP: + prs->input_flags.icmp = 1; + break; + + case _ODP_IPPROTO_TCP: + if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) + return -1; + prs->input_flags.tcp = 1; + parse_tcp(prs, &parseptr, NULL); + break; + + case _ODP_IPPROTO_UDP: + if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) + return -1; + prs->input_flags.udp = 1; + parse_udp(prs, &parseptr, NULL); + break; + + case _ODP_IPPROTO_AH: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_ah = 1; + break; + + case _ODP_IPPROTO_ESP: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_esp = 1; + break; + + default: + prs->input_flags.l4 = 0; + prs->l4_offset = ODP_PACKET_OFFSET_INVALID; + break; + } - case _ODP_IPPROTO_AH: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_ah = 1; + prs->parsed_layers = LAYER_L4; break; - - case _ODP_IPPROTO_ESP: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_esp = 1; + } + case LAYER_ALL: break; default: - prs->input_flags.l4 = 0; - prs->l4_offset = ODP_PACKET_OFFSET_INVALID; - break; + ODP_ERR("Invalid parse layer: %d\n", (int)layer); + return -1; } + prs->parsed_layers = LAYER_ALL; + parse_exit: - prs->input_flags.parsed_all = 1; return prs->error_flags.all != 0; } @@ -1323,5 +1360,17 @@ int packet_parse_full(odp_packet_hdr_t *pkt_hdr) void *base = packet_map(pkt_hdr, 0, &seg_len); return packet_parse_common(&pkt_hdr->p, base, pkt_hdr->frame_len, - seg_len); + seg_len, LAYER_ALL); +} + +/** + * Simple packet parser + */ +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer) +{ + uint32_t seg_len; + void *base = packet_map(pkt_hdr, 0, &seg_len); + + return packet_parse_common(&pkt_hdr->p, base, pkt_hdr->frame_len, + seg_len, layer); }