From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E73B942F9B; Tue, 1 Aug 2023 18:05:18 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A746843253; Tue, 1 Aug 2023 18:05:16 +0200 (CEST) Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) by mails.dpdk.org (Postfix) with ESMTP id 2201343067 for ; Tue, 1 Aug 2023 18:05:15 +0200 (CEST) Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-1bba04b9df3so46342745ad.0 for ; Tue, 01 Aug 2023 09:05:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20221208.gappssmtp.com; s=20221208; t=1690905914; x=1691510714; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=OvjZ3I+6n8/cFyiZLKuDKsl/QkFFmTzjjjFsoREh740=; b=QxaQNOBn7c7kjZ//j3+kBXTD2myXsnyRflRxK+vSAF62YsPXCGeLEntcuKT2DRg2Od naESgpDJo2XDMzL13ApkHbNMlF8P4s76KovOU3/h1KZVH89GQ+O3QpNSAg6/eBegTOi8 n4TiSxPOxa4aWnq2Fea15i4eLcJssBjkiUjGbMNWNwvRcNV1/LnxKGbZZbnQLkqSyF1S n25azxlecaSrpp3O+5n/39rdTPBj/WnuSVdUy6bTssC9R1nSve4NfjvNmqprDyvWkU/a 8yV+kA9JvFcVhjDVp0r0PHQIDzTWO07N/VkggD9Gjiemi3Bk9qlIgtRRcKlJhFN5hKsD lZzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690905914; x=1691510714; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=OvjZ3I+6n8/cFyiZLKuDKsl/QkFFmTzjjjFsoREh740=; b=BOUIVlTEY3TuAjCEA2tL3Mcp/VCt9snDBPm98njzPzSHhVPJc+i7/aG5gUH9xtqN5K 274YstuRNUPCtwv+48VLT6iXNhec650AD2LBDwi9QhaRyvsy1axVrl6incd+Ign/XBV1 0sBv2z8W9ism5WLpNh4gQKBBG7MZxGMsWCEOEjMNbgpEUITcy7xZ4r4OdxTMfIneSCGH E9IIW3PIpfVT7jGeIzudmCr0YRI1WhTMNf/C7o2Fk9JkxmnCrgx9Z2lvwIGaig55yv7B SutdBgvLJGoqb2JdciF+wcJ/HE6kaWMu6vNjzFTRAR8sgnd8LQovXJnwKtn1n3UJ5dRL AFyw== X-Gm-Message-State: ABy/qLZ7pXwJptVI7r+ZcJuQUxDJsCEmyTGqVVJeEe3Z1oHQKu5vqAdY nA2fXHpcBLV5z0qU1fRg4doSwCxJOMVcq9yxbyPOTA== X-Google-Smtp-Source: APBJJlHQtFBWLDILb+xU3z4J7GnJdUv+t9c5sGL6JsDvoHPblFKLwiTOaOBlP/k9DibSnzJabp3zHw== X-Received: by 2002:a17:902:d2d1:b0:1b2:fa8:d9c9 with SMTP id n17-20020a170902d2d100b001b20fa8d9c9mr15762378plc.49.1690905912293; Tue, 01 Aug 2023 09:05:12 -0700 (PDT) Received: from hermes.local (204-195-127-207.wavecable.com. [204.195.127.207]) by smtp.gmail.com with ESMTPSA id li11-20020a170903294b00b001b89f6550d1sm10655939plb.16.2023.08.01.09.05.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Aug 2023 09:05:11 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger , Thomas Monjalon , Bruce Richardson Subject: [PATCH v2 1/2] flow_classify: remove library Date: Tue, 1 Aug 2023 09:04:59 -0700 Message-Id: <20230801160500.67480-2-stephen@networkplumber.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230801160500.67480-1-stephen@networkplumber.org> References: <20230801160500.67480-1-stephen@networkplumber.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The flow_classify library was marked for removal last year because there was no maintainer and the functionality is limited. Signed-off-by: Stephen Hemminger --- MAINTAINERS | 7 - app/test/meson.build | 4 - app/test/test_flow_classify.c | 895 ------------------ app/test/test_flow_classify.h | 26 - doc/api/doxy-api-index.md | 1 - doc/api/doxy-api.conf.in | 1 - doc/guides/freebsd_gsg/build_sample_apps.rst | 2 +- doc/guides/freebsd_gsg/install_from_ports.rst | 2 +- doc/guides/prog_guide/flow_classify_lib.rst | 424 --------- doc/guides/prog_guide/index.rst | 1 - doc/guides/rel_notes/deprecation.rst | 8 +- doc/guides/rel_notes/release_23_11.rst | 2 + doc/guides/sample_app_ug/flow_classify.rst | 242 ----- doc/guides/sample_app_ug/index.rst | 1 - examples/flow_classify/Makefile | 51 - examples/flow_classify/flow_classify.c | 878 ----------------- examples/flow_classify/ipv4_rules_file.txt | 14 - examples/flow_classify/meson.build | 13 - examples/meson.build | 1 - lib/flow_classify/meson.build | 12 - lib/flow_classify/rte_flow_classify.c | 670 ------------- lib/flow_classify/rte_flow_classify.h | 284 ------ lib/flow_classify/rte_flow_classify_parse.c | 532 ----------- lib/flow_classify/rte_flow_classify_parse.h | 58 -- lib/flow_classify/version.map | 13 - lib/meson.build | 3 - meson_options.txt | 2 +- 27 files changed, 6 insertions(+), 4141 deletions(-) delete mode 100644 app/test/test_flow_classify.c delete mode 100644 app/test/test_flow_classify.h delete mode 100644 doc/guides/prog_guide/flow_classify_lib.rst delete mode 100644 doc/guides/sample_app_ug/flow_classify.rst delete mode 100644 examples/flow_classify/Makefile delete mode 100644 examples/flow_classify/flow_classify.c delete mode 100644 examples/flow_classify/ipv4_rules_file.txt delete mode 100644 examples/flow_classify/meson.build delete mode 100644 lib/flow_classify/meson.build delete mode 100644 lib/flow_classify/rte_flow_classify.c delete mode 100644 lib/flow_classify/rte_flow_classify.h delete mode 100644 lib/flow_classify/rte_flow_classify_parse.c delete mode 100644 lib/flow_classify/rte_flow_classify_parse.h delete mode 100644 lib/flow_classify/version.map diff --git a/MAINTAINERS b/MAINTAINERS index 18bc05fccd0d..dbb25211c367 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1511,13 +1511,6 @@ F: lib/pdcp/ F: doc/guides/prog_guide/pdcp_lib.rst F: app/test/test_pdcp* -Flow Classify - EXPERIMENTAL - UNMAINTAINED -F: lib/flow_classify/ -F: app/test/test_flow_classify* -F: doc/guides/prog_guide/flow_classify_lib.rst -F: examples/flow_classify/ -F: doc/guides/sample_app_ug/flow_classify.rst - Distributor M: David Hunt F: lib/distributor/ diff --git a/app/test/meson.build b/app/test/meson.build index b89cf0368fb5..90a2e350c7ae 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -359,10 +359,6 @@ if dpdk_conf.has('RTE_EVENT_SKELETON') test_deps += 'event_skeleton' endif -if dpdk_conf.has('RTE_LIB_FLOW_CLASSIFY') - test_sources += 'test_flow_classify.c' - fast_tests += [['flow_classify_autotest', false, true]] -endif if dpdk_conf.has('RTE_LIB_GRAPH') test_sources += 'test_graph.c' fast_tests += [['graph_autotest', true, true]] diff --git a/app/test/test_flow_classify.c b/app/test/test_flow_classify.c deleted file mode 100644 index 6e274d88e645..000000000000 --- a/app/test/test_flow_classify.c +++ /dev/null @@ -1,895 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#include -#include - -#include "test.h" - -#include -#include -#include -#include - -#ifdef RTE_EXEC_ENV_WINDOWS -static int -test_flow_classify(void) -{ - printf("flow_classify not supported on Windows, skipping test\n"); - return TEST_SKIPPED; -} - -#else - -#include -#include -#include -#include -#include - -#include "packet_burst_generator.h" -#include "test_flow_classify.h" - - -#define FLOW_CLASSIFY_MAX_RULE_NUM 100 -#define MAX_PKT_BURST 32 -#define NB_SOCKETS 4 -#define MEMPOOL_CACHE_SIZE 256 -#define MBUF_SIZE 512 -#define NB_MBUF 512 - -/* test UDP, TCP and SCTP packets */ -static struct rte_mempool *mbufpool[NB_SOCKETS]; -static struct rte_mbuf *bufs[MAX_PKT_BURST]; - -static struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { - /* first input field - always one byte long. */ - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint8_t), - .field_index = PROTO_FIELD_IPV4, - .input_index = PROTO_INPUT_IPV4, - .offset = sizeof(struct rte_ether_hdr) + - offsetof(struct rte_ipv4_hdr, next_proto_id), - }, - /* next input field (IPv4 source address) - 4 consecutive bytes. */ - { - /* rte_flow uses a bit mask for IPv4 addresses */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint32_t), - .field_index = SRC_FIELD_IPV4, - .input_index = SRC_INPUT_IPV4, - .offset = sizeof(struct rte_ether_hdr) + - offsetof(struct rte_ipv4_hdr, src_addr), - }, - /* next input field (IPv4 destination address) - 4 consecutive bytes. */ - { - /* rte_flow uses a bit mask for IPv4 addresses */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint32_t), - .field_index = DST_FIELD_IPV4, - .input_index = DST_INPUT_IPV4, - .offset = sizeof(struct rte_ether_hdr) + - offsetof(struct rte_ipv4_hdr, dst_addr), - }, - /* - * Next 2 fields (src & dst ports) form 4 consecutive bytes. - * They share the same input index. - */ - { - /* rte_flow uses a bit mask for protocol ports */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint16_t), - .field_index = SRCP_FIELD_IPV4, - .input_index = SRCP_DESTP_INPUT_IPV4, - .offset = sizeof(struct rte_ether_hdr) + - sizeof(struct rte_ipv4_hdr) + - offsetof(struct rte_tcp_hdr, src_port), - }, - { - /* rte_flow uses a bit mask for protocol ports */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint16_t), - .field_index = DSTP_FIELD_IPV4, - .input_index = SRCP_DESTP_INPUT_IPV4, - .offset = sizeof(struct rte_ether_hdr) + - sizeof(struct rte_ipv4_hdr) + - offsetof(struct rte_tcp_hdr, dst_port), - }, -}; - -/* parameters for rte_flow_classify_validate and rte_flow_classify_create */ - -/* test UDP pattern: - * "eth / ipv4 src spec 2.2.2.3 src mask 255.255.255.00 dst spec 2.2.2.7 - * dst mask 255.255.255.00 / udp src is 32 dst is 33 / end" - */ -static struct rte_flow_item_ipv4 ipv4_udp_spec_1 = { - { { .version_ihl = 0}, 0, 0, 0, 0, 0, IPPROTO_UDP, 0, - RTE_IPV4(2, 2, 2, 3), RTE_IPV4(2, 2, 2, 7)} -}; -static const struct rte_flow_item_ipv4 ipv4_mask_24 = { - .hdr = { - .next_proto_id = 0xff, - .src_addr = 0xffffff00, - .dst_addr = 0xffffff00, - }, -}; -static struct rte_flow_item_udp udp_spec_1 = { - { 32, 33, 0, 0 } -}; - -static struct rte_flow_item eth_item = { RTE_FLOW_ITEM_TYPE_ETH, - 0, 0, 0 }; -static struct rte_flow_item eth_item_bad = { -1, 0, 0, 0 }; - -static struct rte_flow_item ipv4_udp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4, - &ipv4_udp_spec_1, 0, &ipv4_mask_24}; -static struct rte_flow_item ipv4_udp_item_bad = { RTE_FLOW_ITEM_TYPE_IPV4, - NULL, 0, NULL}; - -static struct rte_flow_item udp_item_1 = { RTE_FLOW_ITEM_TYPE_UDP, - &udp_spec_1, 0, &rte_flow_item_udp_mask}; -static struct rte_flow_item udp_item_bad = { RTE_FLOW_ITEM_TYPE_UDP, - NULL, 0, NULL}; - -static struct rte_flow_item end_item = { RTE_FLOW_ITEM_TYPE_END, - 0, 0, 0 }; - -/* test TCP pattern: - * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8 - * dst mask 255.255.255.00 / tcp src is 16 dst is 17 / end" - */ -static struct rte_flow_item_ipv4 ipv4_tcp_spec_1 = { - { { .version_ihl = 0}, 0, 0, 0, 0, 0, IPPROTO_TCP, 0, - RTE_IPV4(1, 2, 3, 4), RTE_IPV4(5, 6, 7, 8)} -}; - -static struct rte_flow_item_tcp tcp_spec_1 = { - { 16, 17, 0, 0, 0, 0, 0, 0, 0} -}; - -static struct rte_flow_item ipv4_tcp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4, - &ipv4_tcp_spec_1, 0, &ipv4_mask_24}; - -static struct rte_flow_item tcp_item_1 = { RTE_FLOW_ITEM_TYPE_TCP, - &tcp_spec_1, 0, &rte_flow_item_tcp_mask}; - -/* test SCTP pattern: - * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8 - * dst mask 255.255.255.00 / sctp src is 16 dst is 17/ end" - */ -static struct rte_flow_item_ipv4 ipv4_sctp_spec_1 = { - { { .version_ihl = 0}, 0, 0, 0, 0, 0, IPPROTO_SCTP, 0, - RTE_IPV4(11, 12, 13, 14), RTE_IPV4(15, 16, 17, 18)} -}; - -static struct rte_flow_item_sctp sctp_spec_1 = { - { 10, 11, 0, 0} -}; - -static struct rte_flow_item ipv4_sctp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4, - &ipv4_sctp_spec_1, 0, &ipv4_mask_24}; - -static struct rte_flow_item sctp_item_1 = { RTE_FLOW_ITEM_TYPE_SCTP, - &sctp_spec_1, 0, &rte_flow_item_sctp_mask}; - - -/* test actions: - * "actions count / end" - */ -static struct rte_flow_query_count count = { - .reset = 1, - .hits_set = 1, - .bytes_set = 1, - .hits = 0, - .bytes = 0, -}; -static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT, - &count}; -static struct rte_flow_action count_action_bad = { -1, 0}; - -static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0}; - -static struct rte_flow_action actions[2]; - -/* test attributes */ -static struct rte_flow_attr attr; - -/* test error */ -static struct rte_flow_error error; - -/* test pattern */ -static struct rte_flow_item pattern[4]; - -/* flow classify data for UDP burst */ -static struct rte_flow_classify_ipv4_5tuple_stats udp_ntuple_stats; -static struct rte_flow_classify_stats udp_classify_stats = { - .stats = (void *)&udp_ntuple_stats -}; - -/* flow classify data for TCP burst */ -static struct rte_flow_classify_ipv4_5tuple_stats tcp_ntuple_stats; -static struct rte_flow_classify_stats tcp_classify_stats = { - .stats = (void *)&tcp_ntuple_stats -}; - -/* flow classify data for SCTP burst */ -static struct rte_flow_classify_ipv4_5tuple_stats sctp_ntuple_stats; -static struct rte_flow_classify_stats sctp_classify_stats = { - .stats = (void *)&sctp_ntuple_stats -}; - -struct flow_classifier_acl *cls; - -struct flow_classifier_acl { - struct rte_flow_classifier *cls; -} __rte_cache_aligned; - -/* - * test functions by passing invalid or - * non-workable parameters. - */ -static int -test_invalid_parameters(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - - ret = rte_flow_classify_validate(NULL, NULL, NULL, NULL, NULL); - if (!ret) { - printf("Line %i: rte_flow_classify_validate", - __LINE__); - printf(" with NULL param should have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL, - NULL, NULL); - if (rule) { - printf("Line %i: flow_classifier_table_entry_add", __LINE__); - printf(" with NULL param should have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(NULL, NULL); - if (!ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" with NULL param should have failed!\n"); - return -1; - } - - ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL); - if (!ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" with NULL param should have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL, - NULL, &error); - if (rule) { - printf("Line %i: flow_classify_table_entry_add ", __LINE__); - printf("with NULL param should have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(NULL, NULL); - if (!ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf("with NULL param should have failed!\n"); - return -1; - } - - ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL); - if (!ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" with NULL param should have failed!\n"); - return -1; - } - return 0; -} - -static int -test_valid_parameters(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - int key_found; - - /* - * set up parameters for rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item; - pattern[1] = ipv4_udp_item_1; - pattern[2] = udp_item_1; - pattern[3] = end_item; - actions[0] = count_action; - actions[1] = end_action; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (ret) { - printf("Line %i: rte_flow_classify_validate", - __LINE__); - printf(" should not have failed!\n"); - return -1; - } - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - - if (!rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should not have failed!\n"); - return -1; - } - return 0; -} - -static int -test_invalid_patterns(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - int key_found; - - /* - * set up parameters for rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item_bad; - pattern[1] = ipv4_udp_item_1; - pattern[2] = udp_item_1; - pattern[3] = end_item; - actions[0] = count_action; - actions[1] = end_action; - - pattern[0] = eth_item; - pattern[1] = ipv4_udp_item_bad; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (!ret) { - printf("Line %i: rte_flow_classify_validate", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (!ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should have failed!\n"); - return -1; - } - - pattern[1] = ipv4_udp_item_1; - pattern[2] = udp_item_bad; - pattern[3] = end_item; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (!ret) { - printf("Line %i: rte_flow_classify_validate", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (!ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should have failed!\n"); - return -1; - } - return 0; -} - -static int -test_invalid_actions(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - int key_found; - - /* - * set up parameters for rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item; - pattern[1] = ipv4_udp_item_1; - pattern[2] = udp_item_1; - pattern[3] = end_item; - actions[0] = count_action_bad; - actions[1] = end_action; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (!ret) { - printf("Line %i: rte_flow_classify_validate", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (!ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should have failed!\n"); - return -1; - } - - return 0; -} - -static int -init_ipv4_udp_traffic(struct rte_mempool *mp, - struct rte_mbuf **pkts_burst, uint32_t burst_size) -{ - struct rte_ether_hdr pkt_eth_hdr; - struct rte_ipv4_hdr pkt_ipv4_hdr; - struct rte_udp_hdr pkt_udp_hdr; - uint32_t src_addr = IPV4_ADDR(2, 2, 2, 3); - uint32_t dst_addr = IPV4_ADDR(2, 2, 2, 7); - uint16_t src_port = 32; - uint16_t dst_port = 33; - uint16_t pktlen; - - static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; - static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; - - printf("Set up IPv4 UDP traffic\n"); - initialize_eth_header(&pkt_eth_hdr, - (struct rte_ether_addr *)src_mac, - (struct rte_ether_addr *)dst_mac, RTE_ETHER_TYPE_IPV4, 0, 0); - pktlen = (uint16_t)(sizeof(struct rte_ether_hdr)); - printf("ETH pktlen %u\n", pktlen); - - pktlen = initialize_ipv4_header(&pkt_ipv4_hdr, src_addr, dst_addr, - pktlen); - printf("ETH + IPv4 pktlen %u\n", pktlen); - - pktlen = initialize_udp_header(&pkt_udp_hdr, src_port, dst_port, - pktlen); - printf("ETH + IPv4 + UDP pktlen %u\n\n", pktlen); - - return generate_packet_burst(mp, pkts_burst, &pkt_eth_hdr, - 0, &pkt_ipv4_hdr, 1, - &pkt_udp_hdr, burst_size, - PACKET_BURST_GEN_PKT_LEN, 1); -} - -static int -init_ipv4_tcp_traffic(struct rte_mempool *mp, - struct rte_mbuf **pkts_burst, uint32_t burst_size) -{ - struct rte_ether_hdr pkt_eth_hdr; - struct rte_ipv4_hdr pkt_ipv4_hdr; - struct rte_tcp_hdr pkt_tcp_hdr; - uint32_t src_addr = IPV4_ADDR(1, 2, 3, 4); - uint32_t dst_addr = IPV4_ADDR(5, 6, 7, 8); - uint16_t src_port = 16; - uint16_t dst_port = 17; - uint16_t pktlen; - - static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; - static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; - - printf("Set up IPv4 TCP traffic\n"); - initialize_eth_header(&pkt_eth_hdr, - (struct rte_ether_addr *)src_mac, - (struct rte_ether_addr *)dst_mac, RTE_ETHER_TYPE_IPV4, 0, 0); - pktlen = (uint16_t)(sizeof(struct rte_ether_hdr)); - printf("ETH pktlen %u\n", pktlen); - - pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr, - dst_addr, pktlen, IPPROTO_TCP); - printf("ETH + IPv4 pktlen %u\n", pktlen); - - pktlen = initialize_tcp_header(&pkt_tcp_hdr, src_port, dst_port, - pktlen); - printf("ETH + IPv4 + TCP pktlen %u\n\n", pktlen); - - return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr, - 0, &pkt_ipv4_hdr, 1, IPPROTO_TCP, - &pkt_tcp_hdr, burst_size, - PACKET_BURST_GEN_PKT_LEN, 1); -} - -static int -init_ipv4_sctp_traffic(struct rte_mempool *mp, - struct rte_mbuf **pkts_burst, uint32_t burst_size) -{ - struct rte_ether_hdr pkt_eth_hdr; - struct rte_ipv4_hdr pkt_ipv4_hdr; - struct rte_sctp_hdr pkt_sctp_hdr; - uint32_t src_addr = IPV4_ADDR(11, 12, 13, 14); - uint32_t dst_addr = IPV4_ADDR(15, 16, 17, 18); - uint16_t src_port = 10; - uint16_t dst_port = 11; - uint16_t pktlen; - - static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; - static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; - - printf("Set up IPv4 SCTP traffic\n"); - initialize_eth_header(&pkt_eth_hdr, - (struct rte_ether_addr *)src_mac, - (struct rte_ether_addr *)dst_mac, RTE_ETHER_TYPE_IPV4, 0, 0); - pktlen = (uint16_t)(sizeof(struct rte_ether_hdr)); - printf("ETH pktlen %u\n", pktlen); - - pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr, - dst_addr, pktlen, IPPROTO_SCTP); - printf("ETH + IPv4 pktlen %u\n", pktlen); - - pktlen = initialize_sctp_header(&pkt_sctp_hdr, src_port, dst_port, - pktlen); - printf("ETH + IPv4 + SCTP pktlen %u\n\n", pktlen); - - return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr, - 0, &pkt_ipv4_hdr, 1, IPPROTO_SCTP, - &pkt_sctp_hdr, burst_size, - PACKET_BURST_GEN_PKT_LEN, 1); -} - -static int -init_mbufpool(void) -{ - int socketid; - int ret = 0; - unsigned int lcore_id; - char s[64]; - - for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { - if (rte_lcore_is_enabled(lcore_id) == 0) - continue; - - socketid = rte_lcore_to_socket_id(lcore_id); - if (socketid >= NB_SOCKETS) { - printf( - "Socket %d of lcore %u is out of range %d\n", - socketid, lcore_id, NB_SOCKETS); - ret = -1; - break; - } - if (mbufpool[socketid] == NULL) { - snprintf(s, sizeof(s), "mbuf_pool_%d", socketid); - mbufpool[socketid] = - rte_pktmbuf_pool_create(s, NB_MBUF, - MEMPOOL_CACHE_SIZE, 0, MBUF_SIZE, - socketid); - if (mbufpool[socketid]) { - printf("Allocated mbuf pool on socket %d\n", - socketid); - } else { - printf("Cannot init mbuf pool on socket %d\n", - socketid); - ret = -ENOMEM; - break; - } - } - } - return ret; -} - -static int -test_query_udp(void) -{ - struct rte_flow_error error; - struct rte_flow_classify_rule *rule; - int ret; - int i; - int key_found; - - ret = init_ipv4_udp_traffic(mbufpool[0], bufs, MAX_PKT_BURST); - if (ret != MAX_PKT_BURST) { - printf("Line %i: init_udp_ipv4_traffic has failed!\n", - __LINE__); - return -1; - } - - for (i = 0; i < MAX_PKT_BURST; i++) - bufs[i]->packet_type = RTE_PTYPE_L3_IPV4; - - /* - * set up parameters for rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item; - pattern[1] = ipv4_udp_item_1; - pattern[2] = udp_item_1; - pattern[3] = end_item; - actions[0] = count_action; - actions[1] = end_action; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (ret) { - printf("Line %i: rte_flow_classify_validate", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (!rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST, - rule, &udp_classify_stats); - if (ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should not have failed!\n"); - return -1; - } - return 0; -} - -static int -test_query_tcp(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - int i; - int key_found; - - ret = init_ipv4_tcp_traffic(mbufpool[0], bufs, MAX_PKT_BURST); - if (ret != MAX_PKT_BURST) { - printf("Line %i: init_ipv4_tcp_traffic has failed!\n", - __LINE__); - return -1; - } - - for (i = 0; i < MAX_PKT_BURST; i++) - bufs[i]->packet_type = RTE_PTYPE_L3_IPV4; - - /* - * set up parameters for rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item; - pattern[1] = ipv4_tcp_item_1; - pattern[2] = tcp_item_1; - pattern[3] = end_item; - actions[0] = count_action; - actions[1] = end_action; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (!rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST, - rule, &tcp_classify_stats); - if (ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should not have failed!\n"); - return -1; - } - return 0; -} - -static int -test_query_sctp(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - int i; - int key_found; - - ret = init_ipv4_sctp_traffic(mbufpool[0], bufs, MAX_PKT_BURST); - if (ret != MAX_PKT_BURST) { - printf("Line %i: init_ipv4_tcp_traffic has failed!\n", - __LINE__); - return -1; - } - - for (i = 0; i < MAX_PKT_BURST; i++) - bufs[i]->packet_type = RTE_PTYPE_L3_IPV4; - - /* - * set up parameters rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item; - pattern[1] = ipv4_sctp_item_1; - pattern[2] = sctp_item_1; - pattern[3] = end_item; - actions[0] = count_action; - actions[1] = end_action; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (!rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST, - rule, &sctp_classify_stats); - if (ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should not have failed!\n"); - return -1; - } - return 0; -} - -static int -test_flow_classify(void) -{ - struct rte_table_acl_params table_acl_params; - struct rte_flow_classify_table_params cls_table_params; - struct rte_flow_classifier_params cls_params; - int ret; - uint32_t size; - - /* Memory allocation */ - size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct flow_classifier_acl)); - cls = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE); - - cls_params.name = "flow_classifier"; - cls_params.socket_id = 0; - cls->cls = rte_flow_classifier_create(&cls_params); - if (cls->cls == NULL) { - printf("Line %i: flow classifier create has failed!\n", - __LINE__); - rte_free(cls); - return TEST_FAILED; - } - - /* initialise ACL table params */ - table_acl_params.n_rule_fields = RTE_DIM(ipv4_defs); - table_acl_params.name = "table_acl_ipv4_5tuple"; - table_acl_params.n_rules = FLOW_CLASSIFY_MAX_RULE_NUM; - memcpy(table_acl_params.field_format, ipv4_defs, sizeof(ipv4_defs)); - - /* initialise table create params */ - cls_table_params.ops = &rte_table_acl_ops; - cls_table_params.arg_create = &table_acl_params; - cls_table_params.type = RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE; - - ret = rte_flow_classify_table_create(cls->cls, &cls_table_params); - if (ret) { - printf("Line %i: f_create has failed!\n", __LINE__); - rte_flow_classifier_free(cls->cls); - rte_free(cls); - return TEST_FAILED; - } - printf("Created table_acl for for IPv4 five tuple packets\n"); - - ret = init_mbufpool(); - if (ret) { - printf("Line %i: init_mbufpool has failed!\n", __LINE__); - return TEST_FAILED; - } - - if (test_invalid_parameters() < 0) - return TEST_FAILED; - if (test_valid_parameters() < 0) - return TEST_FAILED; - if (test_invalid_patterns() < 0) - return TEST_FAILED; - if (test_invalid_actions() < 0) - return TEST_FAILED; - if (test_query_udp() < 0) - return TEST_FAILED; - if (test_query_tcp() < 0) - return TEST_FAILED; - if (test_query_sctp() < 0) - return TEST_FAILED; - - return TEST_SUCCESS; -} - -#endif /* !RTE_EXEC_ENV_WINDOWS */ - -REGISTER_TEST_COMMAND(flow_classify_autotest, test_flow_classify); diff --git a/app/test/test_flow_classify.h b/app/test/test_flow_classify.h deleted file mode 100644 index 6bd10ec972e5..000000000000 --- a/app/test/test_flow_classify.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#ifndef TEST_FLOW_CLASSIFY_H_ -#define TEST_FLOW_CLASSIFY_H_ - -/* ACL field definitions for IPv4 5 tuple rule */ - -enum { - PROTO_FIELD_IPV4, - SRC_FIELD_IPV4, - DST_FIELD_IPV4, - SRCP_FIELD_IPV4, - DSTP_FIELD_IPV4, - NUM_FIELDS_IPV4 -}; - -enum { - PROTO_INPUT_IPV4, - SRC_INPUT_IPV4, - DST_INPUT_IPV4, - SRCP_DESTP_INPUT_IPV4 -}; - -#endif /* TEST_FLOW_CLASSIFY_H_ */ diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md index 3bc8778981f6..5cd8c9de8105 100644 --- a/doc/api/doxy-api-index.md +++ b/doc/api/doxy-api-index.md @@ -160,7 +160,6 @@ The public API headers are grouped by topics: [EFD](@ref rte_efd.h), [ACL](@ref rte_acl.h), [member](@ref rte_member.h), - [flow classify](@ref rte_flow_classify.h), [BPF](@ref rte_bpf.h) - **containers**: diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in index 1a4210b948a8..9a9c52e5569c 100644 --- a/doc/api/doxy-api.conf.in +++ b/doc/api/doxy-api.conf.in @@ -40,7 +40,6 @@ INPUT = @TOPDIR@/doc/api/doxy-api-index.md \ @TOPDIR@/lib/ethdev \ @TOPDIR@/lib/eventdev \ @TOPDIR@/lib/fib \ - @TOPDIR@/lib/flow_classify \ @TOPDIR@/lib/gpudev \ @TOPDIR@/lib/graph \ @TOPDIR@/lib/gro \ diff --git a/doc/guides/freebsd_gsg/build_sample_apps.rst b/doc/guides/freebsd_gsg/build_sample_apps.rst index b1ab7545b1ce..7bdd88e56d32 100644 --- a/doc/guides/freebsd_gsg/build_sample_apps.rst +++ b/doc/guides/freebsd_gsg/build_sample_apps.rst @@ -31,7 +31,7 @@ the installation of DPDK using `meson install` as described previously:: $ gmake cc -O3 -I/usr/local/include -include rte_config.h -march=native -D__BSD_VISIBLE main.c -o build/helloworld-shared - -L/usr/local/lib -lrte_telemetry -lrte_bpf -lrte_flow_classify + -L/usr/local/lib -lrte_telemetry -lrte_bpf -lrte_pipeline -lrte_table -lrte_port -lrte_fib -lrte_ipsec -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_rcu -lrte_rawdev -lrte_pdump -lrte_member -lrte_lpm diff --git a/doc/guides/freebsd_gsg/install_from_ports.rst b/doc/guides/freebsd_gsg/install_from_ports.rst index d946f3f3b2eb..3c98c46b298f 100644 --- a/doc/guides/freebsd_gsg/install_from_ports.rst +++ b/doc/guides/freebsd_gsg/install_from_ports.rst @@ -84,7 +84,7 @@ via the contigmem module, and 4 NIC ports bound to the nic_uio module:: cd helloworld/ gmake - cc -O3 -I/usr/local/include -include rte_config.h -march=corei7 -D__BSD_VISIBLE main.c -o build/helloworld-shared -L/usr/local/lib -lrte_bpf -lrte_flow_classify -lrte_pipeline -lrte_table -lrte_port -lrte_fib -lrte_ipsec -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_rcu -lrte_rawdev -lrte_pdump -lrte_member -lrte_lpm -lrte_latencystats -lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_eventdev -lrte_efd -lrte_distributor -lrte_cryptodev -lrte_compressdev -lrte_cfgfile -lrte_bitratestats -lrte_bbdev -lrte_acl -lrte_timer -lrte_hash -lrte_metrics -lrte_cmdline -lrte_pci -lrte_ethdev -lrte_meter -lrte_net -lrte_mbuf -lrte_mempool -lrte_ring -lrte_eal -lrte_kvargs + cc -O3 -I/usr/local/include -include rte_config.h -march=corei7 -D__BSD_VISIBLE main.c -o build/helloworld-shared -L/usr/local/lib -lrte_bpf -lrte_pipeline -lrte_table -lrte_port -lrte_fib -lrte_ipsec -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_rcu -lrte_rawdev -lrte_pdump -lrte_member -lrte_lpm -lrte_latencystats -lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_eventdev -lrte_efd -lrte_distributor -lrte_cryptodev -lrte_compressdev -lrte_cfgfile -lrte_bitratestats -lrte_bbdev -lrte_acl -lrte_timer -lrte_hash -lrte_metrics -lrte_cmdline -lrte_pci -lrte_ethdev -lrte_meter -lrte_net -lrte_mbuf -lrte_mempool -lrte_ring -lrte_eal -lrte_kvargs ln -sf helloworld-shared build/helloworld sudo ./build/helloworld -l 0-3 diff --git a/doc/guides/prog_guide/flow_classify_lib.rst b/doc/guides/prog_guide/flow_classify_lib.rst deleted file mode 100644 index ad2e10ec2681..000000000000 --- a/doc/guides/prog_guide/flow_classify_lib.rst +++ /dev/null @@ -1,424 +0,0 @@ -.. SPDX-License-Identifier: BSD-3-Clause - Copyright(c) 2017 Intel Corporation. - -Flow Classification Library -=========================== - -.. note:: - - The Flow Classification library is deprecated and will be removed in future. - See :doc:`../rel_notes/deprecation`. - - It is disabled by default in the DPDK build. - To re-enable the library, remove 'flow_classify' from the "disable_libs" - meson option when configuring a build. - -DPDK provides a Flow Classification library that provides the ability -to classify an input packet by matching it against a set of Flow rules. - -The initial implementation supports counting of IPv4 5-tuple packets which match -a particular Flow rule only. - -Please refer to the -:doc:`./rte_flow` -for more information. - -The Flow Classification library uses the ``librte_table`` API for managing Flow -rules and matching packets against the Flow rules. -The library is table agnostic and can use the following tables: -``Access Control List``, ``Hash`` and ``Longest Prefix Match(LPM)``. -The ``Access Control List`` table is used in the initial implementation. - -Please refer to the -:doc:`./packet_framework` -for more information.on ``librte_table``. - -DPDK provides an Access Control List library that provides the ability to -classify an input packet based on a set of classification rules. - -Please refer to the -:doc:`./packet_classif_access_ctrl` -library for more information on ``librte_acl``. - -There is also a Flow Classify sample application which demonstrates the use of -the Flow Classification Library API's. - -Please refer to the -:doc:`../sample_app_ug/flow_classify` -for more information on the ``flow_classify`` sample application. - -Overview --------- - -The library has the following API's - -.. code-block:: c - - /** - * Flow classifier create - * - * @param params - * Parameters for flow classifier creation - * @return - * Handle to flow classifier instance on success or NULL otherwise - */ - struct rte_flow_classifier * - rte_flow_classifier_create(struct rte_flow_classifier_params *params); - - /** - * Flow classifier free - * - * @param cls - * Handle to flow classifier instance - * @return - * 0 on success, error code otherwise - */ - int - rte_flow_classifier_free(struct rte_flow_classifier *cls); - - /** - * Flow classify table create - * - * @param cls - * Handle to flow classifier instance - * @param params - * Parameters for flow_classify table creation - * @return - * 0 on success, error code otherwise - */ - int - rte_flow_classify_table_create(struct rte_flow_classifier *cls, - struct rte_flow_classify_table_params *params); - - /** - * Validate the flow classify rule - * - * @param[in] cls - * Handle to flow classifier instance - * @param[in] attr - * Flow rule attributes - * @param[in] pattern - * Pattern specification (list terminated by the END pattern item). - * @param[in] actions - * Associated actions (list terminated by the END pattern item). - * @param[out] error - * Perform verbose error reporting if not NULL. Structure - * initialised in case of error only. - * @return - * 0 on success, error code otherwise - */ - int - rte_flow_classify_validate(struct rte_flow_classifier *cls, - const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - struct rte_flow_error *error); - - /** - * Add a flow classify rule to the flow_classifier table. - * - * @param[in] cls - * Flow classifier handle - * @param[in] attr - * Flow rule attributes - * @param[in] pattern - * Pattern specification (list terminated by the END pattern item). - * @param[in] actions - * Associated actions (list terminated by the END pattern item). - * @param[out] key_found - * returns 1 if rule present already, 0 otherwise. - * @param[out] error - * Perform verbose error reporting if not NULL. Structure - * initialised in case of error only. - * @return - * A valid handle in case of success, NULL otherwise. - */ - struct rte_flow_classify_rule * - rte_flow_classify_table_entry_add(struct rte_flow_classifier *cls, - const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - int *key_found; - struct rte_flow_error *error); - - /** - * Delete a flow classify rule from the flow_classifier table. - * - * @param[in] cls - * Flow classifier handle - * @param[in] rule - * Flow classify rule - * @return - * 0 on success, error code otherwise. - */ - int - rte_flow_classify_table_entry_delete(struct rte_flow_classifier *cls, - struct rte_flow_classify_rule *rule); - - /** - * Query flow classifier for given rule. - * - * @param[in] cls - * Flow classifier handle - * @param[in] pkts - * Pointer to packets to process - * @param[in] nb_pkts - * Number of packets to process - * @param[in] rule - * Flow classify rule - * @param[in] stats - * Flow classify stats - * - * @return - * 0 on success, error code otherwise. - */ - int - rte_flow_classifier_query(struct rte_flow_classifier *cls, - struct rte_mbuf **pkts, - const uint16_t nb_pkts, - struct rte_flow_classify_rule *rule, - struct rte_flow_classify_stats *stats); - -Classifier creation -~~~~~~~~~~~~~~~~~~~ - -The application creates the ``Classifier`` using the -``rte_flow_classifier_create`` API. -The ``rte_flow_classify_params`` structure must be initialised by the -application before calling the API. - -.. code-block:: c - - struct rte_flow_classifier_params { - /** flow classifier name */ - const char *name; - - /** CPU socket ID where memory for the flow classifier and its */ - /** elements (tables) should be allocated */ - int socket_id; - }; - -The ``Classifier`` has the following internal structures: - -.. code-block:: c - - struct rte_cls_table { - /* Input parameters */ - struct rte_table_ops ops; - uint32_t entry_size; - enum rte_flow_classify_table_type type; - - /* Handle to the low-level table object */ - void *h_table; - }; - - #define RTE_FLOW_CLASSIFIER_MAX_NAME_SZ 256 - - struct rte_flow_classifier { - /* Input parameters */ - char name[RTE_FLOW_CLASSIFIER_MAX_NAME_SZ]; - int socket_id; - - /* Internal */ - /* ntuple_filter */ - struct rte_eth_ntuple_filter ntuple_filter; - - /* classifier tables */ - struct rte_cls_table tables[RTE_FLOW_CLASSIFY_TABLE_MAX]; - uint32_t table_mask; - uint32_t num_tables; - - uint16_t nb_pkts; - struct rte_flow_classify_table_entry - *entries[RTE_PORT_IN_BURST_SIZE_MAX]; - } __rte_cache_aligned; - -Adding a table to the Classifier -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The application adds a table to the ``Classifier`` using the -``rte_flow_classify_table_create`` API. -The ``rte_flow_classify_table_params`` structure must be initialised by the -application before calling the API. - -.. code-block:: c - - struct rte_flow_classify_table_params { - /** Table operations (specific to each table type) */ - struct rte_table_ops *ops; - - /** Opaque param to be passed to the table create operation */ - void *arg_create; - - /** Classifier table type */ - enum rte_flow_classify_table_type type; - }; - -To create an ACL table the ``rte_table_acl_params`` structure must be -initialised and assigned to ``arg_create`` in the -``rte_flow_classify_table_params`` structure. - -.. code-block:: c - - struct rte_table_acl_params { - /** Name */ - const char *name; - - /** Maximum number of ACL rules in the table */ - uint32_t n_rules; - - /** Number of fields in the ACL rule specification */ - uint32_t n_rule_fields; - - /** Format specification of the fields of the ACL rule */ - struct rte_acl_field_def field_format[RTE_ACL_MAX_FIELDS]; - }; - -The fields for the ACL rule must also be initialised by the application. - -An ACL table can be added to the ``Classifier`` for each ACL rule, for example -another table could be added for the IPv6 5-tuple rule. - -Flow Parsing -~~~~~~~~~~~~ - -The library currently supports three IPv4 5-tuple flow patterns, for UDP, TCP -and SCTP. - -.. code-block:: c - - /* Pattern for IPv4 5-tuple UDP filter */ - static enum rte_flow_item_type pattern_ntuple_1[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END, - }; - - /* Pattern for IPv4 5-tuple TCP filter */ - static enum rte_flow_item_type pattern_ntuple_2[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END, - }; - - /* Pattern for IPv4 5-tuple SCTP filter */ - static enum rte_flow_item_type pattern_ntuple_3[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_SCTP, - RTE_FLOW_ITEM_TYPE_END, - }; - -The API function ``rte_flow_classify_validate`` parses the -IPv4 5-tuple pattern, attributes and actions and returns the 5-tuple data in the -``rte_eth_ntuple_filter`` structure. - -.. code-block:: c - - static int - rte_flow_classify_validate(struct rte_flow_classifier *cls, - const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - struct rte_flow_error *error) - -Adding Flow Rules -~~~~~~~~~~~~~~~~~ - -The ``rte_flow_classify_table_entry_add`` API creates an -``rte_flow_classify`` object which contains the flow_classify id and type, the -action, a union of add and delete keys and a union of rules. -It uses the ``rte_flow_classify_validate`` API function for parsing the -flow parameters. -The 5-tuple ACL key data is obtained from the ``rte_eth_ntuple_filter`` -structure populated by the ``classify_parse_ntuple_filter`` function which -parses the Flow rule. - -.. code-block:: c - - struct acl_keys { - struct rte_table_acl_rule_add_params key_add; /* add key */ - struct rte_table_acl_rule_delete_params key_del; /* delete key */ - }; - - struct classify_rules { - enum rte_flow_classify_rule_type type; - union { - struct rte_flow_classify_ipv4_5tuple ipv4_5tuple; - } u; - }; - - struct rte_flow_classify { - uint32_t id; /* unique ID of classify object */ - enum rte_flow_classify_table_type tbl_type; /* rule table */ - struct classify_rules rules; /* union of rules */ - union { - struct acl_keys key; - } u; - int key_found; /* rule key found in table */ - struct rte_flow_classify_table_entry entry; /* rule meta data */ - void *entry_ptr; /* handle to the table entry for rule meta data */ - }; - -It then calls the ``table.ops.f_add`` API to add the rule to the ACL -table. - -Deleting Flow Rules -~~~~~~~~~~~~~~~~~~~ - -The ``rte_flow_classify_table_entry_delete`` API calls the -``table.ops.f_delete`` API to delete a rule from the ACL table. - -Packet Matching -~~~~~~~~~~~~~~~ - -The ``rte_flow_classifier_query`` API is used to find packets which match a -given flow rule in the table. -This API calls the flow_classify_run internal function which calls the -``table.ops.f_lookup`` API to see if any packets in a burst match any -of the Flow rules in the table. -The meta data for the highest priority rule matched for each packet is returned -in the entries array in the ``rte_flow_classify`` object. -The internal function ``action_apply`` implements the ``Count`` action which is -used to return data which matches a particular Flow rule. - -The rte_flow_classifier_query API uses the following structures to return data -to the application. - -.. code-block:: c - - /** IPv4 5-tuple data */ - struct rte_flow_classify_ipv4_5tuple { - uint32_t dst_ip; /**< Destination IP address in big endian. */ - uint32_t dst_ip_mask; /**< Mask of destination IP address. */ - uint32_t src_ip; /**< Source IP address in big endian. */ - uint32_t src_ip_mask; /**< Mask of destination IP address. */ - uint16_t dst_port; /**< Destination port in big endian. */ - uint16_t dst_port_mask; /**< Mask of destination port. */ - uint16_t src_port; /**< Source Port in big endian. */ - uint16_t src_port_mask; /**< Mask of source port. */ - uint8_t proto; /**< L4 protocol. */ - uint8_t proto_mask; /**< Mask of L4 protocol. */ - }; - - /** - * Flow stats - * - * For the count action, stats can be returned by the query API. - * - * Storage for stats is provided by the application. - * - * - */ - struct rte_flow_classify_stats { - void *stats; - }; - - struct rte_flow_classify_5tuple_stats { - /** count of packets that match IPv4 5tuple pattern */ - uint64_t counter1; - /** IPv4 5tuple data */ - struct rte_flow_classify_ipv4_5tuple ipv4_5tuple; - }; diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst index d89cd3edb63c..c04847bfa148 100644 --- a/doc/guides/prog_guide/index.rst +++ b/doc/guides/prog_guide/index.rst @@ -43,7 +43,6 @@ Programmer's Guide lpm6_lib fib_lib rib_lib - flow_classify_lib packet_distrib_lib reorder_lib ip_fragment_reassembly_lib diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index 494b401cda4b..ce5a8f0361cb 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -35,7 +35,7 @@ Deprecation Notices which also added support for standard atomics (Ref: https://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html) -* build: Enabling deprecated libraries (``flow_classify``, ``kni``) +* build: Enabling deprecated libraries (``kni``) won't be possible anymore through the use of the ``disable_libs`` build option. A new build option for deprecated libraries will be introduced instead. @@ -200,12 +200,6 @@ Deprecation Notices Since these functions are not called directly by the application, the API remains unaffected. -* flow_classify: The flow_classify library and example have no maintainer. - The library is experimental and, as such, it could be removed from DPDK. - Its removal has been postponed to let potential users report interest - in maintaining it. - In the absence of such interest, this library will be removed in DPDK 23.11. - * pipeline: The pipeline library legacy API (functions rte_pipeline_*) will be deprecated and subsequently removed in DPDK 24.11 release. Before this, the new pipeline library API (functions rte_swx_pipeline_*) diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst index 6b4dd21fd0e1..9d96dbdcd302 100644 --- a/doc/guides/rel_notes/release_23_11.rst +++ b/doc/guides/rel_notes/release_23_11.rst @@ -68,6 +68,8 @@ Removed Items Also, make sure to start the actual text at the margin. ======================================================= +* flow_classify: Removed flow classification library and examples. + API Changes ----------- diff --git a/doc/guides/sample_app_ug/flow_classify.rst b/doc/guides/sample_app_ug/flow_classify.rst deleted file mode 100644 index 6c4c04e935e4..000000000000 --- a/doc/guides/sample_app_ug/flow_classify.rst +++ /dev/null @@ -1,242 +0,0 @@ -.. SPDX-License-Identifier: BSD-3-Clause - Copyright(c) 2017 Intel Corporation. - -Flow Classify Sample Application -================================ - -The Flow Classify sample application is based on the simple *skeleton* example -of a forwarding application. - -It is intended as a demonstration of the basic components of a DPDK forwarding -application which uses the Flow Classify library API's. - -Please refer to the -:doc:`../prog_guide/flow_classify_lib` -for more information. - -Compiling the Application -------------------------- - -To compile the sample application see :doc:`compiling`. - -The application is located in the ``flow_classify`` sub-directory. - -Running the Application ------------------------ - -To run the example in a ``linux`` environment: - -.. code-block:: console - - .//examples/dpdk-flow_classify -c 4 -n 4 -- / - --rule_ipv4="../ipv4_rules_file.txt" - -Please refer to the *DPDK Getting Started Guide*, section -:doc:`../linux_gsg/build_sample_apps` -for general information on running applications and the Environment Abstraction -Layer (EAL) options. - - -Sample ipv4_rules_file.txt --------------------------- - -.. code-block:: console - - #file format: - #src_ip/masklen dst_ip/masklen src_port : mask dst_port : mask proto/mask priority - # - 2.2.2.3/24 2.2.2.7/24 32 : 0xffff 33 : 0xffff 17/0xff 0 - 9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 17/0xff 1 - 9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 6/0xff 2 - 9.9.8.3/24 9.9.8.7/24 32 : 0xffff 33 : 0xffff 6/0xff 3 - 6.7.8.9/24 2.3.4.5/24 32 : 0x0000 33 : 0x0000 132/0xff 4 - -Explanation ------------ - -The following sections provide an explanation of the main components of the -code. - -All DPDK library functions used in the sample code are prefixed with ``rte_`` -and are explained in detail in the *DPDK API Documentation*. - -ACL field definitions for the IPv4 5 tuple rule -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The following field definitions are used when creating the ACL table during -initialisation of the ``Flow Classify`` application - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Creation of ACL table during initialization of application. 8< - :end-before: >8 End of creation of ACL table. - -The Main Function -~~~~~~~~~~~~~~~~~ - -The ``main()`` function performs the initialization and calls the execution -threads for each lcore. - -The first task is to initialize the Environment Abstraction Layer (EAL). -The ``argc`` and ``argv`` arguments are provided to the ``rte_eal_init()`` -function. The value returned is the number of parsed arguments: - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Initialize the Environment Abstraction Layer (EAL). 8< - :end-before: >8 End of initialization of EAL. - :dedent: 1 - -It then parses the flow_classify application arguments - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Parse application arguments (after the EAL ones). 8< - :end-before: >8 End of parse application arguments. - :dedent: 1 - -The ``main()`` function also allocates a mempool to hold the mbufs -(Message Buffers) used by the application: - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Creates a new mempool in memory to hold the mbufs. 8< - :end-before: >8 End of creation of new mempool in memory. - :dedent: 1 - -mbufs are the packet buffer structure used by DPDK. They are explained in -detail in the "Mbuf Library" section of the *DPDK Programmer's Guide*. - -The ``main()`` function also initializes all the ports using the user defined -``port_init()`` function which is explained in the next section: - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Initialize all ports. 8< - :end-before: >8 End of initialization of all ports. - :dedent: 1 - -The ``main()`` function creates the ``flow classifier object`` and adds an ``ACL -table`` to the flow classifier. - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Creation of flow classifier object. 8< - :end-before: >8 End of creation of flow classifier object. - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Memory allocation. 8< - :end-before: >8 End of initialization of table create params. - :dedent: 1 - -It then reads the ipv4_rules_file.txt file and initialises the parameters for -the ``rte_flow_classify_table_entry_add`` API. -This API adds a rule to the ACL table. - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Read file of IPv4 tuple rules. 8< - :end-before: >8 End of reading file of IPv4 5 tuple rules. - :dedent: 1 - -Once the initialization is complete, the application is ready to launch a -function on an lcore. In this example ``lcore_main()`` is called on a single -lcore. - -.. code-block:: c - - lcore_main(cls_app); - -The ``lcore_main()`` function is explained below. - -The Port Initialization Function -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The main functional part of the port initialization used in the Basic -Forwarding application is shown below: - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Initializing port using global settings. 8< - :end-before: >8 End of initializing a given port. - -The Ethernet ports are configured with default settings using the -``rte_eth_dev_configure()`` function. - -For this example the ports are set up with 1 RX and 1 TX queue using the -``rte_eth_rx_queue_setup()`` and ``rte_eth_tx_queue_setup()`` functions. - -The Ethernet port is then started: - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Start the Ethernet port. 8< - :end-before: >8 End of starting the Ethernet port. - :dedent: 1 - - -Finally the RX port is set in promiscuous mode: - -.. code-block:: c - - retval = rte_eth_promiscuous_enable(port); - -The Add Rules function -~~~~~~~~~~~~~~~~~~~~~~ - -The ``add_rules`` function reads the ``ipv4_rules_file.txt`` file and calls the -``add_classify_rule`` function which calls the -``rte_flow_classify_table_entry_add`` API. - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Reads file and calls the add_classify_rule function. 8< - :end-before: >8 End of add_rules. - - -The Lcore Main function -~~~~~~~~~~~~~~~~~~~~~~~ - -As we saw above the ``main()`` function calls an application function on the -available lcores. -The ``lcore_main`` function calls the ``rte_flow_classifier_query`` API. -For the Basic Forwarding application the ``lcore_main`` function looks like the -following: - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Flow classify data. 8< - :end-before: >8 End of flow classify data. - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Classifying the packets. 8< - :end-before: >8 End of lcore main. - -The main work of the application is done within the loop: - -.. literalinclude:: ../../../examples/flow_classify/flow_classify.c - :language: c - :start-after: Run until the application is quit or killed. 8< - :end-before: >8 End of main loop. - :dedent: 1 - -Packets are received in bursts on the RX ports and transmitted in bursts on -the TX ports. The ports are grouped in pairs with a simple mapping scheme -using the an XOR on the port number:: - - 0 -> 1 - 1 -> 0 - - 2 -> 3 - 3 -> 2 - - etc. - -The ``rte_eth_tx_burst()`` function frees the memory buffers of packets that -are transmitted. If packets fail to transmit, ``(nb_tx < nb_rx)``, then they -must be freed explicitly using ``rte_pktmbuf_free()``. - -The forwarding loop can be interrupted and the application closed using -``Ctrl-C``. diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst index 6e1e83d7d7c8..19485556c765 100644 --- a/doc/guides/sample_app_ug/index.rst +++ b/doc/guides/sample_app_ug/index.rst @@ -15,7 +15,6 @@ Sample Applications User Guides hello_world skeleton rxtx_callbacks - flow_classify flow_filtering ip_frag ipv4_multicast diff --git a/examples/flow_classify/Makefile b/examples/flow_classify/Makefile deleted file mode 100644 index 539bf9682b06..000000000000 --- a/examples/flow_classify/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2017 Intel Corporation - -# binary name -APP = flow_classify - -# all source are stored in SRCS-y -SRCS-y := flow_classify.c - -PKGCONF ?= pkg-config - -# Build using pkg-config variables if possible -ifneq ($(shell $(PKGCONF) --exists libdpdk && echo 0),0) -$(error "no installation of DPDK found") -endif - -all: shared -.PHONY: shared static -shared: build/$(APP)-shared - ln -sf $(APP)-shared build/$(APP) -static: build/$(APP)-static - ln -sf $(APP)-static build/$(APP) - -PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) -CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) -LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) -LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - -ifeq ($(MAKECMDGOALS),static) -# check for broken pkg-config -ifeq ($(shell echo $(LDFLAGS_STATIC) | grep 'whole-archive.*l:lib.*no-whole-archive'),) -$(warning "pkg-config output list does not contain drivers between 'whole-archive'/'no-whole-archive' flags.") -$(error "Cannot generate statically-linked binaries with this version of pkg-config") -endif -endif - -CFLAGS += -DALLOW_EXPERIMENTAL_API - -build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) - -build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) - -build: - @mkdir -p $@ - -.PHONY: clean -clean: - rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared - test -d build && rmdir -p build || true diff --git a/examples/flow_classify/flow_classify.c b/examples/flow_classify/flow_classify.c deleted file mode 100644 index cdd51b247628..000000000000 --- a/examples/flow_classify/flow_classify.c +++ /dev/null @@ -1,878 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define RX_RING_SIZE 1024 -#define TX_RING_SIZE 1024 - -#define NUM_MBUFS 8191 -#define MBUF_CACHE_SIZE 250 -#define BURST_SIZE 32 - -#define MAX_NUM_CLASSIFY 30 -#define FLOW_CLASSIFY_MAX_RULE_NUM 91 -#define FLOW_CLASSIFY_MAX_PRIORITY 8 -#define FLOW_CLASSIFIER_NAME_SIZE 64 - -#define COMMENT_LEAD_CHAR ('#') -#define OPTION_RULE_IPV4 "rule_ipv4" -#define RTE_LOGTYPE_FLOW_CLASSIFY RTE_LOGTYPE_USER3 -#define flow_classify_log(format, ...) \ - RTE_LOG(ERR, FLOW_CLASSIFY, format, ##__VA_ARGS__) - -#define uint32_t_to_char(ip, a, b, c, d) do {\ - *a = (unsigned char)(ip >> 24 & 0xff);\ - *b = (unsigned char)(ip >> 16 & 0xff);\ - *c = (unsigned char)(ip >> 8 & 0xff);\ - *d = (unsigned char)(ip & 0xff);\ - } while (0) - -enum { - CB_FLD_SRC_ADDR, - CB_FLD_DST_ADDR, - CB_FLD_SRC_PORT, - CB_FLD_SRC_PORT_DLM, - CB_FLD_SRC_PORT_MASK, - CB_FLD_DST_PORT, - CB_FLD_DST_PORT_DLM, - CB_FLD_DST_PORT_MASK, - CB_FLD_PROTO, - CB_FLD_PRIORITY, - CB_FLD_NUM, -}; - -static struct{ - const char *rule_ipv4_name; -} parm_config; -const char cb_port_delim[] = ":"; - -/* Creation of flow classifier object. 8< */ -struct flow_classifier { - struct rte_flow_classifier *cls; -}; - -struct flow_classifier_acl { - struct flow_classifier cls; -} __rte_cache_aligned; -/* >8 End of creation of flow classifier object. */ - -/* Creation of ACL table during initialization of application. 8< */ - -/* ACL field definitions for IPv4 5 tuple rule */ -enum { - PROTO_FIELD_IPV4, - SRC_FIELD_IPV4, - DST_FIELD_IPV4, - SRCP_FIELD_IPV4, - DSTP_FIELD_IPV4, - NUM_FIELDS_IPV4 -}; - -enum { - PROTO_INPUT_IPV4, - SRC_INPUT_IPV4, - DST_INPUT_IPV4, - SRCP_DESTP_INPUT_IPV4 -}; - -static struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { - /* first input field - always one byte long. */ - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint8_t), - .field_index = PROTO_FIELD_IPV4, - .input_index = PROTO_INPUT_IPV4, - .offset = sizeof(struct rte_ether_hdr) + - offsetof(struct rte_ipv4_hdr, next_proto_id), - }, - /* next input field (IPv4 source address) - 4 consecutive bytes. */ - { - /* rte_flow uses a bit mask for IPv4 addresses */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint32_t), - .field_index = SRC_FIELD_IPV4, - .input_index = SRC_INPUT_IPV4, - .offset = sizeof(struct rte_ether_hdr) + - offsetof(struct rte_ipv4_hdr, src_addr), - }, - /* next input field (IPv4 destination address) - 4 consecutive bytes. */ - { - /* rte_flow uses a bit mask for IPv4 addresses */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint32_t), - .field_index = DST_FIELD_IPV4, - .input_index = DST_INPUT_IPV4, - .offset = sizeof(struct rte_ether_hdr) + - offsetof(struct rte_ipv4_hdr, dst_addr), - }, - /* - * Next 2 fields (src & dst ports) form 4 consecutive bytes. - * They share the same input index. - */ - { - /* rte_flow uses a bit mask for protocol ports */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint16_t), - .field_index = SRCP_FIELD_IPV4, - .input_index = SRCP_DESTP_INPUT_IPV4, - .offset = sizeof(struct rte_ether_hdr) + - sizeof(struct rte_ipv4_hdr) + - offsetof(struct rte_tcp_hdr, src_port), - }, - { - /* rte_flow uses a bit mask for protocol ports */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint16_t), - .field_index = DSTP_FIELD_IPV4, - .input_index = SRCP_DESTP_INPUT_IPV4, - .offset = sizeof(struct rte_ether_hdr) + - sizeof(struct rte_ipv4_hdr) + - offsetof(struct rte_tcp_hdr, dst_port), - }, -}; -/* >8 End of creation of ACL table. */ - -/* Flow classify data. 8< */ -static int num_classify_rules; -static struct rte_flow_classify_rule *rules[MAX_NUM_CLASSIFY]; -static struct rte_flow_classify_ipv4_5tuple_stats ntuple_stats; -static struct rte_flow_classify_stats classify_stats = { - .stats = (void **)&ntuple_stats -}; -/* >8 End of flow classify data. */ - -/* parameters for rte_flow_classify_validate and - * rte_flow_classify_table_entry_add functions - */ - -static struct rte_flow_item eth_item = { RTE_FLOW_ITEM_TYPE_ETH, - 0, 0, 0 }; -static struct rte_flow_item end_item = { RTE_FLOW_ITEM_TYPE_END, - 0, 0, 0 }; - -/* sample actions: - * "actions count / end" - */ -struct rte_flow_query_count count = { - .reset = 1, - .hits_set = 1, - .bytes_set = 1, - .hits = 0, - .bytes = 0, -}; -static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT, - &count}; -static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0}; -static struct rte_flow_action actions[2]; - -/* sample attributes */ -static struct rte_flow_attr attr; - -/* flow_classify.c: * Based on DPDK skeleton forwarding example. */ - -/* - * Initializes a given port using global settings and with the RX buffers - * coming from the mbuf_pool passed as a parameter. - */ - -/* Initializing port using global settings. 8< */ -static inline int -port_init(uint8_t port, struct rte_mempool *mbuf_pool) -{ - struct rte_eth_conf port_conf; - struct rte_ether_addr addr; - const uint16_t rx_rings = 1, tx_rings = 1; - int retval; - uint16_t q; - struct rte_eth_dev_info dev_info; - struct rte_eth_txconf txconf; - - if (!rte_eth_dev_is_valid_port(port)) - return -1; - - memset(&port_conf, 0, sizeof(struct rte_eth_conf)); - - retval = rte_eth_dev_info_get(port, &dev_info); - if (retval != 0) { - printf("Error during getting device (port %u) info: %s\n", - port, strerror(-retval)); - return retval; - } - - if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) - port_conf.txmode.offloads |= - RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE; - - /* Configure the Ethernet device. */ - retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf); - if (retval != 0) - return retval; - - /* Allocate and set up 1 RX queue per Ethernet port. */ - for (q = 0; q < rx_rings; q++) { - retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE, - rte_eth_dev_socket_id(port), NULL, mbuf_pool); - if (retval < 0) - return retval; - } - - txconf = dev_info.default_txconf; - txconf.offloads = port_conf.txmode.offloads; - /* Allocate and set up 1 TX queue per Ethernet port. */ - for (q = 0; q < tx_rings; q++) { - retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE, - rte_eth_dev_socket_id(port), &txconf); - if (retval < 0) - return retval; - } - - /* Start the Ethernet port. 8< */ - retval = rte_eth_dev_start(port); - /* >8 End of starting the Ethernet port. */ - if (retval < 0) - return retval; - - /* Display the port MAC address. */ - retval = rte_eth_macaddr_get(port, &addr); - if (retval != 0) - return retval; - - printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 - " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", - port, RTE_ETHER_ADDR_BYTES(&addr)); - - /* Enable RX in promiscuous mode for the Ethernet device. */ - retval = rte_eth_promiscuous_enable(port); - if (retval != 0) - return retval; - - return 0; -} -/* >8 End of initializing a given port. */ - -/* - * The lcore main. This is the main thread that does the work, reading from - * an input port classifying the packets and writing to an output port. - */ - -/* Classifying the packets. 8< */ -static __rte_noreturn void -lcore_main(struct flow_classifier *cls_app) -{ - uint16_t port; - int ret; - int i = 0; - - ret = rte_flow_classify_table_entry_delete(cls_app->cls, - rules[7]); - if (ret) - printf("table_entry_delete failed [7] %d\n\n", ret); - else - printf("table_entry_delete succeeded [7]\n\n"); - - /* - * Check that the port is on the same NUMA node as the polling thread - * for best performance. - */ - RTE_ETH_FOREACH_DEV(port) - if (rte_eth_dev_socket_id(port) >= 0 && - rte_eth_dev_socket_id(port) != (int)rte_socket_id()) { - printf("\n\n"); - printf("WARNING: port %u is on remote NUMA node\n", - port); - printf("to polling thread.\n"); - printf("Performance will not be optimal.\n"); - } - printf("\nCore %u forwarding packets. ", rte_lcore_id()); - printf("[Ctrl+C to quit]\n"); - - /* Run until the application is quit or killed. 8< */ - for (;;) { - /* - * Receive packets on a port, classify them and forward them - * on the paired port. - * The mapping is 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2, etc. - */ - RTE_ETH_FOREACH_DEV(port) { - /* Get burst of RX packets, from first port of pair. */ - struct rte_mbuf *bufs[BURST_SIZE]; - const uint16_t nb_rx = rte_eth_rx_burst(port, 0, - bufs, BURST_SIZE); - - if (unlikely(nb_rx == 0)) - continue; - - for (i = 0; i < MAX_NUM_CLASSIFY; i++) { - if (rules[i]) { - ret = rte_flow_classifier_query( - cls_app->cls, - bufs, nb_rx, rules[i], - &classify_stats); - if (ret) - printf( - "rule [%d] query failed ret [%d]\n\n", - i, ret); - else { - printf( - "rule[%d] count=%"PRIu64"\n", - i, ntuple_stats.counter1); - - printf("proto = %d\n", - ntuple_stats.ipv4_5tuple.proto); - } - } - } - - /* Send burst of TX packets, to second port of pair. */ - const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0, - bufs, nb_rx); - - /* Free any unsent packets. */ - if (unlikely(nb_tx < nb_rx)) { - uint16_t buf; - - for (buf = nb_tx; buf < nb_rx; buf++) - rte_pktmbuf_free(bufs[buf]); - } - } - } - /* >8 End of main loop. */ -} -/* >8 End of lcore main. */ - -/* - * Parse IPv4 5 tuple rules file, ipv4_rules_file.txt. - * Expected format: - * '/' \ - * '/' \ - * ":" \ - * ":" \ - * '/' \ - * - */ - -static int -get_cb_field(char **in, uint32_t *fd, int base, unsigned long lim, - char dlm) -{ - unsigned long val; - char *end; - - errno = 0; - val = strtoul(*in, &end, base); - if (errno != 0 || end[0] != dlm || val > lim) - return -EINVAL; - *fd = (uint32_t)val; - *in = end + 1; - return 0; -} - -static int -parse_ipv4_net(char *in, uint32_t *addr, uint32_t *mask_len) -{ - uint32_t a, b, c, d, m; - - if (get_cb_field(&in, &a, 0, UINT8_MAX, '.')) - return -EINVAL; - if (get_cb_field(&in, &b, 0, UINT8_MAX, '.')) - return -EINVAL; - if (get_cb_field(&in, &c, 0, UINT8_MAX, '.')) - return -EINVAL; - if (get_cb_field(&in, &d, 0, UINT8_MAX, '/')) - return -EINVAL; - if (get_cb_field(&in, &m, 0, sizeof(uint32_t) * CHAR_BIT, 0)) - return -EINVAL; - - addr[0] = RTE_IPV4(a, b, c, d); - mask_len[0] = m; - return 0; -} - -static int -parse_ipv4_5tuple_rule(char *str, struct rte_eth_ntuple_filter *ntuple_filter) -{ - int i, ret; - char *s, *sp, *in[CB_FLD_NUM]; - static const char *dlm = " \t\n"; - int dim = CB_FLD_NUM; - uint32_t temp; - - s = str; - for (i = 0; i != dim; i++, s = NULL) { - in[i] = strtok_r(s, dlm, &sp); - if (in[i] == NULL) - return -EINVAL; - } - - ret = parse_ipv4_net(in[CB_FLD_SRC_ADDR], - &ntuple_filter->src_ip, - &ntuple_filter->src_ip_mask); - if (ret != 0) { - flow_classify_log("failed to read source address/mask: %s\n", - in[CB_FLD_SRC_ADDR]); - return ret; - } - - ret = parse_ipv4_net(in[CB_FLD_DST_ADDR], - &ntuple_filter->dst_ip, - &ntuple_filter->dst_ip_mask); - if (ret != 0) { - flow_classify_log("failed to read destination address/mask: %s\n", - in[CB_FLD_DST_ADDR]); - return ret; - } - - if (get_cb_field(&in[CB_FLD_SRC_PORT], &temp, 0, UINT16_MAX, 0)) - return -EINVAL; - ntuple_filter->src_port = (uint16_t)temp; - - if (strncmp(in[CB_FLD_SRC_PORT_DLM], cb_port_delim, - sizeof(cb_port_delim)) != 0) - return -EINVAL; - - if (get_cb_field(&in[CB_FLD_SRC_PORT_MASK], &temp, 0, UINT16_MAX, 0)) - return -EINVAL; - ntuple_filter->src_port_mask = (uint16_t)temp; - - if (get_cb_field(&in[CB_FLD_DST_PORT], &temp, 0, UINT16_MAX, 0)) - return -EINVAL; - ntuple_filter->dst_port = (uint16_t)temp; - - if (strncmp(in[CB_FLD_DST_PORT_DLM], cb_port_delim, - sizeof(cb_port_delim)) != 0) - return -EINVAL; - - if (get_cb_field(&in[CB_FLD_DST_PORT_MASK], &temp, 0, UINT16_MAX, 0)) - return -EINVAL; - ntuple_filter->dst_port_mask = (uint16_t)temp; - - if (get_cb_field(&in[CB_FLD_PROTO], &temp, 0, UINT8_MAX, '/')) - return -EINVAL; - ntuple_filter->proto = (uint8_t)temp; - - if (get_cb_field(&in[CB_FLD_PROTO], &temp, 0, UINT8_MAX, 0)) - return -EINVAL; - ntuple_filter->proto_mask = (uint8_t)temp; - - if (get_cb_field(&in[CB_FLD_PRIORITY], &temp, 0, UINT16_MAX, 0)) - return -EINVAL; - ntuple_filter->priority = (uint16_t)temp; - if (ntuple_filter->priority > FLOW_CLASSIFY_MAX_PRIORITY) - ret = -EINVAL; - - return ret; -} - -/* Bypass comment and empty lines */ -static inline int -is_bypass_line(char *buff) -{ - int i = 0; - - /* comment line */ - if (buff[0] == COMMENT_LEAD_CHAR) - return 1; - /* empty line */ - while (buff[i] != '\0') { - if (!isspace(buff[i])) - return 0; - i++; - } - return 1; -} - -static uint32_t -convert_depth_to_bitmask(uint32_t depth_val) -{ - uint32_t bitmask = 0; - int i, j; - - for (i = depth_val, j = 0; i > 0; i--, j++) - bitmask |= (1 << (31 - j)); - return bitmask; -} - -static int -add_classify_rule(struct rte_eth_ntuple_filter *ntuple_filter, - struct flow_classifier *cls_app) -{ - int ret = -1; - int key_found; - struct rte_flow_error error; - struct rte_flow_item_ipv4 ipv4_spec; - struct rte_flow_item_ipv4 ipv4_mask; - struct rte_flow_item ipv4_udp_item; - struct rte_flow_item ipv4_tcp_item; - struct rte_flow_item ipv4_sctp_item; - struct rte_flow_item_udp udp_spec; - struct rte_flow_item_udp udp_mask; - struct rte_flow_item udp_item; - struct rte_flow_item_tcp tcp_spec; - struct rte_flow_item_tcp tcp_mask; - struct rte_flow_item tcp_item; - struct rte_flow_item_sctp sctp_spec; - struct rte_flow_item_sctp sctp_mask; - struct rte_flow_item sctp_item; - struct rte_flow_item pattern_ipv4_5tuple[4]; - struct rte_flow_classify_rule *rule; - uint8_t ipv4_proto; - - if (num_classify_rules >= MAX_NUM_CLASSIFY) { - printf( - "\nINFO: classify rule capacity %d reached\n", - num_classify_rules); - return ret; - } - - /* set up parameters for validate and add */ - memset(&ipv4_spec, 0, sizeof(ipv4_spec)); - ipv4_spec.hdr.next_proto_id = ntuple_filter->proto; - ipv4_spec.hdr.src_addr = ntuple_filter->src_ip; - ipv4_spec.hdr.dst_addr = ntuple_filter->dst_ip; - ipv4_proto = ipv4_spec.hdr.next_proto_id; - - memset(&ipv4_mask, 0, sizeof(ipv4_mask)); - ipv4_mask.hdr.next_proto_id = ntuple_filter->proto_mask; - ipv4_mask.hdr.src_addr = ntuple_filter->src_ip_mask; - ipv4_mask.hdr.src_addr = - convert_depth_to_bitmask(ipv4_mask.hdr.src_addr); - ipv4_mask.hdr.dst_addr = ntuple_filter->dst_ip_mask; - ipv4_mask.hdr.dst_addr = - convert_depth_to_bitmask(ipv4_mask.hdr.dst_addr); - - switch (ipv4_proto) { - case IPPROTO_UDP: - ipv4_udp_item.type = RTE_FLOW_ITEM_TYPE_IPV4; - ipv4_udp_item.spec = &ipv4_spec; - ipv4_udp_item.mask = &ipv4_mask; - ipv4_udp_item.last = NULL; - - udp_spec.hdr.src_port = ntuple_filter->src_port; - udp_spec.hdr.dst_port = ntuple_filter->dst_port; - udp_spec.hdr.dgram_len = 0; - udp_spec.hdr.dgram_cksum = 0; - - udp_mask.hdr.src_port = ntuple_filter->src_port_mask; - udp_mask.hdr.dst_port = ntuple_filter->dst_port_mask; - udp_mask.hdr.dgram_len = 0; - udp_mask.hdr.dgram_cksum = 0; - - udp_item.type = RTE_FLOW_ITEM_TYPE_UDP; - udp_item.spec = &udp_spec; - udp_item.mask = &udp_mask; - udp_item.last = NULL; - - attr.priority = ntuple_filter->priority; - pattern_ipv4_5tuple[1] = ipv4_udp_item; - pattern_ipv4_5tuple[2] = udp_item; - break; - case IPPROTO_TCP: - ipv4_tcp_item.type = RTE_FLOW_ITEM_TYPE_IPV4; - ipv4_tcp_item.spec = &ipv4_spec; - ipv4_tcp_item.mask = &ipv4_mask; - ipv4_tcp_item.last = NULL; - - memset(&tcp_spec, 0, sizeof(tcp_spec)); - tcp_spec.hdr.src_port = ntuple_filter->src_port; - tcp_spec.hdr.dst_port = ntuple_filter->dst_port; - - memset(&tcp_mask, 0, sizeof(tcp_mask)); - tcp_mask.hdr.src_port = ntuple_filter->src_port_mask; - tcp_mask.hdr.dst_port = ntuple_filter->dst_port_mask; - - tcp_item.type = RTE_FLOW_ITEM_TYPE_TCP; - tcp_item.spec = &tcp_spec; - tcp_item.mask = &tcp_mask; - tcp_item.last = NULL; - - attr.priority = ntuple_filter->priority; - pattern_ipv4_5tuple[1] = ipv4_tcp_item; - pattern_ipv4_5tuple[2] = tcp_item; - break; - case IPPROTO_SCTP: - ipv4_sctp_item.type = RTE_FLOW_ITEM_TYPE_IPV4; - ipv4_sctp_item.spec = &ipv4_spec; - ipv4_sctp_item.mask = &ipv4_mask; - ipv4_sctp_item.last = NULL; - - sctp_spec.hdr.src_port = ntuple_filter->src_port; - sctp_spec.hdr.dst_port = ntuple_filter->dst_port; - sctp_spec.hdr.cksum = 0; - sctp_spec.hdr.tag = 0; - - sctp_mask.hdr.src_port = ntuple_filter->src_port_mask; - sctp_mask.hdr.dst_port = ntuple_filter->dst_port_mask; - sctp_mask.hdr.cksum = 0; - sctp_mask.hdr.tag = 0; - - sctp_item.type = RTE_FLOW_ITEM_TYPE_SCTP; - sctp_item.spec = &sctp_spec; - sctp_item.mask = &sctp_mask; - sctp_item.last = NULL; - - attr.priority = ntuple_filter->priority; - pattern_ipv4_5tuple[1] = ipv4_sctp_item; - pattern_ipv4_5tuple[2] = sctp_item; - break; - default: - return ret; - } - - attr.ingress = 1; - pattern_ipv4_5tuple[0] = eth_item; - pattern_ipv4_5tuple[3] = end_item; - actions[0] = count_action; - actions[1] = end_action; - - /* Validate and add rule */ - ret = rte_flow_classify_validate(cls_app->cls, &attr, - pattern_ipv4_5tuple, actions, &error); - if (ret) { - printf("table entry validate failed ipv4_proto = %u\n", - ipv4_proto); - return ret; - } - - rule = rte_flow_classify_table_entry_add( - cls_app->cls, &attr, pattern_ipv4_5tuple, - actions, &key_found, &error); - if (rule == NULL) { - printf("table entry add failed ipv4_proto = %u\n", - ipv4_proto); - ret = -1; - return ret; - } - - rules[num_classify_rules] = rule; - num_classify_rules++; - return 0; -} - -/* Reads file and calls the add_classify_rule function. 8< */ -static int -add_rules(const char *rule_path, struct flow_classifier *cls_app) -{ - FILE *fh; - char buff[LINE_MAX]; - unsigned int i = 0; - unsigned int total_num = 0; - struct rte_eth_ntuple_filter ntuple_filter; - int ret; - - fh = fopen(rule_path, "rb"); - if (fh == NULL) - rte_exit(EXIT_FAILURE, "%s: fopen %s failed\n", __func__, - rule_path); - - ret = fseek(fh, 0, SEEK_SET); - if (ret) - rte_exit(EXIT_FAILURE, "%s: fseek %d failed\n", __func__, - ret); - - i = 0; - while (fgets(buff, LINE_MAX, fh) != NULL) { - i++; - - if (is_bypass_line(buff)) - continue; - - if (total_num >= FLOW_CLASSIFY_MAX_RULE_NUM - 1) { - printf("\nINFO: classify rule capacity %d reached\n", - total_num); - break; - } - - if (parse_ipv4_5tuple_rule(buff, &ntuple_filter) != 0) - rte_exit(EXIT_FAILURE, - "%s Line %u: parse rules error\n", - rule_path, i); - - if (add_classify_rule(&ntuple_filter, cls_app) != 0) - rte_exit(EXIT_FAILURE, "add rule error\n"); - - total_num++; - } - - fclose(fh); - return 0; -} -/* >8 End of add_rules. */ - -/* display usage */ -static void -print_usage(const char *prgname) -{ - printf("%s usage:\n", prgname); - printf("[EAL options] -- --"OPTION_RULE_IPV4"=FILE: "); - printf("specify the ipv4 rules file.\n"); - printf("Each rule occupies one line in the file.\n"); -} - -/* Parse the argument given in the command line of the application */ -static int -parse_args(int argc, char **argv) -{ - int opt, ret; - char **argvopt; - int option_index; - char *prgname = argv[0]; - static struct option lgopts[] = { - {OPTION_RULE_IPV4, 1, 0, 0}, - {NULL, 0, 0, 0} - }; - - argvopt = argv; - - while ((opt = getopt_long(argc, argvopt, "", - lgopts, &option_index)) != EOF) { - - switch (opt) { - /* long options */ - case 0: - if (!strncmp(lgopts[option_index].name, - OPTION_RULE_IPV4, - sizeof(OPTION_RULE_IPV4))) - parm_config.rule_ipv4_name = optarg; - break; - default: - print_usage(prgname); - return -1; - } - } - - if (optind >= 0) - argv[optind-1] = prgname; - - ret = optind-1; - optind = 1; /* reset getopt lib */ - return ret; -} - -/* - * The main function, which does initialization and calls the lcore_main - * function. - */ -int -main(int argc, char *argv[]) -{ - struct rte_mempool *mbuf_pool; - uint16_t nb_ports; - uint16_t portid; - int ret; - int socket_id; - struct rte_table_acl_params table_acl_params; - struct rte_flow_classify_table_params cls_table_params; - struct flow_classifier *cls_app; - struct rte_flow_classifier_params cls_params; - uint32_t size; - - /* Initialize the Environment Abstraction Layer (EAL). 8< */ - ret = rte_eal_init(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); - /* >8 End of initialization of EAL. */ - - argc -= ret; - argv += ret; - - /* Parse application arguments (after the EAL ones). 8< */ - ret = parse_args(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Invalid flow_classify parameters\n"); - /* >8 End of parse application arguments. */ - - /* Check that there is an even number of ports to send/receive on. */ - nb_ports = rte_eth_dev_count_avail(); - if (nb_ports < 2 || (nb_ports & 1)) - rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n"); - - /* Creates a new mempool in memory to hold the mbufs. 8< */ - mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports, - MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); - /* >8 End of creation of new mempool in memory. */ - - if (mbuf_pool == NULL) - rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); - - /* Initialize all ports. 8< */ - RTE_ETH_FOREACH_DEV(portid) - if (port_init(portid, mbuf_pool) != 0) - rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n", - portid); - /* >8 End of initialization of all ports. */ - - if (rte_lcore_count() > 1) - printf("\nWARNING: Too many lcores enabled. Only 1 used.\n"); - - socket_id = rte_eth_dev_socket_id(0); - if (socket_id == SOCKET_ID_ANY) - socket_id = rte_lcore_to_socket_id(rte_get_next_lcore(-1, 0, 0)); - - /* Memory allocation. 8< */ - size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct flow_classifier_acl)); - cls_app = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE); - if (cls_app == NULL) - rte_exit(EXIT_FAILURE, "Cannot allocate classifier memory\n"); - - cls_params.name = "flow_classifier"; - cls_params.socket_id = socket_id; - - cls_app->cls = rte_flow_classifier_create(&cls_params); - if (cls_app->cls == NULL) { - rte_free(cls_app); - rte_exit(EXIT_FAILURE, "Cannot create classifier\n"); - } - - /* initialise ACL table params */ - table_acl_params.name = "table_acl_ipv4_5tuple"; - table_acl_params.n_rules = FLOW_CLASSIFY_MAX_RULE_NUM; - table_acl_params.n_rule_fields = RTE_DIM(ipv4_defs); - memcpy(table_acl_params.field_format, ipv4_defs, sizeof(ipv4_defs)); - - /* initialise table create params */ - cls_table_params.ops = &rte_table_acl_ops; - cls_table_params.arg_create = &table_acl_params; - cls_table_params.type = RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE; - - ret = rte_flow_classify_table_create(cls_app->cls, &cls_table_params); - if (ret) { - rte_flow_classifier_free(cls_app->cls); - rte_free(cls_app); - rte_exit(EXIT_FAILURE, "Failed to create classifier table\n"); - } - /* >8 End of initialization of table create params. */ - - /* read file of IPv4 5 tuple rules and initialize parameters - * for rte_flow_classify_validate and rte_flow_classify_table_entry_add - * API's. - */ - - /* Read file of IPv4 tuple rules. 8< */ - if (add_rules(parm_config.rule_ipv4_name, cls_app)) { - rte_flow_classifier_free(cls_app->cls); - rte_free(cls_app); - rte_exit(EXIT_FAILURE, "Failed to add rules\n"); - } - /* >8 End of reading file of IPv4 5 tuple rules. */ - - /* Call lcore_main on the main core only. */ - lcore_main(cls_app); - - /* clean up the EAL */ - rte_eal_cleanup(); - - return 0; -} diff --git a/examples/flow_classify/ipv4_rules_file.txt b/examples/flow_classify/ipv4_rules_file.txt deleted file mode 100644 index cd5215736aaf..000000000000 --- a/examples/flow_classify/ipv4_rules_file.txt +++ /dev/null @@ -1,14 +0,0 @@ -#file format: -#src_ip/masklen dst_ip/masklen src_port : mask dst_port : mask proto/mask priority -# -2.2.2.3/24 2.2.2.7/24 32 : 0xffff 33 : 0xffff 17/0xff 0 -9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 17/0xff 1 -9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 6/0xff 2 -9.9.8.3/24 9.9.8.7/24 32 : 0xffff 33 : 0xffff 6/0xff 3 -6.7.8.9/24 2.3.4.5/24 32 : 0x0000 33 : 0x0000 132/0xff 4 -6.7.8.9/32 192.168.0.36/32 10 : 0xffff 11 : 0xffff 6/0xfe 5 -6.7.8.9/24 192.168.0.36/24 10 : 0xffff 11 : 0xffff 6/0xfe 6 -6.7.8.9/16 192.168.0.36/16 10 : 0xffff 11 : 0xffff 6/0xfe 7 -6.7.8.9/8 192.168.0.36/8 10 : 0xffff 11 : 0xffff 6/0xfe 8 -#error rules -#9.8.7.6/8 192.168.0.36/8 10 : 0xffff 11 : 0xffff 6/0xfe 9 diff --git a/examples/flow_classify/meson.build b/examples/flow_classify/meson.build deleted file mode 100644 index 1be1bf037427..000000000000 --- a/examples/flow_classify/meson.build +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2017 Intel Corporation - -# meson file, for building this example as part of a main DPDK build. -# -# To build this example as a standalone application with an already-installed -# DPDK instance, use 'make' - -deps += 'flow_classify' -allow_experimental_apis = true -sources = files( - 'flow_classify.c', -) diff --git a/examples/meson.build b/examples/meson.build index 55ba8847a053..65c8303a9d23 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -16,7 +16,6 @@ all_examples = [ 'ethtool', 'eventdev_pipeline', 'fips_validation', - 'flow_classify', 'flow_filtering', 'helloworld', 'ip_fragmentation', diff --git a/lib/flow_classify/meson.build b/lib/flow_classify/meson.build deleted file mode 100644 index 3bb861c68fb5..000000000000 --- a/lib/flow_classify/meson.build +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2017 Intel Corporation - -if is_windows - build = false - reason = 'not supported on Windows' - subdir_done() -endif - -sources = files('rte_flow_classify.c', 'rte_flow_classify_parse.c') -headers = files('rte_flow_classify.h') -deps += ['net', 'table'] diff --git a/lib/flow_classify/rte_flow_classify.c b/lib/flow_classify/rte_flow_classify.c deleted file mode 100644 index 60ca319f24e4..000000000000 --- a/lib/flow_classify/rte_flow_classify.c +++ /dev/null @@ -1,670 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#include -#include -#include "rte_flow_classify_parse.h" -#include - -static uint32_t unique_id = 1; - -enum rte_flow_classify_table_type table_type - = RTE_FLOW_CLASSIFY_TABLE_TYPE_NONE; - -struct rte_flow_classify_table_entry { - /* meta-data for classify rule */ - uint32_t rule_id; - - /* Flow action */ - struct classify_action action; -}; - -struct rte_cls_table { - /* Input parameters */ - struct rte_table_ops ops; - uint32_t entry_size; - enum rte_flow_classify_table_type type; - - /* Handle to the low-level table object */ - void *h_table; -}; - -#define RTE_FLOW_CLASSIFIER_MAX_NAME_SZ 256 - -struct rte_flow_classifier { - /* Input parameters */ - char name[RTE_FLOW_CLASSIFIER_MAX_NAME_SZ]; - int socket_id; - - /* Internal */ - /* ntuple_filter */ - struct rte_eth_ntuple_filter ntuple_filter; - - /* classifier tables */ - struct rte_cls_table tables[RTE_FLOW_CLASSIFY_TABLE_MAX]; - uint32_t table_mask; - uint32_t num_tables; - - uint16_t nb_pkts; - struct rte_flow_classify_table_entry - *entries[RTE_PORT_IN_BURST_SIZE_MAX]; -} __rte_cache_aligned; - -enum { - PROTO_FIELD_IPV4, - SRC_FIELD_IPV4, - DST_FIELD_IPV4, - SRCP_FIELD_IPV4, - DSTP_FIELD_IPV4, - NUM_FIELDS_IPV4 -}; - -struct acl_keys { - struct rte_table_acl_rule_add_params key_add; /* add key */ - struct rte_table_acl_rule_delete_params key_del; /* delete key */ -}; - -struct classify_rules { - enum rte_flow_classify_rule_type type; - union { - struct rte_flow_classify_ipv4_5tuple ipv4_5tuple; - } u; -}; - -struct rte_flow_classify_rule { - uint32_t id; /* unique ID of classify rule */ - enum rte_flow_classify_table_type tbl_type; /* rule table */ - struct classify_rules rules; /* union of rules */ - union { - struct acl_keys key; - } u; - int key_found; /* rule key found in table */ - struct rte_flow_classify_table_entry entry; /* rule meta data */ - void *entry_ptr; /* handle to the table entry for rule meta data */ -}; - -int -rte_flow_classify_validate( - struct rte_flow_classifier *cls, - const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - struct rte_flow_error *error) -{ - struct rte_flow_item *items; - parse_filter_t parse_filter; - uint32_t item_num = 0; - uint32_t i = 0; - int ret; - - if (error == NULL) - return -EINVAL; - - if (cls == NULL) { - RTE_FLOW_CLASSIFY_LOG(ERR, - "%s: rte_flow_classifier parameter is NULL\n", - __func__); - return -EINVAL; - } - - if (!attr) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ATTR, - NULL, "NULL attribute."); - return -EINVAL; - } - - if (!pattern) { - rte_flow_error_set(error, - EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM, - NULL, "NULL pattern."); - return -EINVAL; - } - - if (!actions) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION_NUM, - NULL, "NULL action."); - return -EINVAL; - } - - memset(&cls->ntuple_filter, 0, sizeof(cls->ntuple_filter)); - - /* Get the non-void item number of pattern */ - while ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_END) { - if ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_VOID) - item_num++; - i++; - } - item_num++; - - items = malloc(item_num * sizeof(struct rte_flow_item)); - if (!items) { - rte_flow_error_set(error, ENOMEM, - RTE_FLOW_ERROR_TYPE_ITEM_NUM, - NULL, "No memory for pattern items."); - return -ENOMEM; - } - - memset(items, 0, item_num * sizeof(struct rte_flow_item)); - classify_pattern_skip_void_item(items, pattern); - - parse_filter = classify_find_parse_filter_func(items); - if (!parse_filter) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - pattern, "Unsupported pattern"); - free(items); - return -EINVAL; - } - - ret = parse_filter(attr, items, actions, &cls->ntuple_filter, error); - free(items); - return ret; -} - - -#define uint32_t_to_char(ip, a, b, c, d) do {\ - *a = (unsigned char)(ip >> 24 & 0xff);\ - *b = (unsigned char)(ip >> 16 & 0xff);\ - *c = (unsigned char)(ip >> 8 & 0xff);\ - *d = (unsigned char)(ip & 0xff);\ - } while (0) - -static inline void -print_acl_ipv4_key_add(struct rte_table_acl_rule_add_params *key) -{ - unsigned char a, b, c, d; - - printf("%s: 0x%02hhx/0x%hhx ", __func__, - key->field_value[PROTO_FIELD_IPV4].value.u8, - key->field_value[PROTO_FIELD_IPV4].mask_range.u8); - - uint32_t_to_char(key->field_value[SRC_FIELD_IPV4].value.u32, - &a, &b, &c, &d); - printf(" %hhu.%hhu.%hhu.%hhu/0x%x ", a, b, c, d, - key->field_value[SRC_FIELD_IPV4].mask_range.u32); - - uint32_t_to_char(key->field_value[DST_FIELD_IPV4].value.u32, - &a, &b, &c, &d); - printf("%hhu.%hhu.%hhu.%hhu/0x%x ", a, b, c, d, - key->field_value[DST_FIELD_IPV4].mask_range.u32); - - printf("%hu : 0x%x %hu : 0x%x", - key->field_value[SRCP_FIELD_IPV4].value.u16, - key->field_value[SRCP_FIELD_IPV4].mask_range.u16, - key->field_value[DSTP_FIELD_IPV4].value.u16, - key->field_value[DSTP_FIELD_IPV4].mask_range.u16); - - printf(" priority: 0x%x\n", key->priority); -} - -static inline void -print_acl_ipv4_key_delete(struct rte_table_acl_rule_delete_params *key) -{ - unsigned char a, b, c, d; - - printf("%s: 0x%02hhx/0x%hhx ", __func__, - key->field_value[PROTO_FIELD_IPV4].value.u8, - key->field_value[PROTO_FIELD_IPV4].mask_range.u8); - - uint32_t_to_char(key->field_value[SRC_FIELD_IPV4].value.u32, - &a, &b, &c, &d); - printf(" %hhu.%hhu.%hhu.%hhu/0x%x ", a, b, c, d, - key->field_value[SRC_FIELD_IPV4].mask_range.u32); - - uint32_t_to_char(key->field_value[DST_FIELD_IPV4].value.u32, - &a, &b, &c, &d); - printf("%hhu.%hhu.%hhu.%hhu/0x%x ", a, b, c, d, - key->field_value[DST_FIELD_IPV4].mask_range.u32); - - printf("%hu : 0x%x %hu : 0x%x\n", - key->field_value[SRCP_FIELD_IPV4].value.u16, - key->field_value[SRCP_FIELD_IPV4].mask_range.u16, - key->field_value[DSTP_FIELD_IPV4].value.u16, - key->field_value[DSTP_FIELD_IPV4].mask_range.u16); -} - -static int -rte_flow_classifier_check_params(struct rte_flow_classifier_params *params) -{ - if (params == NULL) { - RTE_FLOW_CLASSIFY_LOG(ERR, - "%s: Incorrect value for parameter params\n", __func__); - return -EINVAL; - } - - /* name */ - if (params->name == NULL) { - RTE_FLOW_CLASSIFY_LOG(ERR, - "%s: Incorrect value for parameter name\n", __func__); - return -EINVAL; - } - - /* socket */ - if (params->socket_id < 0) { - RTE_FLOW_CLASSIFY_LOG(ERR, - "%s: Incorrect value for parameter socket_id\n", - __func__); - return -EINVAL; - } - - return 0; -} - -struct rte_flow_classifier * -rte_flow_classifier_create(struct rte_flow_classifier_params *params) -{ - struct rte_flow_classifier *cls; - int ret; - - RTE_FLOW_CLASSIFY_LOG(WARNING, - "WARNING: flow_classify is deprecated and will be removed in DPDK 23.11\n"); - - /* Check input parameters */ - ret = rte_flow_classifier_check_params(params); - if (ret != 0) { - RTE_FLOW_CLASSIFY_LOG(ERR, - "%s: flow classifier params check failed (%d)\n", - __func__, ret); - return NULL; - } - - /* Allocate memory for the flow classifier */ - cls = rte_zmalloc_socket("FLOW_CLASSIFIER", - sizeof(struct rte_flow_classifier), - RTE_CACHE_LINE_SIZE, params->socket_id); - - if (cls == NULL) { - RTE_FLOW_CLASSIFY_LOG(ERR, - "%s: flow classifier memory allocation failed\n", - __func__); - return NULL; - } - - /* Save input parameters */ - strlcpy(cls->name, params->name, RTE_FLOW_CLASSIFIER_MAX_NAME_SZ); - - cls->socket_id = params->socket_id; - - return cls; -} - -static void -rte_flow_classify_table_free(struct rte_cls_table *table) -{ - if (table->ops.f_free != NULL) - table->ops.f_free(table->h_table); -} - -int -rte_flow_classifier_free(struct rte_flow_classifier *cls) -{ - uint32_t i; - - /* Check input parameters */ - if (cls == NULL) { - RTE_FLOW_CLASSIFY_LOG(ERR, - "%s: rte_flow_classifier parameter is NULL\n", - __func__); - return -EINVAL; - } - - /* Free tables */ - for (i = 0; i < cls->num_tables; i++) { - struct rte_cls_table *table = &cls->tables[i]; - - rte_flow_classify_table_free(table); - } - - /* Free flow classifier memory */ - rte_free(cls); - - return 0; -} - -static int -rte_table_check_params(struct rte_flow_classifier *cls, - struct rte_flow_classify_table_params *params) -{ - if (cls == NULL) { - RTE_FLOW_CLASSIFY_LOG(ERR, - "%s: flow classifier parameter is NULL\n", - __func__); - return -EINVAL; - } - if (params == NULL) { - RTE_FLOW_CLASSIFY_LOG(ERR, "%s: params parameter is NULL\n", - __func__); - return -EINVAL; - } - - /* ops */ - if (params->ops == NULL) { - RTE_FLOW_CLASSIFY_LOG(ERR, "%s: params->ops is NULL\n", - __func__); - return -EINVAL; - } - - if (params->ops->f_create == NULL) { - RTE_FLOW_CLASSIFY_LOG(ERR, - "%s: f_create function pointer is NULL\n", __func__); - return -EINVAL; - } - - if (params->ops->f_lookup == NULL) { - RTE_FLOW_CLASSIFY_LOG(ERR, - "%s: f_lookup function pointer is NULL\n", __func__); - return -EINVAL; - } - - /* De we have room for one more table? */ - if (cls->num_tables == RTE_FLOW_CLASSIFY_TABLE_MAX) { - RTE_FLOW_CLASSIFY_LOG(ERR, - "%s: Incorrect value for num_tables parameter\n", - __func__); - return -EINVAL; - } - - return 0; -} - -int -rte_flow_classify_table_create(struct rte_flow_classifier *cls, - struct rte_flow_classify_table_params *params) -{ - struct rte_cls_table *table; - void *h_table; - uint32_t entry_size; - int ret; - - /* Check input arguments */ - ret = rte_table_check_params(cls, params); - if (ret != 0) - return ret; - - /* calculate table entry size */ - entry_size = sizeof(struct rte_flow_classify_table_entry); - - /* Create the table */ - h_table = params->ops->f_create(params->arg_create, cls->socket_id, - entry_size); - if (h_table == NULL) { - RTE_FLOW_CLASSIFY_LOG(ERR, "%s: Table creation failed\n", - __func__); - return -EINVAL; - } - - /* Commit current table to the classifier */ - table = &cls->tables[cls->num_tables]; - table->type = params->type; - cls->num_tables++; - - /* Save input parameters */ - memcpy(&table->ops, params->ops, sizeof(struct rte_table_ops)); - - /* Initialize table internal data structure */ - table->entry_size = entry_size; - table->h_table = h_table; - - return 0; -} - -static struct rte_flow_classify_rule * -allocate_acl_ipv4_5tuple_rule(struct rte_flow_classifier *cls) -{ - struct rte_flow_classify_rule *rule; - - rule = malloc(sizeof(struct rte_flow_classify_rule)); - if (!rule) - return rule; - - memset(rule, 0, sizeof(struct rte_flow_classify_rule)); - rule->id = unique_id++; - rule->rules.type = RTE_FLOW_CLASSIFY_RULE_TYPE_IPV4_5TUPLE; - - /* key add values */ - rule->u.key.key_add.priority = cls->ntuple_filter.priority; - rule->u.key.key_add.field_value[PROTO_FIELD_IPV4].mask_range.u8 = - cls->ntuple_filter.proto_mask; - rule->u.key.key_add.field_value[PROTO_FIELD_IPV4].value.u8 = - cls->ntuple_filter.proto; - rule->rules.u.ipv4_5tuple.proto = cls->ntuple_filter.proto; - rule->rules.u.ipv4_5tuple.proto_mask = cls->ntuple_filter.proto_mask; - - rule->u.key.key_add.field_value[SRC_FIELD_IPV4].mask_range.u32 = - cls->ntuple_filter.src_ip_mask; - rule->u.key.key_add.field_value[SRC_FIELD_IPV4].value.u32 = - cls->ntuple_filter.src_ip; - rule->rules.u.ipv4_5tuple.src_ip_mask = cls->ntuple_filter.src_ip_mask; - rule->rules.u.ipv4_5tuple.src_ip = cls->ntuple_filter.src_ip; - - rule->u.key.key_add.field_value[DST_FIELD_IPV4].mask_range.u32 = - cls->ntuple_filter.dst_ip_mask; - rule->u.key.key_add.field_value[DST_FIELD_IPV4].value.u32 = - cls->ntuple_filter.dst_ip; - rule->rules.u.ipv4_5tuple.dst_ip_mask = cls->ntuple_filter.dst_ip_mask; - rule->rules.u.ipv4_5tuple.dst_ip = cls->ntuple_filter.dst_ip; - - rule->u.key.key_add.field_value[SRCP_FIELD_IPV4].mask_range.u16 = - cls->ntuple_filter.src_port_mask; - rule->u.key.key_add.field_value[SRCP_FIELD_IPV4].value.u16 = - cls->ntuple_filter.src_port; - rule->rules.u.ipv4_5tuple.src_port_mask = - cls->ntuple_filter.src_port_mask; - rule->rules.u.ipv4_5tuple.src_port = cls->ntuple_filter.src_port; - - rule->u.key.key_add.field_value[DSTP_FIELD_IPV4].mask_range.u16 = - cls->ntuple_filter.dst_port_mask; - rule->u.key.key_add.field_value[DSTP_FIELD_IPV4].value.u16 = - cls->ntuple_filter.dst_port; - rule->rules.u.ipv4_5tuple.dst_port_mask = - cls->ntuple_filter.dst_port_mask; - rule->rules.u.ipv4_5tuple.dst_port = cls->ntuple_filter.dst_port; - - if (rte_log_can_log(librte_flow_classify_logtype, RTE_LOG_DEBUG)) - print_acl_ipv4_key_add(&rule->u.key.key_add); - - /* key delete values */ - memcpy(&rule->u.key.key_del.field_value[PROTO_FIELD_IPV4], - &rule->u.key.key_add.field_value[PROTO_FIELD_IPV4], - NUM_FIELDS_IPV4 * sizeof(struct rte_acl_field)); - - if (rte_log_can_log(librte_flow_classify_logtype, RTE_LOG_DEBUG)) - print_acl_ipv4_key_delete(&rule->u.key.key_del); - - return rule; -} - -struct rte_flow_classify_rule * -rte_flow_classify_table_entry_add(struct rte_flow_classifier *cls, - const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - int *key_found, - struct rte_flow_error *error) -{ - struct rte_flow_classify_rule *rule; - struct rte_flow_classify_table_entry *table_entry; - struct classify_action *action; - uint32_t i; - int ret; - - if (!error) - return NULL; - - if (key_found == NULL) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, "NULL key_found."); - return NULL; - } - - /* parse attr, pattern and actions */ - ret = rte_flow_classify_validate(cls, attr, pattern, actions, error); - if (ret < 0) - return NULL; - - switch (table_type) { - case RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE: - rule = allocate_acl_ipv4_5tuple_rule(cls); - if (!rule) - return NULL; - rule->tbl_type = table_type; - cls->table_mask |= table_type; - break; - default: - return NULL; - } - - action = classify_get_flow_action(); - table_entry = &rule->entry; - table_entry->rule_id = rule->id; - table_entry->action.action_mask = action->action_mask; - - /* Copy actions */ - if (action->action_mask & (1LLU << RTE_FLOW_ACTION_TYPE_COUNT)) { - memcpy(&table_entry->action.act.counter, &action->act.counter, - sizeof(table_entry->action.act.counter)); - } - if (action->action_mask & (1LLU << RTE_FLOW_ACTION_TYPE_MARK)) { - memcpy(&table_entry->action.act.mark, &action->act.mark, - sizeof(table_entry->action.act.mark)); - } - - for (i = 0; i < cls->num_tables; i++) { - struct rte_cls_table *table = &cls->tables[i]; - - if (table->type == table_type) { - if (table->ops.f_add != NULL) { - ret = table->ops.f_add( - table->h_table, - &rule->u.key.key_add, - &rule->entry, - &rule->key_found, - &rule->entry_ptr); - if (ret) { - free(rule); - return NULL; - } - - *key_found = rule->key_found; - } - - return rule; - } - } - free(rule); - return NULL; -} - -int -rte_flow_classify_table_entry_delete(struct rte_flow_classifier *cls, - struct rte_flow_classify_rule *rule) -{ - uint32_t i; - int ret = -EINVAL; - - if (!cls || !rule) - return ret; - enum rte_flow_classify_table_type tbl_type = rule->tbl_type; - - for (i = 0; i < cls->num_tables; i++) { - struct rte_cls_table *table = &cls->tables[i]; - - if (table->type == tbl_type) { - if (table->ops.f_delete != NULL) { - ret = table->ops.f_delete(table->h_table, - &rule->u.key.key_del, - &rule->key_found, - &rule->entry); - if (ret == 0) - free(rule); - return ret; - } - } - } - return ret; -} - -static int -flow_classifier_lookup(struct rte_flow_classifier *cls, - struct rte_cls_table *table, - struct rte_mbuf **pkts, - const uint16_t nb_pkts) -{ - int ret = -EINVAL; - uint64_t pkts_mask; - uint64_t lookup_hit_mask; - - pkts_mask = RTE_LEN2MASK(nb_pkts, uint64_t); - ret = table->ops.f_lookup(table->h_table, - pkts, pkts_mask, &lookup_hit_mask, - (void **)cls->entries); - - if (!ret && lookup_hit_mask) - cls->nb_pkts = nb_pkts; - else - cls->nb_pkts = 0; - - return ret; -} - -static int -action_apply(struct rte_flow_classifier *cls, - struct rte_flow_classify_rule *rule, - struct rte_flow_classify_stats *stats) -{ - struct rte_flow_classify_ipv4_5tuple_stats *ntuple_stats; - struct rte_flow_classify_table_entry *entry = &rule->entry; - uint64_t count = 0; - uint32_t action_mask = entry->action.action_mask; - int i, ret = -EINVAL; - - if (action_mask & (1LLU << RTE_FLOW_ACTION_TYPE_COUNT)) { - for (i = 0; i < cls->nb_pkts; i++) { - if (rule->id == cls->entries[i]->rule_id) - count++; - } - if (count) { - ret = 0; - ntuple_stats = stats->stats; - ntuple_stats->counter1 = count; - ntuple_stats->ipv4_5tuple = rule->rules.u.ipv4_5tuple; - } - } - return ret; -} - -int -rte_flow_classifier_query(struct rte_flow_classifier *cls, - struct rte_mbuf **pkts, - const uint16_t nb_pkts, - struct rte_flow_classify_rule *rule, - struct rte_flow_classify_stats *stats) -{ - enum rte_flow_classify_table_type tbl_type; - uint32_t i; - int ret = -EINVAL; - - if (!cls || !rule || !stats || !pkts || nb_pkts == 0) - return ret; - - tbl_type = rule->tbl_type; - for (i = 0; i < cls->num_tables; i++) { - struct rte_cls_table *table = &cls->tables[i]; - - if (table->type == tbl_type) { - ret = flow_classifier_lookup(cls, table, - pkts, nb_pkts); - if (!ret) { - ret = action_apply(cls, rule, stats); - return ret; - } - } - } - return ret; -} - -RTE_LOG_REGISTER_DEFAULT(librte_flow_classify_logtype, INFO); diff --git a/lib/flow_classify/rte_flow_classify.h b/lib/flow_classify/rte_flow_classify.h deleted file mode 100644 index 39512b620667..000000000000 --- a/lib/flow_classify/rte_flow_classify.h +++ /dev/null @@ -1,284 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#ifndef _RTE_FLOW_CLASSIFY_H_ -#define _RTE_FLOW_CLASSIFY_H_ - -/** - * @file - * - * RTE Flow Classify Library. - * - * @warning - * @b EXPERIMENTAL: - * All functions in this file may be changed or removed without prior notice. - * - * This library provides flow record information with some measured properties. - * - * Application should define the flow and measurement criteria (action) for it. - * - * The Library doesn't maintain any flow records itself, instead flow - * information is returned to upper layer only for given packets. - * - * It is application's responsibility to call rte_flow_classifier_query() - * for a burst of packets, just after receiving them or before transmitting - * them. - * Application should provide the flow type interested in, measurement to apply - * to that flow in rte_flow_classify_table_entry_add() API, and should provide - * the rte_flow_classifier object and storage to put results in for the - * rte_flow_classifier_query() API. - * - * Usage: - * - application calls rte_flow_classifier_create() to create an - * rte_flow_classifier object. - * - application calls rte_flow_classify_table_create() to create a table - * in the rte_flow_classifier object. - * - application calls rte_flow_classify_table_entry_add() to add a rule to - * the table in the rte_flow_classifier object. - * - application calls rte_flow_classifier_query() in a polling manner, - * preferably after rte_eth_rx_burst(). This will cause the library to - * match packet information to flow information with some measurements. - * - rte_flow_classifier object can be destroyed when it is no longer needed - * with rte_flow_classifier_free() - */ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern int librte_flow_classify_logtype; - -#define RTE_FLOW_CLASSIFY_LOG(level, ...) \ - rte_log(RTE_LOG_ ## level, \ - librte_flow_classify_logtype, \ - RTE_FMT("%s(): " RTE_FMT_HEAD(__VA_ARGS__,), \ - __func__, \ - RTE_FMT_TAIL(__VA_ARGS__,))) - -#ifndef RTE_FLOW_CLASSIFY_TABLE_MAX -#define RTE_FLOW_CLASSIFY_TABLE_MAX 32 -#endif - -/** Opaque data type for flow classifier */ -struct rte_flow_classifier; - -/** Opaque data type for flow classify rule */ -struct rte_flow_classify_rule; - -/** Flow classify rule type */ -enum rte_flow_classify_rule_type { - /** no type */ - RTE_FLOW_CLASSIFY_RULE_TYPE_NONE, - /** IPv4 5tuple type */ - RTE_FLOW_CLASSIFY_RULE_TYPE_IPV4_5TUPLE, -}; - -/** Flow classify table type */ -enum rte_flow_classify_table_type { - /** No type */ - RTE_FLOW_CLASSIFY_TABLE_TYPE_NONE = 1 << 0, - /** ACL IP4 5TUPLE */ - RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE = 1 << 1, - /** ACL VLAN IP4 5TUPLE */ - RTE_FLOW_CLASSIFY_TABLE_ACL_VLAN_IP4_5TUPLE = 1 << 2, - /** ACL QinQ IP4 5TUPLE */ - RTE_FLOW_CLASSIFY_TABLE_ACL_QINQ_IP4_5TUPLE = 1 << 3, - -}; - -/** Parameters for flow classifier creation */ -struct rte_flow_classifier_params { - /** flow classifier name */ - const char *name; - - /** CPU socket ID where memory for the flow classifier and its */ - /** elements (tables) should be allocated */ - int socket_id; -}; - -/** Parameters for table creation */ -struct rte_flow_classify_table_params { - /** Table operations (specific to each table type) */ - struct rte_table_ops *ops; - - /** Opaque param to be passed to the table create operation */ - void *arg_create; - - /** Classifier table type */ - enum rte_flow_classify_table_type type; -}; - -/** IPv4 5-tuple data */ -struct rte_flow_classify_ipv4_5tuple { - uint32_t dst_ip; /**< Destination IP address in big endian. */ - uint32_t dst_ip_mask; /**< Mask of destination IP address. */ - uint32_t src_ip; /**< Source IP address in big endian. */ - uint32_t src_ip_mask; /**< Mask of destination IP address. */ - uint16_t dst_port; /**< Destination port in big endian. */ - uint16_t dst_port_mask; /**< Mask of destination port. */ - uint16_t src_port; /**< Source Port in big endian. */ - uint16_t src_port_mask; /**< Mask of source port. */ - uint8_t proto; /**< L4 protocol. */ - uint8_t proto_mask; /**< Mask of L4 protocol. */ -}; - -/** - * Flow stats - * - * For the count action, stats can be returned by the query API. - * - * Storage for stats is provided by application. - */ -struct rte_flow_classify_stats { - void *stats; -}; - -struct rte_flow_classify_ipv4_5tuple_stats { - /** count of packets that match IPv4 5tuple pattern */ - uint64_t counter1; - /** IPv4 5tuple data */ - struct rte_flow_classify_ipv4_5tuple ipv4_5tuple; -}; - -/** - * Flow classifier create - * - * @param params - * Parameters for flow classifier creation - * @return - * Handle to flow classifier instance on success or NULL otherwise - */ -__rte_experimental -struct rte_flow_classifier * -rte_flow_classifier_create(struct rte_flow_classifier_params *params); - -/** - * Flow classifier free - * - * @param cls - * Handle to flow classifier instance - * @return - * 0 on success, error code otherwise - */ -__rte_experimental -int -rte_flow_classifier_free(struct rte_flow_classifier *cls); - -/** - * Flow classify table create - * - * @param cls - * Handle to flow classifier instance - * @param params - * Parameters for flow_classify table creation - * @return - * 0 on success, error code otherwise - */ -__rte_experimental -int -rte_flow_classify_table_create(struct rte_flow_classifier *cls, - struct rte_flow_classify_table_params *params); - -/** - * Flow classify validate - * - * @param cls - * Handle to flow classifier instance - * @param[in] attr - * Flow rule attributes - * @param[in] pattern - * Pattern specification (list terminated by the END pattern item). - * @param[in] actions - * Associated actions (list terminated by the END pattern item). - * @param[out] error - * Perform verbose error reporting if not NULL. Structure - * initialised in case of error only. - * @return - * 0 on success, error code otherwise - */ -__rte_experimental -int -rte_flow_classify_validate(struct rte_flow_classifier *cls, - const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - struct rte_flow_error *error); - -/** - * Add a flow classify rule to the flow_classifier table. - * - * @param[in] cls - * Flow classifier handle - * @param[in] attr - * Flow rule attributes - * @param[in] pattern - * Pattern specification (list terminated by the END pattern item). - * @param[in] actions - * Associated actions (list terminated by the END pattern item). - * @param[out] key_found - * returns 1 if rule present already, 0 otherwise. - * @param[out] error - * Perform verbose error reporting if not NULL. Structure - * initialised in case of error only. - * @return - * A valid handle in case of success, NULL otherwise. - */ -__rte_experimental -struct rte_flow_classify_rule * -rte_flow_classify_table_entry_add(struct rte_flow_classifier *cls, - const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - int *key_found, - struct rte_flow_error *error); - -/** - * Delete a flow classify rule from the flow_classifier table. - * - * @param[in] cls - * Flow classifier handle - * @param[in] rule - * Flow classify rule - * @return - * 0 on success, error code otherwise. - */ -__rte_experimental -int -rte_flow_classify_table_entry_delete(struct rte_flow_classifier *cls, - struct rte_flow_classify_rule *rule); - -/** - * Query flow classifier for given rule. - * - * @param[in] cls - * Flow classifier handle - * @param[in] pkts - * Pointer to packets to process - * @param[in] nb_pkts - * Number of packets to process - * @param[in] rule - * Flow classify rule - * @param[in] stats - * Flow classify stats - * - * @return - * 0 on success, error code otherwise. - */ -__rte_experimental -int -rte_flow_classifier_query(struct rte_flow_classifier *cls, - struct rte_mbuf **pkts, - const uint16_t nb_pkts, - struct rte_flow_classify_rule *rule, - struct rte_flow_classify_stats *stats); - -#ifdef __cplusplus -} -#endif - -#endif /* _RTE_FLOW_CLASSIFY_H_ */ diff --git a/lib/flow_classify/rte_flow_classify_parse.c b/lib/flow_classify/rte_flow_classify_parse.c deleted file mode 100644 index 345d129d35e0..000000000000 --- a/lib/flow_classify/rte_flow_classify_parse.c +++ /dev/null @@ -1,532 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#include -#include "rte_flow_classify_parse.h" - -struct classify_valid_pattern { - enum rte_flow_item_type *items; - parse_filter_t parse_filter; -}; - -static struct classify_action action; - -/* Pattern for IPv4 5-tuple UDP filter */ -static enum rte_flow_item_type pattern_ntuple_1[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Pattern for IPv4 5-tuple TCP filter */ -static enum rte_flow_item_type pattern_ntuple_2[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Pattern for IPv4 5-tuple SCTP filter */ -static enum rte_flow_item_type pattern_ntuple_3[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_SCTP, - RTE_FLOW_ITEM_TYPE_END, -}; - -static int -classify_parse_ntuple_filter(const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - struct rte_eth_ntuple_filter *filter, - struct rte_flow_error *error); - -static struct classify_valid_pattern classify_supported_patterns[] = { - /* ntuple */ - { pattern_ntuple_1, classify_parse_ntuple_filter }, - { pattern_ntuple_2, classify_parse_ntuple_filter }, - { pattern_ntuple_3, classify_parse_ntuple_filter }, -}; - -struct classify_action * -classify_get_flow_action(void) -{ - return &action; -} - -/* Find the first VOID or non-VOID item pointer */ -const struct rte_flow_item * -classify_find_first_item(const struct rte_flow_item *item, bool is_void) -{ - bool is_find; - - while (item->type != RTE_FLOW_ITEM_TYPE_END) { - if (is_void) - is_find = item->type == RTE_FLOW_ITEM_TYPE_VOID; - else - is_find = item->type != RTE_FLOW_ITEM_TYPE_VOID; - if (is_find) - break; - item++; - } - return item; -} - -/* Skip all VOID items of the pattern */ -void -classify_pattern_skip_void_item(struct rte_flow_item *items, - const struct rte_flow_item *pattern) -{ - uint32_t cpy_count = 0; - const struct rte_flow_item *pb = pattern, *pe = pattern; - - for (;;) { - /* Find a non-void item first */ - pb = classify_find_first_item(pb, false); - if (pb->type == RTE_FLOW_ITEM_TYPE_END) { - pe = pb; - break; - } - - /* Find a void item */ - pe = classify_find_first_item(pb + 1, true); - - cpy_count = pe - pb; - rte_memcpy(items, pb, sizeof(struct rte_flow_item) * cpy_count); - - items += cpy_count; - - if (pe->type == RTE_FLOW_ITEM_TYPE_END) { - pb = pe; - break; - } - } - /* Copy the END item. */ - rte_memcpy(items, pe, sizeof(struct rte_flow_item)); -} - -/* Check if the pattern matches a supported item type array */ -static bool -classify_match_pattern(enum rte_flow_item_type *item_array, - struct rte_flow_item *pattern) -{ - struct rte_flow_item *item = pattern; - - while ((*item_array == item->type) && - (*item_array != RTE_FLOW_ITEM_TYPE_END)) { - item_array++; - item++; - } - - return (*item_array == RTE_FLOW_ITEM_TYPE_END && - item->type == RTE_FLOW_ITEM_TYPE_END); -} - -/* Find if there's parse filter function matched */ -parse_filter_t -classify_find_parse_filter_func(struct rte_flow_item *pattern) -{ - parse_filter_t parse_filter = NULL; - uint8_t i = 0; - - for (; i < RTE_DIM(classify_supported_patterns); i++) { - if (classify_match_pattern(classify_supported_patterns[i].items, - pattern)) { - parse_filter = - classify_supported_patterns[i].parse_filter; - break; - } - } - - return parse_filter; -} - -#define FLOW_RULE_MIN_PRIORITY 8 -#define FLOW_RULE_MAX_PRIORITY 0 - -#define NEXT_ITEM_OF_PATTERN(item, pattern, index)\ - do {\ - item = pattern + index;\ - while (item->type == RTE_FLOW_ITEM_TYPE_VOID) {\ - index++;\ - item = pattern + index;\ - } \ - } while (0) - -#define NEXT_ITEM_OF_ACTION(act, actions, index)\ - do {\ - act = actions + index;\ - while (act->type == RTE_FLOW_ACTION_TYPE_VOID) {\ - index++;\ - act = actions + index;\ - } \ - } while (0) - -/** - * Please aware there's an assumption for all the parsers. - * rte_flow_item is using big endian, rte_flow_attr and - * rte_flow_action are using CPU order. - * Because the pattern is used to describe the packets, - * normally the packets should use network order. - */ - -/** - * Parse the rule to see if it is a n-tuple rule. - * And get the n-tuple filter info BTW. - * pattern: - * The first not void item can be ETH or IPV4. - * The second not void item must be IPV4 if the first one is ETH. - * The third not void item must be UDP or TCP. - * The next not void item must be END. - * action: - * The first not void action should be QUEUE. - * The next not void action should be END. - * pattern example: - * ITEM Spec Mask - * ETH NULL NULL - * IPV4 src_addr 192.168.1.20 0xFFFFFFFF - * dst_addr 192.167.3.50 0xFFFFFFFF - * next_proto_id 17 0xFF - * UDP/TCP/ src_port 80 0xFFFF - * SCTP dst_port 80 0xFFFF - * END - * other members in mask and spec should set to 0x00. - * item->last should be NULL. - */ -static int -classify_parse_ntuple_filter(const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - struct rte_eth_ntuple_filter *filter, - struct rte_flow_error *error) -{ - const struct rte_flow_item *item; - const struct rte_flow_action *act; - const struct rte_flow_item_ipv4 *ipv4_spec; - const struct rte_flow_item_ipv4 *ipv4_mask; - const struct rte_flow_item_tcp *tcp_spec; - const struct rte_flow_item_tcp *tcp_mask; - const struct rte_flow_item_udp *udp_spec; - const struct rte_flow_item_udp *udp_mask; - const struct rte_flow_item_sctp *sctp_spec; - const struct rte_flow_item_sctp *sctp_mask; - const struct rte_flow_action_count *count; - const struct rte_flow_action_mark *mark_spec; - uint32_t index; - - /* parse pattern */ - index = 0; - - /* the first not void item can be MAC or IPv4 */ - NEXT_ITEM_OF_PATTERN(item, pattern, index); - - if (item->type != RTE_FLOW_ITEM_TYPE_ETH && - item->type != RTE_FLOW_ITEM_TYPE_IPV4) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, "Not supported by ntuple filter"); - return -EINVAL; - } - /* Skip Ethernet */ - if (item->type == RTE_FLOW_ITEM_TYPE_ETH) { - /*Not supported last point for range*/ - if (item->last) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - item, - "Not supported last point for range"); - return -EINVAL; - - } - /* if the first item is MAC, the content should be NULL */ - if (item->spec || item->mask) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, - "Not supported by ntuple filter"); - return -EINVAL; - } - /* check if the next not void item is IPv4 */ - index++; - NEXT_ITEM_OF_PATTERN(item, pattern, index); - if (item->type != RTE_FLOW_ITEM_TYPE_IPV4) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, - "Not supported by ntuple filter"); - return -EINVAL; - } - } - - /* get the IPv4 info */ - if (!item->spec || !item->mask) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, "Invalid ntuple mask"); - return -EINVAL; - } - /*Not supported last point for range*/ - if (item->last) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - item, "Not supported last point for range"); - return -EINVAL; - - } - - ipv4_mask = item->mask; - /** - * Only support src & dst addresses, protocol, - * others should be masked. - */ - if (ipv4_mask->hdr.version_ihl || - ipv4_mask->hdr.type_of_service || - ipv4_mask->hdr.total_length || - ipv4_mask->hdr.packet_id || - ipv4_mask->hdr.fragment_offset || - ipv4_mask->hdr.time_to_live || - ipv4_mask->hdr.hdr_checksum) { - rte_flow_error_set(error, - EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, - item, "Not supported by ntuple filter"); - return -EINVAL; - } - - filter->dst_ip_mask = ipv4_mask->hdr.dst_addr; - filter->src_ip_mask = ipv4_mask->hdr.src_addr; - filter->proto_mask = ipv4_mask->hdr.next_proto_id; - - ipv4_spec = item->spec; - filter->dst_ip = ipv4_spec->hdr.dst_addr; - filter->src_ip = ipv4_spec->hdr.src_addr; - filter->proto = ipv4_spec->hdr.next_proto_id; - - /* check if the next not void item is TCP or UDP or SCTP */ - index++; - NEXT_ITEM_OF_PATTERN(item, pattern, index); - if (item->type != RTE_FLOW_ITEM_TYPE_TCP && - item->type != RTE_FLOW_ITEM_TYPE_UDP && - item->type != RTE_FLOW_ITEM_TYPE_SCTP) { - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, "Not supported by ntuple filter"); - return -EINVAL; - } - - /* get the TCP/UDP info */ - if (!item->spec || !item->mask) { - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, "Invalid ntuple mask"); - return -EINVAL; - } - - /*Not supported last point for range*/ - if (item->last) { - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - item, "Not supported last point for range"); - return -EINVAL; - - } - - if (item->type == RTE_FLOW_ITEM_TYPE_TCP) { - tcp_mask = item->mask; - - /** - * Only support src & dst ports, tcp flags, - * others should be masked. - */ - if (tcp_mask->hdr.sent_seq || - tcp_mask->hdr.recv_ack || - tcp_mask->hdr.data_off || - tcp_mask->hdr.rx_win || - tcp_mask->hdr.cksum || - tcp_mask->hdr.tcp_urp) { - memset(filter, 0, - sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, "Not supported by ntuple filter"); - return -EINVAL; - } - - filter->dst_port_mask = tcp_mask->hdr.dst_port; - filter->src_port_mask = tcp_mask->hdr.src_port; - if (tcp_mask->hdr.tcp_flags == 0xFF) { - filter->flags |= RTE_NTUPLE_FLAGS_TCP_FLAG; - } else if (!tcp_mask->hdr.tcp_flags) { - filter->flags &= ~RTE_NTUPLE_FLAGS_TCP_FLAG; - } else { - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, "Not supported by ntuple filter"); - return -EINVAL; - } - - tcp_spec = item->spec; - filter->dst_port = tcp_spec->hdr.dst_port; - filter->src_port = tcp_spec->hdr.src_port; - filter->tcp_flags = tcp_spec->hdr.tcp_flags; - } else if (item->type == RTE_FLOW_ITEM_TYPE_UDP) { - udp_mask = item->mask; - - /** - * Only support src & dst ports, - * others should be masked. - */ - if (udp_mask->hdr.dgram_len || - udp_mask->hdr.dgram_cksum) { - memset(filter, 0, - sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, "Not supported by ntuple filter"); - return -EINVAL; - } - - filter->dst_port_mask = udp_mask->hdr.dst_port; - filter->src_port_mask = udp_mask->hdr.src_port; - - udp_spec = item->spec; - filter->dst_port = udp_spec->hdr.dst_port; - filter->src_port = udp_spec->hdr.src_port; - } else { - sctp_mask = item->mask; - - /** - * Only support src & dst ports, - * others should be masked. - */ - if (sctp_mask->hdr.tag || - sctp_mask->hdr.cksum) { - memset(filter, 0, - sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, "Not supported by ntuple filter"); - return -EINVAL; - } - - filter->dst_port_mask = sctp_mask->hdr.dst_port; - filter->src_port_mask = sctp_mask->hdr.src_port; - - sctp_spec = item->spec; - filter->dst_port = sctp_spec->hdr.dst_port; - filter->src_port = sctp_spec->hdr.src_port; - } - - /* check if the next not void item is END */ - index++; - NEXT_ITEM_OF_PATTERN(item, pattern, index); - if (item->type != RTE_FLOW_ITEM_TYPE_END) { - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, "Not supported by ntuple filter"); - return -EINVAL; - } - - table_type = RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE; - - /* parse attr */ - /* must be input direction */ - if (!attr->ingress) { - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, - attr, "Only support ingress."); - return -EINVAL; - } - - /* not supported */ - if (attr->egress) { - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, - attr, "Not support egress."); - return -EINVAL; - } - - if (attr->priority > 0xFFFF) { - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, - attr, "Error priority."); - return -EINVAL; - } - filter->priority = (uint16_t)attr->priority; - if (attr->priority > FLOW_RULE_MIN_PRIORITY) - filter->priority = FLOW_RULE_MAX_PRIORITY; - - /* parse action */ - index = 0; - - /** - * n-tuple only supports count and Mark, - * check if the first not void action is COUNT or MARK. - */ - memset(&action, 0, sizeof(action)); - NEXT_ITEM_OF_ACTION(act, actions, index); - switch (act->type) { - case RTE_FLOW_ACTION_TYPE_COUNT: - action.action_mask |= 1LLU << RTE_FLOW_ACTION_TYPE_COUNT; - count = act->conf; - memcpy(&action.act.counter, count, sizeof(action.act.counter)); - break; - case RTE_FLOW_ACTION_TYPE_MARK: - action.action_mask |= 1LLU << RTE_FLOW_ACTION_TYPE_MARK; - mark_spec = act->conf; - memcpy(&action.act.mark, mark_spec, sizeof(action.act.mark)); - break; - default: - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, act, - "Invalid action."); - return -EINVAL; - } - - /* check if the next not void item is MARK or COUNT or END */ - index++; - NEXT_ITEM_OF_ACTION(act, actions, index); - switch (act->type) { - case RTE_FLOW_ACTION_TYPE_COUNT: - action.action_mask |= 1LLU << RTE_FLOW_ACTION_TYPE_COUNT; - count = act->conf; - memcpy(&action.act.counter, count, sizeof(action.act.counter)); - break; - case RTE_FLOW_ACTION_TYPE_MARK: - action.action_mask |= 1LLU << RTE_FLOW_ACTION_TYPE_MARK; - mark_spec = act->conf; - memcpy(&action.act.mark, mark_spec, sizeof(action.act.mark)); - break; - case RTE_FLOW_ACTION_TYPE_END: - return 0; - default: - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, act, - "Invalid action."); - return -EINVAL; - } - - /* check if the next not void item is END */ - index++; - NEXT_ITEM_OF_ACTION(act, actions, index); - if (act->type != RTE_FLOW_ACTION_TYPE_END) { - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, act, - "Invalid action."); - return -EINVAL; - } - - return 0; -} diff --git a/lib/flow_classify/rte_flow_classify_parse.h b/lib/flow_classify/rte_flow_classify_parse.h deleted file mode 100644 index 7943efc0d4ba..000000000000 --- a/lib/flow_classify/rte_flow_classify_parse.h +++ /dev/null @@ -1,58 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#ifndef _RTE_FLOW_CLASSIFY_PARSE_H_ -#define _RTE_FLOW_CLASSIFY_PARSE_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern enum rte_flow_classify_table_type table_type; - -struct classify_action { - /* Flow action mask */ - uint64_t action_mask; - - struct action { - /** Integer value to return with packets */ - struct rte_flow_action_mark mark; - /** Flow rule counter */ - struct rte_flow_query_count counter; - } act; -}; - -typedef int (*parse_filter_t)(const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - struct rte_eth_ntuple_filter *filter, - struct rte_flow_error *error); - -/* Skip all VOID items of the pattern */ -void -classify_pattern_skip_void_item(struct rte_flow_item *items, - const struct rte_flow_item *pattern); - -/* Find the first VOID or non-VOID item pointer */ -const struct rte_flow_item * -classify_find_first_item(const struct rte_flow_item *item, bool is_void); - - -/* Find if there's parse filter function matched */ -parse_filter_t -classify_find_parse_filter_func(struct rte_flow_item *pattern); - -/* get action data */ -struct classify_action * -classify_get_flow_action(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _RTE_FLOW_CLASSIFY_PARSE_H_ */ diff --git a/lib/flow_classify/version.map b/lib/flow_classify/version.map deleted file mode 100644 index 49bc25c6a087..000000000000 --- a/lib/flow_classify/version.map +++ /dev/null @@ -1,13 +0,0 @@ -EXPERIMENTAL { - global: - - rte_flow_classifier_create; - rte_flow_classifier_free; - rte_flow_classifier_query; - rte_flow_classify_table_create; - rte_flow_classify_table_entry_add; - rte_flow_classify_table_entry_delete; - rte_flow_classify_validate; - - local: *; -}; diff --git a/lib/meson.build b/lib/meson.build index fac2f52cad4f..ecac701161c8 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -62,7 +62,6 @@ libraries = [ 'pdump', # pdump lib depends on bpf 'table', 'pipeline', - 'flow_classify', # flow_classify lib depends on pkt framework table lib 'graph', 'node', ] @@ -70,7 +69,6 @@ libraries = [ optional_libs = [ 'bitratestats', 'cfgfile', - 'flow_classify', 'gpudev', 'graph', 'gro', @@ -89,7 +87,6 @@ optional_libs = [ ] dpdk_libs_deprecated += [ - 'flow_classify', 'kni', ] diff --git a/meson_options.txt b/meson_options.txt index 82c8297065f0..95e22e0ce70c 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -10,7 +10,7 @@ option('disable_apps', type: 'string', value: '', description: 'Comma-separated list of apps to explicitly disable.') option('disable_drivers', type: 'string', value: '', description: 'Comma-separated list of drivers to explicitly disable.') -option('disable_libs', type: 'string', value: 'flow_classify,kni', description: +option('disable_libs', type: 'string', value: 'kni', description: 'Comma-separated list of libraries to explicitly disable. [NOTE: not all libs can be disabled]') option('drivers_install_subdir', type: 'string', value: 'dpdk/pmds-', description: 'Subdirectory of libdir where to install PMDs. Defaults to using a versioned subdirectory.') -- 2.39.2