From patchwork Thu Oct 19 10:15:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ori Kam X-Patchwork-Id: 30579 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 0D59E1B1BB; Thu, 19 Oct 2017 12:15:29 +0200 (CEST) Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01on0087.outbound.protection.outlook.com [104.47.1.87]) by dpdk.org (Postfix) with ESMTP id A36261B1BA for ; Thu, 19 Oct 2017 12:15:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=FGxrdTanp7pVTA7NiaC3Xb0wWxUy65UNk5/R6wTCejc=; b=pUTWwgVtFQzWObL8tmBhxNQlk/FSclxLBGpcPsADe/M053Dp9KaP7YZIq/rgb6oRNrZOYOHDk+K8UZC2I5VkHdFQfeOu1T4Dd+dJwsKDmPlfxPTn5QaLVXYbIOw+Ulr0Nx84hFXSMnOCJlwUo+jj6hM1N8Mvnq23jqNnPuwclxM= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=orika@mellanox.com; Received: from localhost.localdomain (82.166.227.17) by HE1PR05MB3212.eurprd05.prod.outlook.com (2603:10a6:7:35::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.77.7; Thu, 19 Oct 2017 10:15:24 +0000 From: Ori Kam To: adrien.mazarguil@6wind.com, john.mcnamara@intel.com, thomas@monjalon.net Cc: dev@dpdk.org, orika@mellanox.com Date: Thu, 19 Oct 2017 13:15:08 +0300 Message-Id: <1508408108-8672-1-git-send-email-orika@mellanox.com> X-Mailer: git-send-email 1.7.1 MIME-Version: 1.0 X-Originating-IP: [82.166.227.17] X-ClientProxiedBy: VI1PR0501CA0015.eurprd05.prod.outlook.com (2603:10a6:800:92::25) To HE1PR05MB3212.eurprd05.prod.outlook.com (2603:10a6:7:35::10) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 6894394e-d36f-4b9b-85b9-08d516da5087 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(2017030254152)(48565401081)(2017052603199)(201703131423075)(201703031133081)(201702281549075); SRVR:HE1PR05MB3212; X-Microsoft-Exchange-Diagnostics: 1; HE1PR05MB3212; 3:NN3FQJJBkJRoV419yWbfnPGA43IEgrQaLXDZ7HUWBKd6tWjiqezAcLUlqQ4jkU1AoDXGPosblZ6JId9QMrh3hLrlhgjIb4qWok5Fx5txOn3Pcpjo5bQQwcCbJ4Nc0TxQzcqqUXhAga43AHUX4PyCNupqi32PxEj+zOoHOv6FfymFzqMdOAGPt6F7rsEOUhhtDwYLkN2yNWmxlaOSG6V8N9kfi+HA2KfNJpTRydPVmJEFWjJeWS7p07Xzso2EdhUH; 25:xo68OAUKCR3i76SiCPXZpyiuCv9i2PvbFu/Z9mK0nevIMtffC26lyvc69LPOVj6jQh3lzRgFSVj82OaEJlG3J6MDOgxXgx4je0QR/W9pP6QLLG879Ia7TBEcXjT0J4zl/wwUi902/bo+K4HWdnRK5n+Kc5zr9DGwIGiYDk+LieJqhyva9z52JzgPQZyQ55RkZU6/91e0cwWtCC4wO2wsDLUSqRaUNeLbYdaziZAtcg0sq2b7f3ZN3udWl4vDVRQNncNAkEyALdIwDEHvZobnqI1imbaM67eXt0Awq1pKAONMS9J72qFTEha3i6InDjQzGnXh88aD59n10AIV9tKoUf/N0Sq1lXDuWFOFocpsAkQ=; 31:S5vytXOZG4R2kAP+uA+JQS9HVB/a579Bzi/pr6hxt5gDXS4LbYCXVctkldV5aI8dL144+3gFHWcbjH+7ttmKof+/vIDUT7Wi73naTQS/lCTDqnnNXjalN0M562jnl8oFddURXsTV0fooC7QzXusgT2Bh4HbrQibT9LhIr4mDwHukAqB9xISFf57iypCxds1Egs0RgDD9ONXw0Z50U++MiTrVQyAucXzYs24WbEwwOfE= X-MS-TrafficTypeDiagnostic: HE1PR05MB3212: X-LD-Processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr X-Microsoft-Exchange-Diagnostics: 1; HE1PR05MB3212; 20:OXMgYhqgV+5XqunYW0wRfDi6mm3El6leBJalNmCXyGoFRMGdQ9QC8yfJVHDpz7Jg/k3xxqEP33ogTC4xCu0yf2A+0Ivyf45U59mameUJ96WEel5yN+dXsQ7J7CVpGfd4JnAszPIGFpP/2NOZopDQinriyRYwI5mShHcQHoIzsqsvc1loUniXmwCKRCDXleIooj2wLwn1HXXx+XYV/mR0UlpuAR4wb80Pn8znb9sL6LNU9rY5l1R0rxNMjh9+E+927RVPRTdbSnOgXMS8ZQJicY2q9KFAIyKfLNqZsQeFNgJB7CRCYtSSM4eu5B9KugJuOnYIH+3KqPlxM4QLu1VPhOu4YfFuBkEcKVY7BF00ONjsgbLhGwGgHAYl860Ppw42nESZBAKp3hyOdZGHO5Flnp3p/oQGu1GONe8XFD8zcKA/ePC5LKN+dm2ABASZgrknY8/GgOWNMXy4E7hjAnEXaV+6Fjhi+uBweHBCA4PZmHZyyf/zVLuP+Jwgf768qZh7; 4:WgKk6I7H51fxxrnUjkdaVp/OonRwxTa+R1GYUgPgWHMxD7LPJfqT3QUzywbjvjhpWjaQVEF9+XxxYbq9FjwSZEcmWy/ppLFGO7LKuT4Fq4V565N2L86yxrUJ0LmTOOR2u4UfRG19hafu4JZagrXA+T3dzCyNvZU2rP/yYtmSt2baXyssQrDaamDlEU+4nMjsze32/kJiWjGYNnhNw3FXNHDJSAIR51ncsn0dPQX0cQ6jM15mLfB3Qff4PrtFYPLP+urxREM+m0ODNi6LmNG0mr4/wRtGRhW9yi0qYvD1/QYq90YqhD/A9mt/A26C7D+Od0+41lcAyKtJ5sZOtXUyxVrwgBJqoOB+wuA51u6Qhy5TMjzDwUYK5H/W+Ibt3A4z X-Exchange-Antispam-Report-Test: UriScan:(200054503718035)(116097685857584)(211171220733660); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(93006095)(93001095)(10201501046)(3002001)(100000703101)(100105400095)(6055026)(6041248)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123558100)(20161123560025)(20161123555025)(20161123562025)(20161123564025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:HE1PR05MB3212; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:HE1PR05MB3212; X-Forefront-PRVS: 0465429B7F X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6069001)(6009001)(39860400002)(346002)(376002)(189002)(199003)(7736002)(48376002)(66066001)(81166006)(305945005)(8676002)(81156014)(50466002)(97736004)(107886003)(8936002)(50226002)(2906002)(6116002)(68736007)(101416001)(3846002)(50986999)(47776003)(6512007)(53936002)(6486002)(6506006)(25786009)(105586002)(16526018)(36756003)(33646002)(316002)(16586007)(5660300001)(4326008)(86362001)(6666003)(189998001)(5003940100001)(478600001)(106356001); DIR:OUT; SFP:1101; SCL:1; SRVR:HE1PR05MB3212; H:localhost.localdomain; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; HE1PR05MB3212; 23:qdT7oHKl+oow793zzZMj2VhniGiJd1LA0R3fm5a4R?= BjgZ3otSh4RrABptQJRLqIdrgq5fUeojboyLZhGSRvCBzz5OgS8YbnJARrvsdMWgUjD/Z+hq0/+dz7jWARJBC6XcaYY8JaPDiaTbG0Hfx9K8msHDPcg+YuckZe5m/KL3+cRZ4XxPbxB2J63E02FCE3/S8dsXBlWnDKyf604axn1a3gEZvphcoENUYmzSFdBVdtMRRcVUyABlpQmX4piZPgqm0n4Xj/y6505pUJoS5MsTrUQTPCZxTUa3DXkZWqD1DW2O14HWZ5yrF9NlztJS03aUiTCdxTuIFZIUh8N2olRO7YYhsNXGHb+6ZzfAGbi4dkWhNAEy7rMcUNC9JEvR7syicUROe4t3OH9OuH8NcXEHYcMk4+wgKmONVMExtNpQFkePzFoKdqqH0uH73Db/X7ZtvZxYZigPo44Tvxj2ShpCnkubjYtNlDYhuArDmuma3DMUlNay73kERgY/hAIanV++WlAM8sJ/j4Hh1YKzoktOZYXUAvuFwQlbswplDaARAFStTYseQTB4TsT68a7yTVLyj5GJ/RCPoEikzRzqnPmaF4lOrvyuS7nyVXcY1WUrGveJDibQGcxMsZZhzkdxm/et/dGJ531faFWPzRlLNYzNdFuKV5OaK1jc3QOjbLEAy2fK1ArhPzNtyK+CKsNQRamVIaRAR6dvVLGvaWnNQOx9SeiR/70LgNaoi+jJiibB/8L/0H+ojdtJUF3YRcSnsHmbdpIw+bnlyrFY4NmjX7DoqHatb4llFBYCKoabQAfFgFo2ekLK7S77TUj/lyVwdzN83XkiDwGJm1UZp28rsnltu2+ePx0we/mbq43rqrKF/XAg2MLmnTggxCDL28RUtElWpX8QeGmiH30FdN9QauBCSQ4Z4/8R2rDoubG3LojOtdkWZCScLk7GqeSA4FzGEsAqcjjdJ83mjZGyhLU182v9x3L5X0cWEtq/J8AxBlWCdGWUcZym+5eZNNo1K7oALQCRGYwGIR2r0MCRy3gakd1GAHAjMyDKNgVP/GDRmIvmYA= X-Microsoft-Exchange-Diagnostics: 1; HE1PR05MB3212; 6:O0OigxG6+9px6S/zsojmRpLsCoUXDiWC0a0hxsEBTgA3ogxvTutLmZz22b808NpeGYmBfO+CuWjYxxFcfq8p2BeQfb/CMeUj/uyqXBR9SBYDRXLqmziZFHPc73jl5Y59fV8XV3PGYm+en8JGRF1KDPWgaaGYcEgFgaG2mg/VtU8A/bexp2wnCGWGh7SjPM1GH7QuT+foOeG7gcaCnT/dCfaYn7F5FA2hN/Xp7HNd6U/iD8964qVttjlw9xcftdc9UycvGqqD8tlh8X59U6k7RNMSXxdLvscfdNWJyxudHA6Gdqcaf1ZKYZr/mOovOKPqzgR4Vvqk5lpDwn7UotF+LA==; 5:FYA9ecol7SRCB6ECXkvSRhAimZkE8toAGuH3V/0TmrayLsafo8bYZ8OThtmu6vtIOhNjc0eRGDa4/A5Yf24PuZT8Q4Rd/JAPK4nCwjPvnCr8Ue+xTf8KpceT6mB/vLHkJy28mZ4B0X0s29O6tANedw==; 24:fJMIqddkGG4YHU4DwZVyxuJZeKQ4lZU4Up3LtEGHKn7dA46WA3QIjMZBGF4WoL0tFuebEn8asO66STLcpRzkpqUyQPoc/aa7L4qG85QpMI4=; 7:htp8VrzRdyarG4eTD4xb/W9lEB/p5x0g6vU9lr8s1XU61D2b1863/Rxtf/fl8hXMYy/rBs1F8klifMqbbSdziCqbbhqneUK59lkNFq6c2yPrHqLuPTEC/lyn/5Yqq1/wgHD7xDQSrx67TKormW3WtAlkGpttQ84tnAa4oqxHXEgwww00LDztXbT3ZwUfE9PO+rwH/L6k6lXBpy3Un7ibLuzj5MvS/znS9WKeWZK0hvg= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Oct 2017 10:15:24.2064 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR05MB3212 Subject: [dpdk-dev] [PATCH 1/2] examples/flow_filtering: demo of simple rte flow X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This application shows a simple usage of the rte_flow API for hardware filtering offloading. In this demo we are filtering specific IP to specific target queue, while sending all the rest of the packets to other queue. Signed-off-by: Ori Kam --- examples/flow_filtering/Makefile | 17 +++ examples/flow_filtering/flow_blocks.c | 150 +++++++++++++++++++++ examples/flow_filtering/main.c | 244 ++++++++++++++++++++++++++++++++++ 3 files changed, 411 insertions(+) create mode 100644 examples/flow_filtering/Makefile create mode 100644 examples/flow_filtering/flow_blocks.c create mode 100644 examples/flow_filtering/main.c diff --git a/examples/flow_filtering/Makefile b/examples/flow_filtering/Makefile new file mode 100644 index 0000000..6e5295d --- /dev/null +++ b/examples/flow_filtering/Makefile @@ -0,0 +1,17 @@ +ifeq ($(RTE_SDK),) +$(error "Please define RTE_SDK environment variable") +endif + +# Default target, can be overridden by command line or environment +RTE_TARGET ?= x86_64-native-linuxapp-gcc + +include $(RTE_SDK)/mk/rte.vars.mk + +APP = flow + +SRCS-y := main.c + +CFLAGS += -g3 +CFLAGS += $(WERROR_FLAGS) + +include $(RTE_SDK)/mk/rte.extapp.mk diff --git a/examples/flow_filtering/flow_blocks.c b/examples/flow_filtering/flow_blocks.c new file mode 100644 index 0000000..7ec2d01 --- /dev/null +++ b/examples/flow_filtering/flow_blocks.c @@ -0,0 +1,150 @@ +/*- + * BSD LICENSE + * + * Copyright 2017 Mellanox. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of 6WIND S.A. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define MAX_PATTERN_NUM 4 + +static struct rte_flow * +generate_ipv4_flow(uint8_t port_id, uint16_t rx_q, + uint32_t src_ip, uint32_t src_mask, + uint32_t dest_ip, uint32_t dest_mask, + struct rte_flow_error *error); + + +/** + * create a flow rule that sends packets with matching src and dest ip + * to selected queue. + * + * @param port_id + * The selected port. + * @param rx_q + * The selected target queue. + * @param src_ip + * The src ip value to match the input packet. + * @param src_mask + * The mask to apply to the src ip. + * @param dest_ip + * The dest ip value to match the input packet. + * @param dest_mask + * The mask to apply to the dest ip. + * @param[out] error + * Perform verbose error reporting if not NULL. + * + * @return + * A flow if the rule could be created else return NULL. + */ +static struct rte_flow * +generate_ipv4_flow(uint8_t port_id, uint16_t rx_q, + uint32_t src_ip, uint32_t src_mask, + uint32_t dest_ip, uint32_t dest_mask, + struct rte_flow_error *error) +{ + struct rte_flow_attr attr; + struct rte_flow_item pattern[MAX_PATTERN_NUM]; + struct rte_flow_action action[MAX_PATTERN_NUM]; + struct rte_flow *flow = NULL; + struct rte_flow_action_queue queue = { .index = rx_q }; + struct rte_flow_item_eth eth_spec; + struct rte_flow_item_eth eth_mask; + struct rte_flow_item_vlan vlan_spec; + struct rte_flow_item_vlan vlan_mask; + struct rte_flow_item_ipv4 ip_spec; + struct rte_flow_item_ipv4 ip_mask; + int res; + + memset(pattern, 0, sizeof(pattern)); + memset(action, 0, sizeof(action)); + + /* + * set the rule attribute. + * in this case only ingress packets will be checked. + */ + memset(&attr, 0, sizeof(struct rte_flow_attr)); + attr.ingress = 1; + + /* + * create the action sequence. + * one action only, move packet to queue + */ + + action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE; + action[0].conf = &queue; + action[1].type = RTE_FLOW_ACTION_TYPE_END; + + /* + * set the first level of the pattern (eth). + * since in this example we just want to get the + * ipv4 we set this level to allow all. + */ + memset(ð_spec, 0, sizeof(struct rte_flow_item_eth)); + memset(ð_mask, 0, sizeof(struct rte_flow_item_eth)); + eth_spec.type = 0; + eth_mask.type = 0; + pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; + pattern[0].spec = ð_spec; + pattern[0].mask = ð_mask; + + /* + * setting the second level of the pattern (vlan). + * since in this example we just want to get the + * ipv4 we also set this level to allow all. + */ + memset(&vlan_spec, 0, sizeof(struct rte_flow_item_vlan)); + memset(&vlan_mask, 0, sizeof(struct rte_flow_item_vlan)); + pattern[1].type = RTE_FLOW_ITEM_TYPE_VLAN; + pattern[1].spec = &vlan_spec; + pattern[1].mask = &vlan_mask; + + /* + * setting the third level of the pattern (ip). + * in this example this is the level we care about + * so we set it according to the parameters. + */ + memset(&ip_spec, 0, sizeof(struct rte_flow_item_ipv4)); + memset(&ip_mask, 0, sizeof(struct rte_flow_item_ipv4)); + ip_spec.hdr.dst_addr = htonl(dest_ip); + ip_mask.hdr.dst_addr = dest_mask; + ip_spec.hdr.src_addr = htonl(src_ip); + ip_mask.hdr.src_addr = src_mask; + pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4; + pattern[2].spec = &ip_spec; + pattern[2].mask = &ip_mask; + + /* the final level must be always type end */ + pattern[3].type = RTE_FLOW_ITEM_TYPE_END; + + res = rte_flow_validate(port_id, &attr, pattern, action, error); + if (!res) + flow = rte_flow_create(port_id, &attr, pattern, action, error); + + return flow; +} + diff --git a/examples/flow_filtering/main.c b/examples/flow_filtering/main.c new file mode 100644 index 0000000..62e95d8 --- /dev/null +++ b/examples/flow_filtering/main.c @@ -0,0 +1,244 @@ +/*- + * BSD LICENSE + * + * Copyright 2017 Mellanox. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of 6WIND S.A. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile bool force_quit; + +static uint8_t port_id; +static uint16_t nr_queues = 5; +static uint8_t selected_queue = 1; +struct rte_mempool *mbuf_pool; +struct rte_flow *flow; + +#define SRC_IP ((0<<24) + (0<<16) + (0<<8) + 0) /* src ip = 0.0.0.0 */ +#define DEST_IP ((192<<24) + (168<<16) + (1<<8) + 1) /* dest ip = 192.168.1.1 */ +#define FULL_MASK 0xffffffff /* full mask */ +#define EMPTY_MASK 0x0 /* empty mask */ + +#include "flow_blocks.c" + +static inline void +print_ether_addr(const char *what, struct ether_addr *eth_addr) +{ + char buf[ETHER_ADDR_FMT_SIZE]; + ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, eth_addr); + printf("%s%s", what, buf); +} + +static void +main_loop(void) +{ + struct rte_mbuf *mbufs[32]; + struct ether_hdr *eth_hdr; + struct rte_flow_error error; + uint16_t nb_rx; + uint16_t i; + uint16_t j; + + while (!force_quit) { + for (i = 0; i < nr_queues; i++) { + nb_rx = rte_eth_rx_burst(port_id, + i, mbufs, 32); + if (nb_rx) { + for (j = 0; j < nb_rx; j++) { + struct rte_mbuf *m = mbufs[j]; + + eth_hdr = rte_pktmbuf_mtod(m, + struct ether_hdr *); + print_ether_addr("src=", + ð_hdr->s_addr); + print_ether_addr(" - dst=", + ð_hdr->d_addr); + printf(" - queue=0x%x", + (unsigned int)i); + printf("\n"); + + rte_pktmbuf_free(m); + } + } + } + } + + /* closing and releasing resources */ + rte_flow_flush(port_id, &error); + rte_eth_dev_stop(port_id); + rte_eth_dev_close(port_id); +} + +static void +assert_link_status(void) +{ + struct rte_eth_link link; + + memset(&link, 0, sizeof(link)); + rte_eth_link_get(port_id, &link); + if (link.link_status == ETH_LINK_DOWN) + rte_exit(EXIT_FAILURE, ":: error: link is still down\n"); +} + +static void +init_port(void) +{ + int ret; + uint16_t i; + struct rte_flow_error error; + struct rte_eth_conf port_conf = { + .rxmode = { + .split_hdr_size = 0, + /**< Header Split disabled */ + .header_split = 0, + /**< IP checksum offload disabled */ + .hw_ip_checksum = 0, + /**< VLAN filtering disabled */ + .hw_vlan_filter = 0, + /**< Jumbo Frame Support disabled */ + .jumbo_frame = 0, + /**< CRC stripped by hardware */ + .hw_strip_crc = 1, + }, + }; + + printf(":: initializing port: %d\n", port_id); + ret = rte_eth_dev_configure(port_id, + nr_queues, nr_queues, &port_conf); + if (ret < 0) { + rte_exit(EXIT_FAILURE, + ":: cannot configure device: err=%d, port=%u\n", + ret, port_id); + } + + /* only set Rx queues: something we care only so far */ + for (i = 0; i < nr_queues; i++) { + ret = rte_eth_rx_queue_setup(port_id, i, 512, + rte_eth_dev_socket_id(port_id), + NULL, + mbuf_pool); + if (ret < 0) { + rte_exit(EXIT_FAILURE, + ":: Rx queue setup failed: err=%d, port=%u\n", + ret, port_id); + } + } + + /* create flow for send packet with */ + flow = generate_ipv4_flow(port_id, selected_queue, + SRC_IP, EMPTY_MASK, + DEST_IP, FULL_MASK, &error); + if (!flow) { + printf("Flow can't be created %d message: %s\n", + error.type, + error.message ? error.message : "(no stated reason)"); + rte_exit(EXIT_FAILURE, "error in creating flow"); + } + + rte_eth_promiscuous_enable(port_id); + ret = rte_eth_dev_start(port_id); + if (ret < 0) { + rte_exit(EXIT_FAILURE, + "rte_eth_dev_start:err=%d, port=%u\n", + ret, port_id); + } + + assert_link_status(); + + printf(":: initializing port: %d done\n", port_id); +} + +static void +signal_handler(int signum) +{ + if (signum == SIGINT || signum == SIGTERM) { + printf("\n\nSignal %d received, preparing to exit...\n", + signum); + force_quit = true; + } +} + +int +main(int argc, char **argv) +{ + int ret; + uint8_t nr_ports; + + ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, ":: invalid EAL arguments\n"); + + force_quit = false; + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + + nr_ports = rte_eth_dev_count(); + if (nr_ports == 0) + rte_exit(EXIT_FAILURE, ":: no Ethernet ports found\n"); + port_id = 0; + if (nr_ports != 1) { + printf(":: warn: %d ports detected, but we use only one: port %u\n", + nr_ports, port_id); + } + mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", 4096, 128, 0, + RTE_MBUF_DEFAULT_BUF_SIZE, + rte_socket_id()); + if (mbuf_pool == NULL) + rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n"); + + init_port(); + + main_loop(); + + return 0; +}